summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog3
-rw-r--r--doc/includes/IFWDoc6
-rw-r--r--src/libs/installer/abstractarchive.cpp2
-rw-r--r--src/libs/installer/createlocalrepositoryoperation.cpp1
-rw-r--r--src/libs/installer/globals.cpp7
-rw-r--r--src/libs/installer/globals.h1
-rw-r--r--src/libs/installer/lib7z_facade.cpp18
-rw-r--r--src/libs/installer/libarchivearchive.cpp130
-rw-r--r--src/libs/installer/libarchivearchive.h11
-rw-r--r--src/libs/installer/libarchivewrapper.cpp13
-rw-r--r--src/libs/installer/libarchivewrapper_p.cpp66
-rw-r--r--src/libs/installer/libarchivewrapper_p.h4
-rw-r--r--src/libs/installer/loggingutils.cpp17
-rw-r--r--src/libs/installer/loggingutils.h2
-rw-r--r--src/libs/installer/protocol.h2
-rw-r--r--src/libs/installer/remoteserverconnection.cpp4
-rw-r--r--src/libs/installer/remoteserverconnection_p.h10
-rw-r--r--src/sdk/commandlineinterface.cpp2
-rw-r--r--src/sdk/sdkapp.h9
-rw-r--r--src/sdk/translations/ifw_ko.ts2771
-rw-r--r--tests/auto/installer/cliinterface/tst_cliinterface.cpp112
-rw-r--r--tests/auto/installer/libarchivearchive/tst_libarchivearchive.cpp68
22 files changed, 360 insertions, 2899 deletions
diff --git a/Changelog b/Changelog
index da8b82447..68d9b319b 100644
--- a/Changelog
+++ b/Changelog
@@ -1,6 +1,6 @@
4.2.0
+- Print essential component information regardless of verbosity (QTIFW-2349)
- Update Chinese translation
-- Add Korean translation
- Update Russian translation
- Update French translation
- Update Japanese translation
@@ -11,7 +11,6 @@
- Update Polish translation file
- Add ability to query used language in script (QTIFW-2208)
- Windows: return the value of "TargetDir" variable with '/' as separator (QTIFW-2344)
-- Show messages from lcPackageInfo logging category regardless of verbosity (QTIFW-2349)
- Fix uncaught exception in InstallIconsOperation::performOperation() (QTIFW-2347)
- Add invokable methods for converting paths to/from native separators (QTIFW-2344)
- binarycreator: support selecting compression level and archive format (QTIFW-1587)
diff --git a/doc/includes/IFWDoc b/doc/includes/IFWDoc
index d4b598a0a..75ed9fb40 100644
--- a/doc/includes/IFWDoc
+++ b/doc/includes/IFWDoc
@@ -46,6 +46,12 @@
#include "lib7z_extract.h"
#include "lib7z_list.h"
#include "lib7z_facade.h"
+#include "lib7zarchive.h"
+#include "libarchivearchive.h"
+#include "libarchivewrapper.h"
+#include "abstractarchive.h"
+#include "archivefactory.h"
+#include "directoryguard.h"
#include "link.h"
#include "messageboxhandler.h"
#include "metadatajob.h"
diff --git a/src/libs/installer/abstractarchive.cpp b/src/libs/installer/abstractarchive.cpp
index dd9b8e625..f2b4300c4 100644
--- a/src/libs/installer/abstractarchive.cpp
+++ b/src/libs/installer/abstractarchive.cpp
@@ -65,7 +65,7 @@ namespace QInstaller {
*/
/*!
- \fn QInstaller::AbstractArchive::completedChanged(quint64 completed, quint64 total)
+ \fn QInstaller::AbstractArchive::completedChanged(const quint64 completed, const quint64 total)
The ratio of \a completed entries from \a total changed. Subclasses should emit
this whenever the progress changes.
diff --git a/src/libs/installer/createlocalrepositoryoperation.cpp b/src/libs/installer/createlocalrepositoryoperation.cpp
index a40838178..576e4fa3d 100644
--- a/src/libs/installer/createlocalrepositoryoperation.cpp
+++ b/src/libs/installer/createlocalrepositoryoperation.cpp
@@ -129,6 +129,7 @@ static QString createArchive(const QString repoPath, const QString &sourceDir, c
throw Error(CreateLocalRepositoryOperation::tr("Cannot create archive \"%1\": %2")
.arg(QDir::toNativeSeparators(archive.fileName()), archiveFile.errorString()));
}
+ archiveFile.close();
removeFiles(sourceDir, helper); // cleanup the files we compressed
if (!archive.rename(sourceDir + fileName)) {
throw Error(CreateLocalRepositoryOperation::tr("Cannot move file \"%1\" to \"%2\": %3")
diff --git a/src/libs/installer/globals.cpp b/src/libs/installer/globals.cpp
index 0da4bc3b6..adf1d2f6e 100644
--- a/src/libs/installer/globals.cpp
+++ b/src/libs/installer/globals.cpp
@@ -33,7 +33,6 @@
const char IFW_SERVER[] = "ifw.server";
const char IFW_INSTALLER_INSTALLLOG[] = "ifw.installer.installlog";
const char IFW_DEVELOPER_BUILD[] = "ifw.developer.build";
-const char IFW_PACKAGE_INFO[] = "ifw.package.info";
// Internal-only, hidden in --help text
const char IFW_PROGRESS_INDICATOR[] = "ifw.progress.indicator";
@@ -61,16 +60,10 @@ namespace QInstaller
\internal
*/
-/*!
- \fn QInstaller::lcPackageInfo()
- \internal
-*/
-
Q_LOGGING_CATEGORY(lcServer, IFW_SERVER)
Q_LOGGING_CATEGORY(lcInstallerInstallLog, IFW_INSTALLER_INSTALLLOG)
Q_LOGGING_CATEGORY(lcProgressIndicator, IFW_PROGRESS_INDICATOR)
Q_LOGGING_CATEGORY(lcDeveloperBuild, IFW_DEVELOPER_BUILD)
-Q_LOGGING_CATEGORY(lcPackageInfo, IFW_PACKAGE_INFO)
/*!
Returns available logging categories.
diff --git a/src/libs/installer/globals.h b/src/libs/installer/globals.h
index 5053f6d9f..b22331e2c 100644
--- a/src/libs/installer/globals.h
+++ b/src/libs/installer/globals.h
@@ -40,7 +40,6 @@ INSTALLER_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcInstallerInstallLog)
INSTALLER_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcProgressIndicator)
INSTALLER_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcDeveloperBuild)
-INSTALLER_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcPackageInfo)
QStringList INSTALLER_EXPORT loggingCategories();
diff --git a/src/libs/installer/lib7z_facade.cpp b/src/libs/installer/lib7z_facade.cpp
index 17176d7b0..6d1b6a57d 100644
--- a/src/libs/installer/lib7z_facade.cpp
+++ b/src/libs/installer/lib7z_facade.cpp
@@ -188,12 +188,6 @@ namespace Lib7z {
Prints string \a s.
*/
-/*!
- \fn bool Lib7z::operator==(const File &lhs, const File &rhs);
-
- Returns \c true if \a lhs and \a rhs are equal; otherwise returns \c false.
-*/
-
// -- 7z init codecs, archives
std::once_flag gOnceFlag;
@@ -770,6 +764,18 @@ STDMETHODIMP ExtractCallback::SetOperationResult(Int32 /*resultEOperationResult*
*/
/*!
+ \typedef Lib7z::Compression
+
+ Synonym for QInstaller::CompressionLevel
+*/
+
+/*!
+ \typedef Lib7z::File
+
+ Synonym for QInstaller::ArchiveEntry
+*/
+
+/*!
\namespace Lib7z
\inmodule QtInstallerFramework
\brief The Lib7z namespace contains miscellaneous identifiers used throughout the Lib7z library.
diff --git a/src/libs/installer/libarchivearchive.cpp b/src/libs/installer/libarchivearchive.cpp
index ad5609490..d3a79bd40 100644
--- a/src/libs/installer/libarchivearchive.cpp
+++ b/src/libs/installer/libarchivearchive.cpp
@@ -32,6 +32,8 @@
#include "errors.h"
#include "globals.h"
+#include <stdio.h>
+
#include <QApplication>
#include <QFileInfo>
#include <QDir>
@@ -93,7 +95,11 @@ void ExtractWorker::extract(const QString &dirPath, const quint64 totalFiles)
foreach (const QString &directory, createdDirs)
emit currentEntryChanged(directory);
- int status = archive_read_open(reader.get(), this, nullptr, readCallback, nullptr);
+ archive_read_set_read_callback(reader.get(), readCallback);
+ archive_read_set_callback_data(reader.get(), this);
+ archive_read_set_seek_callback(reader.get(), seekCallback);
+
+ int status = archive_read_open1(reader.get());
if (status != ARCHIVE_OK) {
m_status = Failure;
emit finished(QLatin1String(archive_error_string(reader.get())));
@@ -117,6 +123,12 @@ void ExtractWorker::extract(const QString &dirPath, const quint64 totalFiles)
const QString outputPath = dirPath + QDir::separator() + QString::fromLocal8Bit(current);
archive_entry_set_pathname(entry, outputPath.toLocal8Bit());
+ const char *hardlink = archive_entry_hardlink(entry);
+ if (hardlink) {
+ const QString hardLinkPath = dirPath + QDir::separator() + QString::fromLocal8Bit(hardlink);
+ archive_entry_set_hardlink(entry, hardLinkPath.toLocal8Bit());
+ }
+
emit currentEntryChanged(outputPath);
if (!writeEntry(reader.get(), writer.get(), entry))
return;
@@ -142,6 +154,12 @@ void ExtractWorker::addDataBlock(const QByteArray buffer)
emit dataReadyForRead();
}
+void ExtractWorker::onFilePositionChanged(qint64 pos)
+{
+ m_lastPos = pos;
+ emit seekReady();
+}
+
void ExtractWorker::cancel()
{
m_status = Canceled;
@@ -177,6 +195,26 @@ ssize_t ExtractWorker::readCallback(archive *reader, void *caller, const void **
return buffer->size();
}
+la_int64_t ExtractWorker::seekCallback(archive *reader, void *caller, la_int64_t offset, int whence)
+{
+ Q_UNUSED(reader)
+
+ ExtractWorker *obj;
+ if (!(obj = static_cast<ExtractWorker *>(caller)))
+ return ARCHIVE_FATAL;
+
+ emit obj->seekRequested(static_cast<qint64>(offset), whence);
+
+ {
+ QEventLoop loop;
+ QTimer::singleShot(30000, &loop, &QEventLoop::quit);
+ connect(obj, &ExtractWorker::seekReady, &loop, &QEventLoop::quit);
+ loop.exec();
+ }
+
+ return static_cast<la_int64_t>(obj->m_lastPos);
+}
+
bool ExtractWorker::writeEntry(archive *reader, archive *writer, archive_entry *entry)
{
int status;
@@ -235,6 +273,13 @@ bool ExtractWorker::writeEntry(archive *reader, archive *writer, archive_entry *
*/
/*!
+ \fn QInstaller::LibArchiveArchive::seekRequested(qint64 offset, int whence)
+
+ Emitted when the worker object requires a seek to \a offset to continue extracting.
+ The \a whence value defines the starting position for \a offset.
+*/
+
+/*!
\fn QInstaller::LibArchiveArchive::workerFinished()
Emitted when the worker object finished extracting an archive.
@@ -267,6 +312,12 @@ bool ExtractWorker::writeEntry(archive *reader, archive *writer, archive_entry *
*/
/*!
+ \fn QInstaller::LibArchiveArchive::workerAboutToSetFilePosition(qint64 pos)
+
+ Emitted when the worker object is about to set new file position \a pos.
+*/
+
+/*!
Constructs an archive object representing an archive file
specified by \a filename with \a parent as the parent object.
*/
@@ -377,7 +428,7 @@ bool LibArchiveArchive::extract(const QString &dirPath, const quint64 totalFiles
foreach (const QString &directory, createdDirs)
emit currentEntryChanged(directory);
- int status = archive_read_open(reader.get(), m_data, nullptr, readCallback, nullptr);
+ int status = archiveReadOpenWithCallbacks(reader.get());
if (status != ARCHIVE_OK)
throw Error(QLatin1String(archive_error_string(reader.get())));
@@ -395,6 +446,12 @@ bool LibArchiveArchive::extract(const QString &dirPath, const quint64 totalFiles
const QString outputPath = dirPath + QDir::separator() + QString::fromLocal8Bit(current);
archive_entry_set_pathname(entry, outputPath.toLocal8Bit());
+ const char *hardlink = archive_entry_hardlink(entry);
+ if (hardlink) {
+ const QString hardLinkPath = dirPath + QDir::separator() + QString::fromLocal8Bit(hardlink);
+ archive_entry_set_hardlink(entry, hardLinkPath.toLocal8Bit());
+ }
+
emit currentEntryChanged(outputPath);
if (!writeEntry(reader.get(), writer.get(), entry))
throw Error(errorString()); // appropriate error string set in writeEntry()
@@ -455,7 +512,7 @@ bool LibArchiveArchive::create(const QStringList &data)
if (status < ARCHIVE_OK)
throw Error(QLatin1String(archive_error_string(writer.get())));
- if (fileOrDir.isDir())
+ if (fileOrDir.isDir() || archive_entry_size(entry.get()) == 0)
continue; // nothing to copy
QFile file(pathWithoutNamespace(QLatin1String(archive_entry_sourcepath(entry.get()))));
@@ -496,7 +553,7 @@ QVector<ArchiveEntry> LibArchiveArchive::list()
QVector<ArchiveEntry> entries;
try {
- int status = archive_read_open(reader.get(), m_data, nullptr, readCallback, nullptr);
+ int status = archiveReadOpenWithCallbacks(reader.get());
if (status != ARCHIVE_OK)
throw Error(QLatin1String(archive_error_string(reader.get())));
@@ -537,7 +594,7 @@ bool LibArchiveArchive::isSupported()
configureReader(reader.get());
try {
- const int status = archive_read_open(reader.get(), m_data, nullptr, readCallback, nullptr);
+ const int status = archiveReadOpenWithCallbacks(reader.get());
if (status != ARCHIVE_OK)
throw Error(QLatin1String(archive_error_string(reader.get())));
} catch (const Error &e) {
@@ -575,6 +632,14 @@ void LibArchiveArchive::workerSetDataAtEnd()
}
/*!
+ Signals the worker object that the client file position changed to \a pos.
+*/
+void LibArchiveArchive::workerSetFilePosition(qint64 pos)
+{
+ emit workerAboutToSetFilePosition(pos);
+}
+
+/*!
Cancels the extract in progress for the worker object.
*/
void LibArchiveArchive::workerCancel()
@@ -672,9 +737,11 @@ void LibArchiveArchive::initExtractWorker()
connect(this, &LibArchiveArchive::workerAboutToExtract, &m_worker, &ExtractWorker::extract);
connect(this, &LibArchiveArchive::workerAboutToAddDataBlock, &m_worker, &ExtractWorker::addDataBlock);
connect(this, &LibArchiveArchive::workerAboutToSetDataAtEnd, &m_worker, &ExtractWorker::dataAtEnd);
+ connect(this, &LibArchiveArchive::workerAboutToSetFilePosition, &m_worker, &ExtractWorker::onFilePositionChanged);
connect(this, &LibArchiveArchive::workerAboutToCancel, &m_worker, &ExtractWorker::cancel);
connect(&m_worker, &ExtractWorker::dataBlockRequested, this, &LibArchiveArchive::dataBlockRequested);
+ connect(&m_worker, &ExtractWorker::seekRequested, this, &LibArchiveArchive::seekRequested);
connect(&m_worker, &ExtractWorker::finished, this, &LibArchiveArchive::onWorkerFinished);
connect(&m_worker, &ExtractWorker::currentEntryChanged, this, &LibArchiveArchive::currentEntryChanged);
@@ -684,6 +751,20 @@ void LibArchiveArchive::initExtractWorker()
}
/*!
+ \internal
+
+ Sets default callbacks for archive \a reader and opens for reading.
+*/
+int LibArchiveArchive::archiveReadOpenWithCallbacks(archive *reader)
+{
+ archive_read_set_read_callback(reader, readCallback);
+ archive_read_set_callback_data(reader, m_data);
+ archive_read_set_seek_callback(reader, seekCallback);
+
+ return archive_read_open1(reader);
+}
+
+/*!
Writes the current \a entry header, then pulls data from the archive \a reader
and writes it to the \a writer handle.
*/
@@ -767,6 +848,43 @@ ssize_t LibArchiveArchive::readCallback(archive *reader, void *archiveData, cons
}
/*!
+ \internal
+
+ Seeks to specified \a offset in the file device in \a archiveData and returns the position.
+ Possible \a whence values are \c SEEK_SET, \c SEEK_CUR, and \c SEEK_END. Returns
+ \c ARCHIVE_FATAL if the seek fails.
+*/
+la_int64_t LibArchiveArchive::seekCallback(archive *reader, void *archiveData, la_int64_t offset, int whence)
+{
+ Q_UNUSED(reader)
+
+ ArchiveData *data;
+ if (!(data = static_cast<ArchiveData *>(archiveData)))
+ return ARCHIVE_FATAL;
+
+ if (!data->file.isOpen() || data->file.isSequential())
+ return ARCHIVE_FATAL;
+
+ switch (whence) {
+ case SEEK_SET: // moves file pointer position to the beginning of the file
+ if (!data->file.seek(offset))
+ return ARCHIVE_FATAL;
+ break;
+ case SEEK_CUR: // moves file pointer position to given location
+ if (!data->file.seek(data->file.pos() + offset))
+ return ARCHIVE_FATAL;
+ break;
+ case SEEK_END: // moves file pointer position to the end of file
+ if (!data->file.seek(data->file.size() + offset))
+ return ARCHIVE_FATAL;
+ break;
+ default:
+ return ARCHIVE_FATAL;
+ }
+ return data->file.pos();
+}
+
+/*!
Returns the \a path to a file or directory, without the Win32 namespace prefix.
On Unix platforms, the \a path is returned unaltered.
*/
@@ -794,7 +912,7 @@ quint64 LibArchiveArchive::totalFiles()
configureReader(reader.get());
try {
- int status = archive_read_open(reader.get(), m_data, nullptr, readCallback, nullptr);
+ int status = archiveReadOpenWithCallbacks(reader.get());
if (status != ARCHIVE_OK)
throw Error(QLatin1String(archive_error_string(reader.get())));
diff --git a/src/libs/installer/libarchivearchive.h b/src/libs/installer/libarchivearchive.h
index e0281e655..796069ed1 100644
--- a/src/libs/installer/libarchivearchive.h
+++ b/src/libs/installer/libarchivearchive.h
@@ -64,12 +64,15 @@ public:
public Q_SLOTS:
void extract(const QString &dirPath, const quint64 totalFiles);
void addDataBlock(const QByteArray buffer);
+ void onFilePositionChanged(qint64 pos);
void cancel();
Q_SIGNALS:
void dataBlockRequested();
void dataAtEnd();
void dataReadyForRead();
+ void seekRequested(qint64 offset, int whence);
+ void seekReady();
void finished(const QString &errorString = QString());
void currentEntryChanged(const QString &filename);
@@ -77,10 +80,12 @@ Q_SIGNALS:
private:
static ssize_t readCallback(archive *reader, void *caller, const void **buff);
+ static la_int64_t seekCallback(archive *reader, void *caller, la_int64_t offset, int whence);
bool writeEntry(archive *reader, archive *writer, archive_entry *entry);
private:
QByteArray m_buffer;
+ qint64 m_lastPos = 0;
Status m_status;
};
@@ -107,16 +112,19 @@ public:
void workerExtract(const QString &dirPath, const quint64 totalFiles);
void workerAddDataBlock(const QByteArray buffer);
void workerSetDataAtEnd();
+ void workerSetFilePosition(qint64 pos);
void workerCancel();
ExtractWorker::Status workerStatus() const;
Q_SIGNALS:
void dataBlockRequested();
+ void seekRequested(qint64 offset, int whence);
void workerFinished();
void workerAboutToExtract(const QString &dirPath, const quint64 totalFiles);
void workerAboutToAddDataBlock(const QByteArray buffer);
void workerAboutToSetDataAtEnd();
+ void workerAboutToSetFilePosition(qint64 pos);
void workerAboutToCancel();
public Q_SLOTS:
@@ -133,11 +141,14 @@ private:
void initExtractWorker();
+ int archiveReadOpenWithCallbacks(archive *reader);
bool writeEntry(archive *reader, archive *writer, archive_entry *entry);
static qint64 readData(QFile *file, char *data, qint64 maxSize);
static ssize_t readCallback(archive *reader, void *archiveData, const void **buff);
+ static la_int64_t seekCallback(archive *reader, void *archiveData, la_int64_t offset, int whence);
+
static QString pathWithoutNamespace(const QString &path);
quint64 totalFiles();
diff --git a/src/libs/installer/libarchivewrapper.cpp b/src/libs/installer/libarchivewrapper.cpp
index c259678ca..9fbbeb889 100644
--- a/src/libs/installer/libarchivewrapper.cpp
+++ b/src/libs/installer/libarchivewrapper.cpp
@@ -45,19 +45,6 @@ namespace QInstaller {
*/
/*!
- \fn QInstaller::LibArchiveWrapper::currentEntryChanged(const QString &filename)
-
- Current entry changed to \a filename. Emitted when the entry to process is changed.
-*/
-
-/*!
- \fn QInstaller::LibArchiveWrapper::completedChanged(quint64 completed, quint64 total)
-
- The ratio of \a completed entries from \a total changed.
- Emitted when the progress changes.
-*/
-
-/*!
Constructs an archive object representing an archive file
specified by \a filename with \a parent as the parent object.
*/
diff --git a/src/libs/installer/libarchivewrapper_p.cpp b/src/libs/installer/libarchivewrapper_p.cpp
index 5509812cf..30f81554a 100644
--- a/src/libs/installer/libarchivewrapper_p.cpp
+++ b/src/libs/installer/libarchivewrapper_p.cpp
@@ -41,13 +41,13 @@ namespace QInstaller {
*/
/*!
- \fn QInstaller::ArchiveWrapper::dataBlockRequested()
+ \fn QInstaller::LibArchiveWrapperPrivate::dataBlockRequested()
Emitted when the server process has requested another data block.
*/
/*!
- \fn QInstaller::ArchiveWrapper::remoteWorkerFinished()
+ \fn QInstaller::LibArchiveWrapperPrivate::remoteWorkerFinished()
Emitted when the server process has finished extracting an archive.
*/
@@ -77,7 +77,6 @@ LibArchiveWrapperPrivate::LibArchiveWrapperPrivate()
*/
LibArchiveWrapperPrivate::~LibArchiveWrapperPrivate()
{
- m_timer.stop();
}
/*!
@@ -140,6 +139,10 @@ QString LibArchiveWrapperPrivate::errorString() const
bool LibArchiveWrapperPrivate::extract(const QString &dirPath, const quint64 totalFiles)
{
if (connectToServer()) {
+ QTimer timer;
+ connect(&timer, &QTimer::timeout, this, &LibArchiveWrapperPrivate::processSignals);
+ timer.start();
+
m_lock.lockForWrite();
callRemoteMethod(QLatin1String(Protocol::AbstractArchiveExtract), dirPath, totalFiles);
m_lock.unlock();
@@ -148,6 +151,7 @@ bool LibArchiveWrapperPrivate::extract(const QString &dirPath, const quint64 tot
connect(this, &LibArchiveWrapperPrivate::remoteWorkerFinished, &loop, &QEventLoop::quit);
loop.exec();
}
+ timer.stop();
return (workerStatus() == ExtractWorker::Success);
}
return m_archive.extract(dirPath, totalFiles);
@@ -247,6 +251,10 @@ void LibArchiveWrapperPrivate::processSignals()
emit completedChanged(completed, total);
} else if (name == QLatin1String(Protocol::AbstractArchiveSignalDataBlockRequested)) {
emit dataBlockRequested();
+ } else if (name == QLatin1String(Protocol::AbstractArchiveSignalSeekRequested)) {
+ const qint64 offset = receivedSignals.takeFirst().value<qint64>();
+ const int whence = receivedSignals.takeFirst().value<int>();
+ emit seekRequested(offset, whence);
} else if (name == QLatin1String(Protocol::AbstractArchiveSignalWorkerFinished)) {
emit remoteWorkerFinished();
}
@@ -258,7 +266,7 @@ void LibArchiveWrapperPrivate::processSignals()
*/
void LibArchiveWrapperPrivate::onDataBlockRequested()
{
- constexpr quint64 blockSize = 10 * 1024 * 1024; // 10MB
+ constexpr quint64 blockSize = 1024 * 1024; // 1MB
QFile *const file = &m_archive.m_data->file;
if (!file->isOpen() || file->isSequential()) {
@@ -294,15 +302,39 @@ void LibArchiveWrapperPrivate::onDataBlockRequested()
}
/*!
- Starts the timer to process server-side signals and connects handler
- signals for the matching signals of the wrapper object.
+ Seeks to specified \a offset in the underlying file device. Possible \a whence
+ values are \c SEEK_SET, \c SEEK_CUR, and \c SEEK_END.
*/
-void LibArchiveWrapperPrivate::init()
+void LibArchiveWrapperPrivate::onSeekRequested(qint64 offset, int whence)
{
- m_timer.start(250);
- QObject::connect(&m_timer, &QTimer::timeout,
- this, &LibArchiveWrapperPrivate::processSignals);
+ QFile *const file = &m_archive.m_data->file;
+ if (!file->isOpen() || file->isSequential()) {
+ qCWarning(QInstaller::lcInstallerInstallLog) << file->errorString();
+ setClientFilePosition(ARCHIVE_FATAL);
+ return;
+ }
+ bool success = false;
+ switch (whence) {
+ case SEEK_SET: // moves file pointer position to the beginning of the file
+ success = file->seek(offset);
+ break;
+ case SEEK_CUR: // moves file pointer position to given location
+ success = file->seek(file->pos() + offset);
+ break;
+ case SEEK_END: // moves file pointer position to the end of file
+ success = file->seek(file->size() + offset);
+ break;
+ default:
+ break;
+ }
+ setClientFilePosition(success ? file->pos() : ARCHIVE_FATAL);
+}
+/*!
+ Connects handler signals for the matching signals of the wrapper object.
+*/
+void LibArchiveWrapperPrivate::init()
+{
QObject::connect(&m_archive, &LibArchiveArchive::currentEntryChanged,
this, &LibArchiveWrapperPrivate::currentEntryChanged);
QObject::connect(&m_archive, &LibArchiveArchive::completedChanged,
@@ -310,6 +342,8 @@ void LibArchiveWrapperPrivate::init()
QObject::connect(this, &LibArchiveWrapperPrivate::dataBlockRequested,
this, &LibArchiveWrapperPrivate::onDataBlockRequested);
+ QObject::connect(this, &LibArchiveWrapperPrivate::seekRequested,
+ this, &LibArchiveWrapperPrivate::onSeekRequested);
}
/*!
@@ -338,6 +372,18 @@ void LibArchiveWrapperPrivate::setClientDataAtEnd()
}
/*!
+ Calls a remote method to set new file position \a pos.
+*/
+void LibArchiveWrapperPrivate::setClientFilePosition(qint64 pos)
+{
+ if (connectToServer()) {
+ m_lock.lockForWrite();
+ callRemoteMethod(QLatin1String(Protocol::AbstractArchiveSetFilePosition), pos, dummy);
+ m_lock.unlock();
+ }
+}
+
+/*!
Calls a remote method to retrieve and return the status of
the extract worker on a server process.
*/
diff --git a/src/libs/installer/libarchivewrapper_p.h b/src/libs/installer/libarchivewrapper_p.h
index ea8409da0..4277cd4f9 100644
--- a/src/libs/installer/libarchivewrapper_p.h
+++ b/src/libs/installer/libarchivewrapper_p.h
@@ -66,6 +66,7 @@ Q_SIGNALS:
void currentEntryChanged(const QString &filename);
void completedChanged(const quint64 completed, const quint64 total);
void dataBlockRequested();
+ void seekRequested(qint64 offset, int whence);
void remoteWorkerFinished();
public Q_SLOTS:
@@ -74,16 +75,17 @@ public Q_SLOTS:
private Q_SLOTS:
void processSignals();
void onDataBlockRequested();
+ void onSeekRequested(qint64 offset, int whence);
private:
void init();
void addDataBlock(const QByteArray &buffer);
void setClientDataAtEnd();
+ void setClientFilePosition(qint64 pos);
ExtractWorker::Status workerStatus() const;
private:
- QTimer m_timer;
mutable QReadWriteLock m_lock;
LibArchiveArchive m_archive;
diff --git a/src/libs/installer/loggingutils.cpp b/src/libs/installer/loggingutils.cpp
index 6e7bff44a..a2b561c53 100644
--- a/src/libs/installer/loggingutils.cpp
+++ b/src/libs/installer/loggingutils.cpp
@@ -145,10 +145,7 @@ void LoggingHandler::messageHandler(QtMsgType type, const QMessageLogContext &co
static Uptime uptime;
- QString ba;
- if (context.category != lcPackageInfo().categoryName()) {
- ba = QLatin1Char('[') + QString::number(uptime.elapsed()) + QStringLiteral("] ");
- }
+ QString ba = QLatin1Char('[') + QString::number(uptime.elapsed()) + QStringLiteral("] ");
ba += trimAndPrepend(type, msg);
if (type != QtDebugMsg && context.file) {
@@ -160,7 +157,7 @@ void LoggingHandler::messageHandler(QtMsgType type, const QMessageLogContext &co
if (VerboseWriter *log = VerboseWriter::instance())
log->appendLine(ba);
- if (type != QtDebugMsg || isVerbose() || context.category == lcPackageInfo().categoryName())
+ if (type != QtDebugMsg || isVerbose())
std::cout << qPrintable(ba) << std::endl;
if (type == QtFatalMsg) {
@@ -251,9 +248,9 @@ bool LoggingHandler::outputRedirected() const
}
/*!
- Prints basic information about \a components.
+ Prints update information from \a components.
*/
-void LoggingHandler::printComponentInfo(const QList<Component *> components) const
+void LoggingHandler::printUpdateInformation(const QList<Component *> components) const
{
QDomDocument doc;
QDomElement root = doc.createElement(QLatin1String("updates"));
@@ -267,7 +264,7 @@ void LoggingHandler::printComponentInfo(const QList<Component *> components) con
update.setAttribute(QLatin1String("id"), component->value(scName));
root.appendChild(update);
}
- qCDebug(lcPackageInfo) << qPrintable(doc.toString(4));
+ std::cout << qPrintable(doc.toString(4));
}
/*!
@@ -297,7 +294,7 @@ void LoggingHandler::printLocalPackageInformation(const QList<KDUpdater::LocalPa
}
root.appendChild(update);
}
- qCDebug(lcPackageInfo) << qPrintable(doc.toString(4));
+ std::cout << qPrintable(doc.toString(4));
}
/*!
@@ -341,7 +338,7 @@ void LoggingHandler::printPackageInformation(const PackagesList &matchedPackages
}
root.appendChild(update);
}
- qCDebug(lcPackageInfo) << qPrintable(doc.toString(4));
+ std::cout << qPrintable(doc.toString(4));
}
/*!
diff --git a/src/libs/installer/loggingutils.h b/src/libs/installer/loggingutils.h
index a997a6d60..06f0400f8 100644
--- a/src/libs/installer/loggingutils.h
+++ b/src/libs/installer/loggingutils.h
@@ -57,7 +57,7 @@ public:
VerbosityLevel verboseLevel() const;
bool outputRedirected() const;
- void printComponentInfo(const QList<Component *> components) const;
+ void printUpdateInformation(const QList<Component *> components) const;
void printLocalPackageInformation(const QList<KDUpdater::LocalPackage> &packages) const;
void printPackageInformation(const PackagesList &matchedPackages, const LocalPackagesHash &installedPackages) const;
diff --git a/src/libs/installer/protocol.h b/src/libs/installer/protocol.h
index c7eb9a308..65241e00b 100644
--- a/src/libs/installer/protocol.h
+++ b/src/libs/installer/protocol.h
@@ -177,6 +177,7 @@ const char AbstractArchiveIsSupported[] = "AbstractArchive::isSupported";
const char AbstractArchiveSetCompressionLevel[] = "AbstractArchive::setCompressionLevel";
const char AbstractArchiveAddDataBlock[] = "AbstractArchive::addDataBlock";
const char AbstractArchiveSetClientDataAtEnd[] = "AbstractArchive::setClientDataAtEnd";
+const char AbstractArchiveSetFilePosition[] = "AbstractArchive::setFilePosition";
const char AbstractArchiveWorkerStatus[] = "AbstractArchive::workerStatus";
const char AbstractArchiveCancel[] = "AbstractArchive::cancel";
@@ -184,6 +185,7 @@ const char GetAbstractArchiveSignals[] = "GetAbstractArchiveSignals";
const char AbstractArchiveSignalCurrentEntryChanged[] = "AbstractArchive::currentEntryChanged";
const char AbstractArchiveSignalCompletedChanged[] = "AbstractArchive::completedChanged";
const char AbstractArchiveSignalDataBlockRequested[] = "AbstractArchive::dataBlockRequested";
+const char AbstractArchiveSignalSeekRequested[] = "AbstractArchive::seekRequested";
const char AbstractArchiveSignalWorkerFinished[] = "AbstractArchive::workerFinished";
} // namespace Protocol
diff --git a/src/libs/installer/remoteserverconnection.cpp b/src/libs/installer/remoteserverconnection.cpp
index 5d72f834d..9e141ea48 100644
--- a/src/libs/installer/remoteserverconnection.cpp
+++ b/src/libs/installer/remoteserverconnection.cpp
@@ -596,6 +596,10 @@ void RemoteServerConnection::handleArchive(QIODevice *socket, const QString &com
archive->workerAddDataBlock(buff);
} else if (command == QLatin1String(Protocol::AbstractArchiveSetClientDataAtEnd)) {
archive->workerSetDataAtEnd();
+ } else if (command == QLatin1String(Protocol::AbstractArchiveSetFilePosition)) {
+ qint64 pos;
+ data >> pos;
+ archive->workerSetFilePosition(pos);
} else if (command == QLatin1String(Protocol::AbstractArchiveWorkerStatus)) {
sendData(socket, static_cast<qint32>(archive->workerStatus()));
} else if (command == QLatin1String(Protocol::AbstractArchiveCancel)) {
diff --git a/src/libs/installer/remoteserverconnection_p.h b/src/libs/installer/remoteserverconnection_p.h
index dc6d794b6..977a64711 100644
--- a/src/libs/installer/remoteserverconnection_p.h
+++ b/src/libs/installer/remoteserverconnection_p.h
@@ -143,6 +143,8 @@ private:
this, &AbstractArchiveSignalReceiver::onCompletedChanged);
connect(archive, &LibArchiveArchive::dataBlockRequested,
this, &AbstractArchiveSignalReceiver::onDataBlockRequested);
+ connect(archive, &LibArchiveArchive::seekRequested,
+ this, &AbstractArchiveSignalReceiver::onSeekRequested);
connect(archive, &LibArchiveArchive::workerFinished,
this, &AbstractArchiveSignalReceiver::onWorkerFinished);
}
@@ -169,6 +171,14 @@ private Q_SLOTS:
m_receivedSignals.append(QLatin1String(Protocol::AbstractArchiveSignalDataBlockRequested));
}
+ void onSeekRequested(qint64 offset, int whence)
+ {
+ QMutexLocker _(&m_lock);
+ m_receivedSignals.append(QLatin1String(Protocol::AbstractArchiveSignalSeekRequested));
+ m_receivedSignals.append(offset);
+ m_receivedSignals.append(whence);
+ }
+
void onWorkerFinished()
{
QMutexLocker _(&m_lock);
diff --git a/src/sdk/commandlineinterface.cpp b/src/sdk/commandlineinterface.cpp
index a63b2a5bf..6b674364c 100644
--- a/src/sdk/commandlineinterface.cpp
+++ b/src/sdk/commandlineinterface.cpp
@@ -108,7 +108,7 @@ int CommandLineInterface::checkUpdates()
qCWarning(QInstaller::lcInstallerInstallLog) << "There are currently no updates available.";
return EXIT_SUCCESS;
}
- QInstaller::LoggingHandler::instance().printComponentInfo(components);
+ QInstaller::LoggingHandler::instance().printUpdateInformation(components);
return EXIT_SUCCESS;
}
diff --git a/src/sdk/sdkapp.h b/src/sdk/sdkapp.h
index 60eca8103..0c09897d7 100644
--- a/src/sdk/sdkapp.h
+++ b/src/sdk/sdkapp.h
@@ -149,18 +149,15 @@ public:
loggingRules = QLatin1String("ifw.* = false\n"
"ifw.installer.* = true\n"
"ifw.server = true\n"
- "ifw.progress.indicator = true\n"
- "ifw.package.* = true\n");
+ "ifw.progress.indicator = true\n");
} else {
// enable all except detailed package information and developer specific logging
loggingRules = QLatin1String("ifw.* = true\n"
- "ifw.developer.build = false\n"
- "ifw.package.* = true\n");
+ "ifw.developer.build = false\n");
}
if (QInstaller::LoggingHandler::instance().verboseLevel() == QInstaller::LoggingHandler::Detailed) {
- loggingRules += QLatin1String("\nifw.developer.build = true\n"
- "ifw.package.* = true\n");
+ loggingRules += QLatin1String("\nifw.developer.build = true\n");
}
QLoggingCategory::setFilterRules(loggingRules);
qCDebug(QInstaller::lcInstallerInstallLog).noquote() << "Arguments:" <<
diff --git a/src/sdk/translations/ifw_ko.ts b/src/sdk/translations/ifw_ko.ts
deleted file mode 100644
index a2db492de..000000000
--- a/src/sdk/translations/ifw_ko.ts
+++ /dev/null
@@ -1,2771 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE TS>
-<TS version="2.1" language="ko_KR" sourcelanguage="en_GB">
-<context>
- <name>QInstaller::ProxyCredentialsDialog</name>
- <message>
- <source>Dialog</source>
- <translation>다이얼로그</translation>
- </message>
- <message>
- <source>The proxy %1 requires a username and password.</source>
- <translation>프록시 1%에 사용자 이름과 비밀번호가 필요합니다.</translation>
- </message>
- <message>
- <source>Username:</source>
- <translation>사용자 이름:</translation>
- </message>
- <message>
- <source>Username</source>
- <translation>사용자 이름</translation>
- </message>
- <message>
- <source>Password:</source>
- <translation>비밀번호:</translation>
- </message>
- <message>
- <source>Password</source>
- <translation>비밀번호</translation>
- </message>
- <message>
- <source>Proxy Credentials</source>
- <translation>프록시 자격 증명</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ServerAuthenticationDialog</name>
- <message>
- <source>Server Requires Authentication</source>
- <translation>서버 인증이 필요함</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>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>SettingsDialog</name>
- <message>
- <source>Settings</source>
- <translation>설정</translation>
- </message>
- <message>
- <source>Network</source>
- <translation>네트워크</translation>
- </message>
- <message>
- <source>No proxy</source>
- <translation>프록시 없음</translation>
- </message>
- <message>
- <source>System proxy settings</source>
- <translation>시스템 프록시 설정</translation>
- </message>
- <message>
- <source>Manual proxy configuration</source>
- <translation>수동 프록시 구성</translation>
- </message>
- <message>
- <source>HTTP proxy:</source>
- <translation>HTTP 프록시:</translation>
- </message>
- <message>
- <source>Port:</source>
- <translation>포트:</translation>
- </message>
- <message>
- <source>FTP proxy:</source>
- <translation>FTP 프록시:</translation>
- </message>
- <message>
- <source>Repositories</source>
- <translation>리포지토리</translation>
- </message>
- <message>
- <source>Add Username and Password for authentication if needed.</source>
- <translation>필요하면 인증을 위한 사용자 이름과 비밀번호를 추가하십시오.</translation>
- </message>
- <message>
- <source>Use temporary repositories only</source>
- <translation>임시 리포지토리만 사용</translation>
- </message>
- <message>
- <source>Add</source>
- <translation>추가</translation>
- </message>
- <message>
- <source>Remove</source>
- <translation>제거</translation>
- </message>
- <message>
- <source>Test</source>
- <translation>테스트</translation>
- </message>
- <message>
- <source>Select All</source>
- <translation>모두 선택</translation>
- </message>
- <message>
- <source>Deselect All</source>
- <translation>모두 선택 해제</translation>
- </message>
- <message>
- <source>Show Passwords</source>
- <translation>비밀번호 표시</translation>
- </message>
- <message>
- <source>Check this to use repository during fetch.</source>
- <translation>가져오는 중에 리포지토리를 사용하려면 확인하십시오.</translation>
- </message>
- <message>
- <source>Add the username to authenticate on the server.</source>
- <translation>서버를 인증하려면 사용자 이름을 추가하십시오.</translation>
- </message>
- <message>
- <source>Add the password to authenticate on the server.</source>
- <translation>서버를 인증하려면 비밀번호를 추가하십시오.</translation>
- </message>
- <message>
- <source>The server&apos;s URL that contains a valid repository.</source>
- <translation>유효한 리포지토리가 포함되어 있는 서버 URL입니다.</translation>
- </message>
- <message>
- <source>An error occurred while testing this repository.</source>
- <translation>이 리포지토리를 테스트하는 중에 오류가 발생했습니다.</translation>
- </message>
- <message>
- <source>The repository was tested successfully.</source>
- <translation>리포지토리를 성공적으로 테스트했습니다.</translation>
- </message>
- <message>
- <source>Do you want to disable the repository?</source>
- <translation>이 리포지토리를 비활성화하시겠습니까?</translation>
- </message>
- <message>
- <source>Do you want to enable the repository?</source>
- <translation>이 리포지토리를 활성화하시겠습니까?</translation>
- </message>
- <message>
- <source>Hide Passwords</source>
- <translation>비밀번호 숨기기</translation>
- </message>
- <message>
- <source>Use</source>
- <translation>사용</translation>
- </message>
- <message>
- <source>Username</source>
- <translation>사용자 이름</translation>
- </message>
- <message>
- <source>Password</source>
- <translation>비밀번호</translation>
- </message>
- <message>
- <source>Repository</source>
- <translation>리포지토리</translation>
- </message>
- <message>
- <source>Default repositories</source>
- <translation>기본 리포지토리</translation>
- </message>
- <message>
- <source>Temporary repositories</source>
- <translation>임시 리포지토리</translation>
- </message>
- <message>
- <source>User defined repositories</source>
- <translation>사용자 정의 리포지토리</translation>
- </message>
-</context>
-<context>
- <name>QInstaller</name>
- <message>
- <source>Invalid content in &quot;%1&quot;.</source>
- <translation>&quot;%1&quot;에 올바르지 않은 내용이 있음</translation>
- </message>
- <message>
- <source>No marker found, stopped after %1.</source>
- <translation>마커를 찾을 수 없습니다. %1 이후에 중지되었습니다.</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for reading: %2</source>
- <translation>&quot;%1&quot; 파일을 읽기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for writing: %2</source>
- <translation>&quot;%1&quot; 파일을 쓰기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Read failed after %1 bytes: %2</source>
- <translation>%1바이트 이후 읽을 수 없음: %2</translation>
- </message>
- <message>
- <source>Copy failed: %1</source>
- <translation>복사할 수 없음: %1</translation>
- </message>
- <message>
- <source>Write failed after %1 bytes: %2</source>
- <translation>%1바이트 이후 쓸 수 없음: %2</translation>
- </message>
- <message>
- <source>bytes</source>
- <translation>바이트</translation>
- </message>
- <message>
- <source>KB</source>
- <translation>KB</translation>
- </message>
- <message>
- <source>MB</source>
- <translation>MB</translation>
- </message>
- <message>
- <source>GB</source>
- <translation>GB</translation>
- </message>
- <message>
- <source>TB</source>
- <translation>TB</translation>
- </message>
- <message>
- <source>PB</source>
- <translation>PB</translation>
- </message>
- <message>
- <source>EB</source>
- <translation>EB</translation>
- </message>
- <message>
- <source>ZB</source>
- <translation>ZB</translation>
- </message>
- <message>
- <source>YB</source>
- <translation>YB</translation>
- </message>
- <message>
- <source>Cannot remove file &quot;%1&quot;: %2</source>
- <translation>&quot;1%&quot; 파일을 제거할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot remove directory &quot;%1&quot;: %2</source>
- <translation>&quot;1%&quot; 디렉토리를 제거할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot create directory &quot;%1&quot;.</source>
- <translation>&quot;1%&quot; 디렉토리를 생성할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot copy file from &quot;%1&quot; to &quot;%2&quot;: %3</source>
- <translation>&quot;%1&quot;에서 &quot;%2&quot;에 파일을 복사할 수 없음: %3</translation>
- </message>
- <message>
- <source>Cannot move file from &quot;%1&quot; to &quot;%2&quot;: %3</source>
- <translation>&quot;%1&quot;에서 &quot;%2&quot;에 파일을 이동할 수 없음: %3</translation>
- </message>
- <message>
- <source>Cannot create directory &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 디렉토리를 생성할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot open temporary file: %1</source>
- <translation>임시 파일을 열 수 없음: %1</translation>
- </message>
- <message>
- <source>Cannot open temporary file for template %1: %2</source>
- <translation>%1 템플릿에 대한 임시 파일을 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot copy file &quot;%1&quot; to &quot;%2&quot;: %3</source>
- <translation>&quot;%1&quot;에서 &quot;%2&quot;에 파일을 복사할 수 없음: %3</translation>
- </message>
- <message>
- <source>Cannot copy file &quot;%1&quot; to &quot;%2&quot;.</source>
- <translation>&quot;%1&quot;에서 &quot;%2&quot;에 파일을 복사할 수 없음:</translation>
- </message>
- <message>
- <source>The specified module could not be found.</source>
- <translation>지정된 모듈을 찾을 수 없습니다.</translation>
- </message>
-</context>
-<context>
- <name>QObject</name>
- <message>
- <source>Error acquiring admin rights</source>
- <translation>관리자 권한 획득 중에 오류 발생</translation>
- </message>
- <message>
- <source>Another %1 instance is already running. Wait until it finishes, close it, or restart your system.</source>
- <translation>다른 %1 인스턴스가 이미 실행 중입니다. 완료될 때까지 기다린 다음 닫거나 시스템을 다시 시작하십시오.</translation>
- </message>
- <message>
- <source>Cannot start installer binary as updater.</source>
- <translation>설치 관리자 바이너리를 업데이터로서 시작할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot start installer binary as package manager.</source>
- <translation>설치 관리자 바이너리를 패키지 관리자로서 시작할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot start installer binary as uninstaller.</source>
- <translation>설치 관리자 바이너리를 설치 제거 관리자로서 시작할 수 없습니다.</translation>
- </message>
- <message>
- <source>Empty repository list for option &apos;addRepository&apos;.</source>
- <translation>옵션 &apos;addRepository&apos;에 대한 리포지토리 목록이 비어있습니다.</translation>
- </message>
- <message>
- <source>Empty repository list for option &apos;addTempRepository&apos;.</source>
- <translation>옵션 &apos;addTempRepository&apos;에 대한 리포지토리 목록이 비어있습니다.</translation>
- </message>
- <message>
- <source>Empty repository list for option &apos;setTempRepository&apos;.</source>
- <translation>옵션 &apos;setTempRepository&apos;에 대한 리포지토리 목록이 비어있습니다.</translation>
- </message>
- <message>
- <source>Empty repository list for option &apos;installCompressedRepository&apos;.</source>
- <translation>옵션 &apos;installCompressedRepository&apos;에 대한 리포지토리 목록이 비어있습니다.</translation>
- </message>
- <message>
- <source>The file %1 does not exist.</source>
- <translation>%1 파일이 없습니다.</translation>
- </message>
- <message>
- <source>Arguments missing for option %1</source>
- <translation>옵션 %1에 대한 인수가 누락되었습니다.</translation>
- </message>
- <message>
- <source>Invalid button value %1 </source>
- <translation>올바르지 않은 버튼 값 %1 </translation>
- </message>
- <message>
- <source>Incorrect arguments for %1</source>
- <translation>%1에 대해 올바르지 않은 인수</translation>
- </message>
- <message>
- <source>Please make sure that the current user has read access to file &quot;%1&quot; or try running %2 as an administrator.</source>
- <translation>현재 사용자가 &amp;quot;%1&amp;quot; 파일에 대한 접근 권한이 있는지 확인하거나 관리자 권한으로 %2 파일을 실행해 보십시오.</translation>
- </message>
-</context>
-<context>
- <name>BinaryLayout</name>
- <message>
- <source>Cannot seek to %1 to read the embedded meta data count.</source>
- <translation>%1을(를) 찾아서 내장된 메타데이터 개수를 읽을 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot seek to %1 to read the resource collection segment.</source>
- <translation>%1을(를) 찾아서 리소스 컬렉션 세그먼트를 읽을 수 없습니다.</translation>
- </message>
- <message>
- <source>Unexpected mismatch of meta resources. Read %1, expected: %2.</source>
- <translation>메타 리소스에 예상과 다르게 일치하지 않는 사항이 있습니다. 읽음: %1, 예상: %2.</translation>
- </message>
-</context>
-<context>
- <name>BinaryContent</name>
- <message>
- <source>Cannot seek to %1 to read the operation data.</source>
- <translation>%1을(를) 찾아서 작업 데이터를 읽을 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot seek to %1 to read the resource collection block.</source>
- <translation>%1을(를) 찾아서 리소스 컬렉션 블록을 읽을 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot open meta resource %1.</source>
- <translation>메타 소스(%1)를 열 수 없습니다.</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::Resource</name>
- <message>
- <source>Cannot open resource %1 for reading.</source>
- <translation>리소스(%1)를 읽기 위해 열 수 없습니다.</translation>
- </message>
- <message>
- <source>Read failed after %1 bytes: %2</source>
- <translation>%1바이트 이후 읽을 수 없음: %2</translation>
- </message>
- <message>
- <source>Write failed after %1 bytes: %2</source>
- <translation>%1바이트 이후 쓸 수 없음: %2</translation>
- </message>
-</context>
-<context>
- <name>ResourceCollectionManager</name>
- <message>
- <source>Cannot open resource %1: %2</source>
- <translation>리소스(%1)를 열 수 없음: %2</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::Component</name>
- <message>
- <source>Components cannot have children in updater mode.</source>
- <translation>업데이터 모드에서는 구성요소에 하위 요소가 있으면 안 됩니다.</translation>
- </message>
- <message>
- <source>Cannot open the requested UI file &quot;%1&quot;: %2</source>
- <translation>요청된 UI 파일(&quot;%1&quot;)을 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot load the requested UI file &quot;%1&quot;: %2</source>
- <translation>요청된 UI 파일(&quot;%1&quot;)을 로드할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot open the requested license file &quot;%1&quot;: %2</source>
- <translation>요청된 라이선스 파일(&quot;%1&quot;)을 열 수 없음: %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>Cannot resolve isDefault in %1</source>
- <translation>%1의 isDefault를 해결할 수 없습니다.</translation>
- </message>
- <message>
- <source>Update Info: </source>
- <translation>업데이트 정보: </translation>
- </message>
- <message>
- <source>There was an error loading the selected component. This component cannot be installed.</source>
- <translation>선택한 구성요소를 로드하는 중에 오류가 발생했습니다. 이 구성요소를 설치할 수 없습니다.</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ComponentModel</name>
- <message>
- <source>Component is marked for installation.</source>
- <translation>구성요소가 설치를 위해 표시되었습니다.</translation>
- </message>
- <message>
- <source>Component is marked for uninstallation.</source>
- <translation>구성요소가 설치 제거를 위해 표시되었습니다.</translation>
- </message>
- <message>
- <source>Component is installed.</source>
- <translation>구성요소가 설치되었습니다.</translation>
- </message>
- <message>
- <source>Component is not installed.</source>
- <translation>구성요소가 설치되지 않았습니다.</translation>
- </message>
- <message>
- <source>Component Name</source>
- <translation>구성요소 이름</translation>
- </message>
- <message>
- <source>Action</source>
- <translation>조치</translation>
- </message>
- <message>
- <source>Installed Version</source>
- <translation>설치된 버전</translation>
- </message>
- <message>
- <source>New Version</source>
- <translation>새 버전</translation>
- </message>
- <message>
- <source>Release Date</source>
- <translation>출시일</translation>
- </message>
- <message>
- <source>Size</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>Select default components in the tree view.</source>
- <translation>트리 보기에서 기본 구성요소를 선택합니다.</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>Reset all components to their original selection state in the tree view.</source>
- <translation>트리 보기에서 모든 구성요소를 원래 선택된 상태로 재설정합니다.</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>Select all components in the tree view.</source>
- <translation>트리 보기에서 모든 구성요소를 선택합니다.</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>Deselect all components in the tree view.</source>
- <translation>트리 보기에서 모든 구성요소를 선택 해제합니다.</translation>
- </message>
- <message>
- <source>&amp;Browse QBSP files</source>
- <translation>QBSP 파일 탐색(&amp;B)</translation>
- </message>
- <message>
- <source>Select a Qt Board Support Package file to install additional content that is not directly available from the online repositories.</source>
- <translation>QBSP(Qt Board Support Package) 파일을 선택하여 온라인 리포지토리에서 직접 사용할 수 없는 추가 콘텐츠를 설치합니다.</translation>
- </message>
- <message>
- <source>Filter the enabled repository categories</source>
- <translation>활성화된 리포지토리 범주를 필터링합니다.</translation>
- </message>
- <message>
- <source>This component will occupy approximately %1 on your hard disk drive.</source>
- <translation>이 구성요소는 하드디스크 드라이브의 약 %1 정도를 차지합니다.</translation>
- </message>
- <message>
- <source>Open File</source>
- <translation>파일 열기</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. Any components already installed will not be updated.</source>
- <translation>설치할 구성요소를 선택하십시오. 설치 제거할 설치된 구성요소를 선택 해제하십시오. 이미 설치된 모든 구성요소는 업데이트되지 않습니다.</translation>
- </message>
- <message>
- <source>Mandatory components need to be updated first before you can select other components to update.</source>
- <translation>필수 구성요소를 먼저 업데이트해야 다른 구성요소를 업데이트하기 위해 선택할 수 있습니다.</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ComponentSelectionPagePrivate</name>
- <message>
- <source>Filter</source>
- <translation>필터</translation>
- </message>
- <message>
- <source>Component Information</source>
- <translation>구성요소 정보</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>오류</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ConsumeOutputOperation</name>
- <message>
- <source>&lt;to be saved installer key name&gt; &lt;executable&gt; [argument1] [argument2] [...]</source>
- <translation>&lt;저장할 설치 관리자 키 이름&gt; &lt;실행 가능&gt; [argument1] [argument2] [...]</translation>
- </message>
- <message>
- <source>Needed installer object in %1 operation is empty.</source>
- <translation>&quot;%1&quot; 작업에 필요한 설치 개체가 비어 있습니다.</translation>
- </message>
- <message>
- <source>Cannot save the output of &quot;%1&quot; to an empty installer key value.</source>
- <translation>빈 설치 관리자 키 값에 &quot;%1&quot;의 출력을 저장할 수 없습니다.</translation>
- </message>
- <message>
- <source>File &quot;%1&quot; does not exist or is not an executable binary.</source>
- <translation>&quot;%1&quot; 파일이 없거나 실행 가능한 바이너리가 아닙니다.</translation>
- </message>
- <message>
- <source>Running &quot;%1&quot; resulted in a crash.</source>
- <translation>&quot;%1&quot; 실행 중에 충돌이 발생했습니다.</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::CopyDirectoryOperation</name>
- <message>
- <source>&lt;source&gt; &lt;target&gt; [&quot;forceOverwrite&quot;]</source>
- <translation>&lt;소스&gt; &lt;대상&gt; [&quot;forceOverwrite&quot;]</translation>
- </message>
- <message>
- <source>Invalid argument in %1: Third argument needs to be forceOverwrite, if specified.</source>
- <translation>%1에 유효하지 않은 인수: 지정될 경우 세 번째 인수는 forceOverwrite해야 합니다.</translation>
- </message>
- <message>
- <source>Invalid argument in %1: Directory &quot;%2&quot; is invalid.</source>
- <translation>%1에 유효하지 않은 인수: &quot;%2&quot; 디렉토리가 유효하지 않습니다.</translation>
- </message>
- <message>
- <source>Cannot create directory &quot;%1&quot;.</source>
- <translation>&quot;1%&quot; 디렉토리를 생성할 수 없습니다.</translation>
- </message>
- <message>
- <source>Failed to overwrite &quot;%1&quot;.</source>
- <translation>&quot;%1&quot;을(를) 덮어쓸 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot copy file &quot;%1&quot; to &quot;%2&quot;: %3</source>
- <translation>&quot;%1&quot;에서 &quot;%2&quot;에 파일을 복사할 수 없음: %3</translation>
- </message>
- <message>
- <source>Cannot remove file &quot;%1&quot;.</source>
- <translation>&quot;1%&quot; 파일을 제거할 수 없음:</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::CopyFileTask</name>
- <message>
- <source>Invalid task item count.</source>
- <translation>작업 아이템 개수가 유효하지 않습니다.</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for reading: %2</source>
- <translation>&quot;%1&quot; 파일을 읽기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for writing: %2</source>
- <translation>&quot;%1&quot; 파일을 쓰기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Writing to file &quot;%1&quot; failed: %2</source>
- <translation>&quot;%1&quot; 파일에 쓰기 실패: %2</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::CreateDesktopEntryOperation</name>
- <message>
- <source>Cannot backup file &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 파일을 백업할 수 없음: %2</translation>
- </message>
- <message>
- <source>Failed to overwrite file &quot;%1&quot;.</source>
- <translation>&quot;%1&quot;을(를) 덮어쓸 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot write desktop entry to &quot;%1&quot;.</source>
- <translation>&quot;%1&quot;에 데스크톱 항목을 쓸 수 없습니다.</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::CreateLinkOperation</name>
- <message>
- <source>Cannot create link from &quot;%1&quot; to &quot;%2&quot;.</source>
- <translation>&quot;%1&quot;에서 &quot;%2&quot;에 대한 링크를 생성할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot remove link from &quot;%1&quot; to &quot;%2&quot;.</source>
- <translation>&quot;%1&quot;에서 &quot;%2&quot;에 대한 링크를 제거할 수 없습니다.</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::CreateLocalRepositoryOperation</name>
- <message>
- <source>Cannot set permissions for file &quot;%1&quot;.</source>
- <translation>파일 &quot;%1&quot;에 대한 권한을 설정할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot remove file &quot;%1&quot;: %2</source>
- <translation>&quot;1%&quot; 파일을 제거할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot move file &quot;%1&quot; to &quot;%2&quot;: %3</source>
- <translation>파일 &quot;%1&quot;을(를) &quot;%2&quot;(으)로 옮길 수 없습니다. %3</translation>
- </message>
- <message>
- <source>Installer at &quot;%1&quot; needs to be an offline one.</source>
- <translation>&quot;%1&quot;의 설치 관리자는 오프라인용이어야 합니다.</translation>
- </message>
- <message>
- <source>Cannot create path &quot;%1&quot;.</source>
- <translation>&quot;%1&quot; 경로를 생성할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot remove directory &quot;%1&quot;.</source>
- <translation>&quot;1%&quot; 디렉토리를 제거할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for reading.</source>
- <translation>&quot;%1&quot; 파일을 읽기 위해 열 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot read file &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 파일을 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for reading: %2</source>
- <translation>&quot;%1&quot; 파일을 읽기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot create target directory: &quot;%1&quot;.</source>
- <translation>대상 디렉토리를 생성할 수 없음: &quot;%1&quot;.</translation>
- </message>
- <message>
- <source>Unknown exception caught: %1.</source>
- <translation>알 수 없는 예외 발생: %1.</translation>
- </message>
- <message>
- <source>Removing file &quot;%1&quot;.</source>
- <translation>&quot;%1&quot; 파일을 제거합니다.</translation>
- </message>
- <message>
- <source>Cannot remove file &quot;%1&quot;.</source>
- <translation>&quot;1%&quot; 파일을 제거할 수 없음:</translation>
- </message>
- <message>
- <source>Cannot remove directory &quot;%1&quot;: %2</source>
- <translation>&quot;1%&quot; 디렉토리를 제거할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot create archive &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 아카이브를 생성할 수 없음: %2</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::CreateShortcutOperation</name>
- <message>
- <source>&lt;target&gt; &lt;link location&gt; [target arguments] [&quot;workingDirectory=...&quot;] [&quot;iconPath=...&quot;] [&quot;iconId=...&quot;] [&quot;description=...&quot;]</source>
- <translation>&lt;대상&gt; &lt;링크 위치&gt; [대상 인수] [&quot;workingDirectory=...&quot;] [&quot;iconPath=...&quot;] [&quot;iconId=...&quot;] [&quot;description=...&quot;]</translation>
- </message>
- <message>
- <source>Cannot create directory &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 디렉토리를 생성할 수 없음: %2</translation>
- </message>
- <message>
- <source>Failed to overwrite &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot;을(를) 덮어쓸 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot create link &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 링크를 생성할 수 없음: %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>Cannot verify Hash</source>
- <translation>해시를 검증할 수 없음</translation>
- </message>
- <message>
- <source>Cannot download archive %1: %2</source>
- <translation>%1 아카이브를 다운로드할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot fetch archives: %1
-Error while loading %2</source>
- <translation>아카이브를 가져올 수 없음: %1
-%2 로드 중 오류 발생</translation>
- </message>
- <message>
- <source>Downloading archive &quot;%1&quot; for component %2.</source>
- <translation>구성요소 %2용 아카이브 &quot;%1&quot; 다운로드 중입니다.</translation>
- </message>
- <message>
- <source>Scheme %1 not supported (URL: %2).</source>
- <translation>%1 스킴을 지원하지 않습니다(URL: %2).</translation>
- </message>
- <message>
- <source>Cannot find component for %1.</source>
- <translation>%1용 구성요소를 찾을 수 없습니다.</translation>
- </message>
- <message>
- <source>%1 of %2</source>
- <translation>%1/%2</translation>
- </message>
- <message>
- <source>%1 downloaded.</source>
- <translation>%1 다운로드가 완료되었습니다.</translation>
- </message>
- <message numerus="yes">
- <source>%n day(s), </source>
- <translation>
- <numerusform>%n일, </numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>%n hour(s), </source>
- <translation>
- <numerusform>%n시간, </numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>%n minute(s)</source>
- <translation>
- <numerusform>%n분</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>%n second(s)</source>
- <translation>
- <numerusform>%n초</numerusform>
- </translation>
- </message>
- <message>
- <source> - %1%2%3%4 remaining.</source>
- <translation> - 남은 시간: %1%2%3%4</translation>
- </message>
- <message>
- <source> - unknown time remaining.</source>
- <translation> - 남은 시간: 알 수 없음</translation>
- </message>
- <message>
- <source>Archive: </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Total: </source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::Downloader</name>
- <message>
- <source>Target file &quot;%1&quot; already exists but is not a file.</source>
- <translation>대상 파일(&quot;%1&quot;)이 이미 있지만 파일이 아닙니다.</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for writing: %2</source>
- <extracomment>%2 is a sentence describing the error</extracomment>
- <translation>&quot;%1&quot; 파일을 쓰기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>File &quot;%1&quot; not open for writing: %2</source>
- <extracomment>%2 is a sentence describing the error.</extracomment>
- <translation>&quot;%1&quot; 파일을 쓰기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Writing to file &quot;%1&quot; failed: %2</source>
- <extracomment>%2 is a sentence describing the error.</extracomment>
- <translation>&quot;%1&quot; 파일에 쓰기 실패: %2</translation>
- </message>
- <message>
- <source>Redirect loop detected for &quot;%1&quot;.</source>
- <translation>&quot;%1&quot;에 대한 리디렉션 루프가 감지되었습니다.</translation>
- </message>
- <message>
- <source>Network error while downloading &apos;%1&apos;: %2.</source>
- <translation>&quot;%1&quot; 다운로드 중에 네트워크 오류 발생: %2.</translation>
- </message>
- <message>
- <source>Unknown network error while downloading &quot;%1&quot;.</source>
- <extracomment>%1 is a sentence describing the error</extracomment>
- <translation>&quot;%1&quot; 다운로드 중에 네트워크 오류 발생:</translation>
- </message>
- <message>
- <source>Network transfers canceled.</source>
- <translation>네트워크 전송이 취소되었습니다.</translation>
- </message>
- <message>
- <source>Pause and resume not supported by network transfers.</source>
- <translation>네트워크 전송은 일시 중지하거나 다시 시작할 수 없습니다.</translation>
- </message>
- <message>
- <source>Invalid source URL &quot;%1&quot;: %2</source>
- <extracomment>%2 is a sentence describing the error</extracomment>
- <translation>유효하지 않은 소스 URL &quot;%1&quot;: %2</translation>
- </message>
-</context>
-<context>
- <name>AuthenticationRequiredException</name>
- <message>
- <source>%1 at %2</source>
- <translation>%2의 %1</translation>
- </message>
- <message>
- <source>Proxy requires authentication.</source>
- <translation>프록시는 인증이 필요합니다.</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ElevatedExecuteOperation</name>
- <message>
- <source>Cannot start detached: &quot;%1&quot;</source>
- <translation>분리된 항목을 시작할 수 없음: &quot;%1&quot;</translation>
- </message>
- <message>
- <source>Cannot start: &quot;%1&quot;: %2</source>
- <translation>시작할 수 없음: &quot;%1&quot;: %2</translation>
- </message>
- <message>
- <source>Program crashed: &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>UpdateOperation</name>
- <message>
- <source>Cannot write to registry path %1.</source>
- <translation>레지스트리 경로(%1)를 쓸 수 없습니다.</translation>
- </message>
- <message>
- <source>Registry path %1 is not writable.</source>
- <translation>레지스트리 경로(%1)를 쓸 수 없습니다.</translation>
- </message>
- <message>
- <source>exactly %1</source>
- <translation>정확히 %1</translation>
- </message>
- <message>
- <source>at least %1</source>
- <translation>최소 %1</translation>
- </message>
- <message>
- <source>not more than %1</source>
- <translation>%1 이하</translation>
- </message>
- <message>
- <source>%1 or %2</source>
- <translation>%1 또는 %2</translation>
- </message>
- <message>
- <source>%1 to %2</source>
- <translation>%1~%2</translation>
- </message>
- <message numerus="yes">
- <source>Invalid arguments in %1: %n arguments given, %2 arguments expected.</source>
- <translation>
- <numerusform>%1에 유효하지 않은 인수: %n개의 인수 입력, %2개의 인수 필요.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>Invalid arguments in %1: %n arguments given, %2 arguments expected in the form: %3.</source>
- <translation>
- <numerusform>%1에 유효하지 않은 인수: %n개의 인수 입력, 양식에 %2개의 인수 필요: %3.</numerusform>
- </translation>
- </message>
- <message>
- <source>Renaming file &quot;%1&quot; to &quot;%2&quot; failed: %3</source>
- <translation>파일 명을 &quot;%1&quot;에서 &quot;%2&quot;(으)로 변경하늦 중에 오류 발생: %3</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ExtractArchiveOperation</name>
- <message>
- <source>Extracting &quot;%1&quot;</source>
- <translation>&quot;%1&quot; 추출 중</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::FakeStopProcessForUpdateOperation</name>
- <message>
- <source>Cannot 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>
-</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>
-</context>
-<context>
- <name>InstallerCalculator</name>
- <message>
- <source>Components added as automatic dependencies:</source>
- <translation>구성요소가 자동 종속성으로 추가됨:</translation>
- </message>
- <message>
- <source>Components added as dependency for &quot;%1&quot;:</source>
- <translation>구성요소가 &quot;%1&quot;용 자동 종속성으로 추가됨:</translation>
- </message>
- <message>
- <source>Components that have resolved dependencies:</source>
- <translation>종속성을 해결한 구성요소:</translation>
- </message>
- <message>
- <source>Selected components without dependencies:</source>
- <translation>종속성 없이 선택된 구성요소:</translation>
- </message>
- <message>
- <source>Recursion detected, component &quot;%1&quot; already added with reason: &quot;%2&quot;</source>
- <translation>회귀가 감지됨. 구성요소(&quot;%1&quot;)가 다음 사유로 이미 추가됨: &quot;%2&quot;</translation>
- </message>
- <message>
- <source>Cannot find missing dependency &quot;%1&quot; for &quot;%2&quot;.</source>
- <translation>&quot;%2&quot;에 대한 누락된 종속성 &quot;%1&quot;을(를) 찾을 수 없습니다.</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::InstallIconsOperation</name>
- <message>
- <source>&lt;source path&gt; [vendor prefix]</source>
- <translation>&lt;소스 경로&gt; [벤더 접두사]</translation>
- </message>
- <message>
- <source>Invalid Argument: source directory must not be empty.</source>
- <translation>유효하지 않은 인수: 소스 디렉토리를 입력해야 합니다.</translation>
- </message>
- <message>
- <source>Cannot backup file &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 파일을 백업할 수 없음: %2</translation>
- </message>
- <message>
- <source>Failed to overwrite &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot;을(를) 덮어쓸 수 없음: %2</translation>
- </message>
- <message>
- <source>Failed to copy file &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 파일을 복사할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot create directory &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 디렉토리를 생성할 수 없음: %2</translation>
- </message>
-</context>
-<context>
- <name>Lib7z</name>
- <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>Cannot 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>Cannot convert UTC file time to system time.</source>
- <translation>UTC 파일 시간을 시스템 시간으로 변환할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot load codecs.</source>
- <translation>코덱을 로드할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot open archive &quot;%1&quot;.</source>
- <translation>&quot;%1&quot; 아카이브를 열 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot retrieve number of items in archive.</source>
- <translation>아카이브의 항목 개수를 검색할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot retrieve path of archive item &quot;%1&quot;.</source>
- <translation>아카이브 항목 &quot;%1&quot;의 경로를 검색할 수 없습니다.</translation>
- </message>
- <message>
- <source>Unknown exception caught (%1).</source>
- <translation>알 수 없는 예외가 발생했습니다(%1).</translation>
- </message>
- <message>
- <source>Cannot create temporary file: %1</source>
- <translation>임시 파일을 생성할 수 없음: %1</translation>
- </message>
- <message>
- <source>Unsupported archive type.</source>
- <translation>아카이브 유형이 지원되지 않습니다.</translation>
- </message>
- <message>
- <source>Cannot create archive &quot;%1&quot;</source>
- <translation>&quot;%1&quot; 아카이브를 생성할 수 없음</translation>
- </message>
- <message>
- <source>Cannot create archive &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 아카이브를 생성할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot remove old archive &quot;%1&quot;: %2</source>
- <translation>이전 아카이브 &quot;%1&quot; 제거 불가: %2</translation>
- </message>
- <message>
- <source>Cannot rename temporary archive &quot;%1&quot; to &quot;%2&quot;: %3</source>
- <translation>임시 아카이브 &quot;%1&quot;의 이름을 &quot;%2&quot;(으)로 변경할 수 없음: %3</translation>
- </message>
- <message>
- <source>Unknown exception caught (%1)</source>
- <translation>알 수 없는 예외 발생(%1)</translation>
- </message>
-</context>
-<context>
- <name>DirectoryGuard</name>
- <message>
- <source>Path &quot;%1&quot; exists but is not a directory.</source>
- <translation>&quot;%1&quot; 경로가 존재하지만 디렉토리가 아닙니다.</translation>
- </message>
- <message>
- <source>Cannot create directory &quot;%1&quot;.</source>
- <translation>&quot;1%&quot; 디렉토리를 생성할 수 없습니다.</translation>
- </message>
-</context>
-<context>
- <name>ExtractCallbackImpl</name>
- <message>
- <source>Cannot retrieve path of archive item %1.</source>
- <translation>아카이브 항목 &quot;%1&quot;의 경로를 검색할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot remove already existing symlink %1.</source>
- <translation>이미 존재하는 symlink %1을(를) 제거할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for writing: %2</source>
- <translation>&quot;%1&quot; 파일을 쓰기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot create symlink at &quot;%1&quot;. Another one is already existing.</source>
- <translation>&quot;%1&quot;에서 symlink를 생성할 수 없습니다. 다른 symlink가 이미 있습니다.</translation>
- </message>
- <message>
- <source>Cannot read symlink target from file &quot;%1&quot;.</source>
- <translation>파일 &quot;%1&quot;에서 symlink 대상을 읽을 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot create symlink at %1: %2</source>
- <translation>&quot;%1&quot;에서 symlink를 생성할 수 없음: %2</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>&quot;%1&quot; 작업에 필요한 설치 개체가 비어 있습니다.</translation>
- </message>
- <message>
- <source>Can not write license file &quot;%1&quot;.</source>
- <translation>&quot;%1&quot; 라이선스 파일을 쓸 수 없습니다.</translation>
- </message>
- <message>
- <source>No license files found to delete.</source>
- <translation>삭제할 라이선스 파일을 찾을 수 없습니다.</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::LineReplaceOperation</name>
- <message>
- <source>Invalid argument in %1: Empty search argument is not supported.</source>
- <translation>%1에 유효하지 않은 인수: 빈 인수는 지원되지 않습니다.</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for reading: %2</source>
- <translation>&quot;%1&quot; 파일을 읽기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for writing: %2</source>
- <translation>&quot;%1&quot; 파일을 쓰기 위해 열 수 없음: %2</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::MetadataJob</name>
- <message>
- <source>Missing package manager core engine.</source>
- <translation>패키지 관리자 코어 엔진이 누락되었습니다.</translation>
- </message>
- <message>
- <source>Preparing meta information download...</source>
- <translation>메타 정보 다운로드 준비 중...</translation>
- </message>
- <message>
- <source>Unpacking compressed repositories. This may take a while...</source>
- <translation>압축된 리포지토리의 압축을 해제합니다. 약간의 시간이 걸릴 수 있습니다...</translation>
- </message>
- <message>
- <source>Metadata download canceled.</source>
- <translation>메타데이터 다운로드가 취소되었습니다.</translation>
- </message>
- <message>
- <source>Unknown exception during extracting.</source>
- <translation>추출 중에 알 수 없는 예외가 발생했습니다.</translation>
- </message>
- <message>
- <source>Missing proxy credentials.</source>
- <translation>프록시 자격 증명이 누락되었습니다.</translation>
- </message>
- <message>
- <source>Authentication failed.</source>
- <translation>인증하지 못했습니다.</translation>
- </message>
- <message>
- <source>Unknown exception during download.</source>
- <translation>다운로드 중에 알 수 없는 예외가 발생했습니다.</translation>
- </message>
- <message>
- <source>Failure to fetch repositories.</source>
- <translation>리포지토리를 가져올 수 없습니다.</translation>
- </message>
- <message>
- <source>Extracting meta information...</source>
- <translation>메타 정보 추출 중...</translation>
- </message>
- <message>
- <source>Checksum mismatch detected for &quot;%1&quot;.</source>
- <translation>&quot;%1&quot;에 대한 체크섬 불일치가 감지되었습니다.</translation>
- </message>
- <message>
- <source>Retrieving meta information from remote repository... %1/%2 </source>
- <translation>원격 리포지토리에서 메타 정보 검색 중... %1/%2 </translation>
- </message>
- <message>
- <source>Retrieving meta information from remote repository... </source>
- <translation>원격 리포지토리에서 메타 정보 검색 중... </translation>
- </message>
- <message>
- <source>Error while extracting archive &quot;%1&quot;: %2</source>
- <translation>아카이브 &quot;%1&quot; 추출 중에 오류 발생: %2</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for reading: %2</source>
- <translation>&quot;%1&quot; 파일을 읽기 위해 열 수 없음: %2</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::FileTaskObserver</name>
- <message>
- <source>%1 of %2</source>
- <translation>%1/%2</translation>
- </message>
- <message>
- <source>%1 received.</source>
- <translation>%1을(를) 받았습니다.</translation>
- </message>
- <message>
- <source>(%1/sec)</source>
- <translation>(%1/초)</translation>
- </message>
- <message numerus="yes">
- <source>%n day(s), </source>
- <translation>
- <numerusform>%n일, </numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>%n hour(s), </source>
- <translation>
- <numerusform>%n시간, </numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>%n minute(s)</source>
- <translation>
- <numerusform>%n분</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>%n second(s)</source>
- <translation>
- <numerusform>%n초</numerusform>
- </translation>
- </message>
- <message>
- <source> - %1%2%3%4 remaining.</source>
- <translation> - 남은 시간: %1%2%3%4</translation>
- </message>
- <message>
- <source> - unknown time remaining.</source>
- <translation> - 남은 시간: 알 수 없음</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::PackageManagerCore</name>
- <message>
- <source>Error writing Maintenance Tool</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>Canceling the Installer</source>
- <translation>설치 관리자 취소 중</translation>
- </message>
- <message>
- <source>Authentication Error</source>
- <translation>인증 오류</translation>
- </message>
- <message>
- <source>Some components could not be removed completely because administrative 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>User input is required but the output device is not associated with a terminal.</source>
- <translation>사용자 입력이 필요하지만 출력 기기가 터미널과 연결되지 않았습니다.</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>오류</translation>
- </message>
- <message>
- <source>The directory you selected already exists and contains an installation. Choose a different target for installation.</source>
- <translation>선택한 디렉토리가 이미 존재하며 설치 항목도 포함되어 있습니다. 설치하려면 다른 디렉토리를 선택하십시오.</translation>
- </message>
- <message>
- <source>Warning</source>
- <translation>경고</translation>
- </message>
- <message>
- <source>You have selected an existing, non-empty directory for installation.
-Note that it will be completely wiped on uninstallation of this application.
-It is not advisable to install into this directory as installation might fail.
-Do you want to continue?</source>
- <translation>파일이 이미 있는 기존 디렉토리를 설치 디렉토리로 선택하셨습니다.
-이 애플리케이션을 제거할 때 디렉토리가 완전히 삭제되오니 유의하십시오.
-설치가 실패할 수 있으므로 이 디렉토리에 설치하는 것은 권장하지 않습니다.
-계속하시겠습니까?</translation>
- </message>
- <message>
- <source>You have selected an existing file or symlink, please choose a different target for installation.</source>
- <translation>기존 파일 또는 symlink를 선택하셨습니다. 설치할 다른 대상을 선택하십시오.</translation>
- </message>
- <message>
- <source>The installation path cannot be empty, please specify a valid directory.</source>
- <translation>설치 경로가 비어 있으면 안 됩니다. 유효한 디렉토리를 선택하십시오.</translation>
- </message>
- <message>
- <source>The installation path cannot be relative, please specify an absolute path.</source>
- <translation>상대적인 경로를 설치 경로로 지정하면 안 됩니다. 절대 경로를 지정하십시오.</translation>
- </message>
- <message>
- <source>The path or installation directory contains non ASCII characters. This is currently not supported! Please choose a different path or installation directory.</source>
- <translation>설치 경로 또는 디렉토리에 ASCII 문자가 아닌 문자가 포함되어 있습니다. 현재 이는 지원되지 않습니다! 다른 설치 경로나 디렉토리를 선택하십시오.</translation>
- </message>
- <message>
- <source>As the install directory is completely deleted, installing in %1 is forbidden.</source>
- <translation>설치 경로가 완전히 삭제되었으므로 %1에 설치할 수 없습니다.</translation>
- </message>
- <message>
- <source>The path you have entered is too long, please make sure to specify a valid path.</source>
- <translation>입력하신 경로가 너무 깁니다. 유효한 경로를 지정하십시오.</translation>
- </message>
- <message>
- <source>The path you have entered is not valid, please make sure to specify a valid target.</source>
- <translation>입력하신 경로가 유효하지 않습니다. 유효한 경로를 지정하십시오.</translation>
- </message>
- <message>
- <source>The path you have entered is not valid, please make sure to specify a valid drive.</source>
- <translation>입력하신 경로가 유효하지 않습니다. 유효한 드라이브를 지정하십시오.</translation>
- </message>
- <message>
- <source>The installation path must not end with &apos;.&apos;, please specify a valid directory.</source>
- <translation>설치 경로가 &apos;.&apos; 문자로 끝나면 안 됩니다. 유효한 디렉토리를 지정하십시오.</translation>
- </message>
- <message>
- <source>The installation path must not contain &quot;%1&quot;, please specify a valid directory.</source>
- <translation>설치 경로에 &quot;%1&quot; 문자가 포함되면 안 됩니다. 유효한 디렉토리를 지정하십시오.</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>Cannot register component! Component with identifier %1 already exists.</source>
- <translation>구성요소를 등록할 수 없습니다! %1 식별자가 있는 구성 요소가 이미 존재합니다.</translation>
- </message>
- <message>
- <source>Application running in Uninstaller mode.</source>
- <translation>애플리케이션이 설치 제거 관리자 모드로 실행 중입니다.</translation>
- </message>
- <message>
- <source>There is an important update available, please run the updater first.</source>
- <translation>중요한 업데이트가 있습니다. 업데이터를 먼저 실행하십시오.</translation>
- </message>
- <message>
- <source>Cannot resolve all dependencies.</source>
- <translation>모든 종속성을 해결할 수 없습니다.</translation>
- </message>
- <message>
- <source>Components about to be removed.</source>
- <translation>구성요소가 제거됩니다.</translation>
- </message>
- <message>
- <source>Cannot install %1. Component not found.
-</source>
- <translation>%1을(를) 설치할 수 없습니다. 구성요소를 찾을 수 없습니다.
-</translation>
- </message>
- <message>
- <source>Cannot install component %1. Component is installed only as automatic dependency to %2.
-</source>
- <translation>%1 구성요소를 설치할 수 없습니다. %2에 대한 자동 종속성으로만 구성요소가 설치됩니다.
-</translation>
- </message>
- <message>
- <source>Cannot install component %1. Component is not checkable, meaning you have to select one of the subcomponents.
-</source>
- <translation>%1 구성요소를 설치할 수 없습니다. 구성요소를 확인할 수 없어 하위 구성요소 중 하나를 설치해야 합니다.
-</translation>
- </message>
- <message>
- <source>Component %1 already installed
-</source>
- <translation>%1 구성요소가 이미 설치됨
-</translation>
- </message>
- <message>
- <source>Cannot install %1. Component is a descendant of a virtual component %2.
-</source>
- <translation>%1을(를) 설치할 수 없습니다. 구성요소가 가상 구성요소 %2의 하위 항목입니다.
-</translation>
- </message>
- <message>
- <source>Cannot install %1. Component is virtual.
-</source>
- <translation>%1을(를) 설치할 수 없습니다. 가상 구성요소입니다.
-</translation>
- </message>
- <message>
- <source>Running processes found.</source>
- <translation>실행 중인 프로세스를 찾았습니다.</translation>
- </message>
- <message>
- <source>Cannot elevate access rights while running from command line. Please restart the application as administrator.</source>
- <translation>명령줄에서 실행할 때 접근 원한을 상승시킬 수 없습니다. 관리자로서 애플리케이션을 재시작하십시오.</translation>
- </message>
- <message>
- <source>Error while elevating access rights.</source>
- <translation>접근 권한을 상승시키는 중에 오류가 발생했습니다.</translation>
- </message>
- <message>
- <source>Not enough disk space to store temporary files and the installation. %1 are available, while the minimum required is %2.</source>
- <translation>디스크 공간이 부족하여 임시 파일과 설치 파일을 저장할 수 없습니다. %1은(는) 사용 가능하지만 최소한 %2이(가) 필요합니다.</translation>
- </message>
- <message>
- <source>Not enough disk space to store all selected components! %1 are available, while the minimum required is %2.</source>
- <translation>디스크 공간이 부족하여 선택한 구성요소를 모두 저장할 수 없습니다! %1은(는) 사용 가능하지만 최소한 %2이(가) 필요합니다.</translation>
- </message>
- <message>
- <source>Not enough disk space to store temporary files! %1 are available, while the minimum required is %2.</source>
- <translation>디스크 공간이 부족하여 임시 파일을 저장할 수 없습니다! %1은(는) 사용 가능하지만 최소한 %2이(가) 필요합니다.</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.</source>
- <translation>설치를 위해 선택한 볼륨은 설치 공간이 충분한 것으로 보이지만, 설치 후에 남은 공간이 볼륨 공간의 %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.</source>
- <translation>설치를 위해 선택한 볼륨은 설치 공간이 충분한 것으로 보이지만, 설치 후에 남은 공간이 100MB 미만일 것으로 예상됩니다.</translation>
- </message>
- <message>
- <source>The estimated installer size %1 would exceed the supported executable size limit of %2. The application may not be able to run.</source>
- <translation>예상 설치 크기(%1)가 지원되는 실행 가능한 크기 제한(%2)을 초과할 것으로 예상됩니다. 애플리케이션 실행이 불가능할 수 있습니다.</translation>
- </message>
- <message>
- <source>Installation will use %1 of disk space.</source>
- <translation>설치 관리자가 디스크 공간의 %1을(를) 사용할 것입니다.</translation>
- </message>
- <message>
- <source>Invalid</source>
- <translation>유효하지 않음</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::PackageManagerCorePrivate</name>
- <message>
- <source>Unresolved dependencies</source>
- <translation>해결되지 않은 종속성</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>오류</translation>
- </message>
- <message>
- <source>Access error</source>
- <translation>접근 오류</translation>
- </message>
- <message>
- <source>Format error</source>
- <translation>형식 오류</translation>
- </message>
- <message>
- <source>Cannot 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>Retry count exceeded</source>
- <translation>재시도 횟수 초과</translation>
- </message>
- <message>
- <source>Writing maintenance tool.</source>
- <translation>유지 보수 도구를 쓰는 중입니다.</translation>
- </message>
- <message>
- <source>Failed to seek in file %1: %2</source>
- <translation>%1 파일에서 찾지 못함: %2</translation>
- </message>
- <message>
- <source>Maintenance tool is not a bundle</source>
- <translation>유지 보수 도구가 번들이 아님</translation>
- </message>
- <message>
- <source>Cannot remove data file &quot;%1&quot;: %2</source>
- <translation>&quot;1%&quot; 데이터 파일을 제거할 수 없음 %2</translation>
- </message>
- <message>
- <source>Cannot write maintenance tool data to %1: %2</source>
- <translation>%1에 유지 보수 도구 데이터를 쓸 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot write maintenance tool to &quot;%1&quot;: %2</source>
- <translation>%1에 유지 보수 도구를 쓸 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot remove temporary data file &quot;%1&quot;: %2</source>
- <translation>임시 디렉토리 &quot;%1&quot; 제거가 불가능합니다. %2</translation>
- </message>
- <message>
- <source>Cannot write maintenance tool binary data to %1: %2</source>
- <translation>%1에 유지 보수 도구 바이너리 데이터를 쓸 수 없음: %2</translation>
- </message>
- <message>
- <source>Writing offline base binary.</source>
- <translation>오프라인 기본 바이너리를 쓰는 중입니다.</translation>
- </message>
- <message>
- <source>Cannot remove file &quot;%1&quot;: %2</source>
- <translation>&quot;1%&quot; 파일을 제거할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot create directory &quot;%1&quot;.</source>
- <translation>&quot;1%&quot; 디렉토리를 생성할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot write offline binary to &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot;에 오프라인 바이너리를 쓸 수 없습니다. %2</translation>
- </message>
- <message>
- <source>Cannot remove temporary file &quot;%1&quot;: %2</source>
- <translation>임시 디렉토리 &quot;%1&quot; 제거가 불가능합니다. %2</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 Maintenance Tool</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>Removal completed successfully.</source>
- <translation>성공적으로 설치 제거했습니다.</translation>
- </message>
- <message>
- <source>Removal aborted.</source>
- <translation>설치 제거가 중단되었습니다.</translation>
- </message>
- <message>
- <source>Cannot create target directory for installer.</source>
- <translation>설치 관리자에 사용할 대상 디렉토리를 생성할 수 없습니다.</translation>
- </message>
- <message>
- <source>Preparing offline generation...</source>
- <translation>오프라인 생성 준비 중...</translation>
- </message>
- <message>
- <source>Preparing installer configuration...</source>
- <translation>설치 관리자 구성 요소 준비 중...</translation>
- </message>
- <message>
- <source>Creating the installer...</source>
- <translation>설치 관리자 생성 중...</translation>
- </message>
- <message>
- <source>Failed to create offline installer. %1</source>
- <translation>오프라인 설치 관리자를 생성할 수 없습니다. %1</translation>
- </message>
- <message>
- <source>Cannot remove temporary directory &quot;%1&quot;.</source>
- <translation>임시 디렉토리 &quot;%1&quot; 제거에 실패했습니다.</translation>
- </message>
- <message>
- <source>Offline generation completed successfully.</source>
- <translation>성공적으로 오프라인 생성을 완료했습니다.</translation>
- </message>
- <message>
- <source>Offline generation 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>Done</source>
- <translation>완료</translation>
- </message>
- <message>
- <source>Cannot prepare removal</source>
- <translation>설치 제거를 준비할 수 없음</translation>
- </message>
- <message>
- <source>Cannot start removal</source>
- <translation>설치 제거를 시작할 수 없음</translation>
- </message>
- <message>
- <source>Error during removal process:
-%1</source>
- <translation>설치 해제 프로세스 중에 오류 발생:
-%1</translation>
- </message>
- <message>
- <source>Unknown error</source>
- <translation>알 수 없는 오류</translation>
- </message>
- <message>
- <source>Cannot retrieve remote tree %1.</source>
- <translation>원격 트리 %1을(를) 검색할 수 없습니다.</translation>
- </message>
- <message>
- <source>Failure to read packages from %1.</source>
- <translation>%1에서 패키지를 읽을 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot retrieve meta information: %1</source>
- <translation>메타 정보를 검색할 수 없음: %1</translation>
- </message>
- <message>
- <source>Cannot add temporary update source information.</source>
- <translation>임시 업데이트 소스 정보를 추가할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot find any update source information.</source>
- <translation>어떠한 업데이트 소스 정보도 추가할 수 없습니다.</translation>
- </message>
- <message>
- <source>Dependency cycle between components &quot;%1&quot; and &quot;%2&quot; detected.</source>
- <translation>구성요소 &quot;%1&quot; 및 &quot;%2&quot; 간의 종속성 사이클이 감지되었습니다.</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>Do you want to cancel the installation process?</source>
- <translation>설치 프로세스를 취소하시겠습니까?</translation>
- </message>
- <message>
- <source>Do you want to cancel the removal process?</source>
- <translation>설치 제거 프로세스를 취소하시겠습니까?</translation>
- </message>
- <message>
- <source>Do you want to quit the installer application?</source>
- <translation>설치 관리자 애플리케이션을 종료하시겠습니까?</translation>
- </message>
- <message>
- <source>Do you want to quit the uninstaller application?</source>
- <translation>설치 제거 관리자 애플리케이션을 종료하시겠습니까?</translation>
- </message>
- <message>
- <source>Do you want to quit the maintenance application?</source>
- <translation>유지 보수 애플리케이션을 종료하시겠습니까?</translation>
- </message>
- <message>
- <source>%1 Question</source>
- <translation>%1 질문</translation>
- </message>
- <message>
- <source>Settings</source>
- <translation>설정</translation>
- </message>
- <message>
- <source>Specify proxy settings and configure repositories for add-on components.</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::IntroductionPage</name>
- <message>
- <source>Setup - %1</source>
- <translation>설정 - %1</translation>
- </message>
- <message>
- <source>Welcome to the %1 Setup Wizard.</source>
- <translation>%1 설정 마법사에 오신 것을 환영합니다.</translation>
- </message>
- <message>
- <source>&amp;Add or remove components</source>
- <translation>구성요소 추가 또는 제거(&amp;A)</translation>
- </message>
- <message>
- <source>&amp;Update components</source>
- <translation>구성요소 업데이트(&amp;U)</translation>
- </message>
- <message>
- <source>&amp;Remove all components</source>
- <translation>모든 구성요소 제거(&amp;R)</translation>
- </message>
- <message>
- <source>Retrieving information from remote installation sources...</source>
- <translation>원격 설치 소스에서 정보 검색 중...</translation>
- </message>
- <message>
- <source>At least one valid and enabled repository required for this action to succeed.</source>
- <translation>이 작업을 성공적으로 수행하려면 최소 1개의 유효하고 활성화된 리포지토리가 필요합니다.</translation>
- </message>
- <message>
- <source>No updates available.</source>
- <translation>사용 가능한 업데이트가 없습니다.</translation>
- </message>
- <message>
- <source> Only local package management available.</source>
- <translation> 로컬 패키지 관리만 가능합니다.</translation>
- </message>
- <message>
- <source>&amp;Quit</source>
- <translation>종료(&amp;Q)</translation>
- </message>
- <message>
- <source>There is an important update available. Please select &apos;%1&apos; first</source>
- <translation type="unfinished"></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>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>
-</context>
-<context>
- <name>QInstaller::TargetDirectoryPage</name>
- <message>
- <source>Installation Folder</source>
- <translation>설치 폴더</translation>
- </message>
- <message>
- <source>Please specify the directory 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;R)...</translation>
- </message>
- <message>
- <source>Browse file system to choose the installation directory.</source>
- <translation>파일 시스템을 탐색하여 설치 디렉토리를 선택합니다.</translation>
- </message>
- <message>
- <source>Select Installation Folder</source>
- <translation>설치 폴더 선택</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 directory.</source>
- <translation>프로그램 바로 가기를 생성하려는 시작 메뉴를 선택합니다. 이름을 직접 입력하여 새 디렉토리를 생성할 수도 있습니다.</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ReadyForInstallationPage</name>
- <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>Ready to Update</source>
- <translation>업데이트 준비 완료</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::PerformInstallationPage</name>
- <message>
- <source>U&amp;ninstall</source>
- <translation>설치 제거(&amp;N)</translation>
- </message>
- <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>Installing</source>
- <translation>설치 중</translation>
- </message>
- <message>
- <source>Updating</source>
- <translation>업데이트 중</translation>
- </message>
- <message>
- <source>Uninstalling</source>
- <translation>설치 제거 중</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::FinishedPage</name>
- <message>
- <source>Completing the %1 Wizard</source>
- <translation>%1 마법사 완료 중</translation>
- </message>
- <message>
- <source>Finished</source>
- <translation>완료됨</translation>
- </message>
- <message>
- <source>Click %1 to exit the %2 Wizard.</source>
- <translation>%2 마법사를 종료하려면 %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::RestartPage</name>
- <message>
- <source>Completing the %1 Setup Wizard</source>
- <translation>%1 설정 마법사 완료 중</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::RegisterFileTypeOperation</name>
- <message>
- <source>Registering file types is only supported on Windows.</source>
- <translation>등록하려는 파일 유형이 Windows에서만 지원됩니다.</translation>
- </message>
- <message>
- <source>Register File Type: Invalid arguments</source>
- <translation>등록 파일 유형: 유효하지 않은 인수</translation>
- </message>
-</context>
-<context>
- <name>RemoteClient</name>
- <message>
- <source>Cannot get authorization.</source>
- <translation>권한 부여를 받을 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot get authorization that is needed for continuing the installation.
- Either abort the installation or use the fallback solution by running
-
-%1
-
-as a user with the appropriate rights and then clicking OK.</source>
- <translation>설치를 계속하기 위해 필요한 권한 부여를 받을 수 없습니다.
- 설치를 중단하거나 임시 해결책으로 적절한 권한이 있는 사용자로
-
-%1을(를)
-
-실행한 다음 ‘확인’을 클릭하십시오.</translation>
- </message>
- <message>
- <source>Cannot get authorization that is needed for continuing the installation.
-
-Please start the setup program as a user with the appropriate rights,
-or accept the elevation of access rights if being asked.</source>
- <translation>설치를 계속하기 위해 필요한 권한 부여를 받을 수 없습니다.
-
-적절한 권한이 있는 사용자로서 설정 프로그램을 시작하십시오.
-또는 요청 시 접근 권한 상승을 수락하십시오.</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::RemoteObject</name>
- <message>
- <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
- <translation>다음 명령 전송 후 모든 데이터를 읽을 수 없음: %1. 예상된 바이트: %2, 수신한 바이트: %3. 오류: %4</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ReplaceOperation</name>
- <message>
- <source>Current search argument calling &quot;%1&quot; with empty search argument is not supported.</source>
- <translation>빈 검색 인수로 &quot;%1&quot;을(를) 호출하는 검색 인수는 지원되지 않습니다.</translation>
- </message>
- <message>
- <source>Current mode argument calling &quot;%1&quot; with arguments &quot;%2&quot; is not supported. Please use string or regex.</source>
- <translation>&quot;%2&quot; 인수로 &quot;%1&quot;을(를) 호출하는 현재 모드는 지원되지 않습니다. 문자열이나 regex를 사용하십시오.</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for reading: %2</source>
- <translation>&quot;%1&quot; 파일을 읽기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for writing: %2</source>
- <translation>&quot;%1&quot; 파일을 쓰기 위해 열 수 없음: %2</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::QFileDialogProxy</name>
- <message>
- <source>User input is required but the output device is not associated with a terminal.</source>
- <translation>사용자 입력이 필요하지만 출력 기기가 터미널과 연결되지 않았습니다.</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ScriptEngine</name>
- <message>
- <source>Cannot open script file at %1: %2</source>
- <translation>%1에서 스크립트 파일을 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Exception while loading the component script &quot;%1&quot;: %2</source>
- <translation>구성요소 스크립트 &quot;%1&quot; 로드 중에 예외 발생: %2</translation>
- </message>
- <message>
- <source>Unknown error.</source>
- <translation>알 수 없는 오류입니다.</translation>
- </message>
- <message>
- <source>on line number: </source>
- <translation>온라인 번호: </translation>
- </message>
-</context>
-<context>
- <name>QInstaller::SelfRestartOperation</name>
- <message>
- <source>Installer object needed in operation %1 is empty.</source>
- <translation>&quot;%1&quot; 작업에 필요한 설치 개체가 비어 있습니다.</translation>
- </message>
- <message>
- <source>Self Restart: Only valid within updater or package manager mode.</source>
- <translation>자가 재시작: 업데이터 또는 패키지 관리자 모드에서만 사용 가능합니다.</translation>
- </message>
- <message>
- <source>Self Restart: Invalid arguments</source>
- <translation>자가 재시작: 유효하지 않은 인수</translation>
- </message>
-</context>
-<context>
- <name>Settings</name>
- <message>
- <source>Cannot open settings file %1 for reading: %2</source>
- <translation>설정 파일 &quot;%1&quot;을(를) 읽기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Select Categories</source>
- <translation>범주 선택</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::SettingsOperation</name>
- <message>
- <source>Missing argument(s) &quot;%1&quot; calling %2 with arguments &quot;%3&quot;.</source>
- <translation>&quot;%3&quot; 인수가 있는 %2를 호출하는 &quot;%1&quot; 인수가 누락되었습니다.</translation>
- </message>
- <message>
- <source>Current method argument calling &quot;%1&quot; with arguments &quot;%2&quot; is not supported. Please use set, remove, add_array_value, or remove_array_value.</source>
- <translation>&quot;%2&quot; 인수로 &quot;%1&quot;을(를) 호출하는 현재 모드는 지원되지 않습니다. set, remove, add_array_value or remove_array_value를 사용하십시오.</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::SimpleMoveFileOperation</name>
- <message>
- <source>None of the arguments can be empty: source &quot;%1&quot;, target &quot;%2&quot;.</source>
- <translation>인수는 모두 입력해야 합니다: 소스 &quot;%1&quot;, 대상 &quot;%2&quot;.</translation>
- </message>
- <message>
- <source>Cannot move file from &quot;%1&quot; to &quot;%2&quot;, because the target path exists and is not removable.</source>
- <translation>대상 파일이 존재하며 제거할 수 없으므로 &quot;%1&quot;에서 &quot;%2&quot;에 파일을 옮길 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot move file &quot;%1&quot; to &quot;%2&quot;: %3</source>
- <translation>파일 &quot;%1&quot;을(를) &quot;%2&quot;(으)로 옮길 수 없습니다. %3</translation>
- </message>
- <message>
- <source>Moving file &quot;%1&quot; to &quot;%2&quot;.</source>
- <translation>파일 &quot;%1&quot;을(를) &quot;%2&quot;으(로) 옮깁니다.</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::TestRepository</name>
- <message>
- <source>Missing package manager core engine.</source>
- <translation>패키지 관리자 코어 엔진이 누락되었습니다.</translation>
- </message>
- <message>
- <source>Empty repository URL.</source>
- <translation>리포지토리 URL이 비었습니다.</translation>
- </message>
- <message>
- <source>Download canceled.</source>
- <translation>다운로드가 취소되었습니다.</translation>
- </message>
- <message>
- <source>Timeout while testing repository &quot;%1&quot;.</source>
- <translation>&quot;%1&quot; 리포지토리를 테스트하는 중에 시간이 초과되었습니다.</translation>
- </message>
- <message>
- <source>Cannot parse Updates.xml: %1</source>
- <translation>Updates.xml을 파싱할 수 없습니다. %1</translation>
- </message>
- <message>
- <source>Cannot open Updates.xml for reading: %1</source>
- <translation>Updates.xml 파일을 읽기 위해 열 수 없습니다. %1</translation>
- </message>
- <message>
- <source>Authentication failed.</source>
- <translation>인증하지 못했습니다.</translation>
- </message>
- <message>
- <source>Unknown error while testing repository &quot;%1&quot;.</source>
- <translation>&quot;%1&quot; 리포지토리를 테스트하는 중에 알 수 없는 오류가 발생했습니다.</translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::FileDownloader</name>
- <message>
- <source>Download finished.</source>
- <translation>다운로드가 완료되었습니다.</translation>
- </message>
- <message>
- <source>Cryptographic hashes do not match.</source>
- <translation>암호화된 해시가 일치하지 않습니다.</translation>
- </message>
- <message>
- <source>Download canceled.</source>
- <translation>다운로드가 취소되었습니다.</translation>
- </message>
- <message>
- <source>%1 of %2</source>
- <translation>%1/%2</translation>
- </message>
- <message>
- <source>%1 downloaded.</source>
- <translation>%1 다운로드가 완료되었습니다.</translation>
- </message>
- <message>
- <source>(%1/sec)</source>
- <translation>(%1/초)</translation>
- </message>
- <message numerus="yes">
- <source>%n day(s), </source>
- <translation>
- <numerusform>%n일, </numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>%n hour(s), </source>
- <translation>
- <numerusform>%n시간, </numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>%n minute(s)</source>
- <translation>
- <numerusform>%n분</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>%n second(s)</source>
- <translation>
- <numerusform>%n초</numerusform>
- </translation>
- </message>
- <message>
- <source> - %1%2%3%4 remaining.</source>
- <translation> - 남은 시간: %1%2%3%4</translation>
- </message>
- <message>
- <source> - unknown time remaining.</source>
- <translation> - 남은 시간: 알 수 없음</translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::LocalFileDownloader</name>
- <message>
- <source>Cannot open file &quot;%1&quot; for reading: %2</source>
- <translation>&quot;%1&quot; 파일을 읽기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for writing: %2</source>
- <translation>&quot;%1&quot; 파일을 쓰기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Writing to file &quot;%1&quot; failed: %2</source>
- <translation>&quot;%1&quot; 파일에 쓰기 실패: %2</translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::ResourceFileDownloader</name>
- <message>
- <source>Cannot read resource file &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 리소스 파일을 읽을 수 없음: %2</translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::HttpDownloader</name>
- <message>
- <source>Cannot download %1. Writing to file &quot;%2&quot; failed: %3</source>
- <translation>%1을(를) 다운로드할 수 없습니다. &quot;%2&quot; 파일에 쓰기 실패: %3</translation>
- </message>
- <message>
- <source>Cannot download %1. Cannot create file &quot;%2&quot;: %3</source>
- <translation>%1을(를) 다운로드할 수 없습니다. &quot;%2&quot; 파일을 생성할 수 없음: %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>Job</name>
- <message>
- <source>Canceled</source>
- <translation>취소됨</translation>
- </message>
-</context>
-<context>
- <name>LocalPackageHub</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>Cannot open %1.</source>
- <translation>%1을(를) 열 수 없습니다.</translation>
- </message>
- <message>
- <source>Parse error in %1 at %2, %3: %4</source>
- <translation>%2의 %1에서 파싱 오류 발생, %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>LockFile</name>
- <message>
- <source>Cannot create lock file &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 파일 잠금을 생성할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot write PID to lock file &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 파일을 잠그기 위해 PID를 쓸 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot obtain the lock for file &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 파일을 위한 잠금을 수행할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot release the lock for file &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 파일을 위한 잠금을 해제할 수 없음: %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>Cannot access the package information of this application.</source>
- <translation>이 애플리케이션의 패키지 정보에 액세스할 수 없습니다.</translation>
- </message>
- <message>
- <source>No package sources set for this application.</source>
- <translation>이 애플리케이션에 설정된 패키지 소스가 없습니다.</translation>
- </message>
- <message numerus="yes">
- <source>%n update(s) found.</source>
- <translation>
- <numerusform>%n개의 업데이트를 찾았습니다.</numerusform>
- </translation>
- </message>
- <message>
- <source>Downloading Updates.xml from update sources.</source>
- <translation>업데이트 소스에서 Updates.xml을 다운로드합니다.</translation>
- </message>
- <message>
- <source>Cannot download package source %1 from &quot;%2&quot;.</source>
- <translation>&quot;%2&quot;에서 패키지 소스(%1)를 다운로드할 수 없습니다.</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>
-</context>
-<context>
- <name>KDUpdater::CopyOperation</name>
- <message>
- <source>Cannot backup file &quot;%1&quot;.</source>
- <translation>&quot;%1&quot; 파일을 백업할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot copy a non-existent file: %1</source>
- <translation>존재하지 않는 파일을 복사할 수 없음: %1</translation>
- </message>
- <message>
- <source>Cannot remove file &quot;%1&quot;: %2</source>
- <translation>&quot;1%&quot; 파일을 제거할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot copy file &quot;%1&quot; to &quot;%2&quot;: %3</source>
- <translation>&quot;%1&quot;에서 &quot;%2&quot;에 파일을 복사할 수 없음: %3</translation>
- </message>
- <message>
- <source>Cannot delete file &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 파일을 삭제할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot restore backup file into &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot;의 백업 파일을 복원할 수 없음: %2</translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::MoveOperation</name>
- <message>
- <source>Cannot backup file &quot;%1&quot;.</source>
- <translation>&quot;%1&quot; 파일을 백업할 수 없습니다.</translation>
- </message>
- <message>
- <source>Cannot remove file &quot;%1&quot;: %2</source>
- <translation>&quot;1%&quot; 파일을 제거할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot copy file &quot;%1&quot; to &quot;%2&quot;: %3</source>
- <translation>&quot;%1&quot;에서 &quot;%2&quot;에 파일을 복사할 수 없음: %3</translation>
- </message>
- <message>
- <source>Cannot remove file &quot;%1&quot;.</source>
- <translation>&quot;1%&quot; 파일을 제거할 수 없음:</translation>
- </message>
- <message>
- <source>Cannot restore backup file for &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot;의 백업 파일을 복원할 수 없음: %2</translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::DeleteOperation</name>
- <message>
- <source>Cannot create backup of file &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 파일의 백업을 생성할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot restore backup file for &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot;의 백업 파일을 복원할 수 없음: %2</translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::MkdirOperation</name>
- <message>
- <source>Cannot create directory &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 디렉토리를 생성할 수 없음: %2</translation>
- </message>
- <message>
- <source>Unknown error.</source>
- <translation>알 수 없는 오류입니다.</translation>
- </message>
- <message>
- <source>Cannot remove directory &quot;%1&quot;: %2</source>
- <translation>&quot;1%&quot; 디렉토리를 제거할 수 없음: %2</translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::RmdirOperation</name>
- <message>
- <source>Cannot remove directory &quot;%1&quot;: %2</source>
- <translation>&quot;1%&quot; 디렉토리를 제거할 수 없음: %2</translation>
- </message>
- <message>
- <source>The directory does not exist.</source>
- <translation>이 디렉토리가 존재하지 않습니다.</translation>
- </message>
- <message>
- <source>Cannot recreate directory &quot;%1&quot;: %2</source>
- <translation>&quot;1%&quot; 디렉토리를 다시 생성할 수 없습니다. %2</translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::AppendFileOperation</name>
- <message>
- <source>Cannot backup file &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 파일을 백업할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for writing: %2</source>
- <translation>&quot;%1&quot; 파일을 쓰기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot find backup file for &quot;%1&quot;.</source>
- <translation>&quot;%1&quot;의 백업 파일을 찾을 수 없음:</translation>
- </message>
- <message>
- <source>Cannot restore backup file for &quot;%1&quot;.</source>
- <translation>&quot;%1&quot;의 백업 파일을 복원할 수 없음:</translation>
- </message>
- <message>
- <source>Cannot restore backup file for &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot;의 백업 파일을 복원할 수 없음: %2</translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::PrependFileOperation</name>
- <message>
- <source>Cannot backup file &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot; 파일을 백업할 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for reading: %2</source>
- <translation>&quot;%1&quot; 파일을 읽기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot open file &quot;%1&quot; for writing: %2</source>
- <translation>&quot;%1&quot; 파일을 쓰기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Cannot find backup file for &quot;%1&quot;.</source>
- <translation>&quot;%1&quot;의 백업 파일을 찾을 수 없음:</translation>
- </message>
- <message>
- <source>Cannot restore backup file for &quot;%1&quot;.</source>
- <translation>&quot;%1&quot;의 백업 파일을 복원할 수 없음:</translation>
- </message>
- <message>
- <source>Cannot restore backup file for &quot;%1&quot;: %2</source>
- <translation>&quot;%1&quot;의 백업 파일을 복원할 수 없음: %2</translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::UpdatesInfoData</name>
- <message>
- <source>Updates.xml contains invalid content: %1</source>
- <translation>Updates.xml 파일에 올바르지 않은 콘텐츠가 포함됨: %1</translation>
- </message>
- <message>
- <source>Cannot read &quot;%1&quot;</source>
- <translation>&quot;%1&quot;을(를) 읽을 수 없음</translation>
- </message>
- <message>
- <source>Parse error in %1 at %2, %3: %4</source>
- <translation>%2의 %1에서 파싱 오류 발생, %3: %4</translation>
- </message>
- <message>
- <source>Root element %1 unexpected, should be &quot;Updates&quot;.</source>
- <translation>%1 루트 요소는 예상하지 못했습니다. &apos;Updates&apos;여야 합니다.</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>InstallerBase</name>
- <message>
- <source>Unable to start installer</source>
- <translation>설치 관리자를 시작할 수 없음</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ExtractArchiveOperation::Worker</name>
- <message>
- <source>Could not create handler object for archive &quot;%1&quot;: &quot;%2&quot;.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot open archive &quot;%1&quot; for reading: %2</source>
- <translation>&quot;%1&quot; 아카이브를 읽기 위해 열 수 없음: %2</translation>
- </message>
- <message>
- <source>Error while reading contents of archive &quot;%1&quot;: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot prepare for file &quot;%1&quot;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Extract for archive &quot;%1&quot; canceled.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error while extracting archive &quot;%1&quot;: %2</source>
- <translation>아카이브 &quot;%1&quot; 추출 중에 오류 발생: %2</translation>
- </message>
-</context>
-</TS>
diff --git a/tests/auto/installer/cliinterface/tst_cliinterface.cpp b/tests/auto/installer/cliinterface/tst_cliinterface.cpp
index d880310ac..25910cd9c 100644
--- a/tests/auto/installer/cliinterface/tst_cliinterface.cpp
+++ b/tests/auto/installer/cliinterface/tst_cliinterface.cpp
@@ -34,6 +34,9 @@
#include <QLoggingCategory>
#include <QTest>
+#include <iostream>
+#include <sstream>
+
using namespace QInstaller;
class tst_CLIInterface : public QObject
@@ -43,8 +46,7 @@ class tst_CLIInterface : public QObject
private slots:
void testListAvailablePackages()
{
- QString loggingRules = (QLatin1String("ifw.* = false\n"
- "ifw.package.* = true\n"));
+ QString loggingRules = (QLatin1String("ifw.* = false\n"));
QTest::ignoreMessage(QtDebugMsg, "Operations sanity check succeeded.");
@@ -52,61 +54,52 @@ private slots:
(m_installDir, ":///data/repository");
QLoggingCategory::setFilterRules(loggingRules);
+ auto func = &PackageManagerCore::listAvailablePackages;
- QTest::ignoreMessage(QtDebugMsg, "<availablepackages>\n"
- " <package name=\"AB\" displayname=\"AB\" version=\"1.0.2-1\"/>\n"
- " <package name=\"A\" displayname=\"A\" version=\"1.0.2-1\"/>\n"
- " <package name=\"B\" displayname=\"B\" version=\"1.0.0-1\"/>\n"
- " <package name=\"C\" displayname=\"C\" version=\"1.0.0-1\"/>\n"
- "</availablepackages>\n");
- core->listAvailablePackages(QLatin1String("."));
-
- QTest::ignoreMessage(QtDebugMsg, "<availablepackages>\n"
- " <package name=\"AB\" displayname=\"AB\" version=\"1.0.2-1\"/>\n"
- " <package name=\"A\" displayname=\"A\" version=\"1.0.2-1\"/>\n"
- "</availablepackages>\n");
- core->listAvailablePackages(QLatin1String("A"));
+ verifyListPackagesMessage(core, QLatin1String("<availablepackages>\n"
+ " <package name=\"AB\" displayname=\"AB\" version=\"1.0.2-1\"/>\n"
+ " <package name=\"A\" displayname=\"A\" version=\"1.0.2-1\"/>\n"
+ " <package name=\"B\" displayname=\"B\" version=\"1.0.0-1\"/>\n"
+ " <package name=\"C\" displayname=\"C\" version=\"1.0.0-1\"/>\n"
+ "</availablepackages>\n"), func, QLatin1String("."), QHash<QString, QString>());
+ verifyListPackagesMessage(core, QLatin1String("<availablepackages>\n"
+ " <package name=\"AB\" displayname=\"AB\" version=\"1.0.2-1\"/>\n"
+ " <package name=\"A\" displayname=\"A\" version=\"1.0.2-1\"/>\n"
+ "</availablepackages>\n"), func, QLatin1String("A"), QHash<QString, QString>());
- QTest::ignoreMessage(QtDebugMsg, "<availablepackages>\n"
- " <package name=\"AB\" displayname=\"AB\" version=\"1.0.2-1\"/>\n"
- " <package name=\"A\" displayname=\"A\" version=\"1.0.2-1\"/>\n"
- "</availablepackages>\n");
- core->listAvailablePackages(QLatin1String("A.*"));
+ verifyListPackagesMessage(core, QLatin1String("<availablepackages>\n"
+ " <package name=\"AB\" displayname=\"AB\" version=\"1.0.2-1\"/>\n"
+ " <package name=\"A\" displayname=\"A\" version=\"1.0.2-1\"/>\n"
+ "</availablepackages>\n"), func, QLatin1String("A.*"), QHash<QString, QString>());
+ verifyListPackagesMessage(core, QLatin1String("<availablepackages>\n"
+ " <package name=\"B\" displayname=\"B\" version=\"1.0.0-1\"/>\n"
+ "</availablepackages>\n"), func, QLatin1String("^B"), QHash<QString, QString>());
- QTest::ignoreMessage(QtDebugMsg, "<availablepackages>\n"
- " <package name=\"B\" displayname=\"B\" version=\"1.0.0-1\"/>\n"
- "</availablepackages>\n");
- core->listAvailablePackages(QLatin1String("^B"));
+ verifyListPackagesMessage(core, QLatin1String("<availablepackages>\n"
+ " <package name=\"B\" displayname=\"B\" version=\"1.0.0-1\"/>\n"
+ "</availablepackages>\n"), func, QLatin1String("^B.*"), QHash<QString, QString>());
- QTest::ignoreMessage(QtDebugMsg, "<availablepackages>\n"
- " <package name=\"B\" displayname=\"B\" version=\"1.0.0-1\"/>\n"
- "</availablepackages>\n");
- core->listAvailablePackages(QLatin1String("^B.*"));
-
- QTest::ignoreMessage(QtDebugMsg, "<availablepackages>\n"
- " <package name=\"C\" displayname=\"C\" version=\"1.0.0-1\"/>\n"
- "</availablepackages>\n");
- core->listAvailablePackages(QLatin1String("^C"));
+ verifyListPackagesMessage(core, QLatin1String("<availablepackages>\n"
+ " <package name=\"C\" displayname=\"C\" version=\"1.0.0-1\"/>\n"
+ "</availablepackages>\n"), func, QLatin1String("^C"), QHash<QString, QString>());
// Test with filters
- QTest::ignoreMessage(QtDebugMsg, "<availablepackages>\n"
- " <package name=\"AB\" displayname=\"AB\" version=\"1.0.2-1\"/>\n"
- " <package name=\"A\" displayname=\"A\" version=\"1.0.2-1\"/>\n"
- "</availablepackages>\n");
QHash<QString, QString> searchHash {
{ "Version", "1.0.2" },
{ "DisplayName", "A" }
};
- core->listAvailablePackages(QString(), searchHash);
+ verifyListPackagesMessage(core, QLatin1String("<availablepackages>\n"
+ " <package name=\"AB\" displayname=\"AB\" version=\"1.0.2-1\"/>\n"
+ " <package name=\"A\" displayname=\"A\" version=\"1.0.2-1\"/>\n"
+ "</availablepackages>\n"), func, QString(), searchHash);
- QTest::ignoreMessage(QtDebugMsg, "<availablepackages>\n"
- " <package name=\"B\" displayname=\"B\" version=\"1.0.0-1\"/>\n"
- "</availablepackages>\n");
searchHash.clear();
searchHash.insert("Default", "false");
- core->listAvailablePackages(QString(), searchHash);
+ verifyListPackagesMessage(core, QLatin1String("<availablepackages>\n"
+ " <package name=\"B\" displayname=\"B\" version=\"1.0.0-1\"/>\n"
+ "</availablepackages>\n"), func, QString(), searchHash);
// Need to change rules here to catch messages
QLoggingCategory::setFilterRules("ifw.* = true\n");
@@ -190,11 +183,11 @@ private slots:
void testListInstalledPackages()
{
- QString loggingRules = (QLatin1String("ifw.* = false\n"
- "ifw.package.* = true\n"));
+ QString loggingRules = (QLatin1String("ifw.* = false\n"));
PackageManagerCore core;
core.setPackageManager();
QLoggingCategory::setFilterRules(loggingRules);
+ auto func = &PackageManagerCore::listInstalledPackages;
const QString testDirectory = QInstaller::generateTemporaryFileName();
QVERIFY(QDir().mkpath(testDirectory));
@@ -202,16 +195,14 @@ private slots:
core.setValue(scTargetDir, testDirectory);
- QTest::ignoreMessage(QtDebugMsg, "<localpackages>\n"
- " <package name=\"A\" displayname=\"A Title\" version=\"1.0.2-1\"/>\n"
- " <package name=\"B\" displayname=\"B Title\" version=\"1.0.0-1\"/>\n"
- "</localpackages>\n");
- core.listInstalledPackages();
+ verifyListPackagesMessage(&core, QLatin1String("<localpackages>\n"
+ " <package name=\"A\" displayname=\"A Title\" version=\"1.0.2-1\"/>\n"
+ " <package name=\"B\" displayname=\"B Title\" version=\"1.0.0-1\"/>\n"
+ "</localpackages>\n"), func, QString());
- QTest::ignoreMessage(QtDebugMsg, "<localpackages>\n"
- " <package name=\"A\" displayname=\"A Title\" version=\"1.0.2-1\"/>\n"
- "</localpackages>\n");
- core.listInstalledPackages(QLatin1String("A"));
+ verifyListPackagesMessage(&core, QLatin1String("<localpackages>\n"
+ " <package name=\"A\" displayname=\"A Title\" version=\"1.0.2-1\"/>\n"
+ "</localpackages>\n"), func, QLatin1String("A"));
QDir dir(testDirectory);
QVERIFY(dir.removeRecursively());
@@ -533,6 +524,21 @@ private slots:
}
private:
+ template <typename Func, typename... Args>
+ void verifyListPackagesMessage(PackageManagerCore *core, const QString &message,
+ Func func, Args... args)
+ {
+ std::ostringstream stream;
+ std::streambuf *buf = std::cout.rdbuf();
+ std::cout.rdbuf(stream.rdbuf());
+
+ (core->*func)(std::forward<Args>(args)...);
+
+ std::cout.rdbuf(buf);
+ QVERIFY(stream && stream.str() == message.toStdString());
+ }
+
+private:
QString m_installDir;
};
diff --git a/tests/auto/installer/libarchivearchive/tst_libarchivearchive.cpp b/tests/auto/installer/libarchivearchive/tst_libarchivearchive.cpp
index f12de22a4..a1f5a1994 100644
--- a/tests/auto/installer/libarchivearchive/tst_libarchivearchive.cpp
+++ b/tests/auto/installer/libarchivearchive/tst_libarchivearchive.cpp
@@ -26,6 +26,8 @@
**
**************************************************************************/
+#include "../shared/verifyinstaller.h"
+
#include <libarchivearchive.h>
#include <fileutils.h>
@@ -44,6 +46,7 @@ private slots:
void initTestCase()
{
m_file.path = "valid";
+ m_file.permissions_mode = 0666;
m_file.compressedSize = 0; // unused
m_file.uncompressedSize = 5242880;
m_file.isDirectory = false;
@@ -79,7 +82,7 @@ private slots:
QVector<ArchiveEntry> files = archive.list();
QCOMPARE(files.count(), 1);
- QVERIFY(entriesMatch(files.first(), m_file));
+ QCOMPARE(files.first(), m_file);
}
void testCreateArchive_data()
@@ -148,6 +151,60 @@ private slots:
QVERIFY(QFile(QDir::tempPath() + QString("/valid")).remove());
}
+ void testCreateExtractWithSymlink_data()
+ {
+ archiveSuffixesTestData();
+ }
+
+ void testCreateExtractWithSymlink()
+ {
+ QFETCH(QString, suffix);
+
+ const QString workingDir = generateTemporaryFileName() + "/";
+ const QString archiveName = workingDir + "archive" + suffix;
+ const QString targetName = workingDir + "target/";
+#ifdef Q_OS_WIN
+ const QString linkName = workingDir + "link.lnk";
+#else
+ const QString linkName = workingDir + "link";
+#endif
+
+ QVERIFY(QDir().mkpath(targetName));
+
+ QFile source(workingDir + "file");
+ QVERIFY(source.open(QIODevice::ReadWrite));
+ QVERIFY(source.write("Source File"));
+
+ // Creates a shortcut on Windows, a symbolic link on Unix
+ QVERIFY(QFile::link(source.fileName(), linkName));
+
+ LibArchiveArchive archive(archiveName);
+ QVERIFY(archive.open(QIODevice::ReadWrite));
+ QVERIFY(archive.create(QStringList() << source.fileName() << linkName));
+ QVERIFY(QFileInfo::exists(archiveName));
+
+ QVERIFY(archive.extract(targetName));
+ const QString sourceFilename = QFileInfo(source.fileName()).fileName();
+ const QString linkFilename = QFileInfo(linkName).fileName();
+ QVERIFY(QFileInfo::exists(targetName + sourceFilename));
+ QVERIFY(QFileInfo::exists(targetName + linkFilename));
+
+ VerifyInstaller::verifyFileContent(targetName + sourceFilename, source.readAll());
+ const QString sourceFilePath = workingDir + sourceFilename;
+ QCOMPARE(QFile::symLinkTarget(targetName + linkFilename), sourceFilePath);
+
+ archive.close();
+
+ QVERIFY(source.remove());
+ QVERIFY(QFile::remove(archiveName));
+ QVERIFY(QFile::remove(linkName));
+ QVERIFY(QFile::remove(targetName + sourceFilename));
+ QVERIFY(QFile::remove(targetName + linkFilename));
+
+ removeDirectory(targetName, true);
+ removeDirectory(workingDir, true);
+ }
+
private:
void archiveFilenamesTestData()
{
@@ -167,15 +224,6 @@ private:
QTest::newRow("xz compressed tar archive") << ".tar.xz";
}
- bool entriesMatch(const ArchiveEntry &lhs, const ArchiveEntry &rhs)
- {
- return lhs.path == rhs.path
- && lhs.utcTime == rhs.utcTime
- && lhs.isDirectory == rhs.isDirectory
- && lhs.compressedSize == rhs.compressedSize
- && lhs.uncompressedSize == rhs.uncompressedSize;
- }
-
QString tempSourceFile(const QByteArray &data, const QString &templateName = QString())
{
QTemporaryFile source;