console/kabcclient
inputformatimpls.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "inputformatimpls.h"
00021 #include "csvtemplate.h"
00022 #include "csvtemplatefactory.h"
00023
00024
00025 #include <iostream>
00026 #include <string>
00027
00028
00029 #include <QtCore/QTextCodec>
00030
00031
00032 #include <klocale.h>
00033
00034
00035 #include <kabc/addressee.h>
00036 #include <kabc/addresseedialog.h>
00037 #include <kabc/addresseelist.h>
00038 #include <kabc/vcardconverter.h>
00039
00040 using namespace KABC;
00041
00043
00044 QString UIDInput::description() const
00045 {
00046 return i18n("Interprets input as a unique KABC contact identifier");
00047 }
00048
00050
00051 bool UIDInput::setOptions(const QByteArray& options)
00052 {
00053 Q_UNUSED(options)
00054 return false;
00055 }
00056
00058
00059 bool UIDInput::setCodec(QTextCodec* codec)
00060 {
00061 if (codec == 0) return false;
00062
00063 m_codec = codec;
00064
00065 return true;
00066 }
00067
00069
00070 KABC::Addressee UIDInput::readAddressee(std::istream& stream)
00071 {
00072 if (stream.bad()) return KABC::Addressee();
00073
00074 KABC::Addressee addressee;
00075
00076 std::string line;
00077 getline(stream, line);
00078 while (line.empty() && !stream.eof())
00079 {
00080 getline(stream, line);
00081 }
00082
00083 if (stream.eof()) return addressee;
00084
00085 QString uid = m_codec->toUnicode(line.c_str(), line.size());
00086
00087 addressee.setUid(uid);
00088
00089 return addressee;
00090 }
00091
00094
00095 VCardInput::VCardInput() : m_converter(0)
00096 {
00097 m_converter = new VCardConverter();
00098 }
00099
00101
00102 QString VCardInput::description() const
00103 {
00104 return i18n("Interprets input as VCard data");
00105 }
00106
00108
00109 VCardInput::~VCardInput()
00110 {
00111 delete m_converter;
00112 }
00113
00115
00116 bool VCardInput::setOptions(const QByteArray& options)
00117 {
00118 Q_UNUSED(options)
00119 return false;
00120 }
00121
00123
00124 bool VCardInput::setCodec(QTextCodec* codec)
00125 {
00126 if (codec == 0) return false;
00127
00128 m_codec = codec;
00129
00130 QString codecName = QString::fromAscii(m_codec->name());
00131
00132 if (codecName != QString::fromUtf8("UTF-8"))
00133 {
00134 QString warning = i18n("Warning: using codec '%1' with input format vcard, "
00135 "but vCards are usually expected to be in UTF-8.",
00136 codecName);
00137
00138 std::cerr << warning.toLocal8Bit().data() << std::endl;
00139 }
00140
00141 return true;
00142 }
00143
00145
00146 KABC::Addressee VCardInput::readAddressee(std::istream& stream)
00147 {
00148 if (stream.bad()) return KABC::Addressee();
00149
00150 std::string line;
00151
00152 while (line.empty() && !stream.eof())
00153 {
00154 getline(stream, line);
00155 }
00156 if (line.empty()) return KABC::Addressee();
00157
00158 QString input = m_codec->toUnicode(line.c_str(), line.size());
00159 input += '\n';
00160
00161 QString inputLine;
00162 while (!inputLine.isEmpty() || !stream.eof())
00163 {
00164 getline(stream, line);
00165 inputLine = m_codec->toUnicode(line.c_str(), line.size());
00166
00167 input += inputLine;
00168 input += '\n';
00169 if (inputLine.startsWith("END:VCARD")) break;
00170 }
00171
00172 return m_converter->parseVCard(input.toUtf8());
00173 }
00174
00177
00178 QString EmailInput::description() const
00179 {
00180 return i18n("Interprets input as email and optional name");
00181 }
00182
00184
00185 bool EmailInput::setOptions(const QByteArray& options)
00186 {
00187 Q_UNUSED(options)
00188 return false;
00189 }
00190
00192
00193 bool EmailInput::setCodec(QTextCodec* codec)
00194 {
00195 if (codec == 0) return false;
00196
00197 m_codec = codec;
00198
00199 return true;
00200 }
00201
00203
00204 KABC::Addressee EmailInput::readAddressee(std::istream& stream)
00205 {
00206 if (stream.bad()) return KABC::Addressee();
00207
00208 KABC::Addressee addressee;
00209
00210 std::string line;
00211 getline(stream, line);
00212 while (line.empty() && !stream.eof())
00213 {
00214 getline(stream, line);
00215 }
00216
00217 if (stream.eof()) return addressee;
00218
00219 QString rawEmail = m_codec->toUnicode(line.c_str(), line.size());
00220 QString name;
00221 QString email;
00222 KABC::Addressee::parseEmailAddress(rawEmail, name, email);
00223
00224 if (!email.isEmpty() && email.indexOf("@") != -1)
00225 {
00226 addressee.insertEmail(email, true);
00227
00228 if (!name.isEmpty())
00229 {
00230 addressee.setNameFromString(name);
00231 }
00232
00233 addressee.setUid(QString());
00234 }
00235
00236 return addressee;
00237 }
00238
00241
00242 QString SearchInput::description() const
00243 {
00244 return i18n("Tries to get email and name from input,\n\t\t"
00245 "otherwise sets input text for both");
00246 }
00247
00249
00250 bool SearchInput::setOptions(const QByteArray& options)
00251 {
00252 Q_UNUSED(options)
00253 return false;
00254 }
00255
00257
00258 bool SearchInput::setCodec(QTextCodec* codec)
00259 {
00260 if (codec == 0) return false;
00261
00262 m_codec = codec;
00263
00264 return true;
00265 }
00266
00268
00269 KABC::Addressee SearchInput::readAddressee(std::istream& stream)
00270 {
00271 if (stream.bad()) return KABC::Addressee();
00272
00273 KABC::Addressee addressee;
00274
00275 std::string line;
00276 getline(stream, line);
00277 while (line.empty() && !stream.eof())
00278 {
00279 getline(stream, line);
00280 }
00281
00282 if (stream.eof()) return addressee;
00283
00284 QString rawEmail = m_codec->toUnicode(line.c_str(), line.size());
00285 QString name;
00286 QString email;
00287 KABC::Addressee::parseEmailAddress(rawEmail, name, email);
00288
00289 if (email.isEmpty() || email.indexOf("@") == -1)
00290 {
00291 addressee.insertEmail(rawEmail, true);
00292 }
00293 else
00294 {
00295 addressee.insertEmail(email, true);
00296 }
00297
00298 if (!name.isEmpty())
00299 {
00300 addressee.setNameFromString(name);
00301 }
00302 else
00303 {
00304 addressee.setNameFromString(rawEmail);
00305 }
00306
00307 addressee.setUid(QString());
00308
00309 return addressee;
00310 }
00311
00314
00315 QString NameInput::description() const
00316 {
00317 return i18n("Interprets the input as a name.\n\t\t"
00318 "Recommended format is 'lastname, firstname middlename'");
00319 }
00320
00322
00323 bool NameInput::setOptions(const QByteArray& options)
00324 {
00325 Q_UNUSED(options)
00326 return false;
00327 }
00328
00330
00331 bool NameInput::setCodec(QTextCodec* codec)
00332 {
00333 if (codec == 0) return false;
00334
00335 m_codec = codec;
00336
00337 return true;
00338 }
00339
00341
00342 KABC::Addressee NameInput::readAddressee(std::istream& stream)
00343 {
00344 if (stream.bad()) return KABC::Addressee();
00345
00346 KABC::Addressee addressee;
00347
00348 std::string line;
00349 getline(stream, line);
00350 while (line.empty() && !stream.eof())
00351 {
00352 getline(stream, line);
00353 }
00354
00355 if (stream.eof()) return addressee;
00356
00357 QString name = m_codec->toUnicode(line.c_str(), line.size());
00358
00359 if (!name.isEmpty())
00360 {
00361 addressee.setNameFromString(name);
00362 }
00363
00364 addressee.setUid(QString());
00365
00366 return addressee;
00367 }
00368
00371
00372 CSVInput::CSVInput(CSVTemplateFactory* templateFactory)
00373 : m_codec(0), m_template(0), m_templateFactory(templateFactory)
00374 {
00375 }
00376
00378
00379 QString CSVInput::description() const
00380 {
00381 return i18n("Interprets the input as a delimiter separated list of fields.");
00382 }
00383
00385
00386 bool CSVInput::setOptions(const QByteArray& options)
00387 {
00388 QString name = QString::fromLocal8Bit(options);
00389 if (name.isEmpty()) return false;
00390
00391 m_template = m_templateFactory->createCachedTemplate(name);
00392
00393 return m_template != 0;
00394 }
00395
00397
00398 QString CSVInput::optionUsage() const
00399 {
00400 QString usage =
00401 i18n("Specify one of the following CSV templates:");
00402
00403 usage += '\n';
00404
00405 const QMap<QString, QString> templateNames = m_templateFactory->templateNames();
00406
00407 QMap<QString, QString>::const_iterator it = templateNames.begin();
00408 QMap<QString, QString>::const_iterator endIt = templateNames.end();
00409 for (; it != endIt; ++it)
00410 {
00411 QString name = it.key();
00412 QString templateName = it.value();
00413
00414 usage += name;
00415
00416 usage += name.length() < 8 ? "\t\t" : "\t";
00417
00418 usage += templateName;
00419
00420 usage += '\n';
00421 }
00422
00423 return usage;
00424 }
00425
00427
00428 bool CSVInput::setCodec(QTextCodec* codec)
00429 {
00430 if (codec == 0) return false;
00431
00432 m_codec = codec;
00433
00434 return true;
00435 }
00436
00438
00439 KABC::Addressee CSVInput::readAddressee(std::istream& stream)
00440 {
00441 if (stream.bad()) return KABC::Addressee();
00442
00443 if (m_template == 0) m_template = CSVTemplate::defaultTemplate();
00444
00445 KABC::Addressee addressee;
00446
00447 std::string line;
00448 getline(stream, line);
00449 while (line.empty() && !stream.eof())
00450 {
00451 getline(stream, line);
00452 }
00453
00454 if (stream.eof()) return addressee;
00455
00456 QString values = m_codec->toUnicode(line.c_str(), line.size());
00457
00458 if (!values.isEmpty())
00459 {
00460 QStringList list = split(values);
00461
00462 QStringList::const_iterator it = list.begin();
00463 QStringList::const_iterator endIt = list.end();
00464 for (int i = 0; it != endIt; ++it, ++i)
00465 {
00466 m_template->setFieldText(i, addressee, *it);
00467 }
00468 }
00469
00470 return addressee;
00471 }
00472
00474
00475 QStringList CSVInput::split(const QString& values) const
00476 {
00477 const QString quote = m_template->quote();
00478 const QString delimiter = m_template->delimiter();
00479
00480 if (quote.isEmpty()) return values.split(delimiter, QString::KeepEmptyParts);
00481
00482 QString remaining = values;
00483
00484 QStringList list;
00485 bool quoted = false;
00486 while (!remaining.isEmpty())
00487 {
00488 if (quoted)
00489 {
00490 int quoteIndex = remaining.indexOf(quote);
00491 if (quoteIndex >= 0)
00492 {
00493 list.append(remaining.left(quoteIndex));
00494 remaining = remaining.mid(quoteIndex + quote.length());
00495
00496 if (remaining.indexOf(delimiter) == 0)
00497 {
00498 remaining = remaining.mid(delimiter.length());
00499 }
00500 }
00501 else
00502 {
00503 list.append(remaining);
00504 remaining.clear();
00505 }
00506
00507 quoted = false;
00508 }
00509 else
00510 {
00511 int quoteIndex = remaining.indexOf(quote);
00512
00513 if (quoteIndex == 0)
00514 {
00515 quoted = true;
00516
00517 remaining = remaining.mid(quote.length());
00518 }
00519 else
00520 {
00521 int delimiterIndex = remaining.indexOf(delimiter);
00522 if (delimiterIndex >= 0)
00523 {
00524 list.append(remaining.left(delimiterIndex));
00525 remaining = remaining.mid(delimiterIndex + delimiter.length());
00526 }
00527 else
00528 {
00529 list.append(remaining);
00530 remaining.clear();
00531 }
00532 }
00533 }
00534 }
00535
00536 return list;
00537 }
00538
00541
00542 class DialogInputPrivate
00543 {
00544 public:
00545 DialogInputPrivate() : showDialog(true) {}
00546
00547 public:
00548 bool showDialog;
00549 KABC::AddresseeList addresseeList;
00550 };
00551
00553
00554 DialogInput::DialogInput() : m_private(new DialogInputPrivate())
00555 {
00556 }
00557
00559
00560 DialogInput::~DialogInput()
00561 {
00562 delete m_private;
00563 }
00564
00566
00567 QString DialogInput::description() const
00568 {
00569 return i18n("Select contacts in a dialog instead of reading input text");
00570 }
00571
00573
00574 bool DialogInput::setOptions(const QByteArray& options)
00575 {
00576 Q_UNUSED(options)
00577 return false;
00578 }
00579
00581
00582 bool DialogInput::setCodec(QTextCodec* codec)
00583 {
00584 if (codec == 0) return false;
00585
00586 return true;
00587 }
00588
00590
00591 KABC::Addressee DialogInput::readAddressee(std::istream& stream)
00592 {
00593 KABC::Addressee addressee;
00594
00595
00596 if (m_private->showDialog)
00597 {
00598 m_private->addresseeList = KABC::AddresseeDialog::getAddressees(0);
00599 m_private->showDialog = false;
00600 }
00601
00602
00603
00604
00605 if (!m_private->addresseeList.isEmpty())
00606 {
00607 KABC::Addressee nextAddressee = m_private->addresseeList.front();
00608
00609
00610 if (!nextAddressee.isEmpty()) addressee.setUid(nextAddressee.uid());
00611
00612 m_private->addresseeList.pop_front();
00613 }
00614 else
00615 stream.setstate(std::ios_base::eofbit);
00616
00617 return addressee;
00618 }
00619
00620