summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Jenssen <tim.jenssen@digia.com>2013-08-26 12:24:11 +0200
committerTim Jenssen <tim.jenssen@digia.com>2013-08-26 12:24:11 +0200
commitd8d93f85d6362e8cfb24a076e3df0504cb93957f (patch)
tree898b5580dab6ce76d1fea05a723416bee2feeed6
parentcf7efd742ff29f932beb8f20b8b6e8ed4cac141b (diff)
parentf84cbe8da86dac7daf75cacbb3b68127bdff761a (diff)
Merge remote-tracking branch 'origin/1.4'
-rw-r--r--3RDPARTY38
-rw-r--r--Changelog5
-rw-r--r--dist/config/config.xml4
-rw-r--r--dist/packages/org.qtproject.ifw.binaries/meta/package.xml4
-rw-r--r--dist/packages/org.qtproject.ifw/meta/3RDPARTY26
-rw-r--r--dist/packages/org.qtproject.ifw/meta/package.xml5
-rw-r--r--doc/installerfw.qdoc13
-rw-r--r--doc/scripting.qdoc6
-rw-r--r--doc/tutorial.qdoc4
-rw-r--r--examples/changeuserinterface/config/config.xml2
-rw-r--r--examples/modifyextract/config/config.xml2
-rw-r--r--examples/quit_installer/config/config.xml2
-rw-r--r--examples/registerfileextension/config/config.xml2
-rw-r--r--examples/startmenu/config/config.xml2
-rw-r--r--examples/tutorial/config/config.xml2
-rw-r--r--installerfw.pri1
-rw-r--r--src/libs/installer/binaryformat.cpp8
-rw-r--r--src/libs/installer/component.cpp33
-rw-r--r--src/libs/installer/component.h4
-rw-r--r--src/libs/installer/component_p.h6
-rw-r--r--src/libs/installer/componentmodel.cpp15
-rw-r--r--src/libs/installer/extractarchiveoperation_p.h8
-rw-r--r--src/libs/installer/fsengineclient.cpp12
-rw-r--r--src/libs/installer/getrepositoriesmetainfojob.cpp18
-rw-r--r--src/libs/installer/getrepositoriesmetainfojob.h6
-rw-r--r--src/libs/installer/getrepositorymetainfojob.cpp33
-rw-r--r--src/libs/installer/getrepositorymetainfojob.h6
-rw-r--r--src/libs/installer/graph.h158
-rw-r--r--src/libs/installer/installer.pro3
-rw-r--r--src/libs/installer/installiconsoperation.cpp47
-rw-r--r--src/libs/installer/macreplaceinstallnamesoperation.cpp3
-rw-r--r--src/libs/installer/packagemanagercore.cpp78
-rw-r--r--src/libs/installer/packagemanagercore.h10
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp83
-rw-r--r--src/libs/installer/packagemanagercore_p.h1
-rw-r--r--src/libs/installer/packagemanagercoredata.cpp2
-rw-r--r--src/libs/installer/packagemanagergui.cpp69
-rw-r--r--src/libs/installer/packagemanagergui.h1
-rw-r--r--src/libs/installer/productkeycheck.cpp7
-rw-r--r--src/libs/installer/productkeycheck.h4
-rw-r--r--src/libs/installer/qtpatchoperation.cpp104
-rw-r--r--src/libs/installer/scriptengine.cpp2
-rw-r--r--src/libs/kdtools/kdupdaterupdatesinfo.cpp3
-rw-r--r--src/sdk/installerbase.cpp22
-rw-r--r--src/sdk/installerbase.qrc2
-rw-r--r--src/sdk/installerbasecommons.cpp5
-rw-r--r--src/sdk/sdk.pro4
-rw-r--r--src/sdk/settingsdialog.cpp8
-rw-r--r--src/sdk/translations/de_de.ts2
-rw-r--r--src/sdk/translations/ja_jp.ts2470
-rw-r--r--src/src.pro2
-rw-r--r--tests/auto/installer/installer.pro4
-rw-r--r--tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp36
-rw-r--r--tests/auto/installer/solver/solver.pro5
-rw-r--r--tests/auto/installer/solver/tst_solver.cpp134
-rw-r--r--tools/binarycreator/binarycreator.cpp4
-rw-r--r--tools/common/repositorygen.cpp33
-rw-r--r--tools/common/repositorygen.h2
-rw-r--r--tools/repogen/repogen.cpp8
59 files changed, 3336 insertions, 247 deletions
diff --git a/3RDPARTY b/3RDPARTY
index 485d3aeee..58b055221 100644
--- a/3RDPARTY
+++ b/3RDPARTY
@@ -2,30 +2,16 @@ The Qt Installer Framework sources include third party code:
============================================================
-P7zip
+LZMA SDK
-Sources for p7zip are under src/libs/7zip/unix. The library
-is released under the GNU LGPL with unRAR restriction. See
-src/libs/7zip/unix/DOCS/License.txt for details. The folder
-contains also parts of Wine, which is distributed under the
-LGPL 2.1 or newer.
+Parts of the sources from the LZMA SDK , version 9.20 are
+under src/libs/7zip/unix and src/libs/7z/win.
-The copyright of the 7z is owned by Igor Pavlov, the
-copyright of the original unRAR code is owned by Alexander
-Roshal.
-
-============================================================
-
-7zip
-
-Sources for p7zip are under src/libs/7zip/win.
-
-The library is released under the GNU LGPL with unRAR restriction.
-See src/libs/7zip/win/DOC/License.txt for details.
-
-The copyright of the 7z is owned by Igor Pavlov, the
-copyright of the original unRAR code is owned by Alexander
-Roshal.
+The LZMA SDK is written and placed in the public domain by
+Igor Pavlov. Some code in LZMA SDK is based on public domain
+code from another developers:
+1) PPMd var.H (2001): Dmitry Shkarin
+2) SHA-256: Wei Dai (Crypto++ library)
============================================================
@@ -33,8 +19,8 @@ KD Tools
Sources for the KD Tools library are under src/libs/kdtools.
-The library is licensed under LGPL 2, LGPL 3, and a commercial
-KD Tools license.
+The library is released under the same license as the rest
+of the installer framework (GPL 3.0/LGPL 2.1 with Digia
+exception/Digia Commercial License).
-The copyright is owned by Klaralvdalens
-Datakonsult AB.
+The copyright is owned by Klaralvdalens Datakonsult AB.
diff --git a/Changelog b/Changelog
index 581fc020a..5cb1418c8 100644
--- a/Changelog
+++ b/Changelog
@@ -1,4 +1,9 @@
1.4
+- Force updating of Essential components. (QTIFW-38, QTIFW-155)
+- Display release date in Updater and Packagemanager. (QTIFW-25)
+- Fixed a crash in the package manager. (QTIFW-313)
+- Fixed component selection showing wrong package sizes. (QTIFW-302)
+- Better handling of dependencies while updating. (QTIFW-318)
- Now allows to ignore SSL errors.
- Implemented dedicated translation settings support.
- Added exceptionhandler code for connected signals/JS methods.
diff --git a/dist/config/config.xml b/dist/config/config.xml
index e2b408e2a..5824b9d8f 100644
--- a/dist/config/config.xml
+++ b/dist/config/config.xml
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<Installer>
<Name>Qt Installer Framework</Name>
- <Title>Qt Installer Framework 1.3.0</Title>
+ <Title>Qt Installer Framework 1.4.0</Title>
<Version>1.0.0</Version>
<Publisher>Qt Project</Publisher>
<ProductUrl>http://qt-project.org</ProductUrl>
@@ -9,5 +9,5 @@
<UninstallerName>Uninstaller</UninstallerName>
<!-- Tweaked for windows in installscript.qs -->
- <TargetDir>@homeDir@/Qt/QtIFW-1.3.0</TargetDir>
+ <TargetDir>@homeDir@/Qt/QtIFW-1.4.0</TargetDir>
</Installer>
diff --git a/dist/packages/org.qtproject.ifw.binaries/meta/package.xml b/dist/packages/org.qtproject.ifw.binaries/meta/package.xml
index edfb30e7f..a7954497f 100644
--- a/dist/packages/org.qtproject.ifw.binaries/meta/package.xml
+++ b/dist/packages/org.qtproject.ifw.binaries/meta/package.xml
@@ -2,7 +2,7 @@
<Package>
<DisplayName>Qt Installer Framework Binaries</DisplayName>
<Description>Installs the binaries, examples and help files.</Description>
- <Version>1.3.0</Version>
- <ReleaseDate>2013-03-21</ReleaseDate>
+ <Version>1.4.0</Version>
+ <ReleaseDate>2013-07-03</ReleaseDate>
<Default>True</Default>
</Package>
diff --git a/dist/packages/org.qtproject.ifw/meta/3RDPARTY b/dist/packages/org.qtproject.ifw/meta/3RDPARTY
new file mode 100644
index 000000000..58b055221
--- /dev/null
+++ b/dist/packages/org.qtproject.ifw/meta/3RDPARTY
@@ -0,0 +1,26 @@
+The Qt Installer Framework sources include third party code:
+
+============================================================
+
+LZMA SDK
+
+Parts of the sources from the LZMA SDK , version 9.20 are
+under src/libs/7zip/unix and src/libs/7z/win.
+
+The LZMA SDK is written and placed in the public domain by
+Igor Pavlov. Some code in LZMA SDK is based on public domain
+code from another developers:
+1) PPMd var.H (2001): Dmitry Shkarin
+2) SHA-256: Wei Dai (Crypto++ library)
+
+============================================================
+
+KD Tools
+
+Sources for the KD Tools library are under src/libs/kdtools.
+
+The library is released under the same license as the rest
+of the installer framework (GPL 3.0/LGPL 2.1 with Digia
+exception/Digia Commercial License).
+
+The copyright is owned by Klaralvdalens Datakonsult AB.
diff --git a/dist/packages/org.qtproject.ifw/meta/package.xml b/dist/packages/org.qtproject.ifw/meta/package.xml
index 8f3e0e814..dedb672df 100644
--- a/dist/packages/org.qtproject.ifw/meta/package.xml
+++ b/dist/packages/org.qtproject.ifw/meta/package.xml
@@ -2,11 +2,12 @@
<Package>
<DisplayName>Qt Installer Framework</DisplayName>
<Description>Installs the Qt Installer Framework.</Description>
- <Version>1.3.0</Version>
- <ReleaseDate>2013-03-21</ReleaseDate>
+ <Version>1.4.0</Version>
+ <ReleaseDate>2013-07-03</ReleaseDate>
<Licenses>
<License name="LGPL 2.1" file="LICENSE.LGPL" />
<License name="Digial Qt LGPL Exception 1.1" file="LGPL_EXCEPTION.txt" />
+ <License name="Third Party Code Licenses" file="3RDPARTY" />
</Licenses>
<Script>installscript.qs</Script>
</Package>
diff --git a/doc/installerfw.qdoc b/doc/installerfw.qdoc
index 5b527d03c..682bca95a 100644
--- a/doc/installerfw.qdoc
+++ b/doc/installerfw.qdoc
@@ -485,6 +485,8 @@
\o Default
\o Possible values are: \c true, \c false, and \c script. Set to
\c true to preselect the component in the installer.
+ This takes effect only on components that have no visible
+ child components.
The boolean values are evaluated directly, while \c script is
resolved during runtime. Add the name of the script as a value
of the \c Script setting in this file. For an example script,
@@ -493,7 +495,10 @@
\o Essential
\o Marks the package as essential to force a restart of the
\c UpdateAgent or \c MaintenanceTool. This is relevant for
- updates found with \c UpdateAgent.
+ updates found with \c UpdateAgent. If there are updates available
+ for an essential component, the package manager stays disabled
+ until that component is updated. Newly introduced essential components
+ are automatically installed when running the updater.
\row
\o ForcedInstallation
\o Determines that the package must always be installed. End users
@@ -504,7 +509,11 @@
\row
\o DownloadableArchives
- \o Lists the data files (separated by commas) for an online installer to download. Optional.
+ \o Lists the data files (separated by commas) for an online
+ installer to download.
+ If there is some data inside the component and the package.xml
+ and/or the script has no DownloadableArchives value, the
+ repogen tool registers the found data automatically.
\endtable
\section2 Component Dependencies
diff --git a/doc/scripting.qdoc b/doc/scripting.qdoc
index d0094575c..38fced90e 100644
--- a/doc/scripting.qdoc
+++ b/doc/scripting.qdoc
@@ -246,6 +246,12 @@
\row
\o os
\o Current platform: \c "x11", \c "win", or \c "mac".
+ \row
+ \o RootDir
+ \o Root directory of the filesystem.
+ \row
+ \o HomeDir
+ \o Home directory of the current user.
\endtable
The variables can be resolved by calls to \c installer.value(). If embedded
diff --git a/doc/tutorial.qdoc b/doc/tutorial.qdoc
index f4d537e49..1531922c7 100644
--- a/doc/tutorial.qdoc
+++ b/doc/tutorial.qdoc
@@ -188,6 +188,10 @@
\endlist
+ \note You have to either call \c lrelease on the included .ts file before building
+ the installer or add \c --ignore-translations as a parameter to the binarycreator
+ call.
+
The installer is created in the current directory and you can deliver it to
end users.
diff --git a/examples/changeuserinterface/config/config.xml b/examples/changeuserinterface/config/config.xml
index cf9eb26f7..c00f6c705 100644
--- a/examples/changeuserinterface/config/config.xml
+++ b/examples/changeuserinterface/config/config.xml
@@ -5,5 +5,5 @@
<Title>Change installer UI Example</Title>
<Publisher>Qt-Project</Publisher>
<StartMenuDir>Change installer UI Example</StartMenuDir>
- <TargetDir>@homeDir@/IFWChangeInstallerUIExample</TargetDir>
+ <TargetDir>@HomeDir@/IFWChangeInstallerUIExample</TargetDir>
</Installer>
diff --git a/examples/modifyextract/config/config.xml b/examples/modifyextract/config/config.xml
index bb2c18ce4..2f365dbcc 100644
--- a/examples/modifyextract/config/config.xml
+++ b/examples/modifyextract/config/config.xml
@@ -5,5 +5,5 @@
<Title>Modify extract Installer Example</Title>
<Publisher>Qt-Project</Publisher>
<StartMenuDir>Qt Installer Framework Example</StartMenuDir>
- <TargetDir>@homeDir@/IFWModifyExtractInstallerExample</TargetDir>
+ <TargetDir>@HomeDir@/IFWModifyExtractInstallerExample</TargetDir>
</Installer>
diff --git a/examples/quit_installer/config/config.xml b/examples/quit_installer/config/config.xml
index a38254d30..36717025c 100644
--- a/examples/quit_installer/config/config.xml
+++ b/examples/quit_installer/config/config.xml
@@ -5,5 +5,5 @@
<Title>Quit Installer Example</Title>
<Publisher>Qt-Project</Publisher>
<StartMenuDir>Qt Installer Framework Example</StartMenuDir>
- <TargetDir>@homeDir@/IFWQuitInstallerExample</TargetDir>
+ <TargetDir>@HomeDir@/IFWQuitInstallerExample</TargetDir>
</Installer>
diff --git a/examples/registerfileextension/config/config.xml b/examples/registerfileextension/config/config.xml
index 6e6db7843..fbc5e3b79 100644
--- a/examples/registerfileextension/config/config.xml
+++ b/examples/registerfileextension/config/config.xml
@@ -5,5 +5,5 @@
<Title>Register File Extension Example</Title>
<Publisher>Qt-Project</Publisher>
<StartMenuDir>Register File Extension Example</StartMenuDir>
- <TargetDir>@homeDir@/IFWRegisterFileExtensionExample</TargetDir>
+ <TargetDir>@HomeDir@/IFWRegisterFileExtensionExample</TargetDir>
</Installer>
diff --git a/examples/startmenu/config/config.xml b/examples/startmenu/config/config.xml
index 9a06186d3..e95445d1b 100644
--- a/examples/startmenu/config/config.xml
+++ b/examples/startmenu/config/config.xml
@@ -6,5 +6,5 @@
<Publisher>Qt-Project</Publisher>
<!-- Directory name is used in component.xml -->
<StartMenuDir>Qt Installer Framework Example</StartMenuDir>
- <TargetDir>@homeDir@/IFWStartMenuExample</TargetDir>
+ <TargetDir>@HomeDir@/IFWStartMenuExample</TargetDir>
</Installer>
diff --git a/examples/tutorial/config/config.xml b/examples/tutorial/config/config.xml
index 235434776..6ffb2e3e8 100644
--- a/examples/tutorial/config/config.xml
+++ b/examples/tutorial/config/config.xml
@@ -5,5 +5,5 @@
<Title>Your application Installer</Title>
<Publisher>Your vendor</Publisher>
<StartMenuDir>Super App</StartMenuDir>
- <TargetDir>@rootDir@InstallationDirectory</TargetDir>
+ <TargetDir>@RootDir@InstallationDirectory</TargetDir>
</Installer>
diff --git a/installerfw.pri b/installerfw.pri
index 84dd58b13..ad559c410 100644
--- a/installerfw.pri
+++ b/installerfw.pri
@@ -100,6 +100,7 @@ CONFIG += depend_includepath
GIT_SHA1 = $$system(git rev-list --abbrev-commit -n1 HEAD)
DEFINES += QT_NO_CAST_FROM_ASCII "_GIT_SHA1_=$$GIT_SHA1" IFW_VERSION=$$IFW_VERSION
+DEFINES += IFW_REPOSITORY_FORMAT_VERSION=$$IFW_REPOSITORY_FORMAT_VERSION
static {
LIBS += -l7z
diff --git a/src/libs/installer/binaryformat.cpp b/src/libs/installer/binaryformat.cpp
index c6562f333..1d257a1b4 100644
--- a/src/libs/installer/binaryformat.cpp
+++ b/src/libs/installer/binaryformat.cpp
@@ -853,7 +853,15 @@ BinaryContent BinaryContent::readAndRegisterFromBinary(const QString &path)
*/
BinaryContent BinaryContent::readFromApplicationFile()
{
+#ifdef Q_OS_MAC
+ // On Mac, data is always in a separate file so that the binary can be signed
+ QDir dataPath(QCoreApplication::applicationFilePath());
+ dataPath.cdUp();
+ dataPath.cd(QLatin1String("Resources"));
+ return BinaryContent::readFromBinary(dataPath.filePath(QLatin1String("installer.dat")));
+#else
return BinaryContent::readFromBinary(QCoreApplication::applicationFilePath());
+#endif
}
/*!
diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp
index 5889c67ce..0ac69aaf8 100644
--- a/src/libs/installer/component.cpp
+++ b/src/libs/installer/component.cpp
@@ -275,8 +275,8 @@ void Component::loadDataFromPackage(const Package &package)
setValue(scDescription, package.data(scDescription).toString());
setValue(scDefault, package.data(scDefault).toString());
setValue(scAutoDependOn, package.data(scAutoDependOn).toString());
- setValue(scCompressedSize, QString::number(0));
- setValue(scUncompressedSize, QString::number(0));
+ setValue(scCompressedSize, package.data(scCompressedSize).toString());
+ setValue(scUncompressedSize, package.data(scUncompressedSize).toString());
setValue(scRemoteVersion, package.data(scRemoteVersion).toString());
setValue(scInheritVersion, package.data(scInheritVersion).toString());
setValue(scDependencies, package.data(scDependencies).toString());
@@ -948,7 +948,7 @@ bool Component::operationsCreatedSuccessfully() const
return d->m_operationsCreatedSuccessfully;
}
-Operation *Component::createOperation(const QString &operation, const QString &parameter1,
+Operation *Component::createOperation(const QString &operationName, const QString &parameter1,
const QString &parameter2, const QString &parameter3, const QString &parameter4, const QString &parameter5,
const QString &parameter6, const QString &parameter7, const QString &parameter8, const QString &parameter9,
const QString &parameter10)
@@ -975,29 +975,29 @@ Operation *Component::createOperation(const QString &operation, const QString &p
if (!parameter10.isNull())
arguments.append(parameter10);
- return createOperation(operation, arguments);
+ return createOperation(operationName, arguments);
}
-Operation *Component::createOperation(const QString &operation, const QStringList &parameters)
+Operation *Component::createOperation(const QString &operationName, const QStringList &parameters)
{
- Operation *op = KDUpdater::UpdateOperationFactory::instance().create(operation);
- if (op == 0) {
+ Operation *operation = KDUpdater::UpdateOperationFactory::instance().create(operationName);
+ if (operation == 0) {
const QMessageBox::StandardButton button =
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
QLatin1String("OperationDoesNotExistError"), tr("Error"), tr("Error: Operation %1 does not exist")
- .arg(operation), QMessageBox::Abort | QMessageBox::Ignore);
+ .arg(operationName), QMessageBox::Abort | QMessageBox::Ignore);
if (button == QMessageBox::Abort)
d->m_operationsCreatedSuccessfully = false;
- return op;
+ return operation;
}
- if (op->name() == QLatin1String("Delete"))
- op->setValue(QLatin1String("performUndo"), false);
- op->setValue(QLatin1String("installer"), qVariantFromValue(d->m_core));
+ if (operation->name() == QLatin1String("Delete"))
+ operation->setValue(QLatin1String("performUndo"), false);
+ operation->setValue(QLatin1String("installer"), qVariantFromValue(d->m_core));
- op->setArguments(d->m_core->replaceVariables(parameters));
-
- return op;
+ operation->setArguments(d->m_core->replaceVariables(parameters));
+ operation->setValue(QLatin1String("component"), name());
+ return operation;
}
/*!
@@ -1404,6 +1404,9 @@ void Component::updateModelData(const QString &key, const QString &data)
if (key == scDisplayVersion)
setData(data, LocalDisplayVersion);
+ if (key == scReleaseDate)
+ setData(data, ReleaseDate);
+
if (key == scUncompressedSize) {
quint64 size = d->m_vars.value(scUncompressedSizeSum).toLongLong();
setData(humanReadableSize(size), UncompressedSize);
diff --git a/src/libs/installer/component.h b/src/libs/installer/component.h
index bf5ef4d18..eefe41ebb 100644
--- a/src/libs/installer/component.h
+++ b/src/libs/installer/component.h
@@ -233,13 +233,13 @@ private Q_SLOTS:
private:
void setLocalTempPath(const QString &tempPath);
- Operation *createOperation(const QString &operation, const QString &parameter1 = QString(),
+ Operation *createOperation(const QString &operationName, const QString &parameter1 = QString(),
const QString &parameter2 = QString(), const QString &parameter3 = QString(),
const QString &parameter4 = QString(), const QString &parameter5 = QString(),
const QString &parameter6 = QString(), const QString &parameter7 = QString(),
const QString &parameter8 = QString(), const QString &parameter9 = QString(),
const QString &parameter10 = QString());
- Operation *createOperation(const QString &operation, const QStringList &parameters);
+ Operation *createOperation(const QString &operationName, const QStringList &parameters);
private:
QString validatorCallbackName;
diff --git a/src/libs/installer/component_p.h b/src/libs/installer/component_p.h
index 1f81ffd4d..1da9eee1a 100644
--- a/src/libs/installer/component_p.h
+++ b/src/libs/installer/component_p.h
@@ -99,14 +99,16 @@ class INSTALLER_EXPORT ComponentModelHelper
public:
enum Roles {
LocalDisplayVersion = Qt::UserRole + 1,
- RemoteDisplayVersion = LocalDisplayVersion + 1,
- UncompressedSize = RemoteDisplayVersion + 1
+ RemoteDisplayVersion,
+ ReleaseDate,
+ UncompressedSize
};
enum Column {
NameColumn = 0,
InstalledVersionColumn,
NewVersionColumn,
+ ReleaseDateColumn,
UncompressedSizeColumn
};
diff --git a/src/libs/installer/componentmodel.cpp b/src/libs/installer/componentmodel.cpp
index f65611ffe..080e84d85 100644
--- a/src/libs/installer/componentmodel.cpp
+++ b/src/libs/installer/componentmodel.cpp
@@ -324,10 +324,17 @@ void ComponentModel::setRootComponents(QList<QInstaller::Component*> rootCompone
m_uncheckable.clear();
m_indexByNameCache.clear();
- m_initialCheckedState.clear();
- m_currentCheckedState.clear();
+ m_rootComponentList.clear();
m_modelState = DefaultChecked;
+ // Initialize these with an empty set for every possible state, cause we compare the hashes later in
+ // updateAndEmitModelState(). The comparison than might lead to wrong results if one of the checked
+ // states is absent initially.
+ m_initialCheckedState[Qt::Checked] = ComponentSet();
+ m_initialCheckedState[Qt::Unchecked] = ComponentSet();
+ m_initialCheckedState[Qt::PartiallyChecked] = ComponentSet();
+ m_currentCheckedState = m_initialCheckedState; // both should be equal
+
// show virtual components only in case we run as updater or if the core engine is set to show them
const bool showVirtuals = m_core->isUpdater() || m_core->virtualComponentsVisible();
foreach (Component *const component, rootComponents) {
@@ -519,6 +526,10 @@ QSet<QModelIndex> ComponentModel::updateCheckedState(const ComponentSet &compone
break;
}
}
+
+ // update all nodes uncompressed size
+ foreach (Component *const node, m_rootComponentList)
+ node->updateUncompressedSize(); // this is a recursive call
return changed;
}
diff --git a/src/libs/installer/extractarchiveoperation_p.h b/src/libs/installer/extractarchiveoperation_p.h
index 44e75a949..4e0632830 100644
--- a/src/libs/installer/extractarchiveoperation_p.h
+++ b/src/libs/installer/extractarchiveoperation_p.h
@@ -117,9 +117,11 @@ public Q_SLOTS:
case PackageManagerCore::Failure:
state = E_FAIL;
break;
- case PackageManagerCore::Unfinished: // fall through
- case PackageManagerCore::Success:
- case PackageManagerCore::Running:
+ default: // fall through
+ // PackageManagerCore::Unfinished, PackageManagerCore::Success, PackageManagerCore::Running
+ // PackageManagerCore::ForceUpdate
+
+ // already set
//state = S_OK;
break;
}
diff --git a/src/libs/installer/fsengineclient.cpp b/src/libs/installer/fsengineclient.cpp
index 169b1e67b..2a7a8a5bd 100644
--- a/src/libs/installer/fsengineclient.cpp
+++ b/src/libs/installer/fsengineclient.cpp
@@ -44,6 +44,8 @@
#include "adminauthorization.h"
#include "messageboxhandler.h"
+#include <QElapsedTimer>
+
#include <QtCore/QCoreApplication>
#include <QtCore/QMutex>
#include <QtCore/QProcess>
@@ -809,8 +811,14 @@ void FSEngineClientHandler::Private::maybeStartServer()
}
if (serverStarted) {
- QTcpSocket s; // now wait for the socket to arrive
- serverStarted = FSEngineClientHandler::instance().connect(&s);
+ QElapsedTimer t;
+ t.start();
+ while (serverStarting && serverStarted
+ && t.elapsed() < 30000) { // 30 seconds ought to be enough for the app to start
+ QTcpSocket s;
+ if (FSEngineClientHandler::instance().connect(&s))
+ serverStarting = false;
+ }
}
serverStarting = false;
}
diff --git a/src/libs/installer/getrepositoriesmetainfojob.cpp b/src/libs/installer/getrepositoriesmetainfojob.cpp
index 99b7e4340..c4564e781 100644
--- a/src/libs/installer/getrepositoriesmetainfojob.cpp
+++ b/src/libs/installer/getrepositoriesmetainfojob.cpp
@@ -42,6 +42,7 @@
#include "getrepositoriesmetainfojob.h"
#include "getrepositorymetainfojob.h"
+#include "productkeycheck.h"
#include "packagemanagercore_p.h"
#include <QtCore/QDebug>
@@ -52,12 +53,12 @@ using namespace QInstaller;
// -- GetRepositoriesMetaInfoJob
-GetRepositoriesMetaInfoJob::GetRepositoriesMetaInfoJob(PackageManagerCorePrivate *corePrivate)
- : KDJob(corePrivate)
+GetRepositoriesMetaInfoJob::GetRepositoriesMetaInfoJob(PackageManagerCore *core)
+ : KDJob(core)
, m_canceled(false)
, m_silentRetries(3)
, m_haveIgnoredError(false)
- , m_corePrivate(corePrivate)
+ , m_core(core)
{
setCapabilities(Cancelable);
}
@@ -118,10 +119,11 @@ bool GetRepositoriesMetaInfoJob::isCanceled() const
void GetRepositoriesMetaInfoJob::doStart()
{
- if ((m_corePrivate->isInstaller() && !m_corePrivate->isOfflineOnly())
- || (m_corePrivate->isUpdater() || m_corePrivate->isPackageManager())) {
- foreach (const Repository &repo, m_corePrivate->m_data.settings().repositories()) {
- if (repo.isEnabled())
+ if ((m_core->isInstaller() && !m_core->isOfflineOnly()) || (m_core->isUpdater()
+ || m_core->isPackageManager())) {
+ const ProductKeyCheck *const productKeyCheck = ProductKeyCheck::instance(m_core);
+ foreach (const Repository &repo, m_core->settings().repositories()) {
+ if (repo.isEnabled() && productKeyCheck->isValidRepository(repo))
m_repositories += repo;
}
}
@@ -156,7 +158,7 @@ void GetRepositoriesMetaInfoJob::fetchNextRepo()
return;
}
- m_job = new GetRepositoryMetaInfoJob(m_corePrivate, this);
+ m_job = new GetRepositoryMetaInfoJob(m_core, this);
connect(m_job, SIGNAL(finished(KDJob*)), this, SLOT(jobFinished(KDJob*)));
connect(m_job, SIGNAL(infoMessage(KDJob*, QString)), this, SIGNAL(infoMessage(KDJob*, QString)));
diff --git a/src/libs/installer/getrepositoriesmetainfojob.h b/src/libs/installer/getrepositoriesmetainfojob.h
index aa381e3a4..2cc53b82a 100644
--- a/src/libs/installer/getrepositoriesmetainfojob.h
+++ b/src/libs/installer/getrepositoriesmetainfojob.h
@@ -59,14 +59,14 @@ namespace KDUpdater {
namespace QInstaller {
class GetRepositoryMetaInfoJob;
-class PackageManagerCorePrivate;
+class PackageManagerCore;
class INSTALLER_EXPORT GetRepositoriesMetaInfoJob : public KDJob
{
Q_OBJECT
public:
- explicit GetRepositoriesMetaInfoJob(PackageManagerCorePrivate *corePrivate);
+ explicit GetRepositoriesMetaInfoJob(PackageManagerCore *core);
QStringList temporaryDirectories() const;
QStringList releaseTemporaryDirectories() const;
@@ -91,7 +91,7 @@ private:
bool m_canceled;
int m_silentRetries;
bool m_haveIgnoredError;
- PackageManagerCorePrivate *m_corePrivate;
+ PackageManagerCore *m_core;
QString m_errorString;
QList<Repository> m_repositories;
diff --git a/src/libs/installer/getrepositorymetainfojob.cpp b/src/libs/installer/getrepositorymetainfojob.cpp
index 6913a63e5..1c8d07525 100644
--- a/src/libs/installer/getrepositorymetainfojob.cpp
+++ b/src/libs/installer/getrepositorymetainfojob.cpp
@@ -111,14 +111,14 @@ private:
// -- GetRepositoryMetaInfoJob
-GetRepositoryMetaInfoJob::GetRepositoryMetaInfoJob(PackageManagerCorePrivate *corePrivate, QObject *parent)
+GetRepositoryMetaInfoJob::GetRepositoryMetaInfoJob(PackageManagerCore *core, QObject *parent)
: KDJob(parent)
, m_canceled(false)
, m_silentRetries(4)
, m_retriesLeft(m_silentRetries)
, m_downloader(0)
, m_waitForDone(false)
- , m_corePrivate(corePrivate)
+ , m_core(core)
{
setCapabilities(Cancelable);
}
@@ -331,12 +331,11 @@ void GetRepositoryMetaInfoJob::updatesXmlDownloadFinished()
}
if (!repositoryUpdates.isEmpty()) {
- if (m_corePrivate->m_data.settings().updateDefaultRepositories(repositoryUpdates)
- == Settings::UpdatesApplied) {
- if (m_corePrivate->isUpdater() || m_corePrivate->isPackageManager())
- m_corePrivate->writeMaintenanceConfigFiles();
- finished(QInstaller::RepositoryUpdatesReceived, tr("Repository updates received."));
- return;
+ if (m_core->settings().updateDefaultRepositories(repositoryUpdates) == Settings::UpdatesApplied) {
+ if (m_core->isUpdater() || m_core->isPackageManager())
+ m_core->writeMaintenanceConfigFiles();
+ finished(QInstaller::RepositoryUpdatesReceived, tr("Repository updates received."));
+ return;
}
}
}
@@ -538,26 +537,26 @@ void GetRepositoryMetaInfoJob::onAuthenticatorChanged(const QAuthenticator &auth
const QString username = authenticator.user();
const QString password = authenticator.password();
if (username != m_repository.username() || password != m_repository.password()) {
- QSet<Repository> repositories = m_corePrivate->m_data.settings().defaultRepositories();
+ QSet<Repository> repositories = m_core->settings().defaultRepositories();
bool reposChanged = updateRepositories(&repositories, username, password);
if (reposChanged)
- m_corePrivate->m_data.settings().setDefaultRepositories(repositories);
+ m_core->settings().setDefaultRepositories(repositories);
- repositories = m_corePrivate->m_data.settings().temporaryRepositories();
+ repositories = m_core->settings().temporaryRepositories();
reposChanged |= updateRepositories(&repositories, username, password);
if (reposChanged) {
- m_corePrivate->m_data.settings().setTemporaryRepositories(repositories,
- m_corePrivate->m_data.settings().hasReplacementRepos());
+ m_core->settings().setTemporaryRepositories(repositories,
+ m_core->settings().hasReplacementRepos());
}
- repositories = m_corePrivate->m_data.settings().userRepositories();
+ repositories = m_core->settings().userRepositories();
reposChanged |= updateRepositories(&repositories, username, password);
if (reposChanged)
- m_corePrivate->m_data.settings().setUserRepositories(repositories);
+ m_core->settings().setUserRepositories(repositories);
if (reposChanged) {
- if (m_corePrivate->isUpdater() || m_corePrivate->isPackageManager())
- m_corePrivate->writeMaintenanceConfigFiles();
+ if (m_core->isUpdater() || m_core->isPackageManager())
+ m_core->writeMaintenanceConfigFiles();
finished(QInstaller::RepositoryUpdatesReceived, tr("Repository updates received."));
}
}
diff --git a/src/libs/installer/getrepositorymetainfojob.h b/src/libs/installer/getrepositorymetainfojob.h
index 8601742a2..803f8b43f 100644
--- a/src/libs/installer/getrepositorymetainfojob.h
+++ b/src/libs/installer/getrepositorymetainfojob.h
@@ -61,7 +61,7 @@ namespace KDUpdater {
namespace QInstaller {
class GetRepositoriesMetaInfoJob;
-class PackageManagerCorePrivate;
+class PackageManagerCore;
class INSTALLER_EXPORT GetRepositoryMetaInfoJob : public KDJob
{
@@ -70,7 +70,7 @@ class INSTALLER_EXPORT GetRepositoryMetaInfoJob : public KDJob
friend class QInstaller::GetRepositoriesMetaInfoJob;
public:
- explicit GetRepositoryMetaInfoJob(PackageManagerCorePrivate *corePrivate, QObject *parent = 0);
+ explicit GetRepositoryMetaInfoJob(PackageManagerCore *core, QObject *parent = 0);
~GetRepositoryMetaInfoJob();
Repository repository() const;
@@ -119,7 +119,7 @@ private:
bool m_waitForDone;
QThreadPool m_threadPool;
- PackageManagerCorePrivate *m_corePrivate;
+ PackageManagerCore *m_core;
};
} // namespace QInstaller
diff --git a/src/libs/installer/graph.h b/src/libs/installer/graph.h
new file mode 100644
index 000000000..59778a440
--- /dev/null
+++ b/src/libs/installer/graph.h
@@ -0,0 +1,158 @@
+/**************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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.
+**
+** 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, 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.
+**
+** 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$
+**
+**************************************************************************/
+
+#ifndef GRAPH_H
+#define GRAPH_H
+
+#include <QHash>
+#include <QList>
+#include <QPair>
+#include <QSet>
+
+namespace QInstaller {
+
+template <class T> class Graph
+{
+public:
+ inline Graph() {}
+ explicit Graph(const QList<T> &nodes)
+ {
+ addNodes(nodes);
+ }
+
+ const QList<T> nodes() const
+ {
+ return m_graph.keys();
+ }
+
+ void addNode(const T &node)
+ {
+ m_graph.insert(node, QSet<T>());
+ }
+
+ void addNodes(const QList<T> &nodes)
+ {
+ foreach (const T &node, nodes)
+ addNode(node);
+ }
+
+ QList<T> edges(const T &node) const
+ {
+ return m_graph.value(node).toList();
+ }
+
+ void addEdge(const T &node, const T &edge)
+ {
+ m_graph[node].insert(edge);
+ }
+
+ void addEdges(const T &node, const QList<T> &edges)
+ {
+ foreach (const T &edge, edges)
+ addEdge(node, edge);
+ }
+
+ bool hasCycle() const
+ {
+ return m_hasCycle;
+ }
+
+ QPair<T, T> cycle() const
+ {
+ return m_cycle;
+ }
+
+ QList<T> sort() const
+ {
+ QSet<T> visitedNodes;
+ QList<T> resolvedNodes;
+
+ m_hasCycle = false;
+ m_cycle = qMakePair(T(), T());
+ foreach (const T &node, nodes())
+ visit(node, &resolvedNodes, &visitedNodes);
+ return resolvedNodes;
+ }
+
+ QList<T> sortReverse() const
+ {
+ QList<T> result = sort();
+ std::reverse(result.begin(), result.end());
+ return result;
+ }
+
+private:
+ void visit(const T &node, QList<T> *const resolvedNodes, QSet<T> *const visitedNodes) const
+ {
+ if (m_hasCycle)
+ return;
+
+ // if we visited this node already
+ if (visitedNodes->contains(node)) {
+ // and if the node is already in the ordered list
+ if (resolvedNodes->contains(node))
+ return;
+
+ m_hasCycle = true;
+ m_cycle.second = node;
+ return; // if not yet in the ordered list, we detected a cycle
+ }
+
+ // mark this node as visited
+ visitedNodes->insert(node);
+
+ m_cycle.first = node;
+ // recursively visit all adjacency
+ foreach (const T &adjacency, edges(node))
+ visit(adjacency, resolvedNodes, visitedNodes);
+
+ // append this node the the ordered list
+ resolvedNodes->append(node);
+ }
+
+private:
+ mutable bool m_hasCycle;
+ QHash<T, QSet<T> > m_graph;
+ mutable QPair<T,T> m_cycle;
+};
+
+}
+#endif // GRAPH_H
diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro
index 5ae0b1afb..a1631c4a3 100644
--- a/src/libs/installer/installer.pro
+++ b/src/libs/installer/installer.pro
@@ -100,7 +100,8 @@ HEADERS += packagemanagercore.h \
createlinkoperation.h \
packagemanagercoredata.h \
applyproductkeyoperation.h \
- globals.h
+ globals.h \
+ graph.h
SOURCES += packagemanagercore.cpp \
packagemanagercore_p.cpp \
diff --git a/src/libs/installer/installiconsoperation.cpp b/src/libs/installer/installiconsoperation.cpp
index f46ab5315..dba6d644b 100644
--- a/src/libs/installer/installiconsoperation.cpp
+++ b/src/libs/installer/installiconsoperation.cpp
@@ -45,6 +45,7 @@
#include <QtCore/QDir>
#include <QtCore/QDirIterator>
+#include <QDebug>
#if QT_VERSION >= 0x040600
# include <QProcessEnvironment>
@@ -121,10 +122,6 @@ InstallIconsOperation::InstallIconsOperation()
InstallIconsOperation::~InstallIconsOperation()
{
const QStringList backupFiles = value(QLatin1String("backupfiles")).toStringList();
- for (QStringList::const_iterator it = backupFiles.begin(); it != backupFiles.end(); it += 2) {
- const QString& backup = *(it + 1);
- deleteFileNowOrLater(backup);
- }
}
void InstallIconsOperation::backup()
@@ -164,8 +161,6 @@ bool InstallIconsOperation::performOperation()
QDirIterator it(sourceDir.path(), QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot,
QDirIterator::Subdirectories);
while (it.hasNext()) {
- qApp->processEvents();
-
const int status = core->status();
if (status == PackageManagerCore::Canceled || status == PackageManagerCore::Failure)
return true;
@@ -194,7 +189,7 @@ bool InstallIconsOperation::performOperation()
if (QFile(target).exists()) {
// first backup...
- const QString backup = generateTemporaryFileName(target + QLatin1String("XXXXXX"));
+ const QString backup = generateTemporaryFileName(target);
QFile bf(target);
if (!bf.copy(backup)) {
setError(UserDefinedError);
@@ -251,12 +246,10 @@ bool InstallIconsOperation::performOperation()
bool InstallIconsOperation::undoOperation()
{
- bool success = true;
-
+ QStringList warningMessages;
// first copy back all files to their origin
const QStringList files = value(QLatin1String("files")).toStringList();
for (QStringList::const_iterator it = files.begin(); it != files.end(); it += 2) {
- qApp->processEvents();
const QString& source = *it;
const QString& target = *(it + 1);
@@ -264,10 +257,11 @@ bool InstallIconsOperation::undoOperation()
// first make sure the "source" path is valid
QDir().mkpath(QFileInfo(source).absolutePath());
- // now copy target to source (feels weird, I know...)
- success = QFile::copy(target, source) && success;
- // and remove target
- success = QFile::remove(target) && success;
+ QFile installedTarget(target);
+ if (installedTarget.exists() && !(installedTarget.copy(source) && installedTarget.remove())) {
+ warningMessages << QString::fromLatin1("Could not move file from '%1' to '%2', error: %3)").arg(
+ target, source, installedTarget.errorString());
+ }
}
// then copy back and remove all backuped files
@@ -278,11 +272,17 @@ bool InstallIconsOperation::undoOperation()
// remove the target
if (QFile::exists(target))
- success = deleteFileNowOrLater(target) && success;
+ deleteFileNowOrLater(target);
// then copy the backup onto the target
- success = QFile::copy(backup, target) && success;
+ if (!QFile::copy(backup, target)) {
+ warningMessages << QString::fromLatin1("Could not restore the backup '%1' to '%2'").arg(
+ backup, target);
+ }
+
// finally remove the backp
- success = deleteFileNowOrLater(backup) && success;
+ if (!deleteFileNowOrLater(backup))
+ warningMessages << QString::fromLatin1("Could not remove the backup '%1'").arg(backup);
+
}
// then remove all directories created by us
@@ -290,10 +290,19 @@ bool InstallIconsOperation::undoOperation()
for (QStringList::const_iterator it = createdDirectories.begin(); it != createdDirectories.end(); ++it) {
const QDir dir(*it);
removeSystemGeneratedFiles(dir.absolutePath());
- success = QDir::root().rmdir(dir.path());
+ if (dir.exists() && !QDir::root().rmdir(dir.path()))
+ warningMessages << QString::fromLatin1("Could not remove directory '%1'").arg(dir.path());
+ }
+
+ if (!warningMessages.isEmpty()) {
+ qWarning() << QString::fromLatin1("Undo of operation '%1' with arguments '%2' had some problems.").arg(
+ name(), arguments().join(QLatin1String(", ")));
+ foreach (const QString &message, warningMessages) {
+ qWarning() << message;
+ }
}
- return success;
+ return true;
}
bool InstallIconsOperation::testOperation()
diff --git a/src/libs/installer/macreplaceinstallnamesoperation.cpp b/src/libs/installer/macreplaceinstallnamesoperation.cpp
index 470c15b37..9ec553358 100644
--- a/src/libs/installer/macreplaceinstallnamesoperation.cpp
+++ b/src/libs/installer/macreplaceinstallnamesoperation.cpp
@@ -198,9 +198,8 @@ void MacReplaceInstallNamesOperation::relocateBinary(const MacBinaryInfo &info,
// change framework ID only if dynamicLibId isn't only the filename, if it has no relative path ("@")
- // and is not existing at the current looking for location
if (!info.dynamicLibId.isEmpty() && (info.dynamicLibId != QFileInfo(info.fileName).fileName())
- && !info.dynamicLibId.contains(QLatin1String("@")) && !QFileInfo(info.dynamicLibId).exists()) {
+ && !info.dynamicLibId.contains(QLatin1String("@"))) {
// error is set inside the execCommand method
if (!execCommand(QLatin1String("install_name_tool"), QStringList(QLatin1String("-id"))
<< info.fileName << info.fileName)) {
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index 9543aca5e..c617dd239 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -192,12 +192,6 @@
*/
/*!
- \qmlsignal QInstaller::setRootComponents(list<Component> components)
-
- Triggered with the list of new root components (for example after an online update).
-*/
-
-/*!
\qmlsignal QInstaller::startAllComponentsReset()
Triggered when the list of components starts to get updated.
@@ -206,9 +200,9 @@
*/
/*!
- \qmlsignal QInstaller::finishAllComponentsReset()
+ \qmlsignal QInstaller::finishAllComponentsReset(list<Component> rootComponents)
- Triggered when the list of components has been updated.
+ Triggered when the list of new root components has been updated.
\sa startAllComponentsReset
*/
@@ -220,9 +214,9 @@
*/
/*!
- \qmlsignal QInstaller::finishUpdaterComponentsReset()
+ \qmlsignal QInstaller::finishUpdaterComponentsReset(list<Component> componentsWithUpdates)
- Triggered when components have been updated during a remote update.
+ Triggered when the list of available remote updates has been updated.
*/
/*!
@@ -419,6 +413,11 @@ void PackageManagerCore::writeUninstaller()
}
}
+void PackageManagerCore::writeMaintenanceConfigFiles()
+{
+ d->writeMaintenanceConfigFiles();
+}
+
void PackageManagerCore::reset(const QHash<QString, QString> &params)
{
d->m_completeUninstall = false;
@@ -814,9 +813,8 @@ bool PackageManagerCore::fetchLocalPackagesTree()
updateDisplayVersions(scDisplayVersion);
- emit finishAllComponentsReset();
+ emit finishAllComponentsReset(d->m_rootComponents);
d->setStatus(Success);
- emit setRootComponents(d->m_rootComponents);
return true;
}
@@ -889,9 +887,39 @@ bool PackageManagerCore::fetchRemotePackagesTree()
return false;
bool success = false;
- if (!isUpdater())
+ if (!isUpdater()) {
success = fetchAllPackages(packages, installedPackages);
- else {
+ if (success && !d->statusCanceledOrFailed() && isPackageManager()) {
+ foreach (Package *const update, packages) {
+ if (update->data(scEssential, scFalse).toString().toLower() == scTrue) {
+ const QString name = update->data(scName).toString();
+ if (!installedPackages.contains(name)) {
+ success = false;
+ break; // unusual, the maintenance tool should always be available
+ }
+
+ const LocalPackage localPackage = installedPackages.value(name);
+ const QString updateVersion = update->data(scRemoteVersion).toString();
+ if (KDUpdater::compareVersion(updateVersion, localPackage.version) <= 0)
+ break; // remote version equals or is less than the installed maintenance tool
+
+ const QDate updateDate = update->data(scReleaseDate).toDate();
+ if (localPackage.lastUpdateDate >= updateDate)
+ break; // remote release date equals or is less than the installed maintenance tool
+
+ success = false;
+ break; // we found a newer version of the maintenance tool
+ }
+ }
+
+ if (!success && !d->statusCanceledOrFailed()) {
+ updateDisplayVersions(scRemoteDisplayVersion);
+ d->setStatus(ForceUpdate, tr("There is an important update available, please run the "
+ "updater first."));
+ return false;
+ }
+ }
+ } else {
success = fetchUpdaterPackages(packages, installedPackages);
}
@@ -1315,6 +1343,8 @@ ComponentModel *PackageManagerCore::defaultComponentModel() const
d->m_defaultModel = componentModel(const_cast<PackageManagerCore*> (this),
QLatin1String("AllComponentsModel"));
}
+ connect(this, SIGNAL(finishAllComponentsReset(QList<QInstaller::Component*>)), d->m_defaultModel,
+ SLOT(setRootComponents(QList<QInstaller::Component*>)));
return d->m_defaultModel;
}
@@ -1325,6 +1355,8 @@ ComponentModel *PackageManagerCore::updaterComponentModel() const
d->m_updaterModel = componentModel(const_cast<PackageManagerCore*> (this),
QLatin1String("UpdaterComponentsModel"));
}
+ connect(this, SIGNAL(finishUpdaterComponentsReset(QList<QInstaller::Component*>)), d->m_updaterModel,
+ SLOT(setRootComponents(QList<QInstaller::Component*>)));
return d->m_updaterModel;
}
@@ -2141,8 +2173,7 @@ bool PackageManagerCore::fetchAllPackages(const PackagesList &remotes, const Loc
if (!d->buildComponentTree(components, true))
return false;
- emit finishAllComponentsReset();
- emit setRootComponents(d->m_rootComponents);
+ emit finishAllComponentsReset(d->m_rootComponents);
return true;
}
@@ -2192,7 +2223,9 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
}
}
- if (!isValidUpdate)
+ // break if the update is not valid and if it's not the maintenance tool (we might get an update
+ // for the maintenance tool even if it's not currently installed - possible offline installation)
+ if (!isValidUpdate && (update->data(scEssential, scFalse).toString().toLower() == scFalse))
continue; // Update for not installed package found, skip it.
const LocalPackage &localPackage = locals.value(name);
@@ -2283,7 +2316,7 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
}
} catch (const Error &error) {
d->clearUpdaterComponentLists();
- emit finishUpdaterComponentsReset();
+ emit finishUpdaterComponentsReset(QList<QInstaller::Component*>());
d->setStatus(Failure, error.message());
// TODO: make sure we remove all message boxes inside the library at some point.
@@ -2292,8 +2325,7 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
return false;
}
- emit finishUpdaterComponentsReset();
- emit setRootComponents(d->m_updaterComponents);
+ emit finishUpdaterComponentsReset(d->m_updaterComponents);
return true;
}
@@ -2346,7 +2378,7 @@ QString PackageManagerCore::findDisplayVersion(const QString &componentName,
ComponentModel *PackageManagerCore::componentModel(PackageManagerCore *core, const QString &objectName) const
{
- ComponentModel *model = new ComponentModel(4, core);
+ ComponentModel *model = new ComponentModel(5, core);
model->setObjectName(objectName);
model->setHeaderData(ComponentModelHelper::NameColumn, Qt::Horizontal,
@@ -2355,10 +2387,10 @@ ComponentModel *PackageManagerCore::componentModel(PackageManagerCore *core, con
ComponentModel::tr("Installed Version"));
model->setHeaderData(ComponentModelHelper::NewVersionColumn, Qt::Horizontal,
ComponentModel::tr("New Version"));
+ model->setHeaderData(ComponentModelHelper::ReleaseDateColumn, Qt::Horizontal,
+ ComponentModel::tr("Release Date"));
model->setHeaderData(ComponentModelHelper::UncompressedSizeColumn, Qt::Horizontal,
ComponentModel::tr("Size"));
- connect(this, SIGNAL(setRootComponents(QList<QInstaller::Component*>)), model,
- SLOT(setRootComponents(QList<QInstaller::Component*>)));
connect(model, SIGNAL(checkStateChanged(QInstaller::ComponentModel::ModelState)), this,
SLOT(componentsToInstallNeedsRecalculation()));
diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h
index 712a5174c..20a3293fa 100644
--- a/src/libs/installer/packagemanagercore.h
+++ b/src/libs/installer/packagemanagercore.h
@@ -82,7 +82,8 @@ public:
Failure = EXIT_FAILURE,
Running,
Canceled,
- Unfinished
+ Unfinished,
+ ForceUpdate
};
Status status() const;
QString error() const;
@@ -157,6 +158,8 @@ public:
QStringList replaceVariables(const QStringList &str) const;
void writeUninstaller();
+ void writeMaintenanceConfigFiles();
+
QString uninstallerName() const;
QString installerBinaryPath() const;
@@ -271,13 +274,12 @@ Q_SIGNALS:
void finishButtonClicked();
void metaJobInfoMessage(const QString &message);
- void setRootComponents(const QList<QInstaller::Component*> &components);
void startAllComponentsReset();
- void finishAllComponentsReset();
+ void finishAllComponentsReset(const QList<QInstaller::Component*> &rootComponents);
void startUpdaterComponentsReset();
- void finishUpdaterComponentsReset();
+ void finishUpdaterComponentsReset(const QList<QInstaller::Component*> &componentsWithUpdates);
void installationStarted();
void installationInterrupted();
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index 1728a85b2..f102d79ed 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -49,6 +49,7 @@
#include "fileutils.h"
#include "fsengineclient.h"
#include "globals.h"
+#include "graph.h"
#include "messageboxhandler.h"
#include "packagemanagercore.h"
#include "progresscoordinator.h"
@@ -95,7 +96,8 @@ public:
{
if (!m_operation)
return;
- qDebug() << QString::fromLatin1("%1 operation: %2").arg(state, m_operation->name());
+ qDebug() << QString::fromLatin1("%1 %2 operation: %3").arg(state, m_operation->value(
+ QLatin1String("component")).toString(), m_operation->name());
qDebug() << QString::fromLatin1("\t- arguments: %1").arg(m_operation->arguments()
.join(QLatin1String(", ")));
}
@@ -379,7 +381,7 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c
std::sort(m_rootComponents.begin(), m_rootComponents.end(), Component::SortingPriorityGreaterThan());
} catch (const Error &error) {
clearAllComponentLists();
- emit m_core->finishAllComponentsReset();
+ emit m_core->finishAllComponentsReset(QList<QInstaller::Component*>());
setStatus(PackageManagerCore::Failure, error.message());
// TODO: make sure we remove all message boxes inside the library at some point.
@@ -630,7 +632,7 @@ void PackageManagerCorePrivate::initialize(const QHash<QString, QString> &params
}
if (!m_repoMetaInfoJob) {
- m_repoMetaInfoJob = new GetRepositoriesMetaInfoJob(this);
+ m_repoMetaInfoJob = new GetRepositoriesMetaInfoJob(m_core);
m_repoMetaInfoJob->setAutoDelete(false);
connect(m_repoMetaInfoJob, SIGNAL(infoMessage(KDJob*, QString)), this, SLOT(infoMessage(KDJob*,
QString)));
@@ -1328,9 +1330,15 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
#endif
}
+ performedOperations = sortOperationsBasedOnComponentDependencies(
+ performedOperations);
+
+ m_core->setValue(QLatin1String("installedOperationAreSorted"), QLatin1String("true"));
+
try {
KDSaveFile file(dataFile + QLatin1String(".new"));
openForWrite(&file, file.fileName());
+
writeUninstallerBinaryData(&file, &input, performedOperations, layout);
appendInt64(&file, MagicCookieDat);
file.setPermissions(file.permissions() | QFile::WriteUser | QFile::ReadGroup
@@ -1611,8 +1619,14 @@ bool PackageManagerCorePrivate::runPackageUpdater()
OperationList nonRevertedOperations;
QHash<QString, Component *> componentsByName;
+ // order the operations in the right component dependency order
+ // next loop will save the needed operations in reverse order for uninstallation
+ OperationList performedOperationsOld = m_performedOperationsOld;
+ if (m_core->value(QLatin1String("installedOperationAreSorted")) != QLatin1String("true"))
+ performedOperationsOld = sortOperationsBasedOnComponentDependencies(m_performedOperationsOld);
+
// build a list of undo operations based on the checked state of the component
- foreach (Operation *operation, m_performedOperationsOld) {
+ foreach (Operation *operation, performedOperationsOld) {
const QString &name = operation->value(QLatin1String("component")).toString();
Component *component = componentsByName.value(name, 0);
if (!component)
@@ -1663,6 +1677,7 @@ bool PackageManagerCorePrivate::runPackageUpdater()
continue;
}
+ // uninstallation should be in reverse order so prepend it here
undoOperations.prepend(operation);
updateAdminRights |= operation->value(QLatin1String("admin")).toBool();
}
@@ -1864,7 +1879,6 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr
// Remember that the operation was performed, that allows us to undo it if a following operation
// fails or if this operation failed but still needs an undo call to cleanup.
addPerformed(operation);
- operation->setValue(QLatin1String("component"), component->name());
}
if (becameAdmin)
@@ -2017,22 +2031,18 @@ void PackageManagerCorePrivate::runUndoOperations(const OperationList &undoOpera
const QString componentName = undoOperation->value(QLatin1String("component")).toString();
if (!componentName.isEmpty()) {
- while (!ok && !ignoreError && m_core->status() != PackageManagerCore::Canceled) {
- const QMessageBox::StandardButton button =
- MessageBoxHandler::warning(MessageBoxHandler::currentBestSuitParent(),
- QLatin1String("installationErrorWithRetry"), tr("Installer Error"),
- tr("Error during uninstallation process:\n%1").arg(undoOperation->errorString()),
- QMessageBox::Retry | QMessageBox::Ignore, QMessageBox::Retry);
-
- if (button == QMessageBox::Retry) {
- ok = performOperationThreaded(undoOperation, Undo);
- } else if (button == QMessageBox::Ignore) {
- ignoreError = true;
- }
- }
- }
-
- if (!componentName.isEmpty()) {
+ while (!ok && !ignoreError && m_core->status() != PackageManagerCore::Canceled) {
+ const QMessageBox::StandardButton button =
+ MessageBoxHandler::warning(MessageBoxHandler::currentBestSuitParent(),
+ QLatin1String("installationErrorWithRetry"), tr("Installer Error"),
+ tr("Error during uninstallation process:\n%1").arg(undoOperation->errorString()),
+ QMessageBox::Retry | QMessageBox::Ignore, QMessageBox::Retry);
+
+ if (button == QMessageBox::Retry)
+ ok = performOperationThreaded(undoOperation, Undo);
+ else if (button == QMessageBox::Ignore)
+ ignoreError = true;
+ }
Component *component = m_core->componentByName(componentName);
if (!component)
component = componentsToReplace().value(componentName).second;
@@ -2359,6 +2369,37 @@ void PackageManagerCorePrivate::connectOperationCallMethodRequest(Operation *con
}
}
+OperationList PackageManagerCorePrivate::sortOperationsBasedOnComponentDependencies(const OperationList &operationList)
+{
+ OperationList sortedOperations;
+ QHash<QString, OperationList> componentOperationHash;
+
+ // sort component unrelated operations to the beginning
+ foreach (Operation *operation, operationList) {
+ const QString componentName = operation->value(QLatin1String("component")).toString();
+ if (componentName.isEmpty())
+ sortedOperations.append(operation);
+ else {
+ OperationList componentOperationList = componentOperationHash.value(componentName);
+ componentOperationList.append(operation);
+ componentOperationHash.insert(operation->value(QLatin1String("component")).toString(),
+ componentOperationList);
+ }
+ }
+
+ // create the complete component graph
+ Graph<QString> componentGraph;
+ foreach (const Component* componentNode, m_core->availableComponents()) {
+ componentGraph.addNode(componentNode->name());
+ componentGraph.addEdges(componentNode->name(), componentNode->dependencies());
+ }
+
+ foreach (const QString &componentName, componentGraph.sort())
+ sortedOperations.append(componentOperationHash.value(componentName));
+
+ return sortedOperations;
+}
+
void PackageManagerCorePrivate::handleMethodInvocationRequest(const QString &invokableMethodName)
{
QObject *obj = QObject::sender();
diff --git a/src/libs/installer/packagemanagercore_p.h b/src/libs/installer/packagemanagercore_p.h
index 11ed23230..d5bdc78fd 100644
--- a/src/libs/installer/packagemanagercore_p.h
+++ b/src/libs/installer/packagemanagercore_p.h
@@ -167,6 +167,7 @@ public:
int countProgressOperations(const OperationList &operations);
void connectOperationToInstaller(Operation *const operation, double progressOperationPartSize);
void connectOperationCallMethodRequest(Operation *const operation);
+ OperationList sortOperationsBasedOnComponentDependencies(const OperationList &operationList);
Operation *createOwnedOperation(const QString &type);
Operation *takeOwnedOperation(Operation *operation);
diff --git a/src/libs/installer/packagemanagercoredata.cpp b/src/libs/installer/packagemanagercoredata.cpp
index efc83f520..2294a8086 100644
--- a/src/libs/installer/packagemanagercoredata.cpp
+++ b/src/libs/installer/packagemanagercoredata.cpp
@@ -57,6 +57,8 @@ PackageManagerCoreData::PackageManagerCoreData(const QHash<QString, QString> &va
// in a script or...
m_variables.insert(QLatin1String("rootDir"), QDir::rootPath());
m_variables.insert(QLatin1String("homeDir"), QDir::homePath());
+ m_variables.insert(QLatin1String("RootDir"), QDir::rootPath());
+ m_variables.insert(QLatin1String("HomeDir"), QDir::homePath());
m_variables.insert(scTargetConfigurationFile, QLatin1String("components.xml"));
#ifdef Q_OS_WIN
diff --git a/src/libs/installer/packagemanagergui.cpp b/src/libs/installer/packagemanagergui.cpp
index 10caed749..2db2a9e4a 100644
--- a/src/libs/installer/packagemanagergui.cpp
+++ b/src/libs/installer/packagemanagergui.cpp
@@ -299,20 +299,30 @@ QString PackageManagerGui::defaultButtonText(int wizardButton) const
void PackageManagerGui::clickButton(int wb, int delay)
{
- if (QAbstractButton *b = button(static_cast<QWizard::WizardButton>(wb) )) {
+ // transform the FinishButton to CancelButton, because of the needed misuse of the
+ // CancelButton as a FinishButton to have some more control of closing the wizard
+ if (!m_core->isInstaller() && currentId() == PackageManagerCore::InstallationFinished &&
+ wb == QWizard::FinishButton) {
+ wb = QWizard::CancelButton;
+ }
+ if (QAbstractButton *b = button(static_cast<QWizard::WizardButton>(wb) ))
QTimer::singleShot(delay, b, SLOT(click()));
- } else {
+ else
qWarning() << "Button with type: " << d->buttonType(wb) << "not found!";
- }
}
bool PackageManagerGui::isButtonEnabled(int wb)
{
- if (QAbstractButton *b = button(static_cast<QWizard::WizardButton>(wb) )) {
- return b->isEnabled();
- } else {
- qWarning() << "Button with type: " << d->buttonType(wb) << "not found!";
+ // transform the FinishButton to CancelButton, because of the needed misuse of the
+ // CancelButton as a FinishButton to have some more control of closing the wizard
+ if (!m_core->isInstaller() && currentId() == PackageManagerCore::InstallationFinished &&
+ wb == QWizard::FinishButton) {
+ wb = QWizard::CancelButton;
}
+ if (QAbstractButton *b = button(static_cast<QWizard::WizardButton>(wb) ))
+ return b->isEnabled();
+
+ qWarning() << "Button with type: " << d->buttonType(wb) << "not found!";
return false;
}
@@ -970,9 +980,9 @@ public:
m_treeView->setObjectName(QLatin1String("ComponentsTreeView"));
connect(m_allModel, SIGNAL(checkStateChanged(QInstaller::ComponentModel::ModelState)), this,
- SLOT(onCheckStateChanged(QInstaller::ComponentModel::ModelState)));
+ SLOT(onModelStateChanged(QInstaller::ComponentModel::ModelState)));
connect(m_updaterModel, SIGNAL(checkStateChanged(QInstaller::ComponentModel::ModelState)), this,
- SLOT(onCheckStateChanged(QInstaller::ComponentModel::ModelState)));
+ SLOT(onModelStateChanged(QInstaller::ComponentModel::ModelState)));
QHBoxLayout *hlayout = new QHBoxLayout;
hlayout->addWidget(m_treeView, 3);
@@ -1034,8 +1044,6 @@ public:
{
m_checkDefault->setVisible(m_core->isInstaller() || m_core->isPackageManager());
if (m_treeView->selectionModel()) {
- disconnect(m_currentModel, SIGNAL(checkStateChanged(QModelIndex)), this,
- SLOT(currentCheckedChanged(QModelIndex)));
disconnect(m_treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)),
this, SLOT(currentSelectedChanged(QModelIndex)));
}
@@ -1060,8 +1068,6 @@ public:
hasChildren = m_currentModel->hasChildren(m_currentModel->index(row, 0));
m_treeView->setRootIsDecorated(hasChildren);
- connect(m_currentModel, SIGNAL(checkStateChanged(QModelIndex)), this,
- SLOT(currentCheckedChanged(QModelIndex)));
connect(m_treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)),
this, SLOT(currentSelectedChanged(QModelIndex)));
@@ -1069,12 +1075,6 @@ public:
}
public slots:
- void currentCheckedChanged(const QModelIndex &current)
- {
- if (m_treeView->selectionModel()->currentIndex() == current)
- currentSelectedChanged(current);
- }
-
void currentSelectedChanged(const QModelIndex &current)
{
if (!current.isValid())
@@ -1088,7 +1088,7 @@ public slots:
if ((m_core->isUninstaller()) || (!component))
return;
- if ((component->checkState() != Qt::Unchecked) && (component->updateUncompressedSize() > 0)) {
+ if (component->isSelected() && (component->value(scUncompressedSizeSum).toLongLong() > 0)) {
m_sizeLabel->setText(ComponentSelectionPage::tr("This component "
"will occupy approximately %1 on your hard disk drive.")
.arg(humanReadableSize(component->value(scUncompressedSizeSum).toLongLong())));
@@ -1110,10 +1110,9 @@ public slots:
m_currentModel->setCheckedState(ComponentModel::DefaultChecked);
}
- void onCheckStateChanged(QInstaller::ComponentModel::ModelState state)
+ void onModelStateChanged(QInstaller::ComponentModel::ModelState state)
{
- q->setModified(state != ComponentModel::DefaultChecked);
-
+ q->setModified(state.testFlag(ComponentModel::DefaultChecked) == false);
// If all components in the checked list are only checkable when run without forced installation, set
// ComponentModel::AllUnchecked as well, as we cannot uncheck anything. Helps to keep the UI correct.
if ((!m_core->noForceInstallation()) && (m_currentModel->checked() == m_currentModel->uncheckable()))
@@ -1123,6 +1122,10 @@ public slots:
m_checkAll->setEnabled(state.testFlag(ComponentModel::AllChecked) == false);
m_uncheckAll->setEnabled(state.testFlag(ComponentModel::AllUnchecked) == false);
m_checkDefault->setEnabled(state.testFlag(ComponentModel::DefaultChecked) == false);
+
+ // update the current selected node (important to reflect possible sub-node changes)
+ if (m_treeView->selectionModel())
+ currentSelectedChanged(m_treeView->selectionModel()->currentIndex());
}
public:
@@ -1233,7 +1236,7 @@ bool ComponentSelectionPage::isComplete() const
{
if (packageManagerCore()->isInstaller() || packageManagerCore()->isUpdater())
return d->m_currentModel->checked().count();
- return d->m_currentModel->checkedState() != ComponentModel::DefaultChecked;
+ return d->m_currentModel->checkedState().testFlag(ComponentModel::DefaultChecked) == false;
}
@@ -1836,6 +1839,13 @@ void FinishedPage::entering()
m_commitButton = cancel;
cancel->setEnabled(true);
cancel->setVisible(true);
+ // we don't use the usual FinishButton so we need to connect the misused CancelButton
+ connect(cancel, SIGNAL(clicked()), gui(), SIGNAL(finishButtonClicked()));
+ connect(cancel, SIGNAL(clicked()), packageManagerCore(), SIGNAL(finishButtonClicked()));
+ // for the moment we don't want the rejected signal connected
+ disconnect(gui(), SIGNAL(rejected()), packageManagerCore(), SLOT(setCanceled()));
+
+ connect(gui()->button(QWizard::CommitButton), SIGNAL(clicked()), this, SLOT(cleanupChangedConnects()));
}
setButtonText(QWizard::CommitButton, tr("Restart"));
setButtonText(QWizard::CancelButton, gui()->defaultButtonText(QWizard::FinishButton));
@@ -1901,6 +1911,17 @@ void FinishedPage::handleFinishClicked()
QProcess::startDetached(program, args);
}
+void FinishedPage::cleanupChangedConnects()
+{
+ if (QAbstractButton *cancel = gui()->button(QWizard::CancelButton)) {
+ // remove the workaround connect from entering page
+ disconnect(cancel, SIGNAL(clicked()), gui(), SIGNAL(finishButtonClicked()));
+ disconnect(cancel, SIGNAL(clicked()), packageManagerCore(), SIGNAL(finishButtonClicked()));
+ connect(gui(), SIGNAL(rejected()), packageManagerCore(), SLOT(setCanceled()));
+
+ disconnect(gui()->button(QWizard::CommitButton), SIGNAL(clicked()), this, SLOT(cleanupChangedConnects()));
+ }
+}
// -- RestartPage
diff --git a/src/libs/installer/packagemanagergui.h b/src/libs/installer/packagemanagergui.h
index 37e5d6852..5c428bf87 100644
--- a/src/libs/installer/packagemanagergui.h
+++ b/src/libs/installer/packagemanagergui.h
@@ -403,6 +403,7 @@ public:
public Q_SLOTS:
void handleFinishClicked();
+ void cleanupChangedConnects();
protected:
void entering();
diff --git a/src/libs/installer/productkeycheck.cpp b/src/libs/installer/productkeycheck.cpp
index fe1fd10af..a4af2b6d3 100644
--- a/src/libs/installer/productkeycheck.cpp
+++ b/src/libs/installer/productkeycheck.cpp
@@ -88,3 +88,10 @@ bool ProductKeyCheck::isValidLicenseTextFile(const QString &/*fileName*/)
{
return true;
}
+
+
+bool ProductKeyCheck::isValidRepository(const QInstaller::Repository &repository) const
+{
+ Q_UNUSED(repository)
+ return true;
+} \ No newline at end of file
diff --git a/src/libs/installer/productkeycheck.h b/src/libs/installer/productkeycheck.h
index d472d9288..6d72089e2 100644
--- a/src/libs/installer/productkeycheck.h
+++ b/src/libs/installer/productkeycheck.h
@@ -38,6 +38,7 @@
namespace QInstaller{
class PackageManagerCore;
+ class Repository;
}
class ProductKeyCheckPrivate;
@@ -60,6 +61,9 @@ public:
// to filter none valid licenses
bool isValidLicenseTextFile(const QString &fileName);
+ // to filter repositories not matching the license
+ bool isValidRepository(const QInstaller::Repository &repository) const;
+
private:
ProductKeyCheck();
ProductKeyCheckPrivate *const d;
diff --git a/src/libs/installer/qtpatchoperation.cpp b/src/libs/installer/qtpatchoperation.cpp
index 822d5e3a4..e9fbb65c5 100644
--- a/src/libs/installer/qtpatchoperation.cpp
+++ b/src/libs/installer/qtpatchoperation.cpp
@@ -254,19 +254,97 @@ bool QtPatchOperation::performOperation()
}
#ifdef Q_OS_MAC
- // just try to patch here at the beginning to keep the unpatched qmake if mac install_names_tool fails
- MacReplaceInstallNamesOperation operation;
- operation.setArguments(QStringList()
- //can not use the old path which is wrong in the webkit case
- //<< QString::fromUtf8(oldQtPath)
- << QLatin1String("/lib/Qt") // search string
- << newQtPathStr + QLatin1String("/lib/Qt") //replace string
- << newQtPathStr //where
- );
- if (!operation.performOperation()) {
- setError(operation.error());
- setErrorString(operation.errorString());
- return false;
+ // looking for /lib/Qt wasn't enough for all libs and frameworks,
+ // at the Qt4 case we had for example: /lib/libQtCLucene* and /lib/phonon*
+ // so now we find every possible replace string inside dynlib dependencies
+ // and we reduce it to few as possible search strings
+ QStringList possibleSearchStringList;
+ QDirIterator dirIterator(newQtPathStr + QLatin1String("/lib/"));
+ while (dirIterator.hasNext()) {
+ const QString possibleSearchString = QString(dirIterator.next()).remove(newQtPathStr);
+ const QFileInfo fileInfo = dirIterator.fileInfo();
+ if (fileInfo.isSymLink())
+ continue;
+ if (fileInfo.isDir()) {
+ if (possibleSearchString.endsWith(QLatin1String(".framework")))
+ possibleSearchStringList.append(possibleSearchString);
+ else
+ continue;
+ }
+ if (possibleSearchString.endsWith(QLatin1String(".dylib")))
+ possibleSearchStringList.append(possibleSearchString);
+ }
+
+ // now we have this in possibleSearchStringList at Qt 4.8.6
+// "/lib/libQtCLucene.4.8.6.dylib"
+// "/lib/libQtCLucene_debug.4.8.6.dylib"
+// "/lib/phonon.framework"
+// "/lib/QtCore.framework"
+// "/lib/QtDeclarative.framework"
+// "/lib/QtDesigner.framework"
+// "/lib/QtDesignerComponents.framework"
+// "/lib/QtGui.framework"
+// "/lib/QtHelp.framework"
+// "/lib/QtMultimedia.framework"
+// "/lib/QtNetwork.framework"
+// "/lib/QtOpenGL.framework"
+// "/lib/QtScript.framework"
+// "/lib/QtScriptTools.framework"
+// "/lib/QtSql.framework"
+// "/lib/QtSvg.framework"
+// "/lib/QtTest.framework"
+// "/lib/QtWebKit.framework"
+// "/lib/QtXml.framework"
+// "/lib/QtXmlPatterns.framework"
+
+ // so then we reduce the possible filter strings as much as possible
+ QStringList searchStringList;
+
+ // as the minimal search string use the subdirector lib + one letter from the name
+ int minFilterLength = QString(QLatin1String("/lib/")).length() + 1;
+
+ while (!possibleSearchStringList.isEmpty()) {
+ QString firstSearchString = possibleSearchStringList.first();
+ int filterLength = minFilterLength;
+ int lastFilterCount = 0;
+ QString lastFilterString;
+ // now filter as long as we find something more then 1
+ for (; filterLength < firstSearchString.length(); ++filterLength) {
+ QString filterString(firstSearchString.left(filterLength));
+ QStringList filteredStringList(possibleSearchStringList.filter(filterString));
+ // found a valid filter
+ if (lastFilterCount > filteredStringList.count()) {
+ possibleSearchStringList = QList<QString>::fromSet(possibleSearchStringList.toSet() -
+ possibleSearchStringList.filter(lastFilterString).toSet());
+ searchStringList.append(lastFilterString);
+ break;
+ } else if (lastFilterCount == 1){ //in case there is only one we can use the complete name
+ possibleSearchStringList = QList<QString>::fromSet(possibleSearchStringList.toSet() -
+ possibleSearchStringList.filter(firstSearchString).toSet());
+ searchStringList.append(firstSearchString);
+ break;
+ } else {
+ lastFilterCount = possibleSearchStringList.filter(filterString).count();
+ lastFilterString = filterString;
+ }
+ }
+ }
+
+ // in the tested Qt 4.8.6 case we have searchStringList ("/lib/libQtCLucene", "/lib/Qt", "/lib/phonon")
+ foreach (const QString &searchString, searchStringList) {
+ MacReplaceInstallNamesOperation operation;
+ operation.setArguments(QStringList()
+ //can not use the old path which is wrong in the webkit case
+ //<< QString::fromUtf8(oldQtPath)
+ << searchString
+ << newQtPathStr + searchString //replace string
+ << newQtPathStr //where
+ );
+ if (!operation.performOperation()) {
+ setError(operation.error());
+ setErrorString(operation.errorString());
+ return false;
+ }
}
#endif
diff --git a/src/libs/installer/scriptengine.cpp b/src/libs/installer/scriptengine.cpp
index 75a60dc15..e85ce9671 100644
--- a/src/libs/installer/scriptengine.cpp
+++ b/src/libs/installer/scriptengine.cpp
@@ -407,6 +407,8 @@ QScriptValue ScriptEngine::generateQInstallerObject()
qinstaller.setProperty(QLatin1String("Failure"), PackageManagerCore::Failure);
qinstaller.setProperty(QLatin1String("Running"), PackageManagerCore::Running);
qinstaller.setProperty(QLatin1String("Canceled"), PackageManagerCore::Canceled);
+ qinstaller.setProperty(QLatin1String("Unfinished"), PackageManagerCore::Unfinished);
+ qinstaller.setProperty(QLatin1String("ForceUpdate"), PackageManagerCore::ForceUpdate);
return qinstaller;
}
diff --git a/src/libs/kdtools/kdupdaterupdatesinfo.cpp b/src/libs/kdtools/kdupdaterupdatesinfo.cpp
index 9e6f35aac..27c21fb19 100644
--- a/src/libs/kdtools/kdupdaterupdatesinfo.cpp
+++ b/src/libs/kdtools/kdupdaterupdatesinfo.cpp
@@ -155,6 +155,9 @@ bool UpdatesInfoData::parsePackageUpdateElement(const QDomElement &updateE)
// overwrite default if we have a language specific description
if (languageAttribute == QLocale().name().toLower())
info.data[childE.tagName()] = childE.text();
+ } else if (childE.tagName() == QLatin1String("UpdateFile")) {
+ info.data[QLatin1String("CompressedSize")] = childE.attribute(QLatin1String("CompressedSize"));
+ info.data[QLatin1String("UncompressedSize")] = childE.attribute(QLatin1String("UncompressedSize"));
} else {
info.data[childE.tagName()] = childE.text();
}
diff --git a/src/sdk/installerbase.cpp b/src/sdk/installerbase.cpp
index 71f45301e..870182e13 100644
--- a/src/sdk/installerbase.cpp
+++ b/src/sdk/installerbase.cpp
@@ -317,8 +317,16 @@ int main(int argc, char *argv[])
// install the default Qt translator
QScopedPointer<QTranslator> translator(new QTranslator(&app));
- if (translator->load(QLocale(), QLatin1String("qt"), QString::fromLatin1("_"), directory))
- app.installTranslator(translator.take());
+ foreach (const QLocale locale, QLocale().uiLanguages()) {
+ // As there is no qt_en.qm, we simply end the search when the next
+ // preferred language is English.
+ if (locale.language() == QLocale::English)
+ break;
+ if (translator->load(locale, QLatin1String("qt"), QString::fromLatin1("_"), directory)) {
+ app.installTranslator(translator.take());
+ break;
+ }
+ }
translator.reset(new QTranslator(&app));
// install English translation as fallback so that correct license button text is used
@@ -327,10 +335,12 @@ int main(int argc, char *argv[])
if (translations.isEmpty()) {
translator.reset(new QTranslator(&app));
- const QString name = QLocale().uiLanguages().value(0).replace(QLatin1Char('-'), QLatin1Char('_'))
- .toLower(); // install "our" default translator
- if (translator->load(name, directory))
- app.installTranslator(translator.take());
+ foreach (const QLocale locale, QLocale().uiLanguages()) {
+ if (translator->load(locale, QLatin1String(""), QLatin1String(""), directory)) {
+ app.installTranslator(translator.take());
+ break;
+ }
+ }
} else {
foreach (const QString &translation, translations) {
translator.reset(new QTranslator(&app));
diff --git a/src/sdk/installerbase.qrc b/src/sdk/installerbase.qrc
index d33e997a5..678515eaf 100644
--- a/src/sdk/installerbase.qrc
+++ b/src/sdk/installerbase.qrc
@@ -7,5 +7,7 @@
<file>translations/qt_ru.qm</file>
<file>translations/zh_cn.qm</file>
<file>translations/qt_zh_CN.qm</file>
+ <file>translations/ja_jp.qm</file>
+ <file>translations/qt_ja.qm</file>
</qresource>
</RCC>
diff --git a/src/sdk/installerbasecommons.cpp b/src/sdk/installerbasecommons.cpp
index 30ba8938d..d2fb5e27b 100644
--- a/src/sdk/installerbasecommons.cpp
+++ b/src/sdk/installerbasecommons.cpp
@@ -177,7 +177,7 @@ bool IntroductionPageImpl::validatePage()
m_allPackagesFetched = core->fetchRemotePackagesTree();
if (!m_allPackagesFetched) {
QString error = core->error();
- if (core->isPackageManager()) {
+ if (core->isPackageManager() && core->status() != PackageManagerCore::ForceUpdate) {
// if that fails and we're in maintenance mode, try to fetch local installed tree
localPackagesTreeFetched = core->fetchLocalPackagesTree();
if (localPackagesTreeFetched) {
@@ -366,6 +366,7 @@ TargetDirectoryPageImpl::TargetDirectoryPageImpl(PackageManagerCore *core)
m_warningLabel = new QLabel(this);
m_warningLabel->setPalette(palette);
+ m_warningLabel->setWordWrap(true);
insertWidget(m_warningLabel, QLatin1String("MessageLabel"), 2);
}
@@ -400,7 +401,7 @@ QString TargetDirectoryPageImpl::targetDirWarning() const
dir = dir.mid(2);
#endif
- QString ambiguousChars = QLatin1String("[<>|?*!@#$%^&:,; ]");
+ QString ambiguousChars = QLatin1String("[~<>|?*!@#$%^&:,; ]");
if (packageManagerCore()->settings().allowSpaceInPath())
ambiguousChars.remove(QLatin1Char(' '));
diff --git a/src/sdk/sdk.pro b/src/sdk/sdk.pro
index d01ea6840..8b428fe48 100644
--- a/src/sdk/sdk.pro
+++ b/src/sdk/sdk.pro
@@ -13,8 +13,8 @@ isEqual(QT_MAJOR_VERSION, 5) {
DESTDIR = $$IFW_APP_PATH
if (exists($$LRELEASE)) {
- QT_LANGUAGES = qt_de qt_ru qt_zh_CN
- IB_LANGUAGES = de_de en_us ru_ru zh_cn
+ QT_LANGUAGES = qt_de qt_ru qt_zh_CN qt_ja
+ IB_LANGUAGES = de_de en_us ru_ru zh_cn ja_jp
defineReplace(prependAll) {
for(a,$$1):result += $$2$${a}$$3
return($$result)
diff --git a/src/sdk/settingsdialog.cpp b/src/sdk/settingsdialog.cpp
index d6dd34e8c..1a7903403 100644
--- a/src/sdk/settingsdialog.cpp
+++ b/src/sdk/settingsdialog.cpp
@@ -45,6 +45,7 @@
#include <kdupdaterfiledownloader.h>
#include <kdupdaterfiledownloaderfactory.h>
#include <packagemanagercore.h>
+#include <productkeycheck.h>
#include <QtCore/QFile>
@@ -572,6 +573,9 @@ void SettingsDialog::setupRepositoriesTreeWidget()
void SettingsDialog::insertRepositories(const QSet<Repository> repos, QTreeWidgetItem *rootItem)
{
rootItem->setFirstColumnSpanned(true);
- foreach (const Repository &repo, repos)
- rootItem->addChild(new RepositoryItem(repo));
+ foreach (const Repository &repo, repos) {
+ RepositoryItem *item = new RepositoryItem(repo);
+ rootItem->addChild(item);
+ item->setHidden(!ProductKeyCheck::instance(m_core)->isValidRepository(repo));
+ }
}
diff --git a/src/sdk/translations/de_de.ts b/src/sdk/translations/de_de.ts
index a1cc5d2e1..d6f033e69 100644
--- a/src/sdk/translations/de_de.ts
+++ b/src/sdk/translations/de_de.ts
@@ -1542,7 +1542,7 @@ Fehler beim Laden von %2</translation>
<message>
<location filename="../../libs/installer/packagemanagergui.cpp" line="946"/>
<source>Please read the following license agreement. You must accept the terms contained in this agreement before continuing with the installation.</source>
- <translation>Bitte lesen Sie das folgenden Lizenzabkommen. Sie müssen die Bedingungen in diesem Abkommen akzeptieren, um die Installation fortsetzen zu können.</translation>
+ <translation>Bitte lesen Sie das folgende Lizenzabkommen. Sie müssen die Bedingungen in diesem Abkommen akzeptieren, um die Installation fortsetzen zu können.</translation>
</message>
<message>
<location filename="../../libs/installer/packagemanagergui.cpp" line="948"/>
diff --git a/src/sdk/translations/ja_jp.ts b/src/sdk/translations/ja_jp.ts
new file mode 100644
index 000000000..5e34e57e6
--- /dev/null
+++ b/src/sdk/translations/ja_jp.ts
@@ -0,0 +1,2470 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="ja_JP">
+<context>
+ <name>Component</name>
+ <message>
+ <source>Could not open archive %1: %2</source>
+ <translation>アーカイブ %1 を開けませんでした: %2</translation>
+ </message>
+</context>
+<context>
+ <name>Dialog</name>
+ <message>
+ <source>Http authentication required</source>
+ <translation>HTTP ユーザ認証が必要です</translation>
+ </message>
+ <message>
+ <source>You need to supply a Username and Password to access this site.</source>
+ <translation>このサイトにアクセスするにはユーザ名とパスワードが必要です。</translation>
+ </message>
+ <message>
+ <source>Username:</source>
+ <translation>ユーザ名:</translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation>パスワード:</translation>
+ </message>
+ <message>
+ <source>%1 at %2</source>
+ <translation>%2 の %1</translation>
+ </message>
+</context>
+<context>
+ <name>KDJob</name>
+ <message>
+ <source>Canceled</source>
+ <translation>キャンセルしました</translation>
+ </message>
+</context>
+<context>
+ <name>KDSaveFile</name>
+ <message>
+ <source>Append mode not supported.</source>
+ <translation>追記モードに対応していません。</translation>
+ </message>
+ <message>
+ <source>Read-only access not supported.</source>
+ <translation>読み込み専用でアクセスできませんでした。</translation>
+ </message>
+ <message>
+ <source>Could not backup existing file %1: %2</source>
+ <translation>既存のファイル %1 へバックアップできませんでした: %2</translation>
+ </message>
+ <message>
+ <source>TODO</source>
+ <translation>TODO</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::AppendFileOperation</name>
+ <message>
+ <source>Cannot backup file %1: %2</source>
+ <translation>ファイル %1 をバックアップできません: %2</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>2個</translation>
+ </message>
+ <message>
+ <source>Could not open file &apos;%1&apos; for writing: %2</source>
+ <translation>書き込み用にファイル &apos;%1&apos; を開けませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Cannot find backup file for %1.</source>
+ <translation>%1 用のバックアップファイルが見つかりません。</translation>
+ </message>
+ <message>
+ <source>Could not restore backup file for %1.</source>
+ <translation>%1 用のバックアップファイルを復元できませんでした。</translation>
+ </message>
+ <message>
+ <source>Could not restore backup file for %1: %2</source>
+ <translation>%1 用のバックアップファイルを復元できませんでした: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::CopyOperation</name>
+ <message>
+ <source>Could not backup file %1.</source>
+ <translation>ファイル %1 をバックアップできませんでした。</translation>
+ </message>
+ <message>
+ <source>Invalid arguments: %1 arguments given, 2 expected.</source>
+ <translation>無効な引数: %1個の引数が渡されましたが、必要なのは2個です。</translation>
+ </message>
+ <message>
+ <source>Could not copy a none existing file: %1</source>
+ <translation>存在しないファイルはコピーできません: %1</translation>
+ </message>
+ <message>
+ <source>Could not remove destination file %1: %2</source>
+ <translation>対象ファイル %1 を削除できませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not copy %1 to %2: %3</source>
+ <translation>%1 を %2 にコピーできませんでした: %3</translation>
+ </message>
+ <message>
+ <source>Could not delete file %1: %2</source>
+ <translation>ファイル %1 を削除できませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not restore backup file into %1: %2</source>
+ <translation>バックアップファイルを %1 へ復元できませんでした: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::DeleteOperation</name>
+ <message>
+ <source>Cannot create backup of %1: %2</source>
+ <translation>%1 のバックアップを作成できません: %2</translation>
+ </message>
+ <message>
+ <source>Invalid arguments: %1 arguments given, 1 expected.</source>
+ <translation>無効な引数: %1個の引数が渡されましたが、必要なのは1個です。</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for %1: %2</source>
+ <translation>%1 用のバックアップファイルを復元できません: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::FileDownloader</name>
+ <message>
+ <source>Download canceled.</source>
+ <translation>ダウンロードをキャンセルしました。</translation>
+ </message>
+ <message>
+ <source>Cryptographic hashes do not match.</source>
+ <translation>暗号学的ハッシュの値が合致しません。</translation>
+ </message>
+ <message>
+ <source>Download finished.</source>
+ <translation>ダウンロードが完了しました。</translation>
+ </message>
+ <message>
+ <source> - unknown time remaining.</source>
+ <translation> - 残り時間: 不明。</translation>
+ </message>
+ <message>
+ <source> of </source>
+ <translation> / </translation>
+ </message>
+ <message>
+ <source> downloaded.</source>
+ <translation> ダウンロードしました。</translation>
+ </message>
+ <message>
+ <source>/sec</source>
+ <translation>/秒</translation>
+ </message>
+ <message>
+ <source> day</source>
+ <translation>日</translation>
+ </message>
+ <message>
+ <source> days</source>
+ <translation>日</translation>
+ </message>
+ <message>
+ <source> hour</source>
+ <translation>時間</translation>
+ </message>
+ <message>
+ <source> hours</source>
+ <translation>時間</translation>
+ </message>
+ <message>
+ <source> minute</source>
+ <translation>分</translation>
+ </message>
+ <message>
+ <source> minutes</source>
+ <translation>分</translation>
+ </message>
+ <message>
+ <source> second</source>
+ <translation> 秒</translation>
+ </message>
+ <message>
+ <source> seconds</source>
+ <translation> 秒</translation>
+ </message>
+ <message>
+ <source> - </source>
+ <translation> - </translation>
+ </message>
+ <message>
+ <source> remaining.</source>
+ <translation>の残り時間。</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::HttpDownloader</name>
+ <message>
+ <source>Cannot download %1: Writing to file &apos;%2&apos; failed: %3</source>
+ <translation>%1 をダウンロードできません: ファイル &apos;%2&apos; への書き込みに失敗しました: %3</translation>
+ </message>
+ <message>
+ <source>Cannot download %1: Could not create %2: %3</source>
+ <translation>%1 をダウンロードできません: %2 を作成できませんでした: %3</translation>
+ </message>
+ <message>
+ <source>%1 at %2</source>
+ <translation>%2 の %1</translation>
+ </message>
+ <message>
+ <source>Authentication request canceled.</source>
+ <translation>認証要求がキャンセルされました。</translation>
+ </message>
+ <message>
+ <source>Secure Connection Failed</source>
+ <translation>安全な接続ができませんでした</translation>
+ </message>
+ <message>
+ <source>There was an error during connection to: %1.</source>
+ <translation>%1 への接続中にエラーが発生しました。</translation>
+ </message>
+ <message>
+ <source>This could be a problem with the server&apos;s configuration, or it could be someone trying to impersonate the server.</source>
+ <translation>サーバーの設定に問題があるか、あるいはサーバーに成りすまそうとしているものがいるかもしれません。</translation>
+ </message>
+ <message>
+ <source>If you have connected to this server successfully in the past or trust this server, the error may be temporary and you can try again.</source>
+ <translation>以前にこのサーバーへの接続に成功しているかこのサーバが信頼できるのであれば、エラーは一時的なものである可能性があります。その場合、再試行してください。</translation>
+ </message>
+ <message>
+ <source>Try again</source>
+ <translation>再試行</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::LocalFileDownloader</name>
+ <message>
+ <source>Cannot open source file &apos;%1&apos; for reading.</source>
+ <translation>読み込み用にソースファイル &apos;%1&apos; を開けません。</translation>
+ </message>
+ <message>
+ <source>Cannot open destination file &apos;%1&apos; for writing.</source>
+ <translation>書き込み用に対象ファイル &apos;%1&apos; を開けません。</translation>
+ </message>
+ <message>
+ <source>Writing to %1 failed: %2</source>
+ <translation>%1 への書き込みに失敗しました: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::MkdirOperation</name>
+ <message>
+ <source>Invalid arguments: %1 arguments given, 1 expected.</source>
+ <translation>無効な引数: %1個の引数が渡されましたが、必要なのは1個です。</translation>
+ </message>
+ <message>
+ <source>Could not create folder %1: Unknown error.</source>
+ <translation>フォルダー %1 を作成できませんでした: 未知のエラーです。</translation>
+ </message>
+ <message>
+ <source>Cannot remove directory %1: %2</source>
+ <translation>ディレクトリ %1 を削除できません: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::MoveOperation</name>
+ <message>
+ <source>Could not backup file %1.</source>
+ <translation>ファイル %1 をバックアップできませんでした。</translation>
+ </message>
+ <message>
+ <source>Invalid arguments: %1 arguments given, 2 expected.</source>
+ <translation>無効な引数: %1個の引数が渡されましたが、必要なのは2個です。</translation>
+ </message>
+ <message>
+ <source>Could not remove destination file %1: %2</source>
+ <translation>対象ファイル %1 を削除できませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not copy %1 to %2: %3</source>
+ <translation>%1 を %2 にコピーできませんでした: %3</translation>
+ </message>
+ <message>
+ <source>Cannot copy %1 to %2: %3</source>
+ <translation>%1 を %2 にコピーできません: %3</translation>
+ </message>
+ <message>
+ <source>Cannot remove file %1.</source>
+ <translation>ファイル %1 を削除できません。</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for %1: %2</source>
+ <translation>%1 用のバックアップファイルを復元できません: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::PackagesInfo</name>
+ <message>
+ <source>%1 contains invalid content: %2</source>
+ <translation>%1 に無効なコンテンツが含まれています: %2</translation>
+ </message>
+ <message>
+ <source>The file %1 does not exist.</source>
+ <translation>ファイル %1 が存在しません。</translation>
+ </message>
+ <message>
+ <source>Could not open %1.</source>
+ <translation>%1 を開けませんでした。</translation>
+ </message>
+ <message>
+ <source>Parse error in %1 at %2, %3: %4</source>
+ <translation>パースエラー %1 の%2行%3列: %4</translation>
+ </message>
+ <message>
+ <source>Root element %1 unexpected, should be &apos;Packages&apos;.</source>
+ <translation>ルートエレメントに %1 は使用できません。&apos;Packages&apos;を使用してください。</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::PrependFileOperation</name>
+ <message>
+ <source>Cannot backup file %1: %2</source>
+ <translation>ファイル %1 をバックアップできません: %2</translation>
+ </message>
+ <message>
+ <source>Invalid arguments: %1 arguments given, 2 expected.</source>
+ <translation>無効な引数: %1個の引数が渡されましたが、必要なのは2個です。</translation>
+ </message>
+ <message>
+ <source>Could not open file %1 for reading: %2</source>
+ <translation>読み込み用にファイル %1 を開けませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not open file %1 for writing: %2</source>
+ <translation>書き込み用にファイル %1 を開けませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Cannot find backup file for %1.</source>
+ <translation>%1 用のバックアップファイルが見つかりません。</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for %1.</source>
+ <translation>%1 用のバックアップファイルを復元できません。</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for %1: %2</source>
+ <translation>%1 用のバックアップファイルを復元できません: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::ResourceFileDownloader</name>
+ <message>
+ <source>Could not read resource file &quot;%1&quot;. Reason:</source>
+ <translation>リソースファイル &quot;%1&quot; を読み込みできませんでした。理由:</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::RmdirOperation</name>
+ <message>
+ <source>Invalid arguments: %1 arguments given, 1 expected.</source>
+ <translation>無効な引数: %1個の引数が渡されましたが、必要なのは1個です。</translation>
+ </message>
+ <message>
+ <source>Could not remove folder %1: The folder does not exist.</source>
+ <translation>フォルダー %1 を削除できませんでした: フォルダーが存在しません。</translation>
+ </message>
+ <message>
+ <source>Could not remove folder %1: %2</source>
+ <translation>フォルダー %1 を削除できませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Cannot recreate directory %1: %2</source>
+ <translation>ディレクトリ %1 が再作成できません: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::Task</name>
+ <message>
+ <source>%1 started</source>
+ <translation>%1 を開始しました</translation>
+ </message>
+ <message>
+ <source>%1 cannot be stopped</source>
+ <translation>%1 は中止できません</translation>
+ </message>
+ <message>
+ <source>Cannot stop task %1</source>
+ <translation>タスク %1 は中止できません</translation>
+ </message>
+ <message>
+ <source>%1 cannot be paused</source>
+ <translation>%1 は一時停止できません</translation>
+ </message>
+ <message>
+ <source>Cannot pause task %1</source>
+ <translation>タスク %1 は一時停止できません</translation>
+ </message>
+ <message>
+ <source>Cannot resume task %1</source>
+ <translation>タスク %1 は再開できません</translation>
+ </message>
+ <message>
+ <source>%1 done</source>
+ <translation>%1 が終了しました</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::UpdateFinder</name>
+ <message>
+ <source>Could not access the package information of this application.</source>
+ <translation>このアプリケーションのパッケージ情報にアクセスできませんでした。</translation>
+ </message>
+ <message>
+ <source>Could not access the update sources information of this application.</source>
+ <translation>このアプリケーションの更新元情報にアクセスできませんでした。</translation>
+ </message>
+ <message>
+ <source>Downloading Updates.xml from update sources.</source>
+ <translation>更新元から Updates.xml をダウンロードしています。</translation>
+ </message>
+ <message>
+ <source>Could not download updates from %1 (&apos;%2&apos;)</source>
+ <translation>%1(&apos;%2)から更新をダウンロードできませんでした</translation>
+ </message>
+ <message>
+ <source>Updates.xml file(s) downloaded from update sources.</source>
+ <translation>更新元から Updates.xml ファイルをダウンロードしました。</translation>
+ </message>
+ <message>
+ <source>Computing applicable updates.</source>
+ <translation>更新を適用しています。</translation>
+ </message>
+ <message>
+ <source>Application updates computed.</source>
+ <translation>アプリケーションに更新を適用しました。</translation>
+ </message>
+ <message>
+ <source>%1 updates found.</source>
+ <translation>%1個の更新が見つかりました。</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::UpdateSourcesInfo</name>
+ <message>
+ <source>%1 contains invalid content: %2</source>
+ <translation>%1 に無効なコンテンツが含まれています: %2</translation>
+ </message>
+ <message>
+ <source>Could not read &quot;%1&quot;</source>
+ <translation>&quot;%1&quot; を読み込めませんでした</translation>
+ </message>
+ <message>
+ <source>XML Parse error in %1 at %2, %3: %4</source>
+ <translation>XMLパースエラー %1 の%2行%3列: %4</translation>
+ </message>
+ <message>
+ <source>Root element %1 unexpected, should be &quot;UpdateSources&quot;</source>
+ <translation>ルートエレメントに %1 は使用できません。&quot;UpdateSources&quot;を使用してください</translation>
+ </message>
+ <message>
+ <source>Could not save changes to &quot;%1&quot;: %2</source>
+ <translation>&quot;%1&quot; への変更を保存できませんでした: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::UpdatesInfoData</name>
+ <message>
+ <source>Could not read &quot;%1&quot;</source>
+ <translation>&quot;%1&quot; を読み込めませんでした</translation>
+ </message>
+ <message>
+ <source>Parse error in %1 at %2, %3: %4</source>
+ <translation>パースエラー %1 の%2行%3列: %4</translation>
+ </message>
+ <message>
+ <source>Updates.xml contains invalid content: %1</source>
+ <translation>Updates.xml に無効なコンテンツが含まれています: %1</translation>
+ </message>
+ <message>
+ <source>Root element %1 unexpected, should be &quot;Updates&quot;.</source>
+ <translation>ルートエレメントに %1 は使用できません。&quot;Updates&quot;を使用してください。</translation>
+ </message>
+ <message>
+ <source>ApplicationName element is missing.</source>
+ <translation>ApplicationName エレメントがありません。</translation>
+ </message>
+ <message>
+ <source>ApplicationVersion element is missing.</source>
+ <translation>ApplicationVersion エレメントがありません。</translation>
+ </message>
+ <message>
+ <source>PackageUpdate element without Name</source>
+ <translation>PackageUpdate エレメントに Name がありません</translation>
+ </message>
+ <message>
+ <source>PackageUpdate element without Version</source>
+ <translation>PackageUpdate エレメントに Version がありません</translation>
+ </message>
+ <message>
+ <source>PackageUpdate element without ReleaseDate</source>
+ <translation>PackageUpdate エレメントに ReleaseDate がありません</translation>
+ </message>
+</context>
+<context>
+ <name>Lib7z::ExtractItemJob</name>
+ <message>
+ <source>Could not list archive: QIODevice not set or already destroyed.</source>
+ <translation>アーカイブからリストを取得できませんでした: QIODevice が設定されていないか、既に破棄されています。</translation>
+ </message>
+</context>
+<context>
+ <name>Lib7z::ListArchiveJob</name>
+ <message>
+ <source>Could not list archive: QIODevice already destroyed.</source>
+ <translation>アーカイブからリストを取得できませんでした: QIODevice が既に破棄されています。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::AddQtCreatorArrayValueOperation</name>
+ <message>
+ <source>exactly 4</source>
+ <translation>4個</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source> (group, arrayname, key, value)</source>
+ <translation>(グループ, 配列名, キー, 値)</translation>
+ </message>
+ <message>
+ <source>Needed installer object in %1 operation is empty.</source>
+ <translation>%1 のインストーラ作成に必要な操作が見つかりません。</translation>
+ </message>
+ <message>
+ <source>There is no value set for %1 on the installer object.</source>
+ <translation>インストーラの %1 用に値が設定されていません。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::Component</name>
+ <message>
+ <source>Could not open the requested translation file &apos;%1&apos;.</source>
+ <translation>要求された翻訳ファイル &apos;%1&apos; を開けませんでした。</translation>
+ </message>
+ <message>
+ <source>Could not open the requested UI file &apos;%1&apos;. Error: %2</source>
+ <translation>要求された UI ファイル &apos;%1&apos; を開けませんでした。エラー: %2</translation>
+ </message>
+ <message>
+ <source>Could not load the requested UI file &apos;%1&apos;. Error: %2</source>
+ <translation>要求された UI ファイル &apos;%1&apos; をロードできませんでした。エラー: %2</translation>
+ </message>
+ <message>
+ <source>An error has occurred while reading the UI file.</source>
+ <translation>UI ファイルの読み込み中にエラーが発生しました。</translation>
+ </message>
+ <message>
+ <source>Could not open the requested license file &apos;%1&apos;. Error: %2</source>
+ <translation>要求されたライセンスファイル &apos;%1&apos; を開けませんでした。エラー: %2</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+ <message>
+ <source>Error: Operation %1 does not exist</source>
+ <translation>エラー: 操作 %1 は存在しません</translation>
+ </message>
+ <message>
+ <source>Update Info: </source>
+ <translation>更新情報: </translation>
+ </message>
+ <message>
+ <source>Can&apos;t resolve isAutoDependOn in %1</source>
+ <translation>%1 の isAutoDependOn を解決できません</translation>
+ </message>
+ <message>
+ <source>Can&apos;t resolve isDefault in %1</source>
+ <translation>%1 の isDefault を解決できません</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ComponentModel</name>
+ <message>
+ <source>Component Name</source>
+ <translation>コンポーネント名</translation>
+ </message>
+ <message>
+ <source>Installed Version</source>
+ <translation>インストール済みバージョン</translation>
+ </message>
+ <message>
+ <source>New Version</source>
+ <translation>新規バージョン</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation>サイズ</translation>
+ </message>
+ <message>
+ <source>Release Date</source>
+ <translation>リリース日</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ComponentSelectionPage</name>
+ <message>
+ <source>Alt+A</source>
+ <comment>select default components</comment>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Def&amp;ault</source>
+ <translation>デフォルト(&amp;A)</translation>
+ </message>
+ <message>
+ <source>Alt+R</source>
+ <comment>reset to already installed components</comment>
+ <translation>Alt+R</translation>
+ </message>
+ <message>
+ <source>&amp;Reset</source>
+ <translation>リセット(&amp;R)</translation>
+ </message>
+ <message>
+ <source>Alt+S</source>
+ <comment>select all components</comment>
+ <translation>Alt+S</translation>
+ </message>
+ <message>
+ <source>&amp;Select All</source>
+ <translation>すべてを選択(&amp;S)</translation>
+ </message>
+ <message>
+ <source>Alt+D</source>
+ <comment>deselect all components</comment>
+ <translation>Alt+D</translation>
+ </message>
+ <message>
+ <source>&amp;Deselect All</source>
+ <translation>すべての選択を解除(&amp;D)</translation>
+ </message>
+ <message>
+ <source>This component will occupy approximately %1 on your hard disk drive.</source>
+ <translation>このコンポーネントはハードディスク上におよそ %1 必要とします。</translation>
+ </message>
+ <message>
+ <source>Select Components</source>
+ <translation>コンポーネントの選択</translation>
+ </message>
+ <message>
+ <source>Please select the components you want to update.</source>
+ <translation>更新したいコンポーネントを選択してください。</translation>
+ </message>
+ <message>
+ <source>Please select the components you want to install.</source>
+ <translation>インストールしたいコンポーネントを選択してください。</translation>
+ </message>
+ <message>
+ <source>Please select the components you want to uninstall.</source>
+ <translation>アンインストールしたいコンポーネントを選択してください。</translation>
+ </message>
+ <message>
+ <source>Select the components to install. Deselect installed components to uninstall them.</source>
+ <translation>インストールするコンポーネントを選択してください。インストール済みのコンポーネントをアンインストールする場合は選択を解除してください。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ConsumeOutputOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>at least 2</source>
+ <translation>少なくとも2個</translation>
+ </message>
+ <message>
+ <source>Needed installer object in %1 operation is empty.</source>
+ <translation>%1 のインストーラ作成に必要な操作が見つかりません。</translation>
+ </message>
+ <message>
+ <source>Can not save the output of %1 to an empty installer key value.</source>
+ <translation>インストーラのキーの値が空のため、%1 の出力を保存できません。</translation>
+ </message>
+ <message>
+ <source>File &apos;%1&apos; does not exist or is not an executable binary.</source>
+ <translation>ファイル &apos;%1&apos; が存在しないか、実行可能なバイナリではありません。</translation>
+ </message>
+ <message>
+ <source>Running &apos;%1&apos; resulted in a crash.</source>
+ <translation>&apos;%1&apos; の実行中にクラッシュしました。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CopyDirectoryOperation</name>
+ <message>
+ <source>2 or 3</source>
+ <translation>2あるいは3個</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source> (&lt;source&gt; &lt;target&gt; [forceOverwrite])</source>
+ <translation> (&lt;ソース&gt; &lt;ターゲット&gt; [forceOverwrite])</translation>
+ </message>
+ <message>
+ <source>Invalid argument in %0: Third argument needs to be forceOverwrite, if specified</source>
+ <translation>%0 に無効な引数: 3番目の引数を指定する場合は &quot;forceOverwrite&quot; である必要があります</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: Directories are invalid: %1 %2</source>
+ <translation>%0 に無効な引数: ディレクトリが無効です: %1 %2</translation>
+ </message>
+ <message>
+ <source>Could not create %0</source>
+ <translation>%0 を作成できませんでした</translation>
+ </message>
+ <message>
+ <source>Failed to overwrite %1</source>
+ <translation>%1 に上書きできません</translation>
+ </message>
+ <message>
+ <source>Could not copy %0 to %1, error was: %3</source>
+ <translation>%0 を %1 にコピーできませんでした。エラー: %3</translation>
+ </message>
+ <message>
+ <source>Could not remove %0</source>
+ <translation>%0 を削除できませんでした</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CreateDesktopEntryOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>2個</translation>
+ </message>
+ <message>
+ <source>Failed to overwrite %1</source>
+ <translation>%1 に上書きできません</translation>
+ </message>
+ <message>
+ <source>Could not write Desktop Entry at %1</source>
+ <translation>%1 へデスクトップエントリーを書き込むことができませんでした</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CreateLinkOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>2個</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CreateLocalRepositoryOperation</name>
+ <message>
+ <source>Could not set file permissions %1!</source>
+ <translation>ファイル %1 にアクセス権限を設定できませんでした!</translation>
+ </message>
+ <message>
+ <source>Could not move file %1 to %2. Error: %3</source>
+ <translation>ファイル %1 を %2 へ移動できませんでした。エラー: %3</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>2個</translation>
+ </message>
+ <message>
+ <source>Installer needs to be an offline version: %1.</source>
+ <translation>インストーラはオフラインバージョンである必要があります: %1</translation>
+ </message>
+ <message>
+ <source>Could not open file: %1</source>
+ <translation>ファイルを開けませんでした: %1</translation>
+ </message>
+ <message>
+ <source>Could not read: %1. Error: %2</source>
+ <translation>%1 を読み込みできませんでした。エラー: %2</translation>
+ </message>
+ <message>
+ <source>Could not open file: %1. Error: %2</source>
+ <translation>ファイル %1 を開けませんでした。エラー: %2</translation>
+ </message>
+ <message>
+ <source>Could not create target dir: %1.</source>
+ <translation>ターゲットディレクトリを作成できませんでした: %1</translation>
+ </message>
+ <message>
+ <source>Unknown exception caught: %1.</source>
+ <translation>未知の例外が発生しました: %1</translation>
+ </message>
+ <message>
+ <source>Removing file: %0</source>
+ <translation>ファイルを削除しています: %0</translation>
+ </message>
+ <message>
+ <source>Could not remove %0.</source>
+ <translation>%0 を削除できませんでした。</translation>
+ </message>
+ <message>
+ <source>Cannot remove directory %1: %2</source>
+ <translation>ディレクトリ %1 を削除できません: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CreateShortcutOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>2 or 3</source>
+ <translation>2あるいは3個</translation>
+ </message>
+ <message>
+ <source> (optional: &apos;workingDirectory=...&apos;, &apos;iconPath=...&apos;, &apos;iconId=...&apos;)</source>
+ <translation> (オプション: &apos;workingDirectory=...&apos;, &apos;iconPath=...&apos;, &apos;iconId=...&apos;) </translation>
+ </message>
+ <message>
+ <source>Could not create folder %1: %2.</source>
+ <translation>フォルダー %1 を作成できませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not create link %1: %2</source>
+ <translation>リンク %1 を作成できませんでした: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::DownloadArchivesJob</name>
+ <message>
+ <source>Canceled</source>
+ <translation>キャンセルしました</translation>
+ </message>
+ <message>
+ <source>Downloading hash signature failed.</source>
+ <translation>ハッシュ値のダウンロードに失敗しました。</translation>
+ </message>
+ <message>
+ <source>Download Error</source>
+ <translation>ダウンロードエラー</translation>
+ </message>
+ <message>
+ <source>Hash verification while downloading failed. This is a temporary error, please retry.</source>
+ <translation>ダウンロード中のハッシュ値の照合に失敗しました。これは一時的なエラーですので、再試行してください。</translation>
+ </message>
+ <message>
+ <source>Could not verify Hash</source>
+ <translation>ハッシュ値の照合ができませんでした</translation>
+ </message>
+ <message>
+ <source>Could not download archive: %1 : %2</source>
+ <translation>アーカイブ %1 をダウンロードできませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not fetch archives: %1
+Error while loading %2</source>
+ <translation>アーカイブを取得できませんでした: %1
+%2 の読み込み中にエラーが発生しました</translation>
+ </message>
+ <message>
+ <source>Downloading archive hash for component: %1</source>
+ <translation>コンポーネントのアーカイブハッシュのダウンロード中: %1</translation>
+ </message>
+ <message>
+ <source>Downloading archive for component: %1</source>
+ <translation>コンポーネントのアーカイブのダウンロード中: %1</translation>
+ </message>
+ <message>
+ <source>Scheme not supported: %1 (%2)</source>
+ <translation>このスキームはサポートしてません: %1 (%2)</translation>
+ </message>
+ <message>
+ <source>Could not find component for: %1.</source>
+ <translation>コンポーネント %1 を見つけることができませんでした。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ElevatedExecuteOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>at least 1</source>
+ <translation>少なくとも1個</translation>
+ </message>
+ <message>
+ <source>Execution failed: Could not start detached: &quot;%1&quot;</source>
+ <translation>実行に失敗しました: &quot;%1&quot; をデタッチして起動できませんでした</translation>
+ </message>
+ <message>
+ <source>Execution failed: Could not start: &quot;%1&quot;(%2)</source>
+ <translation>実行に失敗しました: &quot;%1&quot; を起動できませんでした (%2)</translation>
+ </message>
+ <message>
+ <source>Execution failed(Crash): &quot;%1&quot;</source>
+ <translation>実行に失敗しました(クラッシュ): &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <source>Execution failed(Unexpected exit code: %1): &quot;%2&quot;</source>
+ <translation>実行に失敗しました(想定外の終了コード: %1): &quot;%2&quot;</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::EnvironmentVariableOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>2 to 4</source>
+ <translation>2から4個</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ExtractArchiveOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>2個</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ExtractArchiveOperation::Runnable</name>
+ <message>
+ <source>Could not open %1 for reading: %2.</source>
+ <translation>読み込み用に %1 を開けませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Error while extracting &apos;%1&apos;: %2</source>
+ <translation>&apos;%1&apos; の展開中にエラーが発生しました: %2</translation>
+ </message>
+ <message>
+ <source>Unknown exception caught while extracting %1.</source>
+ <translation>%1 の展開中に未知の例外が発生しました。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::FinishedPage</name>
+ <message>
+ <source>Completing the %1 Wizard</source>
+ <translation>%1 のウィザードの完了</translation>
+ </message>
+ <message>
+ <source>Click Done to exit the %1 Wizard.</source>
+ <translation>%1 のウィザードを終了するには「完了」をクリックしてください。</translation>
+ </message>
+ <message>
+ <source>Click Finish to exit the %1 Wizard.</source>
+ <translation>%1 のウィザードを終了するには「完了」をクリックしてください。</translation>
+ </message>
+ <message>
+ <source>Restart</source>
+ <translation>再起動</translation>
+ </message>
+ <message>
+ <source>Run %1 now.</source>
+ <translation>%1 を実行中。</translation>
+ </message>
+ <message>
+ <source>The %1 Wizard failed.</source>
+ <translation>%1 のウィザードに失敗しました。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::GetRepositoryMetaInfoJob</name>
+ <message>
+ <source>Empty repository URL.</source>
+ <translation>リポジトリの URL が空です。</translation>
+ </message>
+ <message>
+ <source>Retrieving component meta information...</source>
+ <translation>コンポーネントのメタ情報を取得中...</translation>
+ </message>
+ <message>
+ <source>Invalid repository URL: %1</source>
+ <translation>無効なリポジトリ URL: %1</translation>
+ </message>
+ <message>
+ <source>URL scheme not supported: %1 (%2)</source>
+ <translation>この URL スキームはサポートしてません: %1 (%2)</translation>
+ </message>
+ <message>
+ <source>Could not move Updates.xml to target location. Error: %1</source>
+ <translation>Updates.xml をターゲットパスへ移動できませんでした。エラー: %1</translation>
+ </message>
+ <message>
+ <source>Could not open Updates.xml for reading. Error: %1</source>
+ <translation>読み込み用に Updates.xml を開けませんでした。エラー: %1</translation>
+ </message>
+ <message>
+ <source>Could not fetch a valid version of Updates.xml from repository: %1. Error: %2</source>
+ <translation>リポジトリ %1 から有効なバージョンの Updates.xml を取得することができませんでした。エラー: %2</translation>
+ </message>
+ <message>
+ <source>Download Error</source>
+ <translation>ダウンロードエラー</translation>
+ </message>
+ <message>
+ <source>Parsing component meta information...</source>
+ <translation>コンポーネントのメタ情報をパース中...</translation>
+ </message>
+ <message>
+ <source>Repository updates received.</source>
+ <translation>リポジトリの更新を取得しました。</translation>
+ </message>
+ <message>
+ <source>Finished updating component meta information.</source>
+ <translation>コンポーネントのメタ情報の更新が完了しました。</translation>
+ </message>
+ <message>
+ <source>Could not fetch Updates.xml from repository: %1. Error: %2</source>
+ <translation>リポジトリ %1 から Updates.xml を取得することができませんでした。エラー: %2</translation>
+ </message>
+ <message>
+ <source>Retrieving component information from remote repository...</source>
+ <translation>リモートのリポジトリからコンポーネントの情報を取得中...</translation>
+ </message>
+ <message>
+ <source>Could not open meta info archive: %1. Error: %2</source>
+ <translation>メタ情報アーカイブ %1 を開けませんでした。エラー: %2</translation>
+ </message>
+ <message>
+ <source>The hash of one component does not match the expected one.</source>
+ <translation>あるコンポーネントのハッシュ値が既定の値と合致しません。</translation>
+ </message>
+ <message>
+ <source>Bad hash.</source>
+ <translation>ハッシュ値が一致しません。</translation>
+ </message>
+ <message>
+ <source>Could not download meta information for component: %1. Error: %2</source>
+ <translation>コンポーネント %1 用のメタ情報をダウンロードできませんでした。エラー: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::GetRepositoryMetaInfoJob::ZipRunnable</name>
+ <message>
+ <source>Error while extracting &apos;%1&apos;: %2</source>
+ <translation>&apos;%1&apos; の展開中にエラーが発生しました: %2</translation>
+ </message>
+ <message>
+ <source>Unknown exception caught while extracting %1.</source>
+ <translation>%1 の展開中に未知の例外が発生しました。</translation>
+ </message>
+ <message>
+ <source>Could not open %1 for reading. Error: %2</source>
+ <translation>読み込み用に %1 を開けませんでした。エラー: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::GlobalSettingsOperation</name>
+ <message>
+ <source>Settings are not writable</source>
+ <translation>設定が書き込み可能ではありません</translation>
+ </message>
+ <message>
+ <source>Failed to write settings</source>
+ <translation>設定の書き込みに失敗しました</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>3 or 4</source>
+ <translation>3あるいは4個</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::InstallIconsOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>1 or 2</source>
+ <translation>1あるいは2個</translation>
+ </message>
+ <message>
+ <source> (Sourcepath, [Vendorprefix])</source>
+ <translation> (ソースパス, [ベンダープレフィックス])</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::IntroductionPage</name>
+ <message>
+ <source>Setup - %1</source>
+ <translation>セットアップ - %1</translation>
+ </message>
+ <message>
+ <source>Welcome to the %1 Setup Wizard.</source>
+ <translation>%1 のセットアップウィザードへようこそ。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::LicenseAgreementPage</name>
+ <message>
+ <source>License Agreement</source>
+ <translation>ライセンス条項の同意</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <comment>agree license</comment>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Please read the following license agreement. You must accept the terms contained in this agreement before continuing with the installation.</source>
+ <translation>下記のライセンス条項をお読みください。本ライセンス条項に同意されない場合、インストールを継続することはできません。</translation>
+ </message>
+ <message>
+ <source>I accept the license.</source>
+ <translation>ライセンスに同意する。</translation>
+ </message>
+ <message>
+ <source>I do not accept the license.</source>
+ <translation>ライセンスに同意しない。</translation>
+ </message>
+ <message>
+ <source>Please read the following license agreements. You must accept the terms contained in these agreements before continuing with the installation.</source>
+ <translation>下記のライセンス条項をお読みください。これらのライセンス条項に同意されない場合、インストールを継続することはできません。</translation>
+ </message>
+ <message>
+ <source>I accept the licenses.</source>
+ <translation>ライセンスに同意する。</translation>
+ </message>
+ <message>
+ <source>I do not accept the licenses.</source>
+ <translation>ライセンスに同意しない。</translation>
+ </message>
+ <message>
+ <source>Alt+D</source>
+ <comment>do not agree license</comment>
+ <translation>Alt+D</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::LicenseOperation</name>
+ <message>
+ <source>No license files found to copy.</source>
+ <translation>コピーするライセンスファイルが見つかりませんでした。</translation>
+ </message>
+ <message>
+ <source>Needed installer object in %1 operation is empty.</source>
+ <translation>%1 のインストーラ作成に必要な操作が見つかりません。</translation>
+ </message>
+ <message>
+ <source>Can not write license file: %1.</source>
+ <translation>ライセンスファイルに書き込みできません: %1</translation>
+ </message>
+ <message>
+ <source>No license files found to delete.</source>
+ <translation>削除するライセンスファイルが見つかりませんでした。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::LineReplaceOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>exactly 3</source>
+ <translation>3個</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::MacReplaceInstallNamesOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>at least 3</source>
+ <translation>少なくとも3個</translation>
+ </message>
+ <message>
+ <source>One of the given arguments is empty. Argument1=%1; Argument2=%2, Argument3=%3</source>
+ <translation>与えられた引数のうち、少なくとも一つが空です。引数1=%1, 引数2=%2, 引数3=%3</translation>
+ </message>
+ <message>
+ <source>Can&apos;t invoke otool. Is Xcode installed?</source>
+ <translation>otool を起動できません。Xcode はインストールされていますか?</translation>
+ </message>
+ <message>
+ <source>Can&apos;t start process %0.</source>
+ <translation>プロセス %0 を起動できません。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::PackageManagerCore</name>
+ <message>
+ <source>Error writing Uninstaller</source>
+ <translation>アンインストーラ書き込み中のエラー</translation>
+ </message>
+ <message>
+ <source>
+Downloading packages...</source>
+ <translation>
+パッケージのダウンロード中...</translation>
+ </message>
+ <message>
+ <source>Installation canceled by user</source>
+ <translation>ユーザによってインストールがキャンセルされました</translation>
+ </message>
+ <message>
+ <source>All downloads finished.</source>
+ <translation>すべてのダウンロードが完了しました。</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+ <message>
+ <source>Cancelling the Installer</source>
+ <translation>インストーラのキャンセル</translation>
+ </message>
+ <message>
+ <source>Authentication Error</source>
+ <translation>認証エラー</translation>
+ </message>
+ <message>
+ <source>Some components could not be removed completely because admin rights could not be acquired: %1.</source>
+ <translation>管理者権限が取得できなかったため、いくつかのコンポーネントを完全に削除することができませんでした: %1</translation>
+ </message>
+ <message>
+ <source>Unknown error.</source>
+ <translation>未知のエラー。</translation>
+ </message>
+ <message>
+ <source>Some components could not be removed completely because an unknown error happened.</source>
+ <translation>未知のエラーが発生したため、いくつかのコンポーネントを完全に削除することができませんでした。</translation>
+ </message>
+ <message>
+ <source>Application not running in Package Manager mode!</source>
+ <translation>アプリケーションがパッケージマネージャモードで動作していません!</translation>
+ </message>
+ <message>
+ <source>No installed packages found.</source>
+ <translation>インストールされたパッケージが見つかりません。</translation>
+ </message>
+ <message>
+ <source>Application running in Uninstaller mode!</source>
+ <translation>アプリケーションはアンインストーラモードで実行中です!</translation>
+ </message>
+ <message>
+ <source>invalid</source>
+ <translation>無効</translation>
+ </message>
+ <message>
+ <source>There is an important update available, please run the updater first.</source>
+ <translation>重要な更新が利用可能です。先にアップデータを実行してください。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::PackageManagerCorePrivate</name>
+ <message>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+ <message>
+ <source>Component(s) added as automatic dependencies</source>
+ <translation>自動的な依存関係の解決により追加されたコンポーネント</translation>
+ </message>
+ <message>
+ <source>Added as dependency for %1.</source>
+ <translation>%1 が依存しているために追加されました。</translation>
+ </message>
+ <message>
+ <source>Component(s) that have resolved Dependencies</source>
+ <translation>依存関係を解決したコンポーネント</translation>
+ </message>
+ <message>
+ <source>Selected Component(s) without Dependencies</source>
+ <translation>選択されたコンポーネントは依存関係がありません</translation>
+ </message>
+ <message>
+ <source>Access error</source>
+ <translation>アクセスエラー</translation>
+ </message>
+ <message>
+ <source>Format error</source>
+ <translation>フォーマットエラー</translation>
+ </message>
+ <message>
+ <source>Could not write installer configuration to %1: %2</source>
+ <translation>インストーラの設定を %1 に書き込めませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Stop Processes</source>
+ <translation>プロセスの停止</translation>
+ </message>
+ <message>
+ <source>These processes should be stopped to continue:
+
+%1</source>
+ <translation>続行するには次のアプリケーションを終了してください:
+
+%1</translation>
+ </message>
+ <message>
+ <source>Installation canceled by user</source>
+ <translation>ユーザによってインストールがキャンセルされました</translation>
+ </message>
+ <message>
+ <source>Writing uninstaller.</source>
+ <translation>アンインストーラを書き込んでいます。</translation>
+ </message>
+ <message>
+ <source>Uninstaller is not a bundle</source>
+ <translation>アンインストーラがバンドル構造ではありません</translation>
+ </message>
+ <message>
+ <source>Could not write uninstaller data to %1: %2</source>
+ <translation>アンインストーラのデータを %1 に書き込めませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not write uninstaller to %1: %2</source>
+ <translation>アンインストーラを %1 に書き込めませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Found a binary data file, but we are the installer and we should read the binary resource from our very own binary!</source>
+ <translation>バイナリデータファイルを発見しました。しかし、インストーラはその内部データからバイナリリソースを読み込むべきです!</translation>
+ </message>
+ <message>
+ <source>Could not write uninstaller binary data to %1: %2</source>
+ <translation>アンインストーラのバイナリデータを %1 に書き込めませんでした: %2</translation>
+ </message>
+ <message>
+ <source>ProductName should be set</source>
+ <translation>ProductName を設定してください</translation>
+ </message>
+ <message>
+ <source>Variable &apos;TargetDir&apos; not set.</source>
+ <translation>&apos;TargetDir&apos; 変数がセットされていません。</translation>
+ </message>
+ <message>
+ <source>Preparing the installation...</source>
+ <translation>インストールの準備中...</translation>
+ </message>
+ <message>
+ <source>It is not possible to install from network location</source>
+ <translation>ネットワークからインストールできません</translation>
+ </message>
+ <message>
+ <source>Creating local repository</source>
+ <translation>ローカルのリポジトリを作成しています</translation>
+ </message>
+ <message>
+ <source>Creating Uninstaller</source>
+ <translation>アンインストーラを作成しています</translation>
+ </message>
+ <message>
+ <source>
+Installation finished!</source>
+ <translation>
+インストールが完了しました!</translation>
+ </message>
+ <message>
+ <source>
+Installation aborted!</source>
+ <translation>
+インストールが中断されました!</translation>
+ </message>
+ <message>
+ <source>It is not possible to run that operation from a network location</source>
+ <translation>ネットーワーク上からこの操作を実行することはできません</translation>
+ </message>
+ <message>
+ <source>Removing deselected components...</source>
+ <translation>選択解除したコンポーネントを削除中...</translation>
+ </message>
+ <message>
+ <source>
+Update finished!</source>
+ <translation>
+アップデートが完了しました!</translation>
+ </message>
+ <message>
+ <source>
+Update aborted!</source>
+ <translation>
+アップデートが中断されました!</translation>
+ </message>
+ <message>
+ <source>
+Uninstallation completed successfully!</source>
+ <translation>
+アンインストールに成功しました!</translation>
+ </message>
+ <message>
+ <source>
+Uninstallation aborted!</source>
+ <translation>
+アンインストールが中断されました!</translation>
+ </message>
+ <message>
+ <source>
+Installing component %1</source>
+ <translation>
+コンポーネントのインストール中: %1</translation>
+ </message>
+ <message>
+ <source>Installer Error</source>
+ <translation>インストーラエラー</translation>
+ </message>
+ <message>
+ <source>Error during installation process (%1):
+%2</source>
+ <translation>インストール(%1)中にエラーが発生しました: (%2)</translation>
+ </message>
+ <message>
+ <source>Cannot prepare uninstall</source>
+ <translation>アンインストールの準備ができません</translation>
+ </message>
+ <message>
+ <source>Cannot start uninstall</source>
+ <translation>アンインストールを開始できません</translation>
+ </message>
+ <message>
+ <source>Error during uninstallation process:
+%1</source>
+ <translation>アンインストール中にエラーが発生しました: %1</translation>
+ </message>
+ <message>
+ <source>Unknown error</source>
+ <translation>未知のエラー</translation>
+ </message>
+ <message>
+ <source>Could not retrieve remote tree: %1.</source>
+ <translation>リモートのツリーを取得できませんでした: %1</translation>
+ </message>
+ <message>
+ <source>Failure to read packages from: %1.</source>
+ <translation>右記からのパッケージの読み込みに失敗しました: %1</translation>
+ </message>
+ <message>
+ <source>Could not retrieve meta information: %1</source>
+ <translation>メタ情報を取得できませんでした: %1</translation>
+ </message>
+ <message>
+ <source>Could not add temporary update source information.</source>
+ <translation>一時的な更新元情報を追加できませんでした。</translation>
+ </message>
+ <message>
+ <source>Could not find any update source information.</source>
+ <translation>更新元情報が見つかりませんでした。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::PackageManagerGui</name>
+ <message>
+ <source>%1 Setup</source>
+ <translation>%1のセットアップ</translation>
+ </message>
+ <message>
+ <source>Maintain %1</source>
+ <translation>%1のメンテナンス</translation>
+ </message>
+ <message>
+ <source>Question</source>
+ <translation>確認</translation>
+ </message>
+ <message>
+ <source>Do you want to abort the %1 process?</source>
+ <translation>プロセス %1 を中断しますか?</translation>
+ </message>
+ <message>
+ <source>uninstallation</source>
+ <translation>アンインストール</translation>
+ </message>
+ <message>
+ <source>installation</source>
+ <translation>インストール</translation>
+ </message>
+ <message>
+ <source>installer</source>
+ <translation>インストーラ</translation>
+ </message>
+ <message>
+ <source>uninstaller</source>
+ <translation>アンインストーラ</translation>
+ </message>
+ <message>
+ <source>maintenance</source>
+ <translation>メンテナンス</translation>
+ </message>
+ <message>
+ <source>Do you want to quit the %1 application?</source>
+ <translation>アプリケーション %1 を終了しますか?</translation>
+ </message>
+ <message>
+ <source>Settings</source>
+ <translation>設定</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+ <message>
+ <source>It is not possible to install from network location.
+Please copy the installer to a local drive</source>
+ <translation>ネットワーク上からのインストールができません。
+インストーラをローカルドライブにコピーしてください</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::PerformInstallationForm</name>
+ <message>
+ <source>&amp;Show Details</source>
+ <translation>詳細を表示する(&amp;S)</translation>
+ </message>
+ <message>
+ <source>&amp;Hide Details</source>
+ <translation>詳細を隠す(&amp;H)</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::PerformInstallationPage</name>
+ <message>
+ <source>Uninstalling %1</source>
+ <translation>%1のアンインストール</translation>
+ </message>
+ <message>
+ <source>&amp;Update</source>
+ <translation>更新(&amp;U)</translation>
+ </message>
+ <message>
+ <source>Updating components of %1</source>
+ <translation>%1のコンポーネントの更新</translation>
+ </message>
+ <message>
+ <source>&amp;Install</source>
+ <translation>インストール(&amp;I)</translation>
+ </message>
+ <message>
+ <source>Installing %1</source>
+ <translation>%1のインストール</translation>
+ </message>
+ <message>
+ <source>&amp;Uninstall</source>
+ <translation>アンインストール(&amp;U)</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::QtPatchOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>3 or 4</source>
+ <translation>3あるいは4個</translation>
+ </message>
+ <message>
+ <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
+ <translation>&quot;%1&quot; のインストーラ作成に必要な操作が見つかりません。</translation>
+ </message>
+ <message>
+ <source>First argument should be &apos;linux&apos;, &apos;mac&apos; or &apos;windows&apos;. No other type is supported at this time.</source>
+ <translation>最初の引数は &apos;linux&apos;, &apos;mac&apos;, &apos;windows&apos; のいずれかを指定してください。それ以外はサポートしていません。</translation>
+ </message>
+ <message>
+ <source>Could not find the needed QmakeOutputInstallerKey(%1) value on the installer object. The ConsumeOutput operation on the valid qmake needs to be called first.</source>
+ <translation>インストーラに必要な QmakeOutputInstallerKey(%1) の値を見つけることができませんでした。適切な qmake で ConsumeOutput 操作を最初に実行する必要があります。</translation>
+ </message>
+ <message>
+ <source>QMake from the current Qt version
+(%1)is not existing. Please file a bugreport with this dialog at https://bugreports.qt-project.org.</source>
+ <translation>現在の Qt のバージョン(%1)の QMake が見つかりません。このダイアログから https://bugreports.qt-project.org へバグ報告をしてください。</translation>
+ </message>
+ <message>
+ <source>The output of
+%1 -query
+is not parseable. Please file a bugreport with this dialog https://bugreports.qt-project.org.
+output: &quot;%2&quot;</source>
+ <translation>以下の出力がパースできません。
+%1 -query
+このダイアログから https://bugreports.qt-project.org へバグ報告をしてください。
+出力: &quot;%2&quot;</translation>
+ </message>
+ <message>
+ <source>Qt patch error: new Qt dir(%1)
+needs to be less than 255 characters.</source>
+ <translation>Qt パッチエラー: 新しい Qt のパス(%1)
+は255文字以下である必要があります。</translation>
+ </message>
+ <message>
+ <source>Qt patch error: Can not open %1.(%2)</source>
+ <translation>Qt パッチエラー: %1 を開けません。(%2)</translation>
+ </message>
+ <message>
+ <source>The installer was not able to get the unpatched path from
+%1.(maybe it is broken or removed)
+It tried to patch the Qt binaries, but all other files in Qt are unpatched.
+This could result in a broken Qt version.
+Sometimes it helps to restart the installer with a switched off antivirus software.</source>
+ <translation>インストーラはパッチ未適用時のパスを %1 から取得できませんでした。
+(おそらくファイルが壊れているか削除されています)
+Qt のバイナリにパッチを適用しようとしましたが、Qt の他のすべてのファイルに対してパッチは適用されていません。
+このため、この Qt は正常な状態に無い可能性があります。
+アンチウィルスソフトウェアをオフにしてインストーラを再起動することによって改善されるかもしれません。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ReadyForInstallationPage</name>
+ <message>
+ <source>&amp;Show Details</source>
+ <translation>詳細を表示する(&amp;S)</translation>
+ </message>
+ <message>
+ <source>U&amp;ninstall</source>
+ <translation>アンインストール(&amp;N)</translation>
+ </message>
+ <message>
+ <source>Ready to Uninstall</source>
+ <translation>アンインストールの準備完了</translation>
+ </message>
+ <message>
+ <source>Setup is now ready to begin removing %1 from your computer.&lt;br&gt;&lt;font color=&quot;red&quot;&gt;The program directory %2 will be deleted completely&lt;/font&gt;, including all content in that directory!</source>
+ <translation>このコンピュータから %1 を削除する準備ができました。&lt;br&gt;&lt;font color=&quot;red&quot;&gt;このプログラムがインストールされていたディレクトリ %2 は完全に削除されます&lt;/font&gt;。ディレクトリの内容すべてが削除の対象です!</translation>
+ </message>
+ <message>
+ <source>U&amp;pdate</source>
+ <translation>更新(&amp;P)</translation>
+ </message>
+ <message>
+ <source>Ready to Update Packages</source>
+ <translation>パッケージ更新の準備完了</translation>
+ </message>
+ <message>
+ <source>Setup is now ready to begin updating your installation.</source>
+ <translation>インストール済みパッケージを更新する準備ができました。</translation>
+ </message>
+ <message>
+ <source>&amp;Install</source>
+ <translation>インストール(&amp;I)</translation>
+ </message>
+ <message>
+ <source>Ready to Install</source>
+ <translation>インストールの準備完了</translation>
+ </message>
+ <message>
+ <source>Setup is now ready to begin installing %1 on your computer.</source>
+ <translation>このコンピュータに %1 をインストールする準備ができました。</translation>
+ </message>
+ <message>
+ <source>Not enough disk space to store temporary files and the installation! Available space: %1, at least required %2.</source>
+ <translation>ディスクの空き容量が不足しているため、一時ファイルの作成およびインストールができません! 必要な容量 %2 に対して、空き容量は %1 です。</translation>
+ </message>
+ <message>
+ <source>Not enough disk space to store all selected components! Available space: %1, at least required: %2.</source>
+ <translation>ディスクの空き容量が不足しているため、選択されたすべてのコンポーネントをインストールできません! 必要な容量 %2 に対して、空き容量は %1 です。</translation>
+ </message>
+ <message>
+ <source>Not enough disk space to store temporary files! Available space: %1, at least required: %2.</source>
+ <translation>ディスクの空き容量が不足しているため、一時ファイルが作成できません! 必要な容量 %2 に対して、空き容量は %1 です。</translation>
+ </message>
+ <message>
+ <source>The volume you selected for installation seems to have sufficient space for installation, but there will be less than 1% of the volume&apos;s space available afterwards. %1</source>
+ <translation>指定されたディスクの空き容量はインストール可能なレベルだと思われますが、インストール後の空き容量は 1% 以下となる見込みです:。 %1</translation>
+ </message>
+ <message>
+ <source>The volume you selected for installation seems to have sufficient space for installation, but there will be less than 100 MB available afterwards. %1</source>
+ <translation>指定されたディスクの空き容量はインストール可能なレベルだと思われますが、インストール後の空き容量は 100 MB 以下となる見込みです:。 %1</translation>
+ </message>
+ <message>
+ <source>Can not resolve all dependencies!</source>
+ <translation>すべての依存関係を解決できません!</translation>
+ </message>
+ <message>
+ <source>Components about to be removed.</source>
+ <translation>削除されるコンポーネント。</translation>
+ </message>
+ <message>
+ <source>&amp;Hide Details</source>
+ <translation>詳細を隠す(&amp;H)</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::RegisterDefaultDebuggerOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, 2 expected.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは2個です。</translation>
+ </message>
+ <message>
+ <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
+ <translation>&quot;%1&quot; のインストーラ作成に必要な操作が見つかりません。</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>2個</translation>
+ </message>
+ <message>
+ <source>There is no value set for %1 on the installer object.</source>
+ <translation>インストーラの %1 用に値が設定されていません。</translation>
+ </message>
+ <message>
+ <source>Can&apos;t read from tool chains xml file(%1) correctly.</source>
+ <translation>ツールチェイン XML ファイル(%1) を正常に読み込むことができません。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::RegisterFileTypeOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>2 to 5</source>
+ <translation>2から5個</translation>
+ </message>
+ <message>
+ <source>Register File Type: Invalid arguments</source>
+ <translation>ファイル形式の登録: 無効な引数</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::RegisterQtInCreatorQNXOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>at least 5</source>
+ <translation>少なくとも5個</translation>
+ </message>
+ <message>
+ <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
+ <translation>&quot;%1&quot; のインストーラ作成に必要な操作が見つかりません。</translation>
+ </message>
+ <message>
+ <source>There is no value set for %1 on the installer object.</source>
+ <translation>インストーラの %1 用に値が設定されていません。</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, minimum 4 expected.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは少なくとも4個です。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::RegisterToolChainOperation</name>
+ <message>
+ <source>at least 4</source>
+ <translation>少なくとも4個</translation>
+ </message>
+ <message>
+ <source>Needed installer object in &apos;%1&apos; operation is empty.</source>
+ <translation>&apos;%1&apos; のインストーラ作成に必要な操作が見つかりません。</translation>
+ </message>
+ <message>
+ <source>There is no value set for &apos;%1&apos; on the installer object.</source>
+ <translation>インストーラの %1 用に値が設定されていません。</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, minimum 4 expected.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは少なくとも4個です。</translation>
+ </message>
+ <message>
+ <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
+ <translation>&quot;%1&quot; のインストーラ作成に必要な操作が見つかりません。</translation>
+ </message>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>Some arguments are not right in %1 operation.</source>
+ <translation>いくつかの引数が %1 の操作には正しくありません。</translation>
+ </message>
+ <message>
+ <source>Can&apos;t read from tool chains xml file(%1) correctly.</source>
+ <translation>ツールチェイン XML ファイル(%1) を正常に読み込むことができません。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ReplaceOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>exactly 3</source>
+ <translation>3個</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::RestartPage</name>
+ <message>
+ <source>Completing the %1 Setup Wizard</source>
+ <translation>%1 のセットアップウィザードを完了しました</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ScriptEngine</name>
+ <message>
+ <source>Could not open the requested script file at %1: %2.</source>
+ <translation>要求されたスクリプトファイル %1 を開けませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Exception while loading the component script: &apos;%1&apos;</source>
+ <translation>コンポーネントスクリプトのロード中に例外が発生しました: &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <source>Could not load the component script inside a script context: &apos;%1&apos;</source>
+ <translation>コンポーネントスクリプトのコンテキストが正しくロードできませんでした: &apos;%1&apos;</translation>
+ </message>
+ <message>
+ <source>Fatal error while evaluating a script.</source>
+ <translation>スクリプトの評価中に致命的なエラーが発生しました。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SelfRestartOperation</name>
+ <message>
+ <source>Installer object needed in &apos;%1&apos; operation is empty.</source>
+ <translation>&apos;%1&apos; のインストーラ作成に必要な操作が見つかりません。</translation>
+ </message>
+ <message>
+ <source>Self Restart: Only valid within updater or packagemanager mode.</source>
+ <translation>自己再起動: アップデータあるいはパッケージマネージャモードでのみ有効です。</translation>
+ </message>
+ <message>
+ <source>Self Restart: Invalid arguments</source>
+ <translation>自己再起動: 無効な引数</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SetDemosPathOnQtOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>2個</translation>
+ </message>
+ <message>
+ <source>The output of
+&apos;%1 -query&apos;
+is not parseable. Please file a bugreport with this dialog at https://bugreports.qt-project.org.
+output: %2</source>
+ <translation>以下の出力がパースできません。
+%1 -query
+このダイアログから https://bugreports.qt-project.org へバグ報告をしてください。
+出力: &quot;%2&quot;</translation>
+ </message>
+ <message>
+ <source>Qt patch error: new Qt demo path &apos;%1&apos;
+needs to be less than 255 characters.</source>
+ <translation>Qt パッチエラー: 新しい Qt デモのパス &apos;%1&apos;
+は255文字以下である必要があります。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SetExamplesPathOnQtOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>2個</translation>
+ </message>
+ <message>
+ <source>The output of
+&apos;%1 -query&apos;
+is not parseable. Please file a bugreport with this dialog at https://bugreports.qt-project.org.
+output: %2</source>
+ <translation>以下の出力がパースできません。
+%1 -query
+このダイアログから https://bugreports.qt-project.org へバグ報告をしてください。
+出力: &quot;%2&quot;</translation>
+ </message>
+ <message>
+ <source>Qt patch error: new Qt example path &apos;%1&apos;
+needs to be less than 255 characters.</source>
+ <translation>Qt パッチエラー: 新しい Qt サンプルのパス &apos;%1&apos;
+は255文字以下である必要があります。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SetImportsPathOnQtCoreOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>2個</translation>
+ </message>
+ <message>
+ <source>Qt patch error: new Qt imports path &apos;%1&apos;
+needs to be less than 255 characters.</source>
+ <translation>Qt パッチエラー: 新しい Qt の import パス &apos;%1&apos;
+は255文字以下である必要があります。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SetPathOnQtCoreOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>exactly 3</source>
+ <translation>3個</translation>
+ </message>
+ <message>
+ <source>The second type/value needs to be one of: %1</source>
+ <translation>二番目の引数の型あるいは値は右記のいずれかである必要があります: %1</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SetPluginPathOnQtCoreOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>2個</translation>
+ </message>
+ <message>
+ <source>Qt patch error: new Qt plugin path &apos;%1&apos;
+needs to be less than 255 characters.</source>
+ <translation>Qt パッチエラー: 新しい Qt のプラグインパス &apos;%1&apos;
+は255文字以下である必要があります。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SetQtCreatorValueOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>exactly 4</source>
+ <translation>4個</translation>
+ </message>
+ <message>
+ <source> (rootInstallPath, group, key, value)</source>
+ <translation> (ルートインストールパス, グループ, キー, 値)</translation>
+ </message>
+ <message>
+ <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
+ <translation>&quot;%1&quot; のインストーラ作成に必要な操作が見つかりません。</translation>
+ </message>
+ <message>
+ <source>There is no value set for &apos;%1&apos; on the installer object.</source>
+ <translation>インストーラの %1 用に値が設定されていません。</translation>
+ </message>
+ <message>
+ <source>Needed installer object in &apos;%1&apos; operation is empty.</source>
+ <translation>&apos;%1&apos; のインストーラ作成に必要な操作が見つかりません。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SimpleMoveFileOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 に無効な引数: %1個の引数が渡されましたが、必要なのは%2です%3。</translation>
+ </message>
+ <message>
+ <source>exactly 2</source>
+ <translation>2個</translation>
+ </message>
+ <message>
+ <source>None of the arguments can be empty: source &apos;%1&apos;, target &apos;%2&apos;.</source>
+ <translation>どちらの引数も空にはできません: ソース &apos;%1&apos;, ターゲット: &apos;%2&apos;</translation>
+ </message>
+ <message>
+ <source>Can not move source &apos;%1&apos; to target &apos;%2&apos;, because target exists and is not removable.</source>
+ <translation>ソース &apos;%1&apos; をターゲット &apos;%2&apos; に移動できません。ターゲットが存在しており、かつ削除できません。</translation>
+ </message>
+ <message>
+ <source>Can not move source &apos;%1&apos; to target &apos;%2&apos;: %3</source>
+ <translation>ソース &apos;%1&apos; をターゲット &apos;%2&apos; に移動できません: %3</translation>
+ </message>
+ <message>
+ <source>Move &apos;%1&apos; to &apos;%2&apos;.</source>
+ <translation>&apos;%1&apos; を &apos;%2&apos; へ移動。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::StartMenuDirectoryPage</name>
+ <message>
+ <source>Start Menu shortcuts</source>
+ <translation>スタートメニューのショートカット</translation>
+ </message>
+ <message>
+ <source>Select the Start Menu in which you would like to create the program&apos;s shortcuts. You can also enter a name to create a new folder.</source>
+ <translation>プログラムへのショートカットを作成したいスタートメニューを選択してください。新規作成するフォルダ名を入力することもできます。</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::TargetDirectoryPage</name>
+ <message>
+ <source>Installation Folder</source>
+ <translation>インストール先フォルダ</translation>
+ </message>
+ <message>
+ <source>Please specify the folder where %1 will be installed.</source>
+ <translation>%1 をインストールするフォルダを指定してください。</translation>
+ </message>
+ <message>
+ <source>Alt+R</source>
+ <comment>browse file system to choose a file</comment>
+ <translation>Alt+R</translation>
+ </message>
+ <message>
+ <source>B&amp;rowse...</source>
+ <translation>参照(&amp;B)...</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+ <message>
+ <source>The install directory cannot be empty, please specify a valid folder.</source>
+ <translation>インストールディレクトリが殻にできません。有効なフォルダを指定してください。</translation>
+ </message>
+ <message>
+ <source>As the install directory is completely deleted on uninstall, installing in %1 is forbidden.</source>
+ <translation>インストールディレクトリはアンインストール時に完全に削除されるため、%1 へのインストールは許可できません。</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>警告</translation>
+ </message>
+ <message>
+ <source>You have selected an existing, non-empty folder for installation. Note that it will be completely wiped on uninstallation of this application. It is not advisable to install into this folder as installation might fail. Do you want to continue?</source>
+ <translation>インストール先に既存の空ではないフォルダが選択されています。このフォルダはアプリケーションのアンインストール時に完全に消去されることに注意してください。インストールに失敗する可能性もあるため、このフォルダへのインストールは推奨されません。インストールを継続しますか?</translation>
+ </message>
+ <message>
+ <source>Select Installation Folder</source>
+ <translation>インストール先フォルダの選択</translation>
+ </message>
+</context>
+<context>
+ <name>QInstallerCreator::Archive</name>
+ <message>
+ <source>Could not create %1: %2</source>
+ <translation>%1 を作成できませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not open archive file %1 for reading.</source>
+ <translation>読み込み用にアーカイブファイル %1 を開けませんでした。</translation>
+ </message>
+ <message>
+ <source>Could not create archive from %1: Not a file.</source>
+ <translation>%1 からアーカイブを作成できませんでした: ファイルではありません。</translation>
+ </message>
+ <message>
+ <source>Error while packing directory at %1</source>
+ <translation>%1 でディレクトリのパック中にエラーが発生しました</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Searched whole file, no marker found</source>
+ <translation>ファイル全体を検索しましたが、マーカーが見つかりませんでした</translation>
+ </message>
+ <message>
+ <source>Could not seek to %1 in file %2: %3</source>
+ <translation>ファイル %2 の %1 へシークできませんでした: %3</translation>
+ </message>
+ <message>
+ <source>No marker found, stopped after %1.</source>
+ <translation>マーカーが見つからなかったため、%1 で停止しました。</translation>
+ </message>
+ <message>
+ <source>No marker found, unknown exception caught.</source>
+ <translation>マーカーが見つかりませんでした。未知の例外が発生しました。</translation>
+ </message>
+ <message>
+ <source>Cannot create zipped file for path %1: %2</source>
+ <translation>%1 に ZIP ファイルを作成できませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not seek to in-binary resource. (offset: %1, length: %2)</source>
+ <translation>バイナリリソースをシークできませんでした。 (オフセット: %1, 長さ: %2)</translation>
+ </message>
+ <message>
+ <source>Could not register in-binary resource.</source>
+ <translation>バイナリリソースに登録できませんでした。</translation>
+ </message>
+ <message>
+ <source>Could not open binary %1: %2</source>
+ <translation>バイナリ %1 を開けませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not seek to binary layout section.</source>
+ <translation>バイナリレイアウトセクションへシークできませんでした。</translation>
+ </message>
+ <message>
+ <source>Could not seek to metadata index.</source>
+ <translation>メタデータインデックスへシークできませんでした。</translation>
+ </message>
+ <message>
+ <source>Could not seek to operation list.</source>
+ <translation>オペレーションリストへシークできませんでした。</translation>
+ </message>
+ <message>
+ <source>Could not seek to component index information.</source>
+ <translation>コンポーネントインデックス情報へシークできませんでした。</translation>
+ </message>
+ <message>
+ <source>Could not seek to component index.</source>
+ <translation>コンポーネントインデックスへシークできませんでした。</translation>
+ </message>
+ <message>
+ <source>Cannot open file %1 for reading: %2</source>
+ <translation>読み込み用にファイル %1 を開けませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open file %1 for writing: %2</source>
+ <translation>書き込み用にファイル %1 を開けませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Write failed after %1 bytes: %2</source>
+ <translation>%1 バイトの書き込み後にエラーが発生しました: %2</translation>
+ </message>
+ <message>
+ <source>Read failed after %1 bytes: %2</source>
+ <translation>%1 バイトの読み込み後にエラーが発生しました: %2</translation>
+ </message>
+ <message>
+ <source>Could not remove file %1: %2</source>
+ <translation>ファイル %1 を削除できませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not remove folder %1: %2</source>
+ <translation>フォルダー %1 を削除できませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not create folder %1</source>
+ <translation>フォルダー %1 を作成できませんでした</translation>
+ </message>
+ <message>
+ <source>Could not copy file from %1 to %2: %3</source>
+ <translation>ファイル %1 を %2 にコピーできませんでした。エラー: %3</translation>
+ </message>
+ <message>
+ <source>Could not move file from %1 to %2: %3</source>
+ <translation>ファイル %1 を %2 へ移動できませんでした: %3</translation>
+ </message>
+ <message>
+ <source>Could not create folder %1: %2</source>
+ <translation>フォルダー %1 を作成できませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not open temporary file: %1</source>
+ <translation>一時ファイル %1 を開けませんでした</translation>
+ </message>
+ <message>
+ <source>Could not open temporary file for template %1: %2</source>
+ <translation>テンプレート %1 用の一時ファイルを開けませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not create temporary folder for template %1: %2</source>
+ <translation>テンプレート %1 用の一時フォルダを作成できませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not create lock file %1: %2</source>
+ <translation>ロックファイル %1 を作成できませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not write PID to lock file %1: %2</source>
+ <translation>ロックファイル %1 に PID を書き込めませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not lock lock file %1: %2</source>
+ <translation>ロックファイル %1 をロックできませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Could not unlock lock file %1: %2</source>
+ <translation>ロックファイル %1 をアンロックできませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Path exists but is not a folder: %1</source>
+ <translation>パスが存在していますが、フォルダーではありません: %1</translation>
+ </message>
+ <message>
+ <source>Could not create folder: %1</source>
+ <translation>フォルダーを作成できませんでした: %1</translation>
+ </message>
+ <message>
+ <source>Could not create temporary file</source>
+ <translation>一時ファイルを作成できませんでした</translation>
+ </message>
+ <message>
+ <source>Could not retrieve property %1 for item %2</source>
+ <translation>アイテム %2 からプロパティ %1 を取得できませんでした</translation>
+ </message>
+ <message>
+ <source>Property %1 for item %2 not of type VT_FILETIME but %3</source>
+ <translation>アイテム %2 のプロパティ %1 の型が VT_FILETIME ではなく %3 になっています</translation>
+ </message>
+ <message>
+ <source>Could not convert file time to local time</source>
+ <translation>ファイルの時刻をローカルタイムに変換できませんでした</translation>
+ </message>
+ <message>
+ <source>Could not convert local file time to system time</source>
+ <translation>ローカルファイルの時刻をシステムの時刻へ変換できませんでした</translation>
+ </message>
+ <message>
+ <source>No device set for output stream</source>
+ <translation>ストリームを出力するデバイスが指定されていません</translation>
+ </message>
+ <message>
+ <source>Could not load codecs</source>
+ <translation>コーデックをロードできませんでした</translation>
+ </message>
+ <message>
+ <source>Could not retrieve default format</source>
+ <translation>デフォルトフォーマットを取得できませんでした</translation>
+ </message>
+ <message>
+ <source>Could not open archive</source>
+ <translation>アーカイブを開けませんでした</translation>
+ </message>
+ <message>
+ <source>No CArc found</source>
+ <translation>CArc が見つかりません</translation>
+ </message>
+ <message>
+ <source>Could not retrieve number of items in archive</source>
+ <translation>アーカイブ内のアイテム数が取得できませんでした</translation>
+ </message>
+ <message>
+ <source>Could not retrieve path of archive item %1</source>
+ <translation>アーカイブアイテム %1 のパスが取得できませんでした</translation>
+ </message>
+ <message>
+ <source>Unknown exception caught (%1)</source>
+ <translation>未知の例外が発生しました (%1)</translation>
+ </message>
+ <message>
+ <source>Failed</source>
+ <translation>失敗</translation>
+ </message>
+ <message>
+ <source>Could not remove already existing symlink. %1</source>
+ <translation>すでに存在するシンボリックリンクは削除できません: %1</translation>
+ </message>
+ <message>
+ <source>Could not open file: %1 (%2)</source>
+ <translation>ファイルが開けません: %1 (%2)</translation>
+ </message>
+ <message>
+ <source>Could not create symlink at &apos;%1&apos;. Another one is already existing.</source>
+ <translation>&apos;%1&apos; にシンボリックリンクを作成できませんでした。他のリンクがすでに存在します。</translation>
+ </message>
+ <message>
+ <source>Could not read symlink target from file &apos;%1&apos;.</source>
+ <translation>シンボリックリンクの参照先のファイル &apos;%1&apos; を読み込み用に開けませんでした。</translation>
+ </message>
+ <message>
+ <source>Could not create symlink at %1. %2</source>
+ <translation>%1 にシンボリックリンクを作成できませんでした: %2</translation>
+ </message>
+ <message>
+ <source>internal code: %1</source>
+ <translation>内部コード: %1</translation>
+ </message>
+ <message>
+ <source>not enough memory</source>
+ <translation>メモリが不足しています</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>エラー: %1</translation>
+ </message>
+ <message>
+ <source>Could not create archive %1. %2</source>
+ <translation>アーカイブ %1 が作成できませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Error while extracting &apos;%1&apos;: %2</source>
+ <translation>&apos;%1&apos; の展開中にエラーが発生しました: %2</translation>
+ </message>
+ <message>
+ <source>CArc index %1 out of bounds [0, %2]</source>
+ <translation>CArc のインデックス %1 が範囲外です [0, %2]</translation>
+ </message>
+ <message>
+ <source>Item index %1 out of bounds [0, %2]</source>
+ <translation>アイテムのインデックス %1 が範囲外です [0, %2]</translation>
+ </message>
+ <message>
+ <source>Could not create output file for writing: %1</source>
+ <translation>書き込み用に出力ファイルを作成できませんでした: %1</translation>
+ </message>
+ <message>
+ <source>Authorization required</source>
+ <translation>認証要求</translation>
+ </message>
+ <message>
+ <source>Enter your password to authorize for sudo:</source>
+ <translation>sudo の認証用にパスワードを入力してください:</translation>
+ </message>
+ <message>
+ <source>Error acquiring admin rights</source>
+ <translation>管理者権限の取得中にエラーが発生しました</translation>
+ </message>
+ <message>
+ <source>Could not backup file %1</source>
+ <translation>ファイル %1 をバックアップできませんでした</translation>
+ </message>
+ <message>
+ <source>Could not delete file %1</source>
+ <translation>ファイル %1 を削除できませんでした</translation>
+ </message>
+ <message>
+ <source>Could not restore backup file into %1</source>
+ <translation>バックアップファイルを %1 へ復元できませんでした</translation>
+ </message>
+ <message>
+ <source>Failed to overwrite %1: %2</source>
+ <translation>%1 に上書きできません: %2</translation>
+ </message>
+ <message>
+ <source>Registry path %1 is not writable</source>
+ <translation>レジストリのパス %1 に書き込みできません</translation>
+ </message>
+ <message>
+ <source>Could not write to registry path %1</source>
+ <translation>レジストリパス %1 へ書き込めませんでした</translation>
+ </message>
+ <message>
+ <source>Invalid Argument: source folder must not be empty.</source>
+ <translation>無効な引数: ソースフォルダが空ではいけません。</translation>
+ </message>
+ <message>
+ <source>Could not backup file %1: %2</source>
+ <translation>ファイル %1 をバックアップできませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Failed to copy file %1: %2</source>
+ <translation>ファイル %1 へのコピーに失敗しました: %2</translation>
+ </message>
+ <message>
+ <source>Could not create folder at %1: %2</source>
+ <translation>%1 にフォルダーを作成できませんでした: %2</translation>
+ </message>
+ <message>
+ <source>Invalid arguments: %1 arguments given, %2 to %3 expected.</source>
+ <translation>無効な引数: %1個の引数が渡されましたが、必要なのは%2から%3個以内です。</translation>
+ </message>
+ <message>
+ <source>Invalid arguments: %1 arguments given, %2 expected.</source>
+ <translation>無効な引数: %1個の引数が渡されましたが、必要なのは%2個です。</translation>
+ </message>
+ <message>
+ <source>Error while elevating access rights.</source>
+ <translation>アクセス権限の昇格中にエラーが発生しました。</translation>
+ </message>
+ <message>
+ <source>Failed to seek in file %1: %2</source>
+ <translation>ファイル %1 のシークに失敗しました: %2</translation>
+ </message>
+ <message>
+ <source>Failed to open %1 for reading</source>
+ <translation>読み込み用に %1 を開くのに失敗しました</translation>
+ </message>
+ <message>
+ <source>Failed to open %1 for writing</source>
+ <translation>書き込み用に %1 を開くのに失敗しました</translation>
+ </message>
+ <message>
+ <source>Could not create link from %1 to %2.</source>
+ <translation>%1 から %2 へのリンクを作成できませんでした。</translation>
+ </message>
+ <message>
+ <source>Could not remove link from %1 to %2.</source>
+ <translation>%1 から %2 へのリンクを削除できませんでした。</translation>
+ </message>
+ <message>
+ <source>Authorization Error</source>
+ <translation>認証エラー</translation>
+ </message>
+ <message>
+ <source>Registering file types is only supported on Windows.</source>
+ <translation>ファイル形式の登録は Windows でのみサポートしています。</translation>
+ </message>
+ <message>
+ <source>Failed to open &apos;%1&apos; for reading.</source>
+ <translation>読み込み用に &apos;%1&apos; を開くのに失敗しました。</translation>
+ </message>
+ <message>
+ <source>Failed to open &apos;%1&apos; for writing.</source>
+ <translation>書き込み用に &apos;%1&apos; を開くのに失敗しました。</translation>
+ </message>
+ <message>
+ <source>Number of arguments does not match: one is required</source>
+ <translation>引数の数が一致しません: 一つのみ指定してください</translation>
+ </message>
+ <message>
+ <source>Could not get package manager core.</source>
+ <translation>パッケージマネージャのコアを取得できません。</translation>
+ </message>
+ <message>
+ <source>This process should be stopped before continuing: %1</source>
+ <translation>続行するにはこのプロセスを終了してください: %1</translation>
+ </message>
+ <message>
+ <source>These processes should be stopped before continuing: %1</source>
+ <translation>続行するにはこれらのプロセスを終了してください: %1</translation>
+ </message>
+ <message>
+ <source>Couldn&apos;t get authorization.</source>
+ <translation>認証することができませんでした。</translation>
+ </message>
+ <message>
+ <source>Couldn&apos;t get authorization that is needed for continuing the installation.
+Either abort the installation or use the fallback solution by running
+%1
+as root and then clicking ok.</source>
+ <translation>インストールの継続に必要な認証を行うことができませんでした。
+インストールを「中止」するか、別の手段として root で
+%1
+を実行した後に「OK」をクリックしてください。</translation>
+ </message>
+</context>
+<context>
+ <name>Settings</name>
+ <message>
+ <source>Could not open settings file %1 for reading: %2</source>
+ <translation>読み込み用に設定ファイル %1 を開けませんでした: %2</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/src.pro b/src/src.pro
index 0b0c0d1d9..3065e1a97 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,4 +1,4 @@
CONFIG += ordered
TEMPLATE = subdirs
SUBDIRS += libs sdk
-TRANSLATIONS += sdk/translations/de_de.ts sdk/translations/en_us.ts sdk/translations/ru_ru.ts sdk/translations/zh_cn.ts
+TRANSLATIONS += sdk/translations/de_de.ts sdk/translations/en_us.ts sdk/translations/ru_ru.ts sdk/translations/zh_cn.ts sdk/translations/ja_jp.ts
diff --git a/tests/auto/installer/installer.pro b/tests/auto/installer/installer.pro
index f96e5f420..5873a8db8 100644
--- a/tests/auto/installer/installer.pro
+++ b/tests/auto/installer/installer.pro
@@ -11,4 +11,6 @@ SUBDIRS += \
scriptengine \
consumeoutputoperationtest \
mkdiroperationtest \
- copyoperationtest \ No newline at end of file
+ copyoperationtest \
+ solver
+
diff --git a/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp b/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp
index fd427400d..8eef8d2b2 100644
--- a/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp
+++ b/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp
@@ -90,14 +90,14 @@ private slots:
QFETCH(QString, directory);
QString path = QDir::current().path() + QDir::toNativeSeparators(directory);
- QVERIFY2(!QDir(path).exists(), path.toAscii());
+ QVERIFY2(!QDir(path).exists(), path.toLatin1());
MkdirOperation op;
op.setArguments(QStringList() << path);
op.backup();
- QVERIFY2(op.performOperation(), op.errorString().toAscii());
- QVERIFY2(QDir(path).exists(), path.toAscii());
- QVERIFY2(op.undoOperation(), op.errorString().toAscii());
- QVERIFY2(!QDir(path).exists(), path.toAscii());
+ QVERIFY2(op.performOperation(), op.errorString().toLatin1());
+ QVERIFY2(QDir(path).exists(), path.toLatin1());
+ QVERIFY2(op.undoOperation(), op.errorString().toLatin1());
+ QVERIFY2(!QDir(path).exists(), path.toLatin1());
}
void testCreateDirectory_customFile_data()
@@ -116,23 +116,23 @@ private slots:
QString path = QDir::current().path() + QDir::toNativeSeparators(directory);
QString filepath = QDir::current().path() + QDir::toNativeSeparators(filename);
- QVERIFY2(!QDir(path).exists(), path.toAscii());
+ QVERIFY2(!QDir(path).exists(), path.toLatin1());
MkdirOperation op;
op.setArguments(QStringList() << path);
op.backup();
- QVERIFY2(op.performOperation(), op.errorString().toAscii());
- QVERIFY2(QDir(path).exists(), path.toAscii());
+ QVERIFY2(op.performOperation(), op.errorString().toLatin1());
+ QVERIFY2(QDir(path).exists(), path.toLatin1());
QFile file(filepath);
file.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream out(&file);
out << "This file is generated by QTest\n";
file.close();
- QVERIFY2(!op.undoOperation(), op.errorString().toAscii());
- QVERIFY2(file.exists(), filepath.toAscii());
+ QVERIFY2(!op.undoOperation(), op.errorString().toLatin1());
+ QVERIFY2(file.exists(), filepath.toLatin1());
QVERIFY2(QDir(filepath).remove(filepath), "Could not remove file");
- QVERIFY2(!file.exists(), filepath.toAscii());
- QVERIFY2(op.undoOperation(), op.errorString().toAscii());
- QVERIFY2(!QDir(path).exists(), path.toAscii());
+ QVERIFY2(!file.exists(), filepath.toLatin1());
+ QVERIFY2(op.undoOperation(), op.errorString().toLatin1());
+ QVERIFY2(!QDir(path).exists(), path.toLatin1());
}
void testCreateDirectory_customFile_force_data()
@@ -147,20 +147,20 @@ private slots:
QString path = QDir::current().path() + QDir::toNativeSeparators(directory);
QString filepath = QDir::current().path() + QDir::toNativeSeparators(filename);
- QVERIFY2(!QDir(path).exists(), path.toAscii());
+ QVERIFY2(!QDir(path).exists(), path.toLatin1());
MkdirOperation op;
op.setArguments(QStringList() << path);
op.setValue("forceremoval",true);
op.backup();
- QVERIFY2(op.performOperation(), op.errorString().toAscii());
- QVERIFY2(QDir(path).exists(), path.toAscii());
+ QVERIFY2(op.performOperation(), op.errorString().toLatin1());
+ QVERIFY2(QDir(path).exists(), path.toLatin1());
QFile file(filepath);
file.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream out(&file);
out << "This file is generated by QTest\n";
file.close();
- QVERIFY2(op.undoOperation(), op.errorString().toAscii());
- QVERIFY2(!file.exists(), path.toAscii());
+ QVERIFY2(op.undoOperation(), op.errorString().toLatin1());
+ QVERIFY2(!file.exists(), path.toLatin1());
}
};
diff --git a/tests/auto/installer/solver/solver.pro b/tests/auto/installer/solver/solver.pro
new file mode 100644
index 000000000..0094bc090
--- /dev/null
+++ b/tests/auto/installer/solver/solver.pro
@@ -0,0 +1,5 @@
+include(../../qttest.pri)
+
+QT -= gui
+
+SOURCES += tst_solver.cpp
diff --git a/tests/auto/installer/solver/tst_solver.cpp b/tests/auto/installer/solver/tst_solver.cpp
new file mode 100644
index 000000000..f0596b31e
--- /dev/null
+++ b/tests/auto/installer/solver/tst_solver.cpp
@@ -0,0 +1,134 @@
+/**************************************************************************
+**
+** Copyright (C) 2012-2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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.
+**
+** 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, 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.
+**
+** 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 "graph.h"
+
+#include <QTest>
+
+using namespace QInstaller;
+
+class Data {
+public:
+ Data() {}
+ explicit Data(const QString &data)
+ : m_data(data) {}
+ inline uint qHash(const Data &test);
+ QString data() const { return m_data; }
+ bool operator==(const Data &rhs) const { return m_data == rhs.m_data; }
+ const Data &operator=(const Data &rhs) { if (this != &rhs) { m_data = rhs.m_data; } return *this; }
+
+private:
+ QString m_data;
+};
+inline uint qHash(const Data &data)
+{
+ return qHash(data.data());
+}
+
+
+class tst_Solver : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ // TODO: add failing cases
+ void sortGraph()
+ {
+ Graph<QString> graph;
+ graph.addNode("Hut");
+ graph.addEdge("Jacke", "Shirt");
+ graph.addEdge("Guertel", "Hose");
+ graph.addEdge("Guertel", "Shirt");
+ graph.addEdge("Shirt", "Socken");
+ graph.addEdge("Socken", "Unterwaesche");
+ graph.addEdge("Shirt", "Unterwaesche");
+ graph.addEdges("Hose", QStringList() << "Unterwaesche" << "Socken");
+ graph.addEdges("Krawatte", QStringList() << "Shirt" << "Hose" << "Guertel");
+ graph.addEdges("Schuhe", QStringList() << "Socken" << "Unterwaesche" << "Hose");
+ graph.addEdges("Jacke", QStringList() << "Hose" << "Shirt" << "Guertel" << "Schuhe" << "Krawatte");
+
+ QList<QString> resolved = graph.sort();
+ foreach (const QString &value, resolved)
+ qDebug(qPrintable(value));
+ }
+
+ void sortGraphReverse()
+ {
+ Graph<QString> graph;
+ graph.addEdge("Krawatte", "Jacke");
+ graph.addEdge("Guertel", "Jacke");
+ graph.addEdge("Shirt", "Guertel");
+ graph.addEdges("Shirt", QList<QString>() << "Krawatte" << "Schuhe");
+ graph.addEdges("Hose", QList<QString>() << "Schuhe" << "Guertel" << "Shirt");
+ graph.addEdges("Socken", QList<QString>() << "Schuhe" << "Hose");
+ graph.addEdges("Unterwaesche", QList<QString>() << "Socken" << "Hose" << "Guertel" << "Shirt"
+ << "Krawatte" << "Schuhe");
+
+ QList<QString> resolved = graph.sortReverse();
+ foreach (const QString &value, resolved)
+ qDebug(qPrintable(value));
+ }
+
+ void sortGraphCycle()
+ {
+ Data a("A"), b("B"), c("C"), d("D"), e("E");
+
+ Graph<Data> graph;
+ graph.addEdge(a, b);
+ graph.addEdge(b, c);
+ graph.addEdge(c, d);
+ graph.addEdge(d, e);
+ graph.addEdge(e, a);
+
+ QList<Data> resolved = graph.sort();
+ foreach (const Data &value, resolved)
+ qDebug(qPrintable(value.data()));
+
+ QPair<Data, Data> cycle = graph.cycle();
+ qDebug("Found cycle: %s", graph.hasCycle() ? "true" : "false");
+ qDebug("(%s) has a indirect dependency on (%s).", qPrintable(cycle.second.data()),
+ qPrintable(cycle.first.data()));
+ }
+};
+
+QTEST_MAIN(tst_Solver)
+
+#include "tst_solver.moc"
diff --git a/tools/binarycreator/binarycreator.cpp b/tools/binarycreator/binarycreator.cpp
index 14359c41c..a87cf46f6 100644
--- a/tools/binarycreator/binarycreator.cpp
+++ b/tools/binarycreator/binarycreator.cpp
@@ -685,7 +685,7 @@ int main(int argc, char **argv)
}
if (onlineOnly) {
- filteredPackages.append(QLatin1String("XXXXXXXXXXXXXXXXX_online_XXXXXXXXXXXXXXXXX"));
+ filteredPackages.append(QLatin1String("X_fake_filter_component_for_online_only_installer_X"));
ftype = QInstallerTools::Include;
}
@@ -738,7 +738,7 @@ int main(int argc, char **argv)
comp.setName(info.name.toUtf8());
qDebug() << "Creating component info for" << info.name;
- foreach (const QString &archive, info.copiedArchives) {
+ foreach (const QString &archive, info.copiedFiles) {
const QSharedPointer<Archive> arch(new Archive(archive));
qDebug() << QString::fromLatin1("Appending %1 (%2)").arg(archive,
humanReadableSize(arch->size()));
diff --git a/tools/common/repositorygen.cpp b/tools/common/repositorygen.cpp
index 6fec75039..609844829 100644
--- a/tools/common/repositorygen.cpp
+++ b/tools/common/repositorygen.cpp
@@ -201,6 +201,7 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
bool foundDefault = false;
bool foundVirtual = false;
bool foundDisplayName = false;
+ bool foundDownloadableArchives = false;
const QDomNode package = packageXml.firstChildElement(QLatin1String("Package"));
const QDomNodeList childNodes = package.childNodes();
for (int i = 0; i < childNodes.count(); ++i) {
@@ -213,6 +214,8 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
foundVirtual = true;
if (key == QLatin1String("DisplayName"))
foundDisplayName = true;
+ if (key == QLatin1String("DownloadableArchives"))
+ foundDownloadableArchives = true;
if (node.isComment() || blackList.contains(key))
continue; // just skip comments and some tags...
@@ -230,7 +233,8 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
}
if (!foundDisplayName) {
- qWarning() << "No DisplayName tag found, using component Name instead.";
+ qWarning() << QString::fromLatin1("No DisplayName tag found at '%1', using component Name instead."
+ ).arg(info.name);
QDomElement displayNameElement = doc.createElement(QLatin1String("DisplayName"));
update.appendChild(displayNameElement).appendChild(doc.createTextNode(info.name));
}
@@ -295,6 +299,11 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
QTextStream in(&scriptFile);
scriptContent = in.readAll();
}
+
+ // if the user isn't aware of the downloadable archives value we will add it automatically later
+ foundDownloadableArchives |= scriptContent.contains(QLatin1String("addDownloadableArchive"))
+ || scriptContent.contains(QLatin1String("removeDownloadableArchive"));
+
static QScriptEngine testScriptEngine;
testScriptEngine.evaluate(scriptContent, scriptFile.fileName());
if (testScriptEngine.hasUncaughtException()) {
@@ -312,6 +321,21 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
copyWithException(scriptFile.fileName(), toLocation, QLatin1String("script"));
}
+ // write DownloadableArchives tag if that is missed by the user
+ if (!foundDownloadableArchives && !info.copiedFiles.isEmpty()) {
+ QStringList realContentFiles;
+ foreach (const QString &filePath, info.copiedFiles) {
+ if (!filePath.endsWith(QLatin1String(".sha1"), Qt::CaseInsensitive)) {
+ const QString fileName = QFileInfo(filePath).fileName();
+ // remove unnecessary version string from filename and add it to the list
+ realContentFiles.append(fileName.mid(info.version.count()));
+ }
+ }
+
+ update.appendChild(doc.createElement(QLatin1String("DownloadableArchives"))).appendChild(doc
+ .createTextNode(realContentFiles.join(QChar::fromLatin1(','))));
+ }
+
// copy user interfaces
const QStringList uiFiles = copyFilesFromNode(QLatin1String("UserInterfaces"),
QLatin1String("UserInterface"), QString(), QLatin1String("user interface"), package, info,
@@ -447,7 +471,8 @@ PackageInfoVector QInstallerTools::createListOfPackages(const QStringList &packa
qDebug() << QString::fromLatin1("- it provides the package %1 - %2").arg(info.name, info.version);
}
- if (!packagesToFilter->isEmpty()) {
+ if (!packagesToFilter->isEmpty() && packagesToFilter->at(0) != QString::fromLatin1(
+ "X_fake_filter_component_for_online_only_installer_X")) {
qWarning() << "The following explicitly given packages could not be found\n in package directory:" << *packagesToFilter;
}
@@ -583,7 +608,7 @@ void QInstallerTools::copyComponentData(const QStringList &packageDirs, const QS
}
foreach (const QString &target, compressedFiles) {
- (*infos)[i].copiedArchives.append(target);
+ (*infos)[i].copiedFiles.append(target);
QFile archiveFile(target);
QFile archiveHashFile(archiveFile.fileName() + QLatin1String(".sha1"));
@@ -600,7 +625,7 @@ void QInstallerTools::copyComponentData(const QStringList &packageDirs, const QS
QInstaller::openForWrite(&archiveHashFile, archiveHashFile.fileName());
archiveHashFile.write(hashOfArchiveData);
qDebug() << "Generated sha1 hash:" << hashOfArchiveData;
- (*infos)[i].copiedArchives.append(archiveHashFile.fileName());
+ (*infos)[i].copiedFiles.append(archiveHashFile.fileName());
archiveHashFile.close();
} catch (const QInstaller::Error &/*e*/) {
archiveFile.close();
diff --git a/tools/common/repositorygen.h b/tools/common/repositorygen.h
index 300ad3ca1..c7bdfa457 100644
--- a/tools/common/repositorygen.h
+++ b/tools/common/repositorygen.h
@@ -55,7 +55,7 @@ struct PackageInfo
QString version;
QString directory;
QStringList dependencies;
- QStringList copiedArchives;
+ QStringList copiedFiles;
};
typedef QVector<PackageInfo> PackageInfoVector;
diff --git a/tools/repogen/repogen.cpp b/tools/repogen/repogen.cpp
index 638325ae1..549fccb05 100644
--- a/tools/repogen/repogen.cpp
+++ b/tools/repogen/repogen.cpp
@@ -130,7 +130,7 @@ int main(int argc, char** argv)
filteredPackages = args.first().split(QLatin1Char(','));
args.removeFirst();
filterType = QInstallerTools::Include;
- } else if (args.first() == QLatin1String("--single") || args.first() == QLatin1String("--update")) {
+ } else if (args.first() == QLatin1String("--update")) {
args.removeFirst();
updateExistingRepository = true;
} else if (args.first() == QLatin1String("-p") || args.first() == QLatin1String("--packages")) {
@@ -169,7 +169,7 @@ int main(int argc, char** argv)
}
if (remove && updateExistingRepository) {
- throw QInstaller::Error(QObject::tr("Argument -r|--remove and --single|--update are mutually "
+ throw QInstaller::Error(QObject::tr("Argument -r|--remove and --update are mutually "
"exclusive!"));
}
@@ -177,7 +177,9 @@ int main(int argc, char** argv)
if (remove)
QInstaller::removeDirectory(repositoryDir);
- if (!updateExistingRepository && QFile::exists(repositoryDir)) {
+ if (!updateExistingRepository && QFile::exists(repositoryDir) && !QDir(repositoryDir).entryList(
+ QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty()) {
+
throw QInstaller::Error(QObject::tr("Repository target folder %1 already exists!")
.arg(repositoryDir));
}