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

mainwin.cpp

Go to the documentation of this file.
00001 /*
00002                      This file is part of the OPIE Project
00003  
00004                =.            Copyright (c)  2002 Andy Qua <andy.qua@blueyonder.co.uk>
00005       .=l.                                Dan Williams <drw@handhelds.org>
00006      .>+-=
00007 _;:,   .>  :=|.         This file is free software; you can
00008 .> <`_,  > .  <=          redistribute it and/or modify it under
00009 :`=1 )Y*s>-.--  :           the terms of the GNU General Public
00010 .="- .-=="i,   .._         License as published by the Free Software
00011 - .  .-<_>   .<>         Foundation; either version 2 of the License,
00012   ._= =}    :          or (at your option) any later version.
00013   .%`+i>    _;_.
00014   .i_,=:_.   -<s.       This file is distributed in the hope that
00015   + . -:.    =       it will be useful, but WITHOUT ANY WARRANTY;
00016   : ..  .:,   . . .    without even the implied warranty of
00017   =_    +   =;=|`    MERCHANTABILITY or FITNESS FOR A
00018  _.=:.    :  :=>`:     PARTICULAR PURPOSE. See the GNU General
00019 ..}^=.=    =    ;      Public License for more details.
00020 ++=  -.   .`   .:
00021 :   = ...= . :.=-        You should have received a copy of the GNU
00022 -.  .:....=;==+<;          General Public License along with this file;
00023  -_. . .  )=. =           see the file COPYING. If not, write to the
00024   --    :-=`           Free Software Foundation, Inc.,
00025                              59 Temple Place - Suite 330,
00026                              Boston, MA 02111-1307, USA.
00027 
00028 */
00029 
00030 #include "categoryfilterimpl.h"
00031 #include "datamgr.h"
00032 #include "global.h"
00033 #include "inputdlg.h"
00034 #include "ipkg.h"
00035 #include "installdlgimpl.h"
00036 #include "letterpushbutton.h"
00037 #include "mainwin.h"
00038 #include "packagewin.h"
00039 #include "settingsimpl.h"
00040 #include "utils.h"
00041 
00042 /* OPIE */
00043 #include <opie2/oresource.h>
00044 
00045 #include <qpe/qcopenvelope_qws.h>
00046 #include <qpe/qpeapplication.h>
00047 #include <qpe/config.h>
00048 
00049 /* QT */
00050 #include <qmenubar.h>
00051 #include <qtoolbar.h>
00052 #include <qaction.h>
00053 #include <qcombobox.h>
00054 #include <qfile.h>
00055 #include <qlabel.h>
00056 #include <qlayout.h>
00057 #include <qlineedit.h>
00058 #include <qlistview.h>
00059 #include <qmenubar.h>
00060 #include <qmessagebox.h>
00061 #include <qpopupmenu.h>
00062 #include <qprogressbar.h>
00063 #include <qtimer.h>
00064 #include <qwhatsthis.h>
00065 #include <qwidgetstack.h>
00066 
00067 /* STD */
00068 #include <linux/limits.h>
00069 #include <unistd.h>
00070 
00071 extern int compareVersions( const char *v1, const char *v2 );
00072 
00073 MainWindow :: MainWindow( QWidget* parent, const char* name, WFlags fl )
00074         :       QMainWindow( parent, name, fl || WStyle_ContextHelp )
00075 {
00076     // Disable suspend mode
00077     QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::DisableSuspend;
00078 
00079     LOCAL_SERVER = QObject::tr( "Installed packages" );
00080     LOCAL_IPKGS = QObject::tr( "Local packages" );
00081 
00082     setCaption( tr( "AQPkg - Package Manager" ) );
00083 
00084     // Create UI widgets
00085     initMainWidget();
00086     initProgressWidget();
00087 
00088     // Build menu and tool bars
00089     setToolBarsMovable( FALSE );
00090 
00091     QToolBar *bar = new QToolBar( this );
00092     bar->setHorizontalStretchable( TRUE );
00093     QMenuBar *mb = new QMenuBar( bar );
00094     mb->setMargin( 0 );
00095     bar = new QToolBar( this );
00096 
00097     // Find toolbar
00098     findBar = new QToolBar( this );
00099     addToolBar( findBar, QMainWindow::Top, true );
00100     findBar->setHorizontalStretchable( true );
00101     findEdit = new QLineEdit( findBar );
00102     QWhatsThis::add( findEdit, tr( "Type the text to search for here." ) );
00103     findBar->setStretchableWidget( findEdit );
00104     connect( findEdit, SIGNAL( textChanged(const QString&) ), this, SLOT( findPackage(const QString&) ) );
00105 
00106     // Quick jump toolbar
00107     jumpBar = new QToolBar( this );
00108     addToolBar( jumpBar, QMainWindow::Top, true );
00109     jumpBar->setHorizontalStretchable( true );
00110     QWidget *w = new QWidget( jumpBar );
00111     jumpBar->setStretchableWidget( w );
00112 
00113     QGridLayout *layout = new QGridLayout( w );
00114 
00115     char text[2];
00116     text[1] = '\0';
00117     for ( int i = 0 ; i < 26 ; ++i )
00118     {
00119         text[0] = 'A' + i;
00120         LetterPushButton *b = new LetterPushButton( text, w );
00121         connect( b, SIGNAL( released(QString) ), this, SLOT( letterPushed(QString) ) );
00122         layout->addWidget( b, i / 13, i % 13);
00123     }
00124 
00125     QAction *a = new QAction( QString::null, Opie::Core::OResource::loadPixmap( "close", Opie::Core::OResource::SmallIcon ),
00126                               QString::null, 0, w, 0 );
00127     a->setWhatsThis( tr( "Click here to hide the Quick Jump toolbar." ) );
00128     connect( a, SIGNAL( activated() ), this, SLOT( hideJumpBar() ) );
00129     a->addTo( jumpBar );
00130     jumpBar->hide();
00131 
00132     // Packages menu
00133     QPopupMenu *popup = new QPopupMenu( this );
00134 
00135     a = new QAction( tr( "Update lists" ), Opie::Core::OResource::loadPixmap( "aqpkg/update", Opie::Core::OResource::SmallIcon ),
00136                      QString::null, 0, this, 0 );
00137     a->setWhatsThis( tr( "Click here to update package lists from servers." ) );
00138     connect( a, SIGNAL( activated() ), this, SLOT( updateServer() ) );
00139     a->addTo( popup );
00140     a->addTo( bar );
00141 
00142     actionUpgrade = new QAction( tr( "Upgrade" ), Opie::Core::OResource::loadPixmap( "aqpkg/upgrade", Opie::Core::OResource::SmallIcon ),
00143                                  QString::null, 0, this, 0 );
00144     actionUpgrade->setWhatsThis( tr( "Click here to upgrade all installed packages if a newer version is available." ) );
00145     connect( actionUpgrade, SIGNAL( activated() ), this, SLOT( upgradePackages() ) );
00146     actionUpgrade->addTo( popup );
00147     actionUpgrade->addTo( bar );
00148 
00149     iconDownload = Opie::Core::OResource::loadPixmap( "aqpkg/download", Opie::Core::OResource::SmallIcon );
00150     iconRemove = Opie::Core::OResource::loadPixmap( "aqpkg/remove", Opie::Core::OResource::SmallIcon );
00151     actionDownload = new QAction( tr( "Download" ), iconDownload, QString::null, 0, this, 0 );
00152     actionDownload->setWhatsThis( tr( "Click here to download the currently selected package(s)." ) );
00153     connect( actionDownload, SIGNAL( activated() ), this, SLOT( downloadPackage() ) );
00154     actionDownload->addTo( popup );
00155     actionDownload->addTo( bar );
00156 
00157     a = new QAction( tr( "Apply changes" ), Opie::Core::OResource::loadPixmap( "aqpkg/apply", Opie::Core::OResource::SmallIcon ),
00158                      QString::null, 0, this, 0 );
00159     a->setWhatsThis( tr( "Click here to install, remove or upgrade currently selected package(s)." ) );
00160     connect( a, SIGNAL( activated() ), this, SLOT( applyChanges() ) );
00161     a->addTo( popup );
00162     a->addTo( bar );
00163 
00164     popup->insertSeparator();
00165 
00166     a = new QAction( tr( "Configure" ), Opie::Core::OResource::loadPixmap( "SettingsIcon", Opie::Core::OResource::SmallIcon ),
00167                      QString::null, 0, this, 0 );
00168     a->setWhatsThis( tr( "Click here to configure this application." ) );
00169     connect( a, SIGNAL( activated() ), this, SLOT( displaySettings() ) );
00170     a->addTo( popup );
00171     mb->insertItem( tr( "Actions" ), popup );
00172 
00173     // View menu
00174     popup = new QPopupMenu( this );
00175 
00176     actionUninstalled = new QAction( tr( "Show packages not installed" ), QString::null, 0, this, 0 );
00177     actionUninstalled->setToggleAction( TRUE );
00178     actionUninstalled->setWhatsThis( tr( "Click here to show packages available which have not been installed." ) );
00179     connect( actionUninstalled, SIGNAL( activated() ), this, SLOT( filterUninstalledPackages() ) );
00180     actionUninstalled->addTo( popup );
00181 
00182     actionInstalled = new QAction( tr( "Show installed packages" ), QString::null, 0, this, 0 );
00183     actionInstalled->setToggleAction( TRUE );
00184     actionInstalled->setWhatsThis( tr( "Click here to show packages currently installed on this device." ) );
00185     connect( actionInstalled, SIGNAL( activated() ), this, SLOT( filterInstalledPackages() ) );
00186     actionInstalled->addTo( popup );
00187 
00188     actionUpdated = new QAction( tr( "Show updated packages" ), QString::null, 0, this, 0 );
00189     actionUpdated->setToggleAction( TRUE );
00190     actionUpdated->setWhatsThis( tr( "Click here to show packages currently installed on this device which have a newer version available." ) );
00191     connect( actionUpdated, SIGNAL( activated() ), this, SLOT( filterUpgradedPackages() ) );
00192     actionUpdated->addTo( popup );
00193 
00194     popup->insertSeparator();
00195 
00196     actionFilter = new QAction( tr( "Filter by category" ), Opie::Core::OResource::loadPixmap( "aqpkg/filter",
00197                                 Opie::Core::OResource::SmallIcon ),  QString::null, 0, this, 0 );
00198     actionFilter->setToggleAction( TRUE );
00199     actionFilter->setWhatsThis( tr( "Click here to list packages belonging to one category." ) );
00200     connect( actionFilter, SIGNAL( activated() ), this, SLOT( filterCategory() ) );
00201     actionFilter->addTo( popup );
00202 
00203     a = new QAction( tr( "Set filter category" ),  QString::null, 0, this, 0 );
00204     a->setWhatsThis( tr( "Click here to change package category to used filter." ) );
00205     connect( a, SIGNAL( activated() ), this, SLOT( setFilterCategory() ) );
00206     a->addTo( popup );
00207 
00208     popup->insertSeparator();
00209 
00210     a = new QAction( tr( "Find" ), Opie::Core::OResource::loadPixmap( "find", Opie::Core::OResource::SmallIcon ),
00211                      QString::null, 0, this, 0 );
00212     a->setWhatsThis( tr( "Click here to search for text in package names." ) );
00213     connect( a, SIGNAL( activated() ), this, SLOT( displayFindBar() ) );
00214     a->addTo( popup );
00215 
00216     actionFindNext = new QAction( tr( "Find next" ), Opie::Core::OResource::loadPixmap( "next", Opie::Core::OResource::SmallIcon ),
00217                                   QString::null, 0, this, 0 );
00218     actionFindNext->setEnabled( FALSE );
00219     actionFindNext->setWhatsThis( tr( "Click here to find the next package name containing the text you are searching for." ) );
00220     connect( actionFindNext, SIGNAL( activated() ), this, SLOT( repeatFind() ) );
00221     actionFindNext->addTo( popup );
00222     actionFindNext->addTo( findBar );
00223 
00224 
00225     popup->insertSeparator();
00226 
00227     a = new QAction( tr( "Quick Jump keypad" ), Opie::Core::OResource::loadPixmap( "aqpkg/keyboard", Opie::Core::OResource::SmallIcon ),
00228                      QString::null, 0, this, 0 );
00229     a->setWhatsThis( tr( "Click here to display/hide keypad to allow quick movement through the package list." ) );
00230     connect( a, SIGNAL( activated() ), this, SLOT( displayJumpBar() ) );
00231     a->addTo( popup );
00232 
00233     mb->insertItem( tr( "View" ), popup );
00234 
00235     // Finish find toolbar creation
00236     a = new QAction( QString::null, Opie::Core::OResource::loadPixmap( "close", Opie::Core::OResource::SmallIcon ),
00237                      QString::null, 0, this, 0 );
00238     a->setWhatsThis( tr( "Click here to hide the find toolbar." ) );
00239     connect( a, SIGNAL( activated() ), this, SLOT( hideFindBar() ) );
00240     a->addTo( findBar );
00241     findBar->hide();
00242 
00243     // Create widget stack and add UI widgets
00244     stack = new QWidgetStack( this );
00245     stack->addWidget( progressWindow, 2 );
00246     stack->addWidget( networkPkgWindow, 1 );
00247     setCentralWidget( stack );
00248     stack->raiseWidget( progressWindow );
00249 
00250     // Delayed call to finish initialization
00251     QTimer::singleShot( 100, this, SLOT( init() ) );
00252 }
00253 
00254 MainWindow :: ~MainWindow()
00255 {
00256     delete mgr;
00257 
00258     // Reenable suspend mode
00259     QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
00260 }
00261 
00262 void MainWindow :: initMainWidget()
00263 {
00264     networkPkgWindow = new QWidget( this );
00265 
00266     QLabel *l = new QLabel( tr( "Servers:" ), networkPkgWindow );
00267 
00268     serversList = new QComboBox( networkPkgWindow );
00269     connect( serversList, SIGNAL(activated(int)), this, SLOT(serverSelected(int)) );
00270     QWhatsThis::add( serversList, tr( "Click here to select a package feed." ) );
00271 
00272     installedIcon = Opie::Core::OResource::loadPixmap( "installed" );
00273     updatedIcon = Opie::Core::OResource::loadPixmap( "aqpkg/updated" );
00274 
00275     packagesList = new QListView( networkPkgWindow );
00276     packagesList->addColumn( tr( "Packages" ), 225 );
00277     QWhatsThis::add( packagesList, tr( "This is a listing of all packages for the server feed selected above.\n\nA blue dot next to the package name indicates that the package is currently installed.\n\nA blue dot with a star indicates that a newer version of the package is available from the server feed.\n\nClick inside the box at the left to select a package." ) );
00278     QPEApplication::setStylusOperation( packagesList->viewport(), QPEApplication::RightOnHold );
00279     connect( packagesList, SIGNAL(rightButtonPressed(QListViewItem*,const QPoint&,int)),
00280              this, SLOT(slotDisplayPackage(QListViewItem*)) );
00281 
00282     QVBoxLayout *vbox = new QVBoxLayout( networkPkgWindow, 0, -1 );
00283     QHBoxLayout *hbox1 = new QHBoxLayout( vbox, -1 );
00284     hbox1->addWidget( l );
00285     hbox1->addWidget( serversList );
00286 
00287     vbox->addWidget( packagesList );
00288 
00289     downloadEnabled = TRUE;
00290 }
00291 
00292 void MainWindow :: initProgressWidget()
00293 {
00294     progressWindow = new QWidget( this );
00295 
00296     QVBoxLayout *layout = new QVBoxLayout( progressWindow, 4, 4 );
00297 
00298     m_status = new QLabel( progressWindow );
00299     m_status->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
00300     layout->addWidget( m_status );
00301 
00302     m_progress = new QProgressBar( progressWindow );
00303     layout->addWidget( m_progress );
00304 }
00305 
00306 void MainWindow :: init()
00307 {
00308 #ifdef QWS
00309     // read download directory from config file
00310     Config cfg( "aqpkg" );
00311     cfg.setGroup( "settings" );
00312     currentlySelectedServer = cfg.readEntry( "selectedServer", "local" );
00313     //    showJumpTo = cfg.readBoolEntry( "showJumpTo", "true" );
00314 
00315 #endif
00316 
00317     stack->raiseWidget( progressWindow );
00318 
00319     mgr = new DataManager();
00320     connect( mgr, SIGNAL( progressSetSteps(int) ), this, SLOT( setProgressSteps(int) ) );
00321     connect( mgr, SIGNAL( progressSetMessage(const QString&) ),
00322              this, SLOT( setProgressMessage(const QString&) ) );
00323     connect( mgr, SIGNAL( progressUpdate(int) ), this, SLOT( updateProgress(int) ) );
00324     mgr->loadServers();
00325 
00326     showUninstalledPkgs = false;
00327     showInstalledPkgs = false;
00328     showUpgradedPkgs = false;
00329     categoryFilterEnabled = false;
00330 
00331     updateData();
00332 
00333     stack->raiseWidget( networkPkgWindow );
00334 }
00335 
00336 void MainWindow :: setDocument( const QString &doc )
00337 {
00338     // Remove path from package
00339     QString package = Utils::getPackageNameFromIpkFilename( doc );
00340 
00341     // First select local server
00342     for ( int i = 0 ; i < serversList->count() ; ++i )
00343     {
00344         if ( serversList->text( i ) == LOCAL_IPKGS )
00345         {
00346             serversList->setCurrentItem( i );
00347             break;
00348         }
00349     }
00350     serverSelected( 0 );
00351 
00352     // Now set the check box of the selected package
00353     for ( QCheckListItem *item = (QCheckListItem *)packagesList->firstChild();
00354             item != 0 ;
00355             item = (QCheckListItem *)item->nextSibling() )
00356     {
00357         if ( item->text().startsWith( package ) )
00358         {
00359             item->setOn( true );
00360             break;
00361         }
00362     }
00363 }
00364 
00365 void MainWindow :: displaySettings()
00366 {
00367     SettingsImpl *dlg = new SettingsImpl( mgr, this, "Settings", true );
00368     if ( dlg->showDlg() )
00369     {
00370         stack->raiseWidget( progressWindow );
00371         updateData();
00372         stack->raiseWidget( networkPkgWindow );
00373     }
00374     delete dlg;
00375 }
00376 
00377 void MainWindow :: closeEvent( QCloseEvent *e )
00378 {
00379     // If install dialog is visible, return to main view, otherwise close app
00380     QWidget *widget = stack->visibleWidget();
00381 
00382     if ( widget != networkPkgWindow && widget != progressWindow )
00383     {
00384         if ( widget ) delete widget;
00385         stack->raiseWidget( networkPkgWindow );
00386         e->ignore();
00387     }
00388     else
00389     {
00390         e->accept();
00391     }
00392 }
00393 
00394 void MainWindow :: displayFindBar()
00395 {
00396     findBar->show();
00397     findEdit->setFocus();
00398 }
00399 
00400 void MainWindow :: displayJumpBar()
00401 {
00402     jumpBar->show();
00403 }
00404 
00405 void MainWindow :: repeatFind()
00406 {
00407     searchForPackage( findEdit->text() );
00408 }
00409 
00410 void MainWindow :: findPackage( const QString &text )
00411 {
00412     actionFindNext->setEnabled( !text.isEmpty() );
00413     searchForPackage( text );
00414 }
00415 
00416 void MainWindow :: hideFindBar()
00417 {
00418     findBar->hide();
00419 }
00420 
00421 void MainWindow :: hideJumpBar()
00422 {
00423     jumpBar->hide();
00424 }
00425 
00426 void MainWindow :: filterUninstalledPackages()
00427 {
00428     showUninstalledPkgs = actionUninstalled->isOn();
00429     if ( showUninstalledPkgs )
00430     {
00431         showInstalledPkgs = FALSE;
00432         showUpgradedPkgs = FALSE;
00433     }
00434     serverSelected( -1 );
00435 
00436     actionInstalled->setOn( FALSE );
00437     actionUpdated->setOn( FALSE );
00438 }
00439 
00440 void MainWindow :: filterInstalledPackages()
00441 {
00442     showInstalledPkgs = actionInstalled->isOn();
00443     if ( showInstalledPkgs )
00444     {
00445         showUninstalledPkgs = FALSE;
00446         showUpgradedPkgs = FALSE;
00447     }
00448     serverSelected( -1 );
00449 
00450     actionUninstalled->setOn( FALSE );
00451     actionUpdated->setOn( FALSE );
00452 }
00453 
00454 void MainWindow :: filterUpgradedPackages()
00455 {
00456     showUpgradedPkgs = actionUpdated->isOn();
00457     if ( showUpgradedPkgs )
00458     {
00459         showUninstalledPkgs = FALSE;
00460         showInstalledPkgs = FALSE;
00461     }
00462     serverSelected( -1 );
00463 
00464     actionUninstalled->setOn( FALSE );
00465     actionInstalled->setOn( FALSE );
00466 }
00467 
00468 bool MainWindow :: setFilterCategory()
00469 {
00470     // Get categories;
00471     CategoryFilterImpl dlg( DataManager::getAvailableCategories(), categoryFilter, this );
00472     if ( dlg.exec() == QDialog::Accepted )
00473     {
00474         categoryFilter = dlg.getSelectedFilter();
00475 
00476         if ( categoryFilter == "" )
00477             return false;
00478 
00479         categoryFilterEnabled = true;
00480         serverSelected( -1 );
00481         actionFilter->setOn( TRUE );
00482         return true;
00483     }
00484 
00485     return false;
00486 }
00487 
00488 void MainWindow :: filterCategory()
00489 {
00490     if ( !actionFilter->isOn() )
00491     {
00492         filterByCategory( FALSE );
00493     }
00494     else
00495     {
00496         actionFilter->setOn( filterByCategory( TRUE ) );
00497     }
00498 }
00499 
00500 bool MainWindow :: filterByCategory( bool val )
00501 {
00502     if ( val )
00503     {
00504         if ( categoryFilter == "" )
00505         {
00506             if ( !setFilterCategory() )
00507                 return false;
00508         }
00509 
00510         categoryFilterEnabled = true;
00511         serverSelected( -1 );
00512         return true;
00513     }
00514     else
00515     {
00516         // Turn off filter
00517         categoryFilterEnabled = false;
00518         serverSelected( -1 );
00519         return false;
00520     }
00521 }
00522 
00523 void MainWindow :: raiseMainWidget()
00524 {
00525     stack->raiseWidget( networkPkgWindow );
00526 }
00527 
00528 void MainWindow :: raiseProgressWidget()
00529 {
00530     stack->raiseWidget( progressWindow );
00531 }
00532 
00533 void MainWindow :: enableUpgrade( bool enabled )
00534 {
00535     actionUpgrade->setEnabled( enabled );
00536 }
00537 
00538 void MainWindow :: enableDownload( bool enabled )
00539 {
00540     if ( enabled )
00541     {
00542         actionDownload->setIconSet( iconDownload );
00543         actionDownload->setText( tr( "Download" ) );
00544         actionDownload->setWhatsThis( tr( "Click here to download the currently selected package(s)." ) );
00545     }
00546     else
00547     {
00548         actionDownload->setIconSet( iconRemove );
00549         actionDownload->setText( tr( "Remove" ) );
00550         actionDownload->setWhatsThis( tr( "Click here to uninstall the currently selected package(s)." ) );
00551     }
00552 }
00553 
00554 void MainWindow :: setProgressSteps( int numsteps )
00555 {
00556     m_progress->setTotalSteps( numsteps );
00557 }
00558 
00559 void MainWindow :: setProgressMessage( const QString &msg )
00560 {
00561     m_status->setText( msg );
00562 }
00563 
00564 void MainWindow :: updateProgress( int progress )
00565 {
00566     m_progress->setProgress( progress );
00567 }
00568 
00569 void MainWindow :: updateData()
00570 {
00571     m_progress->setTotalSteps( mgr->getServerList().count() );
00572 
00573     serversList->clear();
00574     packagesList->clear();
00575 
00576     int activeItem = -1;
00577     int i = 0;
00578     QString serverName;
00579 
00580     QListIterator<Server> it( mgr->getServerList() );
00581     Server *server;
00582 
00583     for ( ; it.current(); ++it, ++i )
00584     {
00585         server = it.current();
00586         serverName = server->getServerName();
00587         m_status->setText( tr( "Building server list:\n\t%1" ).arg( serverName ) );
00588         m_progress->setProgress( i );
00589         qApp->processEvents();
00590 
00591         if ( !server->isServerActive() )
00592         {
00593             i--;
00594             continue;
00595         }
00596 
00597         serversList->insertItem( serverName );
00598         if ( serverName == currentlySelectedServer )
00599             activeItem = i;
00600     }
00601 
00602     // set selected server to be active server
00603     if ( activeItem != -1 )
00604         serversList->setCurrentItem( activeItem );
00605     serverSelected( 0, FALSE );
00606 }
00607 
00608 void MainWindow :: serverSelected( int index )
00609 {
00610     serverSelected( index, TRUE );
00611 }
00612 
00613 void MainWindow :: serverSelected( int, bool raiseProgress )
00614 {
00615     QPixmap nullIcon( installedIcon.size() );
00616     nullIcon.fill( colorGroup().base() );
00617 
00618     // display packages
00619     QString serverName = serversList->currentText();
00620     currentlySelectedServer = serverName;
00621 
00622     Server *s = mgr->getServer( serverName );
00623 
00624     QList<Package> &list = s->getPackageList();
00625     QListIterator<Package> it( list );
00626 
00627     // Display progress widget while loading list
00628     bool doProgress = ( list.count() > 200 );
00629     if ( doProgress )
00630     {
00631         if ( raiseProgress )
00632         {
00633             stack->raiseWidget( progressWindow );
00634         }
00635         m_progress->setTotalSteps( list.count() );
00636         m_status->setText( tr( "Building package list for:\n\t%1" ).arg( serverName ) );
00637     }
00638 
00639     packagesList->clear();
00640 
00641 #ifdef QWS
00642     // read download directory from config file
00643     Config cfg( "aqpkg" );
00644     cfg.setGroup( "settings" );
00645     cfg.writeEntry( "selectedServer", currentlySelectedServer );
00646 #endif
00647 
00648     int i = 0;
00649     Package *package;
00650     for ( ; it.current(); ++it )
00651     {
00652         // Update progress after every 100th package (arbitrary value, seems to give good balance)
00653         i++;
00654         if ( ( i % 100 ) == 0 )
00655         {
00656             if ( doProgress )
00657             {
00658                 m_progress->setProgress( i );
00659             }
00660             qApp->processEvents();
00661         }
00662 
00663         QString text = "";
00664 
00665         package = it.current();
00666 
00667         // Apply show only uninstalled packages filter
00668         if ( showUninstalledPkgs && package->isInstalled() )
00669             continue;
00670 
00671         // Apply show only installed packages filter
00672         if ( showInstalledPkgs && !package->isInstalled() )
00673             continue;
00674 
00675         // Apply show only new installed packages filter
00676         if ( showUpgradedPkgs )
00677         {
00678             if ( !package->isInstalled() || !package->getNewVersionAvailable() )
00679                 continue;
00680         }
00681 
00682         // Apply the section filter
00683         if ( categoryFilterEnabled && categoryFilter != "" )
00684         {
00685             if ( package->getSection() == "" || categoryFilter.find( package->getSection().lower() ) == -1 )
00686                 continue;
00687         }
00688 
00689         // If the local server, only display installed packages
00690         if ( serverName == LOCAL_SERVER && !package->isInstalled() )
00691             continue;
00692 
00693 
00694         QCheckListItem *item = new QCheckListItem( packagesList, package->getPackageName(),
00695                                QCheckListItem::CheckBox );
00696 
00697         if ( package->isInstalled() )
00698         {
00699             // If a different version of package is available, show update available icon
00700             // Otherwise, show installed icon
00701             if ( package->getNewVersionAvailable())
00702             {
00703 
00704                 item->setPixmap( 0, updatedIcon );
00705             }
00706             else
00707             {
00708                 item->setPixmap( 0, installedIcon );
00709             }
00710         }
00711         else
00712         {
00713             item->setPixmap( 0, nullIcon );
00714         }
00715 
00716         packagesList->insertItem( item );
00717     }
00718 
00719     // If the local server or the local ipkgs server disable the download button
00720     if ( serverName == LOCAL_SERVER )
00721     {
00722         downloadEnabled = TRUE;
00723         actionUpgrade->setEnabled( FALSE );
00724     }
00725     else if ( serverName == LOCAL_IPKGS )
00726     {
00727         downloadEnabled = FALSE;
00728         actionUpgrade->setEnabled( FALSE );
00729     }
00730     else
00731     {
00732         downloadEnabled = TRUE;
00733         actionUpgrade->setEnabled( TRUE );
00734     }
00735     enableDownload( downloadEnabled );
00736 
00737     // Display this widget once everything is done
00738     if ( doProgress && raiseProgress )
00739     {
00740         stack->raiseWidget( networkPkgWindow );
00741     }
00742 }
00743 
00744 void MainWindow :: searchForPackage( const QString &text )
00745 {
00746     if ( !text.isEmpty() )
00747     {
00748         // look through package list for text startng at current position
00749         QCheckListItem *start = (QCheckListItem *)packagesList->currentItem();
00750 
00751         if ( start == 0 )
00752             start = (QCheckListItem *)packagesList->firstChild();
00753 
00754         for ( QCheckListItem *item = start; item != 0 ;
00755                 item = (QCheckListItem *)item->nextSibling() )
00756         {
00757             if ( item->text().lower().find( text ) != -1 )
00758             {
00759                 packagesList->ensureItemVisible( item );
00760                 packagesList->setCurrentItem( item );
00761                 break;
00762             }
00763         }
00764     }
00765 }
00766 
00767 void MainWindow :: updateServer()
00768 {
00769     QString serverName = serversList->currentText();
00770 
00771     // Update the current server
00772     // Display dialog
00773 
00774     // Disable buttons to stop silly people clicking lots on them :)
00775 
00776     // First, write out ipkg_conf file so that ipkg can use it
00777     mgr->writeOutIpkgConf();
00778 
00779     Ipkg *ipkg = new Ipkg;
00780     ipkg->setOption( "update" );
00781 
00782     InstallDlgImpl *dlg = new InstallDlgImpl( ipkg, tr( "Refreshing server package lists" ),
00783                           tr( "Update lists" ) );
00784     connect( dlg, SIGNAL( reloadData(InstallDlgImpl*) ), this, SLOT( reloadData(InstallDlgImpl*) ) );
00785     reloadDocuments = FALSE;
00786     stack->addWidget( dlg, 3 );
00787     stack->raiseWidget( dlg );
00788 
00789     //  delete progDlg;
00790 }
00791 
00792 void MainWindow :: upgradePackages()
00793 {
00794     // We're gonna do an upgrade of all packages
00795     // First warn user that this isn't recommended
00796     // TODO - ODevice????
00797     QString text = tr( "WARNING: Upgrading while\nOpie/Qtopia is running\nis NOT recommended!\n\nAre you sure?\n" );
00798     QMessageBox warn( tr( "Warning" ), text, QMessageBox::Warning,
00799                       QMessageBox::Yes,
00800                       QMessageBox::No | QMessageBox::Escape | QMessageBox::Default ,
00801                       0, this );
00802     warn.adjustSize();
00803 
00804     if ( warn.exec() == QMessageBox::Yes )
00805     {
00806         // First, write out ipkg_conf file so that ipkg can use it
00807         mgr->writeOutIpkgConf();
00808 
00809         // Now run upgrade
00810         Ipkg *ipkg = new Ipkg;
00811         ipkg->setOption( "upgrade" );
00812 
00813         InstallDlgImpl *dlg = new InstallDlgImpl( ipkg, tr( "Upgrading installed packages" ),
00814                               tr ( "Upgrade" ) );
00815         connect( dlg, SIGNAL( reloadData(InstallDlgImpl*) ), this, SLOT( reloadData(InstallDlgImpl*) ) );
00816         reloadDocuments = TRUE;
00817         stack->addWidget( dlg, 3 );
00818         stack->raiseWidget( dlg );
00819     }
00820 }
00821 
00822 void MainWindow :: downloadPackage()
00823 {
00824     bool doUpdate = true;
00825     if ( downloadEnabled )
00826     {
00827         // See if any packages are selected
00828         bool found = false;
00829         if ( serversList->currentText() != LOCAL_SERVER )
00830         {
00831             for ( QCheckListItem *item = (QCheckListItem *)packagesList->firstChild();
00832                     item != 0 && !found;
00833                     item = (QCheckListItem *)item->nextSibling() )
00834             {
00835                 if ( item->isOn() )
00836                     found = true;
00837             }
00838         }
00839 
00840         // If user selected some packages then download the and store the locally
00841         // otherwise, display dialog asking user what package to download from an http server
00842         // and whether to install it
00843         if ( found )
00844             downloadSelectedPackages();
00845         else
00846             downloadRemotePackage();
00847 
00848     }
00849     else
00850     {
00851         doUpdate = false;
00852         for ( QCheckListItem *item = (QCheckListItem *)packagesList->firstChild();
00853                 item != 0 ;
00854                 item = (QCheckListItem *)item->nextSibling() )
00855         {
00856             if ( item->isOn() )
00857             {
00858                 QString name = item->text();
00859                 int pos = name.find( "*" );
00860                 name.truncate( pos );
00861 
00862                 // if (there is a (installed), remove it
00863                 pos = name.find( "(installed)" );
00864                 if ( pos > 0 )
00865                     name.truncate( pos - 1 );
00866 
00867                 Package *p = mgr->getServer( serversList->currentText() )->getPackage( name );
00868 
00869                 QString msgtext;
00870                 msgtext = tr( "Are you sure you wish to delete\n%1?" ).arg( (const char *)p->getPackageName() );
00871                 if ( QMessageBox::information( this, tr( "Are you sure?" ),
00872                                                msgtext, tr( "No" ), tr( "Yes" ) ) == 1 )
00873                 {
00874                     doUpdate = true;
00875                     QFile f( p->getFilename() );
00876                     f.remove();
00877                 }
00878             }
00879         }
00880     }
00881 
00882     if ( doUpdate )
00883     {
00884         reloadData( 0x0 );
00885     }
00886 }
00887 
00888 void MainWindow :: downloadSelectedPackages()
00889 {
00890     // First, write out ipkg_conf file so that ipkg can use it
00891     mgr->writeOutIpkgConf();
00892 
00893     // Display dialog to user asking where to download the files to
00894     bool ok = FALSE;
00895     QString dir = "";
00896 #ifdef QWS
00897     // read download directory from config file
00898     Config cfg( "aqpkg" );
00899     cfg.setGroup( "settings" );
00900     dir = cfg.readEntry( "downloadDir", "/home/root/Documents/application/ipkg" );
00901 #endif
00902 
00903     QString text = InputDialog::getText( tr( "Download to where" ), tr( "Enter path to download to" ), dir, &ok, this );
00904     if ( ok && !text.isEmpty() )
00905         dir = text;   // user entered something and pressed ok
00906     else
00907         return; // user entered nothing or pressed cancel
00908 
00909 #ifdef QWS
00910     // Store download directory in config file
00911     cfg.writeEntry( "downloadDir", dir );
00912 #endif
00913 
00914     // Get starting directory
00915     char initDir[PATH_MAX];
00916     getcwd( initDir, PATH_MAX );
00917 
00918     // Download each package
00919     Ipkg ipkg;
00920     connect( &ipkg, SIGNAL(outputText(const QString&)), this, SLOT(displayText(const QString&)));
00921 
00922     ipkg.setOption( "download" );
00923     ipkg.setRuntimeDirectory( dir );
00924     for ( QCheckListItem *item = (QCheckListItem *)packagesList->firstChild();
00925             item != 0 ;
00926             item = (QCheckListItem *)item->nextSibling() )
00927     {
00928         if ( item->isOn() )
00929         {
00930             ipkg.setPackage( item->text() );
00931             ipkg.runIpkg( );
00932         }
00933     }
00934 }
00935 
00936 void MainWindow :: downloadRemotePackage()
00937 {
00938     // Display dialog
00939     bool ok;
00940     QString package = InputDialog::getText( tr( "Install Remote Package" ), tr( "Enter package location" ), "http://", &ok, this );
00941     if ( !ok || package.isEmpty() )
00942         return;
00943     //    DownloadRemoteDlgImpl dlg( this, "Install", true );
00944     //    if ( dlg.exec() == QDialog::Rejected )
00945     //        return;
00946 
00947     // grab details from dialog
00948     //    QString package = dlg.getPackageLocation();
00949 
00950     InstallData *item = new InstallData();
00951     item->option = "I";
00952     item->packageName = package;
00953     QList<InstallData> workingPackages;
00954     workingPackages.setAutoDelete( TRUE );
00955     workingPackages.append( item );
00956 
00957     InstallDlgImpl *dlg = new InstallDlgImpl( workingPackages, mgr, tr( "Download" ) );
00958     connect( dlg, SIGNAL( reloadData(InstallDlgImpl*) ), this, SLOT( reloadData(InstallDlgImpl*) ) );
00959     reloadDocuments = TRUE;
00960     stack->addWidget( dlg, 3 );
00961     stack->raiseWidget( dlg );
00962 }
00963 
00964 
00965 void MainWindow :: applyChanges()
00966 {
00967     stickyOption = "";
00968 
00969     // First, write out ipkg_conf file so that ipkg can use it
00970     mgr->writeOutIpkgConf();
00971 
00972     // Now for each selected item
00973     // deal with it
00974 
00975     QList<InstallData> workingPackages;
00976     workingPackages.setAutoDelete( TRUE );
00977     for ( QCheckListItem *item = (QCheckListItem *)packagesList->firstChild();
00978             item != 0 ;
00979             item = (QCheckListItem *)item->nextSibling() )
00980     {
00981         if ( item->isOn() )
00982         {
00983             InstallData *instdata = dealWithItem( item );
00984             if ( instdata )
00985                 workingPackages.append( instdata );
00986             else
00987                 return;
00988         }
00989     }
00990 
00991     if ( workingPackages.count() == 0 )
00992     {
00993         // Nothing to do
00994         QMessageBox::information( this, tr( "Nothing to do" ),
00995                                   tr( "No packages selected" ), tr( "OK" ) );
00996 
00997         return;
00998     }
00999 
01000     // do the stuff
01001     InstallDlgImpl *dlg = new InstallDlgImpl( workingPackages, mgr, tr( "Apply changes" ) );
01002     connect( dlg, SIGNAL( reloadData(InstallDlgImpl*) ), this, SLOT( reloadData(InstallDlgImpl*) ) );
01003     reloadDocuments = TRUE;
01004     stack->addWidget( dlg, 3 );
01005     stack->raiseWidget( dlg );
01006 }
01007 
01008 // decide what to do - either remove, upgrade or install
01009 // Current rules:
01010 //    If not installed - install
01011 //    If installed and different version available - upgrade
01012 //    If installed and version up to date - remove
01013 InstallData *MainWindow :: dealWithItem( QCheckListItem *item )
01014 {
01015     QString name = item->text();
01016 
01017     // Get package
01018     Server *s = mgr->getServer( serversList->currentText() );
01019     Package *p = s->getPackage( name );
01020 
01021     // If the package has a filename then it is a local file
01022     if ( p->isPackageStoredLocally() )
01023         name = p->getFilename();
01024 
01025     QString option;
01026     QString dest = "root";
01027     if ( !p->isInstalled() )
01028     {
01029         InstallData *newitem = new InstallData();
01030         newitem->option = "I";
01031         newitem->packageName = name;
01032         return newitem;
01033     }
01034     else
01035     {
01036         InstallData *newitem = new InstallData();
01037         newitem->option = "D";
01038         // If local file, remove using package name, not filename
01039         if ( p->isPackageStoredLocally() )
01040             name = item->text();
01041 
01042         if ( !p->isPackageStoredLocally() )
01043             newitem->packageName = p->getInstalledPackageName();
01044         else
01045             newitem->packageName = name;
01046 
01047         if ( p->getInstalledTo() )
01048         {
01049             newitem->destination = p->getInstalledTo();
01050         }
01051         else
01052         {
01053             newitem->destination = p->getLocalPackage()->getInstalledTo();
01054         }
01055 
01056         // Now see if version is newer or not
01057         int val = compareVersions( p->getInstalledVersion(), p->getVersion() );
01058 
01059         // If the version requested is older and user selected a local ipk file, then reinstall the file
01060         if ( p->isPackageStoredLocally() && val == -1 )
01061             val = 0;
01062 
01063         if ( val == -2 )
01064         {
01065             // Error - should handle
01066         }
01067         else if ( val == -1 )
01068         {
01069             // Version available is older - remove only
01070             newitem->option = "D";
01071             // If local file, remove using package name, not filename
01072             if ( p->isPackageStoredLocally() )
01073                 name = item->text();
01074         }
01075         else
01076         {
01077             QString caption;
01078             QString text;
01079             QString secondButton;
01080             QString secondOption;
01081             if ( val == 0 )
01082             {
01083                 // Version available is the same - option to remove or reinstall
01084                 caption = tr( "Do you wish to remove or reinstall\n%1?" );
01085                 text = tr( "Remove or ReInstall" );
01086                 secondButton = tr( "ReInstall" );
01087                 secondOption = "R"; // Internal action code, do not translate
01088             }
01089             else if ( val == 1 )
01090             {
01091                 // Version available is newer - option to remove or upgrade
01092                 caption = tr( "Do you wish to remove or upgrade\n%1?" );
01093                 text = tr( "Remove or Upgrade" );
01094                 secondButton = tr( "Upgrade" );
01095                 secondOption = "U"; // Internal action code, do not translate
01096             }
01097 
01098             // Sticky option not implemented yet, but will eventually allow
01099             // the user to say something like 'remove all'
01100             if ( stickyOption == "" )
01101             {
01102                 QString msgtext;
01103                 msgtext = caption.arg( ( const char * )name );
01104                 QuestionDlg dlg( text, msgtext, secondButton );
01105                 switch( dlg.exec() )
01106                 {
01107                 case 0: // Cancel
01108                     delete newitem;
01109                     return 0x0;
01110                     break;
01111                 case 1: // Remove
01112                     newitem->option = "D";
01113                     // If local file, remove using package name, not filename
01114                     if ( p->isPackageStoredLocally() )
01115                         name = item->text();
01116                     break;
01117                 case 2: // Reinstall or Upgrade
01118                     newitem->option = secondOption;
01119                     break;
01120                 }
01121             }
01122             else
01123             {
01124                 //                newitem->option = stickyOption;
01125             }
01126         }
01127 
01128 
01129         // Check if we are reinstalling the same version
01130         if ( newitem->option != "R" )
01131             newitem->recreateLinks = true;
01132         else
01133             newitem->recreateLinks = false;
01134 
01135         // User hit cancel (on dlg - assume remove)
01136         return newitem;
01137     }
01138 }
01139 
01140 void MainWindow :: reloadData( InstallDlgImpl *dlg )
01141 {
01142     stack->raiseWidget( progressWindow );
01143 
01144     if ( dlg )
01145     {
01146         dlg->close();
01147         delete dlg;
01148     }
01149 
01150     mgr->reloadServerData();
01151     serverSelected( -1, FALSE );
01152 
01153 #ifdef QWS
01154     if ( reloadDocuments )
01155     {
01156         m_status->setText( tr( "Updating Launcher..." ) );
01157 
01158         // Finally let the main system update itself
01159         QCopEnvelope e("QPE/System", "linkChanged(QString)");
01160         QString lf = QString::null;
01161         e << lf;
01162     }
01163 #endif
01164 
01165     stack->raiseWidget( networkPkgWindow );
01166 }
01167 
01168 void MainWindow :: letterPushed( QString t )
01169 {
01170     QCheckListItem *top = (QCheckListItem *)packagesList->firstChild();
01171     QCheckListItem *start = (QCheckListItem *)packagesList->currentItem();
01172     if ( packagesList->firstChild() == 0 )
01173         return;
01174 
01175     QCheckListItem *item;
01176     if ( start == 0 )
01177     {
01178         item = (QCheckListItem *)packagesList->firstChild();
01179         start = top;
01180     }
01181     else
01182         item = (QCheckListItem *)start->nextSibling();
01183 
01184     if ( item == 0 )
01185         item = (QCheckListItem *)packagesList->firstChild();
01186     do
01187     {
01188         if ( item->text().lower().startsWith( t.lower() ) )
01189         {
01190             packagesList->setSelected( item, true );
01191             packagesList->ensureItemVisible( item );
01192             break;
01193         }
01194 
01195         item = (QCheckListItem *)item->nextSibling();
01196         if ( !item )
01197             item = (QCheckListItem *)packagesList->firstChild();
01198     }
01199     while ( item != start);
01200 }
01201 
01202 void MainWindow :: slotDisplayPackage( QListViewItem *item )
01203 {
01204     QString itemstr( ((QCheckListItem*)item)->text() );
01205     PackageWindow *p = new PackageWindow( mgr->getServer( serversList->currentText() )->getPackage( itemstr ) );
01206     QPEApplication::showWidget( p );
01207 }
01208 
01209 QuestionDlg::QuestionDlg( const QString &caption, const QString &text, const QString &secondbtn )
01210         : QWidget( 0x0, 0x0, WType_Modal | WType_TopLevel | WStyle_Dialog )
01211 {
01212     setCaption( caption );
01213     resize( 175, 100 );
01214 
01215     QGridLayout *layout = new QGridLayout( this );
01216 
01217     QLabel *l = new QLabel( text, this );
01218     l->setAlignment( AlignCenter | WordBreak );
01219     layout->addMultiCellWidget( l, 0, 0, 0, 1 );
01220 
01221     btn1 = new QPushButton( tr( "Remove" ), this );
01222     connect( btn1, SIGNAL(clicked()), this, SLOT(slotButtonPressed()) );
01223     layout->addWidget( btn1, 1, 0 );
01224 
01225     btn2 = new QPushButton( secondbtn, this );
01226     connect( btn2, SIGNAL(clicked()), this, SLOT(slotButtonPressed()) );
01227     layout->addWidget( btn2, 1, 1 );
01228 
01229     executing = FALSE;
01230 }
01231 
01232 int QuestionDlg::exec()
01233 {
01234     show();
01235 
01236     if ( !executing )
01237     {
01238         executing = TRUE;
01239         qApp->enter_loop();
01240     }
01241 
01242     return buttonpressed;
01243 }
01244 
01245 void QuestionDlg::slotButtonPressed()
01246 {
01247     if ( sender() == btn1 )
01248         buttonpressed = 1;
01249     else if ( sender() == btn2 )
01250         buttonpressed = 2;
01251     else
01252         buttonpressed = 0;
01253 
01254     qApp->exit_loop();
01255 }

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