/* ** Copyright (C) 1999,2000 Toivo Pedaste ** // 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 #include #include #include // KDE headers #include #include #include // 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 TQPixmap *pict = NULL; ////////////////////////////////////////////////////////////////////////////// // Constructor -- get the pixmap packageInfo::packageInfo(TQMap _info, pkgInterface *type) { interface = type; info = _info; item = NULL; packageState = UNSET; updated = FALSE; url = TQString(); } // Another constructor, for a packge with a url packageInfo::packageInfo(TQMap _info, const TQString &_url) { info = _info; url = _url; item = NULL; } packageInfo::~packageInfo() { } // Return a property TQString packageInfo::getProperty(const TQString &property) { TQString result = info[property]; if (result.isEmpty()) { return TQString(); } return result; } // Check for existance of a property bool packageInfo::hasProperty(const TQString &property) { TQString s = info[property]; if (s.isEmpty()) return false; else return true; } // Initialize fields if missing void packageInfo::fixup() { if (info["name"].isEmpty()) { TQString 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 TQString &f) { url = f; } // Get the url TQString packageInfo::getUrl() { if (url.isEmpty()) { if (hasProperty("base") && hasProperty("filename")) { url = getProperty("base") + "/" + getProperty("filename"); } } return url; } TQString packageInfo::fetchFilename() { TQString f = getFilename(); if (!f.isEmpty()) { return f; } else { TQString aurl = getUrl(); if (!aurl.isEmpty()) { return kpackage->fetchNetFile(aurl); } else { return getProperty("name"); } } } bool packageInfo::isFileLocal() { TQString 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; } TQString packageInfo::getFilename() { TQString cn = ""; TQString aurl = getUrl(); if (!aurl.isEmpty()) { return KPACKAGE::getFileName(aurl,cn); } else { return ""; } } int packageInfo::getDigElement(const TQString &str, int *pos) // Extract the next element from the string // All digits { TQString s = str; if (*pos < 0) return -1; s = s.mid(*pos); if (s.isEmpty()) return -1; TQRegExp 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; } TQString packageInfo::getNdigElement(const TQString &string, int *pos) // Extract the next element from the string // All all non-digits { TQString s(string); if (*pos < 0) return TQString(); s = s.mid(*pos); if (s.isEmpty()) return TQString(); TQString str; int nf = 0; TQRegExp 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 TQString &s, const TQString &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; TQString svs = getNdigElement(s,&ns); TQString 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 << "=" < 0) { first = orig.mid(0,pos); second = orig.mid(pos+1); return true; } return false; } int packageInfo::newer(packageInfo *p) { TQString mySerial; // Serial number of this package TQString myVersion; // Version of this package TQString myRelease; // Release of this package // Version of this package TQString s = getProperty("version"); (void) split(s, ':', mySerial, s); if (!split(s, '-', myVersion, myRelease)) { myVersion = s; } // Version of other package TQString hisSerial; // Serial number of the other package TQString hisVersion; // Version of the other package TQString 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 TQListView KpTreeListItem *packageInfo::place(KpTreeList *tree, bool insertI) { KpTreeListItem *search = tree->firstChild(), *parent=NULL, *child=NULL; TQString 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; TQStringList list = TQStringList::split("/",qtmp); for ( TQStringList::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; TQString 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,' '); TQString ver = ""; if (!info["version"].isEmpty()) { ver = info["version"]; } TQString over = ""; if (!info["old-version"].isEmpty()) { over = info["old-version"]; } TQString summary = ""; if (!info["summary"].isEmpty()) { summary = info["summary"]; } TQPixmap 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 TQListViewItem KpTreeListItem *packageInfo::getItem() { return item; } ////////////////////////////////////////////////////////////////////////////// bool packageInfo::smerge( const TQString &exp) { TQDict *dirInfoPackages = kpackage->management->dirInfoPackages; TQString pname = getProperty("name") + exp; packageInfo *pi = dirInfoPackages->find(pname); if (pi) { TQMap::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 TQString &fileName) { info.insert("filename", fileName); info.insert("base", "/"); if (pkgInsert(kpackage->management->allPackages, interface->typeID, FALSE)) { packageState = packageInfo::NEW; place(kpackage->management->treeList,TRUE); TQString pname = getProperty("name") + interface->typeID; kpackage->management->dirUninstPackages->insert(pname,this); } } ////////////////////////////////////////////////////////////////////////////// bool packageInfo::pkgInsert(TQPtrList *pki, const TQString &exp, bool installed, bool infoPackage) { TQDict *dirInstPackages = kpackage->management->dirInstPackages; TQDict *dirUninstPackages = kpackage->management->dirUninstPackages; TQDict *dirInfoPackages = kpackage->management->dirInfoPackages; TQString 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 { TQString 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); } TQString 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; } } ////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////