Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

opackagemanager.cpp

Go to the documentation of this file.
00001 /*
00002                              This file is part of the Opie Project
00003 
00004                              Copyright (C)2004, 2005 Dan Williams <drw@handhelds.org>
00005               =.
00006             .=l.
00007            .>+-=
00008  _;:,     .>    :=|.         This program is free software; you can
00009 .> <`_,   >  .   <=          redistribute it and/or  modify it under
00010 :`=1 )Y*s>-.--   :           the terms of the GNU Library General Public
00011 .="- .-=="i,     .._         License as published by the Free Software
00012  - .   .-<_>     .<>         Foundation; either version 2 of the License,
00013      ._= =}       :          or (at your option) any later version.
00014     .%`+i>       _;_.
00015     .i_,=:_.      -<s.       This program is distributed in the hope that
00016      +  .  -:.       =       it will be useful,  but WITHOUT ANY WARRANTY;
00017     : ..    .:,     . . .    without even the implied warranty of
00018     =_        +     =;=|`    MERCHANTABILITY or FITNESS FOR A
00019   _.=:.       :    :=>`:     PARTICULAR PURPOSE. See the GNU
00020 ..}^=.=       =       ;      Library General Public License for more
00021 ++=   -.     .`     .:       details.
00022 :     =  ...= . :.=-
00023  -.   .:....=;==+<;          You should have received a copy of the GNU
00024   -_. . .   )=.  =           Library General Public License along with
00025     --        :-=`           this library; see the file COPYING.LIB.
00026                              If not, write to the Free Software Foundation,
00027                              Inc., 59 Temple Place - Suite 330,
00028                              Boston, MA 02111-1307, USA.
00029 */
00030 
00031 #include "opackagemanager.h"
00032 #include "oipkgconfigdlg.h"
00033 
00034 #include <qpe/qpeapplication.h>
00035 
00036 #include <ctype.h>
00037 
00038 OPackageManager::OPackageManager( Config *config, QObject *parent, const char *name )
00039     : QObject( parent, name )
00040     , m_config( config )
00041     , m_ipkg( m_config, this )
00042     , m_packages( 9973 )
00043     , m_categories()
00044 {
00045     m_packages.setAutoDelete( true );
00046 }
00047 
00048 void OPackageManager::loadAvailablePackages()
00049 {
00050     m_packages.clear();
00051 
00052     OConfItemList *serverList = m_ipkg.servers();
00053 
00054     if ( serverList )
00055     {
00056         // Initialize status messaging
00057         emit initStatus( serverList->count() );
00058         int serverCount = 0;
00059 
00060         bool categoryAdded = false;
00061 
00062         for ( OConfItemListIterator serverIt( *serverList ); serverIt.current(); ++serverIt )
00063         {
00064             OConfItem *server = serverIt.current();
00065 
00066             // Process server only if it is active
00067             if ( server->active() )
00068             {
00069                 // Update status
00070                 QString status = tr( "Reading available packages:\n\t" );
00071                 status.append( server->name() );
00072                 emit statusText( status );
00073                 ++serverCount;
00074                 emit statusBar( serverCount );
00075                 qApp->processEvents();
00076 
00077                 OPackageList *packageList = m_ipkg.availablePackages( server->name() );
00078                 if ( packageList )
00079                 {
00080                     for ( OPackageListIterator packageIt( *packageList ); packageIt.current(); ++packageIt )
00081                     {
00082                         OPackage *package = packageIt.current();
00083 
00084                         // Load package info
00085                         if ( !m_packages.find( package->name() ) )
00086                             m_packages.insert( package->name(), package );
00087                         else
00088                         {
00089                             // If new package is newer version, replace existing package
00090                             OPackage *currPackage = m_packages[package->name()];
00091                             if ( compareVersions( package->version(), currPackage->version() ) == 1 )
00092                                 m_packages.replace( package->name(), package );
00093                         }
00094 
00095                         // Add category to list if it doesn't already exist
00096                         if ( m_categories.grep( package->category() ).isEmpty() )
00097                         {
00098                             m_categories << package->category();
00099                             categoryAdded = true;
00100                         }
00101                     }
00102                 }
00103             }
00104         }
00105         delete serverList;
00106 
00107         // Sort category list if categories were added
00108         if ( categoryAdded )
00109             m_categories.sort();
00110     }
00111 }
00112 
00113 void OPackageManager::loadInstalledPackages()
00114 {
00115     OConfItemList *destList = m_ipkg.destinations();
00116 
00117     if ( destList )
00118     {
00119         // Initialize status messaging
00120         emit initStatus( destList->count() );
00121         int destCount = 0;
00122 
00123         bool categoryAdded = false;
00124 
00125         for ( OConfItemListIterator destIt( *destList ); destIt.current(); ++destIt )
00126         {
00127             OConfItem *destination = destIt.current();
00128 
00129             // Process destination only if it is active
00130             if ( destination->active() )
00131             {
00132                 // Update status
00133                 QString status = tr( "Reading installed packages:\n\t" );
00134                 status.append( destination->name() );
00135                 emit statusText( status );
00136                 ++destCount;
00137                 emit statusBar( destCount );
00138                 qApp->processEvents();
00139 
00140                 OPackageList *packageList = m_ipkg.installedPackages( destination->name(),
00141                                                                       destination->value() );
00142                 if ( packageList )
00143                 {
00144                     for ( OPackageListIterator packageIt( *packageList ); packageIt.current(); ++packageIt )
00145                     {
00146                         OPackage *package = packageIt.current();
00147                         OPackage *currPackage = m_packages[package->name()];
00148                         if ( currPackage )
00149                         {
00150                             // Package is in a current feed, update installed version, destination
00151                             currPackage->setVersionInstalled( package->versionInstalled() );
00152                             currPackage->setDestination( package->destination() );
00153 
00154                             delete package;
00155                         }
00156                         else
00157                         {
00158                             // Package isn't in a current feed, add to list
00159                             m_packages.insert( package->name(), package );
00160 
00161                             // Add category to list if it doesn't already exist
00162                             if ( m_categories.grep( package->category() ).isEmpty() )
00163                             {
00164                                 m_categories << package->category();
00165                                 categoryAdded = true;
00166                             }
00167                         }
00168                     }
00169                 }
00170             }
00171         }
00172         delete destList;
00173 
00174         // Sort category list if categories were added
00175         if ( categoryAdded )
00176             m_categories.sort();
00177     }
00178 }
00179 
00180 OPackageList *OPackageManager::packages()
00181 {
00182     // TODO - look to see if list is loaded, if not, load available & installed
00183 
00184     OPackageList *pl = new OPackageList;
00185 
00186     for ( QDictIterator<OPackage> packageIt( m_packages ); packageIt.current(); ++packageIt )
00187         pl->append( packageIt.current() );
00188 
00189     return pl;
00190 }
00191 
00192 OPackageList *OPackageManager::filterPackages( const QString &name,const QString &server,
00193                                   const QString &destination, Status status, const QString &category )
00194 {
00195     // TODO - look to see if list is loaded, if not, load available & installed
00196 
00197     OPackageList *pl = new OPackageList;
00198     for ( QDictIterator<OPackage> packageIt( m_packages ); packageIt.current(); ++packageIt )
00199     {
00200         OPackage *package = packageIt.current();
00201 
00202         bool nameMatch = ( name.isNull() || package->name().contains( name ) );
00203         bool serverMatch = ( server.isNull() || package->source() == server );
00204         bool destinationMatch = ( destination.isNull() || package->destination() == destination );
00205         bool statusMatch;
00206         switch ( status )
00207         {
00208             case All : statusMatch = true;
00209                 break;
00210             case NotInstalled : statusMatch = package->versionInstalled().isNull();
00211                 break;
00212             case Installed : statusMatch = !package->versionInstalled().isNull();
00213                 break;
00214             case Updated : statusMatch = ( !package->versionInstalled().isNull() &&
00215                                   compareVersions( package->version(), package->versionInstalled() ) == 1 );
00216                 break;
00217             default : statusMatch = true;
00218                 break;
00219         };
00220         bool categoryMatch = ( category.isNull() || package->category() == category );
00221 
00222         if ( nameMatch && serverMatch && destinationMatch && statusMatch && categoryMatch )
00223             pl->append( packageIt.current() );
00224     }
00225 
00226     return pl;
00227 }
00228 
00229 QStringList OPackageManager::servers()
00230 {
00231     QStringList sl;
00232 
00233     OConfItemList *serverList = m_ipkg.servers();
00234     if ( serverList )
00235     {
00236         for ( OConfItemListIterator serverIt( *serverList ); serverIt.current(); ++serverIt )
00237         {
00238             OConfItem *server = serverIt.current();
00239 
00240             // Add only active servers
00241             if ( server->active() )
00242                 sl << server->name();
00243         }
00244     }
00245 
00246     return sl;
00247 }
00248 
00249 QStringList OPackageManager::destinations()
00250 {
00251     QStringList dl;
00252 
00253     OConfItemList *destList = m_ipkg.destinations();
00254     if ( destList )
00255     {
00256         for ( OConfItemListIterator destIt( *destList ); destIt.current(); ++destIt )
00257         {
00258             OConfItem *destination = destIt.current();
00259 
00260             // Add only active destinations
00261             if ( destination->active() )
00262                 dl << destination->name();
00263         }
00264     }
00265 
00266     return dl;
00267 }
00268 
00269 OConfItem *OPackageManager::findConfItem( OConfItem::Type type, const QString &name )
00270 {
00271     return m_ipkg.findConfItem( type, name );
00272 }
00273 
00274 OPackage *OPackageManager::findPackage( const QString &name )
00275 {
00276     return m_packages[ name ];
00277 }
00278 
00279 int OPackageManager::compareVersions( const QString &ver1, const QString &ver2 )
00280 {
00281     // TODO - should this be in OIpkg???
00282 
00283     int epoch1, epoch2;
00284     QString version1, revision1;
00285     QString version2, revision2;
00286 
00287     parseVersion( ver1, &epoch1, &version1, &revision1 );
00288     parseVersion( ver2, &epoch2, &version2, &revision2 );
00289 
00290     if ( epoch1 > epoch2 )
00291         return 1;
00292     else if ( epoch1 < epoch2 )
00293         return -1;
00294 
00295     int r = verrevcmp( version1.latin1(), version2.latin1() );
00296     if (r)
00297         return r;
00298 
00299     r = verrevcmp( revision1.latin1(), revision2.latin1() );
00300     return r;
00301 }
00302 
00303 bool OPackageManager::configureDlg( bool installOptions )
00304 {
00305     OIpkgConfigDlg dlg( &m_ipkg, installOptions, static_cast<QWidget *>(parent()) );
00306     return ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted );
00307 }
00308 
00309 void OPackageManager::saveSettings()
00310 {
00311     m_ipkg.saveSettings();
00312 }
00313 
00314 bool OPackageManager::executeCommand( OPackage::Command command, const QStringList &packages,
00315                                       const QString &destination, const QObject *receiver,
00316                                       const char *slotOutput, bool rawOutput )
00317 {
00318     return m_ipkg.executeCommand( command, packages, destination, receiver, slotOutput, rawOutput );
00319 }
00320 
00321 void OPackageManager::parseVersion( const QString &verstr, int *epoch, QString *version,
00322                                     QString *revision )
00323 {
00324     *epoch = 0;
00325     *revision = QString::null;
00326 
00327     // Version string is in the format "ee:vv-rv", where ee=epoch, vv=version, rv=revision
00328 
00329     // Get epoch
00330     int colonpos = verstr.find( ':' );
00331     if ( colonpos > -1 )
00332     {
00333         *epoch = verstr.left( colonpos ).toInt();
00334     }
00335 
00336     // Get version and revision
00337     int hyphenpos = verstr.find( '-', colonpos + 1 );
00338     int verlen = verstr.length();
00339     if ( hyphenpos > -1 )
00340     {
00341         *version = verstr.mid( colonpos + 1, hyphenpos - colonpos - 1 );
00342         *revision = verstr.right( verlen - hyphenpos - 1 );
00343     }
00344     else
00345     {
00346        *version = verstr.right( verlen - colonpos );
00347     }
00348 }
00349 
00350 /*
00351  * libdpkg - Debian packaging suite library routines
00352  * vercmp.c - comparison of version numbers
00353  *
00354  * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
00355  */
00356 int OPackageManager::verrevcmp( const char *val, const char *ref )
00357 {
00358      int vc, rc;
00359      long vl, rl;
00360      const char *vp, *rp;
00361      const char *vsep, *rsep;
00362 
00363      if (!val) val= "";
00364      if (!ref) ref= "";
00365      for (;;) {
00366       vp= val;  while (*vp && !isdigit(*vp)) vp++;
00367       rp= ref;  while (*rp && !isdigit(*rp)) rp++;
00368       for (;;) {
00369            vc= (val == vp) ? 0 : *val++;
00370            rc= (ref == rp) ? 0 : *ref++;
00371            if (!rc && !vc) break;
00372            if (vc && !isalpha(vc)) vc += 256; /* assumes ASCII character set */
00373            if (rc && !isalpha(rc)) rc += 256;
00374            if (vc != rc) return vc - rc;
00375       }
00376       val= vp;
00377       ref= rp;
00378       vl=0;  if (isdigit(*vp)) vl= strtol(val,(char**)&val,10);
00379       rl=0;  if (isdigit(*rp)) rl= strtol(ref,(char**)&ref,10);
00380       if (vl != rl) return vl - rl;
00381 
00382       vc = *val;
00383       rc = *ref;
00384       vsep = strchr(".-", vc);
00385       rsep = strchr(".-", rc);
00386       if (vsep && !rsep) return -1;
00387       if (!vsep && rsep) return +1;
00388 
00389       if (!*val && !*ref) return 0;
00390       if (!*val) return -1;
00391       if (!*ref) return +1;
00392      }
00393 }

Generated on Sat Nov 5 16:17:57 2005 for OPIE by  doxygen 1.4.2