summaryrefslogtreecommitdiffstats
path: root/kpackage
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit37333bf25ad9a4c538250f5af2f9f1d666362883 (patch)
treec45e8df5b9efbffe07eb3d9340df7811c7e16943 /kpackage
downloadtdeadmin-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')
-rw-r--r--kpackage/CHANGES282
-rw-r--r--kpackage/Makefile.am36
-rw-r--r--kpackage/README11
-rw-r--r--kpackage/cache.cpp229
-rw-r--r--kpackage/cache.h114
-rw-r--r--kpackage/debAptInterface.cpp535
-rw-r--r--kpackage/debAptInterface.h84
-rw-r--r--kpackage/debDpkgInterface.cpp164
-rw-r--r--kpackage/debDpkgInterface.h65
-rw-r--r--kpackage/debInterface.cpp596
-rw-r--r--kpackage/debInterface.h112
-rw-r--r--kpackage/fbsdInterface.cpp641
-rw-r--r--kpackage/fbsdInterface.h158
-rw-r--r--kpackage/findf.cpp228
-rw-r--r--kpackage/findf.h91
-rw-r--r--kpackage/gentooInterface.cpp466
-rw-r--r--kpackage/gentooInterface.h68
-rw-r--r--kpackage/icon/Makefile.am1
-rw-r--r--kpackage/icon/hi128-app-kpackage.pngbin0 -> 16495 bytes
-rw-r--r--kpackage/icon/hi16-app-kpackage.pngbin0 -> 885 bytes
-rw-r--r--kpackage/icon/hi22-app-kpackage.pngbin0 -> 1545 bytes
-rw-r--r--kpackage/icon/hi32-app-kpackage.pngbin0 -> 2547 bytes
-rw-r--r--kpackage/icon/hi48-app-kpackage.pngbin0 -> 4630 bytes
-rw-r--r--kpackage/icon/hi64-app-kpackage.pngbin0 -> 6757 bytes
-rw-r--r--kpackage/kio.cpp124
-rw-r--r--kpackage/kio.h75
-rw-r--r--kpackage/kissInterface.cpp422
-rw-r--r--kpackage/kissInterface.h87
-rw-r--r--kpackage/kpPty.cpp446
-rw-r--r--kpackage/kpPty.h106
-rw-r--r--kpackage/kpTerm.cpp234
-rw-r--r--kpackage/kpTerm.h90
-rw-r--r--kpackage/kpackage.cpp759
-rw-r--r--kpackage/kpackage.desktop101
-rw-r--r--kpackage/kpackage.h336
-rw-r--r--kpackage/kpackageui.rc60
-rw-r--r--kpackage/kplview.cpp667
-rw-r--r--kpackage/kplview.h191
-rw-r--r--kpackage/main.cpp159
-rw-r--r--kpackage/managementWidget.cpp699
-rw-r--r--kpackage/managementWidget.h227
-rw-r--r--kpackage/mini-icon/cr16-mime-debfile.pngbin0 -> 594 bytes
-rw-r--r--kpackage/mini-icon/cr16-mime-rpmfile.pngbin0 -> 567 bytes
-rw-r--r--kpackage/options.cpp469
-rw-r--r--kpackage/options.h181
-rw-r--r--kpackage/packageDisplay.cpp439
-rw-r--r--kpackage/packageDisplay.h164
-rw-r--r--kpackage/packageInfo.cpp635
-rw-r--r--kpackage/packageInfo.h165
-rw-r--r--kpackage/packageProperties.cpp278
-rw-r--r--kpackage/packageProperties.h103
-rw-r--r--kpackage/pics/Makefile.am6
-rw-r--r--kpackage/pics/bnew.pngbin0 -> 174 bytes
-rw-r--r--kpackage/pics/bsd.pngbin0 -> 241 bytes
-rw-r--r--kpackage/pics/bupdated.pngbin0 -> 154 bytes
-rw-r--r--kpackage/pics/cross.pngbin0 -> 817 bytes
-rw-r--r--kpackage/pics/dbad.pngbin0 -> 162 bytes
-rw-r--r--kpackage/pics/deb.pngbin0 -> 358 bytes
-rw-r--r--kpackage/pics/dnew.pngbin0 -> 176 bytes
-rw-r--r--kpackage/pics/dupdated.pngbin0 -> 159 bytes
-rw-r--r--kpackage/pics/kiss.pngbin0 -> 379 bytes
-rw-r--r--kpackage/pics/knew.pngbin0 -> 183 bytes
-rw-r--r--kpackage/pics/kupdated.pngbin0 -> 165 bytes
-rw-r--r--kpackage/pics/noball.pngbin0 -> 126 bytes
-rw-r--r--kpackage/pics/ptick.pngbin0 -> 578 bytes
-rw-r--r--kpackage/pics/question.pngbin0 -> 165 bytes
-rw-r--r--kpackage/pics/rnew.pngbin0 -> 173 bytes
-rw-r--r--kpackage/pics/rpm.pngbin0 -> 325 bytes
-rw-r--r--kpackage/pics/rupdated.pngbin0 -> 160 bytes
-rw-r--r--kpackage/pics/slack.pngbin0 -> 301 bytes
-rw-r--r--kpackage/pics/snew.pngbin0 -> 171 bytes
-rw-r--r--kpackage/pics/supdated.pngbin0 -> 154 bytes
-rw-r--r--kpackage/pics/tick.pngbin0 -> 578 bytes
-rw-r--r--kpackage/pkgInterface.cpp435
-rw-r--r--kpackage/pkgInterface.h220
-rw-r--r--kpackage/pkgOptions.cpp372
-rw-r--r--kpackage/pkgOptions.h151
-rw-r--r--kpackage/procbuf.cpp165
-rw-r--r--kpackage/procbuf.h68
-rw-r--r--kpackage/rpmInterface.cpp631
-rw-r--r--kpackage/rpmInterface.h111
-rw-r--r--kpackage/search.cpp115
-rw-r--r--kpackage/search.h69
-rw-r--r--kpackage/slackInterface.cpp691
-rw-r--r--kpackage/slackInterface.h92
-rw-r--r--kpackage/toolbar/Makefile.am2
-rw-r--r--kpackage/toolbar/ftin.xpm24
-rw-r--r--kpackage/toolbar/ftout.xpm24
-rw-r--r--kpackage/updateLoc.cpp761
-rw-r--r--kpackage/updateLoc.h326
-rw-r--r--kpackage/utils.cpp63
-rw-r--r--kpackage/utils.h39
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
new file mode 100644
index 0000000..8277291
--- /dev/null
+++ b/kpackage/icon/hi128-app-kpackage.png
Binary files differ
diff --git a/kpackage/icon/hi16-app-kpackage.png b/kpackage/icon/hi16-app-kpackage.png
new file mode 100644
index 0000000..fc716d0
--- /dev/null
+++ b/kpackage/icon/hi16-app-kpackage.png
Binary files differ
diff --git a/kpackage/icon/hi22-app-kpackage.png b/kpackage/icon/hi22-app-kpackage.png
new file mode 100644
index 0000000..b89a591
--- /dev/null
+++ b/kpackage/icon/hi22-app-kpackage.png
Binary files differ
diff --git a/kpackage/icon/hi32-app-kpackage.png b/kpackage/icon/hi32-app-kpackage.png
new file mode 100644
index 0000000..b938d97
--- /dev/null
+++ b/kpackage/icon/hi32-app-kpackage.png
Binary files differ
diff --git a/kpackage/icon/hi48-app-kpackage.png b/kpackage/icon/hi48-app-kpackage.png
new file mode 100644
index 0000000..4f629ea
--- /dev/null
+++ b/kpackage/icon/hi48-app-kpackage.png
Binary files differ
diff --git a/kpackage/icon/hi64-app-kpackage.png b/kpackage/icon/hi64-app-kpackage.png
new file mode 100644
index 0000000..2053a1e
--- /dev/null
+++ b/kpackage/icon/hi64-app-kpackage.png
Binary files differ
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>&amp;File</text>
+ <Action name="pack_find" />
+ <Action name="pack_findf" />
+ <Separator/>
+ <Action name="kpack_reload" />
+</Menu>
+
+<Menu name="packages" >
+ <text>&amp;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>&amp;Cache</text>
+ <Action name="clear_dcache" />
+ <Action name="clear_pcache" />
+</Menu>
+
+<Menu name="special" >
+ <text>Spe&amp;cial</text>
+ <Menu name="debapt" >
+ <text>&amp;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>&amp;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
new file mode 100644
index 0000000..35c3b4e
--- /dev/null
+++ b/kpackage/mini-icon/cr16-mime-debfile.png
Binary files differ
diff --git a/kpackage/mini-icon/cr16-mime-rpmfile.png b/kpackage/mini-icon/cr16-mime-rpmfile.png
new file mode 100644
index 0000000..27fa032
--- /dev/null
+++ b/kpackage/mini-icon/cr16-mime-rpmfile.png
Binary files differ
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("<"),"&lt;");
+ f.replace(QRegExp(">"),"&gt;");
+ }
+ 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("<"),"&lt;");
+}
+
+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
new file mode 100644
index 0000000..0a70e91
--- /dev/null
+++ b/kpackage/pics/bnew.png
Binary files differ
diff --git a/kpackage/pics/bsd.png b/kpackage/pics/bsd.png
new file mode 100644
index 0000000..92b0b88
--- /dev/null
+++ b/kpackage/pics/bsd.png
Binary files differ
diff --git a/kpackage/pics/bupdated.png b/kpackage/pics/bupdated.png
new file mode 100644
index 0000000..2d733d6
--- /dev/null
+++ b/kpackage/pics/bupdated.png
Binary files differ
diff --git a/kpackage/pics/cross.png b/kpackage/pics/cross.png
new file mode 100644
index 0000000..748afec
--- /dev/null
+++ b/kpackage/pics/cross.png
Binary files differ
diff --git a/kpackage/pics/dbad.png b/kpackage/pics/dbad.png
new file mode 100644
index 0000000..89b70c4
--- /dev/null
+++ b/kpackage/pics/dbad.png
Binary files differ
diff --git a/kpackage/pics/deb.png b/kpackage/pics/deb.png
new file mode 100644
index 0000000..7c5ac7f
--- /dev/null
+++ b/kpackage/pics/deb.png
Binary files differ
diff --git a/kpackage/pics/dnew.png b/kpackage/pics/dnew.png
new file mode 100644
index 0000000..85cb602
--- /dev/null
+++ b/kpackage/pics/dnew.png
Binary files differ
diff --git a/kpackage/pics/dupdated.png b/kpackage/pics/dupdated.png
new file mode 100644
index 0000000..f807221
--- /dev/null
+++ b/kpackage/pics/dupdated.png
Binary files differ
diff --git a/kpackage/pics/kiss.png b/kpackage/pics/kiss.png
new file mode 100644
index 0000000..40956ae
--- /dev/null
+++ b/kpackage/pics/kiss.png
Binary files differ
diff --git a/kpackage/pics/knew.png b/kpackage/pics/knew.png
new file mode 100644
index 0000000..1b49daa
--- /dev/null
+++ b/kpackage/pics/knew.png
Binary files differ
diff --git a/kpackage/pics/kupdated.png b/kpackage/pics/kupdated.png
new file mode 100644
index 0000000..bc1b90b
--- /dev/null
+++ b/kpackage/pics/kupdated.png
Binary files differ
diff --git a/kpackage/pics/noball.png b/kpackage/pics/noball.png
new file mode 100644
index 0000000..0e9fbe4
--- /dev/null
+++ b/kpackage/pics/noball.png
Binary files differ
diff --git a/kpackage/pics/ptick.png b/kpackage/pics/ptick.png
new file mode 100644
index 0000000..7f8c315
--- /dev/null
+++ b/kpackage/pics/ptick.png
Binary files differ
diff --git a/kpackage/pics/question.png b/kpackage/pics/question.png
new file mode 100644
index 0000000..e6c809d
--- /dev/null
+++ b/kpackage/pics/question.png
Binary files differ
diff --git a/kpackage/pics/rnew.png b/kpackage/pics/rnew.png
new file mode 100644
index 0000000..2b44ca3
--- /dev/null
+++ b/kpackage/pics/rnew.png
Binary files differ
diff --git a/kpackage/pics/rpm.png b/kpackage/pics/rpm.png
new file mode 100644
index 0000000..8437a8f
--- /dev/null
+++ b/kpackage/pics/rpm.png
Binary files differ
diff --git a/kpackage/pics/rupdated.png b/kpackage/pics/rupdated.png
new file mode 100644
index 0000000..b570636
--- /dev/null
+++ b/kpackage/pics/rupdated.png
Binary files differ
diff --git a/kpackage/pics/slack.png b/kpackage/pics/slack.png
new file mode 100644
index 0000000..f46fb11
--- /dev/null
+++ b/kpackage/pics/slack.png
Binary files differ
diff --git a/kpackage/pics/snew.png b/kpackage/pics/snew.png
new file mode 100644
index 0000000..0043371
--- /dev/null
+++ b/kpackage/pics/snew.png
Binary files differ
diff --git a/kpackage/pics/supdated.png b/kpackage/pics/supdated.png
new file mode 100644
index 0000000..c608b55
--- /dev/null
+++ b/kpackage/pics/supdated.png
Binary files differ
diff --git a/kpackage/pics/tick.png b/kpackage/pics/tick.png
new file mode 100644
index 0000000..7f8c315
--- /dev/null
+++ b/kpackage/pics/tick.png
Binary files differ
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> &params)
+{
+ 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> &params);
+ // 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
+