32 #include <QtCore/QTextCodec>
33 #include <QtCore/QTimer>
36 #include <kapplication.h>
41 #include <kabc/addressee.h>
42 #include <kabc/addresseelist.h>
43 #include <kabc/stdaddressbook.h>
48 static const char saveError[] = I18N_NOOP(
"Saving modifications to address book failed");
49 static const char ambiguousMatch[] = I18N_NOOP(
"Input number %1 matches more than one contact. "
50 "Skipping it to avoid undesired results");
56 m_operation(operation),
57 m_formatFactory(factory),
64 m_matchCaseSensitivity(Qt::CaseInsensitive),
74 delete m_outputFormat;
89 if (name ==
"uid" || name ==
"search" || name ==
"dialog")
91 QString operation = QString::fromUtf8(m_operation ==
Add ?
"add" :
"merge");
92 QString error = i18n(
"Input format '%1' not usable with operation '%2'",
93 QString::fromLocal8Bit(name), operation);
94 std::cerr << error.toLocal8Bit().data();
95 std::cerr << std::endl;
103 m_inputFormat = m_formatFactory->
inputFormat(name);
105 return m_inputFormat != 0;
114 return m_outputFormat != 0;
121 if (m_operation ==
List)
return true;
123 if (m_inputFormat == 0)
return false;
132 if (m_outputFormat == 0)
return false;
141 if (m_operation ==
List)
return true;
143 if (m_inputFormat == 0)
return false;
145 m_inputCodec = codecForName(name);
147 if (m_inputCodec == 0)
return false;
149 return m_inputFormat->
setCodec(m_inputCodec);
156 if (m_outputFormat == 0)
return false;
158 m_outputCodec = codecForName(name);
160 if (m_outputCodec == 0)
return false;
162 return m_outputFormat->
setCodec(m_outputCodec);
169 m_inputStream = stream;
176 if (m_inputStream == 0 && m_operation !=
List)
return false;
185 m_addressBook = KABC::StdAddressBook::self(
false);
186 if (m_addressBook == 0)
return false;
188 KABC::StdAddressBook::setAutomaticSave(
false);
192 QTimer::singleShot(0,
this, SLOT(slotAddressBookLoaded()));
199 int KABCClient::performAdd()
202 std::set<QString> uids;
203 AddressBook::ConstIterator it = m_addressBook->constBegin();
204 AddressBook::ConstIterator endIt = m_addressBook->constEnd();
205 for (; it != endIt; ++it)
207 uids.insert((*it).uid());
210 bool wantSave =
false;
211 while (!m_inputStream->bad() && !m_inputStream->eof())
213 Addressee addressee = m_inputFormat->
readAddressee(*m_inputStream);
214 if (addressee.isEmpty())
continue;
217 if (addressee.uid().isEmpty() || uids.find(addressee.uid()) != uids.end())
219 addressee.setUid(KRandom::randomString(10));
220 uids.insert(addressee.uid());
223 m_addressBook->insertAddressee(addressee);
227 std::cout << std::endl;
230 if (!wantSave)
return 2;
234 Ticket* saveTicket = m_addressBook->requestSaveTicket();
237 std::cerr << i18n(
saveError).toLocal8Bit().data() << std::endl;
241 bool saved = m_addressBook->save(saveTicket);
245 std::cerr << i18n(
saveError).toLocal8Bit().data() << std::endl;
250 return (m_inputStream->bad() ? 1 : 0);
255 int KABCClient::performRemove()
257 bool wantSave =
false;
260 while (!m_inputStream->bad() && !m_inputStream->eof())
262 Addressee search = m_inputFormat->
readAddressee(*m_inputStream);
263 if (search.isEmpty())
continue;
267 AddresseeList result;
269 AddressBook::ConstIterator it = m_addressBook->constBegin();
270 AddressBook::ConstIterator endIt = m_addressBook->constEnd();
271 for (; it != endIt; ++it)
273 if (!search.uid().isEmpty() && (*it).uid() == search.uid())
277 else if (!search.realName().isEmpty() &&
278 (*it).realName().indexOf(search.realName(), 0, m_matchCaseSensitivity) != -1)
282 else if (!search.familyName().isEmpty() &&
283 (*it).realName().indexOf(search.familyName(), 0, m_matchCaseSensitivity) != -1)
285 if (!search.givenName().isEmpty())
287 if ((*it).realName().indexOf(search.givenName(), 0, m_matchCaseSensitivity) != -1)
295 else if (!search.givenName().isEmpty() &&
296 (*it).realName().indexOf(search.givenName(), 0, m_matchCaseSensitivity) != -1)
300 else if (!search.preferredEmail().isEmpty())
302 QStringList matches =
303 (*it).emails().filter(search.preferredEmail(), m_matchCaseSensitivity);
304 if (matches.count() > 0)
310 if (result.count() > 1)
break;
314 if (result.count() == 1)
316 m_addressBook->removeAddressee(result[0]);
320 std::cout << std::endl;
322 else if (result.count() > 1)
324 std::cerr << i18n(
ambiguousMatch).arg(count).toLocal8Bit().data() << std::endl;
328 if (!wantSave)
return 2;
332 Ticket* saveTicket = m_addressBook->requestSaveTicket();
335 std::cerr << i18n(
saveError).toLocal8Bit().data() << std::endl;
339 bool saved = m_addressBook->save(saveTicket);
343 std::cerr << i18n(
saveError).toLocal8Bit().data() << std::endl;
348 return (m_inputStream->bad() ? 1 : 0);
353 int KABCClient::performMerge()
355 bool wantSave =
false;
358 while (!m_inputStream->bad() && !m_inputStream->eof())
360 Addressee addressee = m_inputFormat->
readAddressee(*m_inputStream);
361 if (addressee.isEmpty())
continue;
365 AddresseeList result;
367 AddressBook::ConstIterator it = m_addressBook->constBegin();
368 AddressBook::ConstIterator endIt = m_addressBook->constEnd();
369 for (; it != endIt; ++it)
371 if (!addressee.uid().isEmpty() && (*it).uid() == addressee.uid())
375 else if (!addressee.realName().isEmpty() &&
376 (*it).realName().indexOf(addressee.realName(), 0, m_matchCaseSensitivity) != -1)
380 else if (!addressee.familyName().isEmpty() &&
381 (*it).realName().indexOf(addressee.familyName(), 0, m_matchCaseSensitivity) != -1)
383 if (!addressee.givenName().isEmpty())
385 if ((*it).realName().indexOf(addressee.givenName(),
386 0, m_matchCaseSensitivity) != -1)
394 else if (!addressee.givenName().isEmpty() &&
395 (*it).realName().indexOf(addressee.givenName(), 0, m_matchCaseSensitivity) != -1)
399 else if (!addressee.preferredEmail().isEmpty())
401 QStringList matches =
402 (*it).emails().filter(addressee.preferredEmail(), m_matchCaseSensitivity);
403 if (matches.count() > 0)
409 if (result.count() > 1)
break;
413 if (result.count() == 1)
415 Addressee master = result[0];
416 mergeAddressees(master, addressee);
418 m_addressBook->insertAddressee(master);
422 std::cout << std::endl;
424 else if (result.count() > 1)
426 std::cerr << i18n(
ambiguousMatch).arg(count).toLocal8Bit().data() << std::endl;
430 if (!wantSave)
return 2;
434 Ticket* saveTicket = m_addressBook->requestSaveTicket();
437 std::cerr << i18n(
saveError).toLocal8Bit().data() << std::endl;
441 bool saved = m_addressBook->save(saveTicket);
445 std::cerr << i18n(
saveError).toLocal8Bit().data() << std::endl;
450 return (m_inputStream->bad() ? 1 : 0);
455 int KABCClient::performList()
457 AddresseeList list = m_addressBook->allAddressees();
464 int KABCClient::performSearch()
468 AddressBook::ConstIterator endIt = m_addressBook->constEnd();
470 while (!m_inputStream->bad() && !m_inputStream->eof())
472 Addressee search = m_inputFormat->
readAddressee(*m_inputStream);
473 if (search.isEmpty())
continue;
475 AddresseeList result;
477 AddressBook::ConstIterator it = m_addressBook->constBegin();
478 for (; it != endIt; ++it)
480 if (!search.uid().isEmpty() && (*it).uid() == search.uid())
484 else if (!search.realName().isEmpty() &&
485 (*it).realName().indexOf(search.realName(), 0, m_matchCaseSensitivity) != -1)
489 else if (!search.familyName().isEmpty() &&
490 (*it).realName().indexOf(search.familyName(), 0, m_matchCaseSensitivity) != -1)
492 if (!search.givenName().isEmpty())
494 if ((*it).realName().indexOf(search.givenName(), 0, m_matchCaseSensitivity) != -1)
502 else if (!search.givenName().isEmpty() &&
503 (*it).realName().indexOf(search.givenName(), 0, m_matchCaseSensitivity) != -1)
507 else if (!search.preferredEmail().isEmpty())
509 QStringList matches =
510 (*it).emails().filter(search.preferredEmail(), m_matchCaseSensitivity);
511 if (matches.count() > 0)
518 if (result.count() > 0)
535 void KABCClient::mergePictures(KABC::Picture& master,
const KABC::Picture slave)
537 if (master.isIntern())
539 if (master.data().isNull())
541 if (slave.isIntern() && !slave.data().isNull())
542 master.setData(slave.data());
543 else if (!slave.isIntern() && !slave.url().isEmpty())
544 master.setUrl(slave.url());
549 if (master.url().isEmpty())
551 if (slave.isIntern() && !slave.data().isNull())
552 master.setData( slave.data() );
553 else if (!slave.isIntern() && !slave.url().isEmpty())
554 master.setUrl(slave.url());
562 void KABCClient::mergeAddressees(KABC::Addressee& master,
const KABC::Addressee& slave)
564 if (slave.isEmpty())
return;
567 const KABC::Address::List addresses = slave.addresses();
568 KABC::Address::List masterAddresses = master.addresses();
569 KABC::Address::List::ConstIterator addrIt ;
570 for (addrIt = addresses.begin(); addrIt != addresses.end(); ++addrIt)
572 if (!masterAddresses.contains(*addrIt))
573 master.insertAddress(*addrIt);
577 if (master.birthday().isNull() && !slave.birthday().isNull())
578 master.setBirthday(slave.birthday());
581 const QStringList categories = slave.categories();
582 const QStringList masterCategories = master.categories();
584 QStringList newCategories = masterCategories;
585 QStringList::ConstIterator it;
586 for (it = categories.begin(); it != categories.end(); ++it)
588 if (!masterCategories.contains(*it))
589 newCategories.append(*it);
591 master.setCategories(newCategories);
594 if (!master.secrecy().isValid() && slave.secrecy().isValid())
595 master.setSecrecy(slave.secrecy());
598 const QStringList emails = slave.emails();
599 const QStringList masterEmails = master.emails();
601 for (it = emails.begin(); it != emails.end(); ++it)
603 if (!masterEmails.contains(*it))
604 master.insertEmail(*it,
false);
608 if (master.formattedName().isEmpty() && !slave.formattedName().isEmpty())
609 master.setFormattedName(slave.formattedName());
612 if (!master.geo().isValid() && slave.geo().isValid())
613 master.setGeo(slave.geo());
619 KABC::Picture logo = master.logo();
620 mergePictures(logo, slave.logo());
621 master.setLogo(logo);
624 if (master.mailer().isEmpty() && !slave.mailer().isEmpty())
625 master.setMailer(slave.mailer());
628 if (master.assembledName().isEmpty() && !slave.assembledName().isEmpty())
629 master.setNameFromString(slave.assembledName());
632 if (master.nickName().isEmpty() && !slave.nickName().isEmpty())
633 master.setNickName(slave.nickName());
636 if (master.note().isEmpty() && !slave.note().isEmpty())
637 master.setNote(slave.note());
640 if (master.organization().isEmpty() && !slave.organization().isEmpty())
641 master.setOrganization(slave.organization());
644 KABC::Picture photo = master.photo();
645 mergePictures(photo, slave.photo());
646 master.setPhoto( photo );
649 if (master.productId().isEmpty() && !slave.productId().isEmpty())
650 master.setProductId(slave.productId());
653 if (master.revision().isNull() && !slave.revision().isNull())
654 master.setRevision(slave.revision());
657 if (master.role().isEmpty() && !slave.role().isEmpty())
658 master.setRole(slave.role());
661 if (master.sortString().isEmpty() && !slave.sortString().isEmpty())
662 master.setSortString(slave.sortString());
669 const KABC::PhoneNumber::List phones = slave.phoneNumbers();
670 const KABC::PhoneNumber::List masterPhones = master.phoneNumbers();
672 KABC::PhoneNumber::List::ConstIterator phoneIt;
673 for (phoneIt = phones.begin(); phoneIt != phones.end(); ++phoneIt)
675 if (!masterPhones.contains(*phoneIt))
676 master.insertPhoneNumber(*phoneIt);
680 if (master.title().isEmpty() && !slave.title().isEmpty())
681 master.setTitle(slave.title());
684 if (!master.timeZone().isValid() && slave.timeZone().isValid())
685 master.setTimeZone(slave.timeZone());
690 if (master.url().isEmpty() && !slave.url().isEmpty())
691 master.setUrl(slave.url());
694 const QStringList customs = slave.customs();
695 const QStringList masterCustoms = master.customs();
697 QStringList newCustoms = masterCustoms;
698 for (it = customs.begin(); it != customs.end(); ++it)
700 if (!masterCustoms.contains(*it))
701 newCustoms.append(*it);
703 master.setCustoms(newCustoms);
708 QTextCodec* KABCClient::codecForName(
const QByteArray& name)
710 if (name.isEmpty())
return 0;
712 if (name.toLower() ==
"utf-8" || name.toLower() ==
"utf8" || name ==
"utf")
714 return QTextCodec::codecForName(
"UTF-8");
717 if (name.toLower() ==
"local" || name.toLower() ==
"locale")
719 return QTextCodec::codecForLocale();
722 return QTextCodec::codecForName(name.toUpper());
727 void KABCClient::slotAddressBookLoaded()
730 QObject::disconnect(m_addressBook, SIGNAL(addressBookChanged(AddressBook*)),
731 this, SLOT(slotAddressBookLoaded()));
738 result = performAdd();
742 result = performRemove();
746 result = performMerge();
750 result = performList();
754 result = performSearch();
761 KApplication::kApplication()->exit(result);
766 #include "kabcclient.moc"
bool setOutputFormat(const QByteArray &name)
Sets the output format to use.
bool setInputFormat(const QByteArray &name)
Sets the input format to use.
Adds the input to the address book.
static const char saveError[]
Merges input data into the address book.
bool setOutputCodec(const QByteArray &name)
Sets the text codec for writing the output data.
bool setInputOptions(const QByteArray &options)
Sets the options for the input format.
bool setOutputOptions(const QByteArray &options)
Sets the options for the output format.
KABCClient(Operation operation, FormatFactory *factory)
Creates and initializes the instance.
bool initOperation()
Checks if Operation setup is correct and schedules execution.
bool setInputCodec(const QByteArray &name)
Sets the text codec for reading the input data.
static const char ambiguousMatch[]
void setInputStream(std::istream *stream)
Sets the input stream to read data from.
virtual ~KABCClient()
Destroys the instance.
Removes matching contact from the address book.
Searches for matching entries in the address book.
Writes all contacts of the address book.
Operation
List of supported operations.