24#include "ui_InstallSceneryDialog.h"
32#include <QRegularExpression>
34#include <QStandardPaths>
39#include <simgear/io/untar.hxx>
45 ArchiveExtractor(root)
49 auto filterPath(std::string& path) -> PathResult
override
51 if ((path.find(
"Objects/") == 0) || (path.find(
"Terrain/") == 0)) {
55 path =
"Terrain/" + path;
65 m_extractDir(extractDir),
66 m_remainingPaths(files),
77 Q_FOREACH (QString path, m_remainingPaths) {
78 QFileInfo finfo(path);
79 QString baseName = finfo.baseName();
80 QRegularExpression re(
"[e|w]\\d{2}0[n|s]\\d0", QRegularExpression::CaseInsensitiveOption);
81 Q_ASSERT(re.isValid());
82 if (!re.match(baseName).hasMatch()) {
89 f.open(QIODevice::ReadOnly);
90 QByteArray firstData = f.read(8192);
92 auto archiveType = simgear::ArchiveExtractor::determineType((uint8_t*) firstData.data(), firstData.size());
93 if (archiveType == simgear::ArchiveExtractor::Invalid) {
94 emit
extractionError(path,tr(
"file does not appear to be a scenery archive."));
99 m_totalBytes += f.size();
102 while (!m_remainingPaths.isEmpty() && !m_error) {
103 extractNextArchive();
114 void extractNextArchive()
116 SGPath root(m_extractDir.toStdString());
119 QString path = m_remainingPaths.front();
120 m_remainingPaths.pop_front();
121 QFileInfo finfo(path);
126 f.open(QIODevice::ReadOnly);
127 Q_ASSERT(f.isOpen());
130 QByteArray bytes = f.read(4 * 1024 * 1024);
131 m_archive->extractBytes((
const uint8_t*) bytes.constData(), bytes.size());
132 m_bytesRead += bytes.size();
134 if (m_archive->hasError()) {
138 emit
progress((m_bytesRead * 100) / m_totalBytes);
142 if (m_archive->hasError() || !m_archive->isAtEndOfArchive()) {
149 QString m_extractDir;
150 QStringList m_remainingPaths;
151 std::unique_ptr<simgear::ArchiveExtractor> m_archive;
153 quint64 m_totalBytes;
158 QDialog(parent, Qt::Dialog
159 | Qt::CustomizeWindowHint
160 | Qt::WindowTitleHint
161 | Qt::WindowSystemMenuHint
162 | Qt::WindowContextHelpButtonHint
163 | Qt::MSWindowsFixedSizeDialogHint),
164 m_state(STATE_START),
165 m_downloadDir(downloadDir),
169 if (m_downloadDir.isEmpty()) {
170 m_downloadDir = QString::fromStdString(flightgear::defaultDownloadDir().utf8Str());
173 QString baseIntroString = ui->introText->text();
174 ui->introText->setText(baseIntroString.arg(m_downloadDir));
183void InstallSceneryDialog::updateUi()
185 QPushButton* b = ui->buttonBox->button(QDialogButtonBox::Ok);
186 QPushButton* cancel = ui->buttonBox->button(QDialogButtonBox::Cancel);
190 b->setText(tr(
"Next"));
194 case STATE_EXTRACTING:
195 b->setEnabled(
false);
196 cancel->setEnabled(
false);
197 ui->progressText->setText(tr(
"Extracting"));
198 ui->stack->setCurrentIndex(1);
201 case STATE_EXTRACT_FAILED:
202 b->setEnabled(
false);
203 cancel->setEnabled(
true);
204 ui->stack->setCurrentIndex(2);
209 cancel->setEnabled(
false);
210 b->setText(tr(
"Okay"));
211 ui->stack->setCurrentIndex(2);
212 QString basicDesc = ui->resultsSummaryLabel->text();
214 ui->resultsSummaryLabel->setText(basicDesc.arg(
sceneryPath()));
220void InstallSceneryDialog::accept()
227 case STATE_EXTRACTING:
228 case STATE_EXTRACT_FAILED:
239void InstallSceneryDialog::reject()
245void InstallSceneryDialog::pickFiles()
247 QStringList downloads = QStandardPaths::standardLocations(QStandardPaths::DownloadLocation);
248 QStringList files = QFileDialog::getOpenFileNames(
this, tr(
"Choose scenery to install"),
249 downloads.first(),
"Compressed data (*.tar *.gz *.tgz *.zip)");
250 if (!files.isEmpty()) {
251 QDir d(m_downloadDir);
252 if (!d.exists(
"Scenery")) {
256 m_state = STATE_EXTRACTING;
257 m_thread.reset(
new InstallSceneryThread(d.filePath(
"Scenery"), files));
259 connect(m_thread.data(), &QThread::finished,
this, &InstallSceneryDialog::onThreadFinished);
261 this, &InstallSceneryDialog::onExtractError);
263 this, &InstallSceneryDialog::onExtractProgress);
265 this, &InstallSceneryDialog::onExtractFile);
274void InstallSceneryDialog::onThreadFinished()
276 m_state = STATE_FINISHED;
280void InstallSceneryDialog::onExtractError(QString file, QString msg)
282 ui->resultsSummaryLabel->setText(tr(
"Problems occured extracting the archive '%1': %2").arg(file).arg(msg));
283 m_state = STATE_EXTRACT_FAILED;
287void InstallSceneryDialog::onExtractProgress(
int percent)
289 ui->progressBar->setValue(percent);
292void InstallSceneryDialog::onExtractFile(QString file)
294 ui->progressText->setText(tr(
"Extracting %1").arg(file));
299 if (m_state == STATE_FINISHED) {
300 QDir d(m_downloadDir);
301 return d.filePath(
"Scenery");
307#include "InstallSceneryDialog.moc"
InstallSceneryDialog(QWidget *parent, QString downloadDir)
void extractingArchive(QString archiveName)
void progress(int percent)
InstallSceneryThread(QString extractDir, QStringList files)
void extractionError(QString file, QString msg)