-rw-r--r-- | noncore/settings/aqpkg/datamgr.cpp | 34 | ||||
-rw-r--r-- | noncore/settings/aqpkg/datamgr.h | 2 | ||||
-rw-r--r-- | noncore/settings/aqpkg/networkpkgmgr.cpp | 32 |
3 files changed, 36 insertions, 32 deletions
diff --git a/noncore/settings/aqpkg/datamgr.cpp b/noncore/settings/aqpkg/datamgr.cpp index 089c3e3..f342aff 100644 --- a/noncore/settings/aqpkg/datamgr.cpp +++ b/noncore/settings/aqpkg/datamgr.cpp @@ -10,200 +10,200 @@ * * * 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. * * * ***************************************************************************/ #include <fstream> #include <iostream> using namespace std; #ifdef QWS #include <qpe/config.h> #endif #include <stdio.h> #include "datamgr.h" #include "global.h" DataManager::DataManager() { activeServer = ""; } DataManager::~DataManager() { } Server *DataManager :: getServer( const char *name ) { Server *s = 0; vector<Server>::iterator it = serverList.begin(); while ( it != serverList.end() && s == 0 ) { if ( it->getServerName() == name ) s = &(*it); ++it; } return s; } Destination *DataManager :: getDestination( const char *name ) { Destination *d = 0; vector<Destination>::iterator it = destList.begin(); while ( it != destList.end() && d == 0 ) { if ( it->getDestinationName() == name ) d = &(*it); ++it; } return d; } void DataManager :: loadServers() { // First add our local server - not really a server but // the local config (which packages are installed) serverList.push_back( Server( LOCAL_SERVER, "" ) ); serverList.push_back( Server( LOCAL_IPKGS, "" ) ); #ifdef QWS Config cfg( "aqpkg" ); cfg.setGroup( "destinations" ); #endif // Read file from /etc/ipkg.conf QString ipkg_conf = IPKG_CONF; FILE *fp; fp = fopen( ipkg_conf, "r" ); char line[130]; QString lineStr; if ( fp == NULL ) { cout << "Couldn't open " << ipkg_conf << "! err = " << fp << endl; return; } else { while ( fgets( line, sizeof line, fp) != NULL ) { lineStr = line; if ( lineStr.startsWith( "src" ) || lineStr.startsWith( "#src" ) || lineStr.startsWith( "# src" ) ) { char alias[20]; char url[100]; // Looks a little wierd but read up to the r of src (throwing it away), // then read up to the next space and throw that away, the alias // is next. // Should Handle #src, # src, src, and combinations of sscanf( lineStr, "%*[^r]%*[^ ] %s %s", alias, url ); Server s( alias, url ); if ( lineStr.startsWith( "src" ) ) s.setActive( true ); else s.setActive( false ); serverList.push_back( s ); } else if ( lineStr.startsWith( "dest" ) ) { char alias[20]; char path[50]; sscanf( lineStr, "%*[^ ] %s %s", alias, path ); Destination d( alias, path ); bool linkToRoot = true; #ifdef QWS QString key = alias; key += "_linkToRoot"; linkToRoot = cfg.readBoolEntry( key, true ); #endif d.linkToRoot( linkToRoot ); destList.push_back( d ); } } } fclose( fp ); - vector<Server>::iterator it; - for ( it = serverList.begin() ; it != serverList.end() ; ++it ) - reloadServerData( it->getServerName() ); + reloadServerData( ); } -void DataManager :: reloadServerData( const char *serverName ) +void DataManager :: reloadServerData( ) { - Server *s = getServer( serverName ); - // Now we've read the config file in we need to read the servers - // The local server is a special case. This holds the contents of the - // status files the number of which depends on how many destinations - // we've set up - // The other servers files hold the contents of the server package list - if ( s->getServerName() == LOCAL_SERVER ) - s->readStatusFile( destList ); - else if ( s->getServerName() == LOCAL_IPKGS ) - s->readLocalIpks( getServer( LOCAL_SERVER ) ); - else - s->readPackageFile( getServer( LOCAL_SERVER ) ); - + vector<Server>::iterator it = serverList.begin(); + for ( it = serverList.begin() ; it != serverList.end() ; ++it ) + { + // Now we've read the config file in we need to read the servers + // The local server is a special case. This holds the contents of the + // status files the number of which depends on how many destinations + // we've set up + // The other servers files hold the contents of the server package list + if ( it->getServerName() == LOCAL_SERVER ) + it->readStatusFile( destList ); + else if ( it->getServerName() == LOCAL_IPKGS ) + it->readLocalIpks( getServer( LOCAL_SERVER ) ); + else + it->readPackageFile( getServer( LOCAL_SERVER ) ); + } } void DataManager :: writeOutIpkgConf() { QString ipkg_conf = IPKG_CONF; ofstream out( ipkg_conf ); out << "# Written by AQPkg" << endl; out << "# Must have one or more source entries of the form:" << endl; out << "#" << endl; out << "# src <src-name> <source-url>" << endl; out << "#" << endl; out << "# and one or more destination entries of the form:" << endl; out << "#" << endl; out << "# dest <dest-name> <target-path>" << endl; out << "#" << endl; out << "# where <src-name> and <dest-names> are identifiers that" << endl; out << "# should match [a-zA-Z0-9._-]+, <source-url> should be a" << endl; out << "# URL that points to a directory containing a Familiar" << endl; out << "# Packages file, and <target-path> should be a directory" << endl; out << "# that exists on the target system." << endl << endl; // Write out servers vector<Server>::iterator it = serverList.begin(); while ( it != serverList.end() ) { QString alias = it->getServerName(); // Don't write out local as its a dummy if ( alias != LOCAL_SERVER && alias != LOCAL_IPKGS ) { QString url = it->getServerUrl();; if ( !it->isServerActive() ) out << "#"; out << "src " << alias << " " << url << endl; } it++; } out << endl; // Write out destinations vector<Destination>::iterator it2 = destList.begin(); while ( it2 != destList.end() ) { out << "dest " << it2->getDestinationName() << " " << it2->getDestinationPath() << endl; it2++; } out.close(); } diff --git a/noncore/settings/aqpkg/datamgr.h b/noncore/settings/aqpkg/datamgr.h index eb802b5..8c6fb0d 100644 --- a/noncore/settings/aqpkg/datamgr.h +++ b/noncore/settings/aqpkg/datamgr.h @@ -1,64 +1,64 @@ /*************************************************************************** datamgr.h - description ------------------- begin : Thu Aug 29 2002 copyright : (C) 2002 by Andy Qua email : andy.qua@blueyonder.co.uk ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #ifndef DATAMGR_H #define DATAMGR_H #include <map> using namespace std; #include "server.h" #include "destination.h" #define LOCAL_SERVER "Installed Pkgs" #define LOCAL_IPKGS "local IPKG" /** *@author Andy Qua */ class DataManager { public: DataManager(); ~DataManager(); void setActiveServer( const QString &act ) { activeServer = act; } QString &getActiveServer( ) { return activeServer; } Server *getLocalServer() { return getServer( LOCAL_SERVER ); } vector<Server> &getServerList() { return serverList; } Server *getServer( const char *name ); vector<Destination> &getDestinationList() { return destList; } Destination *getDestination( const char *name ); void loadServers(); - void reloadServerData( const char *sn ); + void reloadServerData( ); void writeOutIpkgConf(); private: QString activeServer; vector<Server> serverList; vector<Destination> destList; }; #endif diff --git a/noncore/settings/aqpkg/networkpkgmgr.cpp b/noncore/settings/aqpkg/networkpkgmgr.cpp index 02e4e73..b5d7352 100644 --- a/noncore/settings/aqpkg/networkpkgmgr.cpp +++ b/noncore/settings/aqpkg/networkpkgmgr.cpp @@ -90,521 +90,525 @@ void NetworkPackageManager :: updateData() vector<Server>::iterator it; int activeItem = -1; int i; for ( i = 0, it = dataMgr->getServerList().begin() ; it != dataMgr->getServerList().end() ; ++it, ++i ) { if ( !it->isServerActive() ) { i--; continue; } serversList->insertItem( it->getServerName() ); if ( it->getServerName() == currentlySelectedServer ) activeItem = i; } // set selected server to be active server if ( activeItem != -1 ) serversList->setCurrentItem( activeItem ); serverSelected( 0 ); } void NetworkPackageManager :: selectLocalPackage( const QString &pkg ) { // First select local server for ( int i = 0 ; i < serversList->count() ; ++i ) { if ( serversList->text( i ) == LOCAL_IPKGS ) { serversList->setCurrentItem( i ); break; } } serverSelected( 0 ); // Now set the check box of the selected package for ( QCheckListItem *item = (QCheckListItem *)packagesList->firstChild(); item != 0 ; item = (QCheckListItem *)item->nextSibling() ) { if ( item->text().startsWith( pkg ) ) { item->setOn( true ); break; } } } void NetworkPackageManager :: initGui() { QLabel *l = new QLabel( "Servers", this ); serversList = new QComboBox( this ); packagesList = new QListView( this ); update = new QPushButton( "Refresh List", this ); download = new QPushButton( "Download", this ); upgrade = new QPushButton( "Upgrade", this ); apply = new QPushButton( "Apply", this ); QVBoxLayout *vbox = new QVBoxLayout( this, 0, -1, "VBox" ); QHBoxLayout *hbox1 = new QHBoxLayout( vbox, -1, "HBox1" ); hbox1->addWidget( l ); hbox1->addWidget( serversList ); QHBoxLayout *hbox3 = new QHBoxLayout( vbox, -1, "HBox1" ); QHBoxLayout *hbox4 = new QHBoxLayout( vbox, -1, "HBox1" ); if ( showJumpTo ) { char text[2]; text[1] = '\0'; for ( int i = 0 ; i < 26 ; ++i ) { text[0] = 'A' + i; LetterPushButton *b = new LetterPushButton( text, this ); connect( b, SIGNAL( released( QString ) ), this, SLOT( letterPushed( QString ) ) ); if ( i < 13 ) hbox3->addWidget( b ); else hbox4->addWidget( b ); } } vbox->addWidget( packagesList ); packagesList->addColumn( "Packages" ); QHBoxLayout *hbox2 = new QHBoxLayout( vbox, -1, "HBox2" ); hbox2->addWidget( update ); hbox2->addWidget( download ); hbox2->addWidget( upgrade ); hbox2->addWidget( apply ); } void NetworkPackageManager :: setupConnections() { connect( serversList, SIGNAL(activated( int )), this, SLOT(serverSelected( int ))); connect( apply, SIGNAL(released()), this, SLOT(applyChanges()) ); connect( download, SIGNAL(released()), this, SLOT(downloadPackage()) ); connect( upgrade, SIGNAL( released()), this, SLOT(upgradePackages()) ); connect( update, SIGNAL(released()), this, SLOT(updateServer()) ); } void NetworkPackageManager :: showProgressDialog( char *initialText ) { if ( !progressDlg ) progressDlg = new ProgressDlg( this, "Progress", false ); progressDlg->setText( initialText ); progressDlg->show(); } void NetworkPackageManager :: serverSelected( int ) { packagesList->clear(); // display packages QString serverName = serversList->currentText(); currentlySelectedServer = serverName; #ifdef QWS // read download directory from config file Config cfg( "aqpkg" ); cfg.setGroup( "settings" ); cfg.writeEntry( "selectedServer", currentlySelectedServer ); #endif Server *s = dataMgr->getServer( serverName ); -// dataMgr->setActiveServer( serverName ); vector<Package> &list = s->getPackageList(); vector<Package>::iterator it; for ( it = list.begin() ; it != list.end() ; ++it ) { + QString text = ""; // If the local server, only display installed packages if ( serverName == LOCAL_SERVER && !it->isInstalled() ) continue; text += it->getPackageName(); if ( it->isInstalled() ) { text += " (installed)"; // If a different version of package is available, postfix it with an * if ( it->getVersion() != it->getInstalledVersion() ) { + if ( compareVersions( it->getInstalledVersion(), it->getVersion() ) == 1 ) text += "*"; } } QCheckListItem *item = new QCheckListItem( packagesList, text, QCheckListItem::CheckBox ); if ( it->isInstalled() ) { QString destName = ""; if ( it->getLocalPackage() ) { if ( it->getLocalPackage()->getInstalledTo() ) destName = it->getLocalPackage()->getInstalledTo()->getDestinationName(); } else { if ( it->getInstalledTo() ) destName = it->getInstalledTo()->getDestinationName(); } if ( destName != "" ) new QCheckListItem( item, QString( "Installed To - " ) + destName ); } if ( !it->isPackageStoredLocally() ) new QCheckListItem( item, QString( "Description - " ) + it->getDescription() ); else new QCheckListItem( item, QString( "Filename - " ) + it->getFilename() ); - new QCheckListItem( item, QString( "V. Available - " ) + it->getVersion() ); - if ( it->getLocalPackage() ) - { - if ( it->isInstalled() ) - new QCheckListItem( item, QString( "V. Installed - " ) + it->getInstalledVersion() ); + if ( serverName == LOCAL_SERVER ) + { + new QCheckListItem( item, QString( "V. Installed - " ) + it->getVersion() ); + } + else + { + new QCheckListItem( item, QString( "V. Available - " ) + it->getVersion() ); + if ( it->getLocalPackage() ) + { + if ( it->isInstalled() ) + new QCheckListItem( item, QString( "V. Installed - " ) + it->getInstalledVersion() ); + } } packagesList->insertItem( item ); } // If the local server or the local ipkgs server disable the download button if ( serverName == LOCAL_SERVER ) { upgrade->setEnabled( false ); download->setText( "Download" ); download->setEnabled( false ); } else if ( serverName == LOCAL_IPKGS ) { upgrade->setEnabled( false ); download->setEnabled( true ); download->setText( "Remove" ); } else { upgrade->setEnabled( true ); download->setEnabled( true ); download->setText( "Download" ); } } void NetworkPackageManager :: updateServer() { QString serverName = serversList->currentText(); // Update the current server // Display dialog // ProgressDlg *progDlg = new ProgressDlg( this ); // QString status = "Updating package lists..."; // progDlg->show(); // progDlg->setText( status ); // Disable buttons to stop silly people clicking lots on them :) // First, write out ipkg_conf file so that ipkg can use it dataMgr->writeOutIpkgConf(); Ipkg ipkg; ipkg.setOption( "update" ); InstallDlgImpl dlg( &ipkg, "Refreshing server package lists", this, "Upgrade", true ); dlg.showDlg(); // Reload data - dataMgr->reloadServerData( serversList->currentText() ); + dataMgr->reloadServerData(); serverSelected(-1); // delete progDlg; } void NetworkPackageManager :: upgradePackages() { // We're gonna do an upgrade of all packages // First warn user that this isn't recommended QString text = "WARNING: Upgrading while\nOpie/Qtopia is running\nis NOT recommended!\n\nAre you sure?\n"; QMessageBox warn("Warning", text, QMessageBox::Warning, QMessageBox::Yes, QMessageBox::No | QMessageBox::Escape | QMessageBox::Default , 0, this ); warn.adjustSize(); if ( warn.exec() == QMessageBox::Yes ) { // First, write out ipkg_conf file so that ipkg can use it dataMgr->writeOutIpkgConf(); // Now run upgrade Ipkg ipkg; ipkg.setOption( "upgrade" ); InstallDlgImpl dlg( &ipkg, "Upgrading installed packages", this, "Upgrade", true ); dlg.showDlg(); // Reload data - dataMgr->reloadServerData( LOCAL_SERVER ); - - dataMgr->reloadServerData( serversList->currentText() ); + dataMgr->reloadServerData(); serverSelected(-1); } } void NetworkPackageManager :: downloadPackage() { if ( download->text() == "Download" ) { // First, write out ipkg_conf file so that ipkg can use it dataMgr->writeOutIpkgConf(); // Display dialog to user asking where to download the files to bool ok = FALSE; QString dir = ""; #ifdef QWS // read download directory from config file Config cfg( "aqpkg" ); cfg.setGroup( "settings" ); dir = cfg.readEntry( "downloadDir", "/home/root/Documents/application/ipkg" ); #endif QString text = InputDialog::getText( tr( "Download to where" ), tr( "Enter path to download to" ), dir, &ok, this ); if ( ok && !text.isEmpty() ) dir = text; // user entered something and pressed ok else return; // user entered nothing or pressed cancel #ifdef QWS // Store download directory in config file cfg.writeEntry( "downloadDir", dir ); #endif // Get starting directory char initDir[PATH_MAX]; getcwd( initDir, PATH_MAX ); // Download each package Ipkg ipkg; connect( &ipkg, SIGNAL(outputText(const QString &)), this, SLOT(displayText(const QString &))); ipkg.setOption( "download" ); ipkg.setRuntimeDirectory( dir ); for ( QCheckListItem *item = (QCheckListItem *)packagesList->firstChild(); item != 0 ; item = (QCheckListItem *)item->nextSibling() ) { if ( item->isOn() ) { QString name = item->text(); int pos = name.find( "*" ); name.truncate( pos ); // if (there is a (installed), remove it pos = name.find( "(installed)" ); if ( pos > 0 ) name.truncate( pos - 1 ); ipkg.setPackage( name ); ipkg.runIpkg( ); } } } else if ( download->text() == "Remove" ) { for ( QCheckListItem *item = (QCheckListItem *)packagesList->firstChild(); item != 0 ; item = (QCheckListItem *)item->nextSibling() ) { if ( item->isOn() ) { QString name = item->text(); int pos = name.find( "*" ); name.truncate( pos ); // if (there is a (installed), remove it pos = name.find( "(installed)" ); if ( pos > 0 ) name.truncate( pos - 1 ); Package *p = dataMgr->getServer( serversList->currentText() )->getPackage( name ); QFile f( p->getFilename() ); f.remove(); } } } - dataMgr->reloadServerData( LOCAL_IPKGS ); + dataMgr->reloadServerData(); serverSelected( -1 ); } void NetworkPackageManager :: applyChanges() { stickyOption = ""; // First, write out ipkg_conf file so that ipkg can use it dataMgr->writeOutIpkgConf(); // Now for each selected item // deal with it vector<InstallData> workingPackages; for ( QCheckListItem *item = (QCheckListItem *)packagesList->firstChild(); item != 0 ; item = (QCheckListItem *)item->nextSibling() ) { if ( item->isOn() ) { InstallData data = dealWithItem( item ); workingPackages.push_back( data ); } } if ( workingPackages.size() == 0 ) { // Nothing to do QMessageBox::information( this, "Nothing to do", "No packages selected", "OK" ); return; } // do the stuff InstallDlgImpl dlg( workingPackages, dataMgr, this, "Install", true ); dlg.showDlg(); // Reload data - dataMgr->reloadServerData( LOCAL_SERVER ); - - dataMgr->reloadServerData( serversList->currentText() ); + dataMgr->reloadServerData(); serverSelected(-1); #ifdef QWS // Finally let the main system update itself QCopEnvelope e("QPE/System", "linkChanged(QString)"); QString lf = QString::null; e << lf; #endif } // decide what to do - either remove, upgrade or install // Current rules: // If not installed - install // If installed and different version available - upgrade // If installed and version up to date - remove InstallData NetworkPackageManager :: dealWithItem( QCheckListItem *item ) { QString name = item->text(); int pos = name.find( "*" ); name.truncate( pos ); // if (there is a (installed), remove it pos = name.find( "(installed)" ); if ( pos > 0 ) name.truncate( pos - 1 ); // Get package Server *s = dataMgr->getServer( serversList->currentText() ); Package *p = s->getPackage( name ); // If the package has a filename then it is a local file if ( p->isPackageStoredLocally() ) name = p->getFilename(); QString option; QString dest = "root"; if ( !p->isInstalled() ) { InstallData item; item.option = "I"; item.packageName = name; return item; } else { InstallData item; item.option = "D"; item.packageName = p->getInstalledPackageName(); if ( p->getInstalledTo() ) { item.destination = p->getInstalledTo(); cout << "dest - " << p->getInstalledTo()->getDestinationName() << endl; cout << "dest - " << p->getInstalledTo()->getDestinationPath() << endl; } else { item.destination = p->getLocalPackage()->getInstalledTo(); } // Now see if version is newer or not int val = compareVersions( p->getInstalledVersion(), p->getVersion() ); if ( val == -2 ) { // Error - should handle } else if ( val == -1 ) { // Version available is older - remove only item.option = "R"; } else { QString caption; QString text; QString secondButton; QString secondOption; if ( val == 0 ) { // Version available is the same - option to remove or reinstall caption = "Do you wish to remove or reinstall\n%s?"; text = "Remove or ReInstall"; secondButton = "ReInstall"; secondOption = "R"; } else if ( val == 1 ) { // Version available is newer - option to remove or upgrade caption = "Do you wish to remove or upgrade\n%s?"; text = "Remove or Upgrade"; secondButton = "Upgrade"; secondOption = "U"; } // Sticky option not implemented yet, but will eventually allow // the user to say something like 'remove all' if ( stickyOption == "" ) { QString msgtext; msgtext.sprintf( caption, (const char *)name ); switch( QMessageBox::information( this, text, msgtext, "Remove", secondButton ) ) { case 0: // Try again or Enter item.option = "D"; break; case 1: // Quit or Escape item.option = secondOption; break; } } else { // item.option = stickyOption; } } // Check if we are reinstalling the same version if ( item.option != "R" ) item.recreateLinks = true; else item.recreateLinks = false; // User hit cancel (on dlg - assume remove) return item; } } void NetworkPackageManager :: displayText( const QString &t ) |