42 files changed, 3927 insertions, 0 deletions
diff --git a/apps/Settings/packagemanager.desktop b/apps/Settings/packagemanager.desktop new file mode 100644 index 0000000..c631ff8 --- a/dev/null +++ b/apps/Settings/packagemanager.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Exec=packagemanager +Icon=packagemanager/packagemanager +MimeType=application/ipkg +MimeTypeIcons=packagemanager/ipkg +Type=Application +Name=Package Manager +Comment=Opie package management client diff --git a/noncore/settings/packagemanager/ChangeLog b/noncore/settings/packagemanager/ChangeLog new file mode 100644 index 0000000..a01c8b3 --- a/dev/null +++ b/noncore/settings/packagemanager/ChangeLog @@ -0,0 +1,4 @@ +2004-01-nn Dan Williams <drw@handhelds.org> + + * Released version 0.1.0 + * Initial check-in of new package management client to eventually replace AQPkg diff --git a/noncore/settings/packagemanager/README b/noncore/settings/packagemanager/README new file mode 100644 index 0000000..3e3f409 --- a/dev/null +++ b/noncore/settings/packagemanager/README @@ -0,0 +1,40 @@ +/************************************************************************ +/* +/* Opie - Package Manager +/* ======================== +/* Version 0.1.0 +/* +/* A package management client for Opie +/* +/************************************************************************ + +------------------------------------------------------- + Release Notes for Opie-PackageManager - January, 2004 +------------------------------------------------------- + +====================== += To-do = +====================== + +- See $OPIEDIR/noncore/settings/packagemanager/TODO for more info. + +====================== += Run = +====================== + +- In order to use opie-packagemanager, ipkg must be installed and + configured on the system. + +====================== += Credits = +====================== + +- Opie-PackageManager is (C) 2003-2004 Dan Williams + +====================== += Links = +====================== + +- Opie Project: http://opie.handhelds.org +- OpenZaurus Project: http://openzaurus.org +- Familiar Project: http://familiar.handhelds.org diff --git a/noncore/settings/packagemanager/config.in b/noncore/settings/packagemanager/config.in new file mode 100644 index 0000000..4b47e65 --- a/dev/null +++ b/noncore/settings/packagemanager/config.in @@ -0,0 +1,4 @@ + config PACKAGEMANAGER + boolean "opie-packagemanager (package management client)" + default "y" + depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE diff --git a/noncore/settings/packagemanager/filterdlg.cpp b/noncore/settings/packagemanager/filterdlg.cpp new file mode 100644 index 0000000..2e48d5b --- a/dev/null +++ b/noncore/settings/packagemanager/filterdlg.cpp @@ -0,0 +1,179 @@ +/* + This file is part of the OPIE Project + + =. Copyright (c) 2003 Dan Williams <drw@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This file is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This file is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU General +..}^=.= = ; Public License for more details. +++= -. .` .: + : = ...= . :.=- You should have received a copy of the GNU + -. .:....=;==+<; General Public License along with this file; + -_. . . )=. = see the file COPYING. If not, write to the + -- :-=` Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#include "filterdlg.h" + +FilterDlg::FilterDlg( QWidget *parent, OPackageManager *pm, const QString &name, + const QString &server, const QString &destination, + OPackageManager::Status status, const QString &category ) + : QDialog( parent, QString::null, true ) +{ + setCaption( tr( "Filter packages" ) ); + + QVBoxLayout *layout = new QVBoxLayout( this ); + QScrollView *sv = new QScrollView( this ); + layout->addWidget( sv, 0, 0 ); + sv->setResizePolicy( QScrollView::AutoOneFit ); + sv->setFrameStyle( QFrame::NoFrame ); + QWidget *container = new QWidget( sv->viewport() ); + sv->addChild( container ); + layout = new QVBoxLayout( container, 4, 4 ); + + // Category + m_categoryCB = new QCheckBox( tr( "Category:" ), container ); + connect( m_categoryCB, SIGNAL(toggled(bool)), this, SLOT(slotCategorySelected(bool)) ); + m_category = new QComboBox( container ); + m_category->insertStringList( pm->categories() ); + initItem( m_category, m_categoryCB, category ); + layout->addWidget( m_categoryCB ); + layout->addWidget( m_category ); + + // Package name + m_nameCB = new QCheckBox( tr( "Names containing:" ), container ); + connect( m_nameCB, SIGNAL(toggled(bool)), this, SLOT(slotNameSelected(bool)) ); + m_name = new QLineEdit( name, container ); + if ( !name.isNull() ) + m_nameCB->setChecked( true ); + m_name->setEnabled( !name.isNull() ); + layout->addWidget( m_nameCB ); + layout->addWidget( m_name ); + + // Status + m_statusCB = new QCheckBox( tr( "With the status:" ), container ); + connect( m_statusCB, SIGNAL(toggled(bool)), this, SLOT(slotStatusSelected(bool)) ); + m_status = new QComboBox( container ); + connect( m_status, SIGNAL(activated(const QString &)), this, SLOT(slotStatusChanged(const QString &)) ); + QString currStatus; + switch ( status ) + { + case OPackageManager::All : currStatus = tr( "All" ); + break; + case OPackageManager::Installed : currStatus = tr( "Installed" ); + break; + case OPackageManager::NotInstalled : currStatus = tr( "Not installed" ); + break; + case OPackageManager::Updated : currStatus = tr( "Updated" ); + break; + default : currStatus = QString::null; + }; + m_status->insertItem( tr( "All" ) ); + m_status->insertItem( tr( "Installed" ) ); + m_status->insertItem( tr( "Not installed" ) ); + m_status->insertItem( tr( "Updated" ) ); + initItem( m_status, m_statusCB, currStatus ); + layout->addWidget( m_statusCB ); + layout->addWidget( m_status ); + + // Server + m_serverCB = new QCheckBox( tr( "Available from the following server:" ), container ); + connect( m_serverCB, SIGNAL(toggled(bool)), this, SLOT(slotServerSelected(bool)) ); + m_server = new QComboBox( container ); + m_server->insertStringList( *(pm->servers()) ); + initItem( m_server, m_serverCB, server ); + layout->addWidget( m_serverCB ); + layout->addWidget( m_server ); + + // Destination + m_destCB = new QCheckBox( tr( "Installed on device at:" ), container ); + connect( m_destCB, SIGNAL(toggled(bool)), this, SLOT(slotDestSelected(bool)) ); + m_destination = new QComboBox( container ); + m_destination->insertStringList( *(pm->destinations()) ); + initItem( m_destination, m_destCB, destination ); + layout->addWidget( m_destCB ); + layout->addWidget( m_destination ); + + showMaximized(); +} + +void FilterDlg::initItem( QComboBox *comboBox, QCheckBox *checkBox, const QString &selection ) +{ + if ( !selection.isNull() ) + { + checkBox->setChecked( true ); + + for ( int i = 0; i < comboBox->count(); i++ ) + { + if ( comboBox->text( i ) == selection ) + { + comboBox->setCurrentItem( i ); + return; + } + } + } + comboBox->setEnabled( !selection.isNull() ); +} + +void FilterDlg::slotNameSelected( bool selected ) +{ + m_name->setEnabled( selected ); +} + +void FilterDlg::slotServerSelected( bool selected ) +{ + m_server->setEnabled( selected ); +} + +void FilterDlg::slotDestSelected( bool selected ) +{ + m_destination->setEnabled( selected ); +} + +void FilterDlg::slotStatusSelected( bool selected ) +{ + m_status->setEnabled( selected ); + + if ( !selected && !m_destCB->isEnabled() ) + { + // If status check box has been deselected and destination option was previously deselected + // (because status == "Not installed"), re-enable destination option + m_destCB->setEnabled( true ); + m_destination->setEnabled( true ); + } + else if ( selected && m_destCB->isEnabled() && m_status->currentText() == tr( "Not installed" ) ) + { + // If status check box has been selected and status == "Not installed", disable destination option + m_destCB->setEnabled( false ); + m_destCB->setChecked( false ); + m_destination->setEnabled( false ); + } +} + +void FilterDlg::slotStatusChanged( const QString &category ) +{ + bool notInstalled = ( category == tr( "Not installed" ) ); + m_destCB->setEnabled( !notInstalled ); + m_destination->setEnabled( !notInstalled ); + if ( notInstalled ) + m_destCB->setChecked( false ); +} + +void FilterDlg::slotCategorySelected( bool selected ) +{ + m_category->setEnabled( selected ); +} diff --git a/noncore/settings/packagemanager/filterdlg.h b/noncore/settings/packagemanager/filterdlg.h new file mode 100644 index 0000000..42bae8b --- a/dev/null +++ b/noncore/settings/packagemanager/filterdlg.h @@ -0,0 +1,101 @@ +/* + This file is part of the OPIE Project + + =. Copyright (c) 2003 Dan Williams <drw@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This file is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This file is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU General +..}^=.= = ; Public License for more details. +++= -. .` .: + : = ...= . :.=- You should have received a copy of the GNU + -. .:....=;==+<; General Public License along with this file; + -_. . . )=. = see the file COPYING. If not, write to the + -- :-=` Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#ifndef FILTERDLG_H +#define FILTERDLG_H + +#include <qcheckbox.h> +#include <qdialog.h> +#include <qcombobox.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qscrollview.h> + +#include "opackagemanager.h" + +class FilterDlg : public QDialog +{ + Q_OBJECT + +public: + FilterDlg( QWidget *parent = 0x0, OPackageManager *pm = 0x0, const QString &name = 0x0, + const QString &server = 0x0, const QString &destination = 0x0, + OPackageManager::Status status = OPackageManager::All, + const QString &category = 0x0 ); + + const QString &name() + { return m_nameCB->isChecked() ? m_name->text() : QString::null; }; + const QString &server() + { return m_serverCB->isChecked() ? m_server->currentText() : QString::null; }; + const QString &destination() + { return m_destCB->isChecked() ? m_destination->currentText() : QString::null; }; + OPackageManager::Status status() + { + if ( m_statusCB->isChecked() ) + { + if ( m_status->currentText() == tr( "All" ) ) + return OPackageManager::All; + else if ( m_status->currentText() == tr( "Installed" ) ) + return OPackageManager::Installed; + else if ( m_status->currentText() == tr( "Not installed" ) ) + return OPackageManager::NotInstalled; + else if ( m_status->currentText() == tr( "Updated" ) ) + return OPackageManager::Updated; + } + else + return OPackageManager::NotDefined; + }; + const QString &category() + { return m_categoryCB->isChecked() ? m_category->currentText() : QString::null; }; + +private: + QCheckBox *m_nameCB; + QCheckBox *m_serverCB; + QCheckBox *m_destCB; + QCheckBox *m_statusCB; + QCheckBox *m_categoryCB; + + QLineEdit *m_name; + QComboBox *m_server; + QComboBox *m_destination; + QComboBox *m_status; + QComboBox *m_category; + + void initItem( QComboBox *comboBox, QCheckBox *checkBox, const QString &selection ); + +private slots: + void slotNameSelected( bool ); + void slotServerSelected( bool ); + void slotDestSelected( bool ); + void slotStatusSelected( bool ); + void slotStatusChanged( const QString & ); + void slotCategorySelected( bool ); +}; + +#endif diff --git a/noncore/settings/packagemanager/global.h b/noncore/settings/packagemanager/global.h new file mode 100644 index 0000000..0fe5b85 --- a/dev/null +++ b/noncore/settings/packagemanager/global.h @@ -0,0 +1,37 @@ +/* + This file is part of the Opie Project + + Copyright (c) 2003 Dan Williams <drw@handhelds.org> + =. + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#ifndef GLOBAL_H +#define GLOBAL_H + +#define VERSION "0.0.0" + +#endif
\ No newline at end of file diff --git a/noncore/settings/packagemanager/installdlg.cpp b/noncore/settings/packagemanager/installdlg.cpp new file mode 100644 index 0000000..c0c03fc --- a/dev/null +++ b/noncore/settings/packagemanager/installdlg.cpp @@ -0,0 +1,306 @@ +/* + This file is part of the OPIE Project + + =. Copyright (c) 2003 Dan Williams <drw@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This file is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This file is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU General +..}^=.= = ; Public License for more details. +++= -. .` .: + : = ...= . :.=- You should have received a copy of the GNU + -. .:....=;==+<; General Public License along with this file; + -_. . . )=. = see the file COPYING. If not, write to the + -- :-=` Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#include "installdlg.h" + +#include <sys/vfs.h> + +#include <qapplication.h> +#include <qcombobox.h> +#include <qfileinfo.h> +#include <qgroupbox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qmap.h> +#include <qmultilineedit.h> +#include <qpushbutton.h> + +#include <qpe/fileselector.h> +#include <qpe/resource.h> +#include <qpe/storage.h> + +#include <opie/ofiledialog.h> + +#include "opackagemanager.h" + +InstallDlg::InstallDlg( QWidget *parent, OPackageManager *pm, const QString &caption, bool showDestInfo, + OPackage::Command command1, QStringList *packages1, + OPackage::Command command2, QStringList *packages2, + OPackage::Command command3, QStringList *packages3 ) + : QWidget( 0x0 ) + , m_packman( pm ) + , m_numCommands( 0 ) + , m_currCommand( 0 ) +{ + // Save command/package list information + if ( command1 != OPackage::NotDefined ) + { + m_command[ m_numCommands ] = command1; + m_packages[ m_numCommands ] = packages1; + ++m_numCommands; + } + if ( command2 != OPackage::NotDefined ) + { + m_command[ m_numCommands ] = command2; + m_packages[ m_numCommands ] = packages2; + ++m_numCommands; + } + if ( command3 != OPackage::NotDefined ) + { + m_command[ m_numCommands ] = command3; + m_packages[ m_numCommands ] = packages3; + ++m_numCommands; + } + + // Initialize UI + if ( parent ) + parent->setCaption( caption ); + + QGridLayout *layout = new QGridLayout( this, 4, 2, 2, 4 ); + + if ( showDestInfo ) + { + QLabel *label = new QLabel( tr( "Destination" ), this ); + layout->addWidget( label, 0, 0 ); + m_destination = new QComboBox( this ); + m_destination->insertStringList( *(m_packman->destinations()) ); + layout->addWidget( m_destination, 0, 1 ); + connect( m_destination, SIGNAL(highlighted(const QString&)), + this, SLOT(slotDisplayAvailSpace(const QString&)) ); + + label = new QLabel( tr( "Space Avail" ), this ); + layout->addWidget( label, 1, 0 ); + m_availSpace = new QLabel( this ); + layout->addWidget( m_availSpace, 1, 1 ); + + // TODO - select correct destination + slotDisplayAvailSpace( m_destination->currentText() ); + } + else + { + m_destination = 0x0; + m_availSpace = 0x0; + } + + QGroupBox *groupBox = new QGroupBox( 0, Qt::Vertical, tr( "Output" ), this ); + groupBox->layout()->setSpacing( 0 ); + groupBox->layout()->setMargin( 4 ); + + QVBoxLayout *groupBoxLayout = new QVBoxLayout( groupBox->layout() ); + m_output = new QMultiLineEdit( groupBox ); + m_output->setReadOnly( true ); + groupBoxLayout->addWidget( m_output ); + layout->addMultiCellWidget( groupBox, 2, 2, 0, 1 ); + + m_btnStart = new QPushButton( Resource::loadPixmap( "packagemanager/apply" ), tr( "Start" ), this ); + layout->addWidget( m_btnStart, 3, 0 ); + connect( m_btnStart, SIGNAL(clicked()), this, SLOT(slotBtnStart()) ); + + m_btnOptions = new QPushButton( Resource::loadPixmap( "SettingsIcon" ), tr( "Options" ), this ); + layout->addWidget( m_btnOptions, 3, 1 ); + connect( m_btnOptions, SIGNAL( clicked() ), this, SLOT(slotBtnOptions()) ); + + // Display packages being acted upon in output widget + for( int i = 0; i < m_numCommands; i++ ) + { + if ( m_packages[ i ] ) + { + QString lineStr = tr( "Packages to " ); + + switch( m_command[ i ] ) + { + case OPackage::Install : lineStr.append( tr( "install" ) ); + break; + case OPackage::Remove : lineStr.append( tr( "remove" ) ); + break; + case OPackage::Upgrade : lineStr.append( tr( "upgrade" ) ); + break; + default : + break; + }; + lineStr.append( ":\n" ); + + for ( QStringList::Iterator it = m_packages[ i ]->begin(); it != m_packages[ i ]->end(); ++it ) + { + lineStr.append( QString( "\t%1\n" ).arg( ( *it ) ) ); + } + + m_output->append( lineStr ); + } + } + + m_output->append( tr( "Press the start button to begin.\n" ) ); + m_output->setCursorPosition( m_output->numLines(), 0 ); + +} + +InstallDlg::~InstallDlg() +{ + for( int i = 0; i < m_numCommands; i++ ) + { + if ( m_packages[ i ] ) + delete m_packages[ i ]; + } +} + +void InstallDlg::slotDisplayAvailSpace( const QString &destination ) +{ + // If available space is not displayed, exit + if ( !m_availSpace ) + return; + + QString space = tr( "Unknown" ); + + // Get destination + OConfItem *dest = m_packman->findConfItem( OConfItem::Destination, destination ); + + if ( dest ) + { + // Calculate available space + struct statfs fs; + if ( !statfs( dest->value(), &fs ) ) + { + long mult = fs.f_bsize / 1024; + long div = 1024 / fs.f_bsize; + + if ( !mult ) mult = 1; + if ( !div ) div = 1; + long avail = fs.f_bavail * mult / div; + + space = tr( "%1 Kb" ).arg( avail ); + } + } + + // Display available space (if known) + m_availSpace->setText( space ); +} + +void InstallDlg::slotBtnStart() +{ + QString btnText = m_btnStart->text(); + if ( btnText == tr( "Abort" ) ) + { + // Stop execution of current command and prevent any others from executing + m_packman->abortCommand(); + m_currCommand = 999; + + // Allow user to close dialog + m_btnStart->setText( tr( "Close" ) ); + m_btnStart->setIconSet( Resource::loadPixmap( "enter" ) ); + return; + } + else if ( btnText == tr( "Close" ) ) + { + // TODO - force reload of package data + emit closeInstallDlg(); + return; + } + + // Start was clicked, execute first command + m_btnOptions->setEnabled( false ); + m_btnStart->setText( tr( "Abort" ) ); + m_btnStart->setIconSet( Resource::loadPixmap( "close" ) ); + + m_packman->executeCommand( m_command[ 0 ], m_packages[ 0 ], m_destination->currentText(), this, + SLOT(slotOutput(OProcess*,char*,int)), SLOT(slotErrors(OProcess*,char*,int)), + SLOT(slotFinished(OProcess*)), true ); +} + +void InstallDlg::slotBtnOptions() +{ + QString btnText = m_btnOptions->text(); + if ( btnText == tr( "Options" ) ) + { + // Display configuration dialog (only options tab is enabled) + m_packman->configureDlg( true ); + return; + } + + // Save output was clicked + QMap<QString, QStringList> map; + map.insert( tr( "All" ), QStringList() ); + QStringList text; + text << "text/*"; + map.insert(tr( "Text" ), text ); + text << "*"; + map.insert( tr( "All" ), text ); + + QString filename = OFileDialog::getSaveFileName( 2, "/", "ipkg-output", map ); + if( !filename.isEmpty() ) + { + QString currentFileName = QFileInfo( filename ).fileName(); + DocLnk doc; + doc.setType( "text/plain" ); + doc.setFile( filename ); + doc.setName( currentFileName ); + FileManager fm; + fm.saveFile( doc, m_output->text() ); + } +} + +void InstallDlg::slotOutput( OProcess */*process*/, char *buffer, int buffLen ) +{ + QString lineStr = buffer; + if ( lineStr[buffLen-1] == '\n' ) + lineStr.truncate( buffLen - 1 ); + m_output->append( lineStr ); + m_output->setCursorPosition( m_output->numLines(), 0 ); +} + +void InstallDlg::slotErrors( OProcess */*process*/, char *buffer, int buffLen ) +{ + QString lineStr = buffer; + if ( lineStr[buffLen-1] == '\n' ) + lineStr.truncate( buffLen - 1 ); + m_output->append( lineStr ); + m_output->setCursorPosition( m_output->numLines(), 0 ); +} + +void InstallDlg::slotFinished( OProcess */*process*/ ) +{ + ++m_currCommand; + if ( m_currCommand < m_numCommands ) + { + // More commands left, execute next one + m_packman->executeCommand( m_command[ m_currCommand ], m_packages[ m_currCommand ], m_destination->currentText(), + this, SLOT(slotOutput(OProcess*,char*,int)), + SLOT(slotErrors(OProcess*,char*,int)), + SLOT(slotFinished(OProcess*)), true ); + } + else + { + // All commands executed, allow user to close dialog + m_btnStart->setText( tr( "Close" ) ); + m_btnStart->setIconSet( Resource::loadPixmap( "enter" ) ); + + m_btnOptions->setEnabled( true ); + m_btnOptions->setText( tr( "Save output" ) ); + m_btnOptions->setIconSet( Resource::loadPixmap( "save" ) ); + } +} diff --git a/noncore/settings/packagemanager/installdlg.h b/noncore/settings/packagemanager/installdlg.h new file mode 100644 index 0000000..8075f1d --- a/dev/null +++ b/noncore/settings/packagemanager/installdlg.h @@ -0,0 +1,89 @@ +/* + This file is part of the OPIE Project + + =. Copyright (c) 2003 Dan Williams <drw@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This file is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This file is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU General +..}^=.= = ; Public License for more details. +++= -. .` .: + : = ...= . :.=- You should have received a copy of the GNU + -. .:....=;==+<; General Public License along with this file; + -_. . . )=. = see the file COPYING. If not, write to the + -- :-=` Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#ifndef INSTALLDLG_H +#define INSTALLDLG_H + +#include <qwidget.h> + +#include <opie/oprocess.h> + +#include "opackage.h" + +class QComboBox; +class QLabel; +class QMultiLineEdit; +class QPushButton; + +class OPackageManager; + +class InstallDlg : public QWidget +{ + Q_OBJECT + +public: + InstallDlg( QWidget *parent = 0x0, OPackageManager *pm = 0x0, const QString &caption = QString::null, + bool showDestInfo = true, + OPackage::Command command1 = OPackage::NotDefined, QStringList *packages1 = 0x0, + OPackage::Command command2 = OPackage::NotDefined, QStringList *packages2 = 0x0, + OPackage::Command command3 = OPackage::NotDefined, QStringList *packages3 = 0x0 ); + ~InstallDlg(); + +private: + OPackageManager *m_packman; // Pointer to application instance of package manager + + // UI controls + QComboBox *m_destination; // Destination selection list + QLabel *m_availSpace; // Text label to display available space on selected destination + QMultiLineEdit *m_output; // Multi-line edit to display status + QPushButton *m_btnStart; // Start/abort/close button + QPushButton *m_btnOptions; // Installation options button + + // Commands and packages to execute + int m_numCommands; // Number of commands to be executed + int m_currCommand; // Number of currently executing command + OPackage::Command m_command[3]; // List of commands to be executed + QStringList *m_packages[3]; // Lists of package names associated to commands (m_command[]) + +private slots: + // UI control slots + void slotDisplayAvailSpace( const QString &destination ); + void slotBtnStart(); + void slotBtnOptions(); + + // Execution slots + void slotOutput( OProcess *process, char *buffer, int buffLen ); + void slotErrors( OProcess *process, char *buffer, int buffLen ); + void slotFinished( OProcess *process ); + +signals: + void closeInstallDlg(); +}; + +#endif diff --git a/noncore/settings/packagemanager/main.cpp b/noncore/settings/packagemanager/main.cpp new file mode 100644 index 0000000..b731695 --- a/dev/null +++ b/noncore/settings/packagemanager/main.cpp @@ -0,0 +1,34 @@ +/* + This file is part of the OPIE Project + + =. Copyright (c) 2003 Dan Williams <drw@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This file is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This file is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU General +..}^=.= = ; Public License for more details. +++= -. .` .: + : = ...= . :.=- You should have received a copy of the GNU + -. .:....=;==+<; General Public License along with this file; + -_. . . )=. = see the file COPYING. If not, write to the + -- :-=` Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#include "mainwindow.h" + +#include <opie/oapplicationfactory.h> + +OPIE_EXPORT_APP( OApplicationFactory<MainWindow> ) diff --git a/noncore/settings/packagemanager/mainwindow.cpp b/noncore/settings/packagemanager/mainwindow.cpp new file mode 100644 index 0000000..311b5fc --- a/dev/null +++ b/noncore/settings/packagemanager/mainwindow.cpp @@ -0,0 +1,667 @@ +/* + This file is part of the OPIE Project + + =. Copyright (c) 2003 Dan Williams <drw@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This file is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This file is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU General +..}^=.= = ; Public License for more details. +++= -. .` .: + : = ...= . :.=- You should have received a copy of the GNU + -. .:....=;==+<; General Public License along with this file; + -_. . . )=. = see the file COPYING. If not, write to the + -- :-=` Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#include <qaction.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qmenubar.h> +#include <qmessagebox.h> +#include <qpopupmenu.h> +#include <qtimer.h> +#include <qtoolbar.h> +#include <qwhatsthis.h> + +#include <qpe/qpeapplication.h> +#include <qpe/resource.h> + +#include "mainwindow.h" +#include "installdlg.h" +#include "filterdlg.h" +#include "promptdlg.h" + +MainWindow::MainWindow( QWidget *parent, const char *name, WFlags fl ) + : QMainWindow( parent, name, fl || WStyle_ContextHelp ) + , m_config( "packman" ) + , m_packman( &m_config, this ) + , m_menuBar( this ) + , m_toolBar( this ) + , m_findBar( this ) + , m_widgetStack( this ) + , m_packageList( this ) + , m_statusWidget( this ) + , m_statusText( &m_statusWidget ) + , m_statusBar( &m_statusWidget ) + , m_iconUpdated( Resource::loadPixmap( "packagemanager/updated" ) ) + , m_iconInstalled( Resource::loadPixmap( "installed" ) ) + , m_iconNull( m_iconUpdated.size() ) + , m_filterName( QString::null ) + , m_filterServer( QString::null ) + , m_filterDest( QString::null ) + , m_filterStatus( OPackageManager::NotDefined ) + , m_filterCategory( QString::null ) + +{ +// setCaption( tr( "Package Manager" ) ); + + m_iconNull.fill( colorGroup().base() ); + + connect( &m_widgetStack, SIGNAL(aboutToShow(QWidget*)), this, SLOT(slotWidgetStackShow(QWidget*)) ); + + // Initialize widget stack, package list and status widget + initStatusWidget(); + initPackageList(); + + m_widgetStack.addWidget( &m_statusWidget, 2 ); + m_widgetStack.addWidget( &m_packageList, 1 ); + setCentralWidget( &m_widgetStack ); + + // Initialize remaining user interface items + initUI(); + + // Initialize package information + QTimer::singleShot( 100, this, SLOT( initPackageInfo() ) ); +} + +void MainWindow::closeEvent( QCloseEvent *event ) +{ + // Close app only if either the package or status widgets are currently active + bool close = m_widgetStack.visibleWidget() == &m_packageList || + m_widgetStack.visibleWidget() == &m_statusWidget; + if ( close ) + { + // TODO - write out application configuration settings + + // Write out package manager configuration settings + m_packman.saveSettings(); + event->accept(); + } + else + { + delete m_widgetStack.visibleWidget(); + m_widgetStack.raiseWidget( &m_packageList ); + event->ignore(); + } +} + +void MainWindow::initPackageList() +{ + m_packageList.addColumn( tr( "Packages" ) ); + QWhatsThis::add( &m_packageList, tr( "This is a listing of all packages.\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." ) ); + QPEApplication::setStylusOperation( m_packageList.viewport(), QPEApplication::RightOnHold ); +} + +void MainWindow::initStatusWidget() +{ + QVBoxLayout *layout = new QVBoxLayout( &m_statusWidget, 4, 4 ); + + m_statusText.setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + layout->addWidget( &m_statusText ); + + connect( &m_packman, SIGNAL(initStatus(int)), this, SLOT(slotInitStatusBar(int)) ); + connect( &m_packman, SIGNAL(statusText(const QString &)), this, SLOT(slotStatusText(const QString &)) ); + connect( &m_packman, SIGNAL(statusBar(int)), this, SLOT(slotStatusBar(int)) ); + + layout->addWidget( &m_statusBar ); +} + +void MainWindow::initUI() +{ + // Build menu and tool bars + setToolBarsMovable( false ); + + m_menuBar.setHorizontalStretchable( true ); + QMenuBar *mb = new QMenuBar( &m_menuBar ); + mb->setMargin( 0 ); + + // Find toolbar + addToolBar( &m_findBar, QMainWindow::Top, true ); + m_findBar.setHorizontalStretchable( true ); + m_findEdit = new QLineEdit( &m_findBar ); + QWhatsThis::add( m_findEdit, tr( "Type the text to search for here." ) ); + m_findBar.setStretchableWidget( m_findEdit ); + connect( m_findEdit, SIGNAL(textChanged(const QString &)), this, SLOT(slotFindChanged(const QString &)) ); + + // Packages menu + QPopupMenu *popup = new QPopupMenu( this ); + + QAction *a = new QAction( tr( "Update lists" ), Resource::loadPixmap( "packagemanager/update" ), QString::null, 0, this, 0 ); + a->setWhatsThis( tr( "Click here to update package lists from servers." ) ); + connect( a, SIGNAL(activated()), this, SLOT(slotUpdate()) ); + a->addTo( popup ); + a->addTo( &m_toolBar ); + + QAction *actionUpgrade = new QAction( tr( "Upgrade" ), Resource::loadPixmap( "packagemanager/upgrade" ), QString::null, 0, this, 0 ); + actionUpgrade->setWhatsThis( tr( "Click here to upgrade all installed packages if a newer version is available." ) ); + connect( actionUpgrade, SIGNAL(activated()), this, SLOT(slotUpgrade()) ); + actionUpgrade->addTo( popup ); + actionUpgrade->addTo( &m_toolBar ); + + // Ipkg implementation does not seem to work currently? (not working in aqpkg either) + /* + QPixmap iconDownload = Resource::loadPixmap( "packagemanager/download" ); + QPixmap iconRemove = Resource::loadPixmap( "packagemanager/remove" ); + QAction *actionDownload = new QAction( tr( "Download" ), iconDownload, QString::null, 0, this, 0 ); + actionDownload->setWhatsThis( tr( "Click here to download the currently selected package(s)." ) ); + connect( actionDownload, SIGNAL(activated()), this, SLOT(slotDownload()) ); + actionDownload->addTo( popup ); + actionDownload->addTo( &m_toolBar ); + */ + + a = new QAction( tr( "Apply changes" ), Resource::loadPixmap( "packagemanager/apply" ), QString::null, 0, this, 0 ); + a->setWhatsThis( tr( "Click here to install, remove or upgrade currently selected package(s)." ) ); + connect( a, SIGNAL(activated()), this, SLOT(slotApply()) ); + a->addTo( popup ); + a->addTo( &m_toolBar ); + + popup->insertSeparator(); + + a = new QAction( tr( "Configure" ), Resource::loadPixmap( "SettingsIcon" ), QString::null, 0, this, 0 ); + a->setWhatsThis( tr( "Click here to configure this application." ) ); + connect( a, SIGNAL(activated()), this, SLOT(slotConfigure()) ); + a->addTo( popup ); + mb->insertItem( tr( "Actions" ), popup ); + + // View menu + popup = new QPopupMenu( this ); + + m_actionShowNotInstalled = new QAction( tr( "Show packages not installed" ), QString::null, 0, this, 0 ); + m_actionShowNotInstalled->setToggleAction( true ); + m_actionShowNotInstalled->setWhatsThis( tr( "Click here to show packages available which have not been installed." ) ); + connect( m_actionShowNotInstalled, SIGNAL(activated()), this, SLOT(slotShowNotInstalled()) ); + m_actionShowNotInstalled->addTo( popup ); + + m_actionShowInstalled = new QAction( tr( "Show installed packages" ), QString::null, 0, this, 0 ); + m_actionShowInstalled->setToggleAction( true ); + m_actionShowInstalled->setWhatsThis( tr( "Click here to show packages currently installed on this device." ) ); + connect( m_actionShowInstalled, SIGNAL(activated()), this, SLOT(slotShowInstalled()) ); + m_actionShowInstalled->addTo( popup ); + + m_actionShowUpdated = new QAction( tr( "Show updated packages" ), QString::null, 0, this, 0 ); + m_actionShowUpdated->setToggleAction( true ); + m_actionShowUpdated->setWhatsThis( tr( "Click here to show packages currently installed on this device which have a newer version available." ) ); + connect( m_actionShowUpdated, SIGNAL(activated()), this, SLOT(slotShowUpdated()) ); + m_actionShowUpdated->addTo( popup ); + + popup->insertSeparator(); + + a = new QAction( tr( "Configure filter" ), QString::null, 0, this, 0 ); + a->setWhatsThis( tr( "Click here to change package filter criteria." ) ); + connect( a, SIGNAL(activated()), this, SLOT(slotFilterChange()) ); + a->addTo( popup ); + + m_actionFilter = new QAction( tr( "Filter" ), Resource::loadPixmap( "packagemanager/filter" ), + QString::null, 0, this, 0 ); + m_actionFilter->setToggleAction( true ); + m_actionFilter->setWhatsThis( tr( "Click here to apply current filter." ) ); + connect( m_actionFilter, SIGNAL(toggled(bool)), this, SLOT(slotFilter(bool)) ); + m_actionFilter->addTo( popup ); + + popup->insertSeparator(); + + a = new QAction( tr( "Find" ), Resource::loadPixmap( "find" ), QString::null, 0, this, 0 ); + a->setWhatsThis( tr( "Click here to search for text in package names." ) ); + connect( a, SIGNAL(activated()), this, SLOT(slotFindShowToolbar()) ); + a->addTo( popup ); + + m_actionFindNext = new QAction( tr( "Find next" ), Resource::loadIconSet( "next" ), QString::null, 0, this, 0 ); + m_actionFindNext->setEnabled( false ); + m_actionFindNext->setWhatsThis( tr( "Click here to find the next package name containing the text you are searching for." ) ); + connect( m_actionFindNext, SIGNAL(activated()), this, SLOT(slotFindNext()) ); + m_actionFindNext->addTo( popup ); + m_actionFindNext->addTo( &m_findBar ); + + mb->insertItem( tr( "View" ), popup ); + + // Finish find toolbar creation + a = new QAction( QString::null, Resource::loadPixmap( "close" ), QString::null, 0, this, 0 ); + a->setWhatsThis( tr( "Click here to hide the find toolbar." ) ); + connect( a, SIGNAL(activated()), this, SLOT(slotFindHideToolbar()) ); + a->addTo( &m_findBar ); + m_findBar.hide(); +} + +void MainWindow::loadPackageList( OPackageList *packages, bool clearList ) +{ + if ( clearList ) + m_packageList.clear(); + + if ( packages ) + { + for ( OPackageListIterator packageIt( *packages ); packageIt.current(); ++packageIt ) + { + OPackage *package = packageIt.current(); + QCheckListItem *item = new QCheckListItem( &m_packageList, package->name(), + QCheckListItem::CheckBox ); + m_packageList.insertItem( item ); + + // If a different version of package is available, show update available icon + // Otherwise, show installed icon + if ( !package->versionInstalled().isNull() ) + { + if ( m_packman.compareVersions( package->version(), package->versionInstalled() ) == 1 ) + item->setPixmap( 0, m_iconUpdated ); + else + item->setPixmap( 0, m_iconInstalled ); + } + else + item->setPixmap( 0, m_iconNull ); + } + } +} + +void MainWindow::searchForPackage( const QString &text ) +{ + if ( !text.isEmpty() ) + { + // look through package list for text startng at current position + QCheckListItem *start = static_cast<QCheckListItem *>(m_packageList.currentItem()); + if ( start == 0 ) + start = static_cast<QCheckListItem *>(m_packageList.firstChild()); + +// for ( QCheckListItem *item = static_cast<QCheckListItem *>(start->nextSibling()); item != 0 ; + for ( QCheckListItem *item = static_cast<QCheckListItem *>(start); item != 0 ; + item = static_cast<QCheckListItem *>(item->nextSibling()) ) + { + if ( item->text().lower().find( text ) != -1 ) + { + m_packageList.ensureItemVisible( item ); + m_packageList.setCurrentItem( item ); + break; + } + } + } +} + +void MainWindow::initPackageInfo() +{ + m_widgetStack.raiseWidget( &m_statusWidget ); + + // Load package list + m_packman.loadAvailablePackages(); + m_packman.loadInstalledPackages(); + + OPackageList *packageList = m_packman.packages(); + if ( packageList ) + { + loadPackageList( packageList, true ); + delete packageList; + } + + m_widgetStack.raiseWidget( &m_packageList ); +} + +void MainWindow::slotWidgetStackShow( QWidget *widget ) +{ + if ( widget == &m_packageList ) + { + setCaption( tr( "Package Manager" ) ); + + m_menuBar.show(); + m_toolBar.show(); + } + else + { + m_menuBar.hide(); + m_toolBar.hide(); + } +} + +void MainWindow::slotInitStatusBar( int numSteps ) +{ + m_statusBar.setTotalSteps( numSteps ); +} + +void MainWindow::slotStatusText( const QString &status ) +{ + m_statusText.setText( status ); +} + +void MainWindow::slotStatusBar( int currStep ) +{ + m_statusBar.setProgress( currStep ); +} + +void MainWindow::slotUpdate() +{ + // Create package manager output widget + InstallDlg *dlg = new InstallDlg( this, &m_packman, tr( "Update package information" ), false, + OPackage::Update ); + connect( dlg, SIGNAL(closeInstallDlg()), this, SLOT(slotCloseInstallDlg()) ); + + // Display widget + m_widgetStack.addWidget( dlg, 3 ); + m_widgetStack.raiseWidget( dlg ); +} + +void MainWindow::slotUpgrade() +{ + // Create package manager output widget + InstallDlg *dlg = new InstallDlg( this, &m_packman, tr( "Upgrade installed packages" ), false, + OPackage::Upgrade ); + connect( dlg, SIGNAL(closeInstallDlg()), this, SLOT(slotCloseInstallDlg()) ); + + // Display widget + m_widgetStack.addWidget( dlg, 3 ); + m_widgetStack.raiseWidget( dlg ); +} + + // Ipkg implementation does not seem to work currently? (not working in aqpkg either) +/* +void MainWindow::slotDownload() +{ + // Retrieve list of packages selected for download (if any) + QStringList *workingPackages = new QStringList(); + + for ( QCheckListItem *item = static_cast<QCheckListItem *>(m_packageList.firstChild()); + item != 0 ; + item = static_cast<QCheckListItem *>(item->nextSibling()) ) + { + if ( item->isOn() ) + workingPackages->append( item->text() ); + } + + if ( workingPackages->isEmpty() ) + { + // No packages were selected, prompt for URL of package to download + } + else + { + // Download selected packages + m_config.setGroup( "settings" ); + QString workingDir = m_config.readEntry( "DownloadDir", "/tmp" ); + +// QString text = InputDialog::getText( tr( "Download to where" ), tr( "Enter path to download to" ), workingDir, &ok, this ); +// if ( ok && !text.isEmpty() ) +// workingDir = text; // user entered something and pressed ok +// else +// return; // user entered nothing or pressed cancel + +// // Store download directory in config file +// m_config.writeEntry( "DownloadDir", workingDir ); + + // Get starting directory +// char initDir[PATH_MAX]; +// getcwd( initDir, PATH_MAX ); + + // Download packages + + } + + // Create package manager output widget + InstallDlg *dlg = new InstallDlg( this, &m_packman, tr( "Download packages" ), false, + OPackage::Download, workingPackages ); + connect( dlg, SIGNAL(closeInstallDlg()), this, SLOT(slotCloseInstallDlg()) ); + + // Display widget + m_widgetStack.addWidget( dlg, 3 ); + m_widgetStack.raiseWidget( dlg ); +} +*/ + +void MainWindow::slotApply() +{ + QStringList *removeList = 0x0; + QStringList *installList = 0x0; + QStringList *upgradeList = 0x0; + + for ( QCheckListItem *item = static_cast<QCheckListItem *>(m_packageList.firstChild()); + item != 0 ; + item = static_cast<QCheckListItem *>(item->nextSibling()) ) + { + if ( item->isOn() ) + { + OPackage *package = m_packman.findPackage( item->text() ); + if ( package ) + { + if ( !package->versionInstalled().isNull() ) + { + if ( m_packman.compareVersions( package->version(), package->versionInstalled() ) == 1 ) + { + // Remove/upgrade package + int answer = PromptDlg::ask( tr( "Remove or upgrade" ), + tr( QString( "Do you wish to remove or upgrade\n%1?" ).arg( item->text() ) ), + tr( "Remove" ), tr( "Upgrade" ), this ); + if ( answer == 1 ) // Remove + { + if ( !removeList ) + removeList = new QStringList(); + removeList->append( item->text() ); + } + else if ( answer == 2 ) // Upgrade + { + if ( !upgradeList ) + upgradeList = new QStringList(); + upgradeList->append( item->text() ); + } + } + else + { + // Remove/reinstall package + int answer = PromptDlg::ask( tr( "Remove or reinstall" ), + tr( QString( "Do you wish to remove or reinstall\n%1?" ).arg( item->text() ) ), + tr( "Remove" ), tr( "Reinstall" ), this ); + if ( answer == 1 ) // Remove + { + if ( !removeList ) + removeList = new QStringList(); + removeList->append( item->text() ); + } + else if ( answer == 2 ) // Reinstall + { + if ( !installList ) + installList = new QStringList(); + installList->append( item->text() ); + } + } + } + else + { + // Install package + if ( !installList ) + installList = new QStringList(); + installList->append( item->text() ); + } + } + } + } + + // If nothing is selected, display message and exit + if ( !removeList && !installList && !upgradeList ) + { + QMessageBox::information( this, tr( "Nothing to do" ), tr( "No packages selected" ), tr( "OK" ) ); + return; + } + + // Send command only if there are packages to process + OPackage::Command removeCmd = OPackage::NotDefined; + if ( removeList && !removeList->isEmpty() ) + removeCmd = OPackage::Remove; + OPackage::Command installCmd = OPackage::NotDefined; + if ( installList && !installList->isEmpty() ) + installCmd = OPackage::Install; + OPackage::Command upgradeCmd = OPackage::NotDefined; + if ( upgradeList && !upgradeList->isEmpty() ) + upgradeCmd = OPackage::Upgrade; + + // Create package manager output widget + InstallDlg *dlg = new InstallDlg( this, &m_packman, tr( "Apply changes" ), true, + removeCmd, removeList, + installCmd, installList, + upgradeCmd, upgradeList ); + connect( dlg, SIGNAL(closeInstallDlg()), this, SLOT(slotCloseInstallDlg()) ); + + // Display widget + m_widgetStack.addWidget( dlg, 3 ); + m_widgetStack.raiseWidget( dlg ); +} + +void MainWindow::slotCloseInstallDlg() +{ + // Close install dialog + delete m_widgetStack.visibleWidget(); + + // Reload package list + initPackageInfo(); +} + +void MainWindow::slotConfigure() +{ + if ( m_packman.configureDlg( false ) ) + { + if ( PromptDlg::ask( tr( "Config updated" ), + tr( "The configuration has been updated. Do you want to update server and package information now?" ), + tr( "Yes" ), tr( "No" ), this ) == 1 ) + { + // Update package list and reload package info + slotUpdate(); + } + } +} + +void MainWindow::slotShowNotInstalled() +{ + OPackageList *packageList; + if ( m_actionShowNotInstalled->isOn() ) + { + m_actionShowInstalled->setOn( false ); + m_actionShowUpdated->setOn( false ); + packageList = m_packman.filterPackages( QString::null, QString::null, QString::null, + OPackageManager::NotInstalled, QString::null ); + } + else + packageList = m_packman.packages(); + + if ( packageList ) + { + loadPackageList( packageList, true ); + delete packageList; + } +} + +void MainWindow::slotShowInstalled() +{ + OPackageList *packageList; + if ( m_actionShowInstalled->isOn() ) + { + m_actionShowNotInstalled->setOn( false ); + m_actionShowUpdated->setOn( false ); + packageList = m_packman.filterPackages( QString::null, QString::null, QString::null, + OPackageManager::Installed, QString::null ); + } + else + packageList = m_packman.packages(); + + if ( packageList ) + { + loadPackageList( packageList, true ); + delete packageList; + } +} + +void MainWindow::slotShowUpdated() +{ + OPackageList *packageList; + if ( m_actionShowUpdated->isOn() ) + { + m_actionShowInstalled->setOn( false ); + m_actionShowNotInstalled->setOn( false ); + packageList = m_packman.filterPackages( QString::null, QString::null, QString::null, + OPackageManager::Updated, QString::null ); + } + else + packageList = m_packman.packages(); + + if ( packageList ) + { + loadPackageList( packageList, true ); + delete packageList; + } +} + +void MainWindow::slotFilterChange() +{ + FilterDlg dlg( this, &m_packman, m_filterName, m_filterServer, m_filterDest, m_filterStatus, + m_filterCategory ); + if ( dlg.exec() == QDialog::Accepted ) + { + m_filterName = dlg.name(); + m_filterServer = dlg.server(); + m_filterDest = dlg.destination(); + m_filterStatus = dlg.status(); + m_filterCategory = dlg.category(); + m_actionFilter->setOn( true ); + slotFilter( true ); + } + else + { + m_actionFilter->setOn( false ); + slotFilter( false ); + } +} + +void MainWindow::slotFilter( bool isOn ) +{ + OPackageList *packageList; + if ( isOn ) + { + packageList = m_packman.filterPackages( m_filterName, m_filterServer, m_filterDest, + m_filterStatus, m_filterCategory ); + } + else + packageList = m_packman.packages(); + + if ( packageList ) + { + loadPackageList( packageList, true ); + delete packageList; + } +} + +void MainWindow::slotFindShowToolbar() +{ + m_findBar.show(); + m_findEdit->setFocus(); +} + +void MainWindow::slotFindHideToolbar() +{ + m_findBar.hide(); +} + +void MainWindow::slotFindChanged( const QString &findText ) +{ + + m_actionFindNext->setEnabled( !findText.isEmpty() ); + searchForPackage( findText ); +} + +void MainWindow::slotFindNext() +{ + searchForPackage( m_findEdit->text() ); +} diff --git a/noncore/settings/packagemanager/mainwindow.h b/noncore/settings/packagemanager/mainwindow.h new file mode 100644 index 0000000..49bb66c --- a/dev/null +++ b/noncore/settings/packagemanager/mainwindow.h @@ -0,0 +1,136 @@ +/* + This file is part of the OPIE Project + + =. Copyright (c) 2003 Dan Williams <drw@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This file is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This file is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU General +..}^=.= = ; Public License for more details. +++= -. .` .: + : = ...= . :.=- You should have received a copy of the GNU + -. .:....=;==+<; General Public License along with this file; + -_. . . )=. = see the file COPYING. If not, write to the + -- :-=` Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include <qlabel.h> +#include <qlistview.h> +#include <qmainwindow.h> +#include <qpixmap.h> +#include <qprogressbar.h> +#include <qtoolbar.h> +#include <qwidgetstack.h> + +#include <qpe/config.h> + +#include "opackagemanager.h" + +class QAction; +class QLineEdit; + +class MainWindow :public QMainWindow +{ + Q_OBJECT + +public: + MainWindow( QWidget *parent = 0x0, const char *name = 0x0, WFlags fl = 0 ); + static QString appName() { return QString::fromLatin1( "packagemanager" ); }; + +protected: + void closeEvent( QCloseEvent *event ); + +private: + Config m_config; // Configuration file + + OPackageManager m_packman; // Package manager + + // Toolbars + QToolBar m_menuBar; // Main toolbar containing menu + QToolBar m_toolBar; // Main toolbar + QToolBar m_findBar; // Find toolbar + + QWidgetStack m_widgetStack; // Main widget stack which contains m_packageList & m_statusWidget + QListView m_packageList; // Main list view of all packages + + QLineEdit *m_findEdit; // Line edit box used for find toolbar + + // Status widget controls + QWidget m_statusWidget; // Widget to display status during long operations + QLabel m_statusText; // Text status message + QProgressBar m_statusBar; // Progress bar showing % completed + + // Icon pixmaps + QPixmap m_iconUpdated; // Cached icon which shows when package can be updated + QPixmap m_iconInstalled; // Cached icon which shows when package is installed + QPixmap m_iconNull; // Cached icon which shows when package is not installed + + // Menu/tool bar actions + QAction *m_actionShowNotInstalled; // Action to show pakages not currently installed + QAction *m_actionShowInstalled; // Action to show pakages currently installed + QAction *m_actionShowUpdated; // Action to show pakages currently installed with update available + QAction *m_actionFilter; // Action to filter packages + QAction *m_actionFindNext; // Action to find next match + + // Cached filter settings + QString m_filterName; // Cached name filter value + QString m_filterServer; // Cached server name filter value + QString m_filterDest; // Cached destination name filter value + OPackageManager::Status m_filterStatus; // Cached status filter value + QString m_filterCategory; // Cached category filter value + + void initPackageList(); + void initStatusWidget(); + void initUI(); + + void loadPackageList( OPackageList *packages = 0x0, bool clearList = true ); + void searchForPackage( const QString &text ); + +private slots: + void initPackageInfo(); + void slotWidgetStackShow( QWidget *widget ); + + // Status widget slots + void slotInitStatusBar( int numSteps ); + void slotStatusText( const QString &status ); + void slotStatusBar( int currStep ); + + // Actions menu action slots + void slotUpdate(); + void slotUpgrade(); +// void slotDownload(); + void slotApply(); + void slotCloseInstallDlg(); + void slotConfigure(); + + // View menu action slots + void slotShowNotInstalled(); + void slotShowInstalled(); + void slotShowUpdated(); + void slotFilterChange(); + void slotFilter( bool isOn ); + + // Find action slots + void slotFindShowToolbar(); + void slotFindHideToolbar(); + void slotFindChanged( const QString &findText ); + void slotFindNext(); +}; + +#endif diff --git a/noncore/settings/packagemanager/oconfitem.cpp b/noncore/settings/packagemanager/oconfitem.cpp new file mode 100644 index 0000000..940a6de --- a/dev/null +++ b/noncore/settings/packagemanager/oconfitem.cpp @@ -0,0 +1,42 @@ +/* + This file is part of the Opie Project + + Copyright (c) 2003 Dan Williams <drw@handhelds.org> + =. + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#include "oconfitem.h" + +OConfItem::OConfItem( const QString &location, Type type, const QString &name, + const QString &value, bool active ) + : m_location( location ) + , m_type( type ) + , m_name( name ) + , m_value( value ) + , m_active( active ) +{ +} diff --git a/noncore/settings/packagemanager/oconfitem.h b/noncore/settings/packagemanager/oconfitem.h new file mode 100644 index 0000000..aeee511 --- a/dev/null +++ b/noncore/settings/packagemanager/oconfitem.h @@ -0,0 +1,95 @@ +/* + This file is part of the Opie Project + + Copyright (c) 2003 Dan Williams <drw@handhelds.org> + =. + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#ifndef OCONFITEM_H +#define OCONFITEM_H + +#include <qlist.h> +#include <qstring.h> + +class OConfItem +{ +public: + enum Type { Source, Destination, Option, Arch, NotDefined }; + + OConfItem( const QString &location = 0x0, Type type = NotDefined, const QString &name = 0x0, + const QString &value = 0x0, bool active = true ); + + const QString &location() { return m_location; } + Type type() { return m_type; } + const QString &name() { return m_name; } + const QString &value() { return m_value; } + bool active() { return m_active; } + + void setLocation( const QString &location ) { m_location = location; } + void setType( Type type ) { m_type = type; } + void setName( const QString &name ) { m_name = name; } + void setValue( const QString &value ) { m_value = value; } + void setActive( bool active ) { m_active = active; } + +private: + QString m_location; // Configuration file where item is located + Type m_type; // Type of configuration item + QString m_name; // Name of item + QString m_value; // Value of item + bool m_active; // Indicates whether item is currently active +}; + +class OConfItemList : public QList<OConfItem> +{ +private: + + int compareItems( QCollection::Item item1, QCollection::Item item2 ) + { + // Sort by OConfItem location then by type + QString loc1 = reinterpret_cast<OConfItem*>(item1)->location(); + QString loc2 = reinterpret_cast<OConfItem*>(item2)->location(); + if ( loc1 < loc2 ) + return -1; + else if ( loc1 == loc2 ) + { + OConfItem::Type type1 = reinterpret_cast<OConfItem*>(item1)->type(); + OConfItem::Type type2 = reinterpret_cast<OConfItem*>(item2)->type(); + if ( type1 < type2 ) + return -1; + else if ( type1 == type2 ) + return 0; + else /*if ( type1 > type2 )*/ + return 1; + } + else /*if ( loc1 > loc2 )*/ + return 1; + } +}; + +typedef QListIterator<OConfItem> OConfItemListIterator; + +#endif diff --git a/noncore/settings/packagemanager/oipkg.cpp b/noncore/settings/packagemanager/oipkg.cpp new file mode 100644 index 0000000..13f3d7d --- a/dev/null +++ b/noncore/settings/packagemanager/oipkg.cpp @@ -0,0 +1,505 @@ +/* + This file is part of the Opie Project + + Copyright (c) 2003 Dan Williams <drw@handhelds.org> + =. + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#include "oipkg.h" + +#include <stdio.h> + +#include <qdir.h> +#include <qfile.h> +#include <qtextstream.h> + +#include <opie/oprocess.h> + +const QString IPKG_EXEC = "ipkg"; // Fully-qualified name of Ipkg executable +const QString IPKG_CONF = "/etc/ipkg.conf"; // Fully-qualified name of Ipkg primary configuration file +const QString IPKG_CONF_DIR = "/etc/ipkg"; // Directory of secondary Ipkg configuration files +const QString IPKG_PKG_PATH = "/usr/lib/ipkg/lists"; // Directory containing server package lists +const QString IPKG_STATUS_PATH = "usr/lib/ipkg/status"; // Destination status file location + +OIpkg::OIpkg( Config *config, QObject *parent, const char *name ) + : QObject( parent, name ) + , m_config( config ) + , m_ipkgExec( IPKG_EXEC ) // TODO - find executable? + , m_confInfo( NULL ) + , m_ipkgExecOptions( 0 ) + , m_ipkgExecVerbosity( 1 ) + , m_ipkgProcess( NULL ) +{ +} + +OIpkg::~OIpkg() +{ + // Upon destruction, ensure that items in config list are deleted with list + if ( m_confInfo ) + m_confInfo->setAutoDelete( true ); + + // Terminate any running ipkg processes + if ( m_ipkgProcess ) + delete m_ipkgProcess; +} + +OConfItemList *OIpkg::configItems() +{ + // Retrieve all configuration items + return filterConfItems(); +} + +OConfItemList *OIpkg::servers() +{ + // Retrieve only servers + return filterConfItems( OConfItem::Source ); +} + +OConfItemList *OIpkg::destinations() +{ + // Retrieve only destinations + return filterConfItems( OConfItem::Destination ); +} + +OConfItemList *OIpkg::options() +{ + // Retrieve only destinations + return filterConfItems( OConfItem::Option ); +} + +void OIpkg::setConfigItems( OConfItemList *configList ) +{ + if ( m_confInfo ) + delete m_confInfo; + + m_confInfo = configList; +} + +void OIpkg::saveSettings() +{ + // Save Ipkg execution options to application configuration file + if ( m_config ) + { + m_config->setGroup( "Ipkg" ); + m_config->writeEntry( "ExecOptions", m_ipkgExecOptions ); + m_config->writeEntry( "Verbosity", m_ipkgExecVerbosity ); + } +} + +OPackageList *OIpkg::availablePackages( const QString &server ) +{ + // Load Ipkg configuration info if not already cached + if ( !m_confInfo ) + loadConfiguration(); + + // Build new server list (caller is responsible for deleting) + OPackageList *pl = new OPackageList; + + // Open package list file + QFile f( IPKG_PKG_PATH + "/" + server ); + if ( !f.open( IO_ReadOnly ) ) + return NULL; + QTextStream t( &f ); + + // Process all information in package list file + OPackage *package = NULL; + QString line = t.readLine(); + while ( !t.eof() ) + { + // Determine key/value pair + int pos = line.find( ':', 0 ); + QString key; + if ( pos > -1 ) + key = line.mid( 0, pos ); + else + key = QString::null; + QString value = line.mid( pos+2, line.length()-pos ); + + // Allocate new package and insert into list + if ( package == NULL && !key.isEmpty() ) + { + package = new OPackage( value ); + package->setSource( server ); + pl->append( package ); + } + + // Update package data + if ( key == "Package" ) + package->setName( value ); + else if ( key == "Version" ) + package->setVersion( value ); + else if ( key == "Section" ) + package->setCategory( value ); + //DataManager::setAvailableCategories( value ); + else if ( key.isEmpty() && value.isEmpty() ) + package = NULL; + + // Skip past all description lines + if ( key == "Description" ) + { + line = t.readLine(); + while ( !line.isEmpty() && line.find( ':', 0 ) == -1 && !t.eof() ) + line = t.readLine(); + } + else + line = t.readLine(); + } + + f.close(); + + return pl; +} + +OPackageList *OIpkg::installedPackages( const QString &destName, const QString &destPath ) +{ + // Load Ipkg configuration info if not already cached + if ( !m_confInfo ) + loadConfiguration(); + + // Build new server list (caller is responsible for deleting) + OPackageList *pl = new OPackageList; + + // Open status file + QString path = destPath; + if ( path.right( 1 ) != "/" ) + path.append( "/" ); + path.append( IPKG_STATUS_PATH ); + + QFile f( path ); + if ( !f.open( IO_ReadOnly ) ) + return NULL; + QTextStream t( &f ); + + // Process all information in status file + bool newPackage = false; + QString line = t.readLine(); + QString name; + QString version; + QString status; + + while ( !t.eof() ) + { + // Determine key/value pair + int pos = line.find( ':', 0 ); + QString key; + if ( pos > -1 ) + key = line.mid( 0, pos ); + else + key = QString::null; + QString value = line.mid( pos+2, line.length()-pos ); + + // Allocate new package and insert into list + if ( newPackage && !key.isEmpty() ) + { + // Add to list only if it has a valid name and is installed + if ( !name.isNull() && status.contains( " installed" ) ) + { + pl->append( new OPackage( name, QString::null, version, QString::null, destName ) ); + name = QString::null; + version = QString::null; + status = QString::null; + + newPackage = false; + } + } + + // Update package data + if ( key == "Package" ) + name = value; + else if ( key == "Version" ) + version = value; + else if ( key == "Status" ) + status = value; + else if ( key.isEmpty() && value.isEmpty() ) + newPackage = true; + + // Skip past all description lines + if ( key == "Description" ) + { + line = t.readLine(); + while ( !line.isEmpty() && line.find( ':', 0 ) == -1 && !t.eof() ) + line = t.readLine(); + } + else + line = t.readLine(); + } + + f.close(); + + return pl; +} + +bool OIpkg::executeCommand( OPackage::Command command, QStringList *parameters, const QString &destination, + const QObject *receiver, const char *slotOutput, const char *slotErrors, + const char *slotFinished, bool rawOutput ) +{ + if ( command == OPackage::NotDefined ) + return false; + + // Set up command line for execution + QStringList cmdLine; + cmdLine.append( IPKG_EXEC ); + + QString verbosity( "-V" ); + verbosity.append( QString::number( m_ipkgExecVerbosity ) ); + cmdLine.append( verbosity ); + + // Determine Ipkg execution options + if ( command == OPackage::Install && destination != QString::null ) + { + // TODO - Set destination for installs + cmdLine.append( "-dest" ); + cmdLine.append( destination ); + } + + if ( command != OPackage::Update && command != OPackage::Download ) + { + if ( m_ipkgExecOptions & FORCE_DEPENDS ) + cmdLine.append( "-force-depends" ); + if ( m_ipkgExecOptions & FORCE_REINSTALL ) + cmdLine.append( "-force-reinstall" ); + if ( m_ipkgExecOptions & FORCE_REMOVE ) + cmdLine.append( "-force-removal-of-essential-packages" ); + if ( m_ipkgExecOptions & FORCE_OVERWRITE ) + cmdLine.append( "-force-overwrite" ); + if ( m_ipkgExecVerbosity == 3 ) + cmdLine.append( "-verbose_wget" ); + + // TODO + // Handle make links + // Rules - If make links is switched on, create links to root + // if destDir is NOT / + /* + if ( m_ipkgExecOptions & MAKE_LINKS ) + { + // If destDir == / turn off make links as package is being insalled + // to root already. + if ( destDir == "/" ) + m_ipkgExecOptions ^= MAKE_LINKS; + } + */ + } + + QString cmd; + switch( command ) + { + case OPackage::Install: cmd = "install"; + break; + case OPackage::Remove: cmd = "remove"; + break; + case OPackage::Update: cmd = "update"; + break; + case OPackage::Upgrade: cmd = "upgrade"; + break; + case OPackage::Download: cmd = "download"; + break; + case OPackage::Info: cmd = "info"; + break; + case OPackage::Files: cmd = "files"; + break; + //case OPackage::Version: cmd = "" ); + // break; + default: + break; + }; + cmdLine.append( cmd ); + + // TODO + // If we are removing, reinstalling or upgrading packages and make links option is selected + // create the links +/* + if ( command == Remove || command == Upgrade ) + { + createLinks = false; + if ( flags & MAKE_LINKS ) + { + emit outputText( tr( "Removing symbolic links...\n" ) ); + linkPackage( Utils::getPackageNameFromIpkFilename( package ), destination, destDir ); + emit outputText( QString( " " ) ); + } + } +*/ + // Append package list (if any) to end of command line + if ( parameters && !parameters->isEmpty() ) + { + for ( QStringList::Iterator it = parameters->begin(); it != parameters->end(); ++it ) + { + cmdLine.append( *it ); + } + } + + // Create OProcess + if ( m_ipkgProcess ) + delete m_ipkgProcess; + m_ipkgProcess = new OProcess( cmdLine, this ); + + // Connect signals (if any) + if ( receiver ) + { + if ( rawOutput ) + { + if ( slotOutput ) + connect( m_ipkgProcess, SIGNAL(receivedStdout(OProcess*,char*,int)), receiver, slotOutput ); + if ( slotErrors ) + connect( m_ipkgProcess, SIGNAL(receivedStderr(OProcess*,char*,int)), receiver, slotErrors ); + if ( slotFinished ) + connect( m_ipkgProcess, SIGNAL(processExited(OProcess*)), receiver, slotFinished ); + } + else // !rawOutput + { + // TODO - how should it handle partial lines? (i.e. "Installing opi", "e-aqpkg...") + } + } + + // Run process +printf( "Running: \'%s\'\n", cmdLine.join( " " ).latin1() ); + return m_ipkgProcess->start( OProcess::NotifyOnExit, OProcess::All ); +} + +void OIpkg::abortCommand() +{ + if ( m_ipkgProcess ) + delete m_ipkgProcess; +} + +void OIpkg::loadConfiguration() +{ + if ( m_confInfo ) + delete m_confInfo; + + // Load configuration item list + m_confInfo = new OConfItemList(); + + QStringList confFiles; + QDir confDir( IPKG_CONF_DIR ); + if ( confDir.exists() ) + { + confDir.setNameFilter( "*.conf" ); + confDir.setFilter( QDir::Files ); + confFiles = confDir.entryList( "*.conf", QDir::Files ); + confFiles << IPKG_CONF; + + for ( QStringList::Iterator it = confFiles.begin(); it != confFiles.end(); ++it ) + { + // Create absolute file path if necessary + QString absFile = (*it); + if ( !absFile.startsWith( "/" ) ) + absFile.prepend( QString( IPKG_CONF_DIR ) + "/" ); + + // Read in file + QFile f( absFile ); + if ( f.open( IO_ReadOnly ) ) + { + QTextStream s( &f ); + while ( !s.eof() ) + { + + QString line = s.readLine().simplifyWhiteSpace(); + + // Parse line and save info to the conf options list + if ( !line.isEmpty() ) + { + if ( !line.startsWith( "#" ) || + line.startsWith( "#src" ) || + line.startsWith( "#dest" ) || + line.startsWith( "#arch" ) || + line.startsWith( "#option" ) ) + { + int pos = line.find( ' ', 1 ); + + // Type + QString typeStr = line.left( pos ); + OConfItem::Type type; + if ( typeStr == "src" || typeStr == "#src" ) + type = OConfItem::Source; + else if ( typeStr == "dest" || typeStr == "#dest" ) + type = OConfItem::Destination; + else if ( typeStr == "option" || typeStr == "#option" ) + type = OConfItem::Option; + else if ( typeStr == "arch" || typeStr == "#arch" ) + type = OConfItem::Arch; + else + type = OConfItem::NotDefined; + ++pos; + int endpos = line.find( ' ', pos ); + + // Name + QString name = line.mid( pos, endpos - pos ); + + // Value + QString value = ""; + if ( endpos > -1 ) + value = line.right( line.length() - endpos - 1 ); + + // Active + bool active = !line.startsWith( "#" ); + + // Add to list + m_confInfo->append( new OConfItem( absFile, type, name, value, active ) ); + } + } + } + + f.close(); + } + } + } + + // Load Ipkg execution options from application configuration file + if ( m_config ) + { + m_config->setGroup( "Ipkg" ); + m_ipkgExecOptions = m_config->readNumEntry( "ExecOptions", m_ipkgExecOptions ); + m_ipkgExecVerbosity = m_config->readNumEntry( "Verbosity", m_ipkgExecVerbosity ); + } +} + +OConfItemList *OIpkg::filterConfItems( OConfItem::Type typefilter ) +{ + // Load Ipkg configuration info if not already cached + if ( !m_confInfo ) + loadConfiguration(); + + // Build new server list (caller is responsible for deleting) + OConfItemList *sl = new OConfItemList; + + // If typefilter is empty, retrieve all items + bool retrieveAll = ( typefilter == OConfItem::NotDefined ); + + // Parse configuration info for servers + OConfItemListIterator it( *m_confInfo ); + for ( ; it.current(); ++it ) + { + OConfItem *item = it.current(); + if ( retrieveAll || item->type() == typefilter ) + { + sl->append( item ); + } + } + + return sl; +} diff --git a/noncore/settings/packagemanager/oipkg.h b/noncore/settings/packagemanager/oipkg.h new file mode 100644 index 0000000..4065f48 --- a/dev/null +++ b/noncore/settings/packagemanager/oipkg.h @@ -0,0 +1,100 @@ +/* + This file is part of the Opie Project + + Copyright (c) 2003 Dan Williams <drw@handhelds.org> + =. + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#ifndef OIPKG_H +#define OIPKG_H + +#include <qobject.h> + +#include <qpe/config.h> + +#include "oconfitem.h" +#include "opackage.h" + +// Ipkg execution options (m_ipkgExecOptions) +#define FORCE_DEPENDS 0x0001 +#define FORCE_REMOVE 0x0002 +#define FORCE_REINSTALL 0x0004 +#define FORCE_OVERWRITE 0x0008 + +class OConfItemList; +class OProcess; + +class OIpkg : public QObject +{ + Q_OBJECT + +public: + OIpkg( Config *config = 0x0, QObject *parent = 0x0, const char *name = 0x0 ); + ~OIpkg(); + + OConfItemList *configItems(); + OConfItemList *servers(); + OConfItemList *destinations(); + OConfItemList *options(); + + int ipkgExecOptions() { return m_ipkgExecOptions; } + int ipkgExecVerbosity() { return m_ipkgExecVerbosity; } + + void setConfigItems( OConfItemList *configList ); + void setIpkgExecOptions( int options ) { m_ipkgExecOptions = options; } + void setIpkgExecVerbosity( int verbosity ) { m_ipkgExecVerbosity = verbosity; } + + void saveSettings(); + + OPackageList *availablePackages( const QString &server = QString::null ); + OPackageList *installedPackages( const QString &destName = QString::null, + const QString &destPath = QString::null ); + + bool executeCommand( OPackage::Command command = OPackage::NotDefined, QStringList *parameters = 0x0, + const QString &destination = QString::null, const QObject *receiver = 0x0, + const char *slotOutput = 0x0, const char *slotErrors = 0x0, + const char *slotFinished = 0x0, bool rawOutput = true ); + void abortCommand(); + +private: + Config *m_config; // Pointer to application configuration file + QString m_ipkgExec; // Fully qualified path/filename of ipkg binary + OConfItemList *m_confInfo; // Contains info from all Ipkg configuration files + int m_ipkgExecOptions; // Bit-mapped flags for Ipkg execution options + int m_ipkgExecVerbosity; // Ipkg execution verbosity level + OProcess *m_ipkgProcess; // Pointer to process which Ipkg will run in + + void loadConfiguration(); + OConfItemList *filterConfItems( OConfItem::Type typefilter = OConfItem::NotDefined ); + +signals: + void execOutput( OProcess *process, char *buffer, int length ); + void execErrors( OProcess *process, char *buffer, int length ); + void execFinished( OProcess *process, char *buffer, int length ); +}; + +#endif diff --git a/noncore/settings/packagemanager/oipkgconfigdlg.cpp b/noncore/settings/packagemanager/oipkgconfigdlg.cpp new file mode 100644 index 0000000..e335f8f --- a/dev/null +++ b/noncore/settings/packagemanager/oipkgconfigdlg.cpp @@ -0,0 +1,558 @@ +/* + This file is part of the Opie Project + + Copyright (c) 2003 Dan Williams <drw@handhelds.org> + =. + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#include "oipkgconfigdlg.h" + +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qgroupbox.h> +#include <qlabel.h> +#include <qlineedit.h> +#include <qlistbox.h> +#include <qpushbutton.h> +#include <qscrollview.h> + +#include <qpe/resource.h> + +OIpkgConfigDlg::OIpkgConfigDlg( OIpkg *ipkg, bool installOptions, QWidget *parent ) + : QDialog( parent, QString::null, true ) + , m_ipkg( ipkg ) + , m_configs( 0x0 ) + , m_installOptions( installOptions ) + , m_serverNew( false ) + , m_serverCurrent( -1 ) + , m_destNew( false ) + , m_destCurrent( -1 ) + , m_layout( this, 2, 4 ) + , m_tabWidget( this ) +{ + setCaption( tr( "Configuration" ) ); + + // Initialize configuration widgets + if ( !installOptions ) + { + initServerWidget(); + initDestinationWidget(); + initProxyWidget(); + } + initOptionsWidget(); + + // Load configuration information + initData(); + + // Setup tabs for all info + m_layout.addWidget( &m_tabWidget ); + if ( !m_installOptions ) + { + m_tabWidget.addTab( m_serverWidget, "packagemanager/servertab", tr( "Servers" ) ); + m_tabWidget.addTab( m_destWidget, "packagemanager/desttab", tr( "Destinations" ) ); + m_tabWidget.addTab( m_proxyWidget, "packagemanager/proxytab", tr( "Proxies" ) ); + m_tabWidget.addTab( m_optionsWidget, "exec", tr( "Options" ) ); + m_tabWidget.setCurrentTab( tr( "Servers" ) ); + } + else + { + m_tabWidget.addTab( m_optionsWidget, "exec", tr( "Options" ) ); + } + + showMaximized(); +} + +void OIpkgConfigDlg::accept() +{ + // Save server, destination and proxy configuration + if ( !m_installOptions ) + m_ipkg->setConfigItems( m_configs ); + + // Save options configuration + int options = 0; + if ( m_optForceDepends->isChecked() ) + options |= FORCE_DEPENDS; + if ( m_optForceReinstall->isChecked() ) + options |= FORCE_REINSTALL; + if ( m_optForceRemove->isChecked() ) + options |= FORCE_REMOVE; + if ( m_optForceOverwrite->isChecked() ) + options |= FORCE_OVERWRITE; + m_ipkg->setIpkgExecOptions( options ); + m_ipkg->setIpkgExecVerbosity( m_optVerboseIpkg->currentItem() ); + + QDialog::accept(); +} + +void OIpkgConfigDlg::reject() +{ + if ( m_configs ) + delete m_configs; +} + +void OIpkgConfigDlg::initServerWidget() +{ + m_serverWidget = new QWidget( this ); + + // Initialize UI + QVBoxLayout *vb = new QVBoxLayout( m_serverWidget ); + QScrollView *sv = new QScrollView( m_serverWidget ); + vb->addWidget( sv, 0, 0 ); + sv->setResizePolicy( QScrollView::AutoOneFit ); + sv->setFrameStyle( QFrame::NoFrame ); + QWidget *container = new QWidget( sv->viewport() ); + sv->addChild( container ); + QGridLayout *layout = new QGridLayout( container, 3, 2, 2, 4 ); + + m_serverList = new QListBox( container ); + m_serverList->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) ); + connect( m_serverList, SIGNAL(highlighted(int)), this, SLOT(slotServerEdit(int)) ); + layout->addMultiCellWidget( m_serverList, 0, 0, 0, 1 ); + + QPushButton *btn = new QPushButton( Resource::loadPixmap( "new" ), tr( "New" ), container ); + connect( btn, SIGNAL(clicked()), this, SLOT(slotServerNew()) ); + layout->addWidget( btn, 1, 0 ); + + btn = new QPushButton( Resource::loadPixmap( "trash" ), tr( "Delete" ), container ); + connect( btn, SIGNAL(clicked()), this, SLOT(slotServerDelete()) ); + layout->addWidget( btn, 1, 1 ); + + QGroupBox *grpbox = new QGroupBox( 0, Qt::Vertical, tr( "Server" ), container ); + grpbox->layout()->setSpacing( 2 ); + grpbox->layout()->setMargin( 4 ); + layout->addMultiCellWidget( grpbox, 2, 2, 0, 1 ); + + QGridLayout *grplayout = new QGridLayout( grpbox->layout() ); + + QLabel *label = new QLabel( tr( "Name:" ), grpbox ); + grplayout->addWidget( label, 0, 0 ); + m_serverName = new QLineEdit( grpbox ); + grplayout->addWidget( m_serverName, 0, 1 ); + + label = new QLabel( tr( "Address:" ), grpbox ); + grplayout->addWidget( label, 1, 0 ); + m_serverLocation = new QLineEdit( grpbox ); + grplayout->addWidget( m_serverLocation, 1, 1 ); + + m_serverActive = new QCheckBox( tr( "Active Server" ), grpbox ); + grplayout->addMultiCellWidget( m_serverActive, 2, 2, 0, 1 ); + + btn = new QPushButton( Resource::loadPixmap( "edit" ), tr( "Update" ), grpbox ); + connect( btn, SIGNAL(clicked()), this, SLOT(slotServerUpdate()) ); + grplayout->addMultiCellWidget( btn, 3, 3, 0, 1 ); +} + +void OIpkgConfigDlg::initDestinationWidget() +{ + m_destWidget = new QWidget( this ); + + // Initialize UI + QVBoxLayout *vb = new QVBoxLayout( m_destWidget ); + QScrollView *sv = new QScrollView( m_destWidget ); + vb->addWidget( sv, 0, 0 ); + sv->setResizePolicy( QScrollView::AutoOneFit ); + sv->setFrameStyle( QFrame::NoFrame ); + QWidget *container = new QWidget( sv->viewport() ); + sv->addChild( container ); + QGridLayout *layout = new QGridLayout( container, 3, 2, 2, 4 ); + + m_destList = new QListBox( container ); + m_destList->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) ); + connect( m_destList, SIGNAL(highlighted(int)), this, SLOT(slotDestEdit(int)) ); + layout->addMultiCellWidget( m_destList, 0, 0, 0, 1 ); + + QPushButton *btn = new QPushButton( Resource::loadPixmap( "new" ), tr( "New" ), container ); + connect( btn, SIGNAL(clicked()), this, SLOT(slotDestNew()) ); + layout->addWidget( btn, 1, 0 ); + + btn = new QPushButton( Resource::loadPixmap( "trash" ), tr( "Delete" ), container ); + connect( btn, SIGNAL(clicked()), this, SLOT(slotDestDelete()) ); + layout->addWidget( btn, 1, 1 ); + + QGroupBox *grpbox = new QGroupBox( 0, Qt::Vertical, tr( "Server" ), container ); + grpbox->layout()->setSpacing( 2 ); + grpbox->layout()->setMargin( 4 ); + layout->addMultiCellWidget( grpbox, 2, 2, 0, 1 ); + + QGridLayout *grplayout = new QGridLayout( grpbox->layout() ); + + QLabel *label = new QLabel( tr( "Name:" ), grpbox ); + grplayout->addWidget( label, 0, 0 ); + m_destName = new QLineEdit( grpbox ); + grplayout->addWidget( m_destName, 0, 1 ); + + label = new QLabel( tr( "Address:" ), grpbox ); + grplayout->addWidget( label, 1, 0 ); + m_destLocation = new QLineEdit( grpbox ); + grplayout->addWidget( m_destLocation, 1, 1 ); + + m_destActive = new QCheckBox( tr( "Active Server" ), grpbox ); + grplayout->addMultiCellWidget( m_destActive, 2, 2, 0, 1 ); + + btn = new QPushButton( Resource::loadPixmap( "edit" ), tr( "Update" ), grpbox ); + connect( btn, SIGNAL(clicked()), this, SLOT(slotDestUpdate()) ); + grplayout->addMultiCellWidget( btn, 3, 3, 0, 1 ); +} + +void OIpkgConfigDlg::initProxyWidget() +{ + m_proxyWidget = new QWidget( this ); + + // Initialize UI + QVBoxLayout *vb = new QVBoxLayout( m_proxyWidget ); + QScrollView *sv = new QScrollView( m_proxyWidget ); + vb->addWidget( sv, 0, 0 ); + sv->setResizePolicy( QScrollView::AutoOneFit ); + sv->setFrameStyle( QFrame::NoFrame ); + QWidget *container = new QWidget( sv->viewport() ); + sv->addChild( container ); + QGridLayout *layout = new QGridLayout( container, 4, 2, 2, 4 ); + + // HTTP proxy server configuration + QGroupBox *grpbox = new QGroupBox( 0, Qt::Vertical, tr( "HTTP Proxy" ), container ); + grpbox->layout()->setSpacing( 2 ); + grpbox->layout()->setMargin( 4 ); + layout->addMultiCellWidget( grpbox, 0, 0, 0, 1 ); + QVBoxLayout *grplayout = new QVBoxLayout( grpbox->layout() ); + m_proxyHttpServer = new QLineEdit( grpbox ); + grplayout->addWidget( m_proxyHttpServer ); + m_proxyHttpActive = new QCheckBox( tr( "Enabled" ), grpbox ); + grplayout->addWidget( m_proxyHttpActive ); + + // FTP proxy server configuration + grpbox = new QGroupBox( 0, Qt::Vertical, tr( "FTP Proxy" ), container ); + grpbox->layout()->setSpacing( 2 ); + grpbox->layout()->setMargin( 4 ); + layout->addMultiCellWidget( grpbox, 1, 1, 0, 1 ); + grplayout = new QVBoxLayout( grpbox->layout() ); + m_proxyFtpServer = new QLineEdit( grpbox ); + grplayout->addWidget( m_proxyFtpServer ); + m_proxyFtpActive = new QCheckBox( tr( "Enabled" ), grpbox ); + grplayout->addWidget( m_proxyFtpActive ); + + // Proxy server username and password configuration + QLabel *label = new QLabel( tr( "Username:" ), container ); + layout->addWidget( label, 2, 0 ); + m_proxyUsername = new QLineEdit( container ); + layout->addWidget( m_proxyUsername, 2, 1 ); + + label = new QLabel( tr( "Password:" ), container ); + layout->addWidget( label, 3, 0 ); + m_proxyPassword = new QLineEdit( container ); + layout->addWidget( m_proxyPassword, 3, 1 ); +} + +void OIpkgConfigDlg::initOptionsWidget() +{ + m_optionsWidget = new QWidget( this ); + + // Initialize UI + QVBoxLayout *vb = new QVBoxLayout( m_optionsWidget ); + QScrollView *sv = new QScrollView( m_optionsWidget ); + vb->addWidget( sv, 0, 0 ); + sv->setResizePolicy( QScrollView::AutoOneFit ); + sv->setFrameStyle( QFrame::NoFrame ); + QWidget *container = new QWidget( sv->viewport() ); + sv->addChild( container ); + QVBoxLayout *layout = new QVBoxLayout( container, 2, 4 ); + + m_optForceDepends = new QCheckBox( tr( "Force Depends" ), container ); + layout->addWidget( m_optForceDepends ); + + m_optForceReinstall = new QCheckBox( tr( "Force Reinstall" ), container ); + layout->addWidget( m_optForceReinstall ); + + m_optForceRemove = new QCheckBox( tr( "Force Remove" ), container ); + layout->addWidget( m_optForceRemove ); + + m_optForceOverwrite = new QCheckBox( tr( "Force Overwrite" ), container ); + layout->addWidget( m_optForceOverwrite ); + + QLabel *l = new QLabel( tr( "Information Level" ), container ); + layout->addWidget( l ); + + m_optVerboseIpkg = new QComboBox( container ); + m_optVerboseIpkg->insertItem( tr( "Errors only" ) ); + m_optVerboseIpkg->insertItem( tr( "Normal messages" ) ); + m_optVerboseIpkg->insertItem( tr( "Informative messages" ) ); + m_optVerboseIpkg->insertItem( tr( "Troubleshooting output" ) ); + layout->addWidget( m_optVerboseIpkg ); + + layout->addItem( new QSpacerItem( 1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding ) ); +} + +void OIpkgConfigDlg::initData() +{ + // Read ipkg configuration (server/destination/proxy) information + if ( m_ipkg && !m_installOptions ) + { + m_configs = m_ipkg->configItems(); + if ( m_configs ) + { + for ( OConfItemListIterator configIt( *m_configs ); configIt.current(); ++configIt ) + { + OConfItem *config = configIt.current(); + + // Add configuration item to the appropriate dialog controls + if ( config ) + { + if ( config->type() == OConfItem::Source ) + { + m_serverList->insertItem( config->name() ); + } + else if ( config->type() == OConfItem::Destination ) + { + m_destList->insertItem( config->name() ); + } + else if ( config->type() == OConfItem::Option ) + { + if ( config->name() == "http_proxy" ) + { + m_proxyHttpServer->setText( config->value() ); + m_proxyHttpActive->setChecked( config->active() ); + } + else if ( config->name() == "ftp_proxy" ) + { + m_proxyFtpServer->setText( config->value() ); + m_proxyFtpActive->setChecked( config->active() ); + } + else if ( config->name() == "proxy_username" ) + { + m_proxyUsername->setText( config->value() ); + } + else if ( config->name() == "proxy_password" ) + { + m_proxyPassword->setText( config->value() ); + } + } + } + } + } + } + + // Get Ipkg execution options + int options = m_ipkg->ipkgExecOptions(); + if ( options & FORCE_DEPENDS ) + m_optForceDepends->setChecked( true ); + if ( options & FORCE_REINSTALL ) + m_optForceReinstall->setChecked( true ); + if ( options & FORCE_REMOVE ) + m_optForceRemove->setChecked( true ); + if ( options & FORCE_OVERWRITE ) + m_optForceOverwrite->setChecked( true ); + + m_optVerboseIpkg->setCurrentItem( m_ipkg->ipkgExecVerbosity() ); +} + +OConfItem *OIpkgConfigDlg::findConfItem( OConfItem::Type type, const QString &name ) +{ + // Find selected server in list + OConfItemListIterator configIt( *m_configs ); + OConfItem *config = 0x0; + for ( ; configIt.current(); ++configIt ) + { + config = configIt.current(); + if ( config->type() == type && config->name() == name ) + break; + } + + if ( config && config->type() == type && config->name() == name ) + return config; + + return 0x0; +} + +void OIpkgConfigDlg::slotServerEdit( int index ) +{ + m_serverNew = false; + m_serverCurrent = index; + + // Find selected server in list + OConfItem *server = findConfItem( OConfItem::Source, m_serverList->currentText() ); + + // Display server details + if ( server ) + { + m_serverCurrName = server->name(); + m_serverName->setText( server->name() ); + m_serverLocation->setText( server->value() ); + m_serverActive->setChecked( server->active() ); + m_serverName->setFocus(); + } +} + +void OIpkgConfigDlg::slotServerNew() +{ + m_serverNew = true; + + m_serverName->setText( QString::null ); + m_serverLocation->setText( QString::null ); + m_serverActive->setChecked( true ); + m_serverName->setFocus(); +} + +void OIpkgConfigDlg::slotServerDelete() +{ + // Find selected server in list + OConfItem *server = findConfItem( OConfItem::Source, m_serverList->currentText() ); + + // Delete server + if ( server ) + { + m_configs->removeRef( server ); + m_serverList->removeItem( m_serverCurrent ); + } +} + +void OIpkgConfigDlg::slotServerUpdate() +{ + QString newName = m_serverName->text(); + + // Convert any spaces to underscores + newName.replace( QRegExp( " " ), "_" ); + + if ( !m_serverNew ) + { + // Find selected server in list + OConfItem *server = findConfItem( OConfItem::Source, m_serverCurrName ); + + // Delete server + if ( server ) + { + // Update url + server->setValue( m_serverLocation->text() ); + server->setActive( m_serverActive->isChecked() ); + + // Check if server name has changed, if it has then we need to replace the key in the map + if ( m_serverCurrName != newName ) + { + // Update server name + server->setName( newName ); + + // Update list box + m_serverList->changeItem( newName, m_serverCurrent ); + } + } + } + else + { + // Add new destination to configuration list + m_configs->append( new OConfItem( QString::null, OConfItem::Source, newName, + m_serverLocation->text(), m_serverActive->isChecked() ) ); + m_configs->sort(); + + m_serverList->insertItem( newName ); + m_serverList->setCurrentItem( m_serverList->count() ); + m_serverNew = false; + m_serverList->insertItem( newName ); + } +} + +void OIpkgConfigDlg::slotDestEdit( int index ) +{ + m_destNew = false; + m_destCurrent = index; + + // Find selected destination in list + OConfItem *destination = findConfItem( OConfItem::Destination, m_destList->currentText() ); + + // Display destination details + if ( destination ) + { + m_destCurrName = destination->name(); + m_destName->setText( destination->name() ); + m_destLocation->setText( destination->value() ); + m_destActive->setChecked( destination->active() ); + m_destName->setFocus(); + } +} + +void OIpkgConfigDlg::slotDestNew() +{ + m_destNew = true; + + m_destName->setText( QString::null ); + m_destLocation->setText( QString::null ); + m_destActive->setChecked( true ); + m_destName->setFocus(); +} + +void OIpkgConfigDlg::slotDestDelete() +{ + // Find selected destination in list + OConfItem *destination = findConfItem( OConfItem::Destination, m_destList->currentText() ); + + // Delete destination + if ( destination ) + { + m_configs->removeRef( destination ); + m_destList->removeItem( m_destCurrent ); + } +} + +void OIpkgConfigDlg::slotDestUpdate() +{ + QString newName = m_destName->text(); + + // Convert any spaces to underscores + newName.replace( QRegExp( " " ), "_" ); + + if ( !m_destNew ) + { + // Find selected destination in list + OConfItem *destination = findConfItem( OConfItem::Destination, m_destCurrName ); + + // Display destination details + if ( destination ) + { + // Update url + destination->setValue( m_destLocation->text() ); + destination->setActive( m_destActive->isChecked() ); + + // Check if destination name has changed, if it has then we need to replace the key in the map + if ( m_destCurrName != newName ) + { + // Update destination name + destination->setName( newName ); + + // Update list box + m_destList->changeItem( newName, m_destCurrent ); + } + } + } + else + { + // Add new destination to configuration list + m_configs->append( new OConfItem( QString::null, OConfItem::Destination, newName, + m_destLocation->text(), m_destActive->isChecked() ) ); + m_configs->sort(); + + m_destList->insertItem( newName ); + m_destList->setCurrentItem( m_destList->count() ); + m_destNew = false; + } +} diff --git a/noncore/settings/packagemanager/oipkgconfigdlg.h b/noncore/settings/packagemanager/oipkgconfigdlg.h new file mode 100644 index 0000000..ef8c596 --- a/dev/null +++ b/noncore/settings/packagemanager/oipkgconfigdlg.h @@ -0,0 +1,131 @@ +/* + This file is part of the Opie Project + + Copyright (c) 2003 Dan Williams <drw@handhelds.org> + =. + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + + +#ifndef OIPKGCONFIGDLG_H +#define OIPKGCONFIGDLG_H + +#include <qdialog.h> +#include <qlayout.h> + +#include <opie/otabwidget.h> + +#include "oipkg.h" + +class QCheckBox; +class QComboBox; +class QLineEdit; +class QListBox; + +class OIpkgConfigDlg : public QDialog +{ + Q_OBJECT + +public: + OIpkgConfigDlg( OIpkg *ipkg = 0x0, bool installOptions = false, QWidget *parent = 0x0 ); + +protected slots: + void accept(); + void reject(); + +private: + OIpkg *m_ipkg; // Pointer to Ipkg class for retrieving/saving configuration options + OConfItemList *m_configs; // Local list of configuration items + + bool m_installOptions; // If true, will only display the Options tab + + // Server cached information + bool m_serverNew; // Indicates if server information is for a new server + int m_serverCurrent; // Index of currently selected server in m_serverList + QString m_serverCurrName; // Name of currently selected server in m_serverList + + // Destination cached information + bool m_destNew; // Indicates if destination information is for a new destination + int m_destCurrent; // Index of currently selected destination in m_destList + QString m_destCurrName; // Name of currently selected destination in m_destList + + // UI controls + QVBoxLayout m_layout; // Main dialog layout control + OTabWidget m_tabWidget; // Main tab widget control + QWidget *m_serverWidget; // Widget containing server configuration controls + QWidget *m_destWidget; // Widget containing destination configuration controls + QWidget *m_proxyWidget; // Widget containing proxy configuration controls + QWidget *m_optionsWidget; // Widget containing ipkg execution configuration controls + + // Server configuration UI controls + QListBox *m_serverList; // Server list selection + QLineEdit *m_serverName; // Server name edit box + QLineEdit *m_serverLocation; // Server location URL edit box + QCheckBox *m_serverActive; // Activate server check box + + // Destination configuration UI controls + QListBox *m_destList; // Destination list selection + QLineEdit *m_destName; // Destination name edit box + QLineEdit *m_destLocation; // Destination location URL edit box + QCheckBox *m_destActive; // Activate destination check box + + // Proxy server configuration UI controls + QLineEdit *m_proxyHttpServer; // HTTP proxy server URL edit box + QCheckBox *m_proxyHttpActive; // Activate HTTP proxy check box + QLineEdit *m_proxyFtpServer; // FTP proxy server edit box + QCheckBox *m_proxyFtpActive; // Activate FTP proxy check box + QLineEdit *m_proxyUsername; // Proxy server username edit box + QLineEdit *m_proxyPassword; // Proxy server password edit box + + // Options configuration UI controls + QCheckBox *m_optForceDepends; // Force depends ipkg option checkbox + QCheckBox *m_optForceReinstall; // Force reinstall ipkg option checkbox + QCheckBox *m_optForceRemove; // Force remove ipkg option checkbox + QCheckBox *m_optForceOverwrite; // Force overwrite ipkg option checkbox + QComboBox *m_optVerboseIpkg; // Ipkg verbosity option selection + + void initServerWidget(); + void initDestinationWidget(); + void initProxyWidget(); + void initOptionsWidget(); + + void initData(); + + OConfItem *findConfItem( OConfItem::Type type = OConfItem::NotDefined, const QString &name = 0x0 ); + +private slots: + void slotServerEdit( int index ); + void slotServerNew(); + void slotServerDelete(); + void slotServerUpdate(); + + void slotDestEdit( int index ); + void slotDestNew(); + void slotDestDelete(); + void slotDestUpdate(); +}; + +#endif diff --git a/noncore/settings/packagemanager/opackage.cpp b/noncore/settings/packagemanager/opackage.cpp new file mode 100644 index 0000000..34717e3 --- a/dev/null +++ b/noncore/settings/packagemanager/opackage.cpp @@ -0,0 +1,43 @@ +/* + This file is part of the Opie Project + + Copyright (c) 2003 Dan Williams <drw@handhelds.org> + =. + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#include "opackage.h" + +OPackage::OPackage( const QString &name, const QString &version, const QString &versionInstalled, + const QString &source, const QString &destination, const QString &category ) + : m_name( name ) + , m_version( version ) + , m_versionInstalled( versionInstalled ) + , m_source( source ) + , m_destination( destination ) + , m_category( category ) +{ +} diff --git a/noncore/settings/packagemanager/opackage.h b/noncore/settings/packagemanager/opackage.h new file mode 100644 index 0000000..1e2e49f --- a/dev/null +++ b/noncore/settings/packagemanager/opackage.h @@ -0,0 +1,74 @@ +/* + This file is part of the Opie Project + + Copyright (c) 2003 Dan Williams <drw@handhelds.org> + =. + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#ifndef OPACKAGE_H +#define OPACKAGE_H + +#include <qlist.h> +#include <qstring.h> + +class OPackage +{ +public: + enum Command { Install, Remove, Update, Upgrade, Download, Info, Files, Version, NotDefined }; + + OPackage( const QString &name = 0x0, + const QString &version = 0x0, const QString &versionInstalled = 0x0, + const QString &source = 0x0, const QString &destination = 0x0, + const QString &category = "misc" ); + + const QString &name() { return m_name; } + const QString &version() { return m_version; } + const QString &versionInstalled() { return m_versionInstalled; } + const QString &source() { return m_source; } + const QString &destination() { return m_destination; } + const QString &category() { return m_category; } + + void setName( const QString &name ) { m_name = name; } + void setVersion( const QString &version ) { m_version = version; } + void setVersionInstalled( const QString &version ) { m_versionInstalled = version; } + void setSource( const QString &source ) { m_source = source; } + void setDestination( const QString &destination ) { m_destination = destination; } + void setCategory( const QString &category ) { m_category = category; } + +private: + QString m_name; // Name of item + QString m_version; // Available version number of item + QString m_versionInstalled; // Installed version number of item, null if not installed + QString m_source; // Source feed of available version + QString m_destination; // Location item is installed to, null if not installed + QString m_category; // Item category +}; + +typedef QList<OPackage> OPackageList; +typedef QListIterator<OPackage> OPackageListIterator; + +#endif diff --git a/noncore/settings/packagemanager/opackagemanager.cpp b/noncore/settings/packagemanager/opackagemanager.cpp new file mode 100644 index 0000000..6bef918 --- a/dev/null +++ b/noncore/settings/packagemanager/opackagemanager.cpp @@ -0,0 +1,330 @@ +/* + This file is part of the Opie Project + + Copyright (c) 2003 Dan Williams <drw@handhelds.org> + =. + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#include <qpe/qpeapplication.h> + +#include "opackagemanager.h" +#include "oipkgconfigdlg.h" + +OPackageManager::OPackageManager( Config *config, QObject *parent, const char *name ) + : QObject( parent, name ) + , m_config( config ) + , m_ipkg( m_config, this ) + , m_packages( 9973 ) + , m_categories() +{ + m_packages.setAutoDelete( true ); +} + +void OPackageManager::loadAvailablePackages() +{ + m_packages.clear(); + + OConfItemList *serverList = m_ipkg.servers(); + + if ( serverList ) + { + // Initialize status messaging + emit initStatus( serverList->count() ); + int serverCount = 0; + + bool categoryAdded = false; + + for ( OConfItemListIterator serverIt( *serverList ); serverIt.current(); ++serverIt ) + { + OConfItem *server = serverIt.current(); + + // Process server only if it is active + if ( server->active() ) + { + // Update status + QString status = tr( "Reading available packages:\n\t" ); + status.append( server->name() ); + emit statusText( status ); + ++serverCount; + emit statusBar( serverCount ); + qApp->processEvents(); + + OPackageList *packageList = m_ipkg.availablePackages( server->name() ); + if ( packageList ) + { + for ( OPackageListIterator packageIt( *packageList ); packageIt.current(); ++packageIt ) + { + OPackage *package = packageIt.current(); + + // Load package info + if ( !m_packages.find( package->name() ) ) + m_packages.insert( package->name(), package ); + else + { + // If new package is newer version, replace existing package + OPackage *currPackage = m_packages[package->name()]; + if ( compareVersions( package->version(), currPackage->version() ) == 1 ) + m_packages.replace( package->name(), package ); + } + + // Add category to list if it doesn't already exist + if ( m_categories.grep( package->category() ).isEmpty() ) + { + m_categories << package->category(); + categoryAdded = true; + } + } + } + } + } + delete serverList; + + // Sort category list if categories were added + if ( categoryAdded ) + m_categories.sort(); + } +} + +void OPackageManager::loadInstalledPackages() +{ + OConfItemList *destList = m_ipkg.destinations(); + + if ( destList ) + { + // Initialize status messaging + emit initStatus( destList->count() ); + int destCount = 0; + + bool categoryAdded = false; + + for ( OConfItemListIterator destIt( *destList ); destIt.current(); ++destIt ) + { + OConfItem *destination = destIt.current(); + + // Process destination only if it is active + if ( destination->active() ) + { + // Update status + QString status = tr( "Reading installed packages:\n\t" ); + status.append( destination->name() ); + emit statusText( status ); + ++destCount; + emit statusBar( destCount ); + qApp->processEvents(); + + OPackageList *packageList = m_ipkg.installedPackages( destination->name(), + destination->value() ); + if ( packageList ) + { + for ( OPackageListIterator packageIt( *packageList ); packageIt.current(); ++packageIt ) + { + OPackage *package = packageIt.current(); + OPackage *currPackage = m_packages[package->name()]; + if ( currPackage ) + { + // Package is in a current feed, update installed version, destination + currPackage->setVersionInstalled( package->versionInstalled() ); + currPackage->setDestination( package->destination() ); + + delete package; + } + else + { + // Package isn't in a current feed, add to list + m_packages.insert( package->name(), package ); + + // Add category to list if it doesn't already exist + if ( m_categories.grep( package->category() ).isEmpty() ) + { + m_categories << package->category(); + categoryAdded = true; + } + } + } + } + } + } + delete destList; + + // Sort category list if categories were added + if ( categoryAdded ) + m_categories.sort(); + } +} + +OPackageList *OPackageManager::packages() +{ + // TODO - look to see if list is loaded, if not, load available & installed + + OPackageList *pl = new OPackageList; + + for ( QDictIterator<OPackage> packageIt( m_packages ); packageIt.current(); ++packageIt ) + pl->append( packageIt.current() ); + + return pl; +} + +OPackageList *OPackageManager::filterPackages( const QString &name,const QString &server, + const QString &destination, Status status, const QString &category ) +{ + // TODO - look to see if list is loaded, if not, load available & installed + + OPackageList *pl = new OPackageList; + for ( QDictIterator<OPackage> packageIt( m_packages ); packageIt.current(); ++packageIt ) + { + OPackage *package = packageIt.current(); + + bool nameMatch = ( name.isNull() || package->name().contains( name ) ); + bool serverMatch = ( server.isNull() || package->source() == server ); + bool destinationMatch = ( destination.isNull() || package->destination() == destination ); + bool statusMatch; + switch ( status ) + { + case All : statusMatch = true; + break; + case NotInstalled : statusMatch = package->versionInstalled().isNull(); + break; + case Installed : statusMatch = !package->versionInstalled().isNull(); + break; + case Updated : statusMatch = ( !package->versionInstalled().isNull() && + compareVersions( package->version(), package->versionInstalled() ) == 1 ); + break; + default : statusMatch = true; + break; + }; + bool categoryMatch = ( category.isNull() || package->category() == category ); + + if ( nameMatch && serverMatch && destinationMatch && statusMatch && categoryMatch ) + pl->append( packageIt.current() ); + } + + return pl; +} + +QStringList *OPackageManager::servers() +{ + QStringList *sl = new QStringList(); + + OConfItemList *serverList = m_ipkg.servers(); + if ( serverList ) + { + for ( OConfItemListIterator serverIt( *serverList ); serverIt.current(); ++serverIt ) + { + OConfItem *server = serverIt.current(); + + // Add only active servers + if ( server->active() ) + *sl << server->name(); + } + } + + return sl; +} + +QStringList *OPackageManager::destinations() +{ + QStringList *dl = new QStringList(); + + OConfItemList *destList = m_ipkg.destinations(); + if ( destList ) + { + for ( OConfItemListIterator destIt( *destList ); destIt.current(); ++destIt ) + { + OConfItem *destination = destIt.current(); + + // Add only active destinations + if ( destination->active() ) + *dl << destination->name(); + } + } + + return dl; +} + +OConfItem *OPackageManager::findConfItem( OConfItem::Type type, const QString &name ) +{ + OConfItem *confItem = 0x0; + OConfItemList *confList = m_ipkg.configItems(); + if ( confList ) + { + for ( OConfItemListIterator confIt( *confList ); confIt.current(); ++confIt ) + { + OConfItem *conf = confIt.current(); + + // Add only active confinations + if ( conf->type() == type && conf->name() == name ) + { + confItem = conf; + break; + } + } + } + + return confItem; + +} + +OPackage *OPackageManager::findPackage( const QString &name ) +{ + return m_packages[ name ]; +} + +int OPackageManager::compareVersions( const QString &version1, const QString &version2 ) +{ + // TODO - do proper compare! + if ( version1 < version2 ) + return -1; + else if ( version1 > version2 ) + return 1; + + return 0; +} + +bool OPackageManager::configureDlg( bool installOptions ) +{ + OIpkgConfigDlg dlg( &m_ipkg, installOptions, static_cast<QWidget *>(parent()) ); + return ( dlg.exec() == QDialog::Accepted ); +} + +void OPackageManager::saveSettings() +{ + m_ipkg.saveSettings(); +} + +bool OPackageManager::executeCommand( OPackage::Command command, QStringList *packages, + const QString &destination, const QObject *receiver, + const char *slotOutput, const char *slotErrors, + const char *slotFinished, bool rawOutput ) +{ + return m_ipkg.executeCommand( command, packages, destination, receiver, slotOutput, slotErrors, + slotFinished, rawOutput ); +} + +void OPackageManager::abortCommand() +{ + m_ipkg.abortCommand(); +} diff --git a/noncore/settings/packagemanager/opackagemanager.h b/noncore/settings/packagemanager/opackagemanager.h new file mode 100644 index 0000000..5e1a30a --- a/dev/null +++ b/noncore/settings/packagemanager/opackagemanager.h @@ -0,0 +1,91 @@ +/* + This file is part of the Opie Project + + Copyright (c) 2003 Dan Williams <drw@handhelds.org> + =. + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#ifndef OPACKAGEMANAGER_H +#define OPACKAGEMANAGER_H + +#include <qdict.h> +#include <qobject.h> +#include <qstringlist.h> + +#include <qpe/config.h> + +#include "oipkg.h" + +class OPackageManager : public QObject +{ + Q_OBJECT + +public: + OPackageManager( Config *config = 0x0, QObject *parent = 0x0, const char *name = 0x0 ); + + void loadAvailablePackages(); + void loadInstalledPackages(); + + enum Status { All, NotInstalled, Installed, Updated, NotDefined }; + + OPackageList *packages(); + OPackageList *filterPackages( const QString &name = 0x0,const QString &server = 0x0, + const QString &destination = 0x0, Status status = NotDefined, + const QString &category = 0x0 ); + + const QStringList &categories() { return m_categories; } + QStringList *servers(); + QStringList *destinations(); + + int compareVersions( const QString &version1, const QString &version2 ); + + OConfItem *findConfItem( OConfItem::Type type = OConfItem::NotDefined, + const QString &name = QString::null ); + OPackage *findPackage( const QString &name = QString::null ); + + bool configureDlg( bool installOptions = false ); + void saveSettings(); + + bool executeCommand( OPackage::Command command = OPackage::NotDefined, QStringList *parameters = 0x0, + const QString &destination = QString::null, const QObject *receiver = 0x0, + const char *slotOutput = 0x0, const char *slotErrors = 0x0, + const char *slotFinished = 0x0, bool rawOutput = true ); + void abortCommand(); + +private: + Config *m_config; // Pointer to application configuration file + OIpkg m_ipkg; // OIpkg object to retrieve package/configuration information + QDict<OPackage> m_packages; // Global list of available packages + QStringList m_categories; // List of all categories + +signals: + void initStatus( int numSteps ); + void statusText( const QString &status ); + void statusBar( int currStep ); +}; + +#endif diff --git a/noncore/settings/packagemanager/opie-packagemanager.control b/noncore/settings/packagemanager/opie-packagemanager.control new file mode 100644 index 0000000..db06761 --- a/dev/null +++ b/noncore/settings/packagemanager/opie-packagemanager.control @@ -0,0 +1,10 @@ +Package: opie-packagemanager +Files: plugins/application/libpackagemanager.so* bin/packagemanager pics/packagemanager apps/Settings/packagemanager.desktop +Priority: optional +Section: Settings +Depends: task-opie-minimal +Replaces: packagemanager +Architecture: arm +Maintainer: Dan Williams (drw@handhelds.org) +Description: Opie package management client +Version: 0.1.0 diff --git a/noncore/settings/packagemanager/packageinfodlg.cpp b/noncore/settings/packagemanager/packageinfodlg.cpp new file mode 100644 index 0000000..71f17eb --- a/dev/null +++ b/noncore/settings/packagemanager/packageinfodlg.cpp @@ -0,0 +1,56 @@ +/* + This file is part of the OPIE Project + + =. Copyright (c) 2003 Dan Williams <drw@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This file is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This file is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU General +..}^=.= = ; Public License for more details. +++= -. .` .: + : = ...= . :.=- You should have received a copy of the GNU + -. .:....=;==+<; General Public License along with this file; + -_. . . )=. = see the file COPYING. If not, write to the + -- :-=` Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#include "packageinfodlg.h" + +#include <qlayout.h> +#include <qpushbutton.h> + +#include <qpe/resource.h> + +PackageInfoDlg::PackageInfoDlg( QWidget *parent, OPackageManager *pm, const QString &package ) + : QWidget( 0x0 ) + , m_packman( pm ) + , m_output( this ) +{ + // Initialize UI + if ( parent ) + parent->setCaption( package ); + + QVBoxLayout *layout = new QVBoxLayout( this, 4, 0 ); + + m_output.setReadOnly( true ); + layout->addWidget( &m_output ); + + QPushButton *btn = new QPushButton( Resource::loadPixmap( "enter" ), tr( "Close" ), this ); + layout->addWidget( btn ); +// TODO connect( btn, SIGNAL(clicked()), this, SLOT(slotBtnClose()) ); + + +} diff --git a/noncore/settings/packagemanager/packageinfodlg.h b/noncore/settings/packagemanager/packageinfodlg.h new file mode 100644 index 0000000..3bb9a7a --- a/dev/null +++ b/noncore/settings/packagemanager/packageinfodlg.h @@ -0,0 +1,58 @@ +/* + This file is part of the OPIE Project + + =. Copyright (c) 2003 Dan Williams <drw@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This file is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This file is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU General +..}^=.= = ; Public License for more details. +++= -. .` .: + : = ...= . :.=- You should have received a copy of the GNU + -. .:....=;==+<; General Public License along with this file; + -_. . . )=. = see the file COPYING. If not, write to the + -- :-=` Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#ifndef PACKAGEINFODLG_H +#define PACKAGEINFODLG_H + +#include <qmultilineedit.h> +#include <qwidget.h> + +#include <opie/oprocess.h> + +#include "opackage.h" + +class QPushButton; + +class OPackageManager; + +class PackageInfoDlg : public QWidget +{ + Q_OBJECT + +public: + PackageInfoDlg( QWidget *parent = 0x0, OPackageManager *pm = 0x0, const QString &package = QString::null ); + +private: + OPackageManager *m_packman; // Pointer to application instance of package manager + + // UI controls + QMultiLineEdit m_output; // Multi-line edit to display package information +}; + +#endif diff --git a/noncore/settings/packagemanager/packagemanager.pro b/noncore/settings/packagemanager/packagemanager.pro new file mode 100644 index 0000000..9aa3dc6 --- a/dev/null +++ b/noncore/settings/packagemanager/packagemanager.pro @@ -0,0 +1,31 @@ +CONFIG = qt warn_on release quick-app + +SOURCES = opackage.cpp \ + oconfitem.cpp \ + oipkg.cpp \ + oipkgconfigdlg.cpp \ + opackagemanager.cpp \ + mainwindow.cpp \ + installdlg.cpp \ + packageinfodlg.cpp \ + filterdlg.cpp \ + promptdlg.cpp \ + main.cpp +HEADERS = opackage.h \ + oconfitem.h \ + oipkg.h \ + oipkgconfigdlg.h \ + opackagemanager.h \ + mainwindow.h \ + installdlg.h \ + packageinfodlg.h \ + filterdlg.h \ + promptdlg.h + +TARGET = packagemanager +INCLUDEPATH += $(OPIEDIR)/include +DEPENDPATH += $(OPIEDIR)/include +LIBS += -lqpe -lopie + +include ( $(OPIEDIR)/include.pro ) + diff --git a/noncore/settings/packagemanager/promptdlg.cpp b/noncore/settings/packagemanager/promptdlg.cpp new file mode 100644 index 0000000..3122699 --- a/dev/null +++ b/noncore/settings/packagemanager/promptdlg.cpp @@ -0,0 +1,140 @@ +/* + This file is part of the OPIE Project + + =. Copyright (c) 2003 Dan Williams <drw@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This file is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This file is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU General +..}^=.= = ; Public License for more details. +++= -. .` .: + : = ...= . :.=- You should have received a copy of the GNU + -. .:....=;==+<; General Public License along with this file; + -_. . . )=. = see the file COPYING. If not, write to the + -- :-=` Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#include "promptdlg.h" + +#include <qlabel.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qwidgetlist.h> + +#include <qpe/qpeapplication.h> + +PromptDlg::PromptDlg( const QString &caption, const QString &text, const QString &btn1, const QString &btn2, + QWidget *parent ) + : QWidget( parent, QString::null, WType_Modal | WType_TopLevel | WStyle_Dialog ) + , m_btnClicked( -1 ) +{ + setCaption( caption ); + + QGridLayout *layout = new QGridLayout( this, 2, 2, 4, 2 ); + QLabel *label = new QLabel( text, this ); + label->setAlignment( AlignCenter | WordBreak ); + layout->addMultiCellWidget( label, 0, 0, 0, 1 ); + + QPushButton *btn = new QPushButton( btn1, this ); + layout->addWidget( btn, 1, 0 ); + connect( btn, SIGNAL(clicked()), this, SLOT(slotBtn1Clicked()) ); + + btn = new QPushButton( btn2, this ); + layout->addWidget( btn, 1, 1 ); + connect( btn, SIGNAL(clicked()), this, SLOT(slotBtn2Clicked()) ); +} + +int PromptDlg::exec() +{ + // Determine position of dialog. Derived from QT's QDialog::show() method. + QWidget *w = parentWidget(); + QPoint p( 0, 0 ); + int extraw = 0, extrah = 0; + QWidget * desk = QApplication::desktop(); + if ( w ) + w = w->topLevelWidget(); + + QWidgetList *list = QApplication::topLevelWidgets(); + QWidgetListIt it( *list ); + while ( (extraw == 0 || extrah == 0) && it.current() != 0 ) + { + int w, h; + QWidget * current = it.current(); + ++it; + w = current->geometry().x() - current->x(); + h = current->geometry().y() - current->y(); + + extraw = QMAX( extraw, w ); + extrah = QMAX( extrah, h ); + } + delete list; + + // sanity check for decoration frames. With embedding, we + // might get extraordinary values + if ( extraw >= 10 || extrah >= 40 ) + extraw = extrah = 0; + + if ( w ) + { + // Use mapToGlobal rather than geometry() in case w might + // be embedded in another application + QPoint pp = w->mapToGlobal( QPoint(0,0) ); + p = QPoint( pp.x() + w->width()/2, pp.y() + w->height()/ 2 ); + } + else + p = QPoint( desk->width()/2, desk->height()/2 ); + + p = QPoint( p.x()-width()/2 - extraw, p.y()-height()/2 - extrah ); + + if ( p.x() + extraw + width() > desk->width() ) + p.setX( desk->width() - width() - extraw ); + if ( p.x() < 0 ) + p.setX( 0 ); + + if ( p.y() + extrah + height() > desk->height() ) + p.setY( desk->height() - height() - extrah ); + if ( p.y() < 0 ) + p.setY( 0 ); + + move( p ); + show(); + + // Enter event loop for modality + qApp->enter_loop(); + + return m_btnClicked; +} + +int PromptDlg::ask( const QString &caption, const QString &text, const QString &btn1, const QString &btn2, + QWidget *parent ) +{ + PromptDlg *dlg = new PromptDlg( caption, text, btn1, btn2, parent ); + int rc = dlg->exec(); + delete dlg; + return rc; +} + +void PromptDlg::slotBtn1Clicked() +{ + m_btnClicked = 1; + qApp->exit_loop(); +} + +void PromptDlg::slotBtn2Clicked() +{ + m_btnClicked = 2; + qApp->exit_loop(); +} diff --git a/noncore/settings/packagemanager/promptdlg.h b/noncore/settings/packagemanager/promptdlg.h new file mode 100644 index 0000000..e0e9f41 --- a/dev/null +++ b/noncore/settings/packagemanager/promptdlg.h @@ -0,0 +1,57 @@ +/* + This file is part of the OPIE Project + + =. Copyright (c) 2003 Dan Williams <drw@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This file is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This file is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU General +..}^=.= = ; Public License for more details. +++= -. .` .: + : = ...= . :.=- You should have received a copy of the GNU + -. .:....=;==+<; General Public License along with this file; + -_. . . )=. = see the file COPYING. If not, write to the + -- :-=` Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#ifndef PROMPTDLG_H +#define PROMPTDLG_H + +#include <qwidget.h> + +class PromptDlg : public QWidget +{ + Q_OBJECT + +public: + PromptDlg( const QString &caption = 0x0, const QString &text = 0x0, const QString &btn1 = 0x0, + const QString &btn2 = 0x0, QWidget *parent = 0x0 ); + + int exec(); + int btnPressed() { return m_btnClicked; } + + static int ask( const QString &caption = 0x0, const QString &text = 0x0, const QString &btn1 = 0x0, + const QString &btn2 = 0x0, QWidget *parent = 0x0 ); + +private: + int m_btnClicked; // Indicator for which button was pressed + +private slots: + void slotBtn1Clicked(); + void slotBtn2Clicked(); +}; + +#endif @@ -121,12 +121,13 @@ CONFIG_OPIE-RDESKTOP noncore/net/opierdesktop opierdesktop.pro CONFIG_OPIEREC noncore/multimedia/opierec opierec.pro CONFIG_TONLEITER noncore/multimedia/tonleiter tonleiter.pro CONFIG_OPIETOOTH-APPLET noncore/net/opietooth/applet applet.pro CONFIG_OPIETOOTH-MANAGER noncore/net/opietooth/manager manager.pro CONFIG_OSEARCH core/pim/osearch osearch.pro CONFIG_OXYGEN noncore/apps/oxygen oxygen.pro +CONFIG_PACKAGEMANAGER noncore/settings/packagemanager packagemanager.pro CONFIG_PARASHOOT noncore/games/parashoot parashoot.pro CONFIG_PICKBOARD inputmethods/pickboard pickboard.pro CONFIG_QASTEROIDS noncore/games/qasteroids qasteroids.pro CONFIG_QASHMONEY noncore/apps/qashmoney qashmoney.pro CONFIG_QCOP core/apps/qcop qcop.pro CONFIG_QPDF noncore/unsupported/qpdf qpdf.pro diff --git a/pics/packagemanager/apply.png b/pics/packagemanager/apply.png Binary files differnew file mode 100644 index 0000000..80ceb68 --- a/dev/null +++ b/pics/packagemanager/apply.png diff --git a/pics/packagemanager/desttab.png b/pics/packagemanager/desttab.png Binary files differnew file mode 100644 index 0000000..d0b9b86 --- a/dev/null +++ b/pics/packagemanager/desttab.png diff --git a/pics/packagemanager/download.png b/pics/packagemanager/download.png Binary files differnew file mode 100644 index 0000000..727ec60 --- a/dev/null +++ b/pics/packagemanager/download.png diff --git a/pics/packagemanager/filter.png b/pics/packagemanager/filter.png Binary files differnew file mode 100644 index 0000000..4518e72 --- a/dev/null +++ b/pics/packagemanager/filter.png diff --git a/pics/packagemanager/ipkg.png b/pics/packagemanager/ipkg.png Binary files differnew file mode 100644 index 0000000..da8ffe6 --- a/dev/null +++ b/pics/packagemanager/ipkg.png diff --git a/pics/packagemanager/keyboard.png b/pics/packagemanager/keyboard.png Binary files differnew file mode 100644 index 0000000..5827b6c --- a/dev/null +++ b/pics/packagemanager/keyboard.png diff --git a/pics/packagemanager/packagemanager.png b/pics/packagemanager/packagemanager.png Binary files differnew file mode 100644 index 0000000..b938d97 --- a/dev/null +++ b/pics/packagemanager/packagemanager.png diff --git a/pics/packagemanager/proxytab.png b/pics/packagemanager/proxytab.png Binary files differnew file mode 100644 index 0000000..ab630ed --- a/dev/null +++ b/pics/packagemanager/proxytab.png diff --git a/pics/packagemanager/remove.png b/pics/packagemanager/remove.png Binary files differnew file mode 100644 index 0000000..abb70aa --- a/dev/null +++ b/pics/packagemanager/remove.png diff --git a/pics/packagemanager/servertab.png b/pics/packagemanager/servertab.png Binary files differnew file mode 100644 index 0000000..e3b77ce --- a/dev/null +++ b/pics/packagemanager/servertab.png diff --git a/pics/packagemanager/update.png b/pics/packagemanager/update.png Binary files differnew file mode 100644 index 0000000..20e1192 --- a/dev/null +++ b/pics/packagemanager/update.png diff --git a/pics/packagemanager/updated.png b/pics/packagemanager/updated.png Binary files differnew file mode 100644 index 0000000..eaabbf1 --- a/dev/null +++ b/pics/packagemanager/updated.png diff --git a/pics/packagemanager/upgrade.png b/pics/packagemanager/upgrade.png Binary files differnew file mode 100644 index 0000000..7afbd44 --- a/dev/null +++ b/pics/packagemanager/upgrade.png |