00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
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
00067 if ( server->active() )
00068 {
00069
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
00085 if ( !m_packages.find( package->name() ) )
00086 m_packages.insert( package->name(), package );
00087 else
00088 {
00089
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
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
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
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
00130 if ( destination->active() )
00131 {
00132
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
00151 currPackage->setVersionInstalled( package->versionInstalled() );
00152 currPackage->setDestination( package->destination() );
00153
00154 delete package;
00155 }
00156 else
00157 {
00158
00159 m_packages.insert( package->name(), package );
00160
00161
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
00175 if ( categoryAdded )
00176 m_categories.sort();
00177 }
00178 }
00179
00180 OPackageList *OPackageManager::packages()
00181 {
00182
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
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
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
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
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
00328
00329
00330 int colonpos = verstr.find( ':' );
00331 if ( colonpos > -1 )
00332 {
00333 *epoch = verstr.left( colonpos ).toInt();
00334 }
00335
00336
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
00352
00353
00354
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;
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 }