diff options
Diffstat (limited to 'kpackage/packageInfo.cpp')
-rw-r--r-- | kpackage/packageInfo.cpp | 635 |
1 files changed, 635 insertions, 0 deletions
diff --git a/kpackage/packageInfo.cpp b/kpackage/packageInfo.cpp new file mode 100644 index 0000000..1e19afc --- /dev/null +++ b/kpackage/packageInfo.cpp @@ -0,0 +1,635 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +// Author: Damyan Pepper +// Author: Toivo Pedaste +*/ + +/* +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ + + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// Standard headers +#include <stdlib.h> + +#include <qregexp.h> +#include <qdir.h> +#include <ctype.h> + +// KDE headers +#include <kglobal.h> +#include <klocale.h> +#include <kdebug.h> + +// kpackage headers +#include "kpackage.h" +#include "kplview.h" +#include "packageInfo.h" +#include "pkgInterface.h" +#include "managementWidget.h" +#include "utils.h" +#include "options.h" + +// Global pixmap for +QPixmap *pict = NULL; + +////////////////////////////////////////////////////////////////////////////// +// Constructor -- get the pixmap +packageInfo::packageInfo(QMap<QString, QString> _info, pkgInterface *type) +{ + interface = type; + info = _info; + + item = NULL; + packageState = UNSET; + updated = FALSE; + url = QString::null; +} + +// Another constructor, for a packge with a url +packageInfo::packageInfo(QMap<QString, QString> _info, const QString &_url) +{ + info = _info; + url = _url; + item = NULL; +} + +packageInfo::~packageInfo() +{ +} + +// Return a property +QString packageInfo::getProperty(const QString &property) +{ + QString result = info[property]; + if (result.isEmpty()) { + return QString::null; + } + return result; +} + +// Check for existance of a property +bool packageInfo::hasProperty(const QString &property) +{ + QString s = info[property]; + if (s.isEmpty()) + return false; + else + return true; +} + +// Initialize fields if missing +void packageInfo::fixup() +{ + if (info["name"].isEmpty()) { + QString q; + q.setNum((long)this); + info.insert("name", q); + } + + if (info["group"].isEmpty()) { + info.insert("group", i18n("OTHER")); + kdDebug() << "Package " << info["name"] << " has no group set." << endl; + } + + if (!info["version"]) { + info.insert("version", ""); + } +} + +// Set the file name +void packageInfo::setFilename(const QString &f) +{ + url = f; +} + +// Get the url +QString packageInfo::getUrl() +{ + if (url.isEmpty()) { + if (hasProperty("base") && hasProperty("filename")) { + url = getProperty("base") + "/" + getProperty("filename"); + } + } + return url; +} + +QString packageInfo::fetchFilename() +{ + QString f = getFilename(); + + if (!f.isEmpty()) { + return f; + } else { + QString aurl = getUrl(); + if (!aurl.isEmpty()) { + return kpackage->fetchNetFile(aurl); + } else { + return getProperty("name"); + } + } +} + +bool packageInfo::isFileLocal() +{ + QString aurl = getUrl(); + if (!aurl.isEmpty()) { + return KPACKAGE::isFileLocal(aurl); + } + return false; +} + +bool packageInfo::isInstallable() +{ + if (packageState != packageInfo::INSTALLED && + !getProperty("filename").isNull() ) + return true; + else + return false; +} + +bool packageInfo::isFetchable() +{ + if (interface->noFetch || !getFilename().isEmpty() ) + return true; + else + return false; +} + +QString packageInfo::getFilename() +{ + QString cn = ""; + QString aurl = getUrl(); + if (!aurl.isEmpty()) { + return KPACKAGE::getFileName(aurl,cn); + } else { + return ""; + } +} + +int packageInfo::getDigElement(const QString &str, int *pos) + // Extract the next element from the string + // All digits +{ + QString s = str; + + if (*pos < 0) + return -1; + + s = s.mid(*pos); + if (s.isEmpty()) + return -1; + + QRegExp ndig("[^0-9]"); + + int nf = 0; + int val = 0; + + if ((s[0] >= '0') && (s[0] <= '9')) { + nf = s.find(ndig); + if (nf >= 0) { + val = s.left(nf).toInt(); + } else { + val = s.toInt(); + nf = s.length(); + } + } + + // printf("n=%s %d %d\n",s.mid(nf,999).data(),nf,val); + *pos += nf; + return val; +} + +QString packageInfo::getNdigElement(const QString &string, int *pos) + // Extract the next element from the string + // All all non-digits +{ + QString s(string); + + if (*pos < 0) + return QString::null; + + s = s.mid(*pos); + if (s.isEmpty()) + return QString::null; + + QString str; + int nf = 0; + + QRegExp idig("[0-9]"); + + if ((s[0] < '0') || (s[0] > '9') ) { + nf = s.find(idig); + if (nf < 0) + nf = s.length(); + str = s.left(nf); + for (unsigned int i = 0; i < str.length() ; i++) { + // Strange Debian package sorting magic + if (!str[i].isLetter()) { + char t = str[i].latin1(); + t += 128; + str[i] = t; + } + } + } + *pos += nf; + return str; +} + + +int packageInfo::pnewer(const QString &s, const QString &sp) +{ + int ns = 0, nsp = 0, vs, vsp; + + // kdDebug() << "S=" << s << " SP=" << sp << "\n"; + while (TRUE) { + vs = getDigElement(s,&ns); + vsp = getDigElement(sp,&nsp); + // kdDebug() << "s=" << ns << " " << vs << " sp=" << nsp << " " << vsp << "\n"; + if (vs < 0 && vsp < 0) + return 0; + if (vs < 0 && vsp < 0) + return 1; + if (vs < 0 && vsp < 0) + return -1; + if (vsp > vs) + return 1; + else if (vs > vsp) + return -1; + + QString svs = getNdigElement(s,&ns); + QString svsp = getNdigElement(sp,&nsp); + // kdDebug() << "vs=" << ns << " " << svs << " sp=" << nsp << " " << svsp << "\n"; + if (svs.isEmpty() && svsp.isEmpty()) + return 0; + if (svs.isEmpty() && !svsp.isEmpty()) + return 1; + if (!svs.isEmpty() && svsp.isEmpty()) + return -1; + + if (svsp.isNull()) { // Allow for QT strangeness comparing null string + svsp = ""; + } + if (svs.isNull()) { + svs = ""; + } + int n = svsp.compare(svs); + // kdDebug() << "svsp=" << svsp << "=" << svsp.length() << " svs=" << svs << "=" <<svs.length() << " n=" << n << "\n"; + if (n != 0) + return n; + } +} + +static bool split(QString orig, char seperator, QString &first, QString &second) +{ + int pos = orig.find(seperator); + if (pos > 0) { + first = orig.mid(0,pos); + second = orig.mid(pos+1); + return true; + } + return false; +} + +int packageInfo::newer(packageInfo *p) +{ + QString mySerial; // Serial number of this package + QString myVersion; // Version of this package + QString myRelease; // Release of this package + +// Version of this package + QString s = getProperty("version"); + + (void) split(s, ':', mySerial, s); + if (!split(s, '-', myVersion, myRelease)) + { + myVersion = s; + } + +// Version of other package + QString hisSerial; // Serial number of the other package + QString hisVersion; // Version of the other package + QString hisRelease; // Release of the other package + + s = p->getProperty("version"); + if (p->hasProperty("release")) { + s = s + "-" + p->getProperty("release"); + } + if (p->hasProperty("serial")) { + s = p->getProperty("serial") + ":" + s; + } + + (void) split(s, ':', hisSerial, s); + if (!split(s, '-', hisVersion, hisRelease)) + { + hisVersion = s; + } + + // kdDebug() << "mySerial=" << mySerial << " hisSerial=" << hisSerial <<"\n"; + // kdDebug() << "myVersion=" << myVersion << " hisVersion=" << hisVersion <<"\n"; + // kdDebug() << "myRelease=" << myRelease << " hisRelease=" << hisRelease <<"\n"; + + int n = pnewer(mySerial,hisSerial); + if (n) + return n; + else { + n = pnewer(myVersion,hisVersion); + if (n) + return n; + else + return pnewer(myRelease,hisRelease); + } +} + +bool packageInfo::display(int treeType) +{ + switch (treeType) { + case Opts::INSTALLED: + if (packageState == INSTALLED || packageState == BAD_INSTALL) + return TRUE; + break; + case Opts::UPDATED: + if (packageState == UPDATED) + return TRUE; + break; + case Opts::NEW: + if ((packageState == UPDATED) || (packageState == NEW)) + return TRUE; + break; + case Opts::ALL: + return TRUE; + break; + }; + return FALSE; +} + +////////////////////////////////////////////////////////////////////// +// Place the package in a QListView + +KpTreeListItem *packageInfo::place(KpTreeList *tree, bool insertI) +{ + KpTreeListItem *search = tree->firstChild(), *parent=NULL, *child=NULL; + QString qtmp, tmp; + bool doit = FALSE; + + doit = TRUE; + if (packageState == NOLIST || packageState == HIDDEN) + doit = FALSE; + + if (doit) { + qtmp = interface->head; + qtmp += "/"; + qtmp += getProperty("group"); + int cnt = 0; + + QStringList list = QStringList::split("/",qtmp); + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + KpTreeListItem *group; + + if( search && (group=findGroup(*it, search)) ) { + parent = group; + parent->setOpen(TRUE); + search = group->firstChild(); + } else { + if (parent) { + group = new KpTreeListItem(parent, 0, interface->folder, *it); + } else { + group = new KpTreeListItem(tree, 0, interface->folder, *it); + } + parent = group; + parent->setOpen(TRUE); + search = NULL; + } + cnt++; + } + + tmp = *info.find("name"); + + if(item) + delete item; + + QString sz = ""; + if (!info["size"].isEmpty()) { + sz = info["size"].stripWhiteSpace(); + if (sz.length() > 3) + sz.truncate(sz.length() - 3); + else + sz = "0"; + sz += "K"; + } else if (!info["file-size"].isEmpty()) { + sz = info["file-size"].stripWhiteSpace(); + if (sz.length() > 3) + sz.truncate(sz.length() - 3); + else + sz = "0"; + sz += "k"; + } + sz = sz.rightJustify(6,' '); + + QString ver = ""; + if (!info["version"].isEmpty()) { + ver = info["version"]; + } + + QString over = ""; + if (!info["old-version"].isEmpty()) { + over = info["old-version"]; + } + QString summary = ""; + if (!info["summary"].isEmpty()) { + summary = info["summary"]; + } + + + QPixmap pic; + if (packageState == BAD_INSTALL) { + pic = interface->bad_pict; + } else if (packageState == UPDATED) { + pic = interface->updated_pict; + } else if (packageState == NEW) { + pic = interface->new_pict; + } else if (packageState == INSTALLED) { + pic = interface->pict; + } else { + pic = interface->pict; + } + + if (child) { + item = new KpTreeListItem(child, this, pic, tmp, "", summary, sz, ver, over); + } else { + item = new KpTreeListItem(parent, this, pic, tmp, "", summary, sz, ver, over); + } + + if (insertI) { + parent->setOpen(TRUE); + } else { + parent->setOpen(FALSE); + } + + return item; + } else { + return 0; + } +} + +////////////////////////////////////////////////////////////////////// + +// Get the QListViewItem +KpTreeListItem *packageInfo::getItem() +{ + return item; +} + +////////////////////////////////////////////////////////////////////////////// +bool packageInfo::smerge( const QString &exp) { + + QDict<packageInfo> *dirInfoPackages = kpackage->management->dirInfoPackages; + QString pname = getProperty("name") + exp; + + packageInfo *pi = dirInfoPackages->find(pname); + if (pi) { + QMap<QString,QString>::Iterator it; + + for ( it = pi->info.begin(); it != pi->info.end(); ++it ) { + if (!(it.key() == "size" && !info["size"].isEmpty()) || + !(it.key() == "file-size" && !info["file-size"].isEmpty())) { + info.insert(it.key(), it.data()); + } + ++it; + } + return TRUE; + } + return FALSE; +} + +////////////////////////////////////////////////////////////////////////////// +void packageInfo::pkgFileIns(const QString &fileName) +{ + info.insert("filename", fileName); + info.insert("base", "/"); + + if (pkgInsert(kpackage->management->allPackages, interface->typeID, FALSE)) { + packageState = packageInfo::NEW; + place(kpackage->management->treeList,TRUE); + + QString pname = getProperty("name") + interface->typeID; + kpackage->management->dirUninstPackages->insert(pname,this); + } +} + +////////////////////////////////////////////////////////////////////////////// +bool packageInfo::pkgInsert(QPtrList<packageInfo> *pki, const QString &exp, + bool installed, bool infoPackage) +{ + QDict<packageInfo> *dirInstPackages = kpackage->management->dirInstPackages; + QDict<packageInfo> *dirUninstPackages = kpackage->management->dirUninstPackages; + QDict<packageInfo> *dirInfoPackages = kpackage->management->dirInfoPackages; + + QString pname = getProperty("name") + exp; + // printf("U1=%s\n",pname.data()); + + bool shouldUpdate = TRUE; + bool hidden = FALSE; + + packageInfo *pi = dirInstPackages->find(pname); + if (pi) { // installed version exists + if ((pi->packageState != BAD_INSTALL) + && (pi->packageState != NOLIST)) { + if (newer(pi) >= 0) { + hidden = TRUE; + } + } + } + + packageInfo *pu = dirUninstPackages->find(pname); + if (pu) { // available version exists + if ((pu->packageState != BAD_INSTALL) + && (pu->packageState != NOLIST)) { + if (newer(pu) >= 0) { + shouldUpdate = FALSE; + } else if (!installed) { // If older available package exists, remove it + dirUninstPackages->remove(*(pu->info.find("name"))); + pki->remove(pu); + } + } + } + + if (getProperty("version").isEmpty()) { + shouldUpdate = TRUE; + } + + if (shouldUpdate) { + if (packageState != BAD_INSTALL) { + if (installed) + packageState = INSTALLED; + else if (pi) { // installed version exists + if (hidden) { + packageState = HIDDEN; + } else { + QString version = pi->getProperty("version"); + if (version.isEmpty()) { + if (pi->packageState == NOLIST) + packageState = NEW; + else + packageState = UPDATED; + } else { + packageState = UPDATED; + if (pi->hasProperty("old-version")) { + info.insert("old-version", + pi->getProperty("old-version")); + } else { + info.insert("old-version",version); + } + QString group = getProperty("group"); + if (group == "NEW") { + if (pi->hasProperty("group")) { + info.replace("group", + pi->getProperty("group") ); + } + } + } + } + } else + packageState = NEW; + } + + pki->insert(0,this); + if (installed) { + if (infoPackage) + dirInfoPackages->insert(pname,this); + else + dirInstPackages->insert(pname,this); + } else + dirUninstPackages->insert(pname,this); + return TRUE; + } else { + return FALSE; + } +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + |