29 #include <QtCore/QTextCodec> 
   36 #include <kabc/addressee.h> 
   37 #include <kabc/addresseelist.h> 
   38 #include <kabc/vcardconverter.h> 
   44 QByteArray 
fromUnicode(QTextCodec* codec, 
const QString& text)
 
   46     if (codec == 0) 
return QByteArray();
 
   48     return codec->fromUnicode(text);
 
   55     return i18n(
"Writes the unique KABC contact identifier");
 
   70     if (codec == 0) 
return false;
 
   81     if (stream.bad()) 
return false;
 
   83     stream << 
fromUnicode(m_codec, addressee.uid()).constData();
 
   93     if (stream.bad()) 
return false;
 
   95     AddresseeList::const_iterator it    = addresseeList.constBegin();
 
   96     AddresseeList::const_iterator endIt = addresseeList.constEnd();
 
   97     for (; it != endIt; ++it)
 
   99         if (!writeAddressee(*it, stream)) 
return false;
 
  104     return !stream.bad();
 
  112     m_converter = 
new VCardConverter();
 
  126     return i18n(
"Exports to vCard format");
 
  133     if (options == 
"v2.1")
 
  134         m_vCardVersion = VCardConverter::v2_1;
 
  146         i18n(
"Optionally use a different vCard version (default is %1)",
 
  147              QString::fromLatin1(
"3.0"));
 
  149     usage += QLatin1Char(
'\n');
 
  151     usage += QLatin1String(
"v2.1\t");
 
  152     usage += i18n(
"Uses the vCard version 2.1");
 
  161     if (codec == 0) 
return false;
 
  165     QString codecName = QString::fromLatin1(m_codec->name());
 
  167     if (codecName != QString::fromUtf8(
"UTF-8"))
 
  169         QString warning = i18n(
"Warning: using codec '%1' with output format vcard, " 
  170                                "but vCards are usually expected to be in UTF-8.",
 
  173         std::cerr << warning.toLocal8Bit().data() << std::endl;
 
  183     if (stream.bad()) 
return false;
 
  185     VCardConverter::Version 
version = VCardConverter::v3_0;
 
  186     switch (m_vCardVersion)
 
  188         case VCardConverter::v2_1:
 
  189             version = VCardConverter::v2_1;
 
  192         case VCardConverter::v3_0:
 
  195             version = VCardConverter::v3_0;
 
  199             kDebug() <<
"Unknown vCard version" << m_vCardVersion;
 
  203     QByteArray vcard = m_converter->createVCard(addressee, version);
 
  206     if (m_codec == QTextCodec::codecForName(
"UTF-8")) {
 
  207       vcard = 
fromUnicode(m_codec, QString::fromUtf8(vcard));
 
  210     stream << vcard.constData();
 
  212     return !stream.bad();
 
  218                                      std::ostream& stream)
 
  220     if (stream.bad()) 
return false;
 
  222     VCardConverter::Version 
version = VCardConverter::v3_0;
 
  223     switch (m_vCardVersion)
 
  225         case VCardConverter::v2_1:
 
  226             version = VCardConverter::v2_1;
 
  229         case VCardConverter::v3_0:
 
  232             version = VCardConverter::v3_0;
 
  236             kDebug() <<
"Unknown vCard version" << m_vCardVersion;
 
  240     QByteArray vcards = m_converter->createVCards(addresseeList, version);
 
  243     if (m_codec == QTextCodec::codecForName(
"UTF-8")) {
 
  244       vcards = 
fromUnicode(m_codec, QString::fromUtf8(vcards));
 
  247     stream << vcards.constData();
 
  249     return !stream.bad();
 
  263     return i18n(
"Writes email address or formatted name <email address>");
 
  270     QStringList optionList = QString::fromLocal8Bit(options).split(QLatin1Char(
','), QString::SkipEmptyParts);
 
  272     QStringList::const_iterator it    = optionList.constBegin();
 
  273     QStringList::const_iterator endIt = optionList.constEnd();
 
  274     for (; it != endIt; ++it)
 
  276         if ((*it) == QString::fromUtf8(
"allemails"))
 
  278         else if ((*it) == QString::fromUtf8(
"withname"))
 
  279             m_includeName = 
true;
 
  291     QString usage = i18n(
"Comma separated list of: allemails, withname");
 
  293     usage += QLatin1Char(
'\n');
 
  295     usage += QLatin1String(
"allemails\t");
 
  296     usage += i18n(
"List all email addresses of each contact");
 
  298     usage += QLatin1Char(
'\n');
 
  300     usage += QLatin1String(
"withname\t");
 
  301     usage += i18n(
"Prepend formatted name, e.g\n\t\tJohn Doe <jdoe@foo.com>");
 
  310     if (codec == 0) 
return false;
 
  321     if (stream.bad()) 
return false;
 
  325         QStringList emails = addressee.emails();
 
  327         QStringList::const_iterator it    = emails.constBegin();
 
  328         QStringList::const_iterator endIt = emails.constEnd();
 
  332             if (!(*it).isEmpty())
 
  334                 stream << 
fromUnicode(m_codec, decorateEmail(addressee, *it)).constData();
 
  335                 if (stream.bad()) 
return false;
 
  338             for(++it; it != endIt; ++it)
 
  340                 if ((*it).isEmpty()) 
continue;
 
  343                        << 
fromUnicode(m_codec, decorateEmail(addressee, *it)).constData();
 
  345                 if (stream.bad()) 
return false;
 
  351         if (!addressee.preferredEmail().isEmpty())
 
  353             stream << 
fromUnicode(m_codec, decorateEmail(addressee, addressee.preferredEmail())).constData();
 
  357     return !stream.bad();
 
  363                                      std::ostream& stream)
 
  365     if (stream.bad()) 
return false;
 
  367     AddresseeList::const_iterator it    = addresseeList.constBegin();
 
  368     AddresseeList::const_iterator endIt = addresseeList.constEnd();
 
  369     for (; it != endIt; ++it)
 
  371         if ((*it).emails().count() == 0) 
continue;
 
  378     return !stream.bad();
 
  383 QString EmailOutput::decorateEmail(
const KABC::Addressee& addressee, 
const QString& email)
 const 
  386         return addressee.fullEmail(email);
 
  395     : m_allEmails(false), m_queryFormat(false), m_altKeyFormat(false),
 
  396       m_preferNickNameKey(false), m_alsoNickNameKey(false)
 
  404     return i18n(
"Formats output as needed by the mail client mutt");
 
  411     QStringList optionList = QString::fromLocal8Bit(options).split(QLatin1Char(
','), QString::SkipEmptyParts);
 
  413     QStringList::const_iterator it    = optionList.constBegin();
 
  414     QStringList::const_iterator endIt = optionList.constEnd();
 
  415     for (; it != endIt; ++it)
 
  417         if ((*it) == QLatin1String(
"allemails"))
 
  419         else if ((*it) == QLatin1String(
"query"))
 
  420             m_queryFormat = 
true;
 
  421         else if ((*it) == QLatin1String(
"alias"))
 
  422             m_queryFormat = 
false;
 
  423         else if ((*it) == QLatin1String(
"altkeys"))
 
  424             m_altKeyFormat = 
true;
 
  425         else if ((*it) == QLatin1String(
"prefernick"))
 
  426             m_preferNickNameKey = 
true;
 
  427         else if ((*it) == QLatin1String(
"alsonick"))
 
  428             m_alsoNickNameKey = 
true;
 
  433     if (m_alsoNickNameKey && m_preferNickNameKey)
 
  435         kDebug() << 
"Both 'prefernick' and 'alsonick' specified, using only 'alsonick'";
 
  436         m_preferNickNameKey = 
false;
 
  447         i18n(
"Comma separated list of: allemails, query, alias, altkeys, prefernick, alsonick. " 
  450     usage += QLatin1Char(
'\n');
 
  452     usage += QLatin1String(
"allemails\t");
 
  453     usage += i18n(
"List all email addresses of each contact");
 
  455     usage += QLatin1Char(
'\n');
 
  457     usage += QLatin1String(
"query\t\t");
 
  458     usage += i18n(
"Use mutt's query format, e.g.\n\t\t" 
  459                   "jdoe@foo.com [tab] John Doe\n\t\t" 
  460                   "Conflicts with alias");
 
  462     usage += QLatin1Char(
'\n');
 
  464     usage += QLatin1String(
"alias\t\t");
 
  465     usage += i18n(
"Use mutt's alias format, e.g.\n\t\t" 
  466                   "alias JohDoe[tab]John Doe <jdoe@foo.com>\n\t\t" 
  467                   "Conflicts with query");
 
  469     usage += QLatin1Char(
'\n');
 
  471     usage += QLatin1String(
"altkeys\t\t");
 
  472     usage += i18n(
"Use alternative keys with alias format, e.g.\n\t\t" 
  473                   "alias jdoe[tab]John Doe <jdoe@foo.com>");
 
  475     usage += QLatin1Char(
'\n');
 
  477     usage += QLatin1String(
"prefernick\t");
 
  478     usage += i18n(
"If a nick name exists use it instead of the key, e.g.\n\t\t" 
  479                   "alias johnny[tab]John Doe <jdoe@foo.com>");
 
  481     usage += QLatin1Char(
'\n');
 
  483     usage += QLatin1String(
"alsonick\t");
 
  484     usage += i18n(
"Generate additional aliases with the nick name as the key, e.g.\n\t\t" 
  485                   "alias johnny[tab]John Doe <jdoe@foo.com>\n\t\t" 
  486                   "Deactivates 'prefernick' to avoid duplicates");
 
  495     if (codec == 0) 
return false;
 
  506     if (stream.bad()) 
return false;
 
  508     const QString nickKeyString = nickNameKey(addressee);
 
  512     const QString keyString =
 
  513         (m_preferNickNameKey && !nickKeyString.isEmpty()) ? nickKeyString : key(addressee);
 
  517         QStringList emails = addressee.emails();
 
  519         QStringList::const_iterator it    = emails.constBegin();
 
  520         QStringList::const_iterator endIt = emails.constEnd();
 
  524             if (!(*it).isEmpty())
 
  528                     stream << 
fromUnicode(m_codec, *it).constData() << 
"\t" 
  529                            << 
fromUnicode(m_codec, addressee.givenName()).constData() << 
" " 
  530                            << 
fromUnicode(m_codec, addressee.familyName()).constData();
 
  534                     stream << 
"alias " << 
fromUnicode(m_codec, keyString).constData() << 
"\t";
 
  535                     stream << 
fromUnicode(m_codec, addressee.givenName()).constData() << 
" " 
  536                            << 
fromUnicode(m_codec, addressee.familyName()).constData()<< 
" <" 
  539                     if (m_alsoNickNameKey && !nickKeyString.isEmpty())
 
  543                                << 
fromUnicode(m_codec, nickKeyString).constData()         << 
"\t";
 
  544                         stream << 
fromUnicode(m_codec, addressee.givenName()).constData() << 
" " 
  545                                << 
fromUnicode(m_codec, addressee.familyName()).constData()<< 
" <" 
  550                 if (stream.bad()) 
return false;
 
  554             for(++it; it != endIt; ++it, ++count)
 
  556                 if ((*it).isEmpty()) 
continue;
 
  558                 if (m_queryFormat && count == 1)
 
  560                     stream << 
"\t" << 
fromUnicode(m_codec, i18n(
"preferred")).constData();
 
  566                     stream << 
fromUnicode(m_codec, *it).constData() << 
"\t" 
  567                            << 
fromUnicode(m_codec,  addressee.givenName()).constData() << 
" " 
  568                            << 
fromUnicode(m_codec, addressee.familyName()).constData() << 
"\t" 
  573                     stream << 
"alias " << 
fromUnicode(m_codec, keyString).constData()
 
  575                     stream << 
fromUnicode(m_codec, addressee.givenName()).constData()  << 
" " 
  576                            << 
fromUnicode(m_codec, addressee.familyName()).constData() << 
" <" 
  579                     if (m_alsoNickNameKey && !nickKeyString.isEmpty())
 
  583                                << 
fromUnicode(m_codec, nickKeyString).constData()         << 
"\t";
 
  584                         stream << 
fromUnicode(m_codec, addressee.givenName()).constData() << 
" " 
  585                                << 
fromUnicode(m_codec, addressee.familyName()).constData()<< 
" <" 
  590                 if (stream.bad()) 
return false;
 
  596         const QString preferredEmail = addressee.preferredEmail();
 
  597         if (!preferredEmail.isEmpty())
 
  601                 stream << 
fromUnicode(m_codec, preferredEmail).constData()        << 
"\t" 
  602                        << 
fromUnicode(m_codec, addressee.givenName()).constData() << 
" " 
  603                        << 
fromUnicode(m_codec, addressee.familyName()).constData();
 
  607                 stream << 
"alias " << 
fromUnicode(m_codec, keyString).constData()  << 
"\t";
 
  608                 stream << 
fromUnicode(m_codec, addressee.givenName()).constData()  << 
" " 
  609                        << 
fromUnicode(m_codec, addressee.familyName()).constData() << 
" <" 
  610                        << 
fromUnicode(m_codec, preferredEmail).constData()         << 
">";
 
  612                 if (m_alsoNickNameKey && !nickKeyString.isEmpty())
 
  616                            << 
fromUnicode(m_codec, nickKeyString).constData()         << 
"\t";
 
  617                     stream << 
fromUnicode(m_codec, addressee.givenName()).constData() << 
" " 
  618                            << 
fromUnicode(m_codec, addressee.familyName()).constData()<< 
" <" 
  619                            << 
fromUnicode(m_codec, preferredEmail).constData()        << 
">";
 
  625     return !stream.bad();
 
  631                                      std::ostream& stream)
 
  633     if (stream.bad()) 
return false;
 
  635     AddresseeList::const_iterator it    = addresseeList.constBegin();
 
  636     AddresseeList::const_iterator endIt = addresseeList.constEnd();
 
  637     for (; it != endIt; ++it)
 
  639         if ((*it).emails().count() == 0) 
continue;
 
  646     return !stream.bad();
 
  651 QString MuttOutput::key(
const KABC::Addressee& addressee)
 const 
  655         const QChar space = QLatin1Char(
' ');
 
  656         const QChar underscore = QLatin1Char(
'_');
 
  658         if (addressee.familyName().isEmpty())
 
  659             return addressee.givenName().toLower().replace(space, underscore);
 
  661             return addressee.givenName().left(1).toLower() +
 
  662                    addressee.familyName().toLower().replace(space, underscore);
 
  665         return addressee.givenName().left(3) + addressee.familyName().left(3);
 
  668 QString MuttOutput::nickNameKey(
const KABC::Addressee& addressee)
 const 
  670     if (!addressee.nickName().isEmpty())
 
  672         const QChar space = QLatin1Char(
' ');
 
  673         const QChar underscore = QLatin1Char(
'_');
 
  674         return addressee.nickName().toLower().replace(space, underscore);
 
  684     : m_codec(0), m_template(0), m_templateFactory(templateFactory)
 
  698     return i18n(
"Writes the data as a delimiter separated list of values");
 
  705     QString name = QString::fromLocal8Bit(options);
 
  706     if (name.isEmpty()) 
return false;
 
  710     return m_template != 0;
 
  718         i18n(
"Specify one of the following CSV templates:");
 
  720     usage += QLatin1Char(
'\n');
 
  722     const QMap<QString, QString> templateNames = m_templateFactory->
templateNames();
 
  724     QMap<QString, QString>::const_iterator it    = templateNames.constBegin();
 
  725     QMap<QString, QString>::const_iterator endIt = templateNames.constEnd();
 
  726     for (; it != endIt; ++it)
 
  728         QString name = it.key();
 
  729         QString templateName = it.value();
 
  733         usage += name.length() < 8 ? QLatin1String(
"\t\t") : QLatin1String(
"\t");
 
  735         usage += templateName;
 
  737         usage += QLatin1Char(
'\n');
 
  747     if (codec == 0) 
return false;
 
  758     if (stream.bad()) 
return false;
 
  763     for (
int i = 0; i < m_template->
columns(); ++i)
 
  765         QString text = m_template->
fieldText(i, addressee);
 
  766         text.replace(QLatin1Char(
'\n'), QLatin1String(
"\\n"));
 
  768         columns.append(m_template->
quote() + text + m_template->
quote());
 
  773     return !stream.bad();
 
  779                                   std::ostream& stream)
 
  781     if (stream.bad()) 
return false;
 
  783     AddresseeList::const_iterator it    = addresseeList.constBegin();
 
  784     AddresseeList::const_iterator endIt = addresseeList.constEnd();
 
  785     for (; it != endIt; ++it)
 
  792     return !stream.bad();
 
virtual bool setCodec(QTextCodec *codec)
Sets the text codec to use. 
CSVOutput(CSVTemplateFactory *templateFactory)
virtual QString optionUsage() const 
Returns a translate message about the available format options. 
virtual bool setCodec(QTextCodec *codec)
Sets the text codec to use. 
virtual bool writeAddresseeList(const KABC::AddresseeList &addresseeList, std::ostream &stream)
Writes the data from each addressee in the given list to the given output stream. ...
virtual QString description() const 
Returns a translate description of the output format. 
virtual bool setCodec(QTextCodec *codec)
Sets the text codec to use. 
QMap< QString, QString > templateNames()
Returns a set of available templates. 
virtual QString optionUsage() const 
Returns a translate message about the available format options. 
virtual QString description() const 
Returns a translate description of the output format. 
virtual bool writeAddressee(const KABC::Addressee &addressee, std::ostream &stream)
Writes the data of a given addressee to the given output stream. 
virtual bool writeAddressee(const KABC::Addressee &addressee, std::ostream &stream)
Writes the data of a given addressee to the given output stream. 
virtual bool writeAddressee(const KABC::Addressee &addressee, std::ostream &stream)
Writes the data of a given addressee to the given output stream. 
virtual bool setOptions(const QByteArray &options)
Configures the output format. 
virtual bool writeAddresseeList(const KABC::AddresseeList &addresseeList, std::ostream &stream)
Writes the data from each addressee in the given list to the given output stream. ...
virtual bool setOptions(const QByteArray &options)
Configures the output format. 
virtual bool setOptions(const QByteArray &options)
Configures the output format. 
virtual QString description() const 
Returns a translate description of the output format. 
virtual bool writeAddresseeList(const KABC::AddresseeList &addresseeList, std::ostream &stream)
Writes the data from each addressee in the given list to the given output stream. ...
virtual bool setCodec(QTextCodec *codec)
Sets the text codec to use. 
virtual bool setOptions(const QByteArray &options)
Configures the output format. 
virtual QString optionUsage() const 
Returns a translate message about the available format options. 
const QString & delimiter() const 
Returns the CSV delimiter string. 
QString fieldText(int column, const KABC::Addressee &addressee) const 
Returns the specified field of the given addressee formatted as a string. 
const QString & quote() const 
Returns the CSV quoting string. 
CSVTemplate * createCachedTemplate(const QString &name)
Creates a template handler for a given name and caches the instance. 
virtual bool writeAddresseeList(const KABC::AddresseeList &addresseeList, std::ostream &stream)
Writes the data from each addressee in the given list to the given output stream. ...
static CSVTemplate * defaultTemplate()
Returns the template with default setup. 
virtual QString description() const 
Returns a translate description of the output format. 
virtual QString optionUsage() const 
Returns a translate message about the available format options. 
virtual bool setOptions(const QByteArray &options)
Configures the output format. 
int columns() const 
Returns the number of CSV columns. 
virtual bool writeAddressee(const KABC::Addressee &addressee, std::ostream &stream)
Writes the data of a given addressee to the given output stream. 
virtual QString description() const 
Returns a translate description of the output format. 
virtual bool setCodec(QTextCodec *codec)
Sets the text codec to use. 
virtual bool writeAddresseeList(const KABC::AddresseeList &addresseeList, std::ostream &stream)
Writes the data from each addressee in the given list to the given output stream. ...
Factory for creation CSV template handlers. 
virtual bool writeAddressee(const KABC::Addressee &addressee, std::ostream &stream)
Writes the data of a given addressee to the given output stream. 
static const char version[]