summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkh1 <qt-info@nokia.com>2011-03-30 15:18:21 +0200
committerkh1 <qt-info@nokia.com>2011-03-30 15:18:21 +0200
commit5fb9e4cd8488e67315df18fad585dedf3aeb9be8 (patch)
treeee98c73d6e91a5498ef8dd3fc8e8f1085b30ba70
parenta5507f265067a1268b29a204bf356d1951dc3be6 (diff)
parentca229bc660b7367c94022aea8fa8fc7b4c5b38dd (diff)
Merge branch 'master' into refactor
Conflicts: examples/testapp/testapp.pro installerbuilder/installerbase/installerbasecommons.cpp installerbuilder/libinstaller/qinstaller.cpp installerbuilder/tests/tests.pro
-rw-r--r--installerbuilder/common/installersettings.cpp7
-rw-r--r--installerbuilder/common/installersettings.h1
-rw-r--r--installerbuilder/common/utils.cpp17
-rw-r--r--installerbuilder/installerbase/installerbasecommons.cpp11
-rw-r--r--installerbuilder/libinstaller/elevatedexecuteoperation.cpp112
-rw-r--r--installerbuilder/libinstaller/elevatedexecuteoperation.h9
-rw-r--r--installerbuilder/libinstaller/init.cpp2
-rw-r--r--installerbuilder/libinstaller/libinstaller.pro5
-rw-r--r--installerbuilder/libinstaller/persistentsettings.cpp216
-rw-r--r--installerbuilder/libinstaller/persistentsettings.h76
-rw-r--r--installerbuilder/libinstaller/projectexplorer_export.h1
-rw-r--r--installerbuilder/libinstaller/qinstaller_p.cpp34
-rw-r--r--installerbuilder/libinstaller/qinstallergui.cpp4
-rw-r--r--installerbuilder/libinstaller/registertoolchainoperation.cpp187
-rw-r--r--installerbuilder/libinstaller/registertoolchainoperation.h65
15 files changed, 690 insertions, 57 deletions
diff --git a/installerbuilder/common/installersettings.cpp b/installerbuilder/common/installersettings.cpp
index 7f104c4f6..19f3eeb25 100644
--- a/installerbuilder/common/installersettings.cpp
+++ b/installerbuilder/common/installersettings.cpp
@@ -68,6 +68,7 @@ public:
QString targetDir;
QString adminTargetDir;
QString icon;
+ QString removeTargetDir;
QString uninstallerName;
QString uninstallerIniFile;
QString configurationFileName;
@@ -163,6 +164,7 @@ InstallerSettings InstallerSettings::fromFileAndPrefix( const QString& path, con
s.d->targetDir = readChild( root, QLatin1String("TargetDir") );
s.d->adminTargetDir = readChild( root, QLatin1String("AdminTargetDir") );
s.d->icon = readChild( root, QLatin1String( "Icon" ) );
+ s.d->removeTargetDir = readChild(root, QLatin1String("RemoveTargetDir"), QLatin1String("true"));
s.d->uninstallerName = readChild( root, QLatin1String( "UninstallerName" ), QLatin1String("uninstall") );
s.d->uninstallerIniFile = readChild( root, QLatin1String("UninstallerIniFile"), s.d->uninstallerName + QLatin1String(".ini") );
s.d->privateKey = splitTrimmed( readChild( root, QLatin1String( "PrivateKey" ) ) ).toLatin1();
@@ -256,6 +258,11 @@ QString InstallerSettings::icon() const
#endif
}
+QString InstallerSettings::removeTargetDir() const
+{
+ return d->removeTargetDir;
+}
+
QString InstallerSettings::uninstallerName() const
{
if( d->uninstallerName.isEmpty() )
diff --git a/installerbuilder/common/installersettings.h b/installerbuilder/common/installersettings.h
index d73049345..939d35f00 100644
--- a/installerbuilder/common/installersettings.h
+++ b/installerbuilder/common/installersettings.h
@@ -70,6 +70,7 @@ namespace QInstaller {
QString targetDir() const;
QString adminTargetDir() const;
+ QString removeTargetDir() const;
QString uninstallerName() const;
QString uninstallerIniFile() const;
diff --git a/installerbuilder/common/utils.cpp b/installerbuilder/common/utils.cpp
index 31d92f6be..e4460bd4c 100644
--- a/installerbuilder/common/utils.cpp
+++ b/installerbuilder/common/utils.cpp
@@ -192,14 +192,15 @@ QInstaller::VerboseWriter::~VerboseWriter()
return;
}
QFile output(logFileName);
- if (!output.open(QIODevice::ReadWrite | QIODevice::Append))
- qFatal("Could not open logfile!");
- QString logInfo;
- logInfo += QLatin1String("*************************************");
- logInfo += QString::fromLatin1("Invoked:") + QDateTime::currentDateTime().toString();
- output.write(logInfo.toLocal8Bit());
- output.write(preFileBuffer.data());
- output.close();
+ if (output.open(QIODevice::ReadWrite | QIODevice::Append)) {
+ QString logInfo;
+ logInfo += QLatin1String("*************************************");
+ logInfo += QString::fromLatin1("Invoked:") + QDateTime::currentDateTime().toString();
+ output.write(logInfo.toLocal8Bit());
+ output.write(preFileBuffer.data());
+ output.close();
+ }
+ stream.setDevice(0);
}
void QInstaller::VerboseWriter::setOutputStream(const QString &fileName)
diff --git a/installerbuilder/installerbase/installerbasecommons.cpp b/installerbuilder/installerbase/installerbasecommons.cpp
index c82574d5a..cb29359bb 100644
--- a/installerbuilder/installerbase/installerbasecommons.cpp
+++ b/installerbuilder/installerbase/installerbasecommons.cpp
@@ -225,6 +225,17 @@ bool TargetDirectoryPageImpl::validatePage()
if (!isVisible())
return true;
+ if (targetDir().isEmpty()) {
+ MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
+ QLatin1String("forbiddenTargetDirectory"), tr("Error"),
+ tr( "The install directory cannot be empty, please specify a valid folder"), QMessageBox::Ok);
+ return false;
+ }
+
+ QString remove = installer()->value(QLatin1String("RemoveTargetDir"));
+ if (!QVariant(remove).toBool())
+ return true;
+
if (QFileInfo(targetDir()).isDir()) {
QFileInfo fi2(targetDir() + QDir::separator() + installer()->uninstallerName());
if (QDir(targetDir()) == QDir::root()) {
diff --git a/installerbuilder/libinstaller/elevatedexecuteoperation.cpp b/installerbuilder/libinstaller/elevatedexecuteoperation.cpp
index c255a28af..b333bf7da 100644
--- a/installerbuilder/libinstaller/elevatedexecuteoperation.cpp
+++ b/installerbuilder/libinstaller/elevatedexecuteoperation.cpp
@@ -58,6 +58,7 @@ private:
public:
void readProcessOutput();
+ bool run(const QStringList& arguments);
QProcessWrapper* process;
bool showStandardError;
@@ -78,14 +79,26 @@ bool ElevatedExecuteOperation::performOperation()
{
// This operation receives only one argument. It is the complete
// command line of the external program to execute.
- QStringList args = arguments();
- if( args.isEmpty() )
+ if( arguments().isEmpty() )
{
setError( InvalidArguments );
- setErrorString( tr("Invalid arguments in %1: %2 arguments given, at least 1 expected.").arg( name(), QString::number( args.count() ) ) );
+ setErrorString( tr("Invalid arguments in %1: %2 arguments given, at least 1 expected.").arg( name(), QString::number( arguments().count() ) ) );
return false;
}
+ QStringList args;
+ foreach(const QString &argument, arguments()) {
+ if (argument!=QLatin1String("UNDOEXECUTE"))
+ args.append(argument);
+ else
+ break; //we don't need the UNDOEXECUTE args here
+ }
+
+ return d->run(args);
+}
+bool ElevatedExecuteOperation::Private::run(const QStringList& arguments)
+{
+ QStringList args = arguments;
QString workingDirectory;
QStringList filteredWorkingDirectoryArgs = args.filter(QLatin1String("workingdirectory="), Qt::CaseInsensitive);
if (!filteredWorkingDirectoryArgs.isEmpty()) {
@@ -97,7 +110,7 @@ bool ElevatedExecuteOperation::performOperation()
if ( args.last().endsWith( QLatin1String("showStandardError") ) ) {
- d->showStandardError = true;
+ showStandardError = true;
args.pop_back();
}
@@ -124,87 +137,87 @@ bool ElevatedExecuteOperation::performOperation()
args.pop_back();
const bool success = QProcess::startDetached( args.front(), args.mid( 1 ) );
if ( !success ) {
- setError( UserDefinedError );
- setErrorString( tr( "Execution failed: Could not start detached: \"%1\"" ).arg( callstr ) );
+ q->setError( UserDefinedError );
+ q->setErrorString( tr( "Execution failed: Could not start detached: \"%1\"" ).arg( callstr ) );
}
return success;
}
- d->process = new QProcessWrapper();
+ process = new QProcessWrapper();
if (!workingDirectory.isEmpty()) {
- d->process->setWorkingDirectory( workingDirectory );
+ process->setWorkingDirectory( workingDirectory );
QInstaller::verbose() << " ElevatedExecuteOperation setWorkingDirectory: " << workingDirectory << std::endl;
}
QProcessEnvironment penv;
//there is no way to serialize a QProcessEnvironment properly other than per mangled QStringList :/ (i.e. no other way to list all keys)
- d->process->setEnvironment( KDUpdater::Environment::instance()->applyTo( penv ).toStringList() );
+ process->setEnvironment( KDUpdater::Environment::instance()->applyTo( penv ).toStringList() );
- if (d->showStandardError)
- d->process->setProcessChannelMode(QProcess::MergedChannels);
+ if (showStandardError)
+ process->setProcessChannelMode(QProcess::MergedChannels);
- connect(this, SIGNAL(cancelProcess()), d->process, SLOT(cancel()));
+ connect(q, SIGNAL(cancelProcess()), process, SLOT(cancel()));
//we still like the none blocking possibility to perform this operation without threads
QEventLoop loop;
if (QThread::currentThread() == qApp->thread()) {
- QObject::connect( d->process, SIGNAL( finished( int, QProcess::ExitStatus ) ), &loop, SLOT( quit() ) );
+ QObject::connect( process, SIGNAL( finished( int, QProcess::ExitStatus ) ), &loop, SLOT( quit() ) );
}
//readProcessOutput should only called from this current Thread -> Qt::DirectConnection
- QObject::connect( d->process, SIGNAL( readyRead() ), this, SLOT( readProcessOutput() ), Qt::DirectConnection );
+ QObject::connect( process, SIGNAL( readyRead() ), q, SLOT( readProcessOutput() ), Qt::DirectConnection );
#ifdef Q_OS_WIN
if (args.count() == 1) {
- d->process->setNativeArguments( args.front() );
+ process->setNativeArguments( args.front() );
QInstaller::verbose() << " ElevatedExecuteOperation setNativeArguments to start: " << args.front() << std::endl;
- d->process->start(QString(), QStringList());
+ process->start(QString(), QStringList());
} else
#endif
- d->process->start( args.front(), args.mid( 1 ) );
+ process->start( args.front(), args.mid( 1 ) );
QInstaller::verbose() << args.front() << " started, arguments: " << QStringList(args.mid( 1 )).join(QLatin1String(" ")) << std::endl;
bool success = false;
//we still like the none blocking possibility to perform this operation without threads
if (QThread::currentThread() == qApp->thread()) {
- success = d->process->waitForStarted();
+ success = process->waitForStarted();
} else {
- success = d->process->waitForFinished(-1);
+ success = process->waitForFinished(-1);
}
bool returnValue = true;
if ( !success )
{
- setError( UserDefinedError );
+ q->setError( UserDefinedError );
//TODO: pass errorString() through the wrapper */
- setErrorString( tr( "Execution failed: Could not start: \"%1\"" ).arg( callstr ) );
+ q->setErrorString( tr( "Execution failed: Could not start: \"%1\"" ).arg( callstr ) );
returnValue = false;
}
if (QThread::currentThread() == qApp->thread()) {
- if (d->process->state() != QProcess::NotRunning) {
+ if (process->state() != QProcess::NotRunning) {
loop.exec();
}
- d->readProcessOutput();
+ readProcessOutput();
}
- setValue( QLatin1String( "ExitCode" ), d->process->exitCode() );
+ q->setValue( QLatin1String( "ExitCode" ), process->exitCode() );
- if ( d->process->exitStatus() == QProcess::CrashExit )
+ if ( process->exitStatus() == QProcess::CrashExit )
{
- setError( UserDefinedError );
- setErrorString( tr( "Execution failed (Crash): \"%1\"" ).arg( callstr ) );
+ q->setError( UserDefinedError );
+ q->setErrorString( tr( "Execution failed (Crash): \"%1\"" ).arg( callstr ) );
returnValue = false;
}
- if ( !allowedExitCodes.contains( d->process->exitCode() ) )
+ if ( !allowedExitCodes.contains( process->exitCode() ) )
{
- setError( UserDefinedError );
- setErrorString( tr( "Execution failed (Unexpected exit code: %1): \"%2\"" ).arg( QString::number( d->process->exitCode() ), callstr ) );
+ q->setError( UserDefinedError );
+ q->setErrorString( tr( "Execution failed (Unexpected exit code: %1): \"%2\"" ).arg( QString::number( process->exitCode() ), callstr ) );
returnValue = false;
}
- Q_ASSERT(d->process);
- d->process->deleteLater();
- d->process = 0;
+ Q_ASSERT(process);
+ process->deleteLater();
+ process = 0;
return returnValue;
}
@@ -232,4 +245,37 @@ void ElevatedExecuteOperation::Private::readProcessOutput()
}
}
+
+bool ElevatedExecuteOperation::undoOperation()
+{
+ QStringList args;
+ bool found = false;
+ foreach(const QString &argument, arguments()) {
+ if (found)
+ args.append(argument);
+ else
+ found = argument==QLatin1String("UNDOEXECUTE");
+ }
+ if (args.isEmpty())
+ return true;
+
+ return d->run(args);
+}
+
+bool ElevatedExecuteOperation::testOperation()
+{
+ // TODO
+ return true;
+}
+
+ElevatedExecuteOperation* ElevatedExecuteOperation::clone() const
+{
+ return new ElevatedExecuteOperation;
+}
+
+void ElevatedExecuteOperation::backup()
+{
+}
+
+
#include "moc_elevatedexecuteoperation.cpp"
diff --git a/installerbuilder/libinstaller/elevatedexecuteoperation.h b/installerbuilder/libinstaller/elevatedexecuteoperation.h
index 6fcb5e8de..35cb84afd 100644
--- a/installerbuilder/libinstaller/elevatedexecuteoperation.h
+++ b/installerbuilder/libinstaller/elevatedexecuteoperation.h
@@ -33,17 +33,22 @@
namespace QInstaller {
-class INSTALLER_EXPORT ElevatedExecuteOperation : public KDUpdater::ExecuteOperation
+class INSTALLER_EXPORT ElevatedExecuteOperation : public QObject, public KDUpdater::UpdateOperation
{
Q_OBJECT
public:
ElevatedExecuteOperation();
~ElevatedExecuteOperation();
- bool performOperation();
+ virtual void backup();
+ virtual bool performOperation();
+ virtual bool undoOperation();
+ virtual bool testOperation();
+ virtual ElevatedExecuteOperation* clone() const;
Q_SIGNALS:
void cancelProcess();
+ void outputTextChanged(const QString &text);
public Q_SLOTS:
void cancelOperation();
diff --git a/installerbuilder/libinstaller/init.cpp b/installerbuilder/libinstaller/init.cpp
index 07512808a..df4f89477 100644
--- a/installerbuilder/libinstaller/init.cpp
+++ b/installerbuilder/libinstaller/init.cpp
@@ -57,6 +57,7 @@
#include "registerqtoperation.h"
#include "setqtcreatorvalueoperation.h"
#include "simplemovefileoperation.h"
+#include "registertoolchainoperation.h"
#include "minimumprogressoperation.h"
@@ -175,6 +176,7 @@ void QInstaller::init()
KDUpdater::UpdateOperationFactory::instance().registerUpdateOperation< QInstaller::CopyDirectoryOperation >( QLatin1String( "CopyDirectory") );
KDUpdater::UpdateOperationFactory::instance().registerUpdateOperation< QInstaller::RegisterDocumentationOperation >( QLatin1String( "RegisterDocumentation") );
KDUpdater::UpdateOperationFactory::instance().registerUpdateOperation< QInstaller::RegisterQtInCreatorOperation>( QLatin1String( "RegisterQtInCreator") );
+ KDUpdater::UpdateOperationFactory::instance().registerUpdateOperation< QInstaller::RegisterToolChainOperation>( QLatin1String( "RegisterToolChain") );
KDUpdater::UpdateOperationFactory::instance().registerUpdateOperation< QInstaller::SetDemosPathOnQtOperation>( QLatin1String( "SetDemosPathOnQt") );
KDUpdater::UpdateOperationFactory::instance().registerUpdateOperation< QInstaller::SetExamplesPathOnQtOperation>( QLatin1String( "SetExamplesPathOnQt") );
KDUpdater::UpdateOperationFactory::instance().registerUpdateOperation< QInstaller::SetPluginPathOnQtCoreOperation>( QLatin1String( "SetPluginPathOnQtCore") );
diff --git a/installerbuilder/libinstaller/libinstaller.pro b/installerbuilder/libinstaller/libinstaller.pro
index 21a55dea0..04832f902 100644
--- a/installerbuilder/libinstaller/libinstaller.pro
+++ b/installerbuilder/libinstaller/libinstaller.pro
@@ -48,6 +48,8 @@ HEADERS += $$PWD/qinstaller.h \
qinstallercomponentmodel.h \
qinstallerglobal.h \
qtpatch.h \
+ persistentsettings.h \
+ projectexplorer_export.h \
qtpatchoperation.h \
setdemospathonqtoperation.h \
setexamplespathonqtoperation.h \
@@ -57,6 +59,7 @@ HEADERS += $$PWD/qinstaller.h \
linereplaceoperation.h \
registerdocumentationoperation.h \
registerqtoperation.h \
+ registertoolchainoperation.h \
setqtcreatorvalueoperation.h \
copydirectoryoperation.h \
simplemovefileoperation.h \
@@ -111,6 +114,7 @@ SOURCES += $$PWD/qinstaller.cpp \
qinstallercomponent.cpp \
qinstallercomponentmodel.cpp \
qtpatch.cpp \
+ persistentsettings.cpp \
qtpatchoperation.cpp \
setdemospathonqtoperation.cpp \
setexamplespathonqtoperation.cpp \
@@ -120,6 +124,7 @@ SOURCES += $$PWD/qinstaller.cpp \
linereplaceoperation.cpp \
registerdocumentationoperation.cpp \
registerqtoperation.cpp \
+ registertoolchainoperation.cpp \
setqtcreatorvalueoperation.cpp \
copydirectoryoperation.cpp \
simplemovefileoperation.cpp \
diff --git a/installerbuilder/libinstaller/persistentsettings.cpp b/installerbuilder/libinstaller/persistentsettings.cpp
new file mode 100644
index 000000000..16131c228
--- /dev/null
+++ b/installerbuilder/libinstaller/persistentsettings.cpp
@@ -0,0 +1,216 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "persistentsettings.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QFile>
+#include <QtCore/QVariant>
+#include <QtXml/QDomDocument>
+#include <QtXml/QDomCDATASection>
+#include <QtXml/QDomElement>
+
+
+using namespace ProjectExplorer;
+
+PersistentSettingsReader::PersistentSettingsReader()
+{
+
+}
+
+QVariant PersistentSettingsReader::restoreValue(const QString & variable) const
+{
+ if (m_valueMap.contains(variable))
+ return m_valueMap.value(variable);
+ return QVariant();
+}
+
+QVariantMap PersistentSettingsReader::restoreValues() const
+{
+ return m_valueMap;
+}
+
+bool PersistentSettingsReader::load(const QString & fileName)
+{
+ m_valueMap.clear();
+
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly))
+ return false;
+
+ QDomDocument doc;
+ if (!doc.setContent(&file))
+ return false;
+
+ QDomElement root = doc.documentElement();
+ if (root.nodeName() != QLatin1String("qtcreator"))
+ return false;
+
+ QDomElement child = root.firstChildElement();
+ for (; !child.isNull(); child = child.nextSiblingElement()) {
+ if (child.nodeName() == QLatin1String("data"))
+ readValues(child);
+ }
+
+ file.close();
+ return true;
+}
+
+QVariant PersistentSettingsReader::readValue(const QDomElement &valElement) const
+{
+ QString name = valElement.nodeName();
+ QString type = valElement.attribute(QLatin1String("type"));
+ QVariant v;
+
+ if (name == QLatin1String("value")) {
+ if(type == QLatin1String("QChar")) {
+ //Workaround: QTBUG-12345
+ v.setValue(QChar(valElement.text().at(0)));
+ } else {
+ v.setValue(valElement.text());
+ v.convert(QVariant::nameToType(type.toLatin1().data()));
+ }
+ } else if (name == QLatin1String("valuelist")) {
+ QDomElement child = valElement.firstChildElement();
+ QList<QVariant> valList;
+ for (; !child.isNull(); child = child.nextSiblingElement()) {
+ valList << readValue(child);
+ }
+ v.setValue(valList);
+ } else if (name == QLatin1String("valuemap")) {
+ QDomElement child = valElement.firstChildElement();
+ QMap<QString, QVariant> valMap;
+ for (; !child.isNull(); child = child.nextSiblingElement()) {
+ QString key = child.attribute(QLatin1String("key"));
+ valMap.insert(key, readValue(child));
+ }
+ v.setValue(valMap);
+ }
+
+ return v;
+}
+
+void PersistentSettingsReader::readValues(const QDomElement &data)
+{
+ QString variable;
+ QVariant v;
+
+ QDomElement child = data.firstChildElement();
+ for (; !child.isNull(); child = child.nextSiblingElement()) {
+ if (child.nodeName() == QLatin1String("variable")) {
+ variable = child.text();
+ } else {
+ v = readValue(child);
+ }
+ }
+
+ m_valueMap.insert(variable, v);
+}
+
+///
+/// PersistentSettingsWriter
+///
+
+PersistentSettingsWriter::PersistentSettingsWriter()
+{
+
+}
+
+void PersistentSettingsWriter::writeValue(QDomElement &ps, const QVariant &variant)
+{
+ if (variant.type() == QVariant::StringList || variant.type() == QVariant::List) {
+ QDomElement values = ps.ownerDocument().createElement(QLatin1String("valuelist"));
+ values.setAttribute(QLatin1String("type"), QLatin1String(QVariant::typeToName(QVariant::List)));
+ QList<QVariant> varList = variant.toList();
+ foreach (const QVariant &var, varList) {
+ writeValue(values, var);
+ }
+ ps.appendChild(values);
+ } else if (variant.type() == QVariant::Map) {
+ QDomElement values = ps.ownerDocument().createElement(QLatin1String("valuemap"));
+ values.setAttribute(QLatin1String("type"), QLatin1String(QVariant::typeToName(QVariant::Map)));
+
+ QMap<QString, QVariant> varMap = variant.toMap();
+ QMap<QString, QVariant>::const_iterator i = varMap.constBegin();
+ while (i != varMap.constEnd()) {
+ writeValue(values, i.value());
+ values.lastChild().toElement().
+ setAttribute(QLatin1String("key"), i.key());
+ ++i;
+ }
+
+ ps.appendChild(values);
+ } else {
+ QDomElement value = ps.ownerDocument().createElement(QLatin1String("value"));
+ ps.appendChild(value);
+ QDomText valueText = ps.ownerDocument().createTextNode(variant.toString());
+ value.appendChild(valueText);
+ value.setAttribute(QLatin1String("type"), QLatin1String(variant.typeName()));
+ ps.appendChild(value);
+ }
+}
+
+void PersistentSettingsWriter::saveValue(const QString & variable, const QVariant &value)
+{
+ m_valueMap[variable] = value;
+}
+
+bool PersistentSettingsWriter::save(const QString & fileName, const QString & docType)
+{
+ QFile file(fileName);
+ if (!file.open(QIODevice::WriteOnly))
+ return false;
+
+ QDomDocument doc(docType);
+
+ QDomElement root = doc.createElement(QLatin1String("qtcreator"));
+ doc.appendChild(root);
+
+ QMap<QString, QVariant>::const_iterator i = m_valueMap.constBegin();
+ while (i != m_valueMap.constEnd()) {
+ QDomElement ps = doc.createElement(QLatin1String("data"));
+ root.appendChild(ps);
+
+ QDomElement variable = doc.createElement(QLatin1String("variable"));
+ ps.appendChild(variable);
+ QDomText variableText = doc.createTextNode(i.key());
+ variable.appendChild(variableText);
+
+ writeValue(ps, i.value());
+ ++i;
+ }
+
+ file.write(doc.toByteArray());
+ file.close();
+ return true;
+}
diff --git a/installerbuilder/libinstaller/persistentsettings.h b/installerbuilder/libinstaller/persistentsettings.h
new file mode 100644
index 000000000..605cb9cfb
--- /dev/null
+++ b/installerbuilder/libinstaller/persistentsettings.h
@@ -0,0 +1,76 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef PERSISTENTSETTINGS_H
+#define PERSISTENTSETTINGS_H
+
+#include "projectexplorer_export.h"
+
+#include <QtCore/QMap>
+#include <QtCore/QVariant>
+
+QT_BEGIN_NAMESPACE
+class QDomElement;
+QT_END_NAMESPACE
+
+namespace ProjectExplorer {
+
+class PROJECTEXPLORER_EXPORT PersistentSettingsReader
+{
+public:
+ PersistentSettingsReader();
+ QVariant restoreValue(const QString & variable) const;
+ QVariantMap restoreValues() const;
+ bool load(const QString & fileName);
+
+private:
+ QVariant readValue(const QDomElement &valElement) const;
+ void readValues(const QDomElement &data);
+ QMap<QString, QVariant> m_valueMap;
+};
+
+class PROJECTEXPLORER_EXPORT PersistentSettingsWriter
+{
+public:
+ PersistentSettingsWriter();
+ void saveValue(const QString & variable, const QVariant &value);
+ bool save(const QString & fileName, const QString & docType);
+
+private:
+ void writeValue(QDomElement &ps, const QVariant &value);
+ QMap<QString, QVariant> m_valueMap;
+};
+
+} // namespace ProjectExplorer
+
+#endif // PERSISTENTSETTINGS_H
diff --git a/installerbuilder/libinstaller/projectexplorer_export.h b/installerbuilder/libinstaller/projectexplorer_export.h
new file mode 100644
index 000000000..d93c3da24
--- /dev/null
+++ b/installerbuilder/libinstaller/projectexplorer_export.h
@@ -0,0 +1 @@
+#define PROJECTEXPLORER_EXPORT \ No newline at end of file
diff --git a/installerbuilder/libinstaller/qinstaller_p.cpp b/installerbuilder/libinstaller/qinstaller_p.cpp
index 870c43c61..d4ef12496 100644
--- a/installerbuilder/libinstaller/qinstaller_p.cpp
+++ b/installerbuilder/libinstaller/qinstaller_p.cpp
@@ -331,7 +331,8 @@ void InstallerPrivate::initialize()
m_vars.insert(QLatin1String("TargetDir"), replaceVariables(m_installerSettings->adminTargetDir()));
else
#endif
- m_vars.insert(QLatin1String("TargetDir"), replaceVariables(m_installerSettings->targetDir()));
+ m_vars.insert(QLatin1String("TargetDir"), replaceVariables(m_installerSettings->targetDir()));
+ m_vars.insert(QLatin1String("RemoveTargetDir"), replaceVariables(m_installerSettings->removeTargetDir()));
QSettings creatorSettings(QSettings::IniFormat, QSettings::UserScope, QLatin1String("Nokia"),
QLatin1String("QtCreator"));
@@ -976,7 +977,9 @@ void InstallerPrivate::runInstaller()
if (!q->gainAdminRights() || !performOperationThreaded(mkdirOp.data()))
throw Error(mkdirOp->errorString());
}
- addPerformed(mkdirOp.take());
+ QString remove = q->value(QLatin1String("RemoveTargetDir"));
+ if (QVariant(remove).toBool())
+ addPerformed(mkdirOp.take());
} else {
QTemporaryFile tempAdminFile(target + QLatin1String("/adminrights"));
if (!tempAdminFile.open() || !tempAdminFile.isWritable())
@@ -1456,18 +1459,21 @@ void InstallerPrivate::runUninstaller()
(*it)->setValue(QLatin1String("CurrentState"), QLatin1String("Uninstalled"));
}
- // on !Windows, we need to remove TargetDir manually
- m_packageManagingMode = ! m_completeUninstall;
- verbose() << "Complete Uninstallation is chosen" << std::endl;
- const QString target = targetDir();
- if (!target.isEmpty()) {
- if (m_FSEngineClientHandler->isServerRunning() && !m_FSEngineClientHandler->isActive()) {
- // we were root at least once, so we remove the target dir as root
- q->gainAdminRights();
- removeDirectoryThreaded(target, true);
- q->dropAdminRights();
- } else {
- removeDirectoryThreaded(target, true);
+ QString remove = q->value(QLatin1String("RemoveTargetDir"));
+ if (QVariant(remove).toBool()) {
+ // on !Windows, we need to remove TargetDir manually
+ m_packageManagingMode = ! m_completeUninstall;
+ verbose() << "Complete Uninstallation is chosen" << std::endl;
+ const QString target = targetDir();
+ if (!target.isEmpty()) {
+ if (m_FSEngineClientHandler->isServerRunning() && !m_FSEngineClientHandler->isActive()) {
+ // we were root at least once, so we remove the target dir as root
+ q->gainAdminRights();
+ removeDirectoryThreaded(target, true);
+ q->dropAdminRights();
+ } else {
+ removeDirectoryThreaded(target, true);
+ }
}
}
diff --git a/installerbuilder/libinstaller/qinstallergui.cpp b/installerbuilder/libinstaller/qinstallergui.cpp
index 5d0695bb3..aa3159a8d 100644
--- a/installerbuilder/libinstaller/qinstallergui.cpp
+++ b/installerbuilder/libinstaller/qinstallergui.cpp
@@ -1223,6 +1223,10 @@ bool TargetDirectoryPage::validatePage()
return false;
}
+ QString remove = installer()->value(QLatin1String("RemoveTargetDir"));
+ if (!QVariant(remove).toBool())
+ return true;
+
return MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
QLatin1String("overwriteTargetDirectory"), tr("Warning"),
tr("You have selected an existing, non-empty folder for installation.\n"
diff --git a/installerbuilder/libinstaller/registertoolchainoperation.cpp b/installerbuilder/libinstaller/registertoolchainoperation.cpp
new file mode 100644
index 000000000..22d5b6833
--- /dev/null
+++ b/installerbuilder/libinstaller/registertoolchainoperation.cpp
@@ -0,0 +1,187 @@
+/**************************************************************************
+**
+** This file is part of Qt SDK**
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).*
+**
+** Contact: Nokia Corporation qt-info@nokia.com**
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception version
+** 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you are unsure which license is appropriate for your use, please contact
+** (qt-info@nokia.com).
+**
+**************************************************************************/
+#include "registertoolchainoperation.h"
+#include "persistentsettings.h"
+
+#include <QString>
+#include <QFileInfo>
+#include <QDir>
+#include <QSettings>
+#include <QDebug>
+
+using namespace QInstaller;
+
+//Begin - copied from Creator
+using namespace ProjectExplorer;
+
+static const char *const TOOLCHAIN_DATA_KEY = "ToolChain.";
+static const char *const TOOLCHAIN_COUNT_KEY = "ToolChain.Count";
+static const char *const TOOLCHAIN_FILE_VERSION_KEY = "Version";
+
+static const char *const ID_KEY = "ProjectExplorer.ToolChain.Id";
+static const char *const DISPLAY_NAME_KEY = "ProjectExplorer.ToolChain.DisplayName";
+//End - copied from Creator
+
+
+RegisterToolChainOperation::RegisterToolChainOperation()
+{
+ setName(QLatin1String("RegisterToolChain"));
+}
+
+RegisterToolChainOperation::~RegisterToolChainOperation()
+{
+}
+
+void RegisterToolChainOperation::backup()
+{
+}
+
+bool RegisterToolChainOperation::performOperation()
+{
+ const QStringList args = arguments();
+
+ if( args.count() < 5) {
+ setError( InvalidArguments );
+ setErrorString( tr("Invalid arguments in %0: %1 arguments given, minimum 5 expected.")
+ .arg(name()).arg( args.count() ) );
+ return false;
+ }
+
+ int argCounter = 0;
+ const QString &rootInstallPath = args.at(argCounter++); //for example "C:\\Nokia_SDK\\"
+ const QString &toolChainKey = args.at(argCounter++); //Qt SDK:gccPath
+ const QString &toolChainType = args.at(argCounter++); //where this toolchain is defined in QtCreator
+ const QString &displayName = args.at(argCounter++); //nice special Toolchain (Qt SDK)
+ const QString &abiString = args.at(argCounter++); //x86-windows-msys-pe-32bit
+ const QString &compilerPath = args.at(argCounter++); //gccPath
+ QString debuggerPath;
+ QString armVersion;
+ QString force32Bit;
+ if (args.count() > argCounter)
+ debuggerPath = args.at(argCounter++);
+ if (args.count() > argCounter)
+ armVersion = args.at(argCounter++);
+ if (args.count() > argCounter)
+ force32Bit = args.at(argCounter++);
+
+ QString toolChainsXmlFilePath;
+
+#if defined ( Q_OS_MAC )
+ toolChainsXmlFilePath = QString(
+ QLatin1String("%1/Qt Creator.app/Contents/Resources/Nokia/toolChains.xml")
+ ).arg(rootInstallPath);
+#else
+ toolChainsXmlFilePath = QString(
+ QLatin1String("%1/QtCreator/share/qtcreator/Nokia/toolChains.xml")
+ ).arg(rootInstallPath);
+#endif
+
+
+ QHash< QString, QVariantMap > toolChainHash;
+
+ PersistentSettingsReader reader;
+ if (reader.load(toolChainsXmlFilePath)) {
+ QVariantMap data = reader.restoreValues();
+
+ // Check version:
+ int version = data.value(QLatin1String(TOOLCHAIN_FILE_VERSION_KEY), 0).toInt();
+ if (version < 1) {
+ setError( UserDefinedError );
+ setErrorString(tr("Toolchain settings xml file %1 has not the right version.")
+ .arg(toolChainsXmlFilePath));
+ return false;
+ }
+
+ int count = data.value(QLatin1String(TOOLCHAIN_COUNT_KEY), 0).toInt();
+ for (int i = 0; i < count; ++i) {
+ const QString key = QString::fromLatin1(TOOLCHAIN_DATA_KEY) + QString::number(i);
+
+ const QVariantMap toolChainMap = data.value(key).toMap();
+
+ //gets the path variable, hope ".Path" will stay in QtCreator
+ QStringList pathContainingKeyList =
+ QStringList(toolChainMap.keys()).filter(QLatin1String(".Path"));
+ foreach(const QString& pathKey, pathContainingKeyList) {
+ QString path = toolChainMap.value(pathKey).toString();
+ if (!path.isEmpty() && QFile::exists(path)) {
+ toolChainHash.insert(path, toolChainMap);
+ }
+ }
+ }
+ }
+
+ QVariantMap newToolChainVariantMap;
+
+ newToolChainVariantMap.insert(QLatin1String(ID_KEY),
+ QString(QLatin1String("%1:%2.%3")).arg(toolChainType, compilerPath, abiString));
+ newToolChainVariantMap.insert(QLatin1String(DISPLAY_NAME_KEY), displayName);
+ newToolChainVariantMap.insert(QString(QLatin1String("ProjectExplorer.%1.Path")).arg(toolChainKey),
+ compilerPath);
+ newToolChainVariantMap.insert(QString(QLatin1String("ProjectExplorer.%1.TargetAbi")).arg(toolChainKey),
+ abiString);
+ newToolChainVariantMap.insert(QString(QLatin1String("ProjectExplorer.%1.Debugger")).arg(toolChainKey),
+ debuggerPath);
+
+ toolChainHash.insert(compilerPath, newToolChainVariantMap);
+
+ PersistentSettingsWriter writer;
+ writer.saveValue(QLatin1String(TOOLCHAIN_FILE_VERSION_KEY), 1);
+
+ int count = 0;
+
+ foreach (const QVariantMap &toolChainMap, toolChainHash.values()) {
+ if (toolChainMap.isEmpty())
+ continue;
+ writer.saveValue(QString::fromLatin1(TOOLCHAIN_DATA_KEY) + QString::number(count++),
+ toolChainMap);
+ }
+ writer.saveValue(QLatin1String(TOOLCHAIN_COUNT_KEY), count);
+ writer.save(toolChainsXmlFilePath, QLatin1String("QtCreatorToolChains"));
+
+ return true;
+}
+
+bool RegisterToolChainOperation::undoOperation()
+{
+ return true;
+}
+
+bool RegisterToolChainOperation::testOperation()
+{
+ return true;
+}
+
+KDUpdater::UpdateOperation* RegisterToolChainOperation::clone() const
+{
+ return new RegisterToolChainOperation();
+}
diff --git a/installerbuilder/libinstaller/registertoolchainoperation.h b/installerbuilder/libinstaller/registertoolchainoperation.h
new file mode 100644
index 000000000..4fce9bc7a
--- /dev/null
+++ b/installerbuilder/libinstaller/registertoolchainoperation.h
@@ -0,0 +1,65 @@
+/**************************************************************************
+**
+** This file is part of Qt SDK**
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).*
+**
+** Contact: Nokia Corporation qt-info@nokia.com**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception version
+** 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you are unsure which license is appropriate for your use, please contact
+** (qt-info@nokia.com).
+**
+**************************************************************************/
+#ifndef REGISTERTOOLCHAINOPERATION_H
+#define REGISTERTOOLCHAINOPERATION_H
+
+#include <KDUpdater/UpdateOperation>
+
+namespace QInstaller {
+
+/** Arguments:
+ * SDK Path - to find the QtCreator installation
+ * ToolChainKey - is the internal QtCreator settings key usually: GccToolChain
+ * toolchain type - where this toolchain is defined in QtCreator
+ * ProjectExplorer.ToolChain.Gcc ProjectExplorer.ToolChain.Mingw
+ * ProjectExplorer.ToolChain.LinuxIcc ProjectExplorer.ToolChain.Msvc
+ * Qt4ProjectManager.ToolChain.GCCE Qt4ProjectManager.ToolChain.Maemo
+ * display name - the name how it will be displayed in QtCreator
+ * application binary interface - this is an internal creator typ as a String CPU-OS-OS_FLAVOR-BINARY_FORMAT-WORD_WIDTH
+ * CPU: arm x86 mips ppc itanium
+ * OS: linux macos symbian unix windows
+ * OS_FLAVOR: generic maemo meego generic device emulator generic msvc2005 msvc2008 msvc2010 msys ce
+ * BINARY_FORMAT: elf pe mach_o qml_rt
+ * WORD_WIDTH: 8 16 32 64
+ * compiler path - the binary which is used as the compiler
+ * debugger path - the binary which is used as the debugger
+ */
+class RegisterToolChainOperation : public KDUpdater::UpdateOperation
+{
+public:
+ RegisterToolChainOperation();
+ ~RegisterToolChainOperation();
+
+ void backup();
+ bool performOperation();
+ bool undoOperation();
+ bool testOperation();
+ KDUpdater::UpdateOperation* clone() const;
+};
+
+}; // namespace
+
+#endif // REGISTERTOOLCHAINOPERATION_H