/*
* install . cpp
*
* Copyright ( c ) 2007 Fabian Wuertz
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* 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 General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
# include <kgenericfactory.h>
# include <klocale.h>
# include <kfiledialog.h>
# include <kurlrequester.h>
# include <kaboutapplication.h>
# include <qlistbox.h>
# include <qfile.h>
# include <qpushbutton.h>
# include <qwidgetstack.h>
# include <qlabel.h>
# include <qlistview.h>
# include <qregexp.h>
# include <qradiobutton.h>
# include <qfiledialog.h>
# include <console.h>
# include <install.h>
# include <string>
# include <stdio.h>
using namespace std ;
install : : install ( const QString & url , QWidget * parent , const char * name , const QStringList & )
: InstallDialog ( parent , name )
{
if ( ! url )
path = KFileDialog : : getOpenFileName ( QString : : null , i18n ( " Debian Package (*.deb) " ) , this , i18n ( " Choose a Debian package file to open " ) ) ;
else
path = url ;
this - > shell = new Process ( ) ;
this - > shell - > setCommand ( " dpkg -f " + path ) ;
this - > shell - > start ( true ) ;
fields = QStringList : : split ( " \n " , this - > shell - > getBuffer ( ) . stripWhiteSpace ( ) ) ;
installPushButton - > hide ( ) ;
nextPushButton1 - > hide ( ) ;
// Get KDE prefix
// FIXME Is there a better way to do this???
string prefixcommand = " kde-config --prefix " ;
FILE * pipe_prefix ;
char prefix_result [ 2048 ] ;
int i ;
if ( ( pipe_prefix = popen ( prefixcommand . c_str ( ) , " r " ) ) = = NULL )
{
m_kdePrefix = " /usr " ;
}
else {
fgets ( prefix_result , 2048 , pipe_prefix ) ;
pclose ( pipe_prefix ) ;
for ( i = 0 ; i < 2048 ; i + + ) {
if ( prefix_result [ i ] = = 0 ) {
prefix_result [ i - 1 ] = 0 ;
i = 2048 ;
}
}
m_kdePrefix = QString ( prefix_result ) ;
}
if ( ! checkArchitecture ( ) )
page2x1 ( ) ;
else if ( isLocked ( ) )
page2x2 ( ) ;
}
//----------------------------------------------------------------------------//
//--- next -------------------------------------------------------------------//
//----------------------------------------------------------------------------//
void install : : next1 ( )
{
if ( ! isLocked ( ) )
{
nextPushButton1 - > hide ( ) ;
nextPushButton2 - > show ( ) ;
widgetStack - > raiseWidget ( 0 ) ;
}
}
void install : : next2 ( )
{
nextPushButton2 - > hide ( ) ;
if ( syncRadioButton - > isChecked ( ) )
page3 ( ) ;
else
page1 ( ) ;
}
//----------------------------------------------------------------------------//
//--- pages ------------------------------------------------------------------//
//----------------------------------------------------------------------------//
// page 0: skip apt-get update?
// page 1: dependencies
// page 2: warnings
// page 3: apt-get update
// page 4: install package
void install : : page1 ( )
{
showDependencies ( ) ;
widgetStack - > raiseWidget ( 1 ) ;
installPushButton - > show ( ) ;
closePushButton - > show ( ) ;
titleTextLabel - > setText ( " <b> " + i18n ( " The following packages will be installed, updated or removed: " ) + " </b> " ) ;
}
void install : : page2x1 ( )
{
errorTextLabel - > setText ( " <b> " + i18n ( " The architecture of this package does not match that of your system. You will not be able to install this package! " ) + " </b> " ) ;
nextPushButton2 - > hide ( ) ;
widgetStack - > raiseWidget ( 2 ) ;
}
void install : : page2x2 ( )
{
errorTextLabel - > setText ( " <b> " + i18n ( " The package database is in use by another process (e.g Synaptic). Please terminate this process and select Next to try again. " ) + " </b> " ) ;
nextPushButton1 - > show ( ) ;
nextPushButton2 - > hide ( ) ;
widgetStack - > raiseWidget ( 2 ) ;
}
void install : : page3 ( )
{
titleTextLabel - > setText ( " <b> " + i18n ( " Resynchronize Package Index " ) + " </b> " ) ;
closePushButton - > hide ( ) ;
QStrList run ; run . append ( m_kdePrefix + " /share/kdpkg/sh/kdpkg-sh " ) ;
run . append ( " update " ) ;
QWidget * consoleWidget = new console ( this , run ) ;
widgetStack - > addWidget ( consoleWidget , 3 ) ;
widgetStack - > raiseWidget ( 3 ) ;
connect ( consoleWidget , SIGNAL ( finished ( bool ) ) , this , SLOT ( page1 ( ) ) ) ;
}
void install : : page4 ( )
{
installPushButton - > hide ( ) ;
closePushButton - > hide ( ) ;
titleTextLabel - > setText ( " <b> " + i18n ( " Install New Package " ) + " </b> " ) ;
if ( ! installPkg )
installPkg = " none " ;
if ( ! removePkg )
removePkg = " none " ;
QStrList run ; run . append ( m_kdePrefix + " /share/kdpkg/sh/kdpkg-sh " ) ;
run . append ( " install " ) ;
run . append ( path ) ;
run . append ( installPkg ) ;
run . append ( removePkg ) ;
QWidget * consoleWidget = new console ( this , run ) ;
widgetStack - > addWidget ( consoleWidget , 4 ) ;
widgetStack - > raiseWidget ( 4 ) ;
connect ( consoleWidget , SIGNAL ( finished ( bool ) ) , this , SLOT ( close ( ) ) ) ;
}
//----------------------------------------------------------------------------//
//--- showDependencies -------------------------------------------------------//
//----------------------------------------------------------------------------//
void install : : showDependencies ( )
{
int start_index ;
int stop_index ;
// show packages which will be installed
QString tmpString = fields . grep ( QRegExp ( " ^Depends: " ) ) [ 0 ] . mid ( 9 ) ;
tmpString + = " , " + fields . grep ( " Pre-Depends: " ) [ 0 ] . mid ( 13 ) ;
QStringList allDepends = QStringList : : split ( " , " , tmpString ) ;
QString missingDepends ;
QStringList tmp ;
for ( uint i = 0 ; i < allDepends . count ( ) ; i + + )
{
if ( allDepends [ i ] . contains ( " | " ) ) {
tmp = QStringList : : split ( " | " , allDepends [ i ] ) ;
uint j = 0 ;
bool exit = FALSE ;
while ( ! exit & & j < tmp . count ( ) ) {
if ( isInstalled ( tmp [ j ] ) )
exit = TRUE ;
j + + ;
}
if ( ! exit )
missingDepends + = tmp [ 0 ] + " " ;
}
else
{
if ( ! isInstalled ( allDepends [ i ] ) )
missingDepends + = QStringList : : split ( " " , allDepends [ i ] ) [ 0 ] + " " ;
}
}
while ( missingDepends . find ( " ( " ) ! = - 1 ) {
start_index = missingDepends . find ( " ( " ) ;
stop_index = missingDepends . find ( " ) " , start_index ) ;
missingDepends . replace ( start_index , stop_index - start_index + 1 , " " ) ;
}
this - > shell - > setCommand ( " apt-get -s install " + missingDepends ) ;
this - > shell - > start ( true ) ;
QStringList installList = QStringList : : split ( " \n " , this - > shell - > getBuffer ( ) . stripWhiteSpace ( ) ) . grep ( " Inst " ) ;
for ( uint i = 0 ; i < installList . count ( ) ; i + + )
{
QString name = QStringList : : split ( " " , installList [ i ] ) [ 1 ] ;
QString pkgVersion ;
QString sysVersion ;
if ( installList [ i ] . contains ( " [ " ) )
{
pkgVersion = QStringList : : split ( " " , installList [ i ] ) [ 3 ] . mid ( 1 ) ;
sysVersion = QStringList : : split ( " " , installList [ i ] ) [ 2 ] . mid ( 1 ) . replace ( " ] " , " " ) ;
}
else
pkgVersion = QStringList : : split ( " " , installList [ i ] ) [ 2 ] . mid ( 1 ) ;
QListViewItem * item = new QListViewItem ( dependenciesListView , 0 ) ;
item - > setPixmap ( 0 , QPixmap ( m_kdePrefix + " /share/kdpkg/icons/install.png " ) ) ;
item - > setText ( 1 , name ) ;
item - > setText ( 2 , pkgVersion ) ;
item - > setText ( 3 , sysVersion ) ;
installPkg + = name + " , " ;
}
// find rconflicts
QString pkgName = fields . grep ( " Package: " ) [ 0 ] . mid ( 9 ) ;
QString pkgVersion = fields . grep ( " Version: " ) [ 0 ] . mid ( 9 ) ;
QString rconflicts ;
this - > shell - > setCommand ( " cat /var/lib/dpkg/status | grep " + pkgName + " -B 16| grep Conflicts -B 16 " ) ;
this - > shell - > start ( true ) ;
QStringList input1 = QStringList : : split ( " \n \n " , this - > shell - > getBuffer ( ) . stripWhiteSpace ( ) ) ;
for ( uint i = 0 ; i < input1 . count ( ) ; i + + )
{
if ( input1 [ i ] . contains ( pkgName ) )
{
QStringList input2 = QStringList : : split ( " \n " , input1 [ i ] ) ;
QString name = QStringList : : split ( " " , input2 . grep ( " Package: " ) [ 0 ] ) [ 1 ] ;
QString cVersion = input2 . grep ( " Conflicts: " ) [ 0 ] . mid ( 11 ) ; // conflictVersion
cVersion = QStringList : : split ( " , " , cVersion ) . grep ( pkgName ) [ 0 ] ;
cVersion = QStringList : : split ( " ( " , cVersion ) [ 1 ] ;
cVersion = cVersion . replace ( " ) " , " " ) ;
QString op = QStringList : : split ( " " , cVersion ) [ 0 ] ;
cVersion = QStringList : : split ( " " , cVersion ) [ 1 ] ;
if ( cVersion = = " " )
{
rconflicts + = name + " " ;
printf ( " 1 " ) ;
}
else
{
printf ( " 2 " ) ;
this - > shell - > setCommand ( " if dpkg --compare-versions " + pkgVersion + " \" " + op + " \" " + cVersion + " ; then echo \" TRUE \" ; fi " ) ;
this - > shell - > start ( true ) ;
if ( this - > shell - > getBuffer ( ) . stripWhiteSpace ( ) = = " TRUE " )
rconflicts + = name + " " ;
}
}
}
// show packages which will be removed
QString conflicts = fields . grep ( " Conflicts " ) [ 0 ] . mid ( 11 ) ;
conflicts = conflicts . replace ( " , " , " " ) ;
conflicts = conflicts + " " + rconflicts ;
while ( conflicts . find ( " ( " ) ! = - 1 ) {
start_index = conflicts . find ( " ( " ) ;
stop_index = conflicts . find ( " ) " , start_index ) ;
conflicts . replace ( start_index , stop_index - start_index + 1 , " " ) ;
}
this - > shell - > setCommand ( " apt-get -s remove " + conflicts ) ;
this - > shell - > start ( true ) ;
QStringList removeList = QStringList : : split ( " \n " , this - > shell - > getBuffer ( ) . stripWhiteSpace ( ) ) . grep ( " Remv " ) ;
for ( uint i = 0 ; i < removeList . count ( ) ; i + + )
{
QString name = QStringList : : split ( " " , removeList [ i ] ) [ 1 ] ;
QString sysVersion = QStringList : : split ( " [ " , removeList [ i ] ) [ 1 ] . replace ( " ] " , " " ) ;
QListViewItem * item = new QListViewItem ( dependenciesListView , 0 ) ;
item - > setPixmap ( 0 , QPixmap ( m_kdePrefix + " /share/kdpkg/icons/remove.png " ) ) ;
item - > setText ( 1 , name ) ;
item - > setText ( 3 , sysVersion ) ;
removePkg + = name + " , " ;
}
}
//----------------------------------------------------------------------------//
//--- isInstalled ------------------------------------------------------------//
//----------------------------------------------------------------------------//
bool install : : isInstalled ( QString input )
{
QString package = QStringList : : split ( " " , input ) [ 0 ] ;
QString version = QStringList : : split ( " ( " , input ) [ 1 ] . replace ( " ) " , " " ) ;
this - > shell - > setCommand ( " apt-cache policy " + package ) ;
this - > shell - > start ( true ) ;
QString sysVersion = QStringList : : split ( " \n " , this - > shell - > getBuffer ( ) . stripWhiteSpace ( ) ) [ 1 ] ;
sysVersion = QStringList : : split ( " : " , sysVersion ) [ 1 ] . replace ( " " , " " ) ;
if ( sysVersion . contains ( " ( " ) | | sysVersion = = " " )
return FALSE ;
else if ( version ! = " " )
{
QString op = QStringList : : split ( " " , version ) [ 0 ] ;
QString pkgVersion = QStringList : : split ( " " , version ) [ 1 ] ;
this - > shell - > setCommand ( " if dpkg --compare-versions " + sysVersion + " \" " + op + " \" " + pkgVersion + " ; then echo \" TRUE \" ; fi " ) ;
this - > shell - > start ( true ) ;
if ( this - > shell - > getBuffer ( ) . stripWhiteSpace ( ) = = " TRUE " )
return TRUE ;
else
return FALSE ;
}
else
return TRUE ;
}
//----------------------------------------------------------------------------//
//--- about ------------------------------------------------------------------//
//----------------------------------------------------------------------------//
void install : : showAbout ( )
{
KAboutApplication * about = new KAboutApplication ( this ) ;
about - > show ( ) ;
}
//----------------------------------------------------------------------------//
//--- checks -----------------------------------------------------------------//
//----------------------------------------------------------------------------//
bool install : : checkArchitecture ( )
{
QString arch = fields . grep ( " Architecture: " ) [ 0 ] . mid ( 14 ) ;
if ( arch = = " all " )
return TRUE ;
// get architecture
this - > shell - > setCommand ( " dpkg --print-architecture " ) ;
this - > shell - > start ( true ) ;
if ( arch = = this - > shell - > getBuffer ( ) . stripWhiteSpace ( ) )
return TRUE ;
return FALSE ;
}
bool install : : isLocked ( )
{
this - > shell - > setCommand ( " apt-get install -s " ) ;
this - > shell - > start ( true ) ;
if ( this - > shell - > getBuffer ( ) . stripWhiteSpace ( ) . contains ( " ... " ) )
return FALSE ;
else
return TRUE ;
}
# include "install.moc"