summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/settings/packagemanager/ChangeLog3
-rw-r--r--noncore/settings/packagemanager/oipkg.cpp2
-rw-r--r--noncore/settings/packagemanager/opackagemanager.cpp101
-rw-r--r--noncore/settings/packagemanager/opackagemanager.h3
-rw-r--r--noncore/settings/packagemanager/opie-packagemanager.control2
-rw-r--r--noncore/settings/packagemanager/promptdlg.cpp2
6 files changed, 103 insertions, 10 deletions
diff --git a/noncore/settings/packagemanager/ChangeLog b/noncore/settings/packagemanager/ChangeLog
index 6ad724f..d53a2b3 100644
--- a/noncore/settings/packagemanager/ChangeLog
+++ b/noncore/settings/packagemanager/ChangeLog
@@ -1,25 +1,28 @@
2004-02-13 Dan Williams <drw@handhelds.org>
+ * Released version 0.3.0
* Fix handling of filtering options in View menu
+ * Do proper version string comparison
+ * Fix string alignment code in PromptDlg to eliminate QT warning messages
2004-02-12 Dan Williams <drw@handhelds.org>
* Package information dialog implemented
* What's This app icon enabled
* Changed all QDialog::exec() occurences to QPEApplication::execDialog()
2004-01-23 Dan Williams <drw@handhelds.org>
* Added package download functionality
* Have Opie update links after install/removal so that apps
will display properly in Launcher
2004-01-20 Dan Williams <drw@handhelds.org>
* Released version 0.2.0
* Converted to use libipkg in place of spawning ipkg process
2004-01-13 Dan Williams <drw@handhelds.org>
* Released version 0.1.0
* Initial check-in of new package management client to eventually replace AQPkg
diff --git a/noncore/settings/packagemanager/oipkg.cpp b/noncore/settings/packagemanager/oipkg.cpp
index eb07a61..086e91b 100644
--- a/noncore/settings/packagemanager/oipkg.cpp
+++ b/noncore/settings/packagemanager/oipkg.cpp
@@ -1,456 +1,454 @@
/*
                This file is part of the Opie Project
              Copyright (c) 2003 Dan Williams <drw@handhelds.org>
=.
.=l.
           .>+-=
 _;:,     .>    :=|. This program is free software; you can
.> <`_,   >  .   <= redistribute it and/or modify it under
:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
.="- .-=="i,     .._ License as published by the Free Software
 - .   .-<_>     .<> Foundation; either version 2 of the License,
     ._= =}       : or (at your option) any later version.
    .%`+i>       _;_.
    .i_,=:_.      -<s. 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
..}^=.=       =       ; Library General Public License for more
++=   -.     .`     .: details.
 :     =  ...= . :.=-
 -.   .:....=;==+<; You should have received a copy of the GNU
  -_. . .   )=.  = Library General Public License along with
    --        :-=` this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "oipkg.h"
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <qdir.h>
#include <qfile.h>
#include <qmessagebox.h>
#include <qtextstream.h>
const QString IPKG_CONF = "/etc/ipkg.conf"; // Fully-qualified name of Ipkg primary configuration file
const QString IPKG_CONF_DIR = "/etc/ipkg"; // Directory of secondary Ipkg configuration files
const QString IPKG_PKG_PATH = "/usr/lib/ipkg/lists"; // Directory containing server package lists
const QString IPKG_STATUS_PATH = "usr/lib/ipkg/status"; // Destination status file location
OIpkg *oipkg;
// Ipkg callback functions
int fsignalIpkgMessage( ipkg_conf_t */*conf*/, message_level_t /*level*/, char *msg )
{
oipkg->ipkgMessage( msg );
return 0;
}
char *fIpkgResponse( char */*question*/ )
{
return 0x0;
}
int fIpkgStatus( char */*name*/, int /*status*/, char *desc, void */*userdata*/ )
{
oipkg->ipkgStatus( desc );
return 0;
}
int fIpkgFiles( char */*name*/, char *desc, char */*version*/, pkg_state_status_t /*status*/,
void */*userdata*/ )
{
-printf( "*****List*****\n%s\n", desc );
oipkg->ipkgList( desc );
return 0;
}
OIpkg::OIpkg( Config *config, QObject *parent, const char *name )
: QObject( parent, name )
, m_config( config )
, m_confInfo( NULL )
, m_ipkgExecOptions( 0 )
, m_ipkgExecVerbosity( 1 )
{
oipkg = this;
// Initialize libipkg
if ( ipkg_init( &fsignalIpkgMessage, &fIpkgResponse, &m_ipkgArgs ) )
QMessageBox::critical( 0, tr( "OIpkg" ), tr( "Error initialing libipkg" ) );
// Default ipkg run-time arguments
m_ipkgArgs.noaction = false;
m_ipkgArgs.force_defaults = true;
}
OIpkg::~OIpkg()
{
// Upon destruction, ensure that items in config list are deleted with list
if ( m_confInfo )
m_confInfo->setAutoDelete( true );
// Free up libipkg resources
if ( ipkg_deinit( &m_ipkgArgs ) )
QMessageBox::critical( 0, tr( "OIpkg" ), tr( "Error freeing libipkg" ) );
}
OConfItemList *OIpkg::configItems()
{
// Retrieve all configuration items
return filterConfItems();
}
OConfItemList *OIpkg::servers()
{
// Retrieve only servers
return filterConfItems( OConfItem::Source );
}
OConfItemList *OIpkg::destinations()
{
// Retrieve only destinations
return filterConfItems( OConfItem::Destination );
}
OConfItemList *OIpkg::options()
{
// Retrieve only destinations
return filterConfItems( OConfItem::Option );
}
void OIpkg::setConfigItems( OConfItemList *configList )
{
if ( m_confInfo )
delete m_confInfo;
m_confInfo = configList;
}
void OIpkg::saveSettings()
{
// Save Ipkg execution options to application configuration file
if ( m_config )
{
m_config->setGroup( "Ipkg" );
m_config->writeEntry( "ExecOptions", m_ipkgExecOptions );
m_config->writeEntry( "Verbosity", m_ipkgExecVerbosity );
}
}
OPackageList *OIpkg::availablePackages( const QString &server )
{
// Load Ipkg configuration info if not already cached
if ( !m_confInfo )
loadConfiguration();
// Build new server list (caller is responsible for deleting)
OPackageList *pl = new OPackageList;
// Open package list file
QFile f( IPKG_PKG_PATH + "/" + server );
if ( !f.open( IO_ReadOnly ) )
return NULL;
QTextStream t( &f );
// Process all information in package list file
OPackage *package = NULL;
QString line = t.readLine();
while ( !t.eof() )
{
// Determine key/value pair
int pos = line.find( ':', 0 );
QString key;
if ( pos > -1 )
key = line.mid( 0, pos );
else
key = QString::null;
QString value = line.mid( pos+2, line.length()-pos );
// Allocate new package and insert into list
if ( package == NULL && !key.isEmpty() )
{
package = new OPackage( value );
package->setSource( server );
pl->append( package );
}
// Update package data
if ( key == "Package" )
package->setName( value );
else if ( key == "Version" )
package->setVersion( value );
else if ( key == "Section" )
package->setCategory( value );
//DataManager::setAvailableCategories( value );
else if ( key.isEmpty() && value.isEmpty() )
package = NULL;
// Skip past all description lines
if ( key == "Description" )
{
line = t.readLine();
while ( !line.isEmpty() && line.find( ':', 0 ) == -1 && !t.eof() )
line = t.readLine();
}
else
line = t.readLine();
}
f.close();
return pl;
}
OPackageList *OIpkg::installedPackages( const QString &destName, const QString &destPath )
{
// Load Ipkg configuration info if not already cached
if ( !m_confInfo )
loadConfiguration();
// Build new server list (caller is responsible for deleting)
OPackageList *pl = new OPackageList;
// Open status file
QString path = destPath;
if ( path.right( 1 ) != "/" )
path.append( "/" );
path.append( IPKG_STATUS_PATH );
QFile f( path );
if ( !f.open( IO_ReadOnly ) )
return NULL;
QTextStream t( &f );
// Process all information in status file
bool newPackage = false;
QString line = t.readLine();
QString name;
QString version;
QString status;
while ( !t.eof() )
{
// Determine key/value pair
int pos = line.find( ':', 0 );
QString key;
if ( pos > -1 )
key = line.mid( 0, pos );
else
key = QString::null;
QString value = line.mid( pos+2, line.length()-pos );
// Allocate new package and insert into list
if ( newPackage && !key.isEmpty() )
{
// Add to list only if it has a valid name and is installed
if ( !name.isNull() && status.contains( " installed" ) )
{
pl->append( new OPackage( name, QString::null, version, QString::null, destName ) );
name = QString::null;
version = QString::null;
status = QString::null;
newPackage = false;
}
}
// Update package data
if ( key == "Package" )
name = value;
else if ( key == "Version" )
version = value;
else if ( key == "Status" )
status = value;
else if ( key.isEmpty() && value.isEmpty() )
newPackage = true;
// Skip past all description lines
if ( key == "Description" )
{
line = t.readLine();
while ( !line.isEmpty() && line.find( ':', 0 ) == -1 && !t.eof() )
line = t.readLine();
}
else
line = t.readLine();
}
f.close();
return pl;
}
bool OIpkg::executeCommand( OPackage::Command command, QStringList *parameters, const QString &destination,
const QObject *receiver, const char *slotOutput, bool rawOutput )
{
if ( command == OPackage::NotDefined )
return false;
// Set ipkg run-time options/arguments
m_ipkgArgs.force_depends = ( m_ipkgExecOptions & FORCE_DEPENDS );
m_ipkgArgs.force_reinstall = ( m_ipkgExecOptions & FORCE_REINSTALL );
// TODO m_ipkgArgs.force_remove = ( m_ipkgExecOptions & FORCE_REMOVE );
m_ipkgArgs.force_overwrite = ( m_ipkgExecOptions & FORCE_OVERWRITE );
m_ipkgArgs.verbosity = m_ipkgExecVerbosity;
if ( m_ipkgArgs.dest )
free( m_ipkgArgs.dest );
if ( !destination.isNull() )
{
int len = destination.length() + 1;
m_ipkgArgs.dest = (char *)malloc( len );
strncpy( m_ipkgArgs.dest, destination, destination.length() );
m_ipkgArgs.dest[ len - 1 ] = '\0';
}
else
m_ipkgArgs.dest = 0x0;
// Connect output signal to widget
if ( rawOutput )
{
// if ( slotOutput )
// connect( this, SIGNAL(signalIpkgMessage(char *)), receiver, slotOutput );
}
else
{
// TODO - connect to local slot and parse output before emitting signalIpkgMessage
}
switch( command )
{
case OPackage::Update : {
connect( this, SIGNAL(signalIpkgMessage(char *)), receiver, slotOutput );
ipkg_lists_update( &m_ipkgArgs );
};
break;
case OPackage::Upgrade : {
connect( this, SIGNAL(signalIpkgMessage(char *)), receiver, slotOutput );
ipkg_packages_upgrade( &m_ipkgArgs );
};
break;
case OPackage::Install : {
connect( this, SIGNAL(signalIpkgMessage(char *)), receiver, slotOutput );
for ( QStringList::Iterator it = parameters->begin(); it != parameters->end(); ++it )
{
ipkg_packages_install( &m_ipkgArgs, (*it) );
}
};
break;
case OPackage::Remove : {
connect( this, SIGNAL(signalIpkgMessage(char *)), receiver, slotOutput );
for ( QStringList::Iterator it = parameters->begin(); it != parameters->end(); ++it )
{
ipkg_packages_remove( &m_ipkgArgs, (*it), true );
}
};
break;
case OPackage::Download : {
connect( this, SIGNAL(signalIpkgMessage(char *)), receiver, slotOutput );
for ( QStringList::Iterator it = parameters->begin(); it != parameters->end(); ++it )
{
ipkg_packages_download( &m_ipkgArgs, (*it) );
}
};
break;
case OPackage::Info : {
connect( this, SIGNAL(signalIpkgStatus(char *)), receiver, slotOutput );
ipkg_packages_info( &m_ipkgArgs, (*parameters->begin()), &fIpkgStatus, 0x0 );
};
break;
case OPackage::Files : {
connect( this, SIGNAL(signalIpkgList(char *)), receiver, slotOutput );
ipkg_package_files( &m_ipkgArgs, (*parameters->begin()), &fIpkgFiles, 0x0 );
};
break;
default : break;
};
return true;
}
void OIpkg::ipkgMessage( char *msg )
{
emit signalIpkgMessage( msg );
}
void OIpkg::ipkgStatus( char *status )
{
emit signalIpkgStatus( status );
}
void OIpkg::ipkgList( char *filelist )
{
emit signalIpkgList( filelist );
}
void OIpkg::loadConfiguration()
{
if ( m_confInfo )
delete m_confInfo;
// Load configuration item list
m_confInfo = new OConfItemList();
QStringList confFiles;
QDir confDir( IPKG_CONF_DIR );
if ( confDir.exists() )
{
confDir.setNameFilter( "*.conf" );
confDir.setFilter( QDir::Files );
confFiles = confDir.entryList( "*.conf", QDir::Files );
confFiles << IPKG_CONF;
for ( QStringList::Iterator it = confFiles.begin(); it != confFiles.end(); ++it )
{
// Create absolute file path if necessary
QString absFile = (*it);
if ( !absFile.startsWith( "/" ) )
absFile.prepend( QString( IPKG_CONF_DIR ) + "/" );
// Read in file
QFile f( absFile );
if ( f.open( IO_ReadOnly ) )
{
QTextStream s( &f );
while ( !s.eof() )
{
QString line = s.readLine().simplifyWhiteSpace();
// Parse line and save info to the conf options list
if ( !line.isEmpty() )
{
if ( !line.startsWith( "#" ) ||
line.startsWith( "#src" ) ||
line.startsWith( "#dest" ) ||
line.startsWith( "#arch" ) ||
line.startsWith( "#option" ) )
{
int pos = line.find( ' ', 1 );
// Type
QString typeStr = line.left( pos );
OConfItem::Type type;
if ( typeStr == "src" || typeStr == "#src" )
type = OConfItem::Source;
else if ( typeStr == "dest" || typeStr == "#dest" )
type = OConfItem::Destination;
else if ( typeStr == "option" || typeStr == "#option" )
type = OConfItem::Option;
else if ( typeStr == "arch" || typeStr == "#arch" )
type = OConfItem::Arch;
else
type = OConfItem::NotDefined;
++pos;
int endpos = line.find( ' ', pos );
// Name
diff --git a/noncore/settings/packagemanager/opackagemanager.cpp b/noncore/settings/packagemanager/opackagemanager.cpp
index ad2fe02..3633e05 100644
--- a/noncore/settings/packagemanager/opackagemanager.cpp
+++ b/noncore/settings/packagemanager/opackagemanager.cpp
@@ -1,323 +1,412 @@
/*
                This file is part of the Opie Project
              Copyright (c) 2003 Dan Williams <drw@handhelds.org>
=.
.=l.
           .>+-=
 _;:,     .>    :=|. This program is free software; you can
.> <`_,   >  .   <= redistribute it and/or modify it under
:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
.="- .-=="i,     .._ License as published by the Free Software
 - .   .-<_>     .<> Foundation; either version 2 of the License,
     ._= =}       : or (at your option) any later version.
    .%`+i>       _;_.
    .i_,=:_.      -<s. 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
..}^=.=       =       ; Library General Public License for more
++=   -.     .`     .: details.
 :     =  ...= . :.=-
 -.   .:....=;==+<; You should have received a copy of the GNU
  -_. . .   )=.  = Library General Public License along with
    --        :-=` this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
+#include <ctype.h>
+
#include <qpe/qpeapplication.h>
#include "opackagemanager.h"
#include "oipkgconfigdlg.h"
OPackageManager::OPackageManager( Config *config, QObject *parent, const char *name )
: QObject( parent, name )
, m_config( config )
, m_ipkg( m_config, this )
, m_packages( 9973 )
, m_categories()
{
m_packages.setAutoDelete( true );
}
void OPackageManager::loadAvailablePackages()
{
m_packages.clear();
OConfItemList *serverList = m_ipkg.servers();
if ( serverList )
{
// Initialize status messaging
emit initStatus( serverList->count() );
int serverCount = 0;
bool categoryAdded = false;
for ( OConfItemListIterator serverIt( *serverList ); serverIt.current(); ++serverIt )
{
OConfItem *server = serverIt.current();
// Process server only if it is active
if ( server->active() )
{
// Update status
QString status = tr( "Reading available packages:\n\t" );
status.append( server->name() );
emit statusText( status );
++serverCount;
emit statusBar( serverCount );
qApp->processEvents();
OPackageList *packageList = m_ipkg.availablePackages( server->name() );
if ( packageList )
{
for ( OPackageListIterator packageIt( *packageList ); packageIt.current(); ++packageIt )
{
OPackage *package = packageIt.current();
// Load package info
if ( !m_packages.find( package->name() ) )
m_packages.insert( package->name(), package );
else
{
// If new package is newer version, replace existing package
OPackage *currPackage = m_packages[package->name()];
if ( compareVersions( package->version(), currPackage->version() ) == 1 )
m_packages.replace( package->name(), package );
}
// Add category to list if it doesn't already exist
if ( m_categories.grep( package->category() ).isEmpty() )
{
m_categories << package->category();
categoryAdded = true;
}
}
}
}
}
delete serverList;
// Sort category list if categories were added
if ( categoryAdded )
m_categories.sort();
}
}
void OPackageManager::loadInstalledPackages()
{
OConfItemList *destList = m_ipkg.destinations();
if ( destList )
{
// Initialize status messaging
emit initStatus( destList->count() );
int destCount = 0;
bool categoryAdded = false;
for ( OConfItemListIterator destIt( *destList ); destIt.current(); ++destIt )
{
OConfItem *destination = destIt.current();
// Process destination only if it is active
if ( destination->active() )
{
// Update status
QString status = tr( "Reading installed packages:\n\t" );
status.append( destination->name() );
emit statusText( status );
++destCount;
emit statusBar( destCount );
qApp->processEvents();
OPackageList *packageList = m_ipkg.installedPackages( destination->name(),
destination->value() );
if ( packageList )
{
for ( OPackageListIterator packageIt( *packageList ); packageIt.current(); ++packageIt )
{
OPackage *package = packageIt.current();
OPackage *currPackage = m_packages[package->name()];
if ( currPackage )
{
// Package is in a current feed, update installed version, destination
currPackage->setVersionInstalled( package->versionInstalled() );
currPackage->setDestination( package->destination() );
delete package;
}
else
{
// Package isn't in a current feed, add to list
m_packages.insert( package->name(), package );
// Add category to list if it doesn't already exist
if ( m_categories.grep( package->category() ).isEmpty() )
{
m_categories << package->category();
categoryAdded = true;
}
}
}
}
}
}
delete destList;
// Sort category list if categories were added
if ( categoryAdded )
m_categories.sort();
}
}
OPackageList *OPackageManager::packages()
{
// TODO - look to see if list is loaded, if not, load available & installed
OPackageList *pl = new OPackageList;
for ( QDictIterator<OPackage> packageIt( m_packages ); packageIt.current(); ++packageIt )
pl->append( packageIt.current() );
return pl;
}
OPackageList *OPackageManager::filterPackages( const QString &name,const QString &server,
const QString &destination, Status status, const QString &category )
{
// TODO - look to see if list is loaded, if not, load available & installed
OPackageList *pl = new OPackageList;
for ( QDictIterator<OPackage> packageIt( m_packages ); packageIt.current(); ++packageIt )
{
OPackage *package = packageIt.current();
bool nameMatch = ( name.isNull() || package->name().contains( name ) );
bool serverMatch = ( server.isNull() || package->source() == server );
bool destinationMatch = ( destination.isNull() || package->destination() == destination );
bool statusMatch;
switch ( status )
{
case All : statusMatch = true;
break;
case NotInstalled : statusMatch = package->versionInstalled().isNull();
break;
case Installed : statusMatch = !package->versionInstalled().isNull();
break;
case Updated : statusMatch = ( !package->versionInstalled().isNull() &&
compareVersions( package->version(), package->versionInstalled() ) == 1 );
break;
default : statusMatch = true;
break;
};
bool categoryMatch = ( category.isNull() || package->category() == category );
if ( nameMatch && serverMatch && destinationMatch && statusMatch && categoryMatch )
pl->append( packageIt.current() );
}
return pl;
}
QStringList *OPackageManager::servers()
{
QStringList *sl = new QStringList();
OConfItemList *serverList = m_ipkg.servers();
if ( serverList )
{
for ( OConfItemListIterator serverIt( *serverList ); serverIt.current(); ++serverIt )
{
OConfItem *server = serverIt.current();
// Add only active servers
if ( server->active() )
*sl << server->name();
}
}
return sl;
}
QStringList *OPackageManager::destinations()
{
QStringList *dl = new QStringList();
OConfItemList *destList = m_ipkg.destinations();
if ( destList )
{
for ( OConfItemListIterator destIt( *destList ); destIt.current(); ++destIt )
{
OConfItem *destination = destIt.current();
// Add only active destinations
if ( destination->active() )
*dl << destination->name();
}
}
return dl;
}
OConfItem *OPackageManager::findConfItem( OConfItem::Type type, const QString &name )
{
OConfItem *confItem = 0x0;
OConfItemList *confList = m_ipkg.configItems();
if ( confList )
{
for ( OConfItemListIterator confIt( *confList ); confIt.current(); ++confIt )
{
OConfItem *conf = confIt.current();
// Add only active confinations
if ( conf->type() == type && conf->name() == name )
{
confItem = conf;
break;
}
}
}
return confItem;
}
OPackage *OPackageManager::findPackage( const QString &name )
{
return m_packages[ name ];
}
-int OPackageManager::compareVersions( const QString &version1, const QString &version2 )
+int OPackageManager::compareVersions( const QString &ver1, const QString &ver2 )
{
- // TODO - do proper compare!
- if ( version1 < version2 )
- return -1;
- else if ( version1 > version2 )
+ // TODO - should this be in OIpkg???
+
+ int epoch1, epoch2;
+ QString version1, revision1;
+ QString version2, revision2;
+
+ parseVersion( ver1, &epoch1, &version1, &revision1 );
+ parseVersion( ver2, &epoch2, &version2, &revision2 );
+
+ if ( epoch1 > epoch2 )
return 1;
+ else if ( epoch1 < epoch2 )
+ return -1;
- return 0;
+ int r = verrevcmp( version1.latin1(), version2.latin1() );
+ if (r)
+ return r;
+
+ r = verrevcmp( revision1.latin1(), revision2.latin1() );
+ return r;
}
bool OPackageManager::configureDlg( bool installOptions )
{
OIpkgConfigDlg dlg( &m_ipkg, installOptions, static_cast<QWidget *>(parent()) );
return ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted );
}
void OPackageManager::saveSettings()
{
m_ipkg.saveSettings();
}
bool OPackageManager::executeCommand( OPackage::Command command, QStringList *packages,
const QString &destination, const QObject *receiver,
const char *slotOutput, bool rawOutput )
{
return m_ipkg.executeCommand( command, packages, destination, receiver, slotOutput, rawOutput );
}
+
+void OPackageManager::parseVersion( const QString &verstr, int *epoch, QString *version,
+ QString *revision )
+{
+ *epoch = 0;
+ *revision = QString::null;
+
+ // Version string is in the format "ee:vv-rv", where ee=epoch, vv=version, rv=revision
+
+ // Get epoch
+ int colonpos = verstr.find( ':' );
+ if ( colonpos > -1 )
+ {
+ *epoch = verstr.left( colonpos ).toInt();
+ }
+
+ // Get version and revision
+ int hyphenpos = verstr.find( '-', colonpos + 1 );
+ int verlen = verstr.length();
+ if ( hyphenpos > -1 )
+ {
+ *version = verstr.mid( colonpos + 1, hyphenpos - colonpos - 1 );
+ *revision = verstr.right( verlen - hyphenpos - 1 );
+ }
+ else
+ {
+ *version = verstr.right( verlen - colonpos );
+ }
+}
+
+/*
+ * libdpkg - Debian packaging suite library routines
+ * vercmp.c - comparison of version numbers
+ *
+ * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
+ */
+int OPackageManager::verrevcmp( const char *val, const char *ref )
+{
+ int vc, rc;
+ long vl, rl;
+ const char *vp, *rp;
+ const char *vsep, *rsep;
+
+ if (!val) val= "";
+ if (!ref) ref= "";
+ for (;;) {
+ vp= val; while (*vp && !isdigit(*vp)) vp++;
+ rp= ref; while (*rp && !isdigit(*rp)) rp++;
+ for (;;) {
+ vc= (val == vp) ? 0 : *val++;
+ rc= (ref == rp) ? 0 : *ref++;
+ if (!rc && !vc) break;
+ if (vc && !isalpha(vc)) vc += 256; /* assumes ASCII character set */
+ if (rc && !isalpha(rc)) rc += 256;
+ if (vc != rc) return vc - rc;
+ }
+ val= vp;
+ ref= rp;
+ vl=0; if (isdigit(*vp)) vl= strtol(val,(char**)&val,10);
+ rl=0; if (isdigit(*rp)) rl= strtol(ref,(char**)&ref,10);
+ if (vl != rl) return vl - rl;
+
+ vc = *val;
+ rc = *ref;
+ vsep = strchr(".-", vc);
+ rsep = strchr(".-", rc);
+ if (vsep && !rsep) return -1;
+ if (!vsep && rsep) return +1;
+
+ if (!*val && !*ref) return 0;
+ if (!*val) return -1;
+ if (!*ref) return +1;
+ }
+}
diff --git a/noncore/settings/packagemanager/opackagemanager.h b/noncore/settings/packagemanager/opackagemanager.h
index 871af0c..b710a51 100644
--- a/noncore/settings/packagemanager/opackagemanager.h
+++ b/noncore/settings/packagemanager/opackagemanager.h
@@ -1,89 +1,92 @@
/*
                This file is part of the Opie Project
              Copyright (c) 2003 Dan Williams <drw@handhelds.org>
=.
.=l.
           .>+-=
 _;:,     .>    :=|. This program is free software; you can
.> <`_,   >  .   <= redistribute it and/or modify it under
:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
.="- .-=="i,     .._ License as published by the Free Software
 - .   .-<_>     .<> Foundation; either version 2 of the License,
     ._= =}       : or (at your option) any later version.
    .%`+i>       _;_.
    .i_,=:_.      -<s. 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
..}^=.=       =       ; Library General Public License for more
++=   -.     .`     .: details.
 :     =  ...= . :.=-
 -.   .:....=;==+<; You should have received a copy of the GNU
  -_. . .   )=.  = Library General Public License along with
    --        :-=` this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef OPACKAGEMANAGER_H
#define OPACKAGEMANAGER_H
#include <qdict.h>
#include <qobject.h>
#include <qstringlist.h>
#include <qpe/config.h>
#include "oipkg.h"
class OPackageManager : public QObject
{
Q_OBJECT
public:
OPackageManager( Config *config = 0x0, QObject *parent = 0x0, const char *name = 0x0 );
void loadAvailablePackages();
void loadInstalledPackages();
enum Status { All, NotInstalled, Installed, Updated, NotDefined };
OPackageList *packages();
OPackageList *filterPackages( const QString &name = 0x0,const QString &server = 0x0,
const QString &destination = 0x0, Status status = NotDefined,
const QString &category = 0x0 );
const QStringList &categories() { return m_categories; }
QStringList *servers();
QStringList *destinations();
int compareVersions( const QString &version1, const QString &version2 );
OConfItem *findConfItem( OConfItem::Type type = OConfItem::NotDefined,
const QString &name = QString::null );
OPackage *findPackage( const QString &name = QString::null );
bool configureDlg( bool installOptions = false );
void saveSettings();
bool executeCommand( OPackage::Command command = OPackage::NotDefined, QStringList *parameters = 0x0,
const QString &destination = QString::null, const QObject *receiver = 0x0,
const char *slotOutput = 0x0, bool rawOutput = true );
private:
Config *m_config; // Pointer to application configuration file
OIpkg m_ipkg; // OIpkg object to retrieve package/configuration information
QDict<OPackage> m_packages; // Global list of available packages
QStringList m_categories; // List of all categories
+ void parseVersion( const QString &verstr, int *epoch, QString *version, QString *revision );
+ int verrevcmp( const char *val, const char *ref );
+
signals:
void initStatus( int numSteps );
void statusText( const QString &status );
void statusBar( int currStep );
};
#endif
diff --git a/noncore/settings/packagemanager/opie-packagemanager.control b/noncore/settings/packagemanager/opie-packagemanager.control
index 095e3be..5a3908e 100644
--- a/noncore/settings/packagemanager/opie-packagemanager.control
+++ b/noncore/settings/packagemanager/opie-packagemanager.control
@@ -1,10 +1,10 @@
Package: opie-packagemanager
Files: plugins/application/libpackagemanager.so* bin/packagemanager pics/packagemanager apps/Settings/packagemanager.desktop
Priority: optional
Section: Settings
Depends: task-opie-minimal
Replaces: packagemanager
Architecture: arm
Maintainer: Dan Williams (drw@handhelds.org)
Description: Opie package management client
-Version: 0.2.0
+Version: 0.3.0
diff --git a/noncore/settings/packagemanager/promptdlg.cpp b/noncore/settings/packagemanager/promptdlg.cpp
index 128e88e..4e82ba9 100644
--- a/noncore/settings/packagemanager/promptdlg.cpp
+++ b/noncore/settings/packagemanager/promptdlg.cpp
@@ -1,140 +1,140 @@
/*
                This file is part of the OPIE Project
=. Copyright (c) 2003 Dan Williams <drw@handhelds.org>
             .=l.
           .>+-=
 _;:,     .>    :=|. This file is free software; you can
.> <`_,   >  .   <= redistribute it and/or modify it under
:`=1 )Y*s>-.--   : the terms of the GNU General Public
.="- .-=="i,     .._ License as published by the Free Software
 - .   .-<_>     .<> Foundation; either version 2 of the License,
     ._= =}       : or (at your option) any later version.
    .%`+i>       _;_.
    .i_,=:_.      -<s. This file 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 file;
  -_. . .   )=.  = see the file COPYING. If not, write to the
    --        :-=` Free Software Foundation, Inc.,
59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "promptdlg.h"
#include <qlabel.h>
#include <qlayout.h>
#include <qpushbutton.h>
#include <qwidgetlist.h>
#include <qpe/qpeapplication.h>
PromptDlg::PromptDlg( const QString &caption, const QString &text, const QString &btn1, const QString &btn2,
QWidget *parent )
: QWidget( parent, QString::null, WType_Modal | WType_TopLevel | WStyle_Dialog )
, m_btnClicked( -1 )
{
setCaption( caption );
QGridLayout *layout = new QGridLayout( this, 2, 2, 4, 2 );
QLabel *label = new QLabel( text, this );
- label->setAlignment( AlignCenter | AlignTop | WordBreak );
+ label->setAlignment( AlignCenter | WordBreak );
layout->addMultiCellWidget( label, 0, 0, 0, 1 );
QPushButton *btn = new QPushButton( btn1, this );
layout->addWidget( btn, 1, 0 );
connect( btn, SIGNAL(clicked()), this, SLOT(slotBtn1Clicked()) );
btn = new QPushButton( btn2, this );
layout->addWidget( btn, 1, 1 );
connect( btn, SIGNAL(clicked()), this, SLOT(slotBtn2Clicked()) );
}
int PromptDlg::display()
{
// Determine position of dialog. Derived from QT's QDialog::show() method.
QWidget *w = parentWidget();
QPoint p( 0, 0 );
int extraw = 0, extrah = 0;
QWidget * desk = QApplication::desktop();
if ( w )
w = w->topLevelWidget();
QWidgetList *list = QApplication::topLevelWidgets();
QWidgetListIt it( *list );
while ( (extraw == 0 || extrah == 0) && it.current() != 0 )
{
int w, h;
QWidget * current = it.current();
++it;
w = current->geometry().x() - current->x();
h = current->geometry().y() - current->y();
extraw = QMAX( extraw, w );
extrah = QMAX( extrah, h );
}
delete list;
// sanity check for decoration frames. With embedding, we
// might get extraordinary values
if ( extraw >= 10 || extrah >= 40 )
extraw = extrah = 0;
if ( w )
{
// Use mapToGlobal rather than geometry() in case w might
// be embedded in another application
QPoint pp = w->mapToGlobal( QPoint(0,0) );
p = QPoint( pp.x() + w->width()/2, pp.y() + w->height()/ 2 );
}
else
p = QPoint( desk->width()/2, desk->height()/2 );
p = QPoint( p.x()-width()/2 - extraw, p.y()-height()/2 - extrah );
if ( p.x() + extraw + width() > desk->width() )
p.setX( desk->width() - width() - extraw );
if ( p.x() < 0 )
p.setX( 0 );
if ( p.y() + extrah + height() > desk->height() )
p.setY( desk->height() - height() - extrah );
if ( p.y() < 0 )
p.setY( 0 );
move( p );
show();
// Enter event loop for modality
qApp->enter_loop();
return m_btnClicked;
}
int PromptDlg::ask( const QString &caption, const QString &text, const QString &btn1, const QString &btn2,
QWidget *parent )
{
PromptDlg *dlg = new PromptDlg( caption, text, btn1, btn2, parent );
int rc = dlg->display();
delete dlg;
return rc;
}
void PromptDlg::slotBtn1Clicked()
{
m_btnClicked = 1;
qApp->exit_loop();
}
void PromptDlg::slotBtn2Clicked()
{
m_btnClicked = 2;
qApp->exit_loop();
}