You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
323 lines
8.4 KiB
323 lines
8.4 KiB
11 years ago
|
/***************************************************************************
|
||
|
* Copyright (C) 2004 by David Sansome *
|
||
|
* me@davidsansome.com *
|
||
|
* *
|
||
|
* This program is free software; you can redistribute it and/or modify *
|
||
|
* it under the terms of the GNU General Public License as published by *
|
||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||
|
* (at your option) any later version. *
|
||
|
* *
|
||
|
* 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., *
|
||
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||
|
***************************************************************************/
|
||
|
|
||
|
|
||
|
#include "uninstallwizard.h"
|
||
|
#include "headerlistitem.h"
|
||
|
#include "data.h"
|
||
|
|
||
|
#include <qregexp.h>
|
||
|
#include <qwidgetstack.h>
|
||
|
#include <qfile.h>
|
||
|
#include <qtextstream.h>
|
||
|
#include <qheader.h>
|
||
|
#include <qlistbox.h>
|
||
|
#include <qmessagebox.h>
|
||
|
#include <qpushbutton.h>
|
||
|
#include <qlineedit.h>
|
||
|
#include <qtextedit.h>
|
||
|
#include <qlabel.h>
|
||
|
|
||
|
AppListItem::AppListItem(QString nN, QString n, QListView* parent)
|
||
|
: QCheckListItem(parent, "", QCheckListItem::CheckBox)
|
||
|
{
|
||
|
niceName = nN;
|
||
|
name = n;
|
||
|
section = 2;
|
||
|
|
||
|
setText(0, niceName);
|
||
|
}
|
||
|
|
||
|
int AppListItem::compare(QListViewItem* i, int col, bool ascending) const
|
||
|
{
|
||
|
switch (i->rtti())
|
||
|
{
|
||
|
case 1003: // App
|
||
|
{
|
||
|
AppListItem* item = (AppListItem*) i;
|
||
|
if (section < item->section)
|
||
|
return -1;
|
||
|
if (section > item->section)
|
||
|
return 1;
|
||
|
return QListViewItem::compare(i, col, ascending);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 1002: // Header
|
||
|
{
|
||
|
HeaderListItem* item = (HeaderListItem*) i;
|
||
|
if (section < item->section)
|
||
|
return -1;
|
||
|
return 1;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
UninstallWizard::UninstallWizard(QWidget* parent, const char* name, bool modal, WFlags fl)
|
||
|
: WizardBase(parent,name, modal,fl)
|
||
|
{
|
||
|
mainStack->raiseWidget(1);
|
||
|
setCaption("Uninstall Software");
|
||
|
titleLabel->setText("<b>Uninstall Software</b>");
|
||
|
componentInfo->setMaximumSize(32767,70);
|
||
|
|
||
|
logDialog = new LogDialog(this);
|
||
|
logDialog->hide();
|
||
|
appList->header()->hide();
|
||
|
|
||
|
globalHeader = NULL;
|
||
|
|
||
|
icon.convertFromImage(qembed_findImage("misc"));
|
||
|
|
||
|
externalProcess = new QProcess(this);
|
||
|
connect(externalProcess, SIGNAL(processExited()), SLOT(processExited()));
|
||
|
connect(externalProcess, SIGNAL(readyReadStdout()), SLOT(readyReadStdout()));
|
||
|
connect(externalProcess, SIGNAL(readyReadStderr()), SLOT(readyReadStderr()));
|
||
|
|
||
|
QFile uninstallScript("/tmp/arkollon-uninstall.sh");
|
||
|
if (uninstallScript.exists())
|
||
|
uninstallScript.remove();
|
||
|
uninstallScript.open(IO_WriteOnly);
|
||
|
QDataStream stream(&uninstallScript);
|
||
|
stream.writeRawBytes((const char*)uninstaller_sh_data, uninstaller_sh_len);
|
||
|
uninstallScript.close();
|
||
|
|
||
|
currentStage = ListingPackages;
|
||
|
externalProcess->addArgument("/bin/sh");
|
||
|
externalProcess->addArgument("/tmp/arkollon-uninstall.sh");
|
||
|
externalProcess->addArgument("--list");
|
||
|
externalProcess->start();
|
||
|
}
|
||
|
|
||
|
UninstallWizard::~UninstallWizard()
|
||
|
{
|
||
|
QFile uninstallScript("/tmp/arkollon-uninstall.sh");
|
||
|
if (uninstallScript.exists())
|
||
|
uninstallScript.remove();
|
||
|
}
|
||
|
|
||
|
void UninstallWizard::logPressed()
|
||
|
{
|
||
|
logDialog->show();
|
||
|
}
|
||
|
|
||
|
void UninstallWizard::cancelPressed()
|
||
|
{
|
||
|
reject();
|
||
|
}
|
||
|
|
||
|
void UninstallWizard::previousPressed()
|
||
|
{
|
||
|
int currentId = uninstallStack->id(uninstallStack->visibleWidget());
|
||
|
if (currentId == 0)
|
||
|
return;
|
||
|
|
||
|
uninstallStack->raiseWidget(--currentId);
|
||
|
|
||
|
if (currentId == 0)
|
||
|
previousButton->setEnabled(false);
|
||
|
nextButton->setEnabled(true);
|
||
|
}
|
||
|
|
||
|
void UninstallWizard::nextPressed()
|
||
|
{
|
||
|
int currentId = uninstallStack->id(uninstallStack->visibleWidget());
|
||
|
if (currentId == 2)
|
||
|
{
|
||
|
accept();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (currentId == 0)
|
||
|
{
|
||
|
bool checked = false;
|
||
|
QStringList argList;
|
||
|
argList.append("/bin/sh");
|
||
|
argList.append("/tmp/arkollon-uninstall.sh");
|
||
|
for ( QListViewItem * myChild = appList->firstChild() ; myChild != NULL ; myChild = myChild->nextSibling())
|
||
|
{
|
||
|
if (myChild->rtti() != 1003)
|
||
|
continue;
|
||
|
AppListItem* app = (AppListItem*) myChild;
|
||
|
if (!app->isOn())
|
||
|
continue;
|
||
|
argList.append("--files");
|
||
|
argList.append(app->name);
|
||
|
checked = true;
|
||
|
}
|
||
|
if (!checked)
|
||
|
{
|
||
|
QMessageBox::warning(this, "Error", "You need to select at least one package to remove", QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
|
||
|
return;
|
||
|
}
|
||
|
fileList->clear();
|
||
|
currentStage = ListingFiles;
|
||
|
externalProcess->setArguments(argList);
|
||
|
externalProcess->start();
|
||
|
nextButton->setEnabled(false); // Set true again when the process is done
|
||
|
}
|
||
|
|
||
|
uninstallStack->raiseWidget(++currentId);
|
||
|
|
||
|
if (currentId == 2)
|
||
|
removeUserPackages();
|
||
|
else
|
||
|
previousButton->setEnabled(true);
|
||
|
}
|
||
|
|
||
|
void UninstallWizard::processExited()
|
||
|
{
|
||
|
switch (currentStage)
|
||
|
{
|
||
|
case ListingPackages:
|
||
|
if (appList->childCount() <= 0)
|
||
|
{
|
||
|
QMessageBox::warning(NULL, "Warning", "There are no packages installed", QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
|
||
|
reject();
|
||
|
return;
|
||
|
}
|
||
|
show();
|
||
|
break;
|
||
|
case ListingFiles:
|
||
|
nextButton->setEnabled(true);
|
||
|
fileList->sort();
|
||
|
break;
|
||
|
case RemovingGlobal:
|
||
|
finished();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void UninstallWizard::readyReadStdout()
|
||
|
{
|
||
|
switch (currentStage)
|
||
|
{
|
||
|
case ListingPackages:
|
||
|
{
|
||
|
while (externalProcess->canReadLineStdout())
|
||
|
{
|
||
|
QString line = externalProcess->readLineStdout();
|
||
|
if (line.isEmpty())
|
||
|
continue;
|
||
|
|
||
|
// See if it already exists
|
||
|
bool exists = false;
|
||
|
|
||
|
for ( QListViewItem * myChild = appList->firstChild() ; myChild != NULL ; myChild = myChild->nextSibling())
|
||
|
{
|
||
|
if (myChild->rtti() != 1003)
|
||
|
continue;
|
||
|
AppListItem* app = (AppListItem*) myChild;
|
||
|
if (app->name.lower() == line.lower())
|
||
|
{
|
||
|
exists = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (exists)
|
||
|
continue;
|
||
|
|
||
|
QString niceName = line.left(line.findRev(':'));
|
||
|
niceName = niceName.left(1).upper() + niceName.right(niceName.length()-1);
|
||
|
new AppListItem(niceName, line, appList);
|
||
|
|
||
|
if (globalHeader == NULL)
|
||
|
{
|
||
|
globalHeader = new HeaderListItem(appList);
|
||
|
globalHeader->setText(0, "Applications available to all users");
|
||
|
globalHeader->section = 1;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case ListingFiles:
|
||
|
{
|
||
|
while (externalProcess->canReadLineStdout())
|
||
|
{
|
||
|
QString line = externalProcess->readLineStdout();
|
||
|
if (line.isEmpty())
|
||
|
continue;
|
||
|
fileList->insertItem(icon, line.left(line.find(" ")));
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case RemovingGlobal:
|
||
|
while (externalProcess->canReadLineStdout())
|
||
|
{
|
||
|
QString line = externalProcess->readLineStdout();
|
||
|
if (line.isEmpty())
|
||
|
continue;
|
||
|
line.replace(QRegExp("\\033[^m]*m"), "");
|
||
|
logDialog->logBox->append(line);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void UninstallWizard::readyReadStderr()
|
||
|
{
|
||
|
while (externalProcess->canReadLineStdout())
|
||
|
{
|
||
|
QString line = externalProcess->readLineStdout();
|
||
|
if (line.isEmpty())
|
||
|
continue;
|
||
|
line.replace(QRegExp("\\033[^m]*m"), "");
|
||
|
logDialog->logBox->append(line);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void UninstallWizard::removeUserPackages()
|
||
|
{
|
||
|
nextButton->setEnabled(false); // Set true again when the process is done
|
||
|
previousButton->setEnabled(false);
|
||
|
|
||
|
// Find out which packages belong to the user, and uninstall them
|
||
|
QStringList argList;
|
||
|
argList.append("/bin/sh");
|
||
|
argList.append("/tmp/arkollon-uninstall.sh");
|
||
|
for ( QListViewItem * myChild = appList->firstChild() ; myChild != NULL ; myChild = myChild->nextSibling())
|
||
|
{
|
||
|
if (myChild->rtti() != 1003)
|
||
|
continue;
|
||
|
AppListItem* app = (AppListItem*) myChild;
|
||
|
if (!app->isOn())
|
||
|
continue;
|
||
|
|
||
|
argList.append("--remove");
|
||
|
argList.append(app->name);
|
||
|
}
|
||
|
currentStage = RemovingGlobal;
|
||
|
externalProcess->setArguments(argList);
|
||
|
externalProcess->start();
|
||
|
}
|
||
|
|
||
|
void UninstallWizard::finished()
|
||
|
{
|
||
|
pleaseWaitLabel2->setText("Removal of packages complete!");
|
||
|
nextButton->setText("Finish");
|
||
|
nextButton->setEnabled(true);
|
||
|
}
|
||
|
|
||
|
#include "uninstallwizard.moc"
|
||
|
|