diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 37333bf25ad9a4c538250f5af2f9f1d666362883 (patch) | |
tree | c45e8df5b9efbffe07eb3d9340df7811c7e16943 /kpackage | |
download | tdeadmin-37333bf25ad9a4c538250f5af2f9f1d666362883.tar.gz tdeadmin-37333bf25ad9a4c538250f5af2f9f1d666362883.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeadmin@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kpackage')
92 files changed, 15463 insertions, 0 deletions
diff --git a/kpackage/CHANGES b/kpackage/CHANGES new file mode 100644 index 0000000..e9a8fb2 --- /dev/null +++ b/kpackage/CHANGES @@ -0,0 +1,282 @@ +kpackage-3.5 +------------ +Rewrite kpPty.cpp, now prompt for passwords +Fix reading and writing APT sources.list +Allow using sudo for priveleged commands +Add allow-unathenticated option for debian apt +Change package info to use QMap +Convert bsd package handling to remove procbuf + +kpackage-3.0 +------------ +RPM will now prompt for root password if not root +Integrate package type panel +Fix up Debian Remote Host stuff and add GUI +Strip surrounding spaces from search stings +Add wait cursor for find file +Fix slackware install Divide by Zero <divide@priv.onet.pl> + +kpackage-2.1 +------------ +New popup for installing/uninstalling with list of + packages and integrated terminal window +Use PTY's for talking to programs +Debain APT handling (unfinished) +RPM 4 support - bero +Add options panel for which package handlers to use +Option for using either ssh or su for calling privileged programs +add --remote option +Ignore Debian packages with only conf-files installed + +kpackage-2.0 +------------ +Only QT2/KDE2 +Only RPM3 +Replace multiple select mode with Shift and + Control left-mouse-buttone +Use HTML widget for package properties display +Links for pointing to dependency packages +Debian distribution site handling +Change toolbar to use XML config, add "configure toolbar" option +Use tab bar for selecting package display +Don't write empty entries to config file +Add subdirs Matthias Mohr <MMohr@SysDesign-EDV.de> + +kpackage-1.3.10 +--------------- +Use "rpm --version" for finding RPM version in configure +Fix for RPM 3.0.3 and 2.5 + +kpackage-1.3.9.2 +---------------- +Fixes for compiling with g++ 2.95.2 + +kpackage-1.3.9.1 +---------------- +Fix installing docs with some versions of RPM +Fix RPM nodeps uninstall flag - Torsten Klein <berlinux@gmx.net> +Add some null pointer checks - Ilya Stepanov <ilya@tranzit.donetsk.ua> + +kpackage-1.3.9 +-------------- +Add configure option to force RPM compile +Fix rpm compile for debian potato +Fix kiss and kpkg not found error message on find file +Czech translation update - Miroslav Flidr <flidr@kky.zcu.cz> + +kpackage-1.3.8.1 +---------------- +Fix getuid() check for rpm error messages +Update Romanian translations - Claudiu Costin <claudiuc@calderon.pcnet.ro> + +kpackage-1.3.8 +-------------- +Fix misidentification of package type + +kpackage-1.3.7 +-------------- +Full handling of KISS packages +Korean stuff in kpackage.spec - KIM KyungHeon <tody@tody.sarang.net> +More Romanian translations and i18n fixes - Claudiu Costin <claudiuc@calderon.pcnet.ro> + +kpackage-1.3.6 +-------------- +Romanian translations - Claudiu Costin <claudiuc@calderon.pcnet.ro> + +kpackage-1.3.5 +-------------- +Compile with RPM 3.0, 3.0.1, and the latest 3.0.2 + +kpackage-1.3.4 +-------------- +Compile with RPM 3.0.2 + +kpackage-1.3.3 +------------- +Polish translation +Warning about requiring popt package + +kpackage-1.3.2 +------------- +Fix upgrade flag with RPM +Fix "need root" error messages with rpm +Fix installing index-4.html + +kpackage-1.3.1 +------------- +Another try at finding a define that distinguishes rpm3.0 + +kpackage-1.3 +------------ +FreeBSD package support - Alex Hayward <xelah@ferret.lmh.ox.ac.uk> +Work with QT2 and latest KDE CVS +Work with RPM3.0 +Work with glibc2.1 +RPM 3.0 fixes - prigaux@mandrakesoft.com +Fix rpm verify error messages +Fix changing package when file selected + +kpackage-1.2.1 +-------------- +Fix dependency checking problem for uninstalling RPM packages + +kpackage-1.2 +------------ +Use KAccelMenu class to simplify configuring + accelerators and allow accelerators to be set by typing the + key when the menu item is selected. The ' character is needed + to precede the keys. (with post KDE1.1 libraries) +Add a Keys diaglog as another way of setting + accelerators(with post KDE1.1 libraries) +Add handling of KISS packages +Add handling of SLACKWARE packages +Move common functionality for package types into base class +Replace QString mid with right where appropriate +Set filter on KFileDialog properly +Clean up procbuf class +Compiles with QT2.0 (even works in parts) + +kpackage-1.1.3 +-------------- +Give Icons transparent backgrounds (cooper font) +Russian tranlation update - Serguei Koubouchine <ksi@ksi-linux.com> +Danish translation - Steen Rabol <rabol@get2net.dk> +Building update - Stefan Siegel <siegel@informatik.uni-kl.de> + +kpackage-1.1.2 +-------------- +Fix duplicated folder problem +Fix installing English documentation + +kpackage-1.1.1 +-------------- +Display file size in package tree if don't have installed size +Update config to refer to qt 1.4 +Handle RPM serial version number, DEB num: +fix show tool bar menu item +Hungarian translations + +kpackage-1.1.01 +--------------- +Try to fix compile problem with old gcc + +kpackage-1.1 +------------ +Requires QT 1.4 +Use QTreeView, much faster, allows columns, shows version info +Add multiple selection mode for installing and uninstalling + mulitiple packages at the same time +Speed up list inserting significantly by not doing "insort" +Speed up exiting by not deleting objects +Menu items for expanding and collapsing package tree +Menu item for clearing selections +Remove quit from tool bar +Fix for rpmlib 2.5, use supplied rpmlib.h +Fix specifying a file in panel for reading directories +Fix clearing directory cache with directories changed +Fix comparing packge versions + +kpackage-1.0.01 +--------------- +German tranlations - Dirk Moebius <moebius@informatik.uni-bonn.de> + +kpackage-1.0 +--------------- +Handle uninstalled packages as well as installed +Cache non-local uninstalled package directories in .kpackage +Cache packages in .kpackage directory under their names +Options dialog for package directory caching +Options dialog for package caching +Options dialog for display of packages +Make options dialog tabbed +Put draggable seperator in main window +Sort package properties list +Add Russian translation (Serguei Koubouchin) +Use standard color map for icons +Fix Terminate string in KpMsg +Fix error message for package file no found +Fix kfm file fetching when file not found +Fix open of local file with file select dialog +Fix package properties display when scroll bar disappears +Fix non file URLs from file open dialog +Fix zlib linking problem (maybe) + +kpackage-0.9.02 +--------------- +Add French translation +Fix segfault with Options... +Fix "Check Dependencies" with rpm Uninstall +Change icons on tree display + +kpackage-0.9.01 +--------------- +Add Spanish translation +Fix compiling without RPM + +kpackage-0.9 +------------ +Add searching for package that includes a file (dialog with DND) +Use kfile file selector +Only create file list when accessed +Don't reload package tree after add or delete +Add toolbar (prevent toolbar envy) +Add options menu (option for turning off file verification) +Update automake,autoconf,make stuff +Fix some fd and memory leaks +Fix mini-icon +Save more state on exit +Fix color of description panel +Add more internationalisation +Put more stuff through translation + +kpackage-0.8 +-------------- +Display rpm dependency problems in GUI popup +Display partially installed debian packages +Update icons +Don't rebuild package tree if not needed +Fix other rpm file descriptor leakage +Try to put tmp files into home directory (/tmp has security problems) +Add internationalisation + Portuguese: Pedro Morais <pmmm@camoes.rnl.ist.utl.pt> + Slovakian: Juraj Bednar <bednar@isternet.sk> +Allow for dropping multiple files +Add folder pixmap for groups of packages +Fix searching not to loose package sizes +Change docs to KDE look + +kpackage-0.7 +-------------- +Restructure internals to implement debian and RPM handling as + subclasses and allow for adding other types +Compile without RPM support if the correct libraries aren't available +Add find function for searching for installed packages +Use ktreeview widget +Change rpm errors from STDERR to error popups +Different color tree icons for deb and rpm +Fix to work with newer kprocess +Fix fd leak +Fix some memory leaks + +kpackage-0.6.2 +-------------- +Fix installing .DEB packages with large number of files +Make handling of libraries more intelligent + +kpackage-0.6 +------------ +Fix up pixmaps, add file verify for debian +add recently opened file menu +selecting file in file list opens it +speed up long file list +fix handling non-file URLs +Fix crash when no debian installed +Recognise old Debian format + +kpackage-0.5 +------------ +Add handling DEB packages +Fix problem with loosing text lines in description +Update for session handling +Use kfm for network io +Add open menu item diff --git a/kpackage/Makefile.am b/kpackage/Makefile.am new file mode 100644 index 0000000..4f2791f --- /dev/null +++ b/kpackage/Makefile.am @@ -0,0 +1,36 @@ + +xdg_apps_DATA = kpackage.desktop + +# claim, which subdirectories you want to install +SUBDIRS = pics toolbar icon + +bin_PROGRAMS = kpackage + +# Which sources should be compiled for kpackage. +kpackage_SOURCES = kpackage.cpp managementWidget.cpp packageDisplay.cpp \ + packageProperties.cpp findf.cpp search.cpp \ + options.cpp pkgOptions.cpp \ + packageInfo.cpp cache.cpp main.cpp utils.cpp kio.cpp \ + debInterface.cpp debDpkgInterface.cpp debAptInterface.cpp \ + updateLoc.cpp procbuf.cpp kplview.cpp \ + pkgInterface.cpp rpmInterface.cpp kissInterface.cpp \ + slackInterface.cpp fbsdInterface.cpp gentooInterface.cpp \ + kpPty.cpp kpTerm.cpp + +kpackage_METASOURCES = AUTO + +# the library search path +kpackage_LDFLAGS = $(all_libraries) $(KDE_RPATH) + +# the libraries to link against. Be aware of the order. First the libraries, +# that depend on the following ones. +kpackage_LDADD = $(LIB_KFILE) $(LIBINTL) $(LIBZ) $(LIBUTEMPTER) + +INCLUDES = $(all_includes) + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kpackage.pot + +rcdir = $(kde_datadir)/kpackage +rc_DATA = kpackageui.rc + diff --git a/kpackage/README b/kpackage/README new file mode 100644 index 0000000..9a843dd --- /dev/null +++ b/kpackage/README @@ -0,0 +1,11 @@ +Kpackage handles RPM, Debian and various other packages, it is used +for displaying currently installed packages, uninstalling +them and installing new ones. + +For kpackage to work correctly with RPM packages the RPM database +must be initialised. If typing `rpm -qa' gives an error about +`unable to open....` then try `rpm --rebuilddb'. + + +Toivo Pedaste (toivo@ucs.uwa.edu.au) + diff --git a/kpackage/cache.cpp b/kpackage/cache.cpp new file mode 100644 index 0000000..1877728 --- /dev/null +++ b/kpackage/cache.cpp @@ -0,0 +1,229 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include "kpackage.h" +#include "options.h" +#include "cache.h" +#include <klocale.h> +#include <kdebug.h> + +extern Opts *opts; +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +cacheObj::cacheObj(const QString &Pbase, const QString &Plocation, const QString &PcacheFile, + const QString &Poption, bool Psubdirs) +{ + base = Pbase; + location = Plocation; + cacheFile = PcacheFile; + option = Poption; + subdirs = Psubdirs; +} + +cacheObj::~cacheObj() +{} + +QString cacheObj::PDir() +{ + struct stat buf; + stat(QFile::encodeName(QDir::homeDirPath()), &buf); + + QString tmpd = opts->CacheDir ; + + QDir d(tmpd); + if (!d.exists()) { + if (!d.mkdir(tmpd)) { + KpMsgE(i18n("Cannot create folder %1").arg(tmpd),TRUE); + tmpd = ""; + } else { + chown(QFile::encodeName(tmpd),buf.st_uid,buf.st_gid); + } + } + return tmpd; +} + +QString cacheObj::CDir() +{ + QString tmpd = PDir(); + if (!tmpd.isEmpty()) { + struct stat buf; + stat(QFile::encodeName(tmpd),&buf); + + tmpd += "dir/"; + + QDir d(tmpd); + if (!d.exists()) { + if (!d.mkdir(tmpd)) { + KpMsgE(i18n("Cannot create folder %1").arg(tmpd),TRUE); + tmpd = ""; + } else { + chown(QFile::encodeName(tmpd),buf.st_uid,buf.st_gid); + } + } + } + return tmpd; +} + +int cacheObj::newDCache(const QString &url, const QString &fn, QString &fname) { + + KURL u(url); + if ( !u.isValid() ) { + KpMsgE(i18n("Malformed URL: %1").arg(url),TRUE); + return -1; + } + + QString tmpd = cacheObj::CDir(); + if (tmpd.isEmpty()) { + return -1; + } else { + if (u.protocol() == "file") { + fname = u.path(); + return 0; + } + + fname = tmpd + fn; + + if (opts->DCache == Opts::NEVER) { + return 1; + } + + QFileInfo f(fname); + + if (f.exists() && f.size() > 0) { + return 0;; + } else { + if (f.size() == 0) + rmDCache(fname); + return 1; + } + } +} + +void cacheObj::rmDCache(const QString &fn) { + QString tmpd = cacheObj::CDir(); + tmpd += fn; + + if (!tmpd.isEmpty()) { + unlink(QFile::encodeName(tmpd)); + } +} + +void cacheObj::clearDCache() { + QString tmpd = cacheObj::CDir(); + + if (!tmpd.isEmpty()) { + QDir d(tmpd); + CacheList cl(d) ; + for (CacheList::iterator it = cl.begin() ; it != cl.end() ; ++it) { + QString s = tmpd; + s += *it; + unlink(QFile::encodeName(s)); + } + unlink(QFile::encodeName(cl.getCLFileName())) ; // also delete the kpackage_cachelist file + } +} + +void cacheObj::clearPCache() { + QString tmpd = cacheObj::PDir(); + + if (!tmpd.isEmpty()) { + QDir d(tmpd); + CacheList cl(d); + for (CacheList::iterator it = cl.begin() ; it != cl.end() ; ++it) { + QString s = tmpd ; + s += *it; + unlink(QFile::encodeName(s)); + } + unlink(QFile::encodeName(cl.getCLFileName())) ; // also delete the kpackage_cachelist file + } +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +LcacheObj::LcacheObj() +{ + setAutoDelete(TRUE); +} + +LcacheObj::~LcacheObj() +{ +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +CacheList::CacheList (const QDir& dir) +{ + CLFile.setName (dir.path() + "/kpackage_cachelist") ; + read() ; +} + +void CacheList::read () +{ + kdDebug() << "reading cachelist: " << CLFile.name() << "\n" ; + if (CLFile.open (IO_ReadOnly)) { + QTextStream stream (&CLFile) ; + QString line ; + while (!stream.eof()) { + line = stream.readLine() ; + if (line[0] != '#') { // not a comment + append (line) ; // to this QStringList + } + } + CLFile.close() ; + } + else { + // kdDebug() << "could not open cachelist " << CLFile.name() << "!\n" ; + } +} + +void CacheList::write () +{ + kdDebug() << "writing cachelist: " << CLFile.name() << "\n" ; + if (CLFile.open (IO_WriteOnly)) { + QTextStream stream (&CLFile) ; + stream << "# This file contains a list of files that have been cached in this folder.\n" ; + stream << "# Please only delete this if you want kpackage to forget what it has cached.\n" ; + for (QStringList::iterator it = begin() ; it != end() ; ++it) { + stream << *it << "\n" ; + } + CLFile.close() ; + } + else { + kdDebug() << "could not open cachelist " << CLFile.name() << "!\n" ; + } +} + +QString CacheList::getCLFileName () const +{ + return CLFile.name() ; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// diff --git a/kpackage/cache.h b/kpackage/cache.h new file mode 100644 index 0000000..02dc830 --- /dev/null +++ b/kpackage/cache.h @@ -0,0 +1,114 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + + +#ifndef CACHE_H +#define CACHE_H + +#include <qdir.h> +#include <qptrlist.h> + +#include <kurl.h> + +#include "../config.h" +#include "packageInfo.h" + +class Locations; +class LcacheObj; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +class cacheObj +{ +public: + QString base; + QString location; + QString cacheFile; + QString option; + bool subdirs; + + cacheObj(const QString &Pbase, const QString &Plocation, const QString &PcacheFile, const QString &Poption = QString::null, bool Psubdirs = FALSE); + ~cacheObj(); + + static QString PDir(); + // return path of kpackage cache directory + + static QString CDir(); + // return path of kpackage directory cache + + static int newDCache(const QString &url, const QString &fn, QString &fname); + // Checks directory cache + // -1 Cann't get cache file name + // 0 Cache file exists + // 1 Cache file doesn't exit + // fname return file name + + static void rmDCache(const QString &fn); + + static void clearDCache(); + static void clearPCache(); +}; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +class LcacheObj: public QPtrList<cacheObj> +{ +public: + LcacheObj(); + ~LcacheObj(); +}; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/** + * @short the list of cached files in a directory stored in the file "kpackage_cachelist" + **/ +class CacheList : public QStringList +{ +public: + /** + * create (and read) a cachelist object for the directory dir + **/ + CacheList (const QDir& dir) ; + + /** + * write this cachelist to disk + **/ + void write (void) ; + + QString getCLFileName (void) const ; + +private: + QFile CLFile ; + + void read (void) ; +} ; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +#endif diff --git a/kpackage/debAptInterface.cpp b/kpackage/debAptInterface.cpp new file mode 100644 index 0000000..9dffb39 --- /dev/null +++ b/kpackage/debAptInterface.cpp @@ -0,0 +1,535 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#include "../config.h" +#include <stdlib.h> + +#include "klocale.h" +#include <kaction.h> +#include <kstdaction.h> +#include <kdebug.h> + +#include "kpackage.h" +#include "updateLoc.h" +#include "debAptInterface.h" +#include "cache.h" +#include "pkgOptions.h" + + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +DEBAPT::DEBAPT():DEB() +{ + head = "DEBAPT"; + name = i18n("APT: Debian"); + + queryMsg = i18n("Querying DEB APT package list: "); + procMsg = i18n("KPackage: Waiting on APT-GET"); + + hasRemote = TRUE; + + locatedialog = new Locations(i18n("Location of Debian Packages")); + + locatedialog->aLocations(1, 60, this, i18n("APT sources", "A"), + i18n("APT Sources Entries")); + locatedialog->dLocations(1, 8, this, i18n("Folders", "F"), + "Deb", "*.deb", + i18n("Location of Folders Containing Debian Packages")); + connect(locatedialog,SIGNAL(returnVal(LcacheObj *)), + this,SLOT(setAvail(LcacheObj *))); + locatedialog->apply_slot(); + + paramsInst.append(new param(i18n("Download only"),FALSE,FALSE,"-d")); + paramsInst.append(new param(i18n("No download"),FALSE,FALSE,"--no-download")); + paramsInst.append(new param(i18n("Ignore missing"),FALSE,FALSE,"-m")); + paramsInst.append(new param(i18n("Ignore hold"),FALSE,FALSE,"--ignore-hold")); + paramsInst.append(new param(i18n("Allow Unauthenticated"),FALSE,FALSE,"--allow-unauthenticated")); + paramsInst.append(new param(i18n("Assume yes"),TRUE,FALSE,"--yes")); + paramsInst.append(new param(i18n("Test (do not uninstall)"),FALSE,FALSE,"-s")); + + paramsUninst.append(new param(i18n("Purge Config Files"),FALSE,FALSE,"--purge")); + paramsUninst.append(new param(i18n("Assume yes"),TRUE,FALSE,"--yes")); + paramsUninst.append(new param(i18n("Test (do not uninstall)"),FALSE,FALSE,"-s")); + + env = "DEBIAN_FRONTEND=readline; export DEBIAN_FRONTEND; "; + + noFetch = TRUE; + hasSearchAll = TRUE; + + hasProgram = ifExe("apt-get"); +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +DEBAPT::~DEBAPT() +{ +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +bool DEBAPT::isType(char *, const QString &) +{ + return false; +} + +void DEBAPT::makeMenu(KActionCollection* act) +{ + updateM = new KAction( i18n("&Update"), QString::null, + 0, this, + SLOT(updateS()), act, "debapt_update"); + + upgradeM = new KAction( i18n("U&pgrade"), QString::null, + 0, this, + SLOT(upgradeS()), act, "debapt_upgrade"); + + fixupM = new KAction( i18n("&Fixup"), QString::null, + 0, this, + SLOT(fixupS()), act, "debapt_fixup"); + + fileM = new KAction( i18n("&Apt-File Update"), QString::null, + 0, this, + SLOT(fileS()), act, "debapt_file"); +} + +void DEBAPT::setMenu(KActionCollection*, bool enable) +{ + updateM->setEnabled(enable); + upgradeM->setEnabled(enable); + fixupM->setEnabled(enable); + fileM->setEnabled(enable); +} + +void DEBAPT::updateS() +{ + if (kprun->run("apt-get update", "APT update")) { + if (kprun->exec()) + kpackage->management->collectData(TRUE); + } +} + +void DEBAPT::upgradeS() +{ + if (kprun->run(env + "apt-get dist-upgrade", "APT upgrade")) { + if (kprun->exec()) + kpackage->management->collectData(TRUE); + } +} + +void DEBAPT::fixupS() +{ + if (kprun->run(env + "apt-get -f install", "APT fixup")) { + if (kprun->exec()) + kpackage->management->collectData(TRUE); + } +} + +void DEBAPT::fileS() +{ + if (ifExe("apt-file") || !hostName.isEmpty()) { + if (kprun->run(env + "apt-file update", "APT file update")) { + kprun->exec(); + } + } else { + KpMsg("Error",i18n("The %1 program needs to be installed").arg("apt-file"), TRUE); + } +} + +void DEBAPT::listPackages(QPtrList<packageInfo> *pki) +{ + if (hostName.isEmpty()) { + listInstalledPackages(pki); + } else { + listRemotePackages(pki); + } + listAvail(pki); + if (hostName.isEmpty() && packageLoc) { + listUnIPackages(pki, packageLoc); + } +} + +void DEBAPT::listRemotePackages(QPtrList<packageInfo> *pki) +{ + listRPack(pki); +} + +void DEBAPT::listRPack(QPtrList<packageInfo> *pki) +{ + int NLINES = 70000; + + packageInfo *p; + QStringList plist; + + kpackage->setStatus(i18n("Querying DEB APT remote package list: %1").arg(hostName)); + kpackage->setPercent(0); + + QString cmd = "cat " STATUS; + + QStringList list = kpty->run(cmd); + kpackage->setStatus(i18n("Processing DEB APT remote package list: %1").arg(hostName)); + // kdDebug() << "P=" << list.count() <<"\n"; + kpackage->setPercent(50); + + + if (list.count() > 0) { + + QString s; + + kpackage->setPercent(50 ); + + int cnt = 0; + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + cnt++; + if (cnt % (NLINES/20) == 0) { + kpackage->setPercent(((cnt * 100)/ NLINES ) + 50); + // kdDebug() << cnt << "_" << ((cnt * 100) / NLINES) <<"\n"; + } + + if (!(*it).isEmpty()) { + s = *it; + // kdDebug() << s.length() << "<" << s << ">\n"; + plist << s; + } else { + // kdDebug() << "---------\n"; + p = collectInfo(plist); + if (p) { + if (!p->pkgInsert(pki, typeID, TRUE)) { + delete p; + } + } + plist.clear(); + } + } + } + + list.clear(); + kpackage->setStatus(i18n("DEB APT")); + kpackage->setPercent(100); +} + +void DEBAPT::listAvail(QPtrList<packageInfo> *pki) +{ + int NLINES = 150000; + + packageInfo *p; + QStringList plist; + + // kdDebug() << "H=" << hostName << "\n"; + if (hostName.isEmpty()) + kpackage->setStatus(i18n("Querying DEB APT available list")); + else + kpackage->setStatus(i18n("Querying DEB APT available list: %1").arg(hostName)); + kpackage->setPercent(0); + + QStringList list = kpty->run("apt-cache dumpavail"); + if (hostName.isEmpty()) + kpackage->setStatus(i18n("Processing DEB APT available list")); + else + kpackage->setStatus(i18n("Processing DEB APT available list: %1").arg(hostName)); + + // kdDebug() << "A=" << list.count() <<"\n"; + kpackage->setPercent(50); + + if (list.count() > 0) { + + QString s; + + kpackage->setPercent(50 ); + + int cnt = 0; + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + cnt++; + if (cnt % (NLINES/20) == 0) { + kpackage->setPercent(((cnt * 100)/ NLINES ) + 50); + } + + if (!(*it).isEmpty()) { + s = *it; + plist << s; + } else { + p = collectInfo(plist); + if (p) { + if (!p->pkgInsert(pki, typeID, FALSE)) { + delete p; + } + } + plist.clear(); + } + } + } + + list.clear(); + kpackage->setStatus(i18n("DEB APT")); + kpackage->setPercent(100); +} + +QStringList DEBAPT::listInstalls(const QStringList &packs, bool install, bool &cancel) +{ + bool extras=FALSE, found=FALSE; + + QString match; + QString s = "apt-get -s "; + if (install) { + s += "install "; + match = " extra packages "; + } else { + match = "packages will be REMOVED:"; + s += "remove "; + } + + for ( QStringList::ConstIterator it = packs.begin(); it != packs.end(); ++it ) { + s += *it; + s += " "; + } + + QStringList list = kpty->run(s, TRUE, TRUE); + if (!kpty->inSession) { + cancel = TRUE; // Root login did not work + } else { + cancel = FALSE; + } + // kdDebug() << "LS=" << list.count() << "\n"; + + QString packAll; + for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) { + // kdDebug() << "M=" << *it << "\n"; + if ((*it).find(match) >= 0 || extras) { + if (extras) { + if ((*it)[0] == ' ') { + packAll += *it; + found = true; + } else { + break; + } + } + extras=TRUE; + } + } + + if (!found) { + QStringList nill; + return nill; + } else { + QStringList plist = QStringList::split(' ',packAll); + return plist; + } +} + +////////////////////////////////////////////////////////////////////////////// +QStringList DEBAPT::FindFile(const QString &name, bool searchAll) +{ + if (searchAll) { + if (ifExe("apt-file") || !hostName.isEmpty()) { + QString s = "apt-file search "; + s += name; + + QStringList filelist = kpty->run(s); + + for ( QStringList::Iterator it = filelist.begin(); it != filelist.end(); ++it ) { + int p = (*it).find(": "); + if( p !=-1 ) + (*it).replace(p, 2, "\t"); + } + + if (filelist.count() == 1) { + QStringList::Iterator it = filelist.begin(); + if ((*it).find("not found") >= 0) { + filelist.remove(it); + } + } + + return filelist; + } else { + KpMsg("Error",i18n("The %1 program needs to be installed").arg("apt-file"), TRUE); + QStringList nill; + return nill; + } + } else { + return DEB::FindFile(name); + } +} + + +QStringList DEBAPT::getFileList(packageInfo *p) +{ + QString fn( p->getFilename()); + if(!fn.isEmpty()) + return getUFileList(fn); + else { + if (hostName.isEmpty()) + return getIFileList(p); + else { + if (p->packageState == packageInfo::INSTALLED) { + return getRFileList(p); + } else + return ""; + } + } +} + + QStringList DEBAPT::getRFileList(packageInfo *p) +{ + QString from; + QString name = p->getProperty("name"); + + from = "cat " INFODIR; + from += name; + from += ".list"; + + return kpty->run(from); +} + +////////////////////////////////////////////////////////////////////////////// +QString DEBAPT::doUninstall(int uninstallFlags, const QString &packs, bool &test) +{ + QString s = env + "apt-get remove "; + s += setOptions(uninstallFlags, paramsUninst); + s += packs; + + kdDebug() << "uCMD=" << s << "\n"; + + if (uninstallFlags>>2 & 1) + test = TRUE; + + return s; +} + +////////////////////////////////////////////////////////////////////////////// +QString DEBAPT::install(int installFlags, QPtrList<packageInfo> *p, + bool &test) +{ + QString packs = ""; + QString files = ""; + packageInfo *i; + + for (i = p->first(); i!= 0; i = p->next()) { + QString file = i->getFilename(); + QString fname = i->fetchFilename(); + + if (!file.isEmpty()) { + files += KProcess::quote(file); + files += " "; + } else if (!fname.isEmpty()) { + packs += KProcess::quote(fname); + packs += " "; + } + } + + if (!files.isEmpty()) { // What if mixed? + return DEB::doInstall(installFlags, files, test); + } else { + return doInstall(installFlags, packs, test); + } +} + +QString DEBAPT::doInstall(int installFlags, const QString &packs, bool &test) +{ + QString s = env + "apt-get install "; + s += setOptions(installFlags, paramsInst); + s += packs; + + kdDebug() << "iCMD=" << s << "\n"; + + if ((installFlags>>0 & 1) || (installFlags>>5 & 1)) + test = TRUE; + + return s; +} + + +////////////////////////////////////////////////////////////////////////////// + +QStringList DEBAPT::readApt() +{ + if (hostName.isEmpty()) { + return readAptF(); + } else { + return readAptS(); + } +} + +QStringList DEBAPT::readAptS() +{ + QString cmd = "cat -E " APT_SOURCE; + + QStringList list = kpty->run(cmd); + if (!kpty->Result) { + QString s; + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + (*it).truncate((*it).length() - 1); + (*it) = (*it).stripWhiteSpace(); + } + return list; + } else { + return 0; + } +} + +QStringList DEBAPT::readAptF() +{ + QStringList lines; + QFile file( "/etc/apt/sources.list" ); + if ( file.open( IO_ReadOnly ) ) { + QTextStream stream( &file ); + QString line; + while ( !stream.atEnd() ) { + line = stream.readLine(); // line of text excluding '\n' + line = line.stripWhiteSpace(); + lines += line; + } + file.close(); + return lines; + } else { + return 0; + } +} + +void DEBAPT::writeApt(const QStringList &list) { + kdDebug() << "writeApt\n"; + QString cmd = "sh -c \"/bin/echo -e '"; + for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) { + QString s = *it; + s.replace("\""," "); + s.replace("'"," "); + s.replace("!"," "); + s.replace("`"," "); + cmd += s; + cmd += "\n"; + } + cmd += "' > /etc/apt/sources.list.n; if [ $? = 0 ]; then "; + cmd += "mv /etc/apt/sources.list /etc/apt/sources.list.b; mv /etc/apt/sources.list.n /etc/apt/sources.list; fi\" "; + + + QStringList rlist = kpty->run(cmd,TRUE,TRUE); + //for ( QStringList::Iterator it = rlist.begin(); it != rlist.end(); ++it ) { + // kdDebug() << "SL=" << *it << "\n"; + //} +} + + +#include "debAptInterface.moc" diff --git a/kpackage/debAptInterface.h b/kpackage/debAptInterface.h new file mode 100644 index 0000000..71e52ea --- /dev/null +++ b/kpackage/debAptInterface.h @@ -0,0 +1,84 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#ifndef DEBAPT_IFACE_H +#define DEBAPT_IFACE_H + +#include "../config.h" + +#include <kaction.h> + +#include "debInterface.h" + +#define APT_SOURCE "/etc/apt/sources.list" + +class DEBAPT: public DEB +{ + Q_OBJECT + +public: + DEBAPT(); + ~DEBAPT(); + + virtual bool isType(char *buf, const QString &fname); + + void listPackages(QPtrList<packageInfo> *pki); + QStringList listInstalls(const QStringList &packs, bool install, bool &cancel); + + QString doUninstall(int uninstallFlags, const QString &packs, bool &test); + QString doInstall(int installFlags, const QString &packs, bool &test); + QString install(int installFlags, QPtrList<packageInfo> *p, + bool &test); + + virtual QStringList FindFile(const QString &name, bool seachAll=false); + + void listRemotePackages(QPtrList<packageInfo> *pki); + QStringList getFileList(packageInfo *p); + + KAction *updateM, *upgradeM, *fixupM, *fileM; + + void makeMenu(KActionCollection* act); + void setMenu(KActionCollection* act, bool enable); + + QStringList readApt(); + QStringList readAptS(); + QStringList readAptF(); + void writeApt(const QStringList &list); + +private slots: + void updateS(); + void upgradeS(); + void fixupS(); + void fileS(); + +private: + void listAvail(QPtrList<packageInfo> *pki); + void listRPack(QPtrList<packageInfo> *pki); + QStringList getRFileList(packageInfo *p); + + QString env; +}; +#endif diff --git a/kpackage/debDpkgInterface.cpp b/kpackage/debDpkgInterface.cpp new file mode 100644 index 0000000..896bdfb --- /dev/null +++ b/kpackage/debDpkgInterface.cpp @@ -0,0 +1,164 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#include "../config.h" + +#include <unistd.h> +#include <stdlib.h> // for getenv +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> // for O_RDONLY +#include <setjmp.h> +#include <iostream> + +#include <kurl.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <kdebug.h> + +#include "packageInfo.h" +#include "debDpkgInterface.h" +#include "updateLoc.h" +#include "kpackage.h" +#include "managementWidget.h" +#include "utils.h" +#include "options.h" +#include "cache.h" +#include <klocale.h> + + +extern KApplication *app; +extern Opts *params; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +DEBDPKG::DEBDPKG():DEB() +{ + head = "DEBDPKG"; + name = i18n("DPKG: Debian"); + defaultHandle = 0; + + queryMsg = i18n("Querying DEB package list: "); + procMsg = i18n("Kpackage: Waiting on DPKG"); + + locatedialog = new Locations(i18n("Location of Debian Package Archives")); + locatedialog->cLocations(3, 2, this, i18n("Location", "L"), + "Deb", + i18n("Version\nArchitecture"), + i18n("Location of Base Folder of Debian Distribution"), + "stable frozen unstable\ni386 alpha sparc powerpc arm m68k"); + locatedialog->pLocations(3, 6, this, i18n("Packages", "P"), + "Deb", "*.deb Packages Packages.gz status available", + i18n("Location of 'Packages' Files for Sections of Debian Distributions"), + i18n("Location of Base Folder of Debian Distribution")); + locatedialog->dLocations(2, 6, this, i18n("Folders", "F"), + "Deb", "*.deb", + i18n("Location of Folders Containing Debian Packages")); + connect(locatedialog,SIGNAL(returnVal(LcacheObj *)), + this,SLOT(setAvail(LcacheObj *))); + locatedialog->apply_slot(); + + paramsInst.append(new param(i18n("Allow Downgrade"),TRUE,TRUE,"--refuse-downgrade")); + paramsInst.append(new param(i18n("Check Conflicts"),TRUE,TRUE,"--force-conflicts")); + paramsInst.append(new param(i18n("Check Dependencies"),TRUE,TRUE,"--force-depends")); + paramsInst.append(new param(i18n("Test (do not install)"),FALSE,FALSE,"--no-act")); + + paramsUninst.append(new param(i18n("Purge Config Files"),TRUE,FALSE, + "--purge","--remove")); + paramsUninst.append(new param(i18n("Check Dependencies"),TRUE,TRUE,"--force-depends")); + paramsUninst.append(new param(i18n("Test (do not uninstall)"),FALSE,FALSE,"--no-act")); + + hasProgram = ifExe("dpkg"); + +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +DEBDPKG::~DEBDPKG() +{ +} + +////////////////////////////////////////////////////////////////////////////// +void DEBDPKG::distPackages(QPtrList<packageInfo> *pki, cacheObj *cp) +{ + LcacheObj *cList = new LcacheObj(); + QString loc = cp->base; + + QStringList opt = QStringList::split('\n',cp->option); + QStringList::Iterator ocIt = opt.begin(); + QString rel = *ocIt; + QString arch = *(++ocIt); + + QString parts[3] = {"main", "contrib", "non-free"}; + for (int i = 0; i < 3; i++) { + QString file = loc + "/dists/"; + file += rel; + file += "/"; + file += parts[i]; + file += "/binary-"; + file += arch; + file += "/Packages"; + QString s; + QString tmp = cp->cacheFile; + tmp += s.setNum(i); + cacheObj *cp = new cacheObj(loc,file,tmp); + cList->append(cp); + } + + listUnIPackages(pki, cList); +} + +void DEBDPKG::listPackages(QPtrList<packageInfo> *pki) +{ + listInstalledPackages(pki); + if (packageLoc) { + listUnIPackages(pki, packageLoc); + } +} + + + + +////////////////////////////////////////////////////////////////////////////// +// Call the script to uninstall packages setting parameters +// to dpkg dependent on flags, returning whether everyting worked +////////////////////////////////////////////////////////////////////////////// +QString DEBDPKG::doUninstall(int uninstallFlags, const QString &packs, bool &test) +{ + QString s = "dpkg "; + // The -r or -p flag is set by setOptions + s += setOptions(uninstallFlags, paramsUninst); + s += packs; + + if (uninstallFlags>>3 & 1) + test = 1; + + kdDebug() << "uCMD=" << s << "\n"; + + return s; +} + +#include "debDpkgInterface.moc" diff --git a/kpackage/debDpkgInterface.h b/kpackage/debDpkgInterface.h new file mode 100644 index 0000000..f65ccf0 --- /dev/null +++ b/kpackage/debDpkgInterface.h @@ -0,0 +1,65 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#ifndef DEBDPKG_IFACE_H +#define DEBDPKG_IFACE_H + +#include "../config.h" + +#include "debInterface.h" + +class packageInfo; +class updateLoc; +class cacheObj; + +class DEBDPKG: public DEB +{ + Q_OBJECT + +public: + DEBDPKG(); + ~DEBDPKG(); + + QString doUninstall(int installFlags, const QString &packs, bool &test); + + void listPackList(QPtrList<packageInfo> *pki, const QString &fname, + cacheObj *cp); + + void listPackages(QPtrList<packageInfo> *pki); + void distPackages(QPtrList<packageInfo> *pki, cacheObj *cp); + +public slots: + +protected: + packageInfo *getIPackageInfo(const QString &name); + packageInfo *getUPackageInfo(const QString &name); + +}; + +#endif + + + diff --git a/kpackage/debInterface.cpp b/kpackage/debInterface.cpp new file mode 100644 index 0000000..4c79485 --- /dev/null +++ b/kpackage/debInterface.cpp @@ -0,0 +1,596 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#include "../config.h" + +#include <unistd.h> +#include <stdlib.h> // for getenv +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> // for O_RDONLY +#include <setjmp.h> +#include <iostream> + +#include <kurl.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <kdebug.h> + +#include "packageInfo.h" +#include "debInterface.h" +#include "updateLoc.h" +#include "kpackage.h" +#include "managementWidget.h" +#include "utils.h" +#include "options.h" +#include "cache.h" +#include <klocale.h> + +extern KApplication *app; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +DEB::DEB():pkgInterface() +{ + head = "DEB"; + icon = "deb"; + + pict = UserIcon(icon); + bad_pict = UserIcon("dbad"); + updated_pict = UserIcon("dupdated"); + new_pict = UserIcon("dnew"); + + packagePattern = "*.deb"; + typeID = "/deb"; + + locatedialog = 0; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +DEB::~DEB() +{ +} + +////////////////////////////////////////////////////////////////////////////// + +// check if debian file +bool DEB::isType(char *buf, const QString &) +{ + if (hasProgram) { + if (!strcmp(buf,"!<arch>\n")) { + return true; + } else if (!strncmp(buf,"0.9",3)) { + return true; + } else + return false; + } else { + return false; + } +} + +void DEB::distPackages(QPtrList<packageInfo> *, cacheObj *) +{ +} + +void DEB::listUnIPackages(QPtrList<packageInfo> *pki, LcacheObj *pCache) +{ + QString s; + cacheObj *cp; + + for (cp = pCache->first(); cp != 0; cp = pCache->next()) { + kdDebug() << cp->base << ":: " << cp->option << "\n"; + if (!cp->option.isEmpty()) { + distPackages(pki, cp); + } else if (!cp->base.isEmpty()) { + s = getPackList(cp); + if (!s.isEmpty()) { + listPackList(pki,s,cp); + } + } else { + s = getDir(cp); + if (!s.isEmpty()) { + listDir(pki,s,cp->location,cp->subdirs); + } + } + } +} + +bool DEB::parseName(const QString &name, QString *n, QString *v) +{ + int d1, d2, s1; + + s1 = name.findRev('.'); + if (s1 > 0) { + d2 = name.findRev('-',s1-1); + if (d2 > 0) { + d1 = name.findRev('_',d2-1); + if (d1 < 0) + d1 = d2; + *n = name.left(d1); + *v = name.mid(d1+1,s1-d1-1); + return TRUE; + } + } + return FALSE; +} + +void DEB::listInstalledPackages(QPtrList<packageInfo> *pki) +{ + listPackList(pki,STATUS,0); +} + +void DEB::listPackList(QPtrList<packageInfo> *pki, const QString &fname, cacheObj *cp) +{ + bool local = FALSE; + packageInfo *p; + QStringList list; + QString sline( i18n("Querying DEB package list: ")+fname ); + + if (cp) { + KURL u(cp->base); + local = u.isLocalFile(); + } + + kpackage->setStatus(sline); + kpackage->setPercent(0); + + QFile file(STATUS); + QString s; + + bool fileOpened= file.open(IO_ReadOnly); + if (fileOpened) { + QTextStream stream( &file ); + s = ""; + while ( !s.isNull() ) { + s = stream.readLine(); + if ( !s.isEmpty() ) { + list << s; + } else { + p = collectInfo(list); + if (p) { + if (!p->pkgInsert(pki, typeID, cp == 0)) { + delete p; + } else if (cp) { + p->info.insert("base", cp->base); + } + } + list.clear(); + } + } + file.close(); + } + + kpackage->setPercent(100); +} + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +packageInfo *DEB::getPackageInfo(char mode, const QString &name, const QString &) +{ + if (mode == 'i') { + if (hostName.isEmpty()) { + return getIPackageInfo(name); + } else { + return getIRPackageInfo(name); + } + } else + return getUPackageInfo(name); +} + +packageInfo *DEB::getIPackageInfo( const QString &name) +{ + // query an installed package! + packageInfo *pki = 0; + QString search; + QStringList list; + + search = "Package: "+ name; + + QFile f(STATUS); + if ( f.open(IO_ReadOnly) ) { + QTextStream t( &f ); + QString s; + while ( !t.eof() ) { + s = t.readLine(); + + if ( s == search) { + list << s; + break; + } + } + + while ( !t.eof() ) { + s = t.readLine(); + if (s.length()) { + list << s; + } else { + pki = collectInfo(list); + break; + } + } + } + f.close(); + return pki; +} + +packageInfo *DEB::getIRPackageInfo( const QString &name) +{ + // query an remote installed package + packageInfo *pki = 0; + + QString s = "dpkg --status "; + s += name; + QStringList list = kpty->run(s); + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + // kdDebug() << "U=" << *it << "\n"; + if ((*it).find("Package:") >= 0) { + kdDebug() << "found\n"; + while (it != list.begin()) { + list.remove(list.begin()); + } + break; + } + } + + if (list.count() > 1) { + pki = DEB::collectInfo(list); + if (pki) { + pki->updated = TRUE; + if (pki->getFilename().isEmpty()) + pki->setFilename(name); + } + } + + return pki; +} + +packageInfo *DEB::getUPackageInfo( const QString &name) +{ + // query an uninstalled package + packageInfo *pki = 0; + + QString s = "dpkg --info "; + s += KProcess::quote(name); + + QStringList list = kpty->run(s); + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + // kdDebug() << "U=" << *it << "\n"; + if ((*it).find("Package:") >= 0) { + // kdDebug() << "found\n"; + while (it != list.begin()) { + list.remove(list.begin()); + } + break; + } + } + + if (list.count() > 1) { + pki = DEB::collectInfo(list, kpinterface[0]); // To be fixed up later, assumes order of kpinterface + if (pki) + pki->updated = TRUE; + } + + return pki; +} + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +packageInfo *DEB::collectInfo(QStringList &ln, pkgInterface *pkgInt) +{ + if (!pkgInt) { + pkgInt = this; + } + + QMap<QString, QString> a; + + QString key, val; + bool bad_install = FALSE; + bool available = FALSE; + bool haveName = FALSE; + + for ( QStringList::Iterator it = ln.begin(); it != ln.end(); ++it ) { + loop: + int col = (*it).find(':'); + key = ((*it).left(col)).lower(); + if (key[0] == ' ') { + key.remove(0,1); + } + val = (*it).mid(col+2); + + // val.truncate(val.length() - 1); + + if (key == "conffiles") { + while (++it != ln.end()) { + if ((*it)[0] == ' ') { + } else { + goto loop; + } + } + } else if (key == "description") { + a.insert("summary", val); + QString desc; + while (++it != ln.end()) { + if ((*it)[0] == ' ') { + desc += *it; + } else { + a.insert("description", desc); + goto loop; + } + } + a.insert("description", desc); + break; + } else if (key == "package") { + a.insert("name", val); + haveName = TRUE; + } else if (key == "md5sum") { + available = TRUE; + bad_install = FALSE; + } else if (key == "section") { + a.insert("group", val); + } else if (key == "status") { + if ((val.find("not-installed") >= 0) || (val.find("config-files") >= 0)) { + return 0; + } + if (val != "install ok installed" && + val != "deinstall ok installed" && + val != "deinstall ok config-files" && + val != "purge ok installed") { + bad_install = TRUE; + } + a.insert("status", val); + } else if (key == "version") { + a.insert("version", val); + } else if (key == "size") { + a.insert("file-size", val); + } else if (key == "installed-size") { + a.insert("size", val + "000"); + } else { + a.insert(key, val); + } + // kdDebug() << "C=" << key << "," << val <<"\n"; + } + + if (haveName) { + packageInfo *i = new packageInfo(a,pkgInt); + if (bad_install) { + i->packageState = packageInfo::BAD_INSTALL; + } else if (available) { + i->packageState = packageInfo::AVAILABLE; + } else { + i->packageState = packageInfo::INSTALLED; + } + i->fixup(); + return i; + } else { + return 0; + } +} + +////////////////////////////////////////////////////////////////////////////// + +QStringList DEB::getChangeLog(packageInfo *p) { + QString fn( p->getFilename()); + if(!fn.isEmpty()) + return 0; + else + return getIChangeLog(p); +} + +QStringList DEB::getIChangeLog(packageInfo *p) +{ + QString from; + QStringList ret; + QString name = p->getProperty("name"); + + from = "zcat /usr/share/doc/"; + from += name; + from += "/changelog.Debian.gz"; + + ret = kpty->run(from); + + if (!kpty->Result) + return ret; + else { + from = "zcat /usr/share/doc/"; + from += name; + from += "/changelog.gz"; + + ret = kpty->run(from); + if (!kpty->Result) + return ret; + else + return 0; + } +} + +bool DEB::filesTab(packageInfo *p) { + if (p->packageState == packageInfo::INSTALLED) { + return true; + } else if (p->isFileLocal()) { + return true; + } + return false; +} + +bool DEB::changeTab(packageInfo *p) { + if (p->packageState == packageInfo::INSTALLED) { + return true; + } + return false; +} + +////////////////////////////////////////////////////////////////////////////// + +QStringList DEB::getFileList(packageInfo *p) +{ + QString fn( p->getFilename()); + if(!fn.isEmpty()) + return getUFileList(fn); + else + return getIFileList(p); +} + +// query an installed package +QStringList DEB::getIFileList(packageInfo *p) +{ + FILE *file; + QString name = p->getProperty("name"); + QStringList filelist; + + QString vb( INFODIR + name + ".list"); + file= fopen(vb.ascii(),"r"); + + if (file) { + char linebuf[1024]; + while (fgets(linebuf,sizeof(linebuf),file)) { + linebuf[strlen(linebuf) - 1] = 0; // remove new line + filelist.append(linebuf); + } + fclose(file); + } + return filelist; +} + +// query an uninstalled package +QStringList DEB::getUFileList(const QString &fn) +{ + QString s = "dpkg --contents "; + s += "'"; + s += fn; + s += "'"; + + QStringList filelist = kpty->run(s); + + int pt = -1; + for ( QStringList::Iterator it = filelist.begin(); + it != filelist.end(); ++it ) { + // kdDebug() << "F=" << *it << "\n"; + if (pt < 0) { + pt = (*it).findRev(' '); + } + (*it) = (*it).mid(pt + 1); + } + return filelist; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +QStringList DEB::FindFile(const QString &name, bool) +{ + QString s = "dpkg -S "; + s += name; + + QStringList filelist = kpty->run(s); + + for ( QStringList::Iterator it = filelist.begin(); it != filelist.end(); ++it ) { + int p = (*it).find(": "); + if( p !=-1 ) + (*it).replace(p, 2, "\t"); + } + + if (filelist.count() == 1) { + QStringList::Iterator it = filelist.begin(); + if ((*it).find("not found") >= 0) { + filelist.remove(it); + } + } + + return filelist; +} + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +void DEB::setLocation() +{ + locatedialog->restore(); +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +void DEB::setAvail(LcacheObj *slist) +{ + if (packageLoc) + delete packageLoc; + packageLoc = slist; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +QString DEB::uninstall(int uninstallFlags, QPtrList<packageInfo> *p, + bool &test) +{ + QString packs = ""; + packageInfo *i; + + for (i = p->first(); i!= 0; i = p->next()) { + packs += i->getProperty("name"); + packs += " "; + } + return doUninstall( uninstallFlags, packs, test); +} + +////////////////////////////////////////////////////////////////////////////// +QString DEB::install(int installFlags, QPtrList<packageInfo> *p, + bool &test) +{ + QString packs = ""; + packageInfo *i; + + for (i = p->first(); i!= 0; i = p->next()) { + QString fname = i->fetchFilename(); + if (!fname.isEmpty()) { + packs += KProcess::quote(fname); + packs += " "; + } + } + return doInstall(installFlags, packs, test); +} + +////////////////////////////////////////////////////////////////////////////// +// Call the script to install packages setting parameters +// to dpkg dependent on flags, returning whether everyting worked +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +QString DEB::doInstall(int installFlags, const QString &packs, bool &test) +{ + QString s = "dpkg -i "; + s += setOptions(installFlags, paramsInst); + s += packs; + + kdDebug() << "iCMD=" << s << "\n"; + + if (installFlags>>4 & 1) + test = 1; + + return s; +} + +#include "debInterface.moc" diff --git a/kpackage/debInterface.h b/kpackage/debInterface.h new file mode 100644 index 0000000..98307f8 --- /dev/null +++ b/kpackage/debInterface.h @@ -0,0 +1,112 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + +#ifndef DEB_IFACE_H +#define DEB_IFACE_H + +#include "../config.h" + +#include <qptrlist.h> +#include <qdir.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qtextstream.h> +#include <qstringlist.h> + +#include <kprocess.h> + +#include "pkgInterface.h" + +class packageInfo; +class updateLoc; +class cacheObj; + +#define AVAIL "/var/lib/dpkg/available" +#define STATUS "/var/lib/dpkg/status" + +#define INFODIR "/var/lib/dpkg/info/" + + +class DEB: public pkgInterface +{ + Q_OBJECT + +public: + DEB(); + ~DEB(); + + virtual bool isType(char *buf, const QString &fname); + + virtual packageInfo *getPackageInfo(char mode, const QString &name, + const QString &version); + virtual QStringList getFileList(packageInfo *p); + virtual QStringList getChangeLog(packageInfo *p); + + bool filesTab(packageInfo *p); + // If files tab is to be enabled + + bool changeTab(packageInfo *p); + // If change log tab is to be enabled + + virtual void listInstalledPackages(QPtrList<packageInfo> *pki); + + virtual QStringList FindFile(const QString &name, bool seachAll=false); + virtual bool parseName(const QString &name, QString *n, QString *v); + + virtual packageInfo* collectInfo(QStringList &ln, pkgInterface *pkgInt = 0); + + QString uninstall(int uninstallFlags, QPtrList<packageInfo> *p, + bool &test); + QString install(int installFlags, QPtrList<packageInfo> *p, + bool &test); + QString doInstall(int installFlags, const QString &packs, bool &test); + +public slots: + void setLocation(); + void setAvail(LcacheObj *); + +protected: + packageInfo *getIPackageInfo(const QString &name); + packageInfo *getIRPackageInfo(const QString &name); + packageInfo *getUPackageInfo(const QString &name); + + QStringList getIChangeLog(packageInfo *p); + + void listPackList(QPtrList<packageInfo> *pki, + const QString &fname, cacheObj *cp); + + virtual void distPackages(QPtrList<packageInfo> *pki, cacheObj *cp); + void listUnIPackages(QPtrList<packageInfo> *pki, LcacheObj *pCache); + + QStringList getIFileList(packageInfo *p); + QStringList getUFileList(const QString &fn); +}; + +#endif + + + diff --git a/kpackage/fbsdInterface.cpp b/kpackage/fbsdInterface.cpp new file mode 100644 index 0000000..980ad36 --- /dev/null +++ b/kpackage/fbsdInterface.cpp @@ -0,0 +1,641 @@ +/* +** Copyright (C) 2000 by Alex Hayward <xelah@xelah.com> +*/ + + +/* +** 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 +*/ + + + +#include <errno.h> +#include <stdlib.h> +#include <assert.h> +#include <ctype.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/utsname.h> + +#include <qstringlist.h> + +#include <klocale.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <kdebug.h> + +#include "fbsdInterface.h" +#include "kpackage.h" +#include "updateLoc.h" +#include "cache.h" +#include "options.h" + +#define PKG_INFO_BIN "/usr/sbin/pkg_info" +#define PKG_ADD_BIN "/usr/sbin/pkg_add" +#define PKG_DELETE_BIN "/usr/sbin/pkg_delete" + +#define INFO_SEPARATOR "f;g#z-@IqbX%" + +fbsdInterface::fbsdInterface():pkgInterface() { + head = "BSD"; + name = i18n("BSD"); + icon = "bsd"; + + pict = UserIcon(icon); + updated_pict = UserIcon("bupdated"); + new_pict = UserIcon("bnew"); + + packagePattern = "*.tgz *.tbz"; + typeID = "/tbz"; + + QDict <bsdPortsIndexItem> ports(17777, false); + queryMsg = i18n("Querying package list: "); + + locatedialog = new Locations(i18n("Location of BSD Packages and Ports")); + locatedialog->dLocations(1, 1, this, i18n("Ports"), "Pkg", "*.tbz", + i18n("Location of Ports Tree (e.g. /usr/ports or /usr/opt)"),FALSE); + locatedialog->dLocations(1, 6, this, i18n("Packages"), "Pkg", "*.tbz", + i18n("Location of Folders Containing BSD Packages or Package Trees")); + connect(locatedialog, SIGNAL(returnVal(LcacheObj *)), this, SLOT(setAvail(LcacheObj *))); + locatedialog->apply_slot(); + + paramsInst.append(new param(i18n("Ignore Scripts"),FALSE,FALSE,"-I")); + paramsInst.append(new param(i18n("Check Dependencies"),TRUE,TRUE,"-f")); + paramsInst.append(new param(i18n("Test (do not install)"),FALSE,FALSE,"-n")); + + paramsUninst.append(new param(i18n("Ignore Scripts"),FALSE,FALSE, "-I")); + paramsUninst.append(new param(i18n("Check Dependencies"),TRUE,TRUE, "-f")); + paramsUninst.append(new param(i18n("Test (do not uninstall)"),FALSE,FALSE, "-n")); + + hasProgram = ifExe("pkg_info") && ifExe("pkg_add"); +} + +fbsdInterface::~fbsdInterface() { + +} + +bool fbsdInterface::isType(char *, const QString &fname) { + // These files are .tgz or .tbz files. Pass it to pkg_info and see whether it + // succeeds. + if (hasProgram) { + QString cmd = PKG_INFO_BIN; // cmd += "_q"; + cmd += " -q "; + cmd += fname; + kpty->run(cmd); + + if (!kpty->Result) + return true; + else + return false; + } else { + return false; + } +} + +static void insertGroups(QMap<QString, QString> *a, QString cats) +{ + /* Create the list of groups (which is space-separated), and then + ** iterate through it with the iterator i. count is just to + ** distinguish the first entry (count==0) from the rest, since + ** the key used in a->insert() needs to be different. + */ + QStringList grlist = QStringList::split(' ',cats); + unsigned int count = 0; + for (QStringList::Iterator i = grlist.begin(); + i != grlist.end(); ++count,++i) { + a->insert( (count ? "also in" : "group"), *i); + } +} + +packageInfo *fbsdInterface::getPackageInfo(char mode, const QString &pname, const QString &version) { + QString name( pname); + bool installed = false; + kpackage->setStatus(i18n("Getting package info")); + + kdDebug() << "Looking at package " << pname << endl; + + if (mode == 'i' && !version.isEmpty()) { + name += "-" + version; + } + + QMap<QString, QString> a; + + // Get the package name first (for mode = 'u'). + if (mode == 'u') { + QString cmd = PKG_INFO_BIN; // cmd += "_qf"; + cmd += " -qf "; + cmd += name; + QStringList list = kpty->run(cmd); + + int last_dir = name.find('/'); + if (last_dir != -1) { + a["filename"] = name.mid(last_dir+1); + a["base"] = name.left(last_dir + 1); + } else { + a["filename"] = name; + a["base"] = ""; + } + + if (list.count() > 0) { + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + // Look for a line of the form '@name <pkgname>' + if ((*it).left(5) == "@name") { + QString n = (*it).mid(6); + addNV(a, n); + break; + } + } + } else addNV(a, name); + } + + // Open a pipe to a pkg_info process in order to read the one line comment + // and description for the package. This works for both installed packages + // and for files. + QString cmd = PKG_INFO_BIN; // cmd += "_q"; + cmd += " -q "; + cmd += name; + QStringList list = kpty->run(cmd); + + QStringList::Iterator it = list.begin(); + + + if (list.count() > 0) { + QStringList::Iterator it = list.begin(); + a["summary"] = *it; + it++; + QString desc; + int prevlen = 0, len; + for ( ; it != list.end(); ++it ) { + len = (*it).length(); + desc += (*it); + // kdDebug() << len << " " << prevlen << "=" << *it << "\n"; + if (len > 0 || prevlen > 0) + desc += "<br>\n"; + prevlen = (*it).length(); + } + // kdDebug( << desc << "\n"; + bsdPortsIndexItem *inditem = ports[name]; + + if (inditem) { + installed = inditem->installed; + a["maintainer"] = inditem->fields[bsdPortsIndexItem::MAINT]; + + insertGroups(&a,inditem->fields[bsdPortsIndexItem::CATS]); + + a["build depends"] = !inditem->fields[bsdPortsIndexItem::BDEPS].isEmpty() ? inditem->fields[bsdPortsIndexItem::BDEPS] : i18n("none"); + a["available as"] = inditem->bin ? (inditem->port? i18n("binary package and source port") : i18n("binary package")) : i18n("source port"); + } + a["description"] = desc; + } else { + kpackage->setStatus(QString::null); + return 0; + } + + packageInfo *ret = new packageInfo(a, this); + ret->packageState = installed? packageInfo::INSTALLED : packageInfo::AVAILABLE; + ret->fixup(); + if (!installed) ret->smerge(typeID); + kpackage->setStatus(QString::null); + return ret; +} + +QStringList fbsdInterface::getChangeLog(packageInfo *) { + return 0; +} + + +bool fbsdInterface::filesTab(packageInfo *) { + return TRUE; +} + +bool fbsdInterface::changeTab(packageInfo *) { + return FALSE; +} + +QStringList fbsdInterface::getFileList(packageInfo *p) { + + // Run pkg_info on the package name to get the file list. + // The file list is returned on stdout, one per line. + kpackage->setStatus(i18n("Getting file list")); + + QStringList ret; + + // Find the full name 'name-version', or just 'name' if version is empty. + // Check first that it is actually installed. + QString name( p->getProperty("filename")); + + if (!name.isEmpty() && (p->packageState != packageInfo::INSTALLED)) { + QString qbname( p->getProperty("base")); + if (!qbname.isEmpty()) + name = qbname + "/" + name; + } else { + if (!p->hasProperty("name")) { + ret.append(i18n("Can't find package name!")); + kpackage->setStatus(QString::null); + return ret; + } + + name = p->getProperty("name"); + + QString version( p->getProperty("version")); + if (!version.isEmpty()) { + name = name + "-" + version; + } + } + + // Open a pipe to a pkg_info process in order to read the file list. + // This works for both installed packages and for files. + QString cmd = PKG_INFO_BIN; // cmd += "_Lq"; + cmd += " -L -q "; + cmd += name; + QStringList list = kpty->run(cmd); + + ret = list; + + kpackage->setStatus(QString::null); + return ret; +} + + +// QPtrList<char> *verify(packageInfo *p, QPtrList<char> *files); + +QString fbsdInterface::doUninstall(int uninstallFlags, const QString &packs, bool &) +{ + + QString s = PKG_DELETE_BIN; + s += " "; + s += setOptions(uninstallFlags, paramsUninst); + s += packs; + + kdDebug() << "uCMD=" << s << "\n"; + + return s; +} + + +QString fbsdInterface::doInstall(int installFlags, const QString &packs, bool &) +{ + + QString s = PKG_ADD_BIN; + s += " "; + s += setOptions(installFlags, paramsInst); + s += packs; + + kdDebug() << "iCMD=" << s << "\n"; + + return s; +} + +QString fbsdInterface::uninstall(int uninstallFlags, packageInfo *p, bool &test) +{ + QString packs( p->getProperty("name")); + QString vers( p->getProperty("version")); + if (vers.length() > 0) packs += "-" + vers; + + return doUninstall(uninstallFlags, packs, test); +} + +QString fbsdInterface::uninstall(int uninstallFlags, QPtrList<packageInfo> *p, bool &test) +{ + QString packs ; + packageInfo *i; + + for (i = p->first(); i!= 0; i = p->next()) { + packs += i->getProperty("name"); + QString vers( i->getProperty("version")); + if (vers.length() != 0) packs += "-" + vers; + packs += " "; + } + return doUninstall( uninstallFlags, packs, test); +} + +QStringList fbsdInterface::FindFile(const QString &, bool) { + QStringList tmp; + return tmp; +} + +bool fbsdInterface::parseName(const QString &name, QString *n, QString *v) { + int m1; + + m1 = name.findRev('-'); + if (m1 <= 0) return false; + *n = name.left(m1); + *v = name.right(name.length() - m1 - 1); + return true; +} + +void fbsdInterface::addNV(QMap<QString, QString> &d, const QString &name) { + QString n, v; + + if (!parseName(name, &n, &v)) { + n = name; + v = QString::null; + } + + d.insert("name", n); + d.insert("version", v); +} + + //public slots +void fbsdInterface::setLocation() { + locatedialog->restore(); +} + +void fbsdInterface::setAvail(LcacheObj *slist) { + kdDebug() << k_funcinfo << endl; + + if (packageLoc) delete packageLoc; + packageLoc = slist; + + cacheObj *cp = packageLoc->first(); + + if (cp && !cp->location.isEmpty()) { + for (; cp != 0; cp = packageLoc->next()) { + QString oldloc = cp->location; + cp->location += "/INDEX"; + QString s = getPackList(cp); + if (!s.isEmpty()) bsdPortsIndexItem::processFile(this, QFile::encodeName(s), true, oldloc); + cp->location = oldloc; + } + } + + // Try /usr/port/INDEX-<major version> on FreeBSD + struct utsname fbsdName; + if(uname(&fbsdName) != -1 && !strcmp(fbsdName.sysname, "FreeBSD")) + bsdPortsIndexItem::processFile(this, QString("/usr/ports/INDEX-").append(*fbsdName.release), false, "/usr/ports"); + + // Try the standard ports tree locations. + bsdPortsIndexItem::processFile(this, "/usr/ports/INDEX", false, "/usr/ports"); // FreeBSD/OpenBSD + bsdPortsIndexItem::processFile(this, "/usr/opt/INDEX", false, "/usr/opt"); // NetBSD +} + + +void fbsdInterface::listPackages(QPtrList<packageInfo> *pki) { + kdDebug() << k_funcinfo << endl; + + listInstalledPackages(pki); + + + QDictIterator<bsdPortsIndexItem> it( ports ); // See QDictIterator + for( ; it.current(); ++it ) { + bsdPortsIndexItem *scan = it.current(); + if (!scan->installed /*&& scan->bin */) { + QMap<QString, QString> a; + + addNV(a, scan->fields[bsdPortsIndexItem::NAME]); + a["summary"] = scan->fields[bsdPortsIndexItem::COMMENT]; + a["maintainer"] = scan->fields[bsdPortsIndexItem::MAINT]; + + insertGroups(&a,scan->fields[bsdPortsIndexItem::CATS]); + + a["run depends"] = !scan->fields[bsdPortsIndexItem::RDEPS].isEmpty() ? scan->fields[bsdPortsIndexItem::RDEPS] : i18n("none"); + a["build depends"] = !scan->fields[bsdPortsIndexItem::BDEPS].isEmpty() ? scan->fields[bsdPortsIndexItem::BDEPS] : i18n("none"); + a["available as"] = scan->bin ? (scan->port? i18n("binary package and source port") : i18n("binary package")) : i18n("source port"); + + a["filename"] = scan->bin_filename; + a["base"] = scan->bin_filename_base; + + packageInfo *info = new packageInfo(a, this); + info->packageState = packageInfo::AVAILABLE; + info->smerge(typeID); + info->fixup(); + info->pkgInsert(pki, typeID, false); +// pki->append(info); + } + } + +} + +int fbsdInterface::parseItem(QStringList::Iterator &it, QString &name, QString &value, QString separator, QStringList list ) { + if ((*it).left(separator.length()) == separator) { + name = *it; + name = name.mid(separator.length()); + } else { + return -1; + } + if (it == list.end()) + return -1; + it++; + + value = ""; + int prevlen = 0, len; + while ((*it).left(separator.length()) != separator) { + len = (*it).length(); + value += *it; + if (len > 0 || prevlen > 0) + value += "<br>"; + if (it == list.end()) + return -1; + prevlen = (*it).length(); + it++; + } + return 1; +} + +int fbsdInterface::pathInfo(QMap<QString, QString> &a) +{ + int pkg_state = packageInfo::INSTALLED; + if (a["group"].isEmpty()) { + QString s, ps; + ps = a["name"]; + if (ps.isEmpty()) + s = ps; + else + s = "<anonymous>"; + + ps = a["version"]; + if (!ps.isEmpty()) + s.append(QString("-")+(ps)); + + kdDebug() << "Package " << (s) << " has no group." << endl; + + /* This must be an installed package with no INDEX entry, + ** which usually means that the port has been updated. + */ + QString cmd = PKG_INFO_BIN; + // cmd += "2"; + cmd += " -ol "; + cmd += INFO_SEPARATOR; + QStringList list = kpty->run(cmd); + + if (list.count() > 0) { + QStringList::Iterator it = list.begin(); + QString name, value; + parseItem(it, name, value, INFO_SEPARATOR, list); // Information + parseItem(it, name, value, INFO_SEPARATOR, list); // Path + + int pos = value.findRev('/'); + value.truncate(pos); + a["group"] = value; + } else { + kdDebug() << "Could not read package origin info." << endl; + } + } + return pkg_state; +} + + void fbsdInterface::listInstalledPackages(QPtrList<packageInfo> *pki) { + kdDebug() << k_funcinfo << endl; + + // Open a pipe to a pkg_info process in order to read the comment, name + // and description for the packages. + + kpackage->setStatus(i18n("Querying BSD packages database for installed packages")); + + QString cmd = PKG_INFO_BIN; + cmd += " -acdl "; + cmd += INFO_SEPARATOR; + QStringList list = kpty->run(cmd); + + // We should now get: + // INFO_SEPARATORInformation for pkgname: + // + // INFO_SEPARATORComment: + // <one line description> + // + // INFO_SEPARATORDescription: + // <description> + // + // + // INFO_SEPARATOR + // INFO_SEPARATORInformation for [etc] + + QMap<QString, QString> a; + QString name, value; + if (list.count() > 0) { + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + + parseItem(it, name, value, INFO_SEPARATOR, list); // Information + // Find the last word on this line (which should be the package name) minus a trailing :. + QString pkg = name.section(' ',-1); + if (pkg.isEmpty()) { + KpMsgE(i18n("Unexpected output from pkg_info (looking for package name): %1").arg(value), TRUE); + kpackage->setStatus(QString::null); + return; + } else { + if (pkg[pkg.length()-1] == ':') { + pkg.truncate(pkg.length()-1); + } + } + addNV(a, pkg); + + parseItem(it, name, value, INFO_SEPARATOR, list); //Comment + a["summary"] = value; + + + parseItem(it, name, value, INFO_SEPARATOR, list); //Description + + bsdPortsIndexItem *inditem = ports[pkg]; + + if (inditem) { + inditem->installed = true; + + a["maintainer"] = inditem->fields[bsdPortsIndexItem::MAINT]; + + insertGroups(&a,inditem->fields[bsdPortsIndexItem::CATS]); + if (a["group"].isEmpty()) { + kdDebug() << "Line <" << name << "=" << value << "> has no group?" << endl; + } + + a["run depends"] = !inditem->fields[bsdPortsIndexItem::RDEPS].isEmpty() ? + inditem->fields[bsdPortsIndexItem::RDEPS] : i18n("none"); + a["build depends"] = !inditem->fields[bsdPortsIndexItem::BDEPS].isEmpty() ? + inditem->fields[bsdPortsIndexItem::BDEPS] : i18n("none"); + a["available as"] = inditem->bin ? (inditem->port? i18n("binary package and source port") : i18n("binary package")) : i18n("source port"); + } + + a["description"] = value; + + int pkg_state = pathInfo(a); + packageInfo *info = new packageInfo(a, this); + info->packageState = pkg_state; + + info->fixup(); + //pki->append(info); + info->pkgInsert(pki, typeID, true); + + } + } +} + + +bsdPortsIndexItem::bsdPortsIndexItem(fbsdInterface *parent, char *desc, bool binaries, const QString &dname) : bin(binaries), port(!binaries), installed(false) { + fields = QStringList::split('|', desc, TRUE); + QString name = fields[NAME]; + + bsdPortsIndexItem *port = parent->ports[name]; + if (port) { + port->bin = port->bin || bin; + port->port = port->port || port; + if (binaries) { + port->bin_filename = QString(name) + ".tbz"; + port->bin_filename_base = dname + "/"; + } + fields[NAME] = ""; // Acts as a 'not used' tag. + return; + + } + if (binaries) { + bin_filename = QString(name) + ".tbz"; + bin_filename_base = dname + "/"; + } + +} + +void bsdPortsIndexItem::processFile(fbsdInterface *parent, const QString &fname, bool binaries, const QString &dname) { + // Read the file in to a buffer and null terminate it. + + struct stat s; + + if (stat(fname.ascii(), &s) == -1) { + // Error message? + return; + } + + char *index = (char *) malloc(s.st_size); + int fd; + + fd = open(fname.ascii(), O_RDONLY); + if (fd == -1) { + // Error message? + return; + } + + int size = read(fd, index, s.st_size); + index[size] = 0; + close(fd); + + + // Go through each line and create a new bsdPortsIndexItem. + char *line = strtok(index, "\n"); + while (line != 0) { + bsdPortsIndexItem *i = new bsdPortsIndexItem(parent, line, binaries, dname + "/All"); + if (i->fields[NAME].isEmpty()) { + delete i; + } else { + parent->ports.insert(i->fields[NAME] , i); + } + line = strtok(0, "\n"); + } +} + + +#include "fbsdInterface.moc" diff --git a/kpackage/fbsdInterface.h b/kpackage/fbsdInterface.h new file mode 100644 index 0000000..270b0c9 --- /dev/null +++ b/kpackage/fbsdInterface.h @@ -0,0 +1,158 @@ +/* +** Copyright (C) 2000 by Alex Hayward +** +*/ + + +/* +** 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 +*/ + +#ifndef FBSD_IFACE_H +#define FBSD_IFACE_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +//#ifdef HAVE_FBSD_PKGTOOLS + +#include <qptrlist.h> +#include <qmap.h> + +#include "packageInfo.h" +#include "pkgInterface.h" + +class KDir; +class cacheObj; +class bsdPortsIndexItem; + +class fbsdInterface : public pkgInterface +{ + Q_OBJECT + +public: + fbsdInterface(); + ~fbsdInterface(); + + void init(); + + bool isType(char *buf, const QString &fname); + + packageInfo *getPackageInfo(char mode, const QString &name, const QString &version); + QStringList getFileList(packageInfo *p); + QStringList getChangeLog(packageInfo *p); + + bool filesTab(packageInfo *p); + // If files tab is to be enabled + + bool changeTab(packageInfo *p); + // If change log tab is to be enabled + + QString uninstall(int uninstallFlags, QPtrList<packageInfo> *p, bool &test); + QString uninstall(int uninstallFlags, packageInfo *p, bool &test); + QString doUninstall(int uninstallFlags, const QString &packs, bool &test); + QString doInstall(int installFlags, const QString &packs, bool &test); + + QStringList FindFile(const QString &name, bool seachAll=false); + void collectDepends(packageInfo *p, const QString &name, int src); + bool parseName(const QString& name, QString *n, QString *v); + + void listInstalledPackages(QPtrList<packageInfo> *pki); + void listPackages(QPtrList<packageInfo> *pki); + + QDict <bsdPortsIndexItem> ports; +public slots: + void setLocation(); + void setAvail(LcacheObj *); + +private: + /** + * @short Add the name and version identifiers to a QMap<QString, QString>. + * + * name is parsed in to name and version and these are added to + * d. Errors are handled. + */ + void addNV(QMap<QString, QString> &d, const QString &name); + int parseItem(QStringList::Iterator &it, QString &name, QString &value, QString separator, QStringList list ); + int pathInfo(QMap<QString, QString> &a); + +}; + +/** + * @short Ports description linked list item + * + * Each item in the list describes one port from the ports collection. + */ +class bsdPortsIndexItem { +public: + /** + * desc is a line from the INDEX file (/usr/ports/INDEX under FreeBSD) + * which has a particular format: + * + * name|port path|inst prefix|1 line commect|DESCR file|maintainer|categories|build-deps|run-deps + * + * Multiple space separated categories may be specified. + * + * desc must remain allocated (ie, its not copied) will be modified. + * + * binaries should be true if this is a binary package. + * + * dname is the name of the base directory of this ports/packages tree. + */ + bsdPortsIndexItem(fbsdInterface *parent, char *desc, bool binaries, const QString &dname); + + /** @short true if this has a binary packages. */ + bool bin; + + /** @short true if this has a source port available. */ + bool port; + + /** @short true if this package is installed (set in listInstalledPackages) */ + bool installed; + + /** @short The next item in this linked list */ + bsdPortsIndexItem *next; + + QStringList fields; + + enum {NAME=0, PATH, PREFIX, COMMENT, DESC_PATH, MAINT, CATS, BDEPS, RDEPS}; + + QString bin_filename; + QString bin_filename_base; + QString port_dirname; + + /** + * @short Given the path to an INDEX file process each port in it. + * + * binaries should be true if the file is an index for packages, false for ports. + * dname is the base directory. + */ + static void processFile(fbsdInterface *parent, const QString &fname, bool binaries, const QString &dname); + +private: + unsigned int name_hash; + static unsigned char calc_hash1(const char *name); + static unsigned int calc_hash4(const char *name); + static unsigned char hash1(unsigned int hash4); +}; + +#endif + diff --git a/kpackage/findf.cpp b/kpackage/findf.cpp new file mode 100644 index 0000000..20e6a7c --- /dev/null +++ b/kpackage/findf.cpp @@ -0,0 +1,228 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#include "../config.h" + +#include <qlineedit.h> +#include <qpainter.h> + +#include <klocale.h> +#include <kdebug.h> +#include <kurldrag.h> +#include <kiconloader.h> + +#include "kpackage.h" +#include "managementWidget.h" +#include "findf.h" +#include "options.h" +#include "pkgInterface.h" + +extern pkgInterface *kpinterface[]; +extern Opts *opts; + +FindF::FindF(QWidget *parent) + : KDialogBase(parent, "find_file", false, + i18n("Find File"), + User1 | Close, User1, true, + KGuiItem(i18n("&Find"),"filefind")) +{ + tick = UserIcon("ptick"); + + QFrame *page = makeMainWidget(); + + setFocusPolicy(QWidget::StrongFocus); + + QVBoxLayout* vtop = new QVBoxLayout( page, 10, 10, "vtop"); + QFrame *frame1 = new QGroupBox(i18n("Find Package"), page, "frame1"); + vtop->addWidget(frame1,1); + + QGridLayout* gtop = new QGridLayout( frame1, 1, 1, 20 ); + // gtop->setMargin( KDialog::marginHint() ); + gtop->setSpacing( KDialog::spacingHint() ); + + value = new QLineEdit( frame1, "value" ); + connect(value,SIGNAL(textChanged ( const QString & )),this,SLOT(textChanged ( const QString & ))); + value->setFocus(); + + QLabel *valueLabel = new QLabel(value, i18n("Find:"), frame1); + valueLabel->setAlignment( AlignRight ); + + tab = new KListView(frame1, "tab"); + connect(tab, SIGNAL(selectionChanged ( QListViewItem * )), + this, SLOT(search( QListViewItem * ))); + tab->addColumn(i18n("Installed"),18); + tab->addColumn(i18n("Type"),110); + tab->addColumn("",0); // Hidden column for package type + tab->addColumn(i18n("Package"),180); + tab->addColumn(i18n("File Name"),330); + tab->setAllColumnsShowFocus(TRUE); + tab->setSorting(1); + + if (kpackage->management->dirInstPackages->find("apt-file/deb")) { + searchAll = new QCheckBox(i18n("Also search uninstalled packages"), frame1, "searchAll"); + } else { + searchAll = new QCheckBox(i18n("Also search uninstalled packages (apt-file needs to be installed)"), frame1, "searchAll"); + } + searchAll->setChecked(FALSE); + + gtop->addWidget(valueLabel, 0, 0); + gtop->addWidget(value, 0, 1); + gtop->addMultiCellWidget(tab, 1, 1, 0, 1); + + gtop->addWidget(searchAll, 2, 0); + + connect(this, SIGNAL(user1Clicked()), this, SLOT(ok_slot())); + connect(this, SIGNAL(closeClicked()), this, SLOT(done_slot())); + enableButton(User1 , false); + show(); + + setAcceptDrops(true); +} + +FindF::~FindF() +{ +} + +void FindF::checkSearchAll() +{ + // button not enabled if no package interface has search uninstalled + // packages for files ability + bool hasAll = FALSE; + for (int i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i] && opts->handlePackage[i]) { + if (kpinterface[i]->hasSearchAll) + hasAll = TRUE; + } + } + + searchAll->setEnabled(hasAll); +} + +void FindF::textChanged ( const QString & text) +{ + enableButton(User1 , !text.isEmpty()); +} + +void FindF::ok_slot() +{ + doFind(value->text()); +} + +void FindF::doFind(const QString &str) +{ + QString t; + int i, cnt = 0; + + bool all = searchAll->isChecked(); + + QApplication::setOverrideCursor( waitCursor ); + + tab->clear(); + + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i] && opts->handlePackage[i]) { + QStringList filelist = kpinterface[i]->FindFile(str, all); + + if (filelist.count() > 0) { + cnt++; + + for ( QStringList::Iterator it = filelist.begin(); it != filelist.end(); ++it ) { + if ((*it).find("diversion by") >= 0) { + new QListViewItem(tab, "", *it); + } + + int t1 = (*it).find('\t'); + QString s1 = (*it).left(t1); + QString s2 = (*it).right((*it).length()-t1); + s2 = s2.stripWhiteSpace(); + + QListViewItem *ql = new QListViewItem(tab, "", kpinterface[i]->name, kpinterface[i]->head, s1, s2); + + QString tx = s1 + kpinterface[i]->typeID; + if (kpackage->management->dirInstPackages->find(tx)) { + ql->setPixmap(0,tick); + } + } + } + } + } + + if (!cnt) { + new QListViewItem(tab, "", i18n("--Nothing found--")); + } + + QApplication::restoreOverrideCursor(); +} + +void FindF::done_slot() +{ + hide(); +} + +void FindF::resizeEvent(QResizeEvent *){ +} + +void FindF::search(QListViewItem *item) +{ + int p; + + QString s = item->text(3); + s = s.stripWhiteSpace(); + kdDebug() << "searchF=" << s << "\n"; + + p = s.find(','); + if (p > 0) { + s.truncate(p); + } + + KpTreeListItem *k = kpackage->management->treeList->search(s ,item->text(2)); + if (k) + kpackage->management->treeList->changePack(k); +} + +void FindF::dragEnterEvent(QDragEnterEvent* e) +{ + e->accept(KURLDrag::canDecode(e)); +} + +void FindF::dropEvent(QDropEvent *de) // something has been dropped +{ + KURL::List list; + if (!KURLDrag::decode(de, list) || list.isEmpty()) + return; + + const KURL &url = list.first(); + + if (url.isLocalFile()) { + QString file = url.path(-1); + value->setText(file); + doFind(file); + } else { + KpMsgE(i18n("Incorrect URL type"),FALSE); + } +} + +#include "findf.moc" diff --git a/kpackage/findf.h b/kpackage/findf.h new file mode 100644 index 0000000..5208c05 --- /dev/null +++ b/kpackage/findf.h @@ -0,0 +1,91 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + +#ifndef FINDF_H +#define FINDF_H + +#include "../config.h" + +// Standard Headers +#include <stdio.h> + +// Qt Headers +#include <qdir.h> +#include <qwidget.h> +#include <qframe.h> +#include <qlabel.h> +#include <qfiledialog.h> +#include <qgroupbox.h> +#include <qcheckbox.h> +#include <qlayout.h> + +// KDE headers +#include <kapplication.h> +#include <kmenubar.h> +#include <klistview.h> +#include <kdialogbase.h> + +class FindF : public KDialogBase +{ + Q_OBJECT + +public: + + FindF ( QWidget *parent = 0); + ~FindF(); + void resizeEvent(QResizeEvent *); + void dropEvent(QDropEvent *); + void dragEnterEvent(QDragEnterEvent* e); + void checkSearchAll(); + + +private: + void doFind(const QString &str); + // Do the actual search + + QLineEdit *value; + QListView *tab; + QVBoxLayout* vl; + QVBoxLayout* vtop, vf; + + QHBoxLayout* hb; + QCheckBox *searchAll; + QPixmap tick; + +signals: + void findf_signal(); + void findf_done_signal(); + +public slots: + void done_slot(); + void ok_slot(); + void search(QListViewItem *); + void textChanged ( const QString & text); + +}; + +#endif diff --git a/kpackage/gentooInterface.cpp b/kpackage/gentooInterface.cpp new file mode 100644 index 0000000..a8ef275 --- /dev/null +++ b/kpackage/gentooInterface.cpp @@ -0,0 +1,466 @@ +/* +** +** Copyright (C) 2004 Richard Lärkäng <nouseforaname@home.se> +** +** 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. +*/ + +#include "gentooInterface.h" +#include "updateLoc.h" +#include "kpackage.h" +#include "cache.h" +#include "kpTerm.h" +#include <klocale.h> +#include <kiconloader.h> +#include <kdebug.h> +#include <kfilterdev.h> + +/* TODO + + Make it possible to 'emerge sync' + + Add possibilty for package manager plugins to have own compare version method, + and use it here for: (alpha|beta|pre|rc|p) + + Slots, how to do that in a good way? + + Should we care about the world-file? + + Read masked packages from /usr/portage/profiles/package.mask + + Use flags and CFLAGS? + + Should read arch from make.conf along with directories etc + "~arch" implies "arch" + + Do something about locateDialog, I don't want it here, + but I would like it to be possible to add own configuration, + and I don't like the crash when clicking locate ;-) +*/ + +Gentoo::Gentoo() + : pkgInterface() +{ + head = "Gentoo"; + name = i18n("Gentoo"); + icon = "gentoo"; + + pict = UserIcon(icon); + updated_pict = UserIcon("kupdated"); + new_pict = UserIcon("knew"); + + packagePattern = "*.ebuild"; + //typeID = "/kiss"; + + queryMsg = i18n("Querying Gentoo package list: "); + + archesPossible << "~x86" << "x86"; + portageDir="/usr/portage/"; + QFile f(portageDir+"profiles/package.mask"); + if (f.open(IO_ReadOnly)) + { + QTextStream stream( &f ); + + QString line; + while (!stream.atEnd()) + { + line = stream.readLine(); + if (!line.startsWith("#") && !line.isEmpty()) + { + // kdDebug() << "Adding: " << line << " to packageMask" << endl; + packageMask << line; + } + } + } + + hasProgram = ifExe("emerge"); +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +Gentoo::~Gentoo() +{ +} + +////////////////////////////////////////////////////////////////////////////// +bool Gentoo::isType(char * /*buf*/, const QString &) +{ + return false; +} + +bool Gentoo::parseName(const QString& name, QString *n, QString *v) +{ + // Taken from the portage code, should be correct + QRegExp r("([^/]+)-((\\d+(\\.\\d+)*[a-z]*)(_(alpha|beta|pre|rc|p)\\d*)?(-r(\\d+))?)$"); + + r.search(name); + + *n = r.cap(1); + *v = r.cap(2); + + if (n->isEmpty() || v->isEmpty()) + return false; + else + return true; +} + +void Gentoo::listInstalledPackages(QPtrList<packageInfo> *pki) +{ + QString vb; + packageInfo *p; + + QString sline = i18n("Looking for Gentoo packages: "); + + kpackage->setStatus(sline); + kpackage->setPercent(0); + + QFile f(portageDir+"profiles/categories"); + if (!f.open(IO_ReadOnly)) + { + kdWarning() << "Couldn't open categories file" << endl; + return; + } + + QTextStream stream( &f ); + QStringList categories; + while (!stream.atEnd()) + { + categories.append(stream.readLine()); + } + + int categoriesCount = categories.count(); + int categoriesDone = 0; + for (QStringList::Iterator category = categories.begin(); category != categories.end(); ++category) + { + kpackage->setPercent(categoriesDone/categoriesCount); + categoriesDone += 100; + + if (*category == "packages" || *category == "local" || *category == "virtual") + continue; + + QDir d("/var/db/pkg/"+*category); + QStringList packages = d.entryList(QDir::Dirs); + for (QStringList::Iterator it = packages.begin(); it != packages.end(); ++it) + { + if (*it != "." && *it != "..") + { + p = collectInstalledInfo(*it, *category); + if (p) + { + if (!p->pkgInsert(pki, typeID, true)) + { + delete p; + } + } + } + } + d.setPath("/var/cache/edb/dep/"+*category); + packages = d.entryList(QDir::Files); + for (QStringList::Iterator it = packages.begin(); it != packages.end(); ++it) + { + if (*it != "." && *it != "..") + { + bool isMasked = false; + QString version, name; + if (!parseName(*it, &name, &version)) + { + kdDebug() << "Couldn't parse name: " << *it << endl; + continue; + } + + for (QStringList::Iterator maskIt = packageMask.begin(); maskIt != packageMask.end(); ++maskIt) + { + // FIXME Should all be handled, just not implemented yet + if ((*maskIt).startsWith("<") || (*maskIt).startsWith("=") || (*maskIt).startsWith("~") || (*maskIt).startsWith(">")) + continue; + if (*category+"/"+name == *maskIt) + { + kdDebug() << "Package: " << name << "-" << version << " is masked" << endl; + isMasked = true; + break; + } + } + + if (isMasked) + continue; + + p = collectUninstalledInfo(name, *category, version); + if (p) + { + if (!p->pkgInsert(pki, typeID, false)) + { + delete p; + } + } + } + } + } + +/* +*/ + kpackage->setPercent(100); +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +// mode: i = query installed u = query uninstalled +packageInfo *Gentoo::getPackageInfo(char mode, const QString &name, const QString &version) +{ + packageInfo *pki = 0; + QString vb,search; + + switch(mode) + { + //////////////////////////////////////////////////////////////////////// + // query an installed package! + case 'i': + pki = collectInstalledInfo(name, ""/*FIXME*/); + break; + + //////////////////////////////////////////////////////////////////// + // query an uninstalled package + case 'u': + pki = collectUninstalledInfo(name, ""/*FIXME*/, version); + break; + } + return pki; +} + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +packageInfo *Gentoo::collectInstalledInfo(const QString& name, const QString& category) +{ + QMap<QString, QString> a; + + QIODevice* iod(KFilterDev::deviceForFile("/var/db/pkg/"+category+"/"+name+"/environment.bz2","application/x-bzip2", true)); + QString line; + if (!iod->open(IO_ReadOnly)) + return 0; + QTextStream stream( iod ); + QString n, version, description; + while (!stream.atEnd()) + { + line = stream.readLine(); + if (line.startsWith("PN=")) + { + n = line.mid(3); + a.insert("name", n); + } + else if (line.startsWith("PVR=")) + { + version = line.mid(4); + a.insert("version", version); + } + else if (line.startsWith("DESCRIPTION=")) + { + description = line.mid(12); + a.insert("summary", description); + } + if (a.count() >= 3) + break; + } + delete iod; + a.insert("group", category); +// a.insert("file-size", "File-size"); +// a.insert("size", "Installed-size"); + + packageInfo *i = new packageInfo(a,this); + i->packageState = packageInfo::INSTALLED; + i->fixup(); + return i; +} + +////////////////////////////////////////////////////////////////////////////// +packageInfo *Gentoo::collectUninstalledInfo(const QString& name, const QString& category, const QString& version) +{ + QMap<QString, QString> a; + + a.insert("name", name); + a.insert("group", category); + a.insert("version", version); + a.insert("base", portageDir+category+"/"+name); + a.insert("filename", name+"-"+version+".ebuild"); + + QFile f("/var/cache/edb/dep/"+category+"/"+name+"-"+version); + if (!f.open(IO_ReadOnly)) + { + kdDebug() << "Couldn't read: " << name << "-" << version << endl; + return 0; + } + + // Dep format: + // 1: DEPEND? + // 2: RDEPEND? + // 3: SLOT + // 4: SOURCE_URI + // 5: FEATURES + // 6: HOMEPAGE + // 7: LICENSE + // 8: DESCRIPTION + // 9: KEYWORDS (arch) + // 10: ECLASSES (inherited) + // 11: IUSE + + // Skip first 7 lines for now + QTextStream stream( &f ); + for (int i=0; i < 7 && !stream.atEnd(); i++) + stream.readLine(); + + if (!stream.atEnd()) + a.insert("summary", stream.readLine()); + + QStringList keywords = QStringList::split(' ', stream.readLine()); + + bool works = false; + for (QStringList::Iterator it = keywords.begin(); it != keywords.end(); ++it) + { + for (QStringList::Iterator it2 = archesPossible.begin(); it2 != archesPossible.end(); ++it2) + { + if (*it == *it2) + { + works = true; + break; + } + } + if (works) + break; + } + + if (!works) + { +// kdDebug() << name << "-" << version << ": Doesn't contain working arch" << endl; + return 0; + } + + packageInfo *i = new packageInfo(a,this); + i->packageState = packageInfo::AVAILABLE; + i->fixup(); + return i; +} + +////////////////////////////////////////////////////////////////////////////// + +QStringList Gentoo::getChangeLog(packageInfo *p) { + QStringList clog; + QFile f(portageDir+p->getProperty("group")+"/"+p->getProperty("name")+"/ChangeLog"); + if (!f.open(IO_ReadOnly)) + return clog; + QTextStream stream(&f); + while (!stream.atEnd()) + clog.append(stream.readLine()); + return clog; +} + + +bool Gentoo::filesTab(packageInfo *p) { + return p->packageState == packageInfo::INSTALLED; +} + +bool Gentoo::changeTab(packageInfo *) { + return true; +} + +////////////////////////////////////////////////////////////////////////////// +QStringList Gentoo::getFileList(packageInfo *p) +{ + QStringList filelist; + + QFile f("/var/db/pkg/"+p->getProperty("group")+"/"+p->getProperty("name")+"-"+p->getProperty("version")+"/CONTENTS"); + if (!f.open(IO_ReadOnly)) + return filelist; + QTextStream stream(&f); + QString line; + QRegExp removeEnd("(.*)( [a-f0-9]{32} [0-9]+| -> [^ ] [0-9]+| -> [^\\(]*\\([^\\)]*\\))$"); + while (!stream.atEnd()) + { + line = stream.readLine(); + + int pos=0; + while (line[pos] != ' ') pos++; + + line = line.mid(pos+1); + + removeEnd.search(line); + QString cap = removeEnd.cap(1); + if (!cap.isEmpty()) + line = cap; + + filelist.append(line); + } + + return filelist; +} + +////////////////////////////////////////////////////////////////////////////// +QString Gentoo::uninstall(int , QPtrList<packageInfo> *plist, bool &test) +{ + QString cmd; + packageInfo *pk; + + if (test) + cmd = "NOCOLOR=\"true\" emerge unmerge -p "; + else + cmd = "NOCOLOR=\"true\" emerge unmerge "; + + for (pk = plist->first(); pk != 0; pk = plist->next()) { + cmd += "=" + pk->getProperty("group") + "/" + pk->getProperty("name") + + "-" + pk->getProperty("version") + " "; + } + return cmd; +} + +////////////////////////////////////////////////////////////////////////////// +QString Gentoo::install(int, QPtrList<packageInfo> *plist, bool &test) +{ + QString cmd; + packageInfo *pk; + + if (test) + cmd = "NOCOLOR=\"true\" emerge -p "; + else + cmd = "NOCOLOR=\"true\" emerge "; + + for (pk = plist->first(); pk != 0; pk = plist->next()) { + cmd += "=" + pk->getProperty("group") + "/" + pk->getProperty("name") + + "-" + pk->getProperty("version") + " "; + } + return cmd; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +QStringList Gentoo::FindFile(const QString &, bool) +{ + return QStringList(); +} + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +void Gentoo::setLocation() +{ + +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +void Gentoo::setAvail(LcacheObj *slist) +{ + Q_UNUSED(slist) +} + +#include "gentooInterface.moc" diff --git a/kpackage/gentooInterface.h b/kpackage/gentooInterface.h new file mode 100644 index 0000000..12eaedb --- /dev/null +++ b/kpackage/gentooInterface.h @@ -0,0 +1,68 @@ +/* +** +** Copyright (C) 2004 Richard Lärkäng <nouseforaname@home.se> +** +** 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. +*/ + +#ifndef GENTOOINTERFACE_H +#define GENTOOINTERFACE_H + +#include "pkgInterface.h" + +class Gentoo : public pkgInterface +{ + Q_OBJECT + +public: + Gentoo(); + ~Gentoo(); + + bool isType(char *buf, const QString &fname); + param *initinstallOptions(); + param *inituninstallOptions(); + packageInfo *getPackageInfo(char mode, const QString &name, const QString &version); + QStringList getFileList(packageInfo *p); + QStringList getChangeLog(packageInfo *p); + + bool filesTab(packageInfo *p); + // If files tab is to be enabled + + bool changeTab(packageInfo *p); + // If change log tab is to be enabled + + QStringList FindFile(const QString &name, bool seachAll=false); + bool parseName(const QString& name, QString *n, QString *v); + +public slots: + void setLocation(); + void setAvail(LcacheObj *); + +private: + packageInfo* collectInstalledInfo(const QString& name, const QString& category); + packageInfo* collectUninstalledInfo(const QString& name, const QString& category, const QString& version); + void listInstalledPackages(QPtrList<packageInfo> *pki); + + QString install(int installFlags, QPtrList<packageInfo> *plist, bool &test); + QString uninstall(int uninstallFlags, QPtrList<packageInfo> *plist, bool &test); + + QStringList archesPossible; + QString portageDir; + QStringList packageMask; +}; + + +#endif // GENTOOINTERFACE_H diff --git a/kpackage/icon/Makefile.am b/kpackage/icon/Makefile.am new file mode 100644 index 0000000..7e0a8ef --- /dev/null +++ b/kpackage/icon/Makefile.am @@ -0,0 +1 @@ +KDE_ICON = kpackage diff --git a/kpackage/icon/hi128-app-kpackage.png b/kpackage/icon/hi128-app-kpackage.png Binary files differnew file mode 100644 index 0000000..8277291 --- /dev/null +++ b/kpackage/icon/hi128-app-kpackage.png diff --git a/kpackage/icon/hi16-app-kpackage.png b/kpackage/icon/hi16-app-kpackage.png Binary files differnew file mode 100644 index 0000000..fc716d0 --- /dev/null +++ b/kpackage/icon/hi16-app-kpackage.png diff --git a/kpackage/icon/hi22-app-kpackage.png b/kpackage/icon/hi22-app-kpackage.png Binary files differnew file mode 100644 index 0000000..b89a591 --- /dev/null +++ b/kpackage/icon/hi22-app-kpackage.png diff --git a/kpackage/icon/hi32-app-kpackage.png b/kpackage/icon/hi32-app-kpackage.png Binary files differnew file mode 100644 index 0000000..b938d97 --- /dev/null +++ b/kpackage/icon/hi32-app-kpackage.png diff --git a/kpackage/icon/hi48-app-kpackage.png b/kpackage/icon/hi48-app-kpackage.png Binary files differnew file mode 100644 index 0000000..4f629ea --- /dev/null +++ b/kpackage/icon/hi48-app-kpackage.png diff --git a/kpackage/icon/hi64-app-kpackage.png b/kpackage/icon/hi64-app-kpackage.png Binary files differnew file mode 100644 index 0000000..2053a1e --- /dev/null +++ b/kpackage/icon/hi64-app-kpackage.png diff --git a/kpackage/kio.cpp b/kpackage/kio.cpp new file mode 100644 index 0000000..1eb6f52 --- /dev/null +++ b/kpackage/kio.cpp @@ -0,0 +1,124 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#include <kapplication.h> +#include <kdebug.h> +#include "kio.h" + +Kio::Kio() +{ +} + +bool Kio::download(const KURL & from, const QString & to) +{ + KIO::Job *iojob = KIO::file_copy(from, to); + connect( iojob, SIGNAL( result(KIO::Job*) ), + SLOT( slotIOJobFinished( KIO::Job* ))); + // missing modal widget hack here. + // I'd recommend using KIO::NetAccess instead (David). + kapp->enter_loop(); + return worked; +} + +void Kio::slotIOJobFinished( KIO::Job * job) +{ + worked = (job->error() == 0); + kapp->exit_loop(); +} + +Kiod::Kiod() +{ + file=0L; + fileT = 0L; +} + +Kiod::~Kiod() +{ + delete file; + delete fileT; +} + +bool Kiod::listDir(const QString &url, const QString &fname, bool subdirs) +{ + delete file; + file = new QFile(fname); + if (file->open(IO_WriteOnly)) { + delete fileT; + fileT = new QTextStream(file); + KIO::ListJob *job; + if (!subdirs) + job = KIO::listDir( url ); + else + job = KIO::listRecursive( url, false); + + kdDebug() << "started " << job << " " << subdirs << endl; + + QObject::connect( job, SIGNAL( entries( KIO::Job*, const KIO::UDSEntryList& ) ), + SLOT( slotListEntries( KIO::Job*, const KIO::UDSEntryList& ) ) ); + QObject::connect( job, SIGNAL( result( KIO::Job * ) ), + SLOT( slotFinished( KIO::Job* ) ) ); + + kapp->enter_loop(); + + file->close(); + if (worked) + return TRUE; + else + return FALSE; + } else + return FALSE; +} + +void Kiod::slotListEntries( KIO::Job *, const KIO::UDSEntryList& entries ) +{ + long size = 0; + QString text; + + KIO::UDSEntryList::ConstIterator entryIt = entries.begin(); + + for (; entryIt != entries.end(); ++entryIt) { + //kdDebug() << "listDir " << dynamic_cast<KIO::ListJob*>(job)->url() << endl; + for (KIO::UDSEntry::ConstIterator it = (*entryIt).begin(); + it != (*entryIt).end(); it++ ) + { + if ( (*it).m_uds == KIO::UDS_SIZE ) + size = (*it).m_long; + else if ( (*it).m_uds == KIO::UDS_NAME ) + text = (*it).m_str; + } + *fileT << text << "\n" << size << "\n"; + kdDebug() << text << " " << size << "\n"; + } +} + +void Kiod::slotFinished( KIO::Job *job ) +{ + //kdDebug() << "finished" << " " << job << " " << dynamic_cast<KIO::ListJob*>(job)->url() << endl; + worked = (job->error() == 0); + kapp->exit_loop(); +} + +#include "kio.moc" diff --git a/kpackage/kio.h b/kpackage/kio.h new file mode 100644 index 0000000..60614ea --- /dev/null +++ b/kpackage/kio.h @@ -0,0 +1,75 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + +#ifndef KP_KIO_H +#define KP_KIO_H + + +#include <vector> + +#include <qobject.h> +#include <qfile.h> +#include <qtextstream.h> +#include "../config.h" +#include <kio/job.h> + +class Kio: public QObject +{ + Q_OBJECT + +public: + Kio(); + + bool download(const KURL & from, const QString & to); + +private: + bool worked; + +private slots: + void slotIOJobFinished( KIO::Job *job ); +}; + +class Kiod: public QObject +{ + Q_OBJECT + +public: + Kiod(); + ~Kiod(); + + bool listDir(const QString &url, const QString &fname, bool subdirs); + +private: + QFile *file; + QTextStream *fileT; + bool worked; + +private slots: + void slotListEntries( KIO::Job *, const KIO::UDSEntryList& ); + void slotFinished( KIO::Job *); +}; +#endif diff --git a/kpackage/kissInterface.cpp b/kpackage/kissInterface.cpp new file mode 100644 index 0000000..a568a18 --- /dev/null +++ b/kpackage/kissInterface.cpp @@ -0,0 +1,422 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#include "../config.h" + +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <ctype.h> + +#include <setjmp.h> + +#include <qdir.h> +#include <qfileinfo.h> + +#include <kurl.h> +#include <kglobal.h> +#include <kiconloader.h> + +#include "packageInfo.h" +#include "kissInterface.h" +#include "updateLoc.h" +#include "kpackage.h" +#include "managementWidget.h" +#include "utils.h" +#include "options.h" +#include "cache.h" +#include <klocale.h> + + +extern KApplication *app; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +KISS::KISS():pkgInterface() +{ + head = "KISS"; + name = i18n("KISS"); + icon = "kiss"; + + pict = UserIcon(icon); + updated_pict = UserIcon("kupdated"); + new_pict = UserIcon("knew"); + + packagePattern = "*.installer"; + typeID = "/kiss"; + + locatedialog = new Locations(i18n("Location of KISS Packages")); + locatedialog->dLocations(2, 6, this, i18n("Folders", "F"), + "KISS", "*.installer", + i18n("Location of Folders Containing KISS Packages")); + + connect(locatedialog,SIGNAL(returnVal(LcacheObj *)), + this,SLOT(setAvail(LcacheObj *))); + locatedialog->apply_slot(); + + queryMsg = i18n("Querying KISS package list: "); + procMsg = i18n("KPackage: Waiting on KISS"); + + param paramsInst[] = { + param(0,FALSE,FALSE,0) + }; + + param paramsUninst[] = { + param(0,FALSE,FALSE,0) + }; + hasProgram = ifExe("kiss"); +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +KISS::~KISS() +{ +} + +////////////////////////////////////////////////////////////////////////////// +// check if kiss file +bool KISS::isType(char *buf, const QString &) +{ + if (hasProgram) { + QString tmp = buf; + if (tmp.find("perl",0,false) >= 0) + return true; + else + return false; + } else { + return false; + } +} + +bool KISS::parseName(const QString& name, QString *n, QString *v) +{ + int d1, d2, s1; + + s1 = name.findRev('.'); + if (s1 > 0) { + d2 = name.findRev('-',s1-1); + if (d2 > 0) { + d1 = name.findRev('_',d2-1); + if (d1 < 0) + d1 = d2; + *n = name.left(d1); + *v = name.mid(d1+1,s1-d1-1); + return TRUE; + } + } + return FALSE; +} + +void KISS::listInstalledPackages(QPtrList<packageInfo> *pki) +{ + QString vb; + packageInfo *p; + + QString sline = i18n("Querying KISS package list: "); + + reader.setup("kiss"); + *reader.proc << "-qq"; + if (!reader.start(0,FALSE)) + return; + + kpackage->setStatus(sline); + kpackage->setPercent(0); + + vb = "" ; + + int sc, sp = 0; + while ((sc = reader.buf.find("\n\n",sp)) >= 0) { + if (sc+1 == (signed int)reader.buf.length()) + break; + p = collectInfo(reader.buf.mid(sp,sc-sp).ascii()); + if (p) { + if (!p->pkgInsert(pki, typeID, TRUE)) { + delete p; + } + } + sp = sc + 2; + } + + kpackage->setPercent(100); +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +// mode: i = query installed u = query uninstalled +packageInfo *KISS::getPackageInfo(char mode, const QString &name, const QString &) +{ + packageInfo *pki = 0; + QString vb,search; + + switch(mode) + { + //////////////////////////////////////////////////////////////////////// + // query an installed package! + case 'i': + reader.setup("kiss"); + *reader.proc << "-q" << name; + if (reader.start(0,FALSE)) { + reader.buf += "package: " + name + "\n"; + pki = collectInfo(reader.buf.ascii()); + } + break; + + //////////////////////////////////////////////////////////////////// + // query an uninstalled package + case 'u': + reader.setup("perl"); + *reader.proc << name << "-q"; + if (reader.start(0,TRUE)) { + pki = collectInfo(reader.buf.ascii()); + + QFileInfo fi(name); + QString s; + s.setNum(fi.size()); + pki->info.insert("file-size", s); + } + break; + } + return pki; +} + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +packageInfo *KISS::collectInfo(const char *_inp) +{ + QMap<QString, QString> a; + + char *str, *xstr; + QString qstr; + + char *inp = qstrdup(_inp); + str = strtok(inp,"\n"); + do { + xstr = strchr(str,':'); + if (*str == ' ') + str++; + if (!strncmp("package",str,7)) + break; + } while ((str = strtok(NULL,"\n"))); + + // parse 'name: text' elements + + if (str) { + do { + if (str[0] == 0) + break; + + xstr = strchr(str,':'); + if (xstr) { + *xstr++ = 0; + xstr++; + + for( int i = 0; str[ i ] != '\0'; ++i ) + str[ i ] = tolower( str[ i ] ); + + if (*str == ' ') + str++; + + if (!strcmp("package",str)) { + a.insert("name", xstr); + } else if (!strcmp("name",str)) { + a.insert("summary", xstr); + } else if (!strcmp("section",str)) { + a.insert("group", xstr); + } else if (!strcmp("size",str)) { + a.insert("file-size", xstr); + } else if (!strcmp("installed-size",str)) { + QString str = xstr; + a.insert("size", str + "000"); + } else { + a.insert(str, xstr); + } + } + } while ((str = strtok(NULL,"\n"))); + } + + packageInfo *i = new packageInfo(a,this); + i->packageState = packageInfo::INSTALLED; + i->fixup(); + delete [] inp; + return i; + +} + +////////////////////////////////////////////////////////////////////////////// + +QStringList KISS::getChangeLog(packageInfo *) { + return 0; +} + + +bool KISS::filesTab(packageInfo *) { + return TRUE; +} + +bool KISS::changeTab(packageInfo *) { + return FALSE; +} + +////////////////////////////////////////////////////////////////////////////// +QStringList KISS::getFileList(packageInfo *p) +{ + QString vb, fn; + QString name; + char mode; + + fn = p->getFilename(); + if(!fn.isEmpty()) + mode = 'u'; + else + mode = 'i'; + + QStringList filelist; + + switch(mode) + { + //////////////////////////////////////////////////////////////////////// + // query an installed package! + case 'i': + name = p->getProperty("name"); + + reader.setup("kiss"); + *reader.proc << "-f" << name; + if (reader.start(0,FALSE)) { + char *buffer = qstrdup(reader.buf.ascii()); + char *str = strtok(buffer,"\n"); + if (str) { + do { + filelist.append(str); + } while ((str = strtok(NULL,"\n"))); + } + delete [] buffer; + } + break; + + //////////////////////////////////////////////////////////////////// + // query an uninstalled package + case 'u': + reader.setup("perl"); + *reader.proc << fn << "-f"; + if (reader.start(0,TRUE)) { + char *buffer = qstrdup(reader.buf.ascii()); + char *str = strtok(buffer,"\n"); + if (str) { + do { + filelist.append(strdup(str)); + } while ((str = strtok(NULL,"\n"))); + } + delete [] buffer; + } + break; + } + + return filelist; +} + +////////////////////////////////////////////////////////////////////////////// +// Call the script to install packages setting parameters +// to kiss dependent on flags +////////////////////////////////////////////////////////////////////////////// +QString KISS::uninstall(int uninstallFlags, QPtrList<packageInfo> *plist, bool &test) +{ + QString packs; + packageInfo *pk; + + for (pk = plist->first(); pk != 0; pk = plist->next()) { + packs = pk->getProperty("name"); + doUninstall(uninstallFlags, packs, test); + } + return 0; +} + +QString KISS::doUninstall(int, const QString &packs, bool &) +{ + return "kiss -d " + packs; +} + +////////////////////////////////////////////////////////////////////////////// +// Call the script to install packages setting parameters +// to kiss dependent on flags, returning whether everyting worked +////////////////////////////////////////////////////////////////////////////// +QString KISS::install(int installFlags, QPtrList<packageInfo> *plist, bool &test) +{ + packageInfo *pk; + int i = 0; + for (pk = plist->first(); pk != 0; pk = plist->next()) { + QString fname = pk->fetchFilename(); + if (!fname.isEmpty()) { + doInstall(installFlags, fname, test); + i++; + } + } + return 0; +} + +QString KISS::doInstall(int, const QString &packs, bool &) +{ + return "perl " + packs; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +QStringList KISS::FindFile(const QString &name, bool) +{ + QString s = "kiss -p "; + s += name; + + QStringList filelist; + // filelist = kpty->run(s); + + // for ( QStringList::Iterator it = filelist.begin(); it != filelist.end(); ++it ) { + // *it = *it + '\t' + name ; + // } + + return filelist; +} + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +void KISS::setLocation() +{ + locatedialog->restore(); +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +void KISS::setAvail(LcacheObj *slist) +{ + if (packageLoc) + delete packageLoc; + packageLoc = slist; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +#include "kissInterface.moc" diff --git a/kpackage/kissInterface.h b/kpackage/kissInterface.h new file mode 100644 index 0000000..4a4484d --- /dev/null +++ b/kpackage/kissInterface.h @@ -0,0 +1,87 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#ifndef KISS_IFACE_H +#define KISS_IFACE_H + +#include "../config.h" + +#include <qptrlist.h> +#include <qstringlist.h> +#include <kprocess.h> + +#include "procbuf.h" +#include "pkgInterface.h" + +class packageInfo; +class updateLoc; +class cacheObj; + +class KISS: public pkgInterface +{ + Q_OBJECT + +public: + KISS(); + ~KISS(); + + bool isType(char *buf, const QString &fname); + param *initinstallOptions(); + param *inituninstallOptions(); + packageInfo *getPackageInfo(char mode, const QString &name, const QString &version); + QStringList getFileList(packageInfo *p); + QStringList getChangeLog(packageInfo *p); + + bool filesTab(packageInfo *p); + // If files tab is to be enabled + + bool changeTab(packageInfo *p); + // If change log tab is to be enabled + + QStringList FindFile(const QString &name, bool seachAll=false); + bool parseName(const QString& name, QString *n, QString *v); + +public slots: + void setLocation(); + void setAvail(LcacheObj *); + +private: + packageInfo* collectInfo(const char *inp); + void listInstalledPackages(QPtrList<packageInfo> *pki); + + QString install(int installFlags, QPtrList<packageInfo> *plist, bool &test); + QString uninstall(int uninstallFlags, QPtrList<packageInfo> *plist, bool &test); + + QString doUninstall(int installFlags, const QString &packs, bool &test); + QString doInstall(int installFlags, const QString &packs, bool &test); + + procbuf reader; +}; + +#endif + + + diff --git a/kpackage/kpPty.cpp b/kpackage/kpPty.cpp new file mode 100644 index 0000000..b395483 --- /dev/null +++ b/kpackage/kpPty.cpp @@ -0,0 +1,446 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + +#include "../config.h" + +#include <qtimer.h> +#include <qregexp.h> + +#include <kprocctrl.h> +#include <kpty.h> +#include <kdebug.h> +#include <kpassdlg.h> + +#include <kpPty.h> +#include <kpackage.h> +#include <kpTerm.h> +#include <options.h> +#include <utils.h> + +#define SHPROMPT "# " +const int TIMEOUT = -3; +const int PASSWORD = -2; +const int PROMPT = -1; + +extern Opts *opts; +////////////////////////////////////////////////////////////////////////////// + +kpKProcIO::kpKProcIO ( QTextCodec *_codec) + : KProcIO(_codec) +{ +} + +kpKProcIO::~kpKProcIO() +{ +} + +bool kpKProcIO::sstart (RunMode runmode) +{ + + connect (this, SIGNAL (receivedStdout (KProcess *, char *, int)), + this, SLOT (received (KProcess *, char *, int))); + + + connect (this, SIGNAL (wroteStdin(KProcess *)), + this, SLOT (sent (KProcess *))); + + return KProcess::start (runmode,( KProcess::Communication) ( KProcess::Stdin | KProcess::Stdout)); +} + +////////////////////////////////////////////////////////////////////////////// + +kpPty::kpPty() : QObject() +{ + pty = new kpKProcIO(); + pty->setUsePty(KProcess::All, false); + + connect(pty, SIGNAL(readReady(KProcIO *)), this, + SLOT(readLines())); + connect(pty, SIGNAL(processExited(KProcess *)), this, + SLOT(done())); + pty->pty()->setWinSize(0,80); + tm = new QTimer(this); + connect(tm, SIGNAL(timeout()), this, SLOT(slotTimeout())); + + eventLoop = FALSE; + inSession = FALSE; + pUnterm = FALSE; + loginSession = FALSE; + + codec = QTextCodec::codecForLocale(); + QMap<QString, QCString> passwords; +} + + +kpPty::~kpPty() +{ +} + +void kpPty::startSu() +{ + kdDebug() << "startSu()\n"; + pty->setEnvironment("PS1", SHPROMPT); +#if defined(__FreeBSD__) || defined(__bsdi__) + (*pty) << "su"; +#else + (*pty) << "su" << "-s" << "/bin/sh"; +#endif + +} + +void kpPty::startSudo() +{ + kdDebug() << "startSudo()\n"; + pty->setEnvironment("PS1", SHPROMPT); + (*pty) << "sudo" << "-p" << "Password: " << "/bin/sh"; +} + +void kpPty::startSsh() +{ + kdDebug() << "startSsh()\n"; + (*pty) << "/usr/bin/ssh" << "-t" << "-l" << "root"; + if (hostName.isEmpty()) { + (*pty) << "-o" << "StrictHostKeyChecking=no" << "localhost"; + } else { + (*pty) << hostName; + } + (*pty) << "env PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin PS1='" SHPROMPT "' sh"; +} + +bool kpPty::needSession(bool needRoot) +{ + return (!hostName.isEmpty() || needRoot); +} + +bool kpPty::startSession(bool needRoot) +{ + bool interact = FALSE; // Have interacted with user, prevents loops + bool passwordTried = FALSE; // Have tried the current save password, so need to put up dialog + pUnterm = FALSE; + kdDebug() << "kpPty::startSession\n"; + if (!inSession && needSession(needRoot)) { + // Assume !needRoot actions are simple executables + kdDebug() << "kpPty::startSession TRUE\n"; + loginSession = TRUE; + int ret; + QString s = "echo START=$?\n"; + + FULL_RESTART: + interact = FALSE; + retList.clear(); + pty->resetAll(); + + QString passMsg; + kdDebug() << "privCmd=" << opts->privCmd << "\n"; + if (opts->privCmd == Opts::SSHcmd || !hostName.isEmpty()) { + passMsg = i18n("The action you requested uses ssh. Please enter the password or pass phrase.\n"); + startSsh(); + } else if (opts->privCmd == Opts::SUcmd) { + passMsg = i18n("The action you requested needs root privileges. Please enter root's password.\n"); + startSu(); + } else if (opts->privCmd == Opts::SUDOcmd) { + passMsg = i18n("The action you requested needs root privileges. Please enter your SUDO password.\n"); + startSudo(); + } + pty->sstart(KProcess::NotifyOnExit); + + RESTART: + tm->start(6*1000, TRUE); + eventLoop = TRUE; + kdDebug() << "Loopst\n"; + kapp->enter_loop(); + kdDebug() << "Loopfn Result=" << Result << "\n"; + tm->stop(); + if (Result == TIMEOUT) { // timeout + interact = TRUE; + // kdDebug() << "Line=" << retList.last() << "\n"; + kpstart->addText(retList); + kpstart->run("", i18n("Login Problem: Please login manually")); + + ret = kpstart->exec(); + kdDebug() << "Sret=" << ret << "\n"; + if (ret) { + inSession = FALSE; + } else { + inSession = TRUE; + } + } else if (Result == PASSWORD) { // We got a password prompt + QCString pass; + int res; + interact = TRUE; + // kdDebug() << "H=" << hostName << " PH=" << passwords[hostName] << " PT=" << passwordTried <<"\n"; + if (passwords[hostName] != 0 && !passwordTried) { + pass = passwords[hostName]; + res = 1; + } else { + kdDebug() << "Passwd=" << retList.last() << "\n"; + QString msg = passMsg; + // kdDebug() << "privCmd=" << opts->privCmd << " host=" << hostName.isEmpty() << "\n"; + if (opts->privCmd == Opts::SSHcmd || !hostName.isEmpty()) { + msg += retList.last(); + } + int keep = 1; + res = KPasswordDialog::getPassword(pass,msg,&keep); + // kdDebug() << "Pass=" << pass << " Keep=" << keep << " Res=" << res << "\n"; + if (keep) { + passwords[hostName] = pass; + } else { + passwords.remove(hostName); + } + } + pty->writeStdin(pass.append("\n"), false); + passwordTried = TRUE; + if (res) { + retList.clear(); + goto RESTART; + } else { + inSession = FALSE; + } + } else if (Result == PROMPT) { // Got Prompt + inSession = TRUE; + kdDebug() << "kpPty::startSession TRUE\n"; + } else { // process return code + pty->writeStdin(QCString("\04"), false); // SU doesn't listen to ^C + if (interact) { + goto FULL_RESTART; + } else { + QString errMsg = retList.join(" "); + KpMsgE(errMsg, TRUE); + inSession = FALSE; + } + } + } else { + kdDebug() << "kpPty::startSession Not needed\n"; + } + + loginSession = FALSE; + if (!inSession) + close(); + + return inSession; +} + +void kpPty::breakUpCmd(const QString &cmd) +{ + kdDebug() << " kpPty::run CMD=\""<< cmd <<"\" pty = " << pty << endl; + + bool quote = FALSE; + QString s; + QStringList cl = QStringList::split(" ", cmd); + + for ( QStringList::Iterator it = cl.begin(); it != cl.end(); ++it ) { + int lastPt = (*it).length() - 1; + if ((*it)[0] == '\'') { // Start of quoted string + s = *it; + if ((*it)[lastPt] == '\'') { // Also End of quoted string + s.replace("'",""); + (*pty) << s; + quote = FALSE; + } else { + s += " "; + quote = TRUE; + } + } else if ((*it)[lastPt] == '\'') { // End of quoted string + s += *it; + s.replace("'",""); + (*pty) << s; + quote = FALSE; + } else if (quote) { + s += *it; + s += " "; + } else { + (*pty) << (*it); + } + } +} + +QStringList kpPty::run(const QString &cmd, bool inLoop, bool needRoot) +{ + Result = 0; + + pUnterm = FALSE; + + if (!inSession && !needSession(needRoot)) { + // Assume !needRoot actions are simple executables + pty->resetAll(); + breakUpCmd(cmd); + pty->setEnvironment("TERM", "dumb"); + if (!pty->sstart(KProcess::NotifyOnExit)) { + kdDebug() << " kpPty::run execute=0\n"; + return 0; + } + } else { + if (startSession(needRoot)) { + kdDebug() << "CMDroot='"<< cmd <<"'\n"; + QString s = cmd + ";echo RESULT=$?"; + pty->writeStdin(s); + kdDebug() << " kpPty::run session\n"; + } else { + kdDebug() << " kpPty::run other=0\n"; + return 0; + } + } + + retList.clear(); + + if (inLoop) { + eventLoop = TRUE; + kapp->enter_loop(); + + return retList; + } else { + return 0; + } +} + +void kpPty::close() { + // kdDebug() << "kpPty::close\n"; + + pty->closeAll(); + while(pty->isRunning()) { + KProcessController::theKProcessController->waitForProcessExit(1); + } + inSession = false; +} + +void kpPty::finish(int ret) +{ + kdDebug() << "kpPty::finish " << ret << "\n"; + + QStringList::Iterator l; + Result = ret; + + if (ret == PROMPT) { // Called program executed in session + if (!retList.empty()) { + l = retList.fromLast(); + if ((*l).right(2) == SHPROMPT) { + retList.remove(l); // Remove prompt + } + } + + if (!retList.empty()) { + int p; + l = retList.fromLast(); + if ((p = (*l).find("RESULT=")) >= 0) { + ret = (*l).mid(p+7).toInt(0,10); + retList.remove(l); // Remove return code + } else { + ret = 666; + } + } + + if (!retList.empty()) { + l = retList.begin(); + if ( l != retList.end()) { + if ((*l).find("RESULT=") >= 0) { + retList.remove(l); // Remove command at start + } + } + } + } + emit result(retList,ret); + + + if (eventLoop) { + eventLoop = FALSE; + kapp->exit_loop(); + } +} + +void kpPty::readLines() +{ + bool unterm = FALSE; + + QString stext; + while(pty->readln(stext, false, &unterm) >= 0) + { + stext = codec->toUnicode(stext.ascii(), stext.length()); + emit textIn(stext, !unterm); +// kdDebug() << "[" << pUnterm << "-" << unterm << "-" << stext << ">\n"; + if (pUnterm) { + QStringList::Iterator lst = retList.fromLast(); + if (lst != retList.end()) + { + stext = *lst + stext; + retList.remove(lst); + } + } + int i; + if (!unterm) + { + while (stext.endsWith("\r")) { + stext.truncate(stext.length()-1); + } + + i = stext.findRev('\r'); + if (i > -1) { + stext = stext.mid(i+1); + } + } + + pUnterm = unterm; + + retList << stext; + // kdDebug() << "++" << stext << "\n"; + if (stext.right(2) == SHPROMPT) { // Shell prompt + emit textIn("\r \n", false); + finish(PROMPT); + } else if (loginSession) { + QRegExp rx( "^[^:]+:[\\s]*$"); // Password prompt + if (rx.search(retList.last()) >= 0) { + kdDebug() << loginSession << " " <<retList.last()<< " Match password p\n"; + finish(PASSWORD); + } + } + } + pty->ackRead(); +} + +void kpPty::keyOut(char ch) +{ + QCString s(2); + s[0] = ch; + s[1] = '\0'; + pty->writeStdin(s, false); +} + +void kpPty::done() +{ + int ret = pty->exitStatus(); + QString stext; + + //kdDebug() << "Done (" << ret << ")" << endl; + + finish(ret); +} + +void kpPty::slotTimeout() +{ + kdDebug() << "Timeout..............\n"; + finish(TIMEOUT); +} +#include "kpPty.moc" diff --git a/kpackage/kpPty.h b/kpackage/kpPty.h new file mode 100644 index 0000000..f427ef8 --- /dev/null +++ b/kpackage/kpPty.h @@ -0,0 +1,106 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#ifndef KPPTY_H +#define KPPTY_H + +#include <qmultilineedit.h> +#include <qstringlist.h> +#include <qregexp.h> +#include <qtextcodec.h> +#include <qmap.h> + +#include <kprocio.h> + +////////////////////////////////////////////////////////////////////////////// + +class kpKProcIO: public KProcIO +{ + Q_OBJECT + +public: + + kpKProcIO ( QTextCodec *_codec = 0); + ~kpKProcIO(); + + bool sstart (RunMode runmode); +}; + + +////////////////////////////////////////////////////////////////////////////// +class kpPty: public QObject +{ Q_OBJECT +public: + kpPty(); + ~kpPty(); + + QStringList run(const QString &cmd, bool inLoop = TRUE, + bool needRoot= FALSE); + bool startSession(bool needRoot); + void close(); + + QString remote; + int Result; + // True if have started a session + bool inSession; + +private slots: + void readLines(); + void done(); + void slotTimeout(); + +public slots: + void keyOut(char); + +signals: + void textIn(const QString &, bool); + void result(QStringList &, int); + +private: + void finish(int ret); + + void startSsh(); + void startSu(); + void startSudo(); + void breakUpCmd(const QString &); + bool needSession(bool needRoot); + + kpKProcIO* pty; + QTimer *tm; + QStringList retList; + QRegExp terminator; + bool pUnterm; + QString uptext; + // True if in event loop + bool eventLoop; + // True if trying to login + bool loginSession; + QTextCodec *codec; + QMap<QString, QCString> passwords; +}; + + +#endif diff --git a/kpackage/kpTerm.cpp b/kpackage/kpTerm.cpp new file mode 100644 index 0000000..0336da9 --- /dev/null +++ b/kpackage/kpTerm.cpp @@ -0,0 +1,234 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + +#include "../config.h" + +#include <qvbox.h> + +#include <kglobalsettings.h> +#include <kdebug.h> + +#include <kpTerm.h> + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +kpTerm::kpTerm(kpPty *pt, QWidget * parent, const char * name ) : + QTextEdit(parent,name) +{ + pty = pt; + setFont(KGlobalSettings::fixedFont()); + // setMinimumWidth(fontMetrics().maxWidth()*80 + + // minimumSizeHint().width()); + setWordWrap(NoWrap); + setReadOnly(TRUE); +} + +void kpTerm::doConnect() +{ + connect(pty, SIGNAL(textIn(const QString &, bool)), this, + SLOT(textIn(const QString &, bool))); + connect(pty,SIGNAL(result(QStringList &, int)), + this,SLOT(slotResult(QStringList &, int))); + connect(this, SIGNAL(keyOut(char)), pty, + SLOT(keyOut(char))); +} + +void kpTerm::doUnconnect() +{ + disconnect(pty, SIGNAL(textIn(const QString &, bool)), this, + SLOT(textIn(const QString &, bool))); + disconnect(pty,SIGNAL(result(QStringList &, int)), + this,SLOT(slotResult(QStringList &, int))); + disconnect(this, SIGNAL(keyOut(char)), pty, + SLOT(keyOut(char))); +} + +bool kpTerm::run(const QString &cmd, QStringList &r) +{ + setReadOnly(FALSE); + setFocus(); + if (pty->startSession(TRUE)) { + doConnect(); + + r = pty->run(cmd,FALSE); + return TRUE; + } else { + return FALSE; + } +} + +void kpTerm::cancel() { + emit keyOut('\03'); +} + +void kpTerm::done() +{ + clear(); + doUnconnect(); + setReadOnly(TRUE); + clearFocus(); +} + +void kpTerm::keyPressEvent ( QKeyEvent * e ) +{ + // kdDebug() << "K=" << e->ascii() << "," << e->ascii() << "\n"; + if (e->ascii()) { + emit keyOut(e->ascii()); + } else { + QTextEdit::keyPressEvent (e); + } + setCursorPosition(9999,9999); +} + +void kpTerm::textIn(const QString &stext, bool bNewLine) +{ + QRegExp chrs("[\\010\\012\\015]"); + QString del = "\010"; + // kdDebug() << "Tin=[" << stext << "]\n"; + if (stext.find(chrs) < 0) { + insert( stext ); + } else { + int p; + int op = 0; + + while ((p = stext.find(chrs,op)) >= 0) { + if (p != op) { + insert( stext.mid(op, p-op)); + } + if (stext[p] == '\b') { + doKeyboardAction(ActionBackspace); + } else if (stext[p] == '\r') { + moveCursor(MoveLineStart, false); + } else if (stext[p] == '\n') { + moveCursor(MoveEnd, false); + doKeyboardAction(ActionReturn); + } + op = p + 1; + } + if ((signed int)stext.length() > op) + insert( stext.right(stext.length()-op)); + } + if (bNewLine) { + moveCursor(MoveEnd, false); + doKeyboardAction(ActionReturn); + } + moveCursor(MoveEnd, false); +} + +void kpTerm::insert ( const QString & str, bool) { + int x,y; + getCursorPosition(&y,&x); + + if (str.length() > 0) { + // kdDebug() << "ins:" << y << "," << x << str <<":" << str.length() << "\n"; + if (x == 0 && str != "\n") { + doKeyboardAction(ActionKill); + getCursorPosition(&y,&x); + // kdDebug() << "k=" << y << "," << x <<"\n"; + } + QTextEdit::insert(str,(bool)FALSE); + } +} + +void kpTerm::slotResult(QStringList &rlist, int ret) +{ + emit result(rlist, ret); + doUnconnect(); +} + + + +////////////////////////////////////////////////////////////////////////////// +// +// Dialog window for password prompt +// +////////////////////////////////////////////////////////////////////////////// +kpRun::kpRun( QWidget *parent) + : KDialogBase(parent, "kpRun", true, QString::null, + Cancel, Cancel, true ) +{ + QVBox *page = makeVBoxMainWidget(); + title = new QLabel("", page); + QFont f( KGlobalSettings::generalFont()); + f.setBold(true); + f.setPointSize(f.pointSize()+4); + title->setFont(f); + + term = new kpTerm(kpty,page); + resize(600, 300); + connect(term,SIGNAL(result(QStringList &, int)), + this,SLOT(slotResult(QStringList &, int))); + + hide(); +} + +bool kpRun::run(QString cmd, QString msg) +{ + QStringList r; + + title->setText(msg); + if (!cmd.isEmpty()) { + return term->run(cmd, r); + } else { + term->doConnect(); + term->setReadOnly(FALSE); + term->setFocus(); + return true; + } +} + +void kpRun::addText(const QStringList &ret) +{ + int last = ret.count()-1; + int i = 0; + for ( QStringList::ConstIterator it = ret.begin(); it != ret.end(); ++it, ++i ) { + // kdDebug() << "ks=" << *it << "\n"; + term->textIn(*it, (i != last)); + } +} + +void kpRun::slotResult(QStringList &, int ret) +{ + if (ret == 0 || ret == 666) { + term->clear(); + if (ret == 0) + accept(); + else + reject(); + } +} + +void kpRun::slotCancel() +{ + term->clear(); + term->cancel(); + accept(); +} + +#include "kpTerm.moc" diff --git a/kpackage/kpTerm.h b/kpackage/kpTerm.h new file mode 100644 index 0000000..7767565 --- /dev/null +++ b/kpackage/kpTerm.h @@ -0,0 +1,90 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + + +#ifndef KPTERMD_H +#define KPTERMD_H + +#include "../config.h" + +#include <qtextedit.h> +#include <qstringlist.h> +#include <qlayout.h> +#include <qlabel.h> + +#include <klocale.h> +#include <kdialogbase.h> +#include <kpackage.h> +#include <kpPty.h> + +////////////////////////////////////////////////////////////////////////////// +class kpTerm: public QTextEdit +{ + Q_OBJECT + +public: + kpTerm(kpPty *pt, QWidget * parent=0, const char * name=0); + void keyPressEvent ( QKeyEvent * e ); + bool run(const QString &cmd, QStringList &r); + void doConnect(); + void doUnconnect(); + void insert ( const QString & str, bool mark=FALSE ); + kpPty *pty; + void cancel(); + void done(); + +public slots: + void textIn(const QString &, bool); + void slotResult(QStringList &, int); + +signals: + void keyOut(char); + void result(QStringList &, int); + +}; + +////////////////////////////////////////////////////////////////////////////// + +class kpRun: public KDialogBase +{ + Q_OBJECT + +public: + kpRun(QWidget *parent = 0); + bool run(QString cmd, QString title); + void addText(const QStringList &ret); + +public slots: + void slotResult(QStringList &, int); + void slotCancel(); + +private: + kpTerm *term; + QLabel *title; +}; +////////////////////////////////////////////////////////////////////////////// +#endif diff --git a/kpackage/kpackage.cpp b/kpackage/kpackage.cpp new file mode 100644 index 0000000..5c328e1 --- /dev/null +++ b/kpackage/kpackage.cpp @@ -0,0 +1,759 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +// Author: Damyan Pepper +// Toivo Pedaste +// +// See kpackage.h for more information. +*/ + +/* +** 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 +*/ + + +#include "../config.h" + +#include <qdir.h> +#include <qlabel.h> +#include <qframe.h> + +#include <kdebug.h> +#include <kapplication.h> +#include <kfiledialog.h> +#include <kprogress.h> +#include <kurl.h> +#include <kapplication.h> +#include <kaccel.h> +#include <kaction.h> +#include <klocale.h> +#include <kinputdialog.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <kstdaction.h> +#include <kedittoolbar.h> +#include <kmimemagic.h> +#include <kurldrag.h> + +#include "kpackage.h" +#include "managementWidget.h" +#include "pkgOptions.h" +#include "kio.h" +#include "findf.h" +#include "search.h" +#include "options.h" +#include "cache.h" + +extern Opts *opts; +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +KPKG::KPKG(KConfig *_config) + : KMainWindow(0) +{ + kpackage = new KPACKAGE(_config, this); + setCentralWidget(kpackage); + + config = kapp->config(); + config->setGroup("Kpackage"); + + kpackage->management->readPSeparator(); + + // Get a nice default size + resize(760,540); + + setupMenu(); + disableNext(); + disablePrevious(); + + optiondialog = new Options(this); + + prop_restart = false; + setAutoSaveSettings(); +} + +// Set up the menu + +void KPKG::setupMenu() +{ + + pack_open = KStdAction::open(kpackage, SLOT(fileOpen()), + actionCollection()); + + recent = KStdAction::openRecent(this, SLOT(openRecent(const KURL&)), + actionCollection()); + recent->loadEntries( config ); + + pack_find = new KAction( i18n("Find &Package..."), "find", + KStdAccel::shortcut(KStdAccel::Find), kpackage, + SLOT(find()), actionCollection(), "pack_find"); + + pack_findf = new KAction( i18n("Find &File..."), "filefind", + 0, kpackage, + SLOT(findf()), actionCollection(), "pack_findf"); + + kpack_reload = new KAction( i18n("&Reload"), "reload", + KStdAccel::shortcut(KStdAccel::Reload), kpackage, + SLOT(reload()), actionCollection(), "kpack_reload"); + + (void) KStdAction::quit(kpackage, SLOT(fileQuit()), + actionCollection()); + + pack_prev = KStdAction::back(kpackage->management->treeList, SLOT(previous()), + actionCollection(),"pack_prev"); + + pack_next = KStdAction::forward(kpackage->management->treeList, SLOT(next()), + actionCollection(),"pack_next"); + + (void) (new KAction( i18n("&Expand Tree"), "ftout", + 0, kpackage, + SLOT(expandTree()), actionCollection(), "kpack_expand")); + + (void) (new KAction( i18n("&Collapse Tree"), "ftin", + 0, kpackage, + SLOT(collapseTree()), actionCollection(), "kpack_collapse")); + + (void) (new KAction( i18n("Clear &Marked"), QString::null, + 0, kpackage, + SLOT(clearMarked()), actionCollection(), "kpack_clear")); + + (void) (new KAction( i18n("Mark &All"), QString::null, + 0, kpackage, + SLOT(markAll()), actionCollection(), "kpack_markall")); + + pack_install = new KAction( i18n("&Install"), QString::null, + 0, kpackage->management, + SLOT(installSingleClicked()), actionCollection(), "install_single"); + + pack_install->setEnabled(false); + kpackage->management->setInstallAction(pack_install); + + + pack_uninstall = new KAction( i18n("&Uninstall"), QString::null, + 0, kpackage->management, + SLOT(uninstallSingleClicked()), actionCollection(), "uninstall_single"); + + pack_uninstall->setEnabled(false); + kpackage->management->setUninstallAction(pack_uninstall); + + + (void) (new KAction( i18n("&Install Marked"), QString::null, + 0, kpackage->management, + SLOT(installMultClicked()), actionCollection(), "install_marked")); + + (void) (new KAction( i18n("&Uninstall Marked"), QString::null, + 0, kpackage->management, + SLOT(uninstallMultClicked()), actionCollection(), "uninstall_marked")); + + setStandardToolBarMenuEnabled(true); + + KStdAction::configureToolbars( this, SLOT(configureToolBars()), + actionCollection()); + + KStdAction::saveOptions( this, SLOT(saveSettings()), actionCollection()); + + KStdAction::keyBindings( guiFactory(), SLOT(configureShortcuts()), actionCollection()); + + (void) (new KAction( i18n("Configure &KPackage..."), "configure", + 0, this, + SLOT(setOptions()), actionCollection(), "kpack_options")); + + (void) (new KAction( i18n("Clear Package &Folder Cache"), QString::null, + 0, this, + SLOT(clearDCache()), actionCollection(), "clear_dcache")); + + (void) (new KAction( i18n("Clear &Package Cache"), QString::null, + 0, this, + SLOT(clearPCache()), actionCollection(), "clear_pcache")); + + int i; + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) { + kpinterface[i]->makeMenu(actionCollection()); + } + } + + // urlList.setAutoDelete(TRUE); + createGUI(); +} + +void KPKG::disableMenu() +{ + pack_open->setEnabled(false); + pack_find->setEnabled(false); + pack_findf->setEnabled(false); + kpack_reload->setEnabled(false); + recent->setEnabled(false); +} + +void KPKG::enableMenu() +{ + pack_open->setEnabled(true); + pack_find->setEnabled(true); + pack_findf->setEnabled(true); + kpack_reload->setEnabled(true); + recent->setEnabled(true); +} + +void KPKG::disableNext() { + pack_next->setEnabled(false); +} + +void KPKG::enableNext() { + pack_next->setEnabled(true); +} + +void KPKG::disablePrevious() { + pack_prev->setEnabled(false); +} + +void KPKG::enablePrevious() { + pack_prev->setEnabled(true); +} +void KPKG::openRecent(const KURL& url){ + kpackage->openNetFile( url ); +} + +void KPKG::add_recent_file(const QString &newfile){ + + KURL url = KURL(newfile); + + recent->addURL( url ); +} + +void KPKG::configureToolBars() { + KEditToolbar dlg(actionCollection()); + connect(&dlg,SIGNAL(newToolbarConfig()),this,SLOT(slotNewToolbarConfig())); + dlg.exec(); +} + +void KPKG::slotNewToolbarConfig() { + createGUI(); +} + +void KPKG::writeSettings(){ + + kpackage->management->writePSeparator(); + + KConfig *config = kapp->config(); + + config->setGroup("Kpackage"); + + recent->saveEntries( config ); + + kpackage->management->treeList->writeTreeConfig(); + kpackage->management->treeList->writeTreeType(); + + config->sync(); +} + +void KPKG::setOptions(){ + optiondialog->restore(); +} + +void KPKG::saveSettings(){ + writeSettings(); +} + +void KPKG::clearPCache(){ + cacheObj::clearPCache(); +} + +void KPKG::clearDCache(){ + cacheObj::clearDCache(); +} + +void KPKG::saveProperties(KConfig *config ) +{ + config->writePathEntry("Name", kpackage->save_url.url()); +} + + +void KPKG::readProperties(KConfig *config) +{ + QString entry = config->readPathEntry("Name"); // no default + if (entry.isNull()) + return; + kpackage->openNetFiles(entry); + prop_restart = true; +} + +bool KPKG::queryClose() { + kpackage->cleanUp(); + return true; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +KPACKAGE::KPACKAGE(KConfig *_config, QWidget *parent) + : QWidget(parent) +{ + + // Save copy of config + config = _config; + + setAcceptDrops(true); + setupModeWidgets(); + + setupStatusBar(); + + file_dialog = NULL; + findialog = NULL; + srchdialog = NULL; + +} + +// Destructor +KPACKAGE::~KPACKAGE() +{ + // destroyModeWidgets(); + // delete status; + // delete processProgress; +} + +// resize event -- arrange the widgets +void KPACKAGE::resizeEvent(QResizeEvent *re) +{ + re = re; // prevent warning + arrangeWidgets(); +} + +// Set up the mode widgets +void KPACKAGE::setupModeWidgets() +{ + management = new managementWidget(this); + + for (int i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) { + kpinterface[i]->uninstallation = new pkgOptionsU(kpinterface[i]); + kpinterface[i]->installation = new pkgOptionsI(kpinterface[i]); + } + } +} + +// destroy the mode widgets +void KPACKAGE::destroyModeWidgets() +{ + // delete management; + // for (int i = 0; i < kpinterfaceN; i++) { + // if (kpinterface[i]) { + // delete kpinterface[i]->installation; + // delete kpinterface[i]->uninstallation; + // } + // } +} + + +// Set up the status bar +void KPACKAGE::setupStatusBar() +{ + statusbar = new QFrame(this); + statusbar->setFrameStyle(QFrame::Raised | QFrame::Panel); + processProgress = new KProgress(100,statusbar); + processProgress->setTextEnabled(FALSE); + + status = new QLabel(i18n("Management Mode"), statusbar); +} + +// Arrange the widgets nicely +void KPACKAGE::arrangeWidgets() +{ + int i; + + statusbar->resize(width(),20); + statusbar->move(0,height()-20); + status->resize((statusbar->width() / 4) * 3, 16); + status->move(2,2); + processProgress->resize(statusbar->width() / 4 - 4, 16); + processProgress->move((statusbar->width() / 4) * 3 + 3, 2); + + management->resize(width(),height() - 20); + + for (i = 0; i < kpinterfaceN; i++) + if (kpinterface[i]) { + kpinterface[i]->installation->resize(width(),height() - 20); + } +} + +void KPACKAGE::setup() +{ + management->collectData(1); +} + +void KPACKAGE::fileQuit() // file->quit selected from menu +{ + cleanUp(); + + KApplication::exit(0); // exit the application +} + +void KPACKAGE::cleanUp() // file->quit selected from menu +{ + kpkg->writeSettings(); + if (opts->DCache >= Opts::SESSION) { + cacheObj::clearDCache(); // clear dir caches if needed + } + if (opts->PCache >= Opts::SESSION) { + cacheObj::clearPCache(); // clear package caches if needed + } +} + +void KPACKAGE::reload() +{ + kpackage->management->collectData(TRUE); +} + +void KPACKAGE::fileOpen() // file->quit selected from menu +{ + KFileDialog *box; + + box = getFileDialog(i18n("Select Package")); + + if( box->exec()) + { + if(!box->selectedURL().isEmpty()) + { + openNetFile( box->selectedURL() ); + } + } +} + +void KPACKAGE::clearMarked() +{ + management->treeList->clearMarked(management->treeList->firstChild()); +} + +void KPACKAGE::markAll() +{ + management->treeList->markAll(management->treeList->firstChild()); +} + +void KPACKAGE::expandTree() +{ + management->treeList->expandTree(management->treeList); +} + +void KPACKAGE::collapseTree() +{ + management->treeList->collapseTree(management->treeList); +} + +pkgInterface *KPACKAGE::pkType(const QString &fname) +{ + // Get the package information for this package + char buf[51]; + int i; + + FILE *file= fopen(QFile::encodeName(fname),"r"); + if (file) { + fgets(buf,sizeof(buf)-1,file); + buf[50] = 0; + + // check enabled package handlers + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) { + if (opts->handlePackage[i] && kpinterface[i]->isType(buf, fname)) { + fclose(file); + return kpinterface[i]; + } + } + } + // check unenabled package handlers + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) { + if (!opts->handlePackage[i] && kpinterface[i]->isType(buf, fname)) { + fclose(file); + return kpinterface[i]; + } + } + } + fclose(file); + KpMsgE(i18n("Unknown package type: %1").arg(fname),TRUE); + } else { + KpMsgE(i18n("File not found: %1").arg(fname),TRUE); + } + + return 0; +} + +///////////////////////////////////////////////////////////////////////// +int KPACKAGE::typeIndex(pkgInterface *type) { + int i; + for (i = 0; i < kpinterfaceN; i++) { + if (type == kpinterface[i]) { + return i; + } + } + return -1; +} + +void KPACKAGE::openNetFiles (const QStringList &urls, bool install ) +{ + QStringList files; + int i; + int index; + QPtrList<packageInfo> **lst = new QPtrList<packageInfo>*[kpinterfaceN]; + packageInfo *pk = 0; + + kdDebug() << "openNetFiles\n"; + + for (QStringList::ConstIterator it = urls.begin(); it != urls.end(); ++it) { + files.append(fetchNetFile(*it)); + kpkg->add_recent_file(*it); + } + + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) { + lst[i] = new QPtrList<packageInfo>; + } + } + + for (QStringList::Iterator t = files.begin(); t != files.end(); ++t) { + pkgInterface *type = pkType(*t); + index = typeIndex(type); + if (index >= 0) { + pk = type->getPackageInfo('u', *t, 0); + if (pk) { + pk->pkgFileIns(*t); + lst[index]->insert(0,pk); + } + } + } + + if (install) + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) { + if ( lst[i]->count() > 0) { + kpinterface[i]->installation->setup(lst[i],kpinterface[i]->head); + if (kpinterface[i]->installation->exec()) { + for (packageInfo *inf = lst[i]->first(); inf != 0; inf = lst[i]->next()) { + kpackage->management->updatePackage(inf,TRUE); + } + } + } + } + } else { + if (pk) { + KpTreeListItem *pt = pk->item; + // NOT the best place for this CODE + kpackage->management->tabChanged(Opts::ALL); + if (pt) + kpackage->management->packageHighlighted(pt); + } + } + + // Dealloc memory + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) { + delete lst[i]; + } + } + delete [] lst; +} + +void KPACKAGE::openNetFile(const KURL &url, bool install ) +{ + openNetFiles(url.url(), install); +} + +// KMimeMagic *magic = KMimeMagic::self(); +// KMimeMagicResult *r = magic->findFileType(s); + // printf("r=%s\n",(r->mimeType()).data()); + + + +QString KPACKAGE::getFileName(const KURL & url, QString &cacheName ) +{ + QString none = ""; + QString fname = ""; + + if ( !url.isValid() ) { + KpMsgE(i18n("Malformed URL: %1").arg(url.url()),TRUE); + } else { + + // Just a usual file ? + if ( url.isLocalFile() ) { + cacheName = url.path(); + fname = url.path(); + } else { + + QString tmpd = cacheObj::PDir(); + if (!tmpd.isEmpty()) { + + QString cacheFile = tmpd + url.fileName(); + + cacheName = cacheFile; + QFileInfo f(cacheFile); + if (f.exists() && (opts->DCache != Opts::NEVER)) { + fname = cacheFile; + } + } + } + } + return fname; +} + +bool KPACKAGE::isFileLocal( const KURL & url ) +{ + QString cf; + + QString f = getFileName(url, cf); + + if (cf.isEmpty()) { + return false; + } else { + if (!f.isEmpty()) { + return true; + } else { + return false; + } + } +} + +QString KPACKAGE::fetchNetFile( const KURL & url ) +{ + + QString cf; + + QString f = getFileName(url, cf); + + if (cf.isEmpty()) { + return ""; + } else { + + if (!f.isEmpty()) { + return f; + } else { + save_url = url; + + setStatus(i18n("Starting KIO")); + + Kio kio; + + if (kio.download(url, cf)) { + setStatus(i18n("KIO finished")); + QFileInfo fi(cf); + if (!(fi.exists() && fi.size() > 0)) { + unlink(QFile::encodeName(cf)); + return ""; + } else { + CacheList cl(fi.dirPath()); + cl.append(fi.fileName()); + cl.write(); + return cf; + } + } else { + setStatus(i18n("KIO failed")); + return ""; + } + } + } +} + +///////////////////////////////////////////////////////////////////////// +void KPACKAGE::fileOpenUrl(){ + + bool ok; + + QString url = KInputDialog::getText( QString::null, + i18n( "Open location:" ), save_url.prettyURL(), &ok, this ); + + if ( ok ) + { + kpkg->add_recent_file( url ); + openNetFile( url ); + } +} + +void KPACKAGE::find(){ + if (srchdialog) + srchdialog->show(); + else + srchdialog = new Search(this, "find package"); +} + +void KPACKAGE::findf(){ + if (findialog) + findialog->show(); + else + findialog = new FindF(this); +} + +KFileDialog* KPACKAGE::getFileDialog(const QString &captiontext) +{ + + if(!file_dialog) { + file_dialog = new KFileDialog(QDir::currentDirPath(), "", + this,"file_dialog",TRUE); + } + + QString pat; + for (int i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i] && opts->handlePackage[i]) { + pat += kpinterface[i]->packagePattern; + pat += " "; + } + } + file_dialog->setFilter(pat); + file_dialog->setCaption(captiontext); + // file_dialog->rereadDir(); + + return file_dialog; +} + +void KPACKAGE::dragEnterEvent(QDragEnterEvent* e) +{ + e->accept(KURLDrag::canDecode(e)); +} + +void KPACKAGE::dropEvent(QDropEvent *de) // something has been dropped +{ + KURL::List list; + if (!KURLDrag::decode(de, list) || list.isEmpty()) + return; + + openNetFiles(list.toStringList()); +} + +void KPACKAGE::setStatus(const QString &s) // set the text in the status bar +{ + status->setText(s); + kapp->processEvents(); // refresh the screen +} + +QString KPACKAGE::getStatus() // get the text in the status bar +{ + if(status) + return status->text(); + else + return ""; +} + +void KPACKAGE::setPercent(int x) // set the progress in the status bar +{ + processProgress->setValue(x); + kapp->processEvents(); // refresh it +} + +////////////////////////////////////////////////////////////////////////////// + + + +#include "kpackage.moc" diff --git a/kpackage/kpackage.desktop b/kpackage/kpackage.desktop new file mode 100644 index 0000000..6974aa9 --- /dev/null +++ b/kpackage/kpackage.desktop @@ -0,0 +1,101 @@ +[Desktop Entry] +Name=KPackage +Name[af]=Kpackage +Name[ar]=برنامج KPackage +Name[bn]=কে-পà§à¦¯à¦¾à¦•à§‡à¦œ +Name[eo]=Pakaĵadministrilo +Name[fo]=KPakka +Name[hi]=के-पैकेज +Name[lv]=KPakotne +Name[mn]=КДЕ Багц +Name[ne]=केडीई पà¥à¤¯à¤¾à¤•à¥‡à¤œ +Name[pa]=ਕੇ-ਪੈਕੇਜ +Name[pl]=Pakiety +Name[sv]=Kpackage +Name[ta]=கே தொகà¯à®ªà¯à®ªà¯ +Name[th]=จัดà¸à¸²à¸£à¹à¸žà¹‡à¸„เà¸à¸ˆ - K +Name[ven]=Tshiputo tsha K +Name[xh]=UdibanisolweK +Name[zu]=kphakethe +GenericName=Package Manager +GenericName[af]=Paket Bestuurder +GenericName[ar]=مسيير الØزمات +GenericName[az]=Paket Ä°darəçisi +GenericName[bg]=Мениджър на пакети +GenericName[bn]=পà§à¦¯à¦¾à¦•à§‡à¦œ মà§à¦¯à¦¾à¦¨à§‡à¦œà¦¾à¦° +GenericName[br]=Merour ar pakadoù +GenericName[bs]=Upravitelj paketima +GenericName[ca]=Gestor de paquets +GenericName[cs]=Správce balÃÄků +GenericName[cy]=Rheolydd Pecynnau +GenericName[da]=PakkehÃ¥ndtering +GenericName[de]=Paketmanager +GenericName[el]=ΔιαχειÏιστής πακÎτων +GenericName[eo]=Administrilo por programpakaĵoj +GenericName[es]=Administrador de paquetes +GenericName[et]=Pakettide haldamine +GenericName[eu]=Pakete kudeatzailea +GenericName[fa]=مدیر بسته +GenericName[fi]=Ohjelmapakettien hallinta +GenericName[fo]=Pakkahandfarari +GenericName[fr]=Gestionnaire de paquetages +GenericName[ga]=Bainisteoir Pacáistà +GenericName[gl]=Xestor de Pacotes +GenericName[he]=×ž× ×”×œ חבילות +GenericName[hi]=पैकेज पà¥à¤°à¤¬à¤‚धक +GenericName[hr]=Alat za upravljanje paketima +GenericName[hu]=TelepÃtÅ‘ +GenericName[is]=Pakkastjóri +GenericName[it]=Gestione pacchetti +GenericName[ja]=パッケージマãƒãƒ¼ã‚¸ãƒ£ +GenericName[ka]=პáƒáƒ™áƒ”ტების მმáƒáƒ თველი +GenericName[kk]=ДеÑтелер менеджері +GenericName[km]=កម្មវិធី​គ្រប់គ្រង​កញ្ចប់ +GenericName[ko]=꾸러미 ê´€ë¦¬ìž +GenericName[lt]=Paketų tvarkyklÄ— +GenericName[lv]=Pakotņu Menedžers +GenericName[mk]=Менаџер на пакети +GenericName[mn]=Багц Зохицуулагч +GenericName[ms]=Pengurus Pakej +GenericName[mt]=Manager ta' pakketti +GenericName[nb]=Pakkebehandler +GenericName[nds]=Paket-Pleger +GenericName[ne]=पà¥à¤¯à¤¾à¤•à¥‡à¤œ पà¥à¤°à¤¬à¤¨à¥à¤§à¤• +GenericName[nl]=Pakketbeheerder +GenericName[nn]=Pakkehandsamar +GenericName[pa]=ਪੈਕੇਜ ਪਰਬੰਧਕ +GenericName[pl]=Menedżer pakietów +GenericName[pt]=Gestor de Pacotes +GenericName[pt_BR]=Gerenciador de Pacotes +GenericName[ro]=Manager de pachete +GenericName[ru]=Менеджер пакетов +GenericName[se]=PáhkkagieÄ‘ahalli +GenericName[sk]=Správca balÃkov +GenericName[sl]=Upravljalnik paketov +GenericName[sr]=Менаџер пакета +GenericName[sr@Latn]=Menadžer paketa +GenericName[sv]=Pakethanterare +GenericName[ta]=தொகà¯à®ªà¯à®ªà¯ மேலாளர௠+GenericName[tg]=Роҳбари Package +GenericName[th]=เครื่à¸à¸‡à¸¡à¸·à¸à¸ˆà¸±à¸”à¸à¸²à¸£à¹à¸žà¹‡à¸„เà¸à¸ˆ +GenericName[tr]=Paket Yöneticisi +GenericName[uk]=Менеджер пакунків +GenericName[ven]=Phakhedzhi ya Murangaphanda +GenericName[vi]=Bá»™ quản lý gói +GenericName[wa]=Manaedjeu di pacaedjes +GenericName[xh]=Umphathi Wokudityaniswe kunye +GenericName[zh_CN]=软件包管ç†å™¨ +GenericName[zh_HK]=套件管ç†ç¨‹å¼ +GenericName[zh_TW]=套件管ç†ç¨‹å¼ +GenericName[zu]=Umphathi Wokusongwayo +MimeType=application/x-rpm;application/x-deb; +Exec=kpackage -caption "%c" %i %m %u +Icon=kpackage +Type=Application +DocPath=kpackage/index.html +Terminal=false +Path= +InitialPreference=5 +X-KDE-StartupNotify=true +X-DCOP-ServiceType=Multi +Categories=Qt;KDE;System; diff --git a/kpackage/kpackage.h b/kpackage/kpackage.h new file mode 100644 index 0000000..07d22da --- /dev/null +++ b/kpackage/kpackage.h @@ -0,0 +1,336 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +** This is the main widget for kpackage +** The whole widget is a DND drop zone where users can drop packages to +** be installed. +*/ + +/* +** 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 +*/ + + + + +#ifndef KPACKAGE_H +#define KPACKAGE_H + +#include "../config.h" + +// KDE headers +#include <kurl.h> +#include <kmainwindow.h> +#include <kpPty.h> + +class KFileDialog; +class KProgress; +class QFrame; +class KConfig; +class QLabel; +class Search; +class FindF; +class Options; +class pkgInterface; +class managementWidget; +class KAccel; +class QDropEevnt; +class KRecentFilesAction; +class KAction; +class kpRun; + +#define kpinterfaceN 7 + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +class KPACKAGE : public QWidget +{ + Q_OBJECT + + ///////////// METHODS ------------------------------------------------------ +public: + KPACKAGE(KConfig *_config, QWidget *parent); + // Constructor + + ~KPACKAGE(); + // Destructor + + enum { OPEN_READWRITE = 1, + OPEN_READONLY = 2, + OPEN_INSERT = 4 }; + + void setStatus(const QString &s); + // this sets the status bar's string to s + + void setPercent(int x); + // this set the status bar's progress to x + + QString getStatus(); + // this gets the current status string on the status bar + + // void setMode(int newmode, pkgInterface *type, int refresh); + // This sets the mode to newmode and updates the display accordingly. + + void setup(); + + pkgInterface *pkType(const QString &fname); + // find type of package + + int typeIndex(pkgInterface *); + // convert interface pointer to index + + void openNetFiles(const QStringList &urls, bool install=TRUE); + void openNetFile(const KURL & url, bool install=TRUE); + // open a file given a URL + + QString fetchNetFile(const KURL & url); + // fetch a file given a URL + + static QString getFileName(const KURL & url, QString &cacheName); + // return file name, if not local file cachename is name for cache entry + + static bool isFileLocal( const KURL & url ); + // true if URL refers to local or cached file + +protected: + void resizeEvent(QResizeEvent *re); + // This is called when the widget is resized + + void dropEvent(QDropEvent *); + // This is called when a URL has been dropped in the drop zone + + void dragEnterEvent(QDragEnterEvent* e); + +private: + + void setupModeWidgets(); + // This sets up the mode widgets (ie management/installation widgets) + + void destroyModeWidgets(); + // This deletes the mode widgets (ie management/installation widgets) + + void setupStatusBar(); + // This sets up the status bar + + void arrangeWidgets(); + // This arranges the widgets in the window (should be called after a + // resize event) + + KFileDialog* getFileDialog(const QString &captiontext); + + ///////////// SLOTS -------------------------------------------------------- +public slots: + +// void modeFinished(int mode, pkgInterface *interface, int refresh); + // This is called when the mode `mode' has finished. KPACKAGE should + // then change modes appropriately + + void fileOpen(); + // This is called when File->Open is selected from the menu + + void clearMarked(); + // clear package Marks + + void markAll(); + // mark all packages in the selected view + + void expandTree(); + void collapseTree(); + // expand and collapse file tree + + void fileOpenUrl(); + // menu item FIle->OpenUrl + + void find(); + // search for package + + void findf(); + // search for file in package + + void fileQuit(); + // This is called when File->Quit is selected from the menu + + void cleanUp(); + // Cleanup for Exit + + void reload(); + // reload file package infomation + + ///////////// SIGNALS ------------------------------------------------------ + + ///////////// DATA --------------------------------------------------------- +public: + + enum { Management, Installation } ; + // Widget modes + + KConfig *config; + // pointer to kconfig object + + managementWidget *management; + // management widget + + KURL save_url; + // save the URL entered + + FindF *findialog; + // find file dialog + +private: + int mode; + // Widget mode + + // Menu item identifiers + + QFrame *statusbar; + // the status bar + + KProgress *processProgress; + // Progress bar for showing progress + + QLabel *status; + // The actual status + + KFileDialog *file_dialog; + /// If we load a file from the net this is the corresponding URL + + Search *srchdialog; + // find package dialog + +}; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +class KPKG : public KMainWindow +{ + Q_OBJECT + + enum { Tback = 1, + Tforward = 2, + Tfileopen = 3, + Tftout = 4, + Tftin = 5, + Tfind = 6, + Tfindf = 7, + Treload = 8 + }; + +public: + + KPKG(KConfig *_config); + // Constructor + + void add_recent_file(const QString &newfile); + // keep list of files accessed + + void writeSettings(); + // write config settings + + void saveProperties(KConfig *config); + void readProperties(KConfig *config); + // save and read restart sstate + + void disableMenu(); + void enableMenu(); + // enable/deisable menu elements + + bool prop_restart; + // indicates a restart from saved state + + Options *optiondialog; + // Options dialog + + KConfig *config ; + // Saved config information + + void disableNext(); + void enableNext(); + void disablePrevious(); + void enablePrevious(); + // Control next and previous commands + + +private: + + void setupMenu(); + // This sets up the menubar + + QStrList recent_files; + + KAction *pack_open; + KAction *pack_find; + KAction *pack_findf; + KAction *kpack_reload; + KAction *pack_prev; + KAction *pack_next; + KAction *pack_install; + KAction *pack_uninstall; + + int toolID, selectID; + // refrences to toolbar and menu items + + bool hide_toolbar; + // don't display toolbar + + KRecentFilesAction *recent; + +public slots: + + void openRecent(const KURL& url); + // opens file from list of recently opened ones + + void setOptions(); + // set options + + void saveSettings(); + // save config + + void configureToolBars(); + + void clearPCache(); + // Clear package cache + + void clearDCache(); + // Clear directory cache + +private slots: + void slotNewToolbarConfig(); + +protected: + bool queryClose (); +}; + +////////////////////////////////////////////////////////////////////////////// + +extern KPKG *kpkg; +extern KPACKAGE *kpackage; +extern kpPty *kpty; +extern kpRun *kprun; +extern kpRun *kpstart; + +extern QString hostName; + +extern pkgInterface *kpinterface[]; + +void KpMsg(const QString &lab, const QString &msg, bool stop); +void KpMsgE(const QString &msg, bool stop = FALSE); +#endif + diff --git a/kpackage/kpackageui.rc b/kpackage/kpackageui.rc new file mode 100644 index 0000000..b3229b9 --- /dev/null +++ b/kpackage/kpackageui.rc @@ -0,0 +1,60 @@ +<!DOCTYPE kpartgui > +<kpartgui name="kpackage" version="4"> + <MenuBar> + <Menu name="file" > + <text>&File</text> + <Action name="pack_find" /> + <Action name="pack_findf" /> + <Separator/> + <Action name="kpack_reload" /> +</Menu> + +<Menu name="packages" > + <text>&Packages</text> + <Action name="pack_prev" /> + <Action name="pack_next" /> + <Separator/> + <Action name="kpack_expand" /> + <Action name="kpack_collapse" /> + <Separator/> + <Action name="kpack_clear" /> + <Action name="kpack_markall" /> + <Separator/> + <Action name="install_single" /> + <Action name="install_marked" /> + <Action name="uninstall_single" /> + <Action name="uninstall_marked" /> +</Menu> + +<Menu name="cache" > + <text>&Cache</text> + <Action name="clear_dcache" /> + <Action name="clear_pcache" /> +</Menu> + +<Menu name="special" > + <text>Spe&cial</text> + <Menu name="debapt" > + <text>&APT: Debian</text> + <Action name="debapt_update" /> + <Action name="debapt_upgrade" /> + <Action name="debapt_fixup" /> + <Action name="debapt_file" /> + </Menu> +</Menu> + +<Menu name="settings" > + <text>&Settings</text> + <Action name="kpack_options" append="configure_merge"/> +</Menu> +</MenuBar> + <ToolBar position="Left" name="mainToolBar" > + <Action name="pack_prev" /> + <Action name="pack_next" /> + <Action name="kpack_expand" /> + <Action name="kpack_collapse" /> + <Action name="pack_find" /> + <Action name="pack_findf" /> + <Action name="kpack_reload" /> + </ToolBar> +</kpartgui> diff --git a/kpackage/kplview.cpp b/kpackage/kplview.cpp new file mode 100644 index 0000000..1889150 --- /dev/null +++ b/kpackage/kplview.cpp @@ -0,0 +1,667 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#include "../config.h" +#include <qpixmap.h> +#include <qptrstack.h> +#include <qheader.h> + +#include <kdebug.h> +#include <klocale.h> + +// kpackage.headers +#include "kpackage.h" +#include "pkgInterface.h" +#include "packageInfo.h" +#include "managementWidget.h" +#include "packageDisplay.h" +#include "kplview.h" +#include "options.h" + +#define MPOS 1 + +KpTreeList::KpTreeList( QWidget *parent ) : +KListView (parent) +{ + markPkg = 0; + setShowSortIndicator(true); + + QPtrStack<QString> stack(); + readTreeType(); + + setFrameStyle(QFrame::Panel|QFrame::Sunken); + setLineWidth(2); + setItemMargin(2); + addColumn(i18n("Package")); + setColumnWidthMode(0,QListView::Manual); + addColumn(i18n("Mark")); + setColumnWidthMode(1,QListView::Manual); + addColumn(i18n("Summary")); + setColumnWidthMode(2,QListView::Manual); + addColumn(i18n("Size")); + setColumnWidthMode(3,QListView::Manual); + addColumn(i18n("Version")); + setColumnWidthMode(4,QListView::Manual); + addColumn(i18n("Old Version")); + setColumnWidthMode(5,QListView::Manual); + + // setAllColumnsShowFocus(TRUE); + setRootIsDecorated(TRUE); + readTreeConfig(); + update(); + show(); + +} + +void KpTreeList::clear() +{ + markPkg = 0; + emit cleared(); + KListView::clear(); +} + +KpTreeListItem *KpTreeList::firstChild() +{ + return (KpTreeListItem *)KListView::firstChild(); +} + +KpTreeListItem *KpTreeList::currentItem() +{ + return (KpTreeListItem *)KListView::currentItem(); +} + +void KpTreeList::contentsMousePressEvent ( QMouseEvent * e ) +{ + bool markUpdate = false; + + if (e->button() == LeftButton) { + if (inMark(e->x())) { + QPoint vp = contentsToViewport(e->pos()); + KpTreeListItem *i = ( KpTreeListItem *)itemAt( vp ); + if (i && i->childCount() == 0) { + if (e->state() == ShiftButton) { + if (i->childCount() == 0) { + i->setMark(true); + markUpdate = true; + } + KpTreeListItem *item = i; + while ((item = (KpTreeListItem *)item->itemAbove()) && !item->marked) {;} + if (item) { + item = i; + while ((item = (KpTreeListItem *)item->itemAbove()) && !item->marked) { + if (item->childCount() == 0) { + item->setMark(true); + markUpdate = true; + } + } + } else { + item = i; + while ((item = (KpTreeListItem *)item->itemBelow()) && !item->marked) {;} + if (item) { + item = i; + while ((item = (KpTreeListItem *)item->itemBelow()) && !item->marked) { + if (item->childCount() == 0) { + item->setMark(true); + markUpdate = true; + } + } + } + } + } else { + i->toggleMark(); + markUpdate = true; + } + setCurrentItem(i); + } else + KListView::contentsMousePressEvent (e); + } else + KListView::contentsMousePressEvent (e); + } + + if (markUpdate) + emit updateMarked(); + +} + +bool KpTreeList::inMark(int x) { + int st = 0; + int i; + + + QHeader* const thisHeader = header(); + int mpos = thisHeader->mapToIndex(MPOS); + + for (i = 0; i < mpos; i++) + st += columnWidth(i); + + return (x >= st && x <= st + columnWidth(mpos)); +} + + +/////////////////////////////////////////////////////////////////////////// + +void KpTreeList::expand() +{ + KpTreeListItem *item = firstChild(); + + if (!item) + return; + + do { + expandChild(item->firstChild()); + } while ((item = item->nextSibling())); +} + +void KpTreeList::expandChild(KpTreeListItem *it) +{ + do { + if (it->childCount() > 0) { + expandChild(it->firstChild()); + it->setVisible(true); + } + + } while ((it = it->nextSibling())); +} + +/////////////////////////////////////////////////////////////////////////// + +void KpTreeList::sweep(bool init) +{ + KpTreeListItem *item = firstChild(); + + if (!item) + return; + + if (init) { + expand(); + } + + do { + sweepChild(item->firstChild()); + } while ((item = item->nextSibling())); +} + +int KpTreeList::sweepChild(KpTreeListItem *it) +{ + int ret, shown = 0; + + do { + if (it->childCount() > 0) { + ret = sweepChild(it->firstChild()); + // kdDebug()<<"VV="<<it->text(0)<<" "<<it->isVisible()<<" " << ret << "\n"; + if (!ret) { + it->setVisible(false); + } else { + if (it->isVisible()) + shown += ret; + } + } else { + // kdDebug()<<"VV="<<it->text(0)<<" "<<it->isVisible()<<"\n"; + if (!it->info->display(treeType)) { + it->setVisible(false); + } else { + if (it->isVisible()) + shown++; + } + } + } while ((it = it->nextSibling())); + return shown; +} + + +/////////////////////////////////////////////////////////////////////////// +void KpTreeList::clearMarked(KpTreeListItem *item) +{ + while (item) { + if (item->childCount() > 0) { + clearMarked(item->firstChild()); + } + item->setMark(false); + item = item->nextSibling(); + } +} + +void KpTreeList::markAll(KpTreeListItem *item) +{ + while (item) { + if (item->childCount() > 0) { + markAll(item->firstChild()); + } + else { + if (item->info->display(treeType)) { + item->setMark(true); + } + } + item = item->nextSibling(); + } +} + +void KpTreeList::findMarked(KpTreeListItem *item, QPtrList<KpTreeListItem> &selList) +{ + while (item) { + if (item->childCount() > 0) { + findMarked(item->firstChild(), selList); + } + if (item->marked) { + selList.insert(0,item); + } + item = item->nextSibling(); + } +} + +void KpTreeList::countMarked(KpTreeListItem *item, int &cntInstall, int &cntUnInstall) +{ + while (item) { + if (item->childCount() > 0) { + countMarked(item->firstChild(), cntInstall, cntUnInstall); + } + if (item->marked) { + if (item->info->isInstallable()) + cntInstall++; + else + cntUnInstall++; + } + item = item->nextSibling(); + } +} + +/////////////////////////////////////////////////////////////////////////// +void KpTreeList::expandTree(KpTreeList *list) +{ + KpTreeListItem *item = list->firstChild(); + + while (item) { + if (item->childCount() > 0) { + item->setOpen(TRUE); + expandTree(item); + } + item = item->nextSibling(); + } +} + + +void KpTreeList::expandTree(KpTreeListItem *pitem) +{ + KpTreeListItem *item = pitem->firstChild(); + + while (item) { + if (item->childCount() > 0) { + item->setOpen(TRUE); + expandTree(item); + } + item = item->nextSibling(); + } +} + +void KpTreeList::collapseTree(KpTreeList *list) +{ + KpTreeListItem *item = list->firstChild(); + + while (item) { + if (item->childCount() > 0) { + collapseTree(item); + } + item = item->nextSibling(); + } +} + +void KpTreeList::collapseTree(KpTreeListItem *pitem) +{ + int n = 0; + KpTreeListItem *item = pitem->firstChild(); + + while (item) { + if (item->childCount() > 0) { + n++; + collapseTree(item); + } + item = item->nextSibling(); + }; + if (n) + pitem->setOpen(TRUE); + else + pitem->setOpen(FALSE); +} + +/////////////////////////////////////////////////////////////////////////// +// A package has been highlighted in the list tree +void KpTreeList::packageHighlighted(QListViewItem *item, packageDisplayWidget *packageDisplay) +{ + KpTreeListItem *sel = (KpTreeListItem *)item; + + if (!sel || sel->childCount()) { + packageDisplay->changePackage(0); + } else if (sel) { + if (!notPress) { + int n = stack.at(); + int num = stack.count(); + for (int i = num - 1; i >= n; i--) { + stack.remove(i); + } + kpkg->disableNext(); + } + + // Disable the tree list while we do this + setEnabled(FALSE); + + // Tell everything that is interested to change packages + packageDisplay->changePackage(sel->info); + + // Re-enable the treeList and uninstall button + setEnabled(TRUE); + setFocus(); + + if (!notPress) { + stack.append(sel); + } + } + + notPress = false; +} + +KpTreeListItem *KpTreeList::search(const QString &str, const QString &head, + KpTreeListItem *start) +{ + KpTreeListItem *item = firstChild(); + + searchCitem = start; + searchSkip = FALSE; + searchSubstr = FALSE; + searchStr = str; + searchResult = 0; + + do { + if (item->text(0) == head) { + searchChild(item->firstChild()); + if (searchResult != 0) + return searchResult; + } + } while ((item = item->nextSibling())); + return 0; +} + +KpTreeListItem *KpTreeList::search(const QString &str, bool subStr, bool wrap, + bool start=FALSE) +{ + if (!firstChild()) + return 0; + + if (start) + searchCitem = 0; + else + searchCitem = currentItem(); + searchSkip = !wrap; + searchSubstr = subStr; + searchStr = str; + searchResult = 0; + + searchChild(firstChild()); + + return changePack(searchResult); +} + +bool KpTreeList::searchChild(KpTreeListItem *it) +{ + do { + if (!searchSkip) { + QString s = it->text(0); + // kdDebug() << "s='" << s << "'='" << searchStr << "\n"; + if ((it->childCount() == 0) && (it->info->display(treeType)) && + (searchSubstr ? s.contains(searchStr,FALSE) : s == searchStr)) { + searchResult = it; + return TRUE; + } + } + + if (searchCitem == it) { + if (searchSkip) { + searchSkip = FALSE; + } else { + return TRUE; + } + } + + if (it->childCount() > 0) { + if (searchChild(it->firstChild())) + return TRUE; + } + } while ((it = it->nextSibling())); + return FALSE; +} + +KpTreeListItem *KpTreeList::changePack(KpTreeListItem *searchResult, bool push) +{ + if (searchResult) { + QListViewItem *i; + + i = searchResult; + while ((i = i->parent())) { + i->setOpen(TRUE); + } + if (push) { + stack.append(searchResult); + kpkg->enablePrevious(); + } + + notPress = true; + setSelected(searchResult,TRUE); + setCurrentItem(searchResult); + ensureItemVisible(searchResult); + return searchResult; + } else { + return 0; + } +} + +void KpTreeList::next() +{ + int n = stack.at(); + KpTreeListItem *s = stack.at(n + 1); + if (s) { + changePack(s, false); + } + if (n >= int(stack.count() - 2)) { + kpkg->disableNext(); + } + if (n >= 0) { + kpkg->enablePrevious(); + } +} + +void KpTreeList::previous() +{ + int n = stack.at(); + KpTreeListItem *s = stack.at(n-1); + + if (s) { + changePack(s, false); + kpkg->enableNext(); + } + if (n <= 1) { + kpkg->disablePrevious(); + } + if (n < int(stack.count() - 2)) { + kpkg->enableNext(); + } +} + +void KpTreeList::stackRemove(KpTreeListItem *pack) +{ + int n = stack.find(pack); + if (n >= 0) { + if (n == 0) { + kpkg->disablePrevious(); + } + if (n >= int(stack.count() - 1)) { + kpkg->disableNext(); + } + stack.remove(pack); + } +} + +//////////////////////////////////////////////////////////////// +void KpTreeList::writeTreeType() +{ + KConfig *config = kapp->config(); + + config->setGroup("Kpackage"); + + config->writeEntry("Package_Display",treeType); +} + +void KpTreeList::readTreeType() +{ + KConfig *config = kapp->config(); + + config->setGroup("Kpackage"); + + treeType = config->readNumEntry("Package_Display",3); + +} + +////////////////////////////////////////////////////////////////////////////// + +void KpTreeList::writeTreeConfig() +{ + saveLayout( kapp->config(), "Tree"); +} + +void KpTreeList::readTreeConfig() +{ + KConfig *config = kapp->config(); + + restoreLayout(config, "Tree"); + + config->setGroup("Tree"); + if (!config->hasKey("ColumnWidths")) { + int i,n; + int num[] = {185,37,180,54,95,95}; + + QString colpos; + for (i = 0; i < 6; i++) { + colpos.setNum(i); + n = config->readNumEntry(colpos,num[i]); + setColumnWidth(i,n); + } + } +} + + +////////////////////////////////////////////////////////////////////////////// +KpTreeListItem::KpTreeListItem( QListViewItem *parent, packageInfo* pinfo, + const QPixmap& thePixmap, + QString label1, QString label2 , + QString label3 , QString label4 , + QString label5 , QString label6 , + QString label7 , QString label8 + +) : QListViewItem(parent, label1, label2, label3, label4, label5, + label6, label7, label8) +{ + info = pinfo; + marked = false; + setPixmap(0, thePixmap); + if (!label2.isNull()) + setPixmap(1,info->interface->markUnInst); +} + +KpTreeListItem::KpTreeListItem( KListView *parent, packageInfo* pinfo, + const QPixmap& thePixmap, + QString label1, QString label2 , + QString label3 , QString label4 , + QString label5 , QString label6 , + QString label7 , QString label8 +) : QListViewItem(parent, label1, label2, label3, label4, label5, + label6, label7, label8) +{ + info = pinfo; + marked = false; + setPixmap(0, thePixmap); + if (!label2.isNull()) + setPixmap(1,info->interface->markUnInst); +} + +KpTreeListItem *KpTreeListItem::firstChild() +{ + return (KpTreeListItem *)QListViewItem::firstChild(); +} + +KpTreeListItem *KpTreeListItem::nextSibling() +{ + return (KpTreeListItem *)QListViewItem::nextSibling(); +} + +void KpTreeListItem::toggleMark() +{ + marked = ! marked; + if (marked) + setPixmap(1,info->interface->markInst); + else + setPixmap(1,info->interface->markUnInst); +} + +void KpTreeListItem::setMark(bool mark) +{ + marked = mark; + if (mark) + setPixmap(1,info->interface->markInst); + else { + if (info) + setPixmap(1,info->interface->markUnInst); + } +} + +void KpTreeListItem::hide() +{ + setHeight(0); +} + +void KpTreeListItem::show() +{ + setup(); +} + +int KpTreeListItem::compare( QListViewItem *i, int col, bool ascending ) const +{ // Make sorting more certain + if (col == 3) { // size column + QString k, j; + + j = key( col, ascending ); + j = j.replace(' ','0'); + j = j.rightJustify(6,'0'); + + k = i->key( col, ascending ); + k = k.replace(' ','0'); + k = k.rightJustify(6,'0'); + + // kdDebug() << k <<"=" << j << "\n"; + return j.compare(k); + } else { + return QListViewItem::compare(i, col, ascending); + } +} + +#include "kplview.moc" diff --git a/kpackage/kplview.h b/kpackage/kplview.h new file mode 100644 index 0000000..7931c99 --- /dev/null +++ b/kpackage/kplview.h @@ -0,0 +1,191 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + +#ifndef KPLVITEM_H +#define KPLVITEM_H + +#include "../config.h" +// Standard Headers + +// Qt Headers +#include <qframe.h> +#include <qpushbutton.h> +#include <qptrlist.h> +#include <qstring.h> +#include <qlayout.h> + +// KDE headers +#include "klistview.h" + +// ksetup headers +#include "packageInfo.h" + +class packageDisplayWidget; + +//////////////////////////////////////////////////////////////////////// +class KpTreeList: public KListView +{ + Q_OBJECT + +public: + KpTreeList ( QWidget * parent = 0); + + void contentsMousePressEvent ( QMouseEvent * e ); + + bool inMark(int x); + + KpTreeListItem *firstChild(); + KpTreeListItem *currentItem(); + void clear(); + + KpTreeListItem *markPkg; + + QPtrList<KpTreeListItem> stack; + // Stack of jumped to packages + + void sweep(bool init); + // sweep tree adjusting visibility + void expand(); + // sweep tree expanding everything + + void findMarked(KpTreeListItem *item, QPtrList<KpTreeListItem> &selList); + // generate list of marked tree items + void clearMarked(KpTreeListItem *item); + // unmark marked tree items + + // mark all packages in the selected view + void markAll(KpTreeListItem *item) ; + + void expandTree(KpTreeList *list); + // expand package tree + + void expandTree(KpTreeListItem *item); + // expand package sub-tree + + void collapseTree(KpTreeList *list); + // semi-collapse package tree + + void collapseTree(KpTreeListItem *item); + // semi-collapse package sub-tree + + void countMarked(KpTreeListItem *, int &cntInstall, int &cntUnInstall); + // Count marked packages that can be installed/uninstalled + + void packageHighlighted(QListViewItem *item, packageDisplayWidget *packageDisplay); + // A package has been highlighted in the list tree + + KpTreeListItem *search(const QString &str, const QString &head, + KpTreeListItem *start = 0); + KpTreeListItem *search(const QString &str, bool subStr, bool wrap, bool start); + // search for a package in tree + KpTreeListItem *changePack(KpTreeListItem *searchResult, bool push = true); + // Change to other package + + void stackRemove(KpTreeListItem *pack); + // Remove entry from package stack + + void readTreeType(); + void writeTreeType(); + // config: Tree display type + + void writeTreeConfig(); + void readTreeConfig(); + // save and restore column positions + + int treeType; + +public slots: + void next(); + // Package stack forward + + void previous(); + // Package stack back + +private: + int sweepChild(KpTreeListItem *it); + void expandChild(KpTreeListItem *it); + + bool searchChild(KpTreeListItem *it); + // recurse thru the display tree looking for 'str' + + bool notPress; + // flag to packageHighlighted + + KpTreeListItem *searchCitem; + bool searchSkip, searchSubstr; + QString searchStr; + KpTreeListItem *searchResult; + // globals used by searchChild for start from current position, + // skip to current item before search flag, substring search flag, + // search string, result item (if found) + + // flag skipping in searchChild + + +signals: + void updateMarked(); + void cleared(); +}; + +//////////////////////////////////////////////////////////////////////// +class KpTreeListItem : public QListViewItem +{ +public: + KpTreeListItem( QListViewItem *parent, packageInfo* pinfo, + const QPixmap& thePixmap, + QString label1 = 0, QString label2 = 0, + QString label3 = 0, QString label4 = 0, + QString label5 = 0, QString label6 = 0, + QString label7 = 0, QString label8 = 0); + + + KpTreeListItem( KListView *parent, packageInfo* pinfo, + const QPixmap& thePixmap, + QString label1 = 0, QString label2 = 0, + QString label3 = 0, QString label4 = 0, + QString label5 = 0, QString label6 = 0, + QString label7 = 0, QString label8 = 0); + + + KpTreeListItem *firstChild(); + KpTreeListItem *nextSibling(); + + void toggleMark(); + void setMark(bool mark); + // flag for install/uninstall + + void hide(); + void show(); + + virtual int compare( QListViewItem *i, int col, bool ascending ) const; + + packageInfo *info; + bool marked; +}; + + +#endif diff --git a/kpackage/main.cpp b/kpackage/main.cpp new file mode 100644 index 0000000..781d741 --- /dev/null +++ b/kpackage/main.cpp @@ -0,0 +1,159 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +// Author: Damyan Pepper +// Author: Toivo Pedaste +// +// This is the entry point to the program +*/ + +/* +** 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 +*/ + +#include <stdlib.h> + +#include "../config.h" +#include "kpackage.h" + +#include <qfile.h> + +#include <kapplication.h> +#include <kglobal.h> +#include <klocale.h> +#include <kcmdlineargs.h> +#include <options.h> + +#include <kaboutdata.h> +#include <kdebug.h> + +#include <kpTerm.h> +#include "debInterface.h" +#include "debAptInterface.h" +#include "debDpkgInterface.h" +#include "kissInterface.h" +#include "slackInterface.h" +#include "fbsdInterface.h" +#include "rpmInterface.h" +#include "gentooInterface.h" + + +static const char description[] = + I18N_NOOP("KDE Package installer"); + +static KCmdLineOptions options[] = +{ + { "remote ", I18N_NOOP("Remote host for Debian APT, via SSH"), 0 }, + { "r ", 0, 0}, + { "+[Package]", I18N_NOOP("Package to install"), 0 }, + KCmdLineLastOption +}; + +// Globals +KPKG *kpkg; +KPACKAGE *kpackage; +kpPty *kpty; +kpRun *kprun; +kpRun *kpstart; +Opts *opts; + +QString hostName; + +pkgInterface *kpinterface[kpinterfaceN]; + +int main(int argc, char **argv) +{ + KAboutData aboutData( "kpackage", I18N_NOOP("KPackage"), + VERSION, description, KAboutData::License_GPL, + // VERSION, description, 0, + "(c) 1999-2001, Toivo Pedaste"); + KCmdLineArgs::init( argc, argv, &aboutData ); + aboutData.addAuthor( "Toivo Pedaste",0, "toivo@ucs.uwa.edu.au"); + KCmdLineArgs::addCmdLineOptions( options ); // Add our own options. + KApplication app; + + kpkg = 0; + int j = 0; + +// Make sure PATH has the right directories in it + QCString path = getenv("PATH"); + path = "PATH=" + path + ":/sbin:/usr/sbin:/usr/local/bin"; + putenv(strdup(path.data())); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + QString remoteHost = args->getOption("remote"); + + if (remoteHost.isEmpty() || remoteHost == "localhost") { + hostName = ""; + } else { + hostName = remoteHost; + } + + kpty = new kpPty(); + kprun = new kpRun(); + kpstart = new kpRun(); + + for (int i = 0; i < kpinterfaceN; i++) { + kpinterface[i] = 0; + } + + kdDebug() << "Hostname=" << hostName << "\n"; + opts = new Opts(hostName); + + kpinterface[j++] = new DEBDPKG(); + kpinterface[j++] = new DEBAPT(); + kpinterface[j++] = new KISS(); + kpinterface[j++] = new RPM(); + kpinterface[j++] = new fbsdInterface(); + kpinterface[j++] = new SLACK(); // Also catched BSD packages... + kpinterface[j++] = new Gentoo(); + + opts->readLaterSettings(); + + if ( app.isRestored() ) { + if (KPKG::canBeRestored(1)) { + kpkg = new KPKG(app.config()); + kpkg->restore(1); + } + } else { + // Create the main widget and show it + kpkg = new KPKG(app.config()); + kpkg->show(); + } + kpkg->setCaption(hostName); + + if (args->count()) { // an argument has been given + QStringList files; + for(int i = 0; i < args->count(); i++) { + files.append(args->url(i).url()); + } + kpackage->openNetFiles(files, FALSE); + } else { + if (!kpkg->prop_restart) + kpackage->setup(); + } + + args->clear(); + + int r = app.exec(); // execute the application + + return r; // return the result +} + diff --git a/kpackage/managementWidget.cpp b/kpackage/managementWidget.cpp new file mode 100644 index 0000000..50cda53 --- /dev/null +++ b/kpackage/managementWidget.cpp @@ -0,0 +1,699 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +// Author: Damyan Pepper +// Author: Toivo Pedaste +// +// See managementWidget.h for more information +*/ + +/* +** 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 +*/ + + +#include <qsplitter.h> +#include <qtoolbutton.h> + +#include <klocale.h> +#include <kdebug.h> +#include <klistviewsearchline.h> +#include <kaction.h> +#include <kstdaction.h> +#include <ktoolbar.h> +#include <kiconloader.h> + +// kpackage.headers +#include "kpackage.h" +#include "kplview.h" +#include "managementWidget.h" +#include "pkgInterface.h" +#include "pkgOptions.h" +#include "packageDisplay.h" +#include "packageProperties.h" +#include "options.h" + +extern Opts *opts; + +KpListViewSearchLine::KpListViewSearchLine(QWidget *parent, KpTreeList *listView) + :KListViewSearchLine(parent, listView) +{ + list = listView; +} + +KpListViewSearchLine::~KpListViewSearchLine() +{ +} + +void KpListViewSearchLine::updateSearch(const QString &s) +{ + list->expand(); + KListViewSearchLine::updateSearch(s); + KListViewSearchLine::updateSearch(s); // Yes both are needed + list->sweep(false); +} + + +// constructor -- initialise variables +managementWidget::managementWidget(QWidget *parent) + : QFrame(parent) +{ + install_action = 0; + uninstall_action = 0; + + allPackages = new QPtrList<packageInfo>; + + tType[0] = i18n("Installed"); + tType[1] = i18n("Updated"); + tType[2] = i18n("New"); + tType[3] = i18n("All"); + + dirInstPackages = new QDict<packageInfo>(7717); + dirUninstPackages = new QDict<packageInfo>(7717); + dirInfoPackages = new QDict<packageInfo>(7717); + + setupWidgets(); + + connect(treeList,SIGNAL(updateMarked()), + this, SLOT( checkMarked())); +} + +managementWidget::~managementWidget() +{ + // if(allPackages) + // delete allPackages; + // delete dirInstPackages; + // delete dirUninstPackages; +} + +void managementWidget::resizeEvent(QResizeEvent *) +{ + arrangeWidgets(); +} + + +void managementWidget::setupWidgets() +{ + QTab t; + + top = new QBoxLayout(this,QBoxLayout::TopToBottom); + vPan = new QSplitter(QSplitter::Horizontal, this); + top->addWidget(vPan); + + // the left panel + leftpanel = new QFrame(vPan); + leftbox = new QBoxLayout(leftpanel,QBoxLayout::TopToBottom); + + QTabBar *ltab = new QTabBar(leftpanel); + + treeList = new KpTreeList(leftpanel); + + + for (int i = 0; i < 4; i++) { + QTab *t = new QTab(); + t->setText( tType[i] ); + ltab->addTab(t); + } + // Quick Search Bar + searchToolBar = new KToolBar( leftpanel, "search toolbar"); + + QToolButton *clearSearch = new QToolButton(searchToolBar); + clearSearch->setTextLabel(i18n("Clear Search"), true); + clearSearch->setIconSet(SmallIconSet(QApplication::reverseLayout() ? "clear_left" + : "locationbar_erase")); + (void) new QLabel(i18n("Search: "),searchToolBar); + + searchLine = new KpListViewSearchLine(searchToolBar, treeList); + // searchLine->setKeepParentsVisible(false); + connect( clearSearch, SIGNAL( pressed() ), searchLine, SLOT( clear() )); + + QValueList<int> clist; clist.append(0); clist.append(2); + searchLine->setSearchColumns(clist); + + searchToolBar->setStretchableWidget( searchLine ); + connect( treeList, SIGNAL( cleared() ), searchLine, SLOT( clear() )); + + connect(ltab,SIGNAL(selected (int)),SLOT(tabChanged(int))); + ltab->setCurrentTab(treeList->treeType); + + leftbox->addWidget(ltab,10); + leftbox->addWidget(searchToolBar,10); + leftbox->addWidget(treeList,10); + + leftbox->addStretch(); + + lbuttons = new QBoxLayout(QBoxLayout::LeftToRight); + + luinstButton = new QPushButton(i18n("Uninstall Marked"),leftpanel); + luinstButton->setEnabled(FALSE); + connect(luinstButton,SIGNAL(clicked()), + SLOT(uninstallMultClicked())); + linstButton = new QPushButton(i18n("Install Marked"),leftpanel); + linstButton->setEnabled(FALSE); + connect(linstButton,SIGNAL(clicked()), + SLOT(installMultClicked())); + + leftbox->addLayout(lbuttons,0); // top level layout as child + + // Setup the `buttons' layout + lbuttons->addWidget(linstButton,1,AlignBottom); + lbuttons->addWidget(luinstButton,1,AlignBottom); + lbuttons->addStretch(1); + + connect(treeList, SIGNAL(selectionChanged(QListViewItem *)), + SLOT(packageHighlighted(QListViewItem *))); + + // the right panel + rightpanel = new QFrame(vPan); + rightbox = new QBoxLayout(rightpanel,QBoxLayout::TopToBottom); + + packageDisplay = new packageDisplayWidget(rightpanel); + // connect(this, SIGNAL(changePackage(packageInfo *)), + // packageDisplay, SLOT(changePackage(packageInfo *))); + + rbuttons = new QBoxLayout(QBoxLayout::LeftToRight); + + uinstButton = new QPushButton(i18n("Uninstall"),rightpanel); + uinstButton->setEnabled(FALSE); + connect(uinstButton,SIGNAL(clicked()), + SLOT(uninstallSingleClicked())); + instButton = new QPushButton(i18n("Install"),rightpanel); + instButton->setEnabled(FALSE); + connect(instButton,SIGNAL(clicked()), + SLOT(installSingleClicked())); + + + // Setup the `right panel' layout + rightbox->addWidget(packageDisplay,10); + rightbox->addLayout(rbuttons,0); // top level layout as child + + // Setup the `buttons' layout + rbuttons->addWidget(instButton,1); + rbuttons->addWidget(uinstButton,1); + rbuttons->addStretch(1); + +} + +//////////////////////////////////////////////////////////////// + + + +//////////////////////////////////////////////////////////////// +void managementWidget::writePSeparator() +{ + KConfig *config = kapp->config(); + + config->setGroup("Kpackage"); + + config->writeEntry("panel1Width",vPan->sizes().first()); + config->writeEntry("panel2Width",vPan->sizes().last()); +} + +void managementWidget::readPSeparator() +{ + KConfig *config = kapp->config(); + + config->setGroup("Kpackage"); + + int w1 = config->readNumEntry("panel1Width",200); + int w2 = config->readNumEntry("panel2Width",200); + + QValueList<int> size; + size << w1 << w2; + vPan->setSizes(size); +} + +/////////////////////////////////////////////////////////////////// +void managementWidget::setupMultButton(int &cntInstall, int &cntUnInstall) +{ + if (cntInstall) + linstButton->setEnabled(true); + else + linstButton->setEnabled(false); + + if (cntUnInstall) + luinstButton->setEnabled(true); + else + luinstButton->setEnabled(false); +} + +void managementWidget::setupInstButton() +{ + bool u,i; + + packageInfo *package = packageDisplay->package; + + if (!package) { + i = false; + u = false; + } else { + if (package->isFetchable() ) { + instButton->setText(i18n("Install")); + } else { + instButton->setText(i18n("Fetch")); + } + if (package->isInstallable() ) { + + i = true; + u = false; + } else { + i = false; + u = true; + } + } + instButton->setEnabled(i); + if (install_action) + install_action->setEnabled(i); + + uinstButton->setEnabled(u); + if (uninstall_action) + uninstall_action->setEnabled(u); +} + +void managementWidget::arrangeWidgets() +{ + // this is done automatically by the layout managers +} + +void managementWidget::tabChanged(int tab) +{ + treeList->treeType = tab; + searchLine->updateSearch(); +} + + +// Collect data from package. +void managementWidget::collectData(bool refresh) +{ + int i; + + if (!refresh && allPackages) { + treeList->sweep(true); + return; // if refresh not required already initialised + } + + QApplication::setOverrideCursor( waitCursor ); + +// stop clear() sending selectionChanged signal + disconnect(treeList, SIGNAL(selectionChanged(QListViewItem *)), + this, SLOT(packageHighlighted(QListViewItem *))); + treeList->hide(); // hide list tree + treeList->clear(); // empty it + connect(treeList, SIGNAL(selectionChanged(QListViewItem *)), + SLOT(packageHighlighted(QListViewItem *))); + + packageDisplay->changePackage(0); + + // Delete old list if necessary + if(allPackages) { + delete allPackages; + } + + allPackages = new QPtrList<packageInfo>; + allPackages->setAutoDelete(TRUE); + + dirInstPackages->clear(); + dirUninstPackages->clear(); + // List installed packages + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i] && kpinterface[i]->hasProgram && opts->handlePackage[i]) { + if (hostName.isEmpty() || (kpinterface[i]->hasRemote)) { + kpinterface[i]->listPackages(allPackages); + } + } + } + + // Rebuild the list tree + rebuildListTree(); + + QApplication::restoreOverrideCursor(); +} + +// Rebuild the list tree +void managementWidget::rebuildListTree() +{ + packageInfo *i; + int n = 0; + + kpackage->setStatus(i18n("Building package tree")); + kpackage->setPercent(0); + + treeList->setSorting(-1); + + // place all the packages found + int count = allPackages->count(); + int incr = count/50; + if (incr == 0) + incr = 1; + + for(i=allPackages->first(); i!=0; i=allPackages->next()) + { + i->place(treeList,TRUE); + + if (!(n % incr)) { + kpackage->setPercent(int (n*100/count)); + } + n++; + } + treeList->sweep(true); + treeList->show(); // show the list tree + + treeList->setSorting(0); + + kpackage->setPercent(100); // set the progress + kpackage->setStatus(""); + + checkMarked(); +} + +// A package has been highlighted in the list tree +void managementWidget::packageHighlighted(QListViewItem *item) +{ + + treeList->packageHighlighted(item, packageDisplay); + setupInstButton(); + + kpackage->setPercent(100); +} + +///////////////////////////////////////////////////////////////////////// +// install has been clicked + +void managementWidget::installSingleClicked() +{ + int result; + QPtrList<packageInfo> plist; + + packageInfo *package = packageDisplay->package; + + if (package) { + QString filename = package->getFilename(); + kdDebug() << "File=" << filename <<"\n"; + pkgInterface *interface = package->interface; + if (interface->noFetch || !filename.isEmpty()) { + plist.append(package); + if (!interface->installation->setup(&plist, interface->head)) { + return; + } + result = interface->installation->exec(); + + if (interface->installation->result() == QDialog::Accepted || + interface->installation->modified) { + // it was accepted, so the package has been installed + packageInfo *inf; + for (inf = plist.first(); inf != 0; inf = plist.next()) { + updatePackage(inf,TRUE); + } + + if (treeList->currentItem()) { + KpTreeListItem *p = treeList->currentItem(); + packageDisplay->changePackage(p->info); + } else { + packageDisplay->changePackage(0); // change package to no package + } + setupInstButton(); + } + + // kdDebug() << "Result=" << result <<"\n"; + } else { + QString url = package->getUrl(); + if (!url.isEmpty()) { + QString s = kpackage->fetchNetFile(url); + if (!s.isEmpty()) { + packageDisplay->changePackage(package); + setupInstButton(); + } + } else { + KpMsgE(i18n("Filename not available\n"),TRUE); + } + } + } + kpackage->setPercent(100); + + searchLine->updateSearch(); + checkMarked(); +} + +// install has been clicked +void managementWidget::installMultClicked() +{ + int i; + KpTreeListItem *it; + packageInfo *inf; + QPtrList<packageInfo> **lst = new QPtrList<packageInfo>*[kpinterfaceN]; + + selList.clear(); + treeList->findMarked(treeList->firstChild(), selList); + + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) { + lst[i] = new QPtrList<packageInfo>; + for (it = selList.first(); it != 0; it = selList.next()) { + if (it->info->interface == kpinterface[i] && + it->childCount() == 0 && + (it->info->packageState == packageInfo::UPDATED || + it->info->packageState == packageInfo::NEW) + ) { + lst[i]->insert(0,it->info); + } + } + } + } + selList.clear(); + + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) { + if (lst[i]->count() > 0) { + if (kpinterface[i]->installation->setup(lst[i],kpinterface[i]->head)) { + if (kpinterface[i]->installation->exec() || + kpinterface[i]->installation->modified) { + for (inf = lst[i]->first(); inf != 0; inf = lst[i]->next()) { + updatePackage(inf,TRUE); + } + } + } + delete lst[i]; + } + } + } + delete [] lst; + + searchLine->updateSearch(); + checkMarked(); +} + +///////////////////////////////////////////////////////////////////////////// +// Uninstall has been clicked + +void managementWidget::uninstallSingleClicked() +{ + int result; + QPtrList<packageInfo> plist; + + packageInfo *package = packageDisplay->package; + + if (package) { // check that there is a package to uninstall + pkgInterface *interface = package->interface; + plist.append(package); + if (!interface->uninstallation->setup(&plist, interface->head)) { + return; + } + result = interface->uninstallation->exec(); + + if(result == QDialog::Accepted || + interface->installation->modified) { + packageInfo *inf; + for (inf = plist.first(); inf != 0; inf = plist.next()) { + updatePackage(inf,FALSE); + } + + if (treeList->currentItem()) { + KpTreeListItem *p = treeList->currentItem(); + packageDisplay->changePackage(p->info); + } else { + packageDisplay->changePackage(0); // change package to no package + } + setupInstButton(); + } + // kdDebug() << "Result=" << result <<"\n"; + } + kpackage->setPercent(100); + + searchLine->updateSearch(); + checkMarked(); +} + +void managementWidget::uninstallMultClicked() +{ + int i; + KpTreeListItem *it; + packageInfo *inf; + QPtrList<packageInfo> **lst = new QPtrList<packageInfo>*[kpinterfaceN]; + + selList.clear(); + treeList->findMarked(treeList->firstChild(), selList); + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) { + lst[i] = new QPtrList<packageInfo>; + for (it = selList.first(); it != 0; it = selList.next()) { + if (it->info->interface == kpinterface[i] && + it->childCount() == 0 && + (it->info->packageState == packageInfo::INSTALLED || + it->info->packageState == packageInfo::BAD_INSTALL) + ) { + lst[i]->insert(0,it->info); + } + } + } + } + selList.clear(); + + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) { + if (lst[i]->count() > 0) { + if (kpinterface[i]->uninstallation->setup(lst[i],kpinterface[i]->head)) { + if (kpinterface[i]->uninstallation->exec()|| + kpinterface[i]->installation->modified ) { + for (inf = lst[i]->first(); inf != 0; inf = lst[i]->next()) { + updatePackage(inf,FALSE); + } + } + } + delete lst[i]; + } + } + } + delete [] lst; + + searchLine->updateSearch(); + checkMarked(); +} + + +/////////////////////////////////////////////////////////////////////////// + +void managementWidget::doChangePackage(packageInfo *p) +{ + packageDisplay->changePackage(p); +} + +/////////////////////////////////////////////////////////////////////////// + +KpTreeListItem *managementWidget::search(QString str, bool subStr, bool wrap, + bool start) +{ + return treeList->search(str, subStr, wrap, start); +} + + +/////////////////////////////////////////////////////////////////////////// +KpTreeListItem *managementWidget::updatePackage(packageInfo *pki, bool install) +{ + QString version; + KpTreeListItem *q; + + if (allPackages) { + QString name(pki->getProperty("name")); + if (pki->hasProperty("version")) + version = pki->getProperty("version"); + else + version = ""; + pkgInterface *interface = pki->interface; + packageInfo *pnew = interface->getPackageInfo('i', name, version); + packageInfo *ptree; + QString pkgId = name + interface->typeID; + + if (install) { + if (pnew) { + if (pnew->packageState != packageInfo::BAD_INSTALL) { + ptree = dirInstPackages->find(pkgId); // remove installed entry + dirInstPackages->remove(pkgId); + if (ptree) { + if (ptree->getItem()) { + delete ptree->getItem(); + ptree->item = 0; + } + } + + ptree = dirUninstPackages->find(pkgId); // remove uninstalled entry + if (ptree) { + ptree->packageState = packageInfo::HIDDEN; + if (ptree->getItem()) { + delete ptree->getItem(); + ptree->item = 0; + } + } + } + + dirInstPackages->insert(pkgId,pnew); + + q = pnew->place(treeList,TRUE); + allPackages->insert(0,pnew); + if (!q) { + printf("NOTP=%s \n",pnew->getProperty("name").ascii()); + } else { + return q; + } + } + } else { // uninstalling + if (!pnew) { + dirInstPackages->remove(pkgId); + KpTreeListItem *qt = pki->getItem(); + if (qt) { + treeList->stackRemove(qt); + treeList->setSelected(qt,false); + if (treeList->markPkg == qt) + treeList->markPkg = 0; + delete qt; + } else { + kdDebug() << "DEL=" << name << endl; + } + packageInfo *pb = dirUninstPackages->find(pkgId); + if (pb) { // available package matching the one just uninstalled + pb->packageState = packageInfo::NEW; + q = pb->place(treeList,TRUE); + if (!q) { + printf("NOTP=%s \n",pb->getProperty("name").ascii()); + } else { + return q; + } + } + + } else { + delete pnew; + } + } + } + + return 0; +} + +/////////////////////////////////////////////////////////////////////////// +void managementWidget::checkMarked() +{ +int cntInstall = 0; +int cntUnInstall = 0; + + treeList->countMarked(treeList->firstChild(), cntInstall, cntUnInstall); + setupMultButton(cntInstall, cntUnInstall); +} + + +#include "managementWidget.moc" diff --git a/kpackage/managementWidget.h b/kpackage/managementWidget.h new file mode 100644 index 0000000..bf1c6d1 --- /dev/null +++ b/kpackage/managementWidget.h @@ -0,0 +1,227 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +// Author: Damyan Pepper +// +// This widget is used to provide the management mode of ksetup. +// There are two subwidgets; firstly a tree list showing all the +// currently installed packages and secondly a display of the currently +// selected package's properties. +// +// There are also some control buttons which allow the currently +// selected package to be uninstalled or verified. +*/ + +/* +** 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 +*/ + + + + +#ifndef MANAGEMENTWIDGET_H +#define MANAGEMENTWIDGET_H + +#include "../config.h" +// Standard Headers + +// Qt Headers +#include <qframe.h> +#include <qpushbutton.h> +#include <qptrlist.h> +#include <qstring.h> +#include <qlayout.h> +#include <qtabwidget.h> +#include <qlabel.h> +#include <qhbox.h> + +// KDE headers +#include <kaction.h> +#include <klistview.h> +#include <klistviewsearchline.h> + +// ksetup headers +#include "packageInfo.h" +#include "kplview.h" + +class packageDisplayWidget; +class packageInfo; +class QSplitter; +class KActionCollection; +class KToolBar; +class managementWidget; + +class KpListViewSearchLine : public KListViewSearchLine +{ + Q_OBJECT + +public: + + KpListViewSearchLine(QWidget *parent, KpTreeList *listView); + + ~KpListViewSearchLine(); + + + void updateSearch(const QString &s = QString::null); + +private: + KpTreeList *list; +}; + + +class managementWidget : public QFrame +{ + Q_OBJECT + + ///////////// METHODS ------------------------------------------------------ +public: + managementWidget(QWidget *parent); + // Constructor + + ~managementWidget(); + // Destructor + + KpTreeListItem *updatePackage(packageInfo *pki, bool install); + // update package in treelist + + void readPSeparator(); + void writePSeparator(); + // config: position of panel seperator + + void doChangePackage(packageInfo *p); + // emit change package + + KpTreeListItem *search(QString str, bool subStr, bool wrap, + bool start=FALSE); +protected: + void resizeEvent(QResizeEvent *re); + // This is called when the widget is resized + +private: + void setupWidgets(); + // This sets up the sub-widgets + + void setupInstButton(); + // Set button for inst or uninst + + void arrangeWidgets(); + // This arranges the widgets in the window (should be called after a + // resize event) + + void setupMultButton(int &cntInstall, int &cntUnInstall); + // Setup mult install/uninstall button appropriately + + + ///////////// SLOTS ------------------------------------------------------ + public slots: + void collectData(bool refresh); + // This collects data about all the packages installed. + // The list tree is filled with this data. Whenever something happens + // that requires data to be (re)collected a signal connected to this slot + // should be emitted. This function can also be called directly. + + void rebuildListTree(); + // This rebuilds the list tree. This would normally be called if the + // data contained about the packages has been changed (e.g. a verification + // failed / succeeded). + + void uninstallMultClicked(); + // This is called when uninstalling multiple packages + + void uninstallSingleClicked(); + // This is called when uninstalling a single package + + void installSingleClicked(); + // This is called when the install button has been clicked with single package + + void installMultClicked(); + // This is called when the install button has been clicked with multiple packages + + void setInstallAction(KAction *a) { install_action = a; } + void setUninstallAction(KAction *a) { uninstall_action = a; } + + void packageHighlighted(QListViewItem *); + // This is called when a package has been highlighted in the list tree + + void tabChanged(int); + // treelist display tab changed + + void checkMarked(); + // Count marked packages that can be installed/uninstalled + + ///////////// SIGNALS ------------------------------------------------------ + + + ///////////// DATA --------------------------------------------------------- +private: + + QPushButton *linstButton,*luinstButton,*instButton,*uinstButton; + // This button is used to (un)install the selected package + + packageDisplayWidget *packageDisplay; + // This widget displays the package info / file-list + + QBoxLayout *top, *leftbox, *rightbox, *lbuttons, *rbuttons; + // These are the geometry managers + + QFrame *leftpanel, *rightpanel; + // frame to put QBox in + + QTabWidget *ltab; + // tab between various treelist displays + + QSplitter *vPan; + // veritcal panner between panels + + KToolBar *searchToolBar; + + QPtrList<KpTreeListItem> selList; + // list for selected packages + + QString tType[4]; + // identifiers for tree display + +public: + QPtrList<packageInfo> *allPackages; + // The list of packages + + QDict<packageInfo> *dirInstPackages; + // maps installed package name to package + + QDict<packageInfo> *dirUninstPackages; + // maps uninstalled package name to package + + QDict<packageInfo> *dirInfoPackages; + // maps Info package name to package + + KpTreeList *treeList; + // This is the tree list where all the packages / groups are displayed + + KpListViewSearchLine *searchLine; + // Widget for search treeList + + KAction *install_action; + KAction *uninstall_action; +}; + +#endif + + + diff --git a/kpackage/mini-icon/cr16-mime-debfile.png b/kpackage/mini-icon/cr16-mime-debfile.png Binary files differnew file mode 100644 index 0000000..35c3b4e --- /dev/null +++ b/kpackage/mini-icon/cr16-mime-debfile.png diff --git a/kpackage/mini-icon/cr16-mime-rpmfile.png b/kpackage/mini-icon/cr16-mime-rpmfile.png Binary files differnew file mode 100644 index 0000000..27fa032 --- /dev/null +++ b/kpackage/mini-icon/cr16-mime-rpmfile.png diff --git a/kpackage/options.cpp b/kpackage/options.cpp new file mode 100644 index 0000000..758e68d --- /dev/null +++ b/kpackage/options.cpp @@ -0,0 +1,469 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#include "../config.h" + +#include "kpackage.h" +#include "managementWidget.h" +#include "pkgInterface.h" +#include "options.h" +#include "cache.h" + +#include <qvbox.h> +#include <qcheckbox.h> +#include <klocale.h> +#include <kdebug.h> +#include <kurlrequester.h> +#include <qframe.h> +#include <qlabel.h> +#include <qgroupbox.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qbuttongroup.h> +#include <qradiobutton.h> +#include <qtabdialog.h> +#include <kcombobox.h> +#include <klineedit.h> + +#include <findf.h> + +extern Opts *opts; +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +Options::Options(QWidget *parent) + : KDialogBase(Tabbed, i18n("Options"), Ok | Cancel, Ok, parent, 0, false){ + + fRemote = false; + + DCache = dc = opts->DCache; + PCache = pc = opts->PCache; + privCmd = prc = opts->privCmd; + + if (DCache >= Opts::SESSION) { + cacheObj::clearDCache(); // clear dir caches if needed + } + if (PCache >= Opts::SESSION) { + cacheObj::clearPCache(); // clear package caches if needed + } + + { + QVBox *page = addVBoxPage(i18n("&Types")); + + framet = new QGroupBox(1,Qt::Horizontal,i18n("Handle Package Type"), page); + + hh = new QGroupBox(1,Qt::Horizontal,i18n("Remote Host"),framet); + huse = new QCheckBox(i18n("Use remote host (Debian APT only):"),hh); + connect(huse, SIGNAL(clicked()), this, SLOT(useRemote())); + hosts = new KComboBox( true, hh, "combo" ); + KCompletion *comp = hosts->completionObject(); + connect(hosts,SIGNAL(returnPressed(const QString&)),comp,SLOT(addItem(const QString&))); + connect(hosts,SIGNAL(returnPressed()),this,SLOT(insHosts())); + hosts->setMaxCount(20); + hosts->setDuplicatesEnabled(false); + hosts->setInsertionPolicy(QComboBox::AtTop); + // hosts->setInsertionPolicy(QComboBox::NoInsertion); + hosts->setTrapReturnKey(true); + + int i; + QString msgStr; + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) { + if (kpinterface[i]->hasProgram) { + msgStr = kpinterface[i]->name; + } else { + msgStr = kpinterface[i]->name; + msgStr = i18n("%1: %2 not found") + .arg(kpinterface[i]->name) + .arg(kpinterface[i]->errExe); + } + packageBox[i] = new QGroupBox(2,Qt::Horizontal,msgStr, framet, "box"); + packageHandle[i] = new QCheckBox(i18n("Enable"), packageBox[i]); + connect(packageHandle[i], SIGNAL(clicked()), this, SLOT(scanLocates())); + locate[i] = new QPushButton(i18n("Location of Packages"),packageBox[i]); + connect(locate[i], SIGNAL(clicked()), kpinterface[i], SLOT(setLocation())); + } else { + packageHandle[i] = 0; + } + } + } + + { + QVBox *page = addVBoxPage(i18n("Cac&he")); + + bc = new QButtonGroup(page); + bc->setTitle(i18n("Cache Remote Package Folders")); + connect( bc, SIGNAL(clicked(int)), SLOT(PDCache(int)) ); + + QVBoxLayout* vc = new QVBoxLayout( bc, 15, 10, "vc"); + vc->addSpacing( bc->fontMetrics().height() ); + + dcache[0] = new QRadioButton(i18n("Always"),bc); + vc->addWidget(dcache[0]); + + dcache[1] = new QRadioButton(i18n("During a session"),bc); + vc->addWidget(dcache[1]); + + dcache[2] = new QRadioButton(i18n("Never"),bc); + vc->addWidget(dcache[2]); + + bp = new QButtonGroup(page); + bp->setTitle(i18n("Cache Remote Package Files")); + connect( bp, SIGNAL(clicked(int)), SLOT(PPCache(int)) ); + + QVBoxLayout* vp = new QVBoxLayout( bp, 15, 10, "vp"); + vp->addSpacing( bp->fontMetrics().height() ); + + pcache[0] = new QRadioButton(i18n("Always"),bp); + vp->addWidget(pcache[0]); + + pcache[1] = new QRadioButton(i18n("During a session"),bp); + vp->addWidget(pcache[1]); + + pcache[2] = new QRadioButton(i18n("Never"),bp); + vp->addWidget(pcache[2]); + + QGroupBox* cd = new QGroupBox (1, Qt::Horizontal, i18n("Cache Folder"), page) ; + cd->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Fixed) ; + + cachedir = new KURLRequester("", cd, "cachedir"); + } + + { + QWidget *page = addVBoxPage(i18n("&Misc")); + QVBoxLayout *vf = new QVBoxLayout(page); + + // vf->setSpacing(KDialog::spacingHint()); + vf->setMargin(0); + + bs = new QButtonGroup(page); + bs->setTitle(i18n("Execute Privileged Commands Using")); + connect( bs, SIGNAL(clicked(int)), SLOT(PPrivs(int)) ); + + QVBoxLayout* vs = new QVBoxLayout( bs, 15, 10, "bs"); + vs->addSpacing( bs->fontMetrics().height() ); + + privs[0] = new QRadioButton(i18n("su command"),bs); + vs->addWidget(privs[0]); + + privs[1] = new QRadioButton(i18n("sudo command"),bs); + vs->addWidget(privs[1]); + + privs[2] = new QRadioButton(i18n("ssh command"),bs); + vs->addWidget(privs[2]); + + valid = new QCheckBox(i18n("Verify file list"), page, "valid"); + vf->addWidget(valid,0,AlignLeft); + + pkgRead = new QCheckBox(i18n("Read information from all local package files"), page, "pkgr"); + vf->addWidget(pkgRead,0,AlignLeft); + + vf->addSpacing(100); + } + + connect( this, SIGNAL(okClicked()), SLOT(apply_slot()) ); + connect( this, SIGNAL(closeClicked()), SLOT(cancel_slot()) ); + connect( this, SIGNAL(cancelClicked()), SLOT(cancel_slot()) ); + + setValues(); + +} + + +void Options::insHosts() { + // kdDebug() << "insHosts " << "\n"; + bool found = false; + QString s = hosts->currentText(); + + int i; + for (i = 0; i < hosts->count(); i++) { + if (s == hosts->text(i)) + found = true; + } + + if (!found) + hosts->insertItem(hosts->currentText(), 0); +} + +void Options::setValues() { + // kdDebug() << "setValues:\n"; + DCache = dc = opts->DCache; + PCache = pc = opts->PCache; + privCmd = prc = opts->privCmd; + CacheDir = opts->CacheDir; + + hosts->clear(); + hosts->completionObject()->clear(); + + hosts->insertStringList(opts->hostList); + if (hosts->completionObject()) { + hosts->completionObject()->setItems(opts->hostList); + } + + if (!hostName.isEmpty()) { + huse->setChecked(TRUE); + } + // kdDebug() << "C=" <<opts->hostList.count() << "\n"; + + int i; + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) { + packageHandle[i]->setChecked(opts->handlePackage[i]); + } + } + scanLocates(); + + dcache[DCache]->setChecked(TRUE); + pcache[PCache]->setChecked(TRUE); + privs[privCmd]->setChecked(TRUE); + cachedir->lineEdit()->setText(CacheDir); + + valid->setChecked(opts->VerifyFL); + pkgRead->setChecked(opts->PkgRead); +} + +Options::~Options() +{ +} + +void Options::scanLocates() { + int i; + + bool remote = huse->isChecked(); + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) { + // kdDebug() << i << " " << hostName << " " << kpinterface[i]->hasRemote << "\n"; + if (kpinterface[i]->hasProgram) { + packageBox[i]->setEnabled(true); + if (remote) { + if (kpinterface[i]->hasRemote) { + packageHandle[i]->setEnabled(true); + locate[i]->setEnabled(true); + } else { + packageHandle[i]->setEnabled(false); + locate[i]->setEnabled(false); + } + } else { + packageHandle[i]->setEnabled(true); + if ( packageHandle[i]->isChecked()) { + locate[i]->setEnabled(true); + } else { + locate[i]->setEnabled(false); + } + } + } else { + packageBox[i]->setEnabled(false); + } + } + } +} + +void Options::useRemote() +{ + scanLocates(); +} + +void Options::restore() +{ + show(); + fRemote = huse->isChecked(); +} + +void Options::cancel_slot() +{ + // kdDebug() << "Cancel\n"; + opts->readSettings(); + setValues(); +} + +void Options::apply_slot() +{ + bool doReload = false; + bool newHost = false; + + opts->VerifyFL = valid->isChecked(); + opts->PkgRead = pkgRead->isChecked(); + + insHosts(); + opts->hostList.clear(); + int i; + QString prev; + for (i = 0; i < hosts->count(); i++) { + // kdDebug() << "=" << prev << "=" << hosts->text(i) << "=\n"; + if (prev != hosts->text(i)) + opts->hostList.append(hosts->text(i)); + prev = hosts->text(i); + } + + QString remoteHost = hosts->currentText(); + + if ((fRemote != huse->isChecked()) || huse->isChecked() && (remoteHost != hostName)) { + newHost = true; + doReload = true; + } + if (huse->isChecked()) { + hostName = remoteHost; + } else { + hostName = ""; + } + kpkg->setCaption(hostName); + + opts->DCache = dc; + opts->PCache = pc; + opts->privCmd = prc; + cachedir->lineEdit()->setText (QDir(cachedir->lineEdit()->text()).path().append("/")) ; // make sure that cache directory ends with "/" + opts->CacheDir = cachedir->lineEdit()->text() ; + + for (i = 0; i < kpinterfaceN; i++) { + if (packageHandle[i]) { + if ( opts->handlePackage[i] != packageHandle[i]->isChecked()) { + doReload = true; + } + opts->handlePackage[i] = packageHandle[i]->isChecked(); + } + } + + if (kpackage->findialog) + kpackage->findialog->checkSearchAll(); + scanLocates(); + opts->writeSettings(); + + if (doReload) { + if (newHost) { + kpty->close(); + } + kpackage->reload(); + } +} + +void Options::PDCache(int r) +{ + dc = r; +} + +void Options::PPCache(int r) +{ + pc = r; +} + +void Options::PPrivs(int r) +{ + kdDebug() << "Privs=" << r << "\n"; + prc = r; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +Opts::Opts(const QString &initHost) +{ + readSettings(initHost); +} + +Opts::~Opts() +{ +} + +void Opts::readSettings(const QString &initHost) +{ + + KConfig *config = kapp->config(); + + config->setGroup("Kpackage"); + + // kdDebug() << "readSettings: " << initHost << "\n"; + hostList = config->readListEntry("Host_list"); + if (!initHost.isEmpty() && !hostList.contains(initHost)) { + hostList.prepend(initHost); + config->writeEntry("Host_list", hostList); + } + hostList.sort(); + + DCache = config->readNumEntry("Dir_Cache",1); + if (DCache >2) { + DCache = 1; + } + PCache = config->readNumEntry("Package_Cache",0); + if (PCache >2) { + PCache = 0; + } + CacheDir = config->readPathEntry("Cache_Directory", QDir::homeDirPath() + "/.kpackage/"); + + // Backward compatability + bool useSSH = config->readNumEntry("Use_SSH",0); + privCmd = config->readNumEntry("Priv_Command", -1); + + if (privCmd == -1) { + if (useSSH) { + privCmd = SSHcmd; + } else { + privCmd = SUcmd; + } + } + VerifyFL = config->readNumEntry("Verify_File_List",1); + PkgRead = config->readNumEntry("Read_Package_files",0); +} + +void Opts::readLaterSettings() +{ + KConfig *config = kapp->config(); + config->setGroup("Kpackage"); + + int i; + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) + handlePackage[i] = config->readBoolEntry(kpinterface[i]->head, + kpinterface[i]->defaultHandle); + } +} + +void Opts::writeSettings() +{ + + KConfig *config = kapp->config(); + + config->setGroup("Kpackage"); + + config->writeEntry("Host_list", hostList); + + config->writeEntry("Dir_Cache", DCache); + config->writeEntry("Package_Cache", PCache); + config->writePathEntry("Cache_Directory", CacheDir); + + config->writeEntry("Priv_Command",privCmd ); + + config->writeEntry("Verify_File_List",VerifyFL ); + config->writeEntry("Read_Package_files", PkgRead); + + int i; + for (i = 0; i < kpinterfaceN; i++) { + if (kpinterface[i]) + config->writeEntry(kpinterface[i]->head, handlePackage[i]); + } +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +#include "options.moc" diff --git a/kpackage/options.h b/kpackage/options.h new file mode 100644 index 0000000..4f8b1e7 --- /dev/null +++ b/kpackage/options.h @@ -0,0 +1,181 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + + +#ifndef OPTIONS_H +#define OPTIONS_H + +#include "../config.h" + +// Standard Headers +#include <stdio.h> + +// Qt Headers +#include <qdir.h> +#include <qwidget.h> +#include <qfiledialog.h> +#include <qgroupbox.h> + +// KDE headers +#include <kapplication.h> +#include <kfiledialog.h> + +#include <kpackage.h> + +class KURLRequester; + + +class QVBoxLayout; +class QGroupBox; +class QCheckBox; +class QPushButton; +class KComboBox; +class QButtonGroup; +class QRadioButton; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +class Options : public KDialogBase +{ + Q_OBJECT + +public: + + Options ( QWidget *parent = 0); + ~Options(); + + void restore(); + // show window, setting the buttons + + void setValues(); + // set the dialog to match options values + +private: + + bool verifyFL; + bool PkgRead; + bool fRemote; + int DCache, dc, PCache, pc, privCmd, prc; + QString CacheDir; + + QVBoxLayout* vl; + + QVBoxLayout* vt; + QGroupBox *framet; + QGroupBox *packageBox[kpinterfaceN]; + QCheckBox *packageHandle[kpinterfaceN]; + QPushButton *locate[kpinterfaceN]; + + QGroupBox *hh; + QCheckBox *huse; + KComboBox *hosts; + + QVBoxLayout* vb; + QButtonGroup *bg; + QRadioButton *disp[4]; + + QVBoxLayout* vc; + QButtonGroup *bc; + QRadioButton *dcache[3]; + + QVBoxLayout* vp; + QButtonGroup *bp; + QRadioButton *pcache[3]; + + QVBoxLayout* vs; + QButtonGroup *bs; + QRadioButton *privs[3]; + + KURLRequester *cachedir; + + QVBoxLayout* vr; + QGroupBox *framer; + QCheckBox *pkgRead; + + QVBoxLayout* vf; + QGroupBox *framem; + QCheckBox *valid; + + +public slots: + void scanLocates(); + void apply_slot(); + void cancel_slot(); + void PDCache(int); + void PPCache(int); + void PPrivs(int); + +private slots: + void insHosts(); + void useRemote(); +}; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +class Opts +{ +public: + void readSettings(const QString &initHost = ""); + void writeSettings(); + + void readLaterSettings(); + // options to be setup after package interfaces setup + + QStringList hostList; + // list of hosts to choose from + + bool VerifyFL; + // config: verify the file list + + bool PkgRead; + // read information about uninstalled packages from each RPM file itself + + bool handlePackage[kpinterfaceN]; + + enum {INSTALLED, UPDATED, NEW, ALL}; + enum {ALWAYS, SESSION, NEVER}; + + int DCache; + // how much to cache uninstall package directories + + int PCache; + // how much to cache uninstall packages + + int privCmd; + // which command to use to execute priveliged commands + enum {SUcmd=0, SUDOcmd=1, SSHcmd=2}; + + QString CacheDir; + // cache directory + + Opts(const QString &initHost); + ~Opts(); +}; +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +#endif diff --git a/kpackage/packageDisplay.cpp b/kpackage/packageDisplay.cpp new file mode 100644 index 0000000..67b0754 --- /dev/null +++ b/kpackage/packageDisplay.cpp @@ -0,0 +1,439 @@ +/* +** 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 +*/ + + +#include "../config.h" +// Standard headers +#include <stdio.h> + +// Qt headers + +#include <qapplication.h> +#include <qfileinfo.h> +#include <qtextedit.h> + +#include <kdebug.h> +#include <kiconloader.h> +#include <kglobal.h> +#include <krun.h> +#include <kopenwith.h> + +// kpackage.headers +#include "kpackage.h" +#include "packageDisplay.h" +#include "packageProperties.h" +#include "pkgInterface.h" +#include "utils.h" +#include "options.h" +#include <klocale.h> + +extern Opts *opts; + +// constructor +packageDisplayWidget::packageDisplayWidget(QWidget *parent) + : QTabWidget(parent) +{ + // Initially we're not dealing with any package + package=NULL; + + // Set up the widgets + setupWidgets(); + + // Load the pixmaps + tick = UserIcon("ptick"); + cross = UserIcon("cross"); + question = UserIcon("question"); + blank = new QPixmap(); + +} + +packageDisplayWidget::~packageDisplayWidget() +{ + delete blank; +} + +void packageDisplayWidget::setupWidgets() +{ + proptab = new QVBox( this); + curTab = proptab; + fltab = new QVBox( this); + cltab = new QVBox( this); + + packageProperties = new packagePropertiesWidget(proptab); + + fileList = new kpFileList(fltab, this); + connect(fileList, SIGNAL(executed(QListViewItem *)), + this, SLOT( openBinding(QListViewItem *)) ); + connect(fileList, SIGNAL(returnPressed(QListViewItem *)), + this, SLOT( openBinding(QListViewItem *)) ); + + changeLog = new QTextEdit(cltab); + + addTab(proptab, i18n("Properties")); + addTab(fltab, i18n("File List")); + addTab(cltab, i18n("Change Log")); + + if (isTabEnabled(cltab)) + setTabEnabled(cltab,false); + if (isTabEnabled(fltab)) + setTabEnabled(fltab,false); + if (isTabEnabled(proptab)) + setTabEnabled(proptab,false); + + connect(this,SIGNAL(currentChanged(QWidget *)), this, SLOT(tabSelected(QWidget *))); +} + +void packageDisplayWidget::tabSelected(QWidget *tab) +{ + curTab = tab; + tabSet(tab); +} + +void packageDisplayWidget::tabSet(QWidget *tab) +{ + disconnect(this,SIGNAL(currentChanged(QWidget *)), this, SLOT(tabSelected(QWidget *))); + if(tab == proptab) { + packageProperties->show(); + fileList->hide(); + changeLog->hide(); + setCurrentPage(0); + } else if (tab == fltab) { + packageProperties->hide(); + changeLog->hide(); + if (isTabEnabled(fltab)) { + if (!initList) { + updateFileList(); + initList = 1; + } + fileList->show(); + } else { + fileList->hide(); + } + setCurrentPage(1); + } else { + fileList->hide(); + packageProperties->hide(); + if (isTabEnabled(cltab)) { + updateChangeLog(); + changeLog->show(); + } else { + changeLog->hide(); + } + setCurrentPage(2); + } + connect(this,SIGNAL(currentChanged(QWidget *)), this, SLOT(tabSelected(QWidget *))); +} + +void packageDisplayWidget::noPackage() +{ + disconnect(this,SIGNAL(currentChanged(QWidget *)), this, SLOT(tabSelected(QWidget *))); + + if (isTabEnabled(fltab)) { + fileList->setColumnText(0,""); + setTabEnabled(fltab,false); + } + if (isTabEnabled(proptab)) + setTabEnabled(proptab,false); + if (isTabEnabled(cltab)) + setTabEnabled(cltab,false); + + packageProperties->changePackage(NULL); + + packageProperties->setText(""); + fileList->clear(); + changeLog->setText(""); + + connect(this,SIGNAL(currentChanged(QWidget *)), this, SLOT(tabSelected(QWidget *))); +} + +// Change packages +void packageDisplayWidget::changePackage(packageInfo *p) +{ + +// This is to stop selectionChanged firing off here + + disconnect(fileList, SIGNAL(executed(QListViewItem *)), + this, SLOT( openBinding(QListViewItem *)) ); + disconnect(fileList, SIGNAL(returnPressed(QListViewItem *)), + this, SLOT( openBinding(QListViewItem *)) ); + disconnect(fileList, SIGNAL(contextMenu(KListView *, QListViewItem *, const QPoint &)), + fileList, SLOT( openContext(KListView *, QListViewItem *, const QPoint &)) ); + + + if (package && package != p) { + if (!package->getItem() && !kpackage->management->allPackages->find(package)) { + delete package; + package = 0; + } + } + + package = p; + if (!p) { // change to no package + noPackage(); + } else { + QString u = package->getFilename(); + if (!package->updated && !u.isEmpty()) { + packageInfo *np = package->interface->getPackageInfo('u', u, 0); + + if (np) { + QMap<QString, QString>::Iterator it; // update info entries in p + for ( it = np->info.begin(); it != np->info.end(); ++it ) { + package->info.replace(it.key(),it.data()); + } + package->interface = np->interface; + delete np; + package->updated = TRUE; + } + } + + initList = 0; + packageProperties->changePackage(package); + + if (package->interface->changeTab(package)) + setTabEnabled(cltab,true); + else + setTabEnabled(cltab,false); + + if (package->interface->filesTab(package)) + setTabEnabled(fltab,true); + else + setTabEnabled(fltab,false); + + setTabEnabled(proptab,true); + + tabSet(curTab); + + + } + connect(fileList, SIGNAL(executed(QListViewItem *)), + this, SLOT( openBinding(QListViewItem *)) ); + connect(fileList, SIGNAL(returnPressed(QListViewItem *)), + this, SLOT( openBinding(QListViewItem *)) ); + connect(fileList, SIGNAL(contextMenu(KListView *, QListViewItem *, const QPoint &)), + fileList, SLOT( openContext(KListView *, QListViewItem *, const QPoint &)) ); + + } + +void packageDisplayWidget::updateChangeLog() +{ + if (!package) + return; + + QStringList lines; + QString stmp; + lines = package->interface->getChangeLog(package); + + + changeLog->setTextFormat(Qt::LogText); + changeLog->hide(); + if (lines.count() > 1) { + changeLog->setText(""); + for (QStringList::ConstIterator it = lines.begin(); + (it != lines.end()); + it++) { + if (! (*it).isEmpty()) + changeLog->append(*it); + else + changeLog->append(" "); + } + } else { + changeLog->setText(i18n(" - No change log -")); + } + + changeLog->show(); + changeLog->setContentsPos(0,0); + +} + +void packageDisplayWidget::updateFileList() +{ + if (!package) + return; + + // Get a list of files in the package + QStringList files; + QStringList errorfiles; + + // set the status + kpackage->setStatus(i18n("Updating File List")); + + // clear the file list + fileList->clear(); + + // Check if the package is installed + int installed; + if(package->getFilename().isEmpty()) { + if(package->packageState == packageInfo::UPDATED) { + fileList->setColumnText(0, ""); + return; + } else + installed=1; + } else + installed=0; + + files = package->interface->getFileList(package); + + if (files.count() == 0) + return; + + // Get a list of files that failed verification + if(installed && opts->VerifyFL) { + errorfiles = package->interface->verify(package, files); + } + + kpackage->setStatus(i18n("Updating File List")); + + uint c=0, p=0; + uint step = (files.count() / 100) + 1; + + QString ftmp; + ftmp.setNum(files.count()); + ftmp += i18n(" Files"); + + fileList->setColumnText(0, ftmp); + fileList->hide(); + fileList->setSorting(-1); + + QListViewItem *q; + + // Go through all the files + for (QStringList::ConstIterator it = files.begin(); (it != files.end()); ) { + // Update the status progress + c++; + if(c > step) { + c=0; + p++; + kpackage->setPercent(p); + } + + int error=0; + + QString cur = *it; + it++; + QPixmap pixmap; + + if (installed) { // see if file failed verification, + + if ( errorfiles.count() > 0) { + for( QStringList::ConstIterator itError = errorfiles.begin(); + (itError != errorfiles.end()); + (itError++) ) { + if (cur == *itError) { + error = 1; + } + } + } + if(error) pixmap=cross; + else + pixmap=tick; + + } else + pixmap=question; + + q = fileList->insert(cur, pixmap); + } + + fileList->setSorting(0); + fileList->show(); + kpackage->setPercent(100); +} + + kpFileList::kpFileList(QWidget* parent, packageDisplayWidget* parent2) : KListView(parent) + { + hide(); + addColumn("name"); + setRootIsDecorated(TRUE); + connect(this, SIGNAL(contextMenu(KListView *, QListViewItem *, const QPoint &)), + this, SLOT( openContext(KListView *, QListViewItem *, const QPoint &)) ); + + FileListMenu = new KPopupMenu(); + openwith = FileListMenu->insertItem(i18n("&Open With..."),parent2,SLOT(__openBindingWith())); + + pkDisplay = parent2; + } + + + void packageDisplayWidget::__openBindingWith() + { + openBindingWith(fileList->selectedItem()); + } + + void packageDisplayWidget::openBindingWith(QListViewItem *index) + { + if ( !index ) return; + KURL url; + if (package && package->packageState == packageInfo::INSTALLED) { + url.setPath( fileList->item2Path(index) ); // from local file to URL + KRun::displayOpenWithDialog(KURL::List::List(url) ); + } + } + + + void kpFileList::openContext(KListView *, QListViewItem *, const QPoint &p) + { + FileListMenu->setItemEnabled(openwith, + (selectedItem() && pkDisplay->package && pkDisplay->package->getFilename().isEmpty()) ? TRUE : FALSE); + FileListMenu->exec(p); + + } + + void kpFileList::clear() + { + KListView::clear(); + } + + QString kpFileList::item2Path(QListViewItem *it) + { + QString res; + res = it ? it->text(0) : NULL; + return res; + } + + + QListViewItem* kpFileList::insert(const QString &cur, const QPixmap &pixmap) + { + QListViewItem* q; + + q = new QListViewItem(this, cur); + if (q) + q->setPixmap(0,pixmap); + return q; + } + + void packageDisplayWidget::openBinding(QListViewItem *index) + { + if ( !index ) return; + KURL url; + if (package && package->packageState == packageInfo::INSTALLED) { + url.setPath( fileList->item2Path(index) ); // from local file to URL + (void) new KRun ( url ); // run the URL + } + } + + +#include "packageDisplay.moc" diff --git a/kpackage/packageDisplay.h b/kpackage/packageDisplay.h new file mode 100644 index 0000000..5631925 --- /dev/null +++ b/kpackage/packageDisplay.h @@ -0,0 +1,164 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +// This widget is used to display information and the file list of a +// package. +// +// Package information will be displayed using (another) sub-widget +// that is inherited from a QTableView. +// +// The file list will be displayed using a tree list. +// +// The widget is mainly a QTabDialog with two tabs: Info and FileList. +// The Info tab is the default one. +*/ + +/* +** 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 +*/ + + + + +#ifndef PACKAGEDISPLAY_H +#define PACKAGEDISPLAY_H +#include "../config.h" + +// Qt Headers +#include <qframe.h> +#include <qtabbar.h> +#include <qtabwidget.h> +#include <qvbox.h> +#include <kpopupmenu.h> +#include <klistview.h> + +class packagePropertiesWidget; +class packageInfo; +class QListViewItem; +class QTextEdit; +class packageDisplayWidget; +class kpFileList : public KListView +{ + Q_OBJECT + +public: + + kpFileList(QWidget* parent, packageDisplayWidget* parent2); + + QString item2Path(QListViewItem *it); + + +public slots: + + void openContext(KListView *, QListViewItem *, const QPoint &); + + virtual void clear(); + + QListViewItem* insert(const QString &cur, const QPixmap &pixmap); + + + private: + KPopupMenu *FileListMenu; + packageDisplayWidget* pkDisplay; + + int openwith; + +}; + +class packageDisplayWidget : public QTabWidget +{ + Q_OBJECT + + friend class kpFileList; + ///////////// METHODS ------------------------------------------------------ +public: + packageDisplayWidget(QWidget *parent=0); + // Constructor + + ~packageDisplayWidget(); + // Destructor + + void noPackage(); + // clear package display in right panel + + void changePackage(packageInfo *p); + // Set currently selected package + +private: + void setupWidgets(); + // This sets up the sub-widgets + + void updateFileList(); + // This updates the file list to match that found with the currently + // selected package + + void updateChangeLog(); + // This updates the change log to match that found with the currently + // selected package + + void tabSet(QWidget *); + // Set display for corresponding tab + + ///////////// SLOTS -------------------------------------------------------- +public slots: + + void tabSelected(QWidget *); + + void openBinding(QListViewItem *); + + void openBindingWith(QListViewItem *); + +void __openBindingWith(); + + + ///////////// SIGNALS ------------------------------------------------------ + + ///////////// DATA --------------------------------------------------------- +public: + packageInfo *package; + // the currently selected package + +private: + + QTabWidget *tabbar; + // The tab bar + + QVBox *proptab, *fltab, *cltab; + + QWidget *curTab; + // current active tab + + kpFileList *fileList; + // This holds the file list (and is used as a page on the tab dialog) + + QTextEdit *changeLog; + // Holds changelog + + QPixmap tick, cross, question, *blank; + // The pixmaps for the filelist + + packagePropertiesWidget *packageProperties; + // This displays the package properties (and is used as a page on the + // tab dialog) + + bool initList; + // True is file list has been initialised +}; +#endif 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; + } +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + diff --git a/kpackage/packageInfo.h b/kpackage/packageInfo.h new file mode 100644 index 0000000..be0dbb3 --- /dev/null +++ b/kpackage/packageInfo.h @@ -0,0 +1,165 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +// Author: Damyan Pepper +// +// This file contains the definition of the class packageInfo +// +// packageInfo is used to store information regarding an package. +// This information is normally gained by querying the database or +// by querying an package. +// +// The package information consists of a set of properties. These +// properties are stored in a dictionary that is passed to the +// constructor. The properties can be accessed using the function +// `getProperty'. +// +// In addition, packageInfo objects can place themselves inside +// a tree list with the function `place'. Doing this creates +// a tree list item object that can be accessed with the function +// `item'. +*/ + +/* +** 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 +*/ + +#ifndef PACKAGEINFO_H +#define PACKAGEINFO_H +#include "../config.h" + +#include <qmap.h> +#include <qdict.h> +#include <qstring.h> +#include <qpixmap.h> +#include <qptrlist.h> +#include <qlistview.h> + +class pkgInterface; +class KpTreeListItem; +class KpTreeList; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +class packageInfo +{ +public: + packageInfo(QMap<QString, QString> _info, pkgInterface *type); + // Constructor: create a packageInfo object using the property + // dictionary from _info + + packageInfo(QMap<QString, QString> _info, const QString &_filename); + // Constructor: same as above, but also sets filename to _filename. + // This is used in the case that the package info was obtained from + // an uninstalled package. + + ~packageInfo(); + // Distructor + + /** + * Look ups the property `property' from the dictionary + */ + QString getProperty(const QString &property); + + /** + * Checks whether the property `property' is defined in the dictionary + */ + bool hasProperty(const QString &property); + + void fixup(); + // Initialize fields if missing + + KpTreeListItem *place(KpTreeList *tree, bool InsertI=FALSE); + // places the object in the treelist `tree' and initialises + // `item'. If necessary, new groups will be added to `tree'. + + KpTreeListItem *getItem(); + // returns the treelist item object for this package or + // NULL if the object hasn't been placed + + void setFilename(const QString &f); + + QString getUrl(); + // return URL of package file + + bool isFileLocal(); + // True if package file is local or cached file + + bool isInstallable(); + // True if package can be installed + + bool isFetchable(); + // True if package needs to be fetched + + QString getFilename(); + + QString fetchFilename(); + // gets the filename, fetching package if necessary + + int newer(packageInfo *p); + // if package p is newer + + void pkgFileIns(const QString &fileName); + // Insert a package from a file into package tree + + bool pkgInsert(QPtrList<packageInfo> *pki, const QString &exp, bool installed, + bool infoPackage = FALSE); + // insert packgeInfo either installed or not installed + + QMap<QString, QString> info; + // This stores the property dictionary of the package + + KpTreeListItem *item; + // This stores the tree list item for this package (or NULL if + // the package hasn't been placed in a tree list) + + pkgInterface *interface; + // interface points to the class of the package (deb, rpm etc) + + bool smerge( const QString &exp); + // merge with already existing NOLIST package info + + bool display(int treeType); + // if this package is to be should in the tree list + + enum {UNSET, AVAILABLE, INSTALLED, BAD_INSTALL, UPDATED, + NEW, NOLIST, HIDDEN}; + int packageState; + + bool updated; + +private: + int getDigElement(const QString &s, int *pos); + QString getNdigElement(const QString &s, int *pos); + // break up version string + + int pnewer(const QString &s, const QString &sp); + // compare parts of a version string + + QString url; + // This stores the filename of the package the info was obtained from. + // If it is empty then the info was obtained from an installed package. + +}; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +#endif + diff --git a/kpackage/packageProperties.cpp b/kpackage/packageProperties.cpp new file mode 100644 index 0000000..b05a00c --- /dev/null +++ b/kpackage/packageProperties.cpp @@ -0,0 +1,278 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + +#include "../config.h" +#include <stdio.h> +#include <kdebug.h> + +#include <kapplication.h> + +#include "kpackage.h" +#include "packageProperties.h" +#include "pkgInterface.h" +#include "managementWidget.h" + +packagePropertiesWidget::packagePropertiesWidget + (QWidget *parent) + : KTextBrowser(parent) +{ + QDict<QString> trl(53); + QStringList pList(); + QStringList cList(); + + // hide(); + package=NULL; + QColorGroup cg = colorGroup(); + setBackgroundColor(cg.base()); + initTranslate(); +} + +packagePropertiesWidget::~packagePropertiesWidget() +{ +} + +void packagePropertiesWidget::iList(const QString &txt, const QString &itxt) +{ + trl.insert(txt, new QString(itxt)); + pList.append(txt); +} + + +void packagePropertiesWidget::initTranslate() +{ + + iList("name", i18n("name")); + iList("summary", i18n("summary")); + iList("version", i18n("version")); + iList("old-version", i18n("old-version")); + iList("status", i18n("status")); + iList("group", i18n("group")); + iList("size", i18n("size")); + iList("file-size", i18n("file-size")); + iList("description", i18n("description")); + iList("url", i18n("url")); + iList("architecture", i18n("architecture")); + + iList("unsatisfied dependencies", i18n("unsatisfied dependencies")); + iList("pre-depends", i18n("pre-depends")); + iList("dependencies", i18n("dependencies")); + iList("depends", i18n("depends")); + iList("conflicts", i18n("conflicts")); + iList("provides", i18n("provides")); + iList("recommends", i18n("recommends")); + iList("replaces", i18n("replaces")); + iList("suggests", i18n("suggests")); + iList("priority", i18n("priority")); + + iList("essential", i18n("essential")); + iList("install time", i18n("install time")); + iList("config-version", i18n("config-version")); + iList("distribution", i18n("distribution")); + iList("vendor", i18n("vendor")); + iList("maintainer", i18n("maintainer")); + iList("packager", i18n("packager")); + iList("source", i18n("source")); + iList("build-time", i18n("build-time")); + iList("build-host", i18n("build-host")); + iList("base", i18n("base")); + iList("filename", i18n("filename")); + iList("serial", i18n("serial")); + + iList("also in", i18n("also in")); + iList("run depends", i18n("run depends")); + iList("build depends", i18n("build depends")); + iList("available as", i18n("available as")); +} + +void packagePropertiesWidget::changePackage(packageInfo *p) +{ + + package = p; + cList.clear(); + if (p) { + // append properties in ordered list to current list + for ( QStringList::Iterator s = pList.begin(); + s != pList.end(); + ++s) { + + if (!p->getProperty(*s).isEmpty()) { + cList.append(*s); + } + } + // append other properties to end + QMap<QString, QString>::Iterator it; + for ( it = p->info.begin(); it != p->info.end(); ++it ) { + if (!trl.find(it.key())) { + if (!it.data().isEmpty()) + cList.append(it.key()); + } + } + + stmp = ""; + stmp += "<html><head></head><body>"; + stmp += "<h1 style='font-family: serif;'>"; + stmp += p->getProperty("name"); + stmp += "</h1><hr/>"; + stmp += "<table style='width: 100%; border: none; border-spacing: 4px;>"; + for ( QStringList::Iterator s = cList.begin(); + s != cList.end(); + ++s) { + QString *pr = trl[*s]; + QString propName; + if(pr) { + propName = *pr; + } else { + propName = *s; + } + stmp += "<tr>"; + stmp += "<td style='vertical-align: top; font-weight: bold'>"; + stmp += propName; + stmp += "</td><td>"; + QString f = p->getProperty(*s); + if (*s == "maintainer" || *s == "packager") { + f.replace(QRegExp("<"),"<"); + f.replace(QRegExp(">"),">"); + } + if (*s == "filename") { + int p = f.findRev("/"); + if (p >= 0) { + f.insert(p+1,"\n"); + }; + stmp += f; + } else if (*s == "depends" || *s == "conflicts" || + *s == "replaces" || + *s == "suggests" || *s == "recommends" || + *s == "pre-depends" || *s == "unsatisfied dependencies") { + depends(f); + } else if (*s == "url") { + if (f.right(1) == " ") f.remove(f.length()-1, 1); + if (f.startsWith("http:") || f.startsWith("ftp:")) /*if (!(f == "(none)")) */ + stmp += "<a href=\"" + f +"\">" + f + "</a>"; + else stmp += i18n("none"); + } else { + stmp += f; + } + stmp += "</td>"; + stmp += "</tr>"; + } + stmp += "</table>"; + stmp += "</body></html>"; + setText(stmp); + } + update(); +} + +void packagePropertiesWidget::depends(const QString &f) { + // printf("d=%s\n",f.data()); + + int i = 0; + QStringList list = QStringList::split(',',f); + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + if (i++ > 0) + stmp += ","; + dor((*it)); + } +} + +void packagePropertiesWidget::dor(const QString &f) { + // printf("o=%s\n",f.data()); + + int i = 0; + QStringList list = QStringList::split('|',f); + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + if (i++ > 0) + stmp += "|"; + delement((*it)); + } +} + +void packagePropertiesWidget::delement(const QString &f) { + int n = f.find("("); + if (n < 0) { + n = f.length(); + } + + QString u = f.left(n); + QString uf = package->interface->provMap(u.stripWhiteSpace()); + + QString us = uf + package->interface->typeID; + + bool inst = false, uninst = false; + if (kpackage->management->dirInstPackages->find(us)) { + inst = true; + } else if (kpackage->management->dirUninstPackages->find(us)) { + uninst = true; + } + + if (uninst) + stmp += "<i>"; + if (inst||uninst) { + stmp += "<a href=\""; + stmp += uf; + stmp += "\">"; + stmp += u; + stmp += "</a>"; + } else { + stmp += u; + } + if (uninst) + stmp += "</i>"; + if (n < (signed)f.length()) + stmp += f.mid(n).replace(QRegExp("<"),"<"); +} + +void packagePropertiesWidget::setSource(const QString &name) { + QString s = name; + + if (s.startsWith("http:") || s.startsWith("ftp:")) + { + KApplication::kApplication()->invokeBrowser( s ); + return; + } + + if (s.startsWith("file:")) { + s = s.mid(5); + } + else if (s.at(1) == '/') { + s = s.mid(1); + } + + QString ind = s + package->interface->typeID; + packageInfo *p = kpackage->management->dirInstPackages->find(ind); + if (p) { + kpackage->management->treeList->changePack(p->getItem(), package->getItem() != 0); + } else { + kdDebug() << "nfound=" << ind << endl; + p = kpackage->management->dirUninstPackages->find(ind); + if (p) { + kpackage->management->treeList->changePack(p->getItem(), package->getItem() != 0); + } else { + kdDebug() << "Nfound=" << ind << endl; + } + } +} +#include "packageProperties.moc" diff --git a/kpackage/packageProperties.h b/kpackage/packageProperties.h new file mode 100644 index 0000000..0b7e035 --- /dev/null +++ b/kpackage/packageProperties.h @@ -0,0 +1,103 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +// Author: Damyan Pepper +// +// This widget is used to provide a list of all the properties that are +// found in the package's property dictionary +*/ + +/* +** 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 +*/ + + +#ifndef PACKAGEPROPERTIES_H +#define PACKAGEPROPERTIES_H +#include "../config.h" + +// Standard Headers + +// Qt Headers +#include <qpainter.h> +#include <qstringlist.h> +#include <qregexp.h> + +// KDE Headers +#include <klocale.h> +#include <ktextbrowser.h> + +// kpackage Headers +#include "packageInfo.h" + +class packageInfo; + +class packagePropertiesWidget : public KTextBrowser +{ + Q_OBJECT + ///////////// METHODS ------------------------------------------------------ +public: + + packagePropertiesWidget(QWidget *parent=0); + // constructor + + ~packagePropertiesWidget(); + // destructor + + void changePackage(packageInfo *p); + + void setSource( const QString & name ); + // url selected + +protected: + + + + ///////////// DATA --------------------------------------------------------- +private: + packageInfo *package; + + void initTranslate(); + void iList(const QString &txt, const QString &itxt); + + QDict<QString> trl ; + // allow for translation of labels + + QStringList pList; + // list specifying order of property distplay + + QStringList cList; + // list giving order of currently displayed properties + + QString stmp; + // text accumulation buffer + + void depends(const QString &f); + // translate depends string + + void dor(const QString &f); + // translate depends string + + void delement(const QString &f); + // translate depends element +}; + + +#endif diff --git a/kpackage/pics/Makefile.am b/kpackage/pics/Makefile.am new file mode 100644 index 0000000..4e55083 --- /dev/null +++ b/kpackage/pics/Makefile.am @@ -0,0 +1,6 @@ +pics_DATA = cross.png dbad.png deb.png dnew.png dupdated.png \ + ptick.png question.png rnew.png rpm.png rupdated.png \ + kiss.png knew.png kupdated.png slack.png snew.png \ + supdated.png bsd.png bnew.png bupdated.png tick.png noball.png + +picsdir = $(kde_datadir)/kpackage/pics diff --git a/kpackage/pics/bnew.png b/kpackage/pics/bnew.png Binary files differnew file mode 100644 index 0000000..0a70e91 --- /dev/null +++ b/kpackage/pics/bnew.png diff --git a/kpackage/pics/bsd.png b/kpackage/pics/bsd.png Binary files differnew file mode 100644 index 0000000..92b0b88 --- /dev/null +++ b/kpackage/pics/bsd.png diff --git a/kpackage/pics/bupdated.png b/kpackage/pics/bupdated.png Binary files differnew file mode 100644 index 0000000..2d733d6 --- /dev/null +++ b/kpackage/pics/bupdated.png diff --git a/kpackage/pics/cross.png b/kpackage/pics/cross.png Binary files differnew file mode 100644 index 0000000..748afec --- /dev/null +++ b/kpackage/pics/cross.png diff --git a/kpackage/pics/dbad.png b/kpackage/pics/dbad.png Binary files differnew file mode 100644 index 0000000..89b70c4 --- /dev/null +++ b/kpackage/pics/dbad.png diff --git a/kpackage/pics/deb.png b/kpackage/pics/deb.png Binary files differnew file mode 100644 index 0000000..7c5ac7f --- /dev/null +++ b/kpackage/pics/deb.png diff --git a/kpackage/pics/dnew.png b/kpackage/pics/dnew.png Binary files differnew file mode 100644 index 0000000..85cb602 --- /dev/null +++ b/kpackage/pics/dnew.png diff --git a/kpackage/pics/dupdated.png b/kpackage/pics/dupdated.png Binary files differnew file mode 100644 index 0000000..f807221 --- /dev/null +++ b/kpackage/pics/dupdated.png diff --git a/kpackage/pics/kiss.png b/kpackage/pics/kiss.png Binary files differnew file mode 100644 index 0000000..40956ae --- /dev/null +++ b/kpackage/pics/kiss.png diff --git a/kpackage/pics/knew.png b/kpackage/pics/knew.png Binary files differnew file mode 100644 index 0000000..1b49daa --- /dev/null +++ b/kpackage/pics/knew.png diff --git a/kpackage/pics/kupdated.png b/kpackage/pics/kupdated.png Binary files differnew file mode 100644 index 0000000..bc1b90b --- /dev/null +++ b/kpackage/pics/kupdated.png diff --git a/kpackage/pics/noball.png b/kpackage/pics/noball.png Binary files differnew file mode 100644 index 0000000..0e9fbe4 --- /dev/null +++ b/kpackage/pics/noball.png diff --git a/kpackage/pics/ptick.png b/kpackage/pics/ptick.png Binary files differnew file mode 100644 index 0000000..7f8c315 --- /dev/null +++ b/kpackage/pics/ptick.png diff --git a/kpackage/pics/question.png b/kpackage/pics/question.png Binary files differnew file mode 100644 index 0000000..e6c809d --- /dev/null +++ b/kpackage/pics/question.png diff --git a/kpackage/pics/rnew.png b/kpackage/pics/rnew.png Binary files differnew file mode 100644 index 0000000..2b44ca3 --- /dev/null +++ b/kpackage/pics/rnew.png diff --git a/kpackage/pics/rpm.png b/kpackage/pics/rpm.png Binary files differnew file mode 100644 index 0000000..8437a8f --- /dev/null +++ b/kpackage/pics/rpm.png diff --git a/kpackage/pics/rupdated.png b/kpackage/pics/rupdated.png Binary files differnew file mode 100644 index 0000000..b570636 --- /dev/null +++ b/kpackage/pics/rupdated.png diff --git a/kpackage/pics/slack.png b/kpackage/pics/slack.png Binary files differnew file mode 100644 index 0000000..f46fb11 --- /dev/null +++ b/kpackage/pics/slack.png diff --git a/kpackage/pics/snew.png b/kpackage/pics/snew.png Binary files differnew file mode 100644 index 0000000..0043371 --- /dev/null +++ b/kpackage/pics/snew.png diff --git a/kpackage/pics/supdated.png b/kpackage/pics/supdated.png Binary files differnew file mode 100644 index 0000000..c608b55 --- /dev/null +++ b/kpackage/pics/supdated.png diff --git a/kpackage/pics/tick.png b/kpackage/pics/tick.png Binary files differnew file mode 100644 index 0000000..7f8c315 --- /dev/null +++ b/kpackage/pics/tick.png diff --git a/kpackage/pkgInterface.cpp b/kpackage/pkgInterface.cpp new file mode 100644 index 0000000..eeb6f74 --- /dev/null +++ b/kpackage/pkgInterface.cpp @@ -0,0 +1,435 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#include <klocale.h> +#include <kglobal.h> +#include <kdebug.h> +#include <kiconloader.h> + +#include "kpackage.h" +#include "pkgInterface.h" +#include "options.h" +#include "cache.h" +#include "updateLoc.h" +#include "kio.h" + +extern Opts *opts; +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +param::param(const QString &nameP, bool initP, bool invertP, const QString &flagP) +{ + name = nameP; + init = initP; + invert = invertP; + flag = flagP; + flagA = ""; +} + +param::param(const QString &nameP, bool initP, bool invertP, const QString &flagP, const QString &flagAP ) +{ + name = nameP; + init = initP; + invert = invertP; + flag = flagP; + flagA = flagAP; + +} + +param::~param() +{ +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +pkgInterface::pkgInterface( ) : QObject(), new_pict(), updated_pict() +{ + packageLoc = 0; + + DELMSG = i18n("'Delete this window to continue'"); + + folder = SmallIcon("folder"); + markInst = UserIcon("tick"); + markUnInst = UserIcon("noball"); + bad_pict = UserIcon("dbad"); + + hasRemote = FALSE; + defaultHandle = 1; + noFetch = FALSE; + hasSearchAll = FALSE; +} + +////////////////////////////////////////////////////////////////////////////// +pkgInterface::~pkgInterface() +{ + // if (locatedialog) + // delete locatedialog; + // if (packageLoc) + // delete packageLoc; +} + +////////////////////////////////////////////////////////////////////////////// +void pkgInterface::makeMenu(KActionCollection *) +{ +} + +void pkgInterface::setMenu(KActionCollection*, bool ) +{ +} + +////////////////////////////////////////////////////////////////////////////// +QStringList pkgInterface::depends(const QString &, int ) {return 0;} + +QString pkgInterface::doUninstall(int, const QString &, bool &) {return 0;} +QString pkgInterface::doInstall(int, const QString &, bool &) {return 0;} + +//////////////////////////////////////////////////////////////////////////// + +bool pkgInterface::ifExe(QString exe) { + if (!KGlobal::dirs()->findExe( exe ).isNull()) { + return TRUE; + } else { + kdDebug() << "Program not found: " << exe << "\n"; + errExe = exe; + return FALSE; + } +} + + +void pkgInterface::listPackages(QPtrList<packageInfo> *pki) +{ + listInstalledPackages(pki); + if (packageLoc) { + for (cacheObj *cp = packageLoc->first(); cp != 0; cp = packageLoc->next()) { + QString s = getDir(cp); + if (!s.isEmpty()) + listDir(pki, s, cp->location, cp->subdirs); + } + } +} + +void pkgInterface::smerge(packageInfo *) +{ } + +void pkgInterface::listDir(QPtrList<packageInfo> *pki, const QString &fname, const QString &dir, bool subdirs) +{ + // fname - path to directory or cached remote infromation file + // dir - url of directory + + QString name, size, rfile; + packageInfo *p; + + QString sline( queryMsg + fname ); + kpackage->setStatus(sline); + + kdDebug() << "listDir fn=" << fname << " dir=" << dir << endl; + + QDir d(fname,packagePattern); + + if (subdirs) + d.setMatchAllDirs( TRUE ); // list contains subdirs + else + d.setMatchAllDirs( FALSE ); // list contains no subdirs + + if (d.exists()) { + if ( d.isReadable() ) { + QString pn; + const QFileInfoList *list = d.entryInfoList(); + QFileInfoListIterator it( *list ); // create list iterator + QFileInfo *fi; // pointer for traversing + + while ( (fi=it.current()) ) { // for each entry... + if ( fi->isDir() ) { + // entry is a subdir + if ( fi->fileName() != QString::fromLatin1(".") && + fi->fileName() != QString::fromLatin1("..") ) + { + // not current dir and not parent dir + // -> recursive call: + listDir( pki, dir + "/" + fi->fileName(), dir + "/" + fi->fileName(), subdirs ); + } else { + // current dir or parent dir + // -> notihng to do + ; + } + } else { + // entry is a file + if (opts->PkgRead) { + rfile = fname + "/"; + rfile += fi->fileName(); + p = getPackageInfo('u',rfile, 0); + if (p) { + p->info.insert("filename", fi->fileName()); + p->info.insert("base", dir); + } + } else { + p = collectDir(fi->fileName(),pn.setNum(fi->size()),dir); + } + if (p) { + smerge(p); + if (!p->pkgInsert(pki, typeID, FALSE)) + delete p; + } + } + ++it; // goto next list element + } + } else { + // directory is not readable + kdDebug() << QString("WARNING: directory '%1' not readable (will be ignored) !\n").arg(d.absPath() ) << endl; + } + } else { + QFile f(fname); + if ( f.open(IO_ReadOnly) ) { + QTextStream t( &f ); + QString name; + while ( !t.eof() ) { + name = t.readLine(); + if (!t.eof() ) { + size = t.readLine(); + } else + size = ""; + packageInfo *p = collectDir(name,size,dir); + if (p) { + smerge(p); + if (!p->pkgInsert(pki, typeID, FALSE)) + delete p; + } + } + f.close(); + } + } + } + +packageInfo *pkgInterface::collectDir(const QString &name, const QString &size, const QString &dir) +{ + kdDebug() << "collectDir " << name << " " << size << " " << dir << endl; + QString n,v; + + if (parseName(name, &n, &v)) { + QMap<QString, QString> a; + + a.insert("group", "NEW"); + a.insert("name", n); + a.insert("version", v); + a.insert("file-size", size); + a.insert("filename", name); + a.insert("base", dir); + + packageInfo *i = new packageInfo(a,this); + i->packageState = packageInfo::AVAILABLE; + // i->packageState = packageInfo::NEW; + return i; + } + return 0; +} + +QString pkgInterface::getPackList(cacheObj *cp) +{ + QString tmpf; + int res; + QString url = cp->location; + kdDebug() << "pkgInterface::getPackList " << url << " " << cp->cacheFile << "\n"; + if ((res = cacheObj::newDCache(url, cp->cacheFile, tmpf))) { + if (res < 0) + return 0; + + unlink(QFile::encodeName(tmpf)); + if (kpkg) + kpackage->setStatus(i18n("Starting Kio")); + + Kio kio; + if (kio.download(url, tmpf)) { + if (kpkg) + kpackage->setStatus(i18n("Kio finished")); + QFileInfo f(tmpf); + if (!(f.exists() && f.size() > 0)) { + unlink(QFile::encodeName(tmpf)); + return ""; + } else { + return tmpf; + } + } else { + if (kpkg) + kpackage->setStatus(i18n("Kio failed")); + return ""; + } + } else { + return tmpf; + } +} + +QString pkgInterface::getDir(cacheObj *cp) { + int res; + QString tmpDir; + QString url = cp->location; + + if ((res = cacheObj::newDCache(url, cp->cacheFile, tmpDir))) { + if (res < 0) + return QString::null; + + Kiod kiod; + if (kiod.listDir(url,tmpDir, cp->subdirs)) { + QFileInfo fi (tmpDir); + CacheList cl (fi.dirPath()); + cl.append (fi.fileName()); + cl.write(); + return tmpDir; + } else { + KpMsgE(i18n("Cannot read folder %1").arg(url),FALSE); + unlink(tmpDir.ascii()); + return QString::null; + } + } else { + return tmpDir; + } +} + + +////////////////////////////////////////////////////////////////////////////// + +QString pkgInterface::provMap(const QString &p) +{ + // kdDebug() << "provMap=>" << p << endl; + return p; +} + +////////////////////////////////////////////////////////////////////////////// +QStringList pkgInterface::verify(packageInfo *, const QStringList &files) +{ + int p = 0; + uint c = 0; + QStringList errorlist; + QDir d; + + if (hostName.isEmpty()) { + + uint step = (files.count() / 100) + 1; + + kpackage->setStatus(i18n("Verifying")); + kpackage->setPercent(0); + + for( QStringList::ConstIterator it = files.begin(); + it != files.end(); + it++) + { + // Update the status progress + c++; + if(c > step) { + c=0; p++; + kpackage->setPercent(p); + } + + if (!d.exists(*it)) { + errorlist.append(*it); + } + } + + kpackage->setPercent(100); + } + return errorlist; +} + +////////////////////////////////////////////////////////////////////////////// +QString pkgInterface::uninstall(int uninstallFlags, packageInfo *p, bool &test) +{ + QString packs( p->getProperty("name")); + + return doUninstall(uninstallFlags, packs, test); +} + +////////////////////////////////////////////////////////////////////////////// +QString pkgInterface::uninstall(int uninstallFlags, QPtrList<packageInfo> *p, bool &test) +{ + QString packs; + packageInfo *i; + + for (i = p->first(); i!= 0; i = p->next()) { + packs += i->getProperty("name"); + packs += " "; + } + return doUninstall( uninstallFlags, packs, test); +} +////////////////////////////////////////////////////////////////////////////// + +QString pkgInterface::install(int installFlags, packageInfo *p, bool &test) +{ + QString fname = p->fetchFilename(); + + return doInstall(installFlags, fname, test); +} + +////////////////////////////////////////////////////////////////////////////// +QString pkgInterface::install(int installFlags, QPtrList<packageInfo> *p, bool &test) +{ + QString packs = ""; + packageInfo *i; + + for (i = p->first(); i!= 0; i = p->next()) { + QString fname = i->fetchFilename(); + if (!fname.isEmpty()) { + packs += fname; + packs += " "; + } + } + return doInstall(installFlags, packs, test); +} + +////////////////////////////////////////////////////////////////////////////// +QStringList pkgInterface::listInstalls(const QStringList &packs, bool , bool &cancel) +{ + cancel = FALSE; + return packs; +} + +////////////////////////////////////////////////////////////////////////////// + +QString pkgInterface::setOptions(int flags, QPtrList<param> ¶ms) +{ + int i; + QString s; + + param *p; + i = 0; + for ( p=params.first(); p != 0; p=params.next(), i++ ) { + if ((flags>>i & 1) ^ p->invert) { + s += p->flag + " "; + } else { + if (!p->flagA.isEmpty()) + s += p->flagA + " "; + } + } + return s; +} + + QStringList pkgInterface::readApt() +{ + return 0; +} + + void pkgInterface::writeApt(const QStringList &) +{ +} + +#include "pkgInterface.moc" diff --git a/kpackage/pkgInterface.h b/kpackage/pkgInterface.h new file mode 100644 index 0000000..3094af8 --- /dev/null +++ b/kpackage/pkgInterface.h @@ -0,0 +1,220 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + +#ifndef PKG_IFACE_H +#define PKG_IFACE_H + +#include "../config.h" +#include <qptrlist.h> +#include <qstring.h> +#include <qstringlist.h> + +#include <kglobal.h> +#include <kstandarddirs.h> + +#include "packageInfo.h" +#include "managementWidget.h" + +class packageInfo; +class pkgOptions; +class Locations; +class LcacheObj; +class cacheObj; +class KAccel; +class KActionCollection; +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +// flags to install and uninstall +class param +{ +public: + param(const QString &nameP, bool initP, bool invertP, const QString &flagP); + param(const QString &nameP, bool initP, bool invertP, const QString &flagP, const QString &flagAP); + ~param(); + + QString name; // Name of flag + bool init; // Initial value + bool invert; // Whether it needs to be inverted + QString flag; // text flag on command + QString flagA; // text flag on command +}; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +class pkgInterface: public QObject +{ + Q_OBJECT + +public: + pkgInterface(); + virtual ~pkgInterface(); + + virtual bool isType(char *buf, const QString &fname) = 0; + // looks at start of file to check that package is correct type + + virtual void makeMenu(KActionCollection* act); + virtual void setMenu(KActionCollection* act, bool enable); + + bool ifExe(QString exe); + // Check if this executable exists + + virtual packageInfo *getPackageInfo(char mode, const QString &name, + const QString &version) = 0; + // get info on installed or uninstalled package. version is only set if + // mode is 'i' (ie, if the package is already installed). + + virtual QStringList getFileList(packageInfo *p) = 0; + // get list of files in the package + + virtual QStringList depends(const QString &name, int src); + // check dependencies for package + + virtual QStringList verify(packageInfo *p, const QStringList &files); + // check the installed files in a package + + virtual QStringList FindFile(const QString &name, bool seachAll=false) = 0; + // search for packages containg a file + + virtual QStringList getChangeLog(packageInfo *p) = 0; + // Get change log + + virtual bool filesTab(packageInfo *p) = 0; + // If files tab is to be enabled + + virtual bool changeTab(packageInfo *p) = 0; + // If change log tab is to be enabled + + virtual bool parseName(const QString &name, QString *n, QString *v) = 0; + // breakup file name into package name and version + + virtual void listPackages(QPtrList<packageInfo> *pki); + // scan various locations for list of packages + + virtual void listInstalledPackages(QPtrList<packageInfo> *pki) = 0; + // produce list of currently installed packages + + virtual QStringList listInstalls(const QStringList &packs, bool install, bool &cancel); + // Convert list of packages requested to install to list of all packages to install + + virtual void smerge(packageInfo *p); + // merge in package info entry + + QString getDir(cacheObj *cp); + // list directory local or remote + + void listDir(QPtrList<packageInfo> *pki, const QString &fname, const QString &dir, bool subdirs = FALSE); + // list the packages in a directory + + packageInfo *collectDir(const QString &name, const QString &size, const QString &dir); + // build packageInfo object from directory entry + + QString getPackList(cacheObj *cp); + // get packages information file + + virtual QString provMap(const QString &p); + // convert from package depends to package + + QString setOptions(int flags, QPtrList<param> ¶ms); + // convert un/install flags to text + + virtual QString doUninstall(int uninstallFlags, const QString &packs, bool &test); + virtual QString doInstall(int installFlags, const QString &packs, bool &test); + virtual QString uninstall(int uninstallFlags, QPtrList<packageInfo> *p, + bool &test); + virtual QString uninstall(int uninstallFlags, packageInfo *p, + bool &test); + virtual QString install(int installFlags, QPtrList<packageInfo> *p, + bool &test); + virtual QString install(int installFlags, packageInfo *p, + bool &test); + + virtual QStringList readApt(); + virtual void writeApt(const QStringList &list); + + ///////////// DATA /////////////////////// + pkgOptions *uninstallation, *installation; + + QString icon; + // name icon file + QString head; + // capitalized name of package type + QString name; + // More descriptive name + QPixmap pict, bad_pict, new_pict, updated_pict; + // icons for package states + QPixmap folder; + // icon for package group + QPixmap markInst; + QPixmap markUnInst; + // icon indicating mark for install/uninstall + + Locations *locatedialog; + // dialog for setting the locations of uninstalled packages + LcacheObj *packageLoc; + // List of locations of uninstalled pacckages + + bool dirOK; + // variables related to reading packages from directories + + QString packagePattern; + QString queryMsg; + QString typeID; + // Parameters for reading packages from directories + + QPtrList<param> paramsInst; + QPtrList<param> paramsUninst; + + bool noFetch; + // kpackage doesn't fetch this type of package itself + + bool defaultHandle; + // This package type defaults to on + + QString errExe; + // The name of an executable that wasn't found + + QString procMsg; + // for running processes + + QString DELMSG; + + bool hasRemote; + // can access on remote host + + bool hasSearchAll; + // can search uninstalled packages for files + + bool hasProgram; + // the program needed to handle this package type is available + +public slots: + virtual void setLocation() = 0; + virtual void setAvail(LcacheObj *) = 0; +}; + +#endif diff --git a/kpackage/pkgOptions.cpp b/kpackage/pkgOptions.cpp new file mode 100644 index 0000000..19a3c5e --- /dev/null +++ b/kpackage/pkgOptions.cpp @@ -0,0 +1,372 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + +#include "../config.h" +// qt headers +#include <qlabel.h> + +#include <klocale.h> +#include <kglobal.h> +#include <kglobalsettings.h> +#include <klistview.h> +#include <kseparator.h> +#include <kdebug.h> +#include <kpushbutton.h> +#include <kstdguiitem.h> + +#include "pkgOptions.h" +#include "managementWidget.h" +#include "debInterface.h" +#include "kpackage.h" +#include "options.h" + +/////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// + +pkgOptions::pkgOptions(pkgInterface *pki, QWidget *parent, const QString &caption) + : KDialog(parent,0,TRUE) +{ + // setFrameStyle(QFrame::Raised | QFrame::Panel); + + pkgInt = pki; + + hide(); + + setCaption(caption); +} + +// Destructor +pkgOptions::~pkgOptions() +{ + // int i; + // for (i = 0; i < bnumber; i++) { + // delete(Boxs[i]); + // } +} + +// Set up the sub-widgets +void pkgOptions::setupWidgets(QPtrList<param> &pars) +{ + int i; + + // Create widgets + title = new QLabel("", this); + QFont f( KGlobalSettings::generalFont()); + f.setBold(true); + f.setPointSize(f.pointSize()+6); + title->setFont(f); + // title->setAutoResize(TRUE); + // title->update(); + + installButton = new QPushButton(insType,this); + cancelButton = new KPushButton(KStdGuiItem::cancel(),this); + // count number of buttons + bnumber = pars.count(); + + Boxs = new QCheckBox *[bnumber]; + param *p; + i = 0; + for ( p=pars.first(); p != 0; p=pars.next(), i++ ) { + Boxs[i] = new QCheckBox(p->name, this); + Boxs[i]->setChecked(p->init); + } + + Keep = new QCheckBox(i18n("Keep this window"), this); + + // Connections + connect(installButton,SIGNAL(clicked()),SLOT(pkginstallButtonClicked())); + connect(cancelButton,SIGNAL(clicked()),SLOT(cancelButtonClicked())); + connect(Keep, SIGNAL(toggled(bool)), SLOT(keepToggle(bool))); + + // Do the layout + vlayout = new QBoxLayout(this, QBoxLayout::TopToBottom, marginHint(), spacingHint()); + vlayout->addWidget(title,0); + + { + hlayout = new QBoxLayout(vlayout,QBoxLayout::LeftToRight, spacingHint()); + + { + layout = new QBoxLayout(hlayout,QBoxLayout::TopToBottom, spacingHint()); + + packages = new KListView(this); + layout->addWidget(packages,20); + packages->addColumn(i18n("PACKAGES"),200); + + connect(packages, SIGNAL(selectionChanged ( QListViewItem * )), + this, SLOT(slotSearch( QListViewItem * ))); + + layout->addStretch(1); + for (i = 0; i < bnumber; i++) { + layout->addWidget(Boxs[i],1); + } + layout->addWidget(new KSeparator(KSeparator::HLine, this), 2); + + QBoxLayout *slayout = new QBoxLayout(layout, QBoxLayout::LeftToRight); + slayout->addStretch(1); + slayout->addWidget(Keep, 1); + slayout->addStretch(1); + + layout->addWidget(new KSeparator(KSeparator::HLine, this), 2); + + QBoxLayout *buttons = new QBoxLayout(QBoxLayout::LeftToRight); + layout->addLayout(buttons); + + buttons->addWidget(installButton,2); + buttons->addStretch(1); + buttons->addWidget(cancelButton,2); + } + { + term = new kpTerm(kpty,this); + hlayout->addWidget(term, 1000); + } + } + resize(800, 400); +} + +void pkgOptions::setup(packageInfo *p, const QString &type) { + QPtrList<packageInfo> *pl = new QPtrList<packageInfo>; + pl->append(p); + setup(pl,type); +} + +bool pkgOptions::setup(QPtrList<packageInfo> *pl, const QString &) +{ + QString s; + modified = FALSE; + + packList = pl; + + packages->clear(); + packageInfo *p; + + QStringList plist, rlist, clist; + QDict<QString> dict; + QString mark("x"); + for ( p = pl->first(); p != 0; p = pl->next() ) { + QString file = p->getFilename(); + plist += p->getProperty("name"); + if (file.isEmpty()) { + clist += p->getProperty("name"); + } + dict.insert(p->getProperty("name"), &mark); + } + + packageInfo *pk; + bool cancel; + if (clist.count() > 0) { + rlist = pkgInt->listInstalls(clist, installer, cancel); + if (cancel) { + reject(); + return false; + } + for ( QStringList::Iterator it = rlist.begin(); it != rlist.end(); ++it ) { + if (!dict[*it]) { + plist.append(*it); + QString dirIndex = *it + pkgInt->typeID; + if (installer) { + pk = kpackage->management->dirUninstPackages->find(dirIndex); + } else { + pk = kpackage->management->dirInstPackages->find(dirIndex); + } + if (pk) { + // kdDebug() << "FF=" << dirIndex << "\n"; + pl->append(pk); + } else { + // kdDebug() << "uF=" << dirIndex << "\n"; + } + } + } + } + + s = i18n("%1: 1 %2 Package","%1: %n %2 Packages",plist.count()).arg(insType,pkgInt->name); + title->setText(s); + + for (QStringList::Iterator pit = plist.begin(); pit != plist.end(); ++pit ) { + // kdDebug() << "P=" << *pit << "\n"; + new QListViewItem(packages, *pit); + } + cancelButton->setGuiItem(KStdGuiItem::cancel()); + return TRUE; +} + +// install button has been clicked....so install the package +void pkgOptions::pkginstallButtonClicked() +{ + int i; + QStringList r; + modified = TRUE; + + // Collect data from check boxes + int installFlags = 0; + + for (i = 0; i < bnumber; i++) { + installFlags |= (Boxs[i]->isChecked()) << i; + } + + test = FALSE; + QString s = doPackages(installFlags, packList, test); + // A "0=" or "1=" indicates it was actually (un)installed by the doPackages + // routine instead of just returning a command to execute + + kdDebug() << "S=" << s << "\n"; + if (s == "0=") { + cancelButtonClicked(); + } else if (s.left(2) == "1=") { + term->textIn(s.mid(2), true); + } else { + connect(term,SIGNAL(result(QStringList &, int)), + this,SLOT(slotResult(QStringList &, int))); + + installButton->setEnabled(FALSE); + + if (term->run(s, r)) { + running = TRUE; + cancelButton->setGuiItem(KStdGuiItem::cancel()); + } else { + reset(); + } + } +} + +void pkgOptions::slotSearch(QListViewItem *item) +{ + QString s = item->text(0); + kdDebug() << "searchI=" << s << "h=" << pkgInt->head <<"\n"; + + packageInfo *p; + for ( p = packList->first(); p != 0; p = packList->next() ) { + if (s == p->getProperty("name")) { + kpackage->management->doChangePackage(p); + break; + } + } +} + +void pkgOptions::reset() { + installButton->setEnabled(TRUE); + cancelButton->setGuiItem(KGuiItem(i18n("Done"))); //clear icon + disconnect(term,SIGNAL(result(QStringList &, int)), + this,SLOT(slotResult(QStringList &, int))); + running = FALSE; +} + +void pkgOptions::slotResult(QStringList &, int ret) +{ + reset(); + if (ret == 0 && !test && !keep) { + term->done(); + accept(); + } +} + +void pkgOptions::terminate() { + if (running) { + term->cancel(); + reset(); + } +} + +void pkgOptions::cancelButtonClicked() +{ + terminate(); + term->done(); + + if (!modified || test) + reject(); + else + accept(); +} + +void pkgOptions::closeEvent ( QCloseEvent * e ) { + kdDebug() << "pkgOptions::QCloseEvent\n"; + terminate(); + + QWidget::closeEvent (e); +} + +void pkgOptions::showEvent ( QShowEvent *e ) { + // kdDebug() << "pkgOptions::showEvent\n"; + getKeep(); + + modified = FALSE; + running = FALSE; + + QWidget::showEvent(e); +} + +void pkgOptions::keepToggle(bool kp) +{ + // kdDebug() << "KEEP " << kp << "\n"; + + KConfig *config = kapp->config(); + + config->setGroup("Kpackage"); + config->writeEntry("keepIWin", kp); + + keep = kp; +} + +void pkgOptions::getKeep() +{ + KConfig *config = kapp->config(); + config->setGroup("Kpackage"); + keep = config->readBoolEntry("keepIWin", true); + kdDebug() << "getKEEP " << keep << "\n"; + Keep->setChecked(keep); + +} + +/////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +pkgOptionsI::pkgOptionsI(pkgInterface *pkg, QWidget *parent): + pkgOptions(pkg, parent, i18n("Install")) +{ + insType = i18n("Install"); + installer = TRUE; + setupWidgets(pkg->paramsInst); +} + +QString pkgOptionsI::doPackages(int installFlags, QPtrList<packageInfo> *p, bool &test) +{ + return pkgInt->install(installFlags, p, test); +} + +/////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +pkgOptionsU::pkgOptionsU(pkgInterface *pkg, QWidget *parent): + pkgOptions(pkg, parent, i18n("Uninstall")) +{ + insType = i18n("Uninstall"); + installer = FALSE; + setupWidgets(pkg->paramsUninst); +} + +QString pkgOptionsU::doPackages(int installFlags, QPtrList<packageInfo> *p, bool &test) +{ + return pkgInt->uninstall(installFlags, p, test); +} +#include "pkgOptions.moc" diff --git a/kpackage/pkgOptions.h b/kpackage/pkgOptions.h new file mode 100644 index 0000000..707c340 --- /dev/null +++ b/kpackage/pkgOptions.h @@ -0,0 +1,151 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +// This provides the installation options, plus the install and cancel +// buttons. When the install button is clicked, the current package +// is installed. +*/ + +/* +** 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 +*/ + + +#ifndef PKGINSTALL_OPTIONS +#define PKGINSTALL_OPTIONS + +#include "../config.h" +// Qt headers +#include <qframe.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qlabel.h> +#include <qcheckbox.h> + +#include <kdialog.h> + +// kpackage headers +#include "packageInfo.h" +#include "pkgInterface.h" +#include "kpTerm.h" + +class KListView; +class KPushButton; + +class pkgOptions : public KDialog +{ + Q_OBJECT +public: + pkgOptions( pkgInterface *pki, QWidget *parent=0, const QString &caption=QString::null); + ~pkgOptions(); + + bool setup(QPtrList<packageInfo> *pl, const QString &type); + void setup(packageInfo *p, const QString &type); + void reset(); + + virtual QString doPackages(int installFlags, QPtrList<packageInfo> *p, + bool &test) = 0; + + QCheckBox **Boxs; + // options buttons + + QCheckBox *Keep; + // keep window + + KListView *packages; + + int bnumber; + // number of option buttons + + QLabel *title; + // Widget title + + kpTerm *term; + + pkgInterface *pkgInt; + + bool modified; + bool test; + bool running; + +protected: + // This sets up the sub-widgets + void setupWidgets(QPtrList<param> &pars); + +private slots: + virtual void pkginstallButtonClicked(); + virtual void cancelButtonClicked(); + void slotSearch(QListViewItem *item); + void keepToggle(bool); + +public slots: + void slotResult(QStringList &rlist, int ret); + +signals: + // This signal indicates that the widget has finished. + void finished(int refresh); + +protected: + // The layout managers + QBoxLayout *layout, *hlayout, *vlayout; + + // Sub widgets + QPushButton *installButton; + KPushButton *cancelButton; + + QString insType; + bool installer; + // install or uninstall + + bool keep; + // keep the window + + QPtrList<packageInfo> *packList; + + void getKeep(); + + void showEvent (QShowEvent *); + void closeEvent (QCloseEvent * e ); + + void terminate(); +}; + + +/////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +class pkgOptionsI: public pkgOptions +{ + Q_OBJECT +public: + pkgOptionsI(pkgInterface *pkg, QWidget *parent = 0); + QString doPackages(int installFlags, QPtrList<packageInfo> *p, bool &test); +}; + +/////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +class pkgOptionsU: public pkgOptions +{ + Q_OBJECT +public: + pkgOptionsU(pkgInterface *pkg, QWidget *parent = 0); + QString doPackages(int installFlags, QPtrList<packageInfo> *p, bool &test); +}; + +#endif diff --git a/kpackage/procbuf.cpp b/kpackage/procbuf.cpp new file mode 100644 index 0000000..c994d70 --- /dev/null +++ b/kpackage/procbuf.cpp @@ -0,0 +1,165 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#include "../config.h" +#include "procbuf.h" +#include <kprocess.h> +#include "kpackage.h" +#include <klocale.h> +#include <qlabel.h> +#include <kdebug.h> + +Modal::Modal(QString msg, QWidget *parent, const char * name ) + : KDialog( parent, name, TRUE ) +{ + QLabel *line1 = new QLabel(msg,this); + line1->setAlignment(AlignCenter); + line1->setAutoResize(true); + + } + +void Modal::terminate() +{ + done(0); +} + +procbuf::procbuf() +{ + m = NULL; + tm = new QTimer(this); + connect(tm, SIGNAL(timeout()), this, SLOT(slotTimeout())); +} + +procbuf::~procbuf() +{ +} + +void procbuf::setup(QString cmd) +{ + buf.truncate(0); + proc = new KProcess(); + connect(proc, SIGNAL( receivedStdout(KProcess *, char *, int)), + this, SLOT(slotReadInfo(KProcess *, char *, int))); + connect(proc, SIGNAL( receivedStderr(KProcess *, char *, int)), + this, SLOT(slotReadInfo(KProcess *, char *, int))); + connect(proc, SIGNAL( processExited(KProcess *)), + this, SLOT(slotExited(KProcess *))); + proc->clearArguments(); + *proc << cmd; + command = cmd; +} + +void procbuf::slotReadInfo(KProcess *, char *buffer, int buflen) +{ + char last; + + last = buffer[buflen - 1]; + buffer[buflen - 1] = 0; + + buf += buffer; + buf += last; + + if (timed) { + timed = FALSE; + tm->stop(); + } +} + +void procbuf::slotExited(KProcess *) +{ + if (m) { + m->terminate(); + } + if (timed) { + timed = FALSE; + tm->stop(); + } +} + +void procbuf::slotTimeout() +{ + if (m) { + m->terminate(); + } + // kdDebug() << "TTT\n"; +} + +int procbuf::start (QString msg, bool errorDlg, + int timeout, QString timeMsg ) +{ + if (timeout) { + tm->start(timeout*1000, TRUE); + timed = true; + } + + if (!proc->start(!msg.isNull() ? KProcess::NotifyOnExit : KProcess::Block, + KProcess::All)) { + if (errorDlg) { + KpMsgE(i18n("Kprocess Failure"),TRUE); + } + return 0; + }; + + if (!msg.isEmpty()) { + m = new Modal(msg,kpkg, "wait"); + m->exec(); + delete m; + m = 0; + } + + kdDebug() << command + << " dialog=" << errorDlg + << " normal=" << proc->normalExit() + << " exit=" << proc->exitStatus() << endl; + if (timed) { + kdDebug() << "timeout..................\n"; + KpMsg("Error",i18n("Timeout: %1").arg(timeMsg), TRUE); + delete proc; proc = 0; + return 0; + } else { + if (!proc->normalExit() || proc->exitStatus()) { + if (errorDlg) { + KpMsg("Error",i18n("Kprocess error:%1").arg(buf), TRUE); + } + delete proc; proc = 0; + return 0; + } + } + delete proc; proc = 0; + return 1; +} + + + + + + + + + + + +#include "procbuf.moc" diff --git a/kpackage/procbuf.h b/kpackage/procbuf.h new file mode 100644 index 0000000..8463810 --- /dev/null +++ b/kpackage/procbuf.h @@ -0,0 +1,68 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + + +#include "../config.h" +#include <kprocess.h> +#include <kdialog.h> +#include <qobject.h> +#include <qtimer.h> + +#ifndef PROCBUF +#define PROCBUF + +class Modal : public KDialog { + Q_OBJECT +public: + Modal(QString msg, QWidget *parent, const char * name ); + void terminate(); +}; + +class procbuf: public QObject +{ + Q_OBJECT + +public: + procbuf(); + ~procbuf(); + void setup(QString); + int start(QString msg, bool errorDlg = TRUE, + int timeout=0, QString timeMsg = ""); + + QString buf; + KProcess *proc; + Modal *m; + QString command; + bool timed; + QTimer *tm; + +public slots: + void slotReadInfo(KProcess *, char *, int); + void slotExited(KProcess *); + void slotTimeout(); +}; +#endif diff --git a/kpackage/rpmInterface.cpp b/kpackage/rpmInterface.cpp new file mode 100644 index 0000000..655e6b8 --- /dev/null +++ b/kpackage/rpmInterface.cpp @@ -0,0 +1,631 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + +////////////////////////////////////////////////////////////////////////////// +/// +/// RPM Program version +/// +////////////////////////////////////////////////////////////////////////////// + +#include <kdebug.h> +#include <klocale.h> +#include <kglobal.h> +#include <kiconloader.h> + +#include "kpPty.h" +#include "kpackage.h" +#include "rpmInterface.h" +#include "updateLoc.h" +#include "cache.h" + +RPM::RPM():pkgInterface() +{ + head = "RPM"; + name = i18n("RPM"); + icon = "rpm"; + + pict = UserIcon(icon); + updated_pict = UserIcon("rupdated"); + new_pict = UserIcon("rnew"); + + packagePattern = "*.rpm"; + typeID = "/rpm"; + + locatedialog = new Locations(i18n("Location of RPM Package Archives")); + locatedialog->dLocations(7,6, this, i18n("Folder","F"), + "Rpm","*.rpm", i18n("Location of Folders Containing RPM Packages")); + + connect(locatedialog,SIGNAL(returnVal(LcacheObj *)), + this,SLOT(setAvail(LcacheObj *))); + locatedialog->apply_slot(); + + paramsInst.append(new param(i18n("Upgrade"),TRUE,FALSE,"-U","-i")); + paramsInst.append(new param(i18n("Replace Files"),FALSE,FALSE,"--replacefiles")); + paramsInst.append(new param(i18n("Replace Packages"),TRUE,FALSE,"--replacepkgs")); + paramsInst.append(new param(i18n("Check Dependencies"),TRUE,TRUE,"--nodeps")); + paramsInst.append(new param(i18n("Test (do not install)"),FALSE,FALSE,"--test")); + + paramsUninst.append(new param(i18n("Remove all versions"),FALSE,FALSE,"--allmatches")); + paramsUninst.append(new param(i18n("Use Scripts"),TRUE,TRUE,"--noscripts")); + paramsUninst.append(new param(i18n("Check Dependencies"),TRUE,TRUE,"--nodeps")); + paramsUninst.append(new param(i18n("Test (do not uninstall)"),FALSE,FALSE,"--test")); + + + queryMsg = i18n("Querying RPM package list: "); + + QDict<QString> provides(1433,false); + + infoList.append("name/%{NAME}"); + infoList.append("version/%{VERSION}"); + infoList.append("release/%{RELEASE}"); + infoList.append("summary/%{SUMMARY}"); + infoList.append("url/%{URL}"); + infoList.append("architecture/%{ARCH}"); + infoList.append("group/%{GROUP}"); + infoList.append("distribution/%{DISTRIBUTION}"); + infoList.append("vendor/%{VENDOR}"); + infoList.append("packager/%{PACKAGER}"); + infoList.append("installtime/%{INSTALLTIME:date}"); + infoList.append("buildtime/%{BUILDTIME:date}"); + infoList.append("size/%{SIZE}"); + infoList.append("provides/[%{PROVIDES}, ]"); + infoList.append("requires/[%{REQUIRENAME} (%{REQUIREFLAGS:depflags} %{REQUIREVERSION}), ]"); + infoList.append("description/[%{DESCRIPTION}]"); + + hasProgram = ifExe("rpm"); +} + + RPM::~RPM(){} + +bool RPM::isType(char *buf, const QString & /* fname */) +{ + if (hasProgram) { + if ((unsigned char)buf[0] == 0355 && (unsigned char)buf[1] == 0253 && + (unsigned char)buf[2] == 0356 && (unsigned char)buf[3] == 0333 ) { + return true; + } else + return false; + } else { + return false; + } +} + +bool RPM::parseName(const QString &name, QString *n, QString *v) +{ + int d1, d2, s1, s2; + + s2 = name.findRev('.'); + if (s2 > 0) { + s1 = name.findRev('.',s2-1); + if (s1 > 0) { + d2 = name.findRev('-',s1-1); + if (d2 > 0) { + d1 = name.findRev('-',d2-1); + if (d1 < 0) + d1 = d2; + *n = name.left(d1); + *v = name.mid(d1+1,s1-d1-1); + return TRUE; + } + } + } + return FALSE; +} + +QString RPM::packageQuery() { + QString cmd = " --queryformat '"; + for ( QStringList::Iterator it = infoList.begin(); it != infoList.end(); ++it ) { + QStringList s = QStringList::split("/",*it); + cmd += "=="; + cmd += s[0]; + cmd += "\\n"; + cmd += s[1]; + cmd += "\\n"; + } + cmd += "==\\n'"; + return cmd; +} + +void RPM::listInstalledPackages(QPtrList<packageInfo> *pki) +{ + int NLINES = 70000; + + packageInfo *p; + QStringList plist; + + QString cmd = "rpm -q -a"; + cmd += packageQuery(); + + kpackage->setStatus(i18n("Querying RPM package list")); + kpackage->setPercent(0); + + QStringList list = kpty->run(cmd); + kpackage->setStatus(i18n("Processing RPM package list")); + // kdDebug() << "P=" << list.count() <<"\n"; + kpackage->setPercent(50); + + + if (list.count() > 0) { + + QString s; + + kpackage->setPercent(0 ); + int cnt = 0; + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + cnt++; + if (cnt % (NLINES/20) == 0) { + kpackage->setPercent((cnt * 100)/ NLINES ); + } + if (*it != "==") { + s = *it; + // kdDebug() << s.length() << "<" << s << ">\n"; + plist << s; + } else { + p = collectInfo(plist); + if (p) { + if (!p->pkgInsert(pki, typeID, TRUE)) { + delete p; + } + } + plist.clear(); + } + } + } + + list.clear(); + kpackage->setStatus(i18n("DEB APT")); + kpackage->setPercent(100); +} + +packageInfo* RPM::collectInfo(QStringList &ln) { + + bool haveName = FALSE; + QMap<QString, QString> a; + + QString name, value; + + for ( QStringList::Iterator it = ln.begin(); it != ln.end(); ++it ) { + if ((*it).left(2) == "==" && (*it).length() >= 2) { + name = (*it).right((*it).length() - 2); + } + value = ""; + it++; + while (it != ln.end() && (*it).left(2) != "==") { + value += *it; + value += " "; + it++; + } + it--; + + // kdDebug() << "name=" << name << " value='" << value << "'\n"; + if (name == "installtime") { + a.insert("install time", value); + } else if (name == "name") { + if (!value.isEmpty()) + haveName = TRUE; + a.insert("name", value.stripWhiteSpace()); + } else if (name == "buildtime") { + a.insert("build-time", value); + } else if (name == "requires") { + value = value.replace(QRegExp("\\(\\)"),""); + value = value.replace(QRegExp("\\( \\)"),""); + value = value.stripWhiteSpace(); + if (value.endsWith(",")) { + value.truncate(value.length()-1); + } + a.insert("depends", value); + } else if (name == "provides") { + int s = 0, n; + QString t; + + if (!(*a.find("name")).isEmpty()) { + while ((n = value.find(",",s)) > 0) { + t = value.mid(s,n-s); + t = t.stripWhiteSpace(); + if (!t.isEmpty()) + provides.insert(t,new QString(*a.find("name"))); + s = n+1; + } + t = value.mid(s); + t = t.stripWhiteSpace(); + if (!t.isEmpty()) + provides.insert(t,new QString(*a.find("name"))); + + value = value.stripWhiteSpace(); + if (value.endsWith(",")) { + value.truncate(value.length()-1); + } + a.insert("provides", value); + } + } else { + if (!name.isEmpty()) + a.insert(name, value.stripWhiteSpace()); + } + + } + + QString vers = a["version"]; + QString rel = a["release"]; + if (!vers.isEmpty() && !rel.isEmpty()) { + vers += "-"; + vers += rel; + a["version"] = vers; + a.remove("release"); + } + + if (haveName) { + packageInfo *i = new packageInfo(a,this); + i->packageState = packageInfo::INSTALLED; + i->fixup(); + return i; + } else { + return 0; + } +} + +////////////////////////////////////////////////////////////////////////////// + +QStringList RPM::getChangeLog(packageInfo *p) +{ + QStringList clog; + QString fn( p->getFilename()); + + if(!fn.isEmpty()) + return getUChangeLog(fn); + else + return getIChangeLog(p); + + return clog; +} + + +// query an installed package +QStringList RPM::getIChangeLog(packageInfo *p) +{ + QString name = p->getProperty("name"); + + QString cmd = "rpm -q --changelog "; + cmd += name; + + QStringList filelist = kpty->run(cmd); + + return filelist; +} + + +// query an uninstalled package +QStringList RPM::getUChangeLog(const QString &fn) +{ + QString cmd = "rpm -q --changelog -p "; + cmd += quotePath(fn); + + QStringList filelist = kpty->run(cmd); + + return filelist; +} + + +bool RPM::filesTab(packageInfo *p) { + if (p->packageState == packageInfo::INSTALLED) { + return true; + } else if (p->isFileLocal()) { + return true; + } + return false; +} + +bool RPM::changeTab(packageInfo *p) { + if (p->packageState == packageInfo::INSTALLED) { + return true; + } else if (p->isFileLocal()) { + return true; + } + return false; +} + +////////////////////////////////////////////////////////////////////////////// + + +QStringList RPM::getFileList(packageInfo *p) +{ + QStringList filelist; + QString fn( p->getFilename()); + + if(!fn.isEmpty()) + return getUFileList(fn); + else + return getIFileList(p); + + return filelist; +} + + + +// query an installed package +QStringList RPM::getIFileList(packageInfo *p) +{ + QString name = p->getProperty("name"); + + QString cmd = "rpm -q -l "; + cmd += name; + + QStringList filelist = kpty->run(cmd); + + return filelist; +} + + +// query an uninstalled package +QStringList RPM::getUFileList(const QString &fn) +{ + QString cmd = "rpm -q -l -p "; + cmd += quotePath(fn); + + QStringList filelist = kpty->run(cmd); + + return filelist; +} + +////////////////////////////////////////////////////////////////////////////// +packageInfo *RPM::getPackageInfo(char mode, const QString &name, const QString &) +{ + if (mode == 'i') { + return getIPackageInfo(name); + } else + return getUPackageInfo(name); +} + +packageInfo *RPM::getIPackageInfo( const QString &name ) +{ + // query an installed package! + QString cmd = "rpm -q"; + cmd += packageQuery(); + cmd += " "; + cmd += name; + + QStringList infoList = kpty->run(cmd); + packageInfo *pki = collectInfo(infoList); + if (pki) { + pki->packageState = packageInfo::INSTALLED; + collectDepends(pki,name,0); + } + return pki; +} + +packageInfo *RPM::getUPackageInfo( const QString &name ) +{ + // query an uninstalled package + QString cmd = "rpm -q"; + cmd += packageQuery(); + cmd += " -p "; + cmd += quotePath(name); + + QStringList infoList = kpty->run(cmd); + packageInfo *pki = collectInfo(infoList); + if (pki) { + pki->updated = TRUE; + pki->packageState = packageInfo::AVAILABLE; + if (pki->hasProperty("install time")) + pki->info.remove("install time"); + collectDepends(pki,name,1); + } + + return pki; +} + +QString RPM::provMap( const QString &p ) +{ + QString *r = provides[p]; + if (r) { + QString s = *r; + // printf("%s=>%s\n",p.data(),s.data()); + return s; + } else { + return p; + } +} + + +////////////////////////////////////////////////////////////////////////////// +void RPM::collectDepends(packageInfo *p, const QString &name, int src) +{ + QString cmd = "rpm -V --nofiles "; + if (src) { + cmd += "-p "; + } + cmd += quotePath(name); + + // cmd = "cat /home/toivo/rpm.deps"; + QStringList list = kpty->run(cmd); + + if (list.count() > 0) { + QStringList::Iterator it = list.begin(); + int pt = (*it).find(":"); + if (pt > 0) { + QString s = (*it).mid(pt+1); + if (!s.isEmpty()) { + // kdDebug() << "S=" << s << "\n"; + p->info.insert("unsatisfied dependencies", s); + } + } + } +} + +////////////////////////////////////////////////////////////////////////////// +void RPM::setLocation() +{ + locatedialog->restore(); +} + +void RPM::setAvail(LcacheObj *slist) +{ + if (packageLoc) + delete packageLoc; + packageLoc = slist; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +QString RPM::uninstall(int uninstallFlags, QPtrList<packageInfo> *plist, bool &test) +{ + QStringList files; + + packageInfo *pk; + for (pk = plist->first(); pk != 0; pk = plist->next()) { + files.append( pk->getProperty("name") ); + } + + if (getuid() == 0) { + return doUninst(uninstallFlags,files, test); + } else { + return doUninstP(uninstallFlags,files, test); + } +} + +QString RPM::uninstall(int uninstallFlags, packageInfo *p, bool &test) +{ + QStringList files; + files.append( p->getProperty("name") ); + + if (getuid() == 0) { + return doUninstP(uninstallFlags,files, test); + } else { + return doUninstP(uninstallFlags,files, test); + } +} + +QString RPM::doUninstP(int uninstallFlags, const QStringList &files, bool &test) +{ + QString s = "rpm -e "; + s += setOptions(uninstallFlags, paramsUninst); + + for (QStringList::ConstIterator it = files.begin(); it != files.end(); ++it ) { + s += " "; + s += *it; + } + + if (uninstallFlags>>3 & 1) + test = TRUE; + + kdDebug() << "uCMD=" << s << " test=" << test << "\n"; + + return s; +} + + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +QString RPM::install(int installFlags, QPtrList<packageInfo> *plist, bool &test) +{ + QStringList files; + + for (packageInfo *pk = plist->first(); pk != 0; pk = plist->next()) { + QString fname( pk->fetchFilename() ); + if (!fname.isEmpty()) { + files.append(quotePath(fname)); + } + } + + if (getuid() == 0) { + return doinstP(installFlags,files,test); + } else { + return doinstP(installFlags,files,test); + } +} + +QString RPM::install(int installFlags, packageInfo *p, bool &test) +{ + QStringList files; + files.append(quotePath(p->fetchFilename())); + if (getuid() == 0) { + return doinstP(installFlags,files,test); + } else { + return doinstP(installFlags,files,test); + } +} + + +QString RPM::doinstP(int installFlags, const QStringList &files, bool &test) +{ + QString s = "rpm "; + s += setOptions(installFlags, paramsInst); + + for (QStringList::ConstIterator it = files.begin(); it != files.end(); ++it ) { + s += " "; + s += *it; + } + + if (installFlags>>4 & 1) + test = TRUE; + + kdDebug() << "iCMD=" << s << " test=" << test << "\n"; + + return s; +} + + QStringList RPM::verify(packageInfo *p, const QStringList &files){ + return pkgInterface::verify(p,files);} + +////////////////////////////////////////////////////////////////////////////// +QStringList RPM::FindFile(const QString &name, bool) { + QString cmd = "rpm -q -a --filesbypkg"; + + QStringList list = kpty->run(cmd); + QStringList retlist; + if (kpty->Result > 0) { + list.clear(); + } else { + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + int p = (*it).find(" "); + int nm = (*it).find(name,p); + if (nm >= 0) { + (*it).replace(p, 1, "\t"); + retlist.append(*it); + } + } + } + + return retlist; +} + +////////////////////////////////////////////////////////////////////////////// +QString RPM::quotePath( const QString &path) { + QString s = path; + s = s.replace(" ","\\ "); + return ( "'" + s + "'" ); +} + +////////////////////////////////////////////////////////////////////////////// + QStringList RPM::depends(const QString &, int){return 0;} + + QString RPM::doUninst(int, const QStringList &, bool &){return "0=";} + QString RPM::doinst(int, const QStringList &, bool &){return "0=";} + + +#include "rpmInterface.moc" diff --git a/kpackage/rpmInterface.h b/kpackage/rpmInterface.h new file mode 100644 index 0000000..a1357ef --- /dev/null +++ b/kpackage/rpmInterface.h @@ -0,0 +1,111 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#ifndef RPM_IFACE_H +#define RPM_IFACE_H + +#include "../config.h" + + +#include <qptrlist.h> + +#include "packageInfo.h" +#include "pkgInterface.h" + +class KDir; +class cacheObj; + +class RPM : public pkgInterface +{ + Q_OBJECT + +public: + RPM(); + ~RPM(); + + bool isType(char *buf, const QString &fname); + + packageInfo *getPackageInfo(char mode, const QString &name, const QString &version); + QStringList getFileList(packageInfo *p); + QStringList getChangeLog(packageInfo *p); + + bool filesTab(packageInfo *p); + // If files tab is to be enabled + + bool changeTab(packageInfo *p); + // If change log tab is to be enabled + + QStringList depends(const QString &name, int src); + QStringList verify(packageInfo *p, const QStringList &files); + + QString uninstall(int uninstallFlags, QPtrList<packageInfo> *p, bool &test); + QString uninstall(int uninstallFlags, packageInfo *p, bool &test); + QString doUninst(int uninstallFlags, const QStringList &files, bool &test); + QString doUninstP(int uninstallFlags, const QStringList &files, bool &test); + + QString install(int installFlags, QPtrList<packageInfo> *p, bool &test); + QString install(int installFlags, packageInfo *p, bool &test); + QString doinst(int installFlags, const QStringList &files, bool &test); + QString doinstP(int installFlags, const QStringList &files, bool &test); + + QStringList FindFile(const QString &name, bool seachAll=false); + void collectDepends(packageInfo *p, const QString &name, int src); + bool parseName(const QString &name, QString *n, QString *v); + + QString provMap(const QString &p); + +public slots: + void setLocation(); + void setAvail(LcacheObj *); + +private: + packageInfo* collectInfo(QStringList &ln); + + void listInstalledPackages(QPtrList<packageInfo> *pki); + + QDict<QString> provides; + bool rpmSetup; + QStringList infoList; + + QString packageQuery(); + + QStringList getIFileList( packageInfo *p ); + QStringList getUFileList( const QString &fn ); + + QStringList getIChangeLog( packageInfo *p ); + QStringList getUChangeLog( const QString &fn ); + + packageInfo *getIPackageInfo( const QString &name); + packageInfo *getUPackageInfo( const QString &name); + + QString quotePath( const QString &path); + + }; + +#endif + + + diff --git a/kpackage/search.cpp b/kpackage/search.cpp new file mode 100644 index 0000000..e4254f4 --- /dev/null +++ b/kpackage/search.cpp @@ -0,0 +1,115 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#include "../config.h" + +#include "kpackage.h" +#include "managementWidget.h" +#include "search.h" +#include <klocale.h> +#include <qlineedit.h> +#include <qcheckbox.h> +#include <qframe.h> +#include <qgroupbox.h> + +Search::Search(QWidget *parent, const char * name) + : KDialogBase(parent, name, false, + i18n("Find Package"), + User1 | Close, User1, true, + KGuiItem( i18n("&Find"), "find")) +{ + QFrame *page = makeMainWidget(); + + setFocusPolicy(QWidget::StrongFocus); + + QVBoxLayout* vtop = new QVBoxLayout( page, 10, 10, "vtop"); + + QFrame *frame1 = new QGroupBox(i18n("Find Package"), page, "frame1"); + vtop->addWidget(frame1,1); + QVBoxLayout* vf = new QVBoxLayout( frame1, 20, 10, "vf"); + + value = new QLineEdit( frame1, "v"); + vf->addWidget(value,0); + value->setFocus(); + value->setFixedHeight(value->sizeHint().height()); + value->setMinimumWidth(250); + connect(value, SIGNAL(textChanged(const QString &)),this, SLOT(textChanged(const QString &))); + + QHBoxLayout* hc = new QHBoxLayout( ); + vf->addLayout(hc,0); + + substr = new QCheckBox(i18n("Sub string"), frame1, "substr"); + substr->setChecked(TRUE); + hc->addWidget(substr,1,AlignLeft); + substr->setFixedSize(substr->sizeHint()); + hc->addStretch(1); + + wrap = new QCheckBox(i18n("Wrap search"), frame1, "wrap"); + wrap->setChecked(TRUE); + hc->addWidget(wrap,1,AlignRight); + wrap->setFixedSize(wrap->sizeHint()); + + enableButton( User1, false ); + + connect(this, SIGNAL(user1Clicked()), this, SLOT(ok_slot())); + connect(this, SIGNAL(closeClicked()), this, SLOT(done_slot())); + + show(); +} + +Search::~Search() +{ +} + +void Search::textChanged(const QString &text) +{ + enableButton( User1, !text.isEmpty() ); +} + +void Search::ok_slot() +{ + QListViewItem *pkg; + + QString to_find = value->text(); + to_find = to_find.stripWhiteSpace(); + + pkg = kpackage->management->search(to_find, + substr->isChecked(),FALSE,FALSE); + if (pkg == 0 && wrap->isChecked()) { + pkg = kpackage->management->search(to_find, + substr->isChecked(),TRUE,FALSE); + } + if (pkg == 0) + KpMsg(i18n("Note"), + i18n("%1 was not found.").arg(to_find),TRUE); +} + +void Search::done_slot() +{ + hide(); +} + +#include "search.moc" diff --git a/kpackage/search.h b/kpackage/search.h new file mode 100644 index 0000000..e5ae2cd --- /dev/null +++ b/kpackage/search.h @@ -0,0 +1,69 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + + +#ifndef SEARCH_H +#define SEARCH_H + +#include "../config.h" + +// Standard Headers +#include <stdio.h> + + +class QLineEdit; +class QCheckBox; + +// KDE headers +#include <kapplication.h> +#include <kmenubar.h> +#include <kdialogbase.h> + +class Search : public KDialogBase +{ + Q_OBJECT + +public: + + Search ( QWidget *parent = 0, const char * name=0); + ~Search(); + +private: + QCheckBox *substr; + QCheckBox *wrap; + QLineEdit *value; + +signals: + void search_signal(); + void search_done_signal(); + +public slots: + void done_slot(); + void ok_slot(); + void textChanged(const QString &); +}; +#endif diff --git a/kpackage/slackInterface.cpp b/kpackage/slackInterface.cpp new file mode 100644 index 0000000..8b80f2d --- /dev/null +++ b/kpackage/slackInterface.cpp @@ -0,0 +1,691 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#include "../config.h" + +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <ctype.h> + +#include <setjmp.h> + +#include <qdir.h> +#include <qfileinfo.h> +#include <qregexp.h> + +#include <kurl.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <kdebug.h> + +#include "packageInfo.h" +#include "slackInterface.h" +#include "updateLoc.h" +#include "kpackage.h" +#include "managementWidget.h" +#include "utils.h" +#include "procbuf.h" +#include "options.h" +#include "cache.h" +#include <klocale.h> + + +#define DIR "/var/log/packages/" +#define FILELIST "FILE LIST:\n" + +enum {INITIAL, INSTALLED, UNINSTALLED}; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +SLACK::SLACK():pkgInterface() +{ + head = "SLACK"; + name = i18n("Slackware"); + icon = "slack"; + + pict = UserIcon(icon); + updated_pict = UserIcon("supdated"); + new_pict = UserIcon("snew"); + + packagePattern = "*.tgz *.tar.gz"; + typeID = "/slack"; + + locatedialog = 0; + + queryMsg = i18n("Querying SLACK package list: "); + procMsg = i18n("KPackage: Waiting on SLACK"); + + locatedialog = new Locations(i18n("Location of Slackware Package Archives")); + locatedialog->pLocations(1, 1, this, i18n("Install location", "I"), + "Slackware", "*.TXT *.txt *.tgz *.tar.gz", + i18n("Location of a 'PACKAGES.TXT' File for Extended Information")); + locatedialog->pLocations(4, 1, this, i18n("Packages file", "P"), + "Slackware", "*.tgz *.tar.gz", + i18n("Location of 'PACKAGES.TXT' File for Slackware Distribution"), + i18n("Location of Base Folder of Slackware Distribution")); + locatedialog->dLocations(2, 6, this, i18n("Folders", "F"), + "Slackware", "*.tgz *.tar.gz", + i18n("Location of Folders Containing Slackware Packages")); + + connect(locatedialog,SIGNAL(returnVal(LcacheObj *)), + this,SLOT(setAvail(LcacheObj *))); + locatedialog->apply_slot(); + + paramsInst.append(new param(i18n("Test (do not install)"),FALSE,FALSE,"-warn")); + + paramsUninst.append(new param(i18n("Test (do not uninstall)"),FALSE,FALSE,"-warn")); + + hasProgram = ifExe("installpkg"); + + initTranslate(); +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +SLACK::~SLACK() +{ +} + +////////////////////////////////////////////////////////////////////////////// +void SLACK::initTranslate() +{ + trl = new QDict<QString>(53); + + trl->insert("a",new QString(i18n("Base System"))); + trl->insert("ap",new QString(i18n("Linux Applications"))); + trl->insert("d",new QString(i18n("Program Development"))); + trl->insert("e",new QString(i18n("GNU EMacs"))); + trl->insert("f",new QString(i18n("FAQs"))); + trl->insert("k",new QString(i18n("Kernel Source"))); + trl->insert("n",new QString(i18n("Networking"))); + trl->insert("t",new QString(i18n("TeX Distribution"))); + trl->insert("tcl",new QString(i18n("TCL Script Language"))); + trl->insert("x",new QString(i18n("X Window System"))); + trl->insert("xap",new QString(i18n("X Applications"))); + trl->insert("xd",new QString(i18n("X Development Tools"))); + trl->insert("xv",new QString(i18n("XView and OpenLook"))); + trl->insert("y",new QString(i18n("Games"))); +} + +// check if slack file +bool SLACK::isType(char *buf, const QString &) +{ + if (hasProgram) { + if ((unsigned char)buf[0] == 037 && (unsigned char)buf[1] == 0213 ) { + return true; + } else + return false; + } else { + return false; + } +} + +bool SLACK::parseName(const QString &name, QString *n, QString *v) +{ + int s1; + s1 = name.findRev('.'); + if (s1 > 0) { + *n = name.left(s1); + v = new QString(""); + return TRUE; + } + return FALSE; +} + +void SLACK::listPackages(QPtrList<packageInfo> *pki) +{ + QString s; + cacheObj *cp; + + if (packageLoc) { + for (cp = packageLoc->first(); cp != 0; cp = packageLoc->next()) { + // first entry is special + if (cp->cacheFile == "SLACK_0_0") { + s = getPackList(cp); + if (!s.isEmpty()) { + listPackList(pki, s, cp, INITIAL); + } + } + } + } + + listInstalledPackages(pki); + + if (packageLoc) { + for (cp = packageLoc->first(); cp != 0; cp = packageLoc->next()) { + if (cp->cacheFile == "SLACK_0_0") { + // already done + } else if ( !cp->base.isEmpty() ) { + s = getPackList(cp); + if (!s.isEmpty()) { + listPackList(pki, s, cp, UNINSTALLED); + } + } else { + s = getDir(cp); + if (!s.isEmpty()) { + listDir(pki,s,cp->location); + } + } + } + } +} + +void SLACK::listInstalledPackages(QPtrList<packageInfo> *pki) +{ + FILE *file; + char linebuf[1024]; + QString vb; + packageInfo *p; + QString fn, dr = DIR; + + QDir d(DIR); + if (d.exists()) { + QString sline = i18n("Querying SLACK package list: "); + kpackage->setStatus(sline); + + const QFileInfoList *list = d.entryInfoList(); + int count = list->count(); + QFileInfoListIterator it( *list ); // create list iterator + QFileInfo *fi; // pointer for traversing + + kpackage->setPercent(0); + int cnt = 0; + while ( (fi=it.current()) ) { // for each file... + int n = (cnt*100)/count; + if (!(n % 5)) + kpackage->setPercent(n); + + if (!fi->isDir() && fi->isReadable()) { + fn = dr + fi->fileName(); + file = fopen(QFile::encodeName(fn),"r"); + if (file) { + vb = QString::null; + while (fgets(linebuf,sizeof(linebuf),file)) { + if (strcmp(linebuf,FILELIST)) { + vb += linebuf; + } else { + break; + } + } + fclose(file); + p = collectInfo(vb.ascii(), INSTALLED); + if (p) { + smerge(p); + if (!p->pkgInsert(pki, typeID, TRUE)) + delete p; + } + } + } + cnt++; + ++it; // goto next list element + } + kpackage->setPercent(100); + } +} + +////////////////////////////////////////////////////////////////////////////// +void SLACK::listPackList(QPtrList<packageInfo> *pki, const QString &s, cacheObj *cp, int insState) +{ + int np; + QString vb; + char linebuf[1024]; + FILE *file; + packageInfo *p; + + QString sline = i18n("Querying SLACK package list: "); + sline += cp->location; + + kpackage->setStatus(sline); + kpackage->setPercent(0); + + np = 0; + file= fopen(QFile::encodeName(s), "r"); + vb = ""; + + if (file) { + while (fgets(linebuf,sizeof(linebuf),file)) { + int len = strlen(linebuf); + if (len > 1) { + if (linebuf[len - 2] == '\r') { + linebuf[len - 2] = '\n'; + linebuf[len - 1] = 0; + } + } + if (strcmp(linebuf,"\n")) { + vb += linebuf; + } else if ( !vb.isEmpty() ) { + p = collectInfo(vb.ascii(), insState); + if (p) { + if (!p->pkgInsert(pki, typeID, insState == INITIAL, insState == INITIAL)) { + delete p; + } else if (cp && insState != INITIAL) { + p->info.insert("base", cp->base); + } + if (p && insState == INITIAL) { + p->packageState = packageInfo::NOLIST; + p->info.remove("summary"); + } + } + vb.truncate(0); + } + } + fclose(file); + } + kpackage->setPercent(100); +} + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +// mode: i = query installed u = query uninstalled +packageInfo *SLACK::getPackageInfo(char mode, const QString &name, const QString &) +{ + char linebuf[1024]; + packageInfo *pki = 0; + QString vb, search, fn; + QString n,v; + FILE *file; + + switch(mode) { + //////////////////////////////////////////////////////////////////////// + // query an installed package! + case 'i': + fn = DIR + name; + file = fopen(QFile::encodeName(fn),"r"); + if (file) { + vb = QString::null; + while (fgets(linebuf,sizeof(linebuf),file)) { + if (strcmp(linebuf,FILELIST)) { + vb += linebuf; + } else { + break; + } + } + fclose(file); + pki = collectInfo(vb.ascii(), INSTALLED); + if (pki) { + smerge(pki); + } + } + break; + + //////////////////////////////////////////////////////////////////// + // query an uninstalled package + case 'u': + QFile f(name); + if (f.exists()) { + QMap<QString, QString> a; + + a.insert("group", i18n("OTHER")); + a.insert("filename", name); + + QFileInfo f(name); + a.insert("name", f.baseName()); + + QString st; + st.setNum(f.size()); + a.insert("file-size", st); + + pki = new packageInfo(a,this); + if (pki) { + smerge(pki); + pki->updated = TRUE; + } + } + break; + } + return pki; +} + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +packageInfo *SLACK::collectInfo(const char *_inp, int insState) +{ + QString stmp, fn = ""; + QMap<QString, QString> a; + + char *str, *xstr; + QString qstr; + + char *inp = qstrdup(_inp); + str = strtok(inp,"\n"); + + if (str) { + do { + if (str[0] == 0) + break; + + xstr = strchr(str,':'); + if (xstr) { + *xstr++ = 0; + xstr++; + while (*xstr == ' ') { + xstr++; + } + + for( int i = 0; str[ i ] != '\0'; ++i ) + str[ i ] = tolower( str[ i ] ); + + if (*str == ' ') + str++; + + if (!strcmp("package name",str)) { + fn = xstr; + QString st = xstr; + if (st.right(4) == ".tgz") + a.insert("name", st.left(st.length() - 4)); + else + a.insert("name", st); + } else if (!strcmp("package description",str)) { + int i = 0; + QString qstr = ""; + + while ((str = strtok(NULL,"\n"))) { + xstr = strchr(str,':'); + if (xstr) { + *xstr++ = 0; + if (*(xstr) != 0) + xstr++; + while (*xstr == ' ') { + xstr++; + } + if (i == 0) { + a.insert("summary", xstr); + } else { + if (!strcmp(xstr,"") && (i != 1)) { + qstr += "\n"; + } else { + qstr += xstr; + qstr += " "; + } + } + } + i++; + } + a.insert("description", qstr); + } else if (!strcmp("package location",str)) { + QString sl = xstr; + if (insState != INSTALLED) { + int sls = sl.findRev("/"); + if (sls >= 0) { + QRegExp num("[0-9][0-9]*"); + int slf = sl.find(num,sls); + if (slf >= 0) { + sls++; + QString gt = sl.mid(sls,slf-sls); + if (trl->find(gt)) { + gt = *trl->find(gt); + } + a.insert("group",gt); + } + } + sl = sl.right(sl.length() - 2); + sl += "/"; + sl += fn; + } + if (insState == UNINSTALLED) { + a.insert("filename", sl); + } + } else if (!strcmp("section",str)) { + a.insert("group", xstr); + } else if (!strcmp("compressed package size",str) || + !strcmp("package size (compressed)",str)) { + QString stmp = xstr; + stmp.truncate(stmp.length() - 2); + stmp += "000"; + a.insert("file-size", stmp); + } else if (!strcmp("uncompressed package size",str) || + !strcmp("package size (uncompressed)",str)) { + QString stmp = xstr; + stmp.truncate(stmp.length() - 2); + stmp += "000"; + a.insert("size", stmp); + } else { + a.insert(str, xstr); + } + } + } while ((str = strtok(NULL,"\n"))); + } + + delete [] inp; + + if (a["name"].isEmpty()) { + return 0; + } else { + packageInfo *i = new packageInfo(a,this); + i->packageState = packageInfo::INSTALLED; + i->fixup(); + return i; + } +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +QStringList SLACK::getChangeLog(packageInfo *) { + return 0; +} + +bool SLACK::filesTab(packageInfo *) { + return TRUE; +} + +bool SLACK::changeTab(packageInfo *) { + return FALSE; +} + +////////////////////////////////////////////////////////////////////////////// + +QStringList SLACK::getFileList(packageInfo *p) +{ + char linebuf[1024]; + QString st, fn; + FILE *file; + QString name; + char mode; + + fn = p->getFilename(); + if(!fn.isEmpty()) + mode = 'u'; + else + mode = 'i'; + + QStringList filelist; + + switch(mode) { + //////////////////////////////////////////////////////////////////////// + // query an installed package! + case 'i': + name = p->getProperty("name"); + + fn = DIR + name; + file = fopen(QFile::encodeName(fn),"r"); + if (file) { + while (fgets(linebuf,sizeof(linebuf),file)) { + if (!strcmp(linebuf,FILELIST)) { + break; + } + } + while (fgets(linebuf,sizeof(linebuf),file)) { + st = "/"; + st += linebuf; + st.truncate(st.length() -1); + if (st.left(8) != "/install") { + filelist.append(st); + } + } + fclose(file); + } + break; + + //////////////////////////////////////////////////////////////////// + // query an uninstalled package + case 'u': + name = fn; + + QString s = "sh -c 'cat "; + s += fn; + s += "|gunzip |tar -t -f -'"; + + filelist = kpty->run(s); + break; + } + + return filelist; +} + +////////////////////////////////////////////////////////////////////////////// +// Call the script to uninstall packages setting parameters +// to slack dependent on flags, returning whether everyting worked +////////////////////////////////////////////////////////////////////////////// +QString SLACK::doUninstall(int uninstallFlags, const QString &packs, bool &) +{ + QString s = "removepkg "; + s += setOptions(uninstallFlags, paramsUninst); + s += packs; + + kdDebug() << "uCMD=" << s << "\n"; + + return s; +} + +////////////////////////////////////////////////////////////////////////////// +// Call the script to install packages setting parameters +// to slack dependent on flags, returning whether everyting worked +////////////////////////////////////////////////////////////////////////////// +QString SLACK::install(int installFlags, QPtrList<packageInfo> *plist, bool &test) +{ + packageInfo *pk; + int i = 0; + QString packs = ""; + for (pk = plist->first(); pk != 0; pk = plist->next()) { + QString fname = pk->fetchFilename(); + if ( !fname.isEmpty() ) { + packs += fname + " "; + i++; + } + } + return doInstall(installFlags, packs, test); +} + +QString SLACK::doInstall(int installFlags, const QString &packs, bool &) +{ + + QString s = "installpkg "; + s += setOptions(installFlags, paramsInst); + s += packs; + + kdDebug() << "iCMD=" << s << "\n"; + + return s; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +QStringList SLACK::FindFile(const QString &name, bool) +{ + FILE *file; + char linebuf[1024]; + QString buf, st; + QString fn, dr = DIR; + QStringList filelist; + + QDir d(DIR); + if (d.exists()) { + QString sline = i18n("Querying SLACK package list: "); + kpackage->setStatus(sline); + + const QFileInfoList *list = d.entryInfoList(); + int count = list->count(); + QFileInfoListIterator it( *list ); // create list iterator + QFileInfo *fi; // pointer for traversing + + kpackage->setPercent(0); + int cnt = 0; + while ( (fi=it.current()) ) { // for each file... + int n = (cnt*100)/count; + if (!(n % 5)) + kpackage->setPercent(n); + + if (!fi->isDir() && fi->isReadable()) { + fn = dr + fi->fileName(); + file = fopen(QFile::encodeName(fn),"r"); + if (file) { + while (fgets(linebuf,sizeof(linebuf),file)) { + if (!strcmp(linebuf,FILELIST)) { + break; + } + } + while (fgets(linebuf,sizeof(linebuf),file)) { + if (QString::fromLocal8Bit(linebuf).find(name) != -1) { + st = "/"; + st += linebuf; + st.truncate(st.length() -1); + if (st.left(8) != "/install") { + QString s = fi->fileName(); + s += "\t"; + s += st; + filelist.append(s); + } + } + } + fclose(file); + } + } + cnt++; + ++it; // goto next list element + } + } + return filelist; +} + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +void SLACK::setLocation() +{ + locatedialog->restore(); +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +void SLACK::setAvail(LcacheObj *slist) +{ + delete packageLoc; + packageLoc = slist; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +void SLACK::smerge(packageInfo *p) +{ + p->smerge(typeID); +} +#include "slackInterface.moc" diff --git a/kpackage/slackInterface.h b/kpackage/slackInterface.h new file mode 100644 index 0000000..c11a7c2 --- /dev/null +++ b/kpackage/slackInterface.h @@ -0,0 +1,92 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#ifndef SLACK_IFACE_H +#define SLACK_IFACE_H + +#include "../config.h" + +#include <qptrlist.h> +#include <kprocess.h> + +#include "pkgInterface.h" + +class packageInfo; +class updateLoc; +class cacheObj; + +class SLACK: public pkgInterface +{ + Q_OBJECT + +public: + SLACK(); + ~SLACK(); + + bool isType(char *buf, const QString &fname); + + packageInfo *getPackageInfo(char mode, const QString &name, + const QString &version); + QStringList getFileList(packageInfo *p); + QStringList getChangeLog(packageInfo *p); + + bool filesTab(packageInfo *p); + // If files tab is to be enabled + + bool changeTab(packageInfo *p); + // If change log tab is to be enabled + + QStringList FindFile(const QString &name, bool seachAll=false); + bool parseName(const QString& name, QString *n, QString *v); + + QString install(int installFlags, QPtrList<packageInfo> *plist, bool &test); + +public slots: + void setLocation(); + void setAvail(LcacheObj *); + +private: + packageInfo* collectInfo(const char *inp, int insState); + void listInstalledPackages(QPtrList<packageInfo> *pki); + + QString doUninstall(int installFlags, const QString &packs, bool &test); + QString doInstall(int installFlags, const QString &packs, bool &test); + + void listPackages(QPtrList<packageInfo> *pki); + void listPackList(QPtrList<packageInfo> *pki, const QString &s, + cacheObj *cp, int insState); + + void initTranslate(); + + void smerge(packageInfo *p); + + QDict<QString> *trl; +}; + +#endif + + + diff --git a/kpackage/toolbar/Makefile.am b/kpackage/toolbar/Makefile.am new file mode 100644 index 0000000..c19c175 --- /dev/null +++ b/kpackage/toolbar/Makefile.am @@ -0,0 +1,2 @@ +pics_DATA = ftin.xpm ftout.xpm +picsdir = $(kde_datadir)/kpackage/pics diff --git a/kpackage/toolbar/ftin.xpm b/kpackage/toolbar/ftin.xpm new file mode 100644 index 0000000..e70d56d --- /dev/null +++ b/kpackage/toolbar/ftin.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char * kmfolderin_xpm[] = { +/* width height num_colors chars_per_pixel */ +"15 13 5 1", +/* colors */ +" c None", +". c red3", +"X c white", +"o c #c0c0c0", +"O c #808080", +/* pixels */ +" . . ", +" ... ", +" ...XXXXXXXX", +" ...ooooooXX", +" .......XXXXXO", +" .....oooXXOX", +" XX...XXXXXOXO", +" Xooo.oooXXOXOX", +"XXXXXXXXXXOXOX ", +"OOOOOOOOOOXOX ", +"XXXXXXXXXXOX ", +"OOOOOOOOOOX ", +"XXXXXXXXXX "}; diff --git a/kpackage/toolbar/ftout.xpm b/kpackage/toolbar/ftout.xpm new file mode 100644 index 0000000..db28a8e --- /dev/null +++ b/kpackage/toolbar/ftout.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char * kmfolderout_xpm[] = { +/* width height num_colors chars_per_pixel */ +"15 13 5 1", +/* colors */ +" c None", +". c blue4", +"X c white", +"o c #c0c0c0", +"O c #808080", +/* pixels */ +" . ", +" ... ", +" .....XXXXXXX", +" .......ooooXX", +" ...XXXXXXXO", +" X...ooooXXOX", +" XX...XXXXXOXO", +" Xoo.X.ooXXOXOX", +"XXXXXXXXXXOXOX ", +"OOOOOOOOOOXOX ", +"XXXXXXXXXXOX ", +"OOOOOOOOOOX ", +"XXXXXXXXXX "}; diff --git a/kpackage/updateLoc.cpp b/kpackage/updateLoc.cpp new file mode 100644 index 0000000..cf4e582 --- /dev/null +++ b/kpackage/updateLoc.cpp @@ -0,0 +1,761 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#include "../config.h" + +#include "kpackage.h" +#include "updateLoc.h" +#include "pkgInterface.h" +#include "options.h" +#include "cache.h" + +#include <qvbox.h> +#include <qscrollview.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kcombobox.h> + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +apanel::apanel( QWidget *parent, + const char * name ) + : QWidget( parent, name ) +{ + puse = 0; + + pack = new QHBoxLayout(this); + { + puse = new QCheckBox(i18n("Use"),this); + pack->addWidget(puse,0); + + pent = new QLineEdit(this); + pent->setMinimumWidth(600); + pack->addWidget(pent,0); + + } +} + +apanel::~apanel() +{ +} + +QString apanel::getText() const +{ + QString s = pent->text(); + return s; +} + +void apanel::setText(const QString &s) +{ + pent->setText(s); +} + +bool apanel::getUse() +{ + if (puse) + return puse->isChecked(); + else + return FALSE; +} + +void apanel::setUse(int n) +{ + if (puse) { + if (n) + puse->setChecked(TRUE); + else + puse->setChecked(FALSE); + } +} + +void apanel::clear() +{ + puse->setChecked(FALSE); + pent->clear(); +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +dpanel::dpanel( QWidget *parent, const char * name ) + : QWidget( parent, name ) +{ + puse = 0; + psubdirs = 0; + + pack = new QHBoxLayout(this); + { + pent = new QLineEdit(this); + pent->setMinimumWidth(280); + pack->addWidget(pent,0); + + pbut = new QPushButton("...",this); + pack->addWidget(pbut,0); + + connect(pbut, SIGNAL(clicked()), this, SLOT(dirOpen())); + + } +} + +dpanel::dpanel(dpanel *basep, const QString &Pfilter, bool bsubdirs, + QWidget *parent, const char * name ) + : QWidget( parent, name ) +{ + filter = Pfilter; + puse = 0; + psubdirs = 0; + + base = basep; + + pack = new QHBoxLayout(this); + { + puse = new QCheckBox(i18n("Use"),this); + pack->addWidget(puse,0); + + pent = new QLineEdit(this); + pent->setMinimumWidth(280); + pack->addWidget(pent,0); + + if (bsubdirs) { + psubdirs = new QCheckBox(i18n("Subfolders"),this); + psubdirs->setFixedSize(psubdirs->sizeHint()); + pack->addWidget(psubdirs,0); + } + + pbut = new QPushButton("...",this); + pack->addWidget(pbut,0); + + if (base) + connect(pbut, SIGNAL(clicked()), this, SLOT(fileOpen())); + else + connect(pbut, SIGNAL(clicked()), this, SLOT(dirOpen())); + + } +} + +dpanel::~dpanel() +{ +} + +QString dpanel::getText() const +{ + QString s = pent->text(); + return s; +} + +void dpanel::setText(const QString &s) +{ + pent->setText(s); +} + +bool dpanel::getUse() const +{ + if (puse) + return puse->isChecked(); + else + return FALSE; +} + +void dpanel::setUse(int n) +{ + if (puse) { + if (n) + puse->setChecked(TRUE); + else + puse->setChecked(FALSE); + } +} + +bool dpanel::getSubdirs() const +{ + if (psubdirs) + return psubdirs->isChecked(); + else + return FALSE; +} + +void dpanel::setSubdirs(int n) +{ + if (psubdirs) + { + if (n) + psubdirs->setChecked(TRUE); + else + psubdirs->setChecked(FALSE); + } +} + +void dpanel::fileOpen() +{ + QString st; + + if (base && getText().isEmpty()) { + st = base->getText(); + } else { + st = getText(); + } + if (st.right(8) == "Packages") { + st.truncate(st.length() - 8); + } + + KURL url = KFileDialog::getOpenURL + (st, filter, 0, i18n("Package File")); + + if( url.isEmpty() ) + return; + + pent->setText( url.url() ); +} + +void dpanel::dirOpen() +{ + QString st; + + if (base && getText().isEmpty()) { + st = base->getText(); + } else { + st = getText(); + } + + KURL url = KFileDialog::getExistingURL + (st, 0, i18n("Package Archive")); + + + if( url.isEmpty() ) + return; + + pent->setText( url.url() ); + +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +updateLoc::updateLoc(QWidget *p, int panelNumber, pkgInterface *inter, const QString &iname) + : QWidget(p,"updateLoc",FALSE) +{ + interName = iname; + interface = inter; + panNumber = panelNumber; + + vf = new QVBoxLayout( this, 15, 10, "vf"); +} + +updateLoc::~updateLoc() +{ +} + +void updateLoc::doBase(const QString & bmsg) +{ + base = 0; + if (haveBase) { + fbase = new QGroupBox(bmsg, this); + fbase->setColumnLayout(0, Qt::Vertical ); + fbase->layout()->setSpacing( KDialog::spacingHint() ); + fbase->layout()->setMargin( KDialog::marginHint() ); + vbase = new QVBoxLayout(fbase->layout()); + vf->addWidget(fbase,1); + base = new dpanel(fbase); + vbase->addWidget(base,0); + vbase->activate(); + } +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +aUpdateLoc::aUpdateLoc(QWidget *p, int panelNumber, pkgInterface *inter, const QString &iname, + int numberLines, const QString &label) + : updateLoc(p, panelNumber, inter, iname) +{ + + if (numberLines > PNUM) + numLines = PNUM; + else + numLines = numberLines; + + ap[0] = 0; + + QGroupBox *floc = new QGroupBox(1,Qt::Vertical, label, this); + vf->addWidget(floc,1); + QScrollView* sv = new QScrollView(floc); + sv->setHScrollBarMode(QScrollView::AlwaysOff); + sv->setResizePolicy(QScrollView::AutoOneFit); + + QFrame *f = new QFrame(sv->viewport()); + sv->addChild(f); + + QVBoxLayout *vloc = new QVBoxLayout(f, 0, 3, "vloc"); + + for (int i = 0; i < numLines; i++) { + ap[i] = new apanel( f); + vloc->addWidget(ap[i],0); + } + +} + + +aUpdateLoc::~aUpdateLoc() +{ +} + +void aUpdateLoc::readSettings() +{ + int i = 0; + QString a,b; + + for (int i = 0; i < numLines; i++) { + ap[i]->clear(); + } + + QStringList list = interface->readApt(); + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + if (!(*it).isEmpty()) { + if ((*it).left(1) == "#") { + ap[i]->setText(((*it).mid(1)).stripWhiteSpace()); + ap[i]->setUse(0); + } else { + ap[i]->setText((*it)); + ap[i]->setUse(1); + } + i++; + if (i >= numLines) { + ap[numLines - 1]->setText(i18n("File truncated...")); + break; + } + } + } +} + +void aUpdateLoc::writeSettings() { + QStringList list; + QString s; + + QString ln; + for (int i = 0; i < numLines; i++) { + if (!ap[i]) + break; + + ln = ap[i]->getText(); + if (!ln.isEmpty()) { + if (ap[i]->getUse()) { + s = ""; + } else { + s = "# "; + } + s += ln; + list.append(s); + } + } + interface->writeApt(list); +} + +void aUpdateLoc::applyS(LcacheObj *) { +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +pdUpdateLoc::pdUpdateLoc(QWidget *p, int panelNumber, pkgInterface *inter, const QString &iname, + int numberLines, const QString &filter, + const QString &lmsg, QString bmsg, + bool subdirs ) + : updateLoc(p, panelNumber, inter, iname) +{ + + if (numberLines > PNUM) + numLines = PNUM; + else + numLines = numberLines; + + haveBase = !bmsg.isNull(); + + dp[0] = 0; + + QString pn; + pn.setNum(panNumber); + pn += "_"; + + packL = "Package_L_"; + packL += pn; + packU = "Package_U_"; + packU += pn; + packS = "Package_S_"; + packS += pn; + availB = "Available_Base"; + availB += pn; + + doBase(bmsg); + + QGroupBox *floc = new QGroupBox(lmsg, this); + floc->setColumnLayout(0, Qt::Vertical ); + floc->layout()->setSpacing( KDialog::spacingHint() ); + floc->layout()->setMargin( KDialog::marginHint() ); + vf->addWidget(floc,1); + QVBoxLayout *vloc = new QVBoxLayout(floc->layout()); + + for (int i = 0; i < numLines; i++) { + dp[i] = new dpanel(base, filter, subdirs, floc); + vloc->addWidget(dp[i],0); + } + + readSettings(); +} + + +pdUpdateLoc::~pdUpdateLoc() +{ +} + +void pdUpdateLoc::applyS(LcacheObj *slist) +{ + QString t,pn,cn,pv,prev,opts; + cacheObj *CObj; + KConfig *config = kapp->config(); + config->setGroup(interName); + + cn = interface->head; + cn += "_"; + cn += pn.setNum(panNumber); + cn += "_"; + + + for (int i = 0; i < numLines; i++) { + // delete chached dir if text changed + pv = packL + pn.setNum(i); + prev = config->readEntry(pv); + if (prev != dp[i]->getText()) + cacheObj::rmDCache(QString(cn + pn.setNum(i))); + + // create cache object corresponding to this entry + if (dp[i]->getUse()) { + t = dp[i]->getText(); + if (!t.isEmpty()) { + CObj = new cacheObj(haveBase ? base->getText() : QString::null, + t, cn + pn.setNum(i), "", dp[i]->getSubdirs()); + slist->append(CObj); + // printf("T=%s\n",t.data()); + } + } + } + // writeSettings(); +} + +void pdUpdateLoc::readSettings() +{ + QString pv, pn; + + KConfig *config = kapp->config(); + + config->setGroup(interName); + + if (haveBase) + base->setText(config->readEntry(availB)); + + for (int i = 0; i < numLines; i++) { + if (!dp[i]) + break; + pv = packL + pn.setNum(i); + dp[i]->setText(config->readEntry(pv)); + pv = packU + pn.setNum(i); + dp[i]->setUse(config->readNumEntry(pv)); + pv = packS + pn.setNum(i); + dp[i]->setSubdirs(config->readNumEntry(pv)); + } +} + +void pdUpdateLoc::writeSettings() +{ + QString pv, pn; + + KConfig *config = kapp->config(); + + config->setGroup(interName); + if (haveBase) { + if (!base->getText().isEmpty()) + config->writeEntry(availB,base->getText()); + } + + for (int i = 0; i < numLines; i++) { + if (!dp[i]) + break; + pv = packL + pn.setNum(i); + config->writeEntry(pv,dp[i]->getText()); + pv = packU + pn.setNum(i); + config->writeEntry(pv,(int)dp[i]->getUse()); + pv = packS + pn.setNum(i); + config->writeEntry(pv,(int)dp[i]->getSubdirs()); + } + +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +cUpdateLoc::cUpdateLoc(QWidget *p, int panelNumber, pkgInterface *inter, const QString &iname, + int numberLines, const QString &baseMsg, + const QString &boxLabels, const QString &boxValues) + : updateLoc(p, panelNumber, inter, iname) +{ + if (numberLines > PNUM) + numLines = PNUM; + else + numLines = numberLines; + + haveBase = !baseMsg.isNull(); + + combo[0] = 0; + + QString pn; + pn.setNum(panNumber); + pn += "_"; + + packC = "Package_C_"; + packC += pn; + availB = "Available_Base"; + availB += pn; + + QStringList kc = QStringList::split('\n', boxLabels); + QStringList::Iterator kcIt = kc.begin(); + + QStringList oc = QStringList::split('\n', boxValues); + QStringList::Iterator ocIt = oc.begin(); + + + doBase(baseMsg); + + for (int i = 0; i < numLines; i++) { + QGroupBox *floc = new QGroupBox(*kcIt, this); + floc->setColumnLayout(0, Qt::Vertical ); + floc->layout()->setSpacing( KDialog::spacingHint() ); + floc->layout()->setMargin( KDialog::marginHint() ); + vf->addWidget(floc,1); + QVBoxLayout *vloc = new QVBoxLayout(floc->layout()); + + combo[i] = new KComboBox( true, floc); + KCompletion *comp = combo[i]->completionObject(); + connect(combo[i],SIGNAL(returnPressed(const QString&)) + ,comp,SLOT(addItem(const QString&))); + combo[i]->insertStringList(QStringList::split(' ',*ocIt)); + vloc->addWidget(combo[i]); + if (kcIt != kc.end()) { + ++kcIt; + } + if (ocIt != oc.end()) { + ++ocIt; + } + } + + readSettings(); +} + +cUpdateLoc::~cUpdateLoc() +{ +} + + void cUpdateLoc::applyS(LcacheObj *slist) +{ + QString t,pn,cn,pv,prev,opts; + cacheObj *CObj; + KConfig *config = kapp->config(); + config->setGroup(interName); + + cn = interface->head; + cn += "_"; + cn += pn.setNum(panNumber); + cn += "_"; + + if (!base->getText().isEmpty()) { + for (int i = 0; i < numLines; i++) { + opts += combo[i]->currentText(); + opts += "\n"; + } + CObj = new cacheObj(base->getText(), + "", cn + ":", opts); + slist->append(CObj); + } + // writeSettings(); +} + +void cUpdateLoc::readSettings() +{ + QString pv, pn; + + KConfig *config = kapp->config(); + + config->setGroup(interName); + + if (haveBase) + base->setText(config->readEntry(availB)); + + for (int i = 0; i < numLines; i++) { + if (!combo[i]) + break; + pv = packC + pn.setNum(i); + if (!config->readEntry(pv).isEmpty()) { + combo[i]->insertItem(config->readEntry(pv), 0); + } + } + +} + +void cUpdateLoc::writeSettings() +{ + QString pv, pn; + + KConfig *config = kapp->config(); + + config->setGroup(interName); + + if (haveBase) { + config->writeEntry(availB,base->getText()); + } + + for (int i = 0; i < numLines; i++) { + if (!combo[i]) + break; + pv = packC + pn.setNum(i); + config->writeEntry(pv,combo[i]->currentText()); + } + +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +Locations::Locations(const QString &msg) + : KDialogBase(Tabbed, msg, Ok | Cancel, Ok, 0, "Locations", false) +{ + numPanels = 0; + + connect( this, SIGNAL(okClicked()), SLOT(write_slot()) ); +} + +void Locations::dLocations(int numberDirs, int numberLines, + pkgInterface *inter, const QString &iname, + const QString &label, const QString &filter, const QString &dirMsg, + bool subdirs) +{ + QString nm; + + for (int i = numPanels ; (i < numPanels + numberDirs) && (i < PANNUM); i++) { + + QString mp = iname; + nm.setNum(i+1); + mp += nm; + QVBox *page = addVBoxPage(mp); + pn[i] = new pdUpdateLoc(page, i, inter, + label, numberLines, + filter, dirMsg, NULL, subdirs); + } + numPanels += numberDirs; +} + +void Locations::pLocations(int numberDirs, int numberLines, + pkgInterface *inter, const QString &iname, const QString &label, + const QString &filter, + const QString &packMsg, QString baseMsg, bool subdirs) +{ + QString nm; + + for (int i = numPanels; (i < numPanels + numberDirs) && (i < PANNUM); i++) { + QString mp = iname; + nm.setNum(i+1); + mp += nm; + QVBox *page = addVBoxPage(mp); + pn[i] = new pdUpdateLoc(page, i, inter, label, + numberLines, + filter, packMsg, baseMsg, subdirs); + } + numPanels += numberDirs; +} + +void Locations::cLocations(int numberDirs, int numberLines, + pkgInterface *inter, const QString &iname, const QString &label, + const QString &boxLables, const QString &baseMsg, const QString &boxValues) +{ + QString nm; + + for (int i = numPanels; (i < numPanels + numberDirs) && (i < PANNUM); i++) { + QString mp = iname; + nm.setNum(i+1); + mp += nm; + QVBox *page = addVBoxPage(mp); + pn[i] = new cUpdateLoc(page, i, inter, label, + numberLines, baseMsg, + boxLables, boxValues); + } + numPanels += numberDirs; +} + +void Locations::aLocations(int numberDirs, int numberLines, + pkgInterface *inter, const QString &iname, const QString &label) +{ + QString nm; + + for (int i = numPanels; (i < numPanels + numberDirs) && (i < PANNUM); i++) { + QString mp = iname; + nm.setNum(i+1); + mp += nm; + QVBox *page = addVBoxPage(mp); + pn[i] = new aUpdateLoc(page, i, inter, iname, + numberLines, label); + } + numPanels += numberDirs; +} + +Locations::~Locations() { + // for (int i = 0; (i < numPanels) && (i < PANNUM) && pn[i]; i++) { + // delete pn[i]; + // } +} + +void Locations::restore() +{ + for (int i = 0; (i < numPanels) && (i < PANNUM); i++) { + pn[i]->readSettings(); + } + show(); +} + +void Locations::apply_slot() +{ + LcacheObj *slist = new LcacheObj(); + + for (int i = 0; (i < numPanels) && (i < PANNUM); i++) { + pn[i]->applyS(slist); + } + emit returnVal(slist); +} + +void Locations::write_slot() +{ + apply_slot(); + + for (int i = 0; (i < numPanels) && (i < PANNUM); i++) { + pn[i]->writeSettings(); + } +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +#include "updateLoc.moc" diff --git a/kpackage/updateLoc.h b/kpackage/updateLoc.h new file mode 100644 index 0000000..269bf74 --- /dev/null +++ b/kpackage/updateLoc.h @@ -0,0 +1,326 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + + + +#ifndef DEBLOCATE_H +#define DEBLOCATE_H + +#include "../config.h" + +// Standard Headers +#include <stdio.h> + +// Qt Headers +#include <qdir.h> +#include <qwidget.h> +#include <qframe.h> +#include <qlabel.h> +#include <qfiledialog.h> +#include <qgroupbox.h> +#include <qcheckbox.h> +#include <qlayout.h> +#include <qlineedit.h> + +// KDE headers +#include <kbuttonbox.h> +#include <kdialogbase.h> + +class pkgInterface; +class updateLoc; +class cacheObj; +class LcacheObj; +class KComboBox; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +class dpanel : public QWidget +{ + Q_OBJECT + +public: + dpanel(QWidget *parent, const char * name = 0); + dpanel(dpanel *basep, const QString &Pfilter, bool bsubdirs, + QWidget *parent, const char * name = 0); + ~dpanel(); + + + QString getText() const; + void setText(const QString &s); + bool getUse() const; + void setUse(int n); + bool getSubdirs() const; + void setSubdirs(int n); + +private: + + QCheckBox *psubdirs; + QCheckBox *puse; + QHBoxLayout* pack; + QLineEdit *pent; + QPushButton *pbut; + + dpanel *base; + QString filter; + + public slots: + void fileOpen(); + void dirOpen(); + +}; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +class apanel : public QWidget +{ + Q_OBJECT + +public: + apanel( QWidget *parent, const char * name = 0 ); + ~apanel(); + + + QString getText() const; + void setText(const QString &s); + bool getUse(); + void setUse(int n); + void clear(); + +private: + + QCheckBox *puse; + QHBoxLayout* pack; + QLineEdit *pent; + + + + public slots: + +}; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +class updateLoc : public QWidget +{ + Q_OBJECT + +public: + + updateLoc (QWidget *p, int panelNumber, pkgInterface *inter, const QString &iname); + ~updateLoc(); + + virtual void readSettings() = 0; + virtual void writeSettings() = 0; + + virtual void applyS(LcacheObj *slist) = 0; + + void doBase(const QString &bmsg); + + QString interName; + int panNumber; + + bool haveBase; + + pkgInterface *interface; + + QVBoxLayout *vf; + dpanel *base; + + QGroupBox *fbase; + QVBoxLayout* vbase; +}; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +class aUpdateLoc : public updateLoc +{ + Q_OBJECT + +public: + + aUpdateLoc (QWidget *p, int panelNumber, pkgInterface *inter, const QString &iname, + int numberLines, const QString &label); + ~aUpdateLoc(); + + + void readSettings(); + void writeSettings(); + + void applyS(LcacheObj *slist); + +private: + + QString packL, packU, packS, availB; + + int wdth; + + QPushButton *butloc; + + QHBoxLayout* hloc; + + int numLines; + enum { PNUM = 100 }; + apanel *ap[PNUM]; + + QVBoxLayout* vl; + QVBoxLayout* vtop; + QGroupBox *frame1; + KButtonBox* hb; + +}; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +class pdUpdateLoc : public updateLoc +{ + Q_OBJECT + +public: + + pdUpdateLoc (QWidget *p, int panelNumber, pkgInterface *inter, + const QString &iname, int numberLines, const QString &filter, + const QString &lmsg, QString bmsg = 0, + bool subdirs = FALSE); + ~pdUpdateLoc(); + + + void readSettings(); + void writeSettings(); + + void applyS(LcacheObj *slist); + +private: + + QString packL, packU, packS, availB; + + int wdth; + + QPushButton *butloc; + + QHBoxLayout* hloc; + + int numLines; + enum { PNUM = 40 }; + dpanel *dp[PNUM]; + + QVBoxLayout* vl; + QVBoxLayout* vtop; + QGroupBox *frame1; + KButtonBox* hb; + +}; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +class cUpdateLoc : public updateLoc +{ + Q_OBJECT + +public: + + cUpdateLoc (QWidget *p, int panelNumber, pkgInterface *inter, + const QString &iname, int numberLines, const QString &baseMsg, + const QString &boxLabels, const QString &boxValues); + ~cUpdateLoc(); + + + void readSettings(); + void writeSettings(); + + void applyS(LcacheObj *slist); + +private: + + QString packC, availB; + + QPushButton *butloc; + + QHBoxLayout* hloc; + + int numLines; + enum { PNUM = 40 }; + KComboBox *combo[PNUM]; + + QVBoxLayout* vl; + QVBoxLayout* vtop; + QGroupBox *frame1; + KButtonBox* hb; + + + +}; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +class Locations : public KDialogBase +{ + Q_OBJECT + +public: + Locations( const QString &msg); + ~Locations(); + + void dLocations(int numberDirs, int numberLines, + pkgInterface *inter, const QString &iname, + const QString &label, const QString &filter, const QString &dirMsg, + bool subdirs=TRUE ); + + void pLocations(int numberDirs, int numberLines, + pkgInterface *inter, const QString &iname, + const QString &label, const QString &filter, + const QString &packMsg, QString baseMsg = 0, + bool subdirs=FALSE); + + void cLocations(int numberDirs, int numberLines, + pkgInterface *inter, const QString &iname, const QString &label, + const QString &boxLabels, const QString &baseMsg, const QString &boxValues); + + void aLocations(int numberDirs, int numberLines, + pkgInterface *inter, const QString &iname, const QString &label); + + + + // bmsg indicates the panel has a base entry + void restore(); + + int numPanels; + enum { PANNUM = 10 }; + updateLoc *pn[PANNUM]; + +public slots: + void apply_slot(); + void write_slot(); + +signals: + void returnVal(LcacheObj *); + +}; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +#endif diff --git a/kpackage/utils.cpp b/kpackage/utils.cpp new file mode 100644 index 0000000..4f0ef44 --- /dev/null +++ b/kpackage/utils.cpp @@ -0,0 +1,63 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#include "../config.h" +#include <kpackage.h> +#include <kmessagebox.h> +#include <klocale.h> + +#include "utils.h" +#include "kplview.h" + +void KpMsgE( const QString &msg, bool stop) +{ + KpMsg( "Error", msg, stop); +} + +void KpMsg(const QString &lab, const QString &msg, bool stop) +{ + if (stop) + KMessageBox::sorry(kpkg, msg, lab); + else + KMessageBox::information(kpkg, msg, lab); +} + +KpTreeListItem *findGroup(const QString &name, KpTreeListItem *search) +{ + if(!search) + return NULL; + + do { + if (name == search->text(0)) { + return search; + } + } while( (search=search->nextSibling()) != NULL); + + return NULL; +} + + + diff --git a/kpackage/utils.h b/kpackage/utils.h new file mode 100644 index 0000000..5cf30d9 --- /dev/null +++ b/kpackage/utils.h @@ -0,0 +1,39 @@ +/* +** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au> +** +*/ + +/* +** 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 +*/ + +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#include "../config.h" +#include <string.h> +#include <klistview.h> + +class KpTreeListItem; + +KpTreeListItem *findGroup(const QString &name, KpTreeListItem *search); + +#endif + |