KNewStuff
entryinternal.cpp
Go to the documentation of this file.
00001 /* 00002 This file is part of KNewStuff2. 00003 Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org> 00004 Copyright (c) 2003 - 2007 Josef Spillner <spillner@kde.org> 00005 Copyright (C) 2009 Frederik Gladhorn <gladhorn@kde.org> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Lesser General Public 00009 License as published by the Free Software Foundation; either 00010 version 2.1 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public 00018 License along with this library. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 #include "entryinternal.h" 00022 00023 #include <QtCore/QStringList> 00024 #include <QtGui/QImage> 00025 #include <kdebug.h> 00026 00027 #include "core/xmlloader.h" 00028 00029 #include <knewstuff3/entry_p.h> 00030 00031 00032 using namespace KNS3; 00033 00034 class EntryInternal::Private : public QSharedData 00035 { 00036 public: 00037 Private() 00038 : mReleaseDate(QDate::currentDate()) 00039 , mRating(0) 00040 , mDownloadCount(0) 00041 , mNumberFans(0) 00042 , mNumberKnowledgebaseEntries(0) 00043 , mStatus(Entry::Invalid) 00044 , mSource(EntryInternal::Online) 00045 {} 00046 00047 bool operator==(const Private& other) const 00048 { 00049 return mUniqueId == other.mUniqueId && mProviderId == other.mProviderId; 00050 } 00051 00052 QString mUniqueId; 00053 QString mName; 00054 KUrl mHomepage; 00055 QString mCategory; 00056 QString mLicense; 00057 QString mVersion; 00058 QDate mReleaseDate; 00059 00060 // Version and date if a newer version is found (updateable) 00061 QString mUpdateVersion; 00062 QDate mUpdateReleaseDate; 00063 00064 Author mAuthor; 00065 int mRating; 00066 int mDownloadCount; 00067 int mNumberFans; 00068 int mNumberKnowledgebaseEntries; 00069 QString mKnowledgebaseLink; 00070 QString mSummary; 00071 QString mChangelog; 00072 QString mPayload; 00073 QStringList mInstalledFiles; 00074 QString mProviderId; 00075 QStringList mUnInstalledFiles; 00076 QString mDonationLink; 00077 00078 QString mChecksum; 00079 QString mSignature; 00080 Entry::Status mStatus; 00081 EntryInternal::Source mSource; 00082 00083 QString mPreviewUrl[6]; 00084 QImage mPreviewImage[6]; 00085 00086 QList<EntryInternal::DownloadLinkInformation> mDownloadLinkInformationList; 00087 }; 00088 00089 EntryInternal::EntryInternal() 00090 : d(new Private) 00091 { 00092 } 00093 00094 EntryInternal::EntryInternal(const EntryInternal& other) 00095 : d(other.d) 00096 { 00097 } 00098 00099 EntryInternal& EntryInternal::operator=(const EntryInternal& other) 00100 { 00101 d = other.d; 00102 return *this; 00103 } 00104 00105 bool EntryInternal::operator<(const KNS3::EntryInternal& other) const 00106 { 00107 return d->mUniqueId < other.d->mUniqueId; 00108 } 00109 00110 bool EntryInternal::operator==(const KNS3::EntryInternal& other) const 00111 { 00112 return d->mUniqueId == other.d->mUniqueId && d->mProviderId == other.d->mProviderId; 00113 } 00114 00115 EntryInternal::~EntryInternal() 00116 { 00117 } 00118 00119 bool EntryInternal::isValid() const 00120 { 00121 return !d->mUniqueId.isEmpty(); 00122 } 00123 00124 QString EntryInternal::name() const 00125 { 00126 return d->mName; 00127 } 00128 00129 void EntryInternal::setName(const QString& name) 00130 { 00131 d->mName = name; 00132 } 00133 00134 QString EntryInternal::uniqueId() const 00135 { 00136 return d->mUniqueId; 00137 } 00138 00139 void EntryInternal::setUniqueId(const QString& id) 00140 { 00141 d->mUniqueId = id; 00142 } 00143 00144 QString EntryInternal::providerId() const 00145 { 00146 return d->mProviderId; 00147 } 00148 00149 void EntryInternal::setProviderId(const QString& id) 00150 { 00151 d->mProviderId = id; 00152 } 00153 00154 QString EntryInternal::category() const 00155 { 00156 return d->mCategory; 00157 } 00158 00159 void EntryInternal::setCategory(const QString& category) 00160 { 00161 d->mCategory = category; 00162 } 00163 00164 KUrl EntryInternal::homepage() const 00165 { 00166 return d->mHomepage; 00167 } 00168 00169 void EntryInternal::setHomepage(const KUrl& page) 00170 { 00171 d->mHomepage = page; 00172 } 00173 00174 Author EntryInternal::author() const 00175 { 00176 return d->mAuthor; 00177 } 00178 00179 void EntryInternal::setAuthor(const KNS3::Author& author) 00180 { 00181 d->mAuthor = author; 00182 } 00183 00184 QString EntryInternal::license() const 00185 { 00186 return d->mLicense; 00187 } 00188 00189 void EntryInternal::setLicense(const QString& license) 00190 { 00191 d->mLicense = license; 00192 } 00193 00194 QString EntryInternal::summary() const 00195 { 00196 return d->mSummary; 00197 } 00198 00199 void EntryInternal::setSummary(const QString& summary) 00200 { 00201 d->mSummary = summary; 00202 } 00203 00204 void EntryInternal::setChangelog(const QString& changelog) 00205 { 00206 d->mChangelog = changelog; 00207 } 00208 00209 QString EntryInternal::changelog() const 00210 { 00211 return d->mChangelog; 00212 } 00213 00214 QString EntryInternal::version() const 00215 { 00216 return d->mVersion; 00217 } 00218 00219 void EntryInternal::setVersion(const QString& version) 00220 { 00221 d->mVersion = version; 00222 } 00223 00224 QDate EntryInternal::releaseDate() const 00225 { 00226 return d->mReleaseDate; 00227 } 00228 00229 void EntryInternal::setReleaseDate(const QDate& releasedate) 00230 { 00231 d->mReleaseDate = releasedate; 00232 } 00233 00234 QString EntryInternal::payload() const 00235 { 00236 return d->mPayload; 00237 } 00238 00239 void EntryInternal::setPayload(const QString& url) 00240 { 00241 d->mPayload = url; 00242 } 00243 00244 QDate EntryInternal::updateReleaseDate() const 00245 { 00246 return d->mUpdateReleaseDate; 00247 } 00248 00249 void EntryInternal::setUpdateReleaseDate(const QDate& releasedate) 00250 { 00251 d->mUpdateReleaseDate = releasedate; 00252 } 00253 00254 QString EntryInternal::updateVersion() const 00255 { 00256 return d->mUpdateVersion; 00257 } 00258 00259 void EntryInternal::setUpdateVersion(const QString& version) 00260 { 00261 d->mUpdateVersion = version; 00262 } 00263 00264 QString EntryInternal::previewUrl(PreviewType type) const 00265 { 00266 return d->mPreviewUrl[type]; 00267 } 00268 00269 void EntryInternal::setPreviewUrl(const QString& url, PreviewType type) 00270 { 00271 d->mPreviewUrl[type] = url; 00272 } 00273 00274 QImage EntryInternal::previewImage(PreviewType type) const 00275 { 00276 return d->mPreviewImage[type]; 00277 } 00278 00279 void EntryInternal::setPreviewImage(const QImage& image, PreviewType type) 00280 { 00281 d->mPreviewImage[type] = image; 00282 } 00283 00284 int EntryInternal::rating() const 00285 { 00286 return d->mRating; 00287 } 00288 00289 void EntryInternal::setRating(int rating) 00290 { 00291 d->mRating = rating; 00292 } 00293 00294 int EntryInternal::downloadCount() const 00295 { 00296 return d->mDownloadCount; 00297 } 00298 00299 void EntryInternal::setDownloadCount(int downloads) 00300 { 00301 d->mDownloadCount = downloads; 00302 } 00303 00304 int EntryInternal::numberFans() const 00305 { 00306 return d->mNumberFans; 00307 } 00308 00309 void EntryInternal::setNumberFans(int fans) 00310 { 00311 d->mNumberFans = fans; 00312 } 00313 00314 QString EntryInternal::donationLink() const 00315 { 00316 return d->mDonationLink; 00317 } 00318 00319 void EntryInternal::setDonationLink(const QString& link) 00320 { 00321 d->mDonationLink = link; 00322 } 00323 00324 int EntryInternal::numberKnowledgebaseEntries() const 00325 { 00326 return d->mNumberKnowledgebaseEntries; 00327 } 00328 void EntryInternal::setNumberKnowledgebaseEntries(int num) 00329 { 00330 d->mNumberKnowledgebaseEntries = num; 00331 } 00332 00333 QString EntryInternal::knowledgebaseLink() const 00334 { 00335 return d->mKnowledgebaseLink; 00336 } 00337 void EntryInternal::setKnowledgebaseLink(const QString& link) 00338 { 00339 d->mKnowledgebaseLink = link; 00340 } 00341 00342 00343 /* 00344 QString EntryInternal::checksum() const 00345 { 00346 00347 return d->mChecksum; 00348 } 00349 00350 QString EntryInternal::signature() const 00351 { 00352 00353 return d->mSignature; 00354 } 00355 */ 00356 00357 EntryInternal::Source EntryInternal::source() const 00358 { 00359 return d->mSource; 00360 } 00361 00362 void EntryInternal::setSource(Source source) 00363 { 00364 d->mSource = source; 00365 } 00366 00367 Entry::Status EntryInternal::status() const 00368 { 00369 return d->mStatus; 00370 } 00371 00372 void EntryInternal::setStatus(Entry::Status status) 00373 { 00374 d->mStatus = status; 00375 } 00376 00377 void KNS3::EntryInternal::setInstalledFiles(const QStringList & files) 00378 { 00379 d->mInstalledFiles = files; 00380 } 00381 00382 QStringList KNS3::EntryInternal::installedFiles() const 00383 { 00384 return d->mInstalledFiles; 00385 } 00386 00387 void KNS3::EntryInternal::setUnInstalledFiles(const QStringList & files) 00388 { 00389 d->mUnInstalledFiles = files; 00390 } 00391 00392 QStringList KNS3::EntryInternal::uninstalledFiles() const 00393 { 00394 return d->mUnInstalledFiles; 00395 } 00396 00397 int KNS3::EntryInternal::downloadLinkCount() const 00398 { 00399 return d->mDownloadLinkInformationList.size(); 00400 } 00401 00402 QList<KNS3::EntryInternal::DownloadLinkInformation> KNS3::EntryInternal::downloadLinkInformationList() const 00403 { 00404 return d->mDownloadLinkInformationList; 00405 } 00406 00407 void KNS3::EntryInternal::appendDownloadLinkInformation(const KNS3::EntryInternal::DownloadLinkInformation& info) 00408 { 00409 d->mDownloadLinkInformationList.append(info); 00410 } 00411 00412 void EntryInternal::clearDownloadLinkInformation() 00413 { 00414 d->mDownloadLinkInformationList.clear(); 00415 } 00416 00417 bool KNS3::EntryInternal::setEntryXML(const QDomElement & xmldata) 00418 { 00419 if (xmldata.tagName() != "stuff") { 00420 kWarning() << "Parsing Entry from invalid XML"; 00421 return false; 00422 } 00423 00424 d->mCategory = xmldata.attribute("category"); 00425 00426 QDomNode n; 00427 for (n = xmldata.firstChild(); !n.isNull(); n = n.nextSibling()) { 00428 QDomElement e = n.toElement(); 00429 if (e.tagName() == "name") { 00430 // TODO maybe do something with the language attribute? QString lang = e.attribute("lang"); 00431 d->mName = e.text().trimmed(); 00432 } else if (e.tagName() == "author") { 00433 QString email = e.attribute("email"); 00434 QString jabber = e.attribute("im"); 00435 QString homepage = e.attribute("homepage"); 00436 d->mAuthor.setName(e.text().trimmed()); 00437 d->mAuthor.setEmail(email); 00438 d->mAuthor.setJabber(jabber); 00439 d->mAuthor.setHomepage(homepage); 00440 } else if (e.tagName() == "providerid") { 00441 d->mProviderId = e.text(); 00442 } else if (e.tagName() == "homepage") { 00443 d->mHomepage = e.text(); 00444 } else if (e.tagName() == "licence") { // krazy:exclude=spelling 00445 d->mLicense = e.text().trimmed(); 00446 } else if (e.tagName() == "summary") { 00447 d->mSummary = e.text(); 00448 } else if (e.tagName() == "changelog") { 00449 d->mChangelog = e.text(); 00450 } else if (e.tagName() == "version") { 00451 d->mVersion = e.text().trimmed(); 00452 } else if (e.tagName() == "releasedate") { 00453 d->mReleaseDate = QDate::fromString(e.text().trimmed(), Qt::ISODate); 00454 } else if (e.tagName() == "preview") { 00455 // TODO support for all 6 image links 00456 d->mPreviewUrl[PreviewSmall1] = e.text().trimmed(); 00457 } else if (e.tagName() == "previewBig") { 00458 d->mPreviewUrl[PreviewBig1] = e.text().trimmed(); 00459 } else if (e.tagName() == "payload") { 00460 d->mPayload = e.text().trimmed(); 00461 } else if (e.tagName() == "rating") { 00462 d->mRating = e.text().toInt(); 00463 } else if (e.tagName() == "downloads") { 00464 d->mDownloadCount = e.text().toInt(); 00465 } else if (e.tagName() == "category") { 00466 d->mCategory = e.text(); 00467 } else if (e.tagName() == "signature") { 00468 d->mSignature = e.text(); 00469 } else if (e.tagName() == "checksum") { 00470 d->mChecksum = e.text(); 00471 } else if (e.tagName() == "installedfile") { 00472 d->mInstalledFiles.append(e.text()); 00473 } else if (e.tagName() == "id") { 00474 d->mUniqueId = e.text(); 00475 } else if (e.tagName() == "status") { 00476 QString statusText = e.text(); 00477 if (statusText == "installed") { 00478 kDebug() << "Found an installed entry in registry"; 00479 d->mStatus = Entry::Installed; 00480 } else if (statusText == "updateable") { 00481 d->mStatus = Entry::Updateable; 00482 } 00483 } 00484 } 00485 00486 // Validation 00487 if (d->mName.isEmpty()) { 00488 kWarning(550) << "Entry: no name given"; 00489 return false; 00490 } 00491 00492 if (d->mUniqueId.isEmpty()) { 00493 if (!d->mPayload.isEmpty()) { 00494 d->mUniqueId = d->mPayload; 00495 } else { 00496 d->mUniqueId = d->mName; 00497 } 00498 } 00499 00500 if (d->mPayload.isEmpty()) { 00501 kWarning(550) << "Entry: no payload URL given for: " << d->mName << " - " << d->mUniqueId; 00502 return false; 00503 } 00504 return true; 00505 } 00506 00510 QDomElement KNS3::EntryInternal::entryXML() const 00511 { 00512 Q_ASSERT(!d->mUniqueId.isEmpty()); 00513 Q_ASSERT(!d->mProviderId.isEmpty()); 00514 00515 QDomDocument doc; 00516 00517 QDomElement el = doc.createElement("stuff"); 00518 el.setAttribute("category", d->mCategory); 00519 00520 QString name = d->mName; 00521 00522 QDomElement e; 00523 e = addElement(doc, el, "name", name); 00524 // todo: add language attribute 00525 (void)addElement(doc, el, "providerid", d->mProviderId); 00526 00527 QDomElement author = addElement(doc, el, "author", d->mAuthor.name()); 00528 if (!d->mAuthor.email().isEmpty()) 00529 author.setAttribute("email", d->mAuthor.email()); 00530 if (!d->mAuthor.homepage().isEmpty()) 00531 author.setAttribute("homepage", d->mAuthor.homepage()); 00532 if (!d->mAuthor.jabber().isEmpty()) 00533 author.setAttribute("im", d->mAuthor.jabber()); 00534 // FIXME: 'jabber' or 'im'? consult with kopete guys... 00535 addElement(doc, el, "homepage", d->mHomepage.url()); 00536 (void)addElement(doc, el, "licence", d->mLicense); // krazy:exclude=spelling 00537 (void)addElement(doc, el, "version", d->mVersion); 00538 if ((d->mRating > 0) || (d->mDownloadCount > 0)) { 00539 (void)addElement(doc, el, "rating", QString::number(d->mRating)); 00540 (void)addElement(doc, el, "downloads", QString::number(d->mDownloadCount)); 00541 } 00542 if (!d->mSignature.isEmpty()) { 00543 (void)addElement(doc, el, "signature", d->mSignature); 00544 } 00545 if (!d->mChecksum.isEmpty()) { 00546 (void)addElement(doc, el, "checksum", d->mChecksum); 00547 } 00548 foreach(const QString &file, d->mInstalledFiles) { 00549 (void)addElement(doc, el, "installedfile", file); 00550 } 00551 if (!d->mUniqueId.isEmpty()) { 00552 addElement(doc, el, "id", d->mUniqueId); 00553 } 00554 00555 (void)addElement(doc, el, "releasedate", 00556 d->mReleaseDate.toString(Qt::ISODate)); 00557 00558 e = addElement(doc, el, "summary", d->mSummary); 00559 e = addElement(doc, el, "changelog", d->mChangelog); 00560 e = addElement(doc, el, "preview", d->mPreviewUrl[PreviewSmall1]); 00561 e = addElement(doc, el, "previewBig", d->mPreviewUrl[PreviewBig1]); 00562 e = addElement(doc, el, "payload", d->mPayload); 00563 00564 if (d->mStatus == Entry::Installed) { 00565 (void)addElement(doc, el, "status", "installed"); 00566 } 00567 if (d->mStatus == Entry::Updateable) { 00568 (void)addElement(doc, el, "status", "updateable"); 00569 } 00570 00571 return el; 00572 } 00573 00574 Entry EntryInternal::toEntry() const 00575 { 00576 Entry e; 00577 e.d->e = *this; 00578 return e; 00579 } 00580 00581 KNS3::EntryInternal EntryInternal::fromEntry(const KNS3::Entry& entry) 00582 { 00583 return entry.d->e; 00584 } 00585 00586 QString KNS3::replaceBBCode(const QString& unformattedText) 00587 { 00588 QString text(unformattedText); 00589 text.replace("[b]", "<b>"); 00590 text.replace("[/b]", "</b>"); 00591 text.replace("[i]", "<i>"); 00592 text.replace("[/i]", "</i>"); 00593 text.replace("[u]", "<i>"); 00594 text.replace("[/u]", "</i>"); 00595 text.replace("\\\"", "\""); 00596 text.replace("\\\'", "\'"); 00597 text.replace("[li]", "* "); // TODO: better replacement for list elements? 00598 text.remove("[/li]"); 00599 text.remove("[url]"); 00600 text.remove("[/url]"); 00601 return text; 00602 }
KDE 4.6 API Reference