diff options
Diffstat (limited to 'src/libs/kdtools/kdupdaterupdateoperations.cpp')
-rw-r--r-- | src/libs/kdtools/kdupdaterupdateoperations.cpp | 557 |
1 files changed, 155 insertions, 402 deletions
diff --git a/src/libs/kdtools/kdupdaterupdateoperations.cpp b/src/libs/kdtools/kdupdaterupdateoperations.cpp index 835697040..5a4296242 100644 --- a/src/libs/kdtools/kdupdaterupdateoperations.cpp +++ b/src/libs/kdtools/kdupdaterupdateoperations.cpp @@ -1,49 +1,56 @@ /**************************************************************************** -** Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB. All rights reserved. ** -** This file is part of the KD Tools library. +** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB) +** Contact: http://www.qt-project.org/legal ** -** Licensees holding valid commercial KD Tools licenses may use this file in -** accordance with the KD Tools Commercial License Agreement provided with -** the Software. +** This file is part of the Qt Installer Framework. ** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. ** -** This file may be distributed and/or modified under the terms of the -** GNU Lesser General Public License version 2 and version 3 as published by the -** Free Software Foundation and appearing in the file LICENSE.LGPL included. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** -** Contact info@kdab.com if any conditions of this licensing are not -** clear to you. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** -**********************************************************************/ +** +** $QT_END_LICENSE$ +** +****************************************************************************/ #include "kdupdaterupdateoperations.h" -#include "kdupdaterapplication.h" -#include "kdupdaterpackagesinfo.h" -#include "environment.h" +#include "errors.h" +#include "fileutils.h" -#include <QFile> #include <QDir> -#include <QDirIterator> -#include <QProcess> +#include <QFile> #include <QTextStream> -#include <QDebug> #include <QTemporaryFile> - +#include <QFileInfo> #include <cerrno> -#define SUPPORT_DETACHED_PROCESS_EXECUTION - -#ifdef SUPPORT_DETACHED_PROCESS_EXECUTION -#ifdef Q_OS_WIN -#include <windows.h> -#endif -#endif - using namespace KDUpdater; static QString errnoToQString(int error) @@ -85,6 +92,7 @@ static bool removeDirectory(const QString &path, QString *errorString, bool forc *errorString = errnoToQString(errno); return success; } + /* * \internal * Returns a filename for a temporary file based on \a templateName @@ -113,67 +121,90 @@ CopyOperation::~CopyOperation() deleteFileNowOrLater(value(QLatin1String("backupOfExistingDestination")).toString()); } +QString CopyOperation::sourcePath() +{ + return arguments().first(); +} + +QString CopyOperation::destinationPath() +{ + QString destination = arguments().last(); + + // if the target is a directory use the source filename to complete the destination path + if (QFileInfo(destination).isDir()) + destination = QDir(destination).filePath(QFileInfo(sourcePath()).fileName()); + return destination; +} + + void CopyOperation::backup() { - const QString dest = arguments().last(); - if (!QFile::exists(dest)) { + QString destination = destinationPath(); + + if (!QFile::exists(destination)) { clearValue(QLatin1String("backupOfExistingDestination")); return; } - setValue(QLatin1String("backupOfExistingDestination"), backupFileName(dest)); + setValue(QLatin1String("backupOfExistingDestination"), backupFileName(destination)); - // race condition: The backup file could get created - // by another process right now. But this is the same + // race condition: The backup file could get created by another process right now. But this is the same // in QFile::copy... - const bool success = QFile::rename(dest, value(QLatin1String("backupOfExistingDestination")).toString()); - if (!success) - setError(UserDefinedError, tr("Could not backup file %1.").arg(dest)); + if (!QFile::rename(destination, value(QLatin1String("backupOfExistingDestination")).toString())) + setError(UserDefinedError, tr("Could not backup file %1.").arg(destination)); } bool CopyOperation::performOperation() { - // We need two args to complete the copy operation. - // First arg provides the complete file name of source + // We need two args to complete the copy operation. First arg provides the complete file name of source // Second arg provides the complete file name of dest - QStringList args = this->arguments(); - if (args.count() != 2) { + if (arguments().count() != 2) { setError(InvalidArguments); - setErrorString(tr("Invalid arguments: %1 arguments given, 2 expected.").arg(args.count())); + setErrorString(tr("Invalid arguments: %1 arguments given, 2 expected.").arg(arguments().count())); return false; } - QString source = args.first(); - QString dest = args.last(); - // If destination file exists, then we cannot use QFile::copy() - // because it does not overwrite an existing file. So we remove - // the destination file. - if (QFile::exists(dest)) { - QFile file(dest); - if (!file.remove()) { + QString source = sourcePath(); + QString destination = destinationPath(); + + QFile sourceFile(source); + if (!sourceFile.exists()) { + setError(UserDefinedError); + setErrorString(tr("Could not copy a none existing file: %1").arg(source)); + return false; + } + // If destination file exists, we cannot use QFile::copy() because it does not overwrite an existing + // file. So we remove the destination file. + QFile destinationFile(destination); + if (destinationFile.exists()) { + if (!destinationFile.remove()) { setError(UserDefinedError); - setErrorString(tr("Could not remove destination file %1: %2").arg(dest, file.errorString())); + setErrorString(tr("Could not remove destination file %1: %2").arg(destination, destinationFile.errorString())); return false; } } - QFile file(source); - const bool copied = file.copy(dest); + const bool copied = sourceFile.copy(destination); if (!copied) { setError(UserDefinedError); - setErrorString(tr("Could not copy %1 to %2: %3").arg(source, dest, file.errorString())); + setErrorString(tr("Could not copy %1 to %2: %3").arg(source, destination, sourceFile.errorString())); } return copied; } bool CopyOperation::undoOperation() { - const QString dest = arguments().last(); + QString source = sourcePath(); + QString destination = destinationPath(); - QFile destF(dest); + // if the target is a directory use the source filename to complete the destination path + if (QFileInfo(destination).isDir()) + destination = destination + QDir::separator() + QFileInfo(source).fileName(); + + QFile destFile(destination); // first remove the dest - if (destF.exists() && !destF.remove()) { - setError(UserDefinedError, tr("Could not delete file %1: %2").arg(dest, destF.errorString())); + if (destFile.exists() && !destFile.remove()) { + setError(UserDefinedError, tr("Could not delete file %1: %2").arg(destination, destFile.errorString())); return false; } @@ -182,11 +213,11 @@ bool CopyOperation::undoOperation() if (!hasValue(QLatin1String("backupOfExistingDestination"))) return true; - QFile backupF(value(QLatin1String("backupOfExistingDestination")).toString()); + QFile backupFile(value(QLatin1String("backupOfExistingDestination")).toString()); // otherwise we have to copy the backup back: - const bool success = backupF.rename(dest); + const bool success = backupFile.rename(destination); if (!success) - setError(UserDefinedError, tr("Could not restore backup file into %1: %2").arg(dest, backupF.errorString())); + setError(UserDefinedError, tr("Could not restore backup file into %1: %2").arg(destination, backupFile.errorString())); return success; } @@ -198,9 +229,9 @@ QDomDocument CopyOperation::toXml() const // we don't want to save the backupOfExistingDestination if (!hasValue(QLatin1String("backupOfExistingDestination"))) return UpdateOperation::toXml(); - + CopyOperation *const me = const_cast<CopyOperation *>(this); - + const QVariant v = value(QLatin1String("backupOfExistingDestination")); me->clearValue(QLatin1String("backupOfExistingDestination")); const QDomDocument xml = UpdateOperation::toXml(); @@ -244,32 +275,26 @@ void MoveOperation::backup() setValue(QLatin1String("backupOfExistingDestination"), backupFileName(dest)); - // race condition: The backup file could get created - // by another process right now. But this is the same + // race condition: The backup file could get created by another process right now. But this is the same // in QFile::copy... - const bool success = QFile::rename(dest, value(QLatin1String("backupOfExistingDestination")).toString()); - if (!success) + if (!QFile::rename(dest, value(QLatin1String("backupOfExistingDestination")).toString())) setError(UserDefinedError, tr("Could not backup file %1.").arg(dest)); } bool MoveOperation::performOperation() { - // We need two args to complete the copy operation. - // First arg provides the complete file name of source - // Second arg provides the complete file name of dest - QStringList args = this->arguments(); + // We need two args to complete the copy operation. // First arg provides the complete file name of + // source, second arg provides the complete file name of dest + const QStringList args = this->arguments(); if (args.count() != 2) { setError(InvalidArguments); setErrorString(tr("Invalid arguments: %1 arguments given, 2 expected.").arg(args.count())); return false; } - QString source = args.first(); - QString dest = args.last(); - - // If destination file exists, then we cannot use QFile::copy() - // because it does not overwrite an existing file. So we remove - // the destination file. + const QString dest = args.last(); + // If destination file exists, then we cannot use QFile::copy() because it does not overwrite an existing + // file. So we remove the destination file. if (QFile::exists(dest)) { QFile file(dest); if (!file.remove(dest)) { @@ -280,27 +305,23 @@ bool MoveOperation::performOperation() } // Copy source to destination. - QFile file(source); - const bool copied = file.copy(source, dest); - if (!copied) { + QFile file(args.first()); + if (!file.copy(dest)) { setError(UserDefinedError); - setErrorString(tr("Could not copy %1 to %2: %3").arg(source, dest, file.errorString())); + setErrorString(tr("Could not copy %1 to %2: %3").arg(file.fileName(), dest, file.errorString())); return false; } - - return deleteFileNowOrLater(source); + return deleteFileNowOrLater(file.fileName()); } bool MoveOperation::undoOperation() { const QStringList args = arguments(); - const QString& source = args.first(); - const QString& dest = args.last(); - + const QString dest = args.last(); // first: copy back the destination to source QFile destF(dest); - if (!destF.copy(source)) { - setError(UserDefinedError, tr("Cannot copy %1 to %2: %3").arg(dest, source, destF.errorString())); + if (!destF.copy(args.first())) { + setError(UserDefinedError, tr("Cannot copy %1 to %2: %3").arg(dest, args.first(), destF.errorString())); return false; } @@ -317,7 +338,7 @@ bool MoveOperation::undoOperation() // otherwise we have to copy the backup back: QFile backupF(value(QLatin1String("backupOfExistingDestination")).toString()); - const bool success = backupF.rename(dest); + const bool success = backupF.rename(dest); if (!success) setError(UserDefinedError, tr("Cannot restore backup file for %1: %2").arg(dest, backupF.errorString())); @@ -354,25 +375,22 @@ void DeleteOperation::backup() { const QString fileName = arguments().first(); setValue(QLatin1String("backupOfExistingFile"), backupFileName(fileName)); + QFile file(fileName); - const bool success = file.copy(value(QLatin1String("backupOfExistingFile")).toString()); - if (!success) + if (!file.copy(value(QLatin1String("backupOfExistingFile")).toString())) setError(UserDefinedError, tr("Cannot create backup of %1: %2").arg(fileName, file.errorString())); } bool DeleteOperation::performOperation() { - // Requires only one parameter. That is the name of - // the file to remove. - QStringList args = this->arguments(); + // Requires only one parameter. That is the name of the file to remove. + const QStringList args = this->arguments(); if (args.count() != 1) { setError(InvalidArguments); setErrorString(tr("Invalid arguments: %1 arguments given, 1 expected.").arg(args.count())); return false; } - - const QString fName = args.first(); - return deleteFileNowOrLater(fName); + return deleteFileNowOrLater(args.first()); } bool DeleteOperation::undoOperation() @@ -385,7 +403,6 @@ bool DeleteOperation::undoOperation() const bool success = backupF.copy(fileName) && deleteFileNowOrLater(backupF.fileName()); if (!success) setError(UserDefinedError, tr("Cannot restore backup file for %1: %2").arg(fileName, backupF.errorString())); - return success; } @@ -408,9 +425,9 @@ QDomDocument DeleteOperation::toXml() const // we don't want to save the backupOfExistingFile if (!hasValue(QLatin1String("backupOfExistingFile"))) return UpdateOperation::toXml(); - + DeleteOperation *const me = const_cast<DeleteOperation *>(this); - + const QVariant v = value(QLatin1String("backupOfExistingFile")); me->clearValue(QLatin1String("backupOfExistingFile")); const QDomDocument xml = UpdateOperation::toXml(); @@ -460,7 +477,8 @@ bool MkdirOperation::performOperation() setErrorString(tr("Invalid arguments: %1 arguments given, 1 expected.").arg(args.count())); return false; } - QString dirName = args.first(); + + const QString dirName = args.first(); const bool created = QDir::root().mkpath(dirName); if (!created) { setError(UserDefinedError); @@ -520,8 +538,8 @@ MkdirOperation *MkdirOperation::clone() const RmdirOperation::RmdirOperation() { - setValue(QLatin1String("removed"), false); setName(QLatin1String("Rmdir")); + setValue(QLatin1String("removed"), false); } void RmdirOperation::backup() @@ -531,29 +549,27 @@ void RmdirOperation::backup() bool RmdirOperation::performOperation() { - // Requires only one parameter. That is the name of - // the file to remove. - QStringList args = this->arguments(); + // Requires only one parameter. That is the name of the file to remove. + const QStringList args = this->arguments(); if (args.count() != 1) { setError(InvalidArguments); setErrorString(tr("Invalid arguments: %1 arguments given, 1 expected.").arg(args.count())); return false; } - QString dirName = args.first(); - QDir dir(dirName); + QDir dir(args.first()); if (!dir.exists()) { setError(UserDefinedError); - setErrorString(tr("Could not remove folder %1: The folder does not exist.").arg(dirName)); + setErrorString(tr("Could not remove folder %1: The folder does not exist.").arg(args.first())); return false; } errno = 0; - const bool removed = dir.rmdir(dirName); + const bool removed = dir.rmdir(args.first()); setValue(QLatin1String("removed"), removed); if (!removed) { setError(UserDefinedError); - setErrorString(tr("Could not remove folder %1: %2").arg(dirName, errnoToQString(errno))); + setErrorString(tr("Could not remove folder %1: %2").arg(args.first(), errnoToQString(errno))); } return removed; } @@ -563,8 +579,8 @@ bool RmdirOperation::undoOperation() if (!value(QLatin1String("removed")).toBool()) return true; - const QFileInfo fi(arguments().first()); errno = 0; + const QFileInfo fi(arguments().first()); const bool success = fi.dir().mkdir(fi.fileName()); if( !success) setError(UserDefinedError, tr("Cannot recreate directory %1: %2").arg(fi.fileName(), errnoToQString(errno))); @@ -610,34 +626,46 @@ void AppendFileOperation::backup() bool AppendFileOperation::performOperation() { - // This operation takes two arguments. First argument is the name - // of the file into which a text has to be appended. Second argument - // is the text to append. - QStringList args = this->arguments(); + // This operation takes two arguments. First argument is the name of the file into which a text has to be + // appended. Second argument is the text to append. + const QStringList args = this->arguments(); if (args.count() != 2) { setError(InvalidArguments); - setErrorString(tr("Invalid arguments: %1 arguments given, 2 expected.").arg(args.count())); + setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.") + .arg(name()).arg(arguments().count()).arg(tr("exactly 2"), QLatin1String(""))); return false; } - QString fName = args.first(); - QString text = args.last(); - + const QString fName = args.first(); QFile file(fName); if (!file.open(QFile::Append)) { // first we rename the file, then we copy it to the real target and open the copy - the renamed original is then marked for deletion + bool error = false; const QString newName = backupFileName(fName); - if (!QFile::rename(fName, newName) && QFile::copy(newName, fName) && file.open(QFile::Append)) { + + if (!QFile::rename(fName, newName)) + error = true; + + if (!error && !QFile::copy(newName, fName)) { + error = true; QFile::rename(newName, fName); + } + + if (!error && !file.open(QFile::Append)) { + error = true; + deleteFileNowOrLater(newName); + } + + if (error) { setError(UserDefinedError); - setErrorString(tr("Could not open file %1 for writing: %2").arg(file.fileName(), file.errorString())); + setErrorString(tr("Could not open file '%1' for writing: %2").arg(file.fileName(), file.errorString())); return false; } deleteFileNowOrLater(newName); } QTextStream ts(&file); - ts << text; + ts << args.last(); file.close(); return true; @@ -711,16 +739,14 @@ bool PrependFileOperation::performOperation() // This operation takes two arguments. First argument is the name // of the file into which a text has to be appended. Second argument // is the text to append. - QStringList args = this->arguments(); + const QStringList args = this->arguments(); if (args.count() != 2) { setError(InvalidArguments); setErrorString(tr("Invalid arguments: %1 arguments given, 2 expected.").arg(args.count())); return false; } - QString fName = args.first(); - QString text = args.last(); - + const QString fName = args.first(); // Load the file first. QFile file(fName); if (!file.open(QFile::ReadOnly)) { @@ -728,11 +754,13 @@ bool PrependFileOperation::performOperation() setErrorString(tr("Could not open file %1 for reading: %2").arg(file.fileName(), file.errorString())); return false; } + + // TODO: fix this, use a text stream QString fContents(QLatin1String(file.readAll())); file.close(); // Prepend text to the file text - fContents = text + fContents; + fContents = args.last() + fContents; // Now re-open the file in write only mode. if (!file.open(QFile::WriteOnly)) { @@ -790,278 +818,3 @@ PrependFileOperation *PrependFileOperation::clone() const { return new PrependFileOperation; } - - -//////////////////////////////////////////////////////////////////////////// -// KDUpdater::ExecuteOperation -//////////////////////////////////////////////////////////////////////////// - -ExecuteOperation::ExecuteOperation() - : QObject() -{ - setName(QLatin1String("Execute")); -} - -void ExecuteOperation::backup() -{ - // this is not possible, since the process can do whatever... -} - -#if defined(SUPPORT_DETACHED_PROCESS_EXECUTION) && defined(Q_OS_WIN) -// stolen from qprocess_win.cpp -static QString qt_create_commandline(const QString &program, const QStringList &arguments) -{ - QString args; - if (!program.isEmpty()) { - QString programName = program; - if (!programName.startsWith(QLatin1Char('\"')) && !programName.endsWith(QLatin1Char('\"')) && programName.contains(QLatin1Char(' '))) - programName = QLatin1Char('\"') + programName + QLatin1Char('\"'); - programName.replace(QLatin1Char('/'), QLatin1Char('\\')); - - // add the prgram as the first arg ... it works better - args = programName + QLatin1Char(' '); - } - - for (int i = 0; i < arguments.size(); ++i) { - QString tmp = arguments.at(i); - // in the case of \" already being in the string the \ must also be escaped - tmp.replace(QLatin1String("\\\""), QLatin1String("\\\\\"")); - // escape a single " because the arguments will be parsed - tmp.replace(QLatin1Char('\"'), QLatin1String("\\\"")); - if (tmp.isEmpty() || tmp.contains(QLatin1Char(' ')) || tmp.contains(QLatin1Char('\t'))) { - // The argument must not end with a \ since this would be interpreted - // as escaping the quote -- rather put the \ behind the quote: e.g. - // rather use "foo"\ than "foo\" - QString endQuote(QLatin1Char('\"')); - int i = tmp.length(); - while (i > 0 && tmp.at(i - 1) == QLatin1Char('\\')) { - --i; - endQuote += QLatin1Char('\\'); - } - args += QLatin1String(" \"") + tmp.left(i) + endQuote; - } else { - args += QLatin1Char(' ') + tmp; - } - } - return args; -} -#endif - -bool ExecuteOperation::performOperation() -{ - // This operation receives only one argument. It is the complete - // command line of the external program to execute. - QStringList args = this->arguments(); - if (args.isEmpty()) { - setError(InvalidArguments); - setErrorString(tr("Invalid arguments: %1 arguments given, 2 expected.").arg(args.count())); - return false; - } - - QList<int> allowedExitCodes; - - QRegExp re(QLatin1String("^\\{((-?\\d+,)*-?\\d+)\\}$")); - if (re.exactMatch(args.first())) { - const QStringList numbers = re.cap(1).split(QLatin1Char(',')); - for (QStringList::const_iterator it = numbers.begin(); it != numbers.end(); ++it) - allowedExitCodes.push_back(it->toInt()); - args.pop_front(); - } else { - allowedExitCodes.push_back(0); - } - - bool success = false; -#ifdef SUPPORT_DETACHED_PROCESS_EXECUTION - // unix style: when there's an ampersand after the command, it's started detached - if (args.count() >= 2 && args.last() == QLatin1String("&")) { - args.pop_back(); -#ifdef Q_OS_WIN - QString arguments = qt_create_commandline(args.front(), args.mid(1)); - - PROCESS_INFORMATION pinfo; - - STARTUPINFOW startupInfo = { sizeof(STARTUPINFO), 0, 0, 0, - static_cast< ulong >(CW_USEDEFAULT), static_cast< ulong >(CW_USEDEFAULT), - static_cast< ulong >(CW_USEDEFAULT), static_cast< ulong >(CW_USEDEFAULT), - 0, 0, 0, STARTF_USESHOWWINDOW, SW_HIDE, 0, 0, 0, 0, 0 - }; - success = CreateProcess(0, (wchar_t*)arguments.utf16(), - 0, 0, FALSE, CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE, 0, - 0, - &startupInfo, &pinfo); - -#else - success = QProcess::startDetached(args.front(), args.mid(1)); -#endif - } - else -#endif - { - Environment::instance().applyTo(&process); //apply non-persistent variables - process.start(args.front(), args.mid(1)); - - QEventLoop loop; - QObject::connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit())); - QObject::connect(&process, SIGNAL(readyRead()), this, SLOT(readProcessOutput())); - success = process.waitForStarted(-1); - if (success) { - loop.exec(); - setValue(QLatin1String("ExitCode"), process.exitCode()); - success = allowedExitCodes.contains(process.exitCode()); - } - } - if (!success) { - setError(UserDefinedError); - setErrorString(tr("Execution failed: %1").arg(args.join(QLatin1String(" ")))); - } - - return success; -} - -/*! - Cancels the ExecuteOperation. This methods tries to terminate the process - gracefully by calling QProcess::terminate. After 10 seconds, the process gets killed. - */ -void ExecuteOperation::cancelOperation() -{ - if (process.state() == QProcess::Running) - process.terminate(); - if (!process.waitForFinished(10000)) - process.kill(); -} - -void ExecuteOperation::readProcessOutput() -{ - QByteArray output = process.readAll(); - if (!output.isEmpty()) - emit outputTextChanged(QString::fromLocal8Bit(output)); -} - -bool ExecuteOperation::undoOperation() -{ - // this is not possible, since the process can do whatever... - return false; -} - -bool ExecuteOperation::testOperation() -{ - // TODO - return true; -} - -ExecuteOperation *ExecuteOperation::clone() const -{ - return new ExecuteOperation; -} - - -//////////////////////////////////////////////////////////////////////////// -// KDUpdater::UpdatePackageOperation -//////////////////////////////////////////////////////////////////////////// - -UpdatePackageOperation::UpdatePackageOperation() -{ - setName(QLatin1String("UpdatePackage")); -} - -void UpdatePackageOperation::backup() -{ - const PackageInfo info = application()->packagesInfo()->packageInfo(application()->packagesInfo()->findPackageInfo(arguments().first())); - setValue(QLatin1String("oldVersion"), info.version); - setValue(QLatin1String("oldDate"), info.lastUpdateDate); -} - -bool UpdatePackageOperation::performOperation() -{ - // This operation receives three arguments : the name of the package - // the new version and the release date - const QStringList args = this->arguments(); - if (args.count() != 3) { - setError(InvalidArguments, tr("Invalid arguments: %1 arguments given, 3 expected.").arg(args.count())); - return false; - } - - const QString &packageName = args.at(0); - const QString &version = args.at(1); - const QDate date = QDate::fromString(args.at(2)); - const bool success = application()->packagesInfo()->updatePackage(packageName, version, date); - if (!success) - setError(UserDefinedError, tr("Cannot update %1-%2").arg(packageName, version)); - - return success; -} - -bool UpdatePackageOperation::undoOperation() -{ - const QString packageName = arguments().first(); - const QString version = arguments().at(1); - const QString oldVersion = value(QLatin1String("oldVersion")).toString(); - const QDate oldDate = value(QLatin1String("oldDate")).toDate(); - const bool success = application()->packagesInfo()->updatePackage(packageName, oldVersion, oldDate); - if (!success) - setError(UserDefinedError, tr("Cannot restore %1-%2").arg(packageName, version)); - - return success; -} - -bool UpdatePackageOperation::testOperation() -{ - // TODO - return true; -} - -UpdatePackageOperation *UpdatePackageOperation::clone() const -{ - return new UpdatePackageOperation; -} - - -//////////////////////////////////////////////////////////////////////////// -// KDUpdater::UpdateCompatOperation -//////////////////////////////////////////////////////////////////////////// - -UpdateCompatOperation::UpdateCompatOperation() -{ - setName(QLatin1String("UpdateCompatLevel")); -} - -void UpdateCompatOperation::backup() -{ - setValue(QLatin1String("oldCompatLevel"), application()->packagesInfo()->compatLevel()); -} - -bool UpdateCompatOperation::performOperation() -{ - // This operation receives one argument : the new compat level - const QStringList args = this->arguments(); - if (args.count() != 1) { - setError(InvalidArguments, tr("Invalid arguments: %1 arguments given, 1 expected.").arg(args.count())); - return false; - } - - const int level = args.first().toInt(); - application()->packagesInfo()->setCompatLevel(level); - return true; -} - -bool UpdateCompatOperation::undoOperation() -{ - if (!hasValue(QLatin1String("oldCompatLevel"))) { - setError(UserDefinedError, tr("Cannot restore previous compat-level")); - return false; - } - - application()->packagesInfo()->setCompatLevel(value(QLatin1String("oldCompatLevel")).toInt()); - return true; -} - -bool UpdateCompatOperation::testOperation() -{ - // TODO - return true; -} - -UpdateCompatOperation *UpdateCompatOperation::clone() const -{ - return new UpdateCompatOperation; -} |