Files
qt5-legatus-legacy/Lts/Plugins/TakeHomePackageManager/OldTHP/ThpUsbManagement/tpm_usb_dialog.cpp
T
2026-08-13 18:33:10 +02:00

1700 lines
50 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Show the exported scripts and allow them to upload them to the server
* $Id: tpm_exported_scripts_dialog.cpp 53111 2021-03-22 08:21:29Z wille_m $
* $HeadURL: svn://slssvn/TDS/branches/product/iterations/21_03_salted_caramel/Lts/Plugins/TakeHomePackageManager/tpm_exported_scripts_dialog.cpp $
* $Author: wille_m $
*
* Created by Gerlinde Rudolphus, NLE, 2019-03-25
* Rebuilt to use httq by Mike Wille, NLE, 2020-07-07
*/
/* TODO: FIXME: sme problem here!
* adjust data.json when uploading file, as data.json contains ALL
* scripts, but we only upload ONE script at a time - so remove all scripts but
* the one to be uploaded from data.json (but don't touch the main data.json!!)
*/
/*
*
* TODO:
* index.html that searches all exercises instead of stuff
* copy everything in exercise folder for now until above is done
* copy situation_map init into share folder
*
*/
#include "ui_tpm_usb_dialog.h"
#include "tpm_usb_dialog.h"
#include <Common/tpm_process_dialog.h>
#include <Common/tpm_exported_scripts_model.h>
#include <nglcompression/nglcomp_compress.h>
#include <nglsettings/nglsettings_connections.h>
#include <nglsettings/nglsettings_settings.h>
#include <LtsWidgets/lts_message_dialog.h>
#include <LtsWidgets/lts_global_wait_dialog.h>
#include <LtsSession/lts_session.h>
#include <LtsSession/lts_session_data.h>
#include <ngltools/ngltools_filesystem.h>
#include <QDir>
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QProcess>
#include <QTemporaryFile>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>
#include <QWebSocket>
#include <QLocale>
#include <QTimer>
#include <QFileSystemWatcher>
#include <QTreeView>
#include <QFuture>
#include <QFutureWatcher>
#include <QtCore/qstring.h>
#include <QtCore/qobject.h>
#include <QtCore/qfile.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qvector.h>
#include <QtCore/qthread.h>
#include <QtConcurrent>
#include <QDirIterator>
#include <QFileDialog>
#ifdef Q_OS_UNIX
#include <unistd.h>
#endif
#include <QDebug>
#ifdef Q_OS_UNIX
#define _compiler_warning(x) _Pragma(#x)
#define compiler_warning(x) _compiler_warning(GCC warning x)
#define TMP_WARNING_LOG(x) compiler_warning("Temporary warning log active!") \
WARNING_LOG(x)
#else
#define compiler_warning(x)
#define TMP_WARNING_LOG(x) WARNING_LOG(x)
#endif
#ifndef ELOG
#define ELOG ERROR_LOG(m_logger) // polyfill
#endif
namespace TakeHomePackageManager
{
// TODO: mv to LtsCommon
class AsyncFileCopy : public QObject
{
Q_OBJECT
public:
static const int s_chunkSize = 1 * 1024 * 1024;
static AsyncFileCopy *createAsyncFileCopy(const QDir &src, const QDir &dst, const QFileInfoList &fil = {}, bool cdUp = true) // to prevent the user from thinking having to delete the class (which it does itself)
{
return new AsyncFileCopy(src, dst, fil, cdUp);
}
~AsyncFileCopy() = default;
private:
AsyncFileCopy(const QDir &src, const QDir &dst, const QFileInfoList &fil, bool cdUp)
{
QFutureWatcher<bool> *fw = new QFutureWatcher<bool>(this);
connect(fw, &QFutureWatcher<bool>::finished,
this, [this, fw]()
{
emit finished(fw->result());
});
connect(fw, &QFutureWatcher<bool>::finished,
this, &QObject::deleteLater); // self-deleting
fw->setFuture(QtConcurrent::run(this, &AsyncFileCopy::copy, src, dst, fil, cdUp));
}
private:
#define cancelationPoint if (m_wasCanceled) { qWarning() << "canceled"; return false; } (void)m_wasCanceled
bool copy(const QDir &src, const QDir &dst, const QFileInfoList &fil, bool cdUp)
{
qint64 totalAll = 0, writtenAll = 0;
int fileCount = 0;
//TODO
{
QDirIterator it(src.absolutePath(), QDir::Files | QDir::NoDotAndDotDot,
QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
while (it.hasNext())
{
const QFileInfo fi(it.next());
//qWarning() << "size fi 1" << fi;
// copy only files in fil (only if fil is not optional aka. empty)
// operator== doesn't work as intended, so no fil.contains(fi) :(
if (!fil.isEmpty())
{
auto it = std::find_if(fil.constBegin(), fil.constEnd(), [fi](const QFileInfo &_fi)
{
// qWarning() << "does" << fi.absoluteFilePath() << "and" << _fi.absoluteFilePath() << "match?";
return (fi.absoluteFilePath() == _fi.absoluteFilePath());
});
if (it == fil.constEnd())
continue;
}
//qWarning() << "size fi 2" << fi;
totalAll += fi.size();
fileCount++;
}
}
//qWarning() << "fileList size" << fileList.size() << fileList;
//qWarning() << "src for it" << src;
int currentFile = 0;
QDirIterator it(src.absolutePath(), QDir::Files | QDir::NoDotAndDotDot,
QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
while (it.hasNext())
{
cancelationPoint;
const QFileInfo fi(it.next());
//qWarning() << "copy fi 1" << fi;
// copy only files in fil (only if fil is not optional aka. empty)
// operator== doesn't work as intended, so no fil.contains(fi) :(
if (!fil.isEmpty())
{
auto it = std::find_if(fil.constBegin(), fil.constEnd(), [fi](const QFileInfo &_fi)
{
return (fi.absoluteFilePath() == _fi.absoluteFilePath());
});
if (it == fil.constEnd())
continue;
}
//qWarning() << "copy fi 2" << fi;
currentFile++;
qint64 totalFile = fi.size(), writtenFile = 0;
QDir x(src);
if (cdUp)
x.cdUp();
QString srcFilePath(fi.absolutePath());
QString dstFilePath(dst.absolutePath() + QDir::separator() + srcFilePath.remove(x.absolutePath()));
if (!QDir().mkpath(dstFilePath) /* why is this not static, Qt? Directory validation? */)
{
qWarning() << "cannot create path";
return false;
}
QFile srcFile(fi.absoluteFilePath());
QFile dstFile(dstFilePath + QDir::separator() + fi.fileName());
// qWarning() << "fi" << fi.absolutePath()
// << "src" << src.absolutePath()
// << "x" << x.absolutePath()
// << "srcFilePath" << srcFilePath
// << "dstFilePath" << dstFilePath
// << "srcFile" << fi.absoluteFilePath()
// << "dstFile" << dstFilePath + QDir::separator() + fi.fileName()
// ;
if (!srcFile.open(QIODevice::ReadOnly))
{
qWarning() << QStringLiteral("failed to open src '%1' (error: %2)").arg(srcFile.fileName(), srcFile.errorString());
continue;
}
if (!dstFile.open(QIODevice::ReadWrite | QIODevice::Truncate))
{
qWarning() << QStringLiteral("failed to open dst '%1' (error: %2)").arg(dstFile.fileName(), dstFile.errorString());
continue;
}
// not needed with mode truncate: dstFile.seek(0); // if file exists, overwrite
qint64 fileSize = srcFile.size();
while (fileSize)
{
cancelationPoint;
const auto data = srcFile.read(s_chunkSize);
cancelationPoint;
const auto _written = dstFile.write(data);
qWarning() << "progress" << writtenFile << totalFile << writtenAll << totalAll << currentFile << fileCount;
emit newAction(tr("Copying..."));
emit progress(writtenFile, totalFile, writtenAll, totalAll, currentFile, fileCount);
// TODO: windoofs
#ifdef Q_OS_UNIX
//qWarning() << "flushing...";
emit newAction(tr("Writing..."));
QElapsedTimer t;
t.start();
fsync(dstFile.handle()); // fsync(2): "The call blocks until the device reports that the transfer has completed."
//qWarning() << "took" << t.elapsed() << "ms";
#endif
if (data.size() == _written)
{
writtenFile += _written;
fileSize -= data.size();
}
else
{
qWarning() << "cannot write to" << dstFile.fileName() << ":" << dstFile.errorString();
fileSize = 0;
break; // skip this operation
}
}
writtenAll += writtenFile;
}
if (totalAll == writtenAll)
{
qWarning() << "done - " << writtenAll << "/" << totalAll << "bytes";
return true;
}
else
{
qWarning() << "failed.....";
return false;
}
}
bool m_wasCanceled { false };
public slots:
void slotCancel()
{
m_wasCanceled = true;
}
signals:
void newAction(const QString &newAction);
void progress(qint64 bytesCopiedFile, qint64 bytesTotalFile, qint64 bytesCopiedAll, qint64 bytesTotalAll, int currentFile, int fileCount);
void finished(bool success);
};
class CopyProcess : public QObject
{
Q_OBJECT
public:
CopyProcess(const QDir &src, const QDir &dst, const QFileInfoList &fil = {}, bool cdUp = true, QObject *parent = nullptr)
: QObject(parent)
, m_process(new ProcessOverlay)
{
connect(m_process, &ProcessOverlay::signalCancel,
this, [this]()
{
//DEBUG_LOG(m_logger) << "m_wasCanceled!!";
m_wasCanceled = true;
m_process->setCancelEnabled(false);
});
connect(m_process, &ProcessOverlay::signalCancel,
this, &CopyProcess::signalCancel);
AsyncFileCopy *afc = AsyncFileCopy::createAsyncFileCopy(src, dst, fil, cdUp);
connect(m_process, &ProcessOverlay::signalCancel,
afc, &AsyncFileCopy::slotCancel);
connect(afc, &AsyncFileCopy::progress,
this, [this](qint64 bytesCopiedFile, qint64 bytesTotalFile,
qint64 bytesCopiedAll, qint64 bytesTotalAll,
int currentFile, int fileCount)
{
m_process->setStatus(m_currentAction, fileCount, currentFile, bytesTotalFile, bytesCopiedFile);
});
connect(afc, &AsyncFileCopy::newAction,
this, [this](const QString &newAction)
{
m_currentAction = newAction;
});
connect(afc, &AsyncFileCopy::finished,
this, &QObject::deleteLater);
connect(afc, &AsyncFileCopy::finished,
this, &CopyProcess::finished);
}
~CopyProcess()
{
//DEBUG_LOG(m_logger) << "~CopyProcess";
delete m_process;
}
QWidget *process() { return m_process; }
signals:
void signalCancel();
void finished(bool success);
private:
ProcessOverlay *m_process;
bool m_wasCanceled { false };
QString m_currentAction;
};
// USBDialog
USBDialog::USBDialog(LtsSession::LtsSession *session, QWidget *parent)
: LtsWidgets::LtsDialog(parent)
, m_localThpModel(new ExportedScriptsModel(this))
, m_usbThpModel(new ExportedScriptsModel(this))
, m_ui(new Ui::USBDialog)
, m_session(session)
//, m_fsWatcher(new QFileSystemWatcher(this))
, m_exerciseId(m_session->exerciseId())
, m_paths(0)
, m_logger(getLogger("USBDialog"))
{
m_ui->setupUi(this);
connect(m_ui->pbCHange, &QPushButton::clicked,
this, &USBDialog::slotChangePath);
connect(m_ui->pbCopy, &QPushButton::clicked,
this, &USBDialog::slotCopy);
connect(m_ui->pbRemove, &QPushButton::clicked,
this, &USBDialog::slotRemove);
connect(this, &USBDialog::nextMap,
this, &USBDialog::onNextMap);
connect(m_ui->pbCopyMaps, &QPushButton::clicked,
this, &USBDialog::slotCopyMaps);
connect(m_ui->pbRemoveMaps, &QPushButton::clicked,
this, &USBDialog::slotRemoveMaps);
connect(m_ui->tvLocal->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &USBDialog::slotSelectionChanged);
// compiler_warning("TODO")
// auto initModelFn = [this]()
// {
// try
// {
// initModel();
// }
// catch()
// {
// ERROR_LOG(m_logger) << "initModel failed";
// }
// };
// connect(m_fsWatcher, &QFileSystemWatcher::directoryChanged,
// this, initModelFn);
// connect(m_fsWatcher, &QFileSystemWatcher::fileChanged,
// this, initModelFn);
initModel(); // throws!
setOnlineHelpFilename(QStringLiteral("Script_Editor-Export_Script_Administration"));
}
USBDialog::~USBDialog()
{
delete m_ui;
}
void USBDialog::initUsbModel()
{
m_usbThpModel->clear();
if (!m_usbThpModel->init(m_usbRoot))
{
new LtsWidgets::LtsMessageDialogNew(this, tr("The directory '%1' doesn't contain valid THP data.").arg(m_usbRoot));
ERROR_LOG(m_logger) << "cannot initialize usb thp model from usb root" << m_usbRoot;
return;
}
QDir tmp;
tmp.mkpath(getContentFolder(m_usbRoot) + QDir::separator() + QStringLiteral("Maps")); //getContentFolder
m_ui->tvUSB->setModel(m_usbThpModel);
m_ui->tvUSB->hideColumn(ExportedScriptsModel::ColId);
m_ui->tvUSB->hideColumn(ExportedScriptsModel::ColLocation);
m_ui->tvUSB->hideColumn(ExportedScriptsModel::ColUploaded);
m_ui->tvUSB->hideColumn(ExportedScriptsModel::ColUploadedTime);
m_ui->lblPath->setText(m_usbRoot);
// fill usb maps
{
m_ui->tvUSBMaps->setRowCount(0);
m_ui->tvUSBMaps->clearContents();
QDirIterator it(getContentFolder(m_usbRoot) + QDir::separator() + QStringLiteral("Maps"), QDir::Files | QDir::NoDotAndDotDot,
QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
while (it.hasNext())
{
QFileInfo fi(it.next());
m_ui->tvUSBMaps->insertRow(m_ui->tvUSBMaps->rowCount());
m_ui->tvUSBMaps->setItem(m_ui->tvUSBMaps->rowCount() - 1, 0, new QTableWidgetItem(fi.fileName()));
if (fi.fileName().endsWith(QStringLiteral("json")) ||
fi.fileName().endsWith(QStringLiteral("tif")))
m_ui->tvUSBMaps->hideRow(m_ui->tvUSBMaps->rowCount() -1);
}
}
}
void USBDialog::slotChangePath()
{
QFileDialog *dlg = new QFileDialog(this);
dlg->setFileMode(QFileDialog::Directory);
dlg->setOption(QFileDialog::ShowDirsOnly);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->show();
connect(dlg, &QFileDialog::accepted,
this, [this, dlg]()
{
QStringList selected(dlg->selectedFiles());
if (selected.count() > 1)
return;
m_usbRoot = selected.first();
if (!QFile::exists(m_usbRoot + QDir::separator() + QStringLiteral("exercises.json")))
{
auto m = new LtsWidgets::LtsMessageDialogNew(this, tr("The selected directory '%1' doesn't contain THPs yet. <br />Do you want to initialize the directory now?").arg(m_usbRoot),
{}, LtsWidgets::Behaviour::Modal, LtsWidgets::Button::Yes | LtsWidgets::Button::Cancel);
connect(m, &LtsWidgets::LtsMessageDialogNew::yes,
this, [this]()
{
QFile exerciseJsonFile(m_usbRoot + QDir::separator() + QStringLiteral("exercises.json"));
if (!exerciseJsonFile.open(QIODevice::WriteOnly))
{
new LtsWidgets::LtsMessageDialogNew(this, tr("The selected directory '%1' can't be written to and the initialization was aborted.").arg(m_usbRoot));
return;
}
exerciseJsonFile.write(QString(QStringLiteral("{ \"Exercises\": [ %1 ] }\n").arg(m_exerciseId)).toUtf8()); // meh... but quick
exerciseJsonFile.close();
slotCopyWinBin();
//create data.json if it doesn't exist
std::shared_ptr<ExerciseManagement::Interface::Dtc> exmDtc;
std::shared_ptr<AssetManagement::Interface::Dtc> asmDtc;
if (m_session->getDtc<AssetManagement::DataInterface>(asmDtc) &&
m_session->getDtc<ExerciseManagement::DataInterface>(exmDtc))
{
if (!m_usbThpModel->createDataJson(m_usbRoot, exmDtc, asmDtc, m_exerciseId))
{
// TODO: user msg
ERROR_LOG(m_logger) << "Failed to initialize data.json";
return;
}
TMP_WARNING_LOG(m_logger) << "DONE!";
}
else
TMP_WARNING_LOG(m_logger) << "Failed to get dtcs :( !";
});
return;
}
initUsbModel();
generateLayerMappingXML();
});
}
void USBDialog::slotCopyMaps()
{
if (m_usbRoot.isEmpty())
return;
m_finished_mapCopys = 0;
QDir dstDir(getContentFolder(m_usbRoot) + QDir::separator() + QStringLiteral("Maps")); //getContentFolder for now
if (!dstDir.exists())
{
ERROR_LOG(m_logger) << "dst dir " << m_usbRoot << " is not accessible";
return;
}
const QModelIndexList mil = m_ui->tvLocalMaps->selectionModel()->selectedRows();
if (mil.size() < 1)
return;
DEBUG_LOG(m_logger) << "mil.size()" << mil.size();
for (const QModelIndex &idx : mil)
{
// qWarning() << "added fi" << idx.data().toString();
QString abs = m_ui->tvLocalMaps->item(idx.row(), 2)->text() + QDir::separator() + m_ui->tvLocalMaps->item(idx.row(), 1)->text();
m_files[m_ui->tvLocalMaps->item(idx.row(), 2)->text()] += abs;
// qWarning() << "the fi" << QFileInfo(idx.data().toString());
}
//add elevations
//Eleveation
// We will copy all elevations every time!
QDirIterator eleit(QStringLiteral("/usr/share/arcgis/resources/elevation/"), QDir::Files | QDir::NoDotAndDotDot,
QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
while (eleit.hasNext())
{
QString file = eleit.next();
QFileInfo eleFile(file);
if (!eleFile.fileName().toLower().endsWith(QStringLiteral(".tif")))
continue;
m_files[eleFile.absolutePath()] += eleFile.absoluteFilePath();
}
m_paths = m_files.count();
//ProcessOverlay* overlay = new ProcessOverlay();
//setOverlay(overlay);
//overlay->setStatus(QStringLiteral("Copy Maps"), paths, 1);
//overlay->setCancelEnabled(false);
emit nextMap();
}
void USBDialog::onNextMap()
{
auto path = m_files.firstKey();
{
QString src(path);
DEBUG_LOG(m_logger) << "src" << src;
QDir srcDir(src);
if (!srcDir.exists())
{
ERROR_LOG(m_logger) << "src dir " << src << " is not accessible";
return;
}
QDir dstDir(getContentFolder(m_usbRoot) + QDir::separator() + QStringLiteral("Maps")); //getContentFolder for now
auto cp = new CopyProcess(srcDir, dstDir, m_files[path], false, this);
setOverlay(cp->process());
connect(cp, &CopyProcess::finished,
this, [this, path](bool success)
{
if (!success)
new LtsWidgets::LtsMessageDialogNew(this, tr("The files could not be copied successfully from path! ") + path);
m_finished_mapCopys++;
m_files.remove(path);
// overlay->setStatus(QStringLiteral("Copy Maps"), paths, m_finished_mapCopys);
if(m_paths == m_finished_mapCopys)
{
// overlay->deleteLater();
new LtsWidgets::LtsMessageDialogNew(this, tr("The files were copied successfully from path: ") + path);
initUsbModel();
generateLayerMappingXML();
m_finished_mapCopys = 0;
}else
emit nextMap();
});
}
}
void USBDialog::generateLayerMappingXML()
{
QJsonObject layers;
QJsonArray elevationUrls;
QJsonArray mapUrls;
QJsonArray sceneObjectUrls;
QJsonArray sceneUrls;
for(int i = 0; i < m_ui->tvUSBMaps->rowCount(); ++i)
{
QFileInfo fileInfo = QFileInfo(m_usbRoot + QDir::separator() + m_ui->tvUSBMaps->item(i,0)->text());
if(fileInfo.suffix() == QStringLiteral("tif") || fileInfo.suffix() == QStringLiteral("dt2"))
{
QJsonObject elavation;
elavation.insert(QStringLiteral("description"), QJsonValue(QStringLiteral("Elevation")));
elavation.insert(QStringLiteral("maxScale"), QJsonValue(-1));
elavation.insert(QStringLiteral("minScale"), QJsonValue(-1));
elavation.insert(QStringLiteral("name"), QJsonValue(fileInfo.baseName()));
elavation.insert(QStringLiteral("url"), QJsonValue(fileInfo.fileName()));
elevationUrls.push_back(elavation);
}
else if (fileInfo.suffix() == QStringLiteral("slpk"))
{
QJsonObject objectScene;
objectScene.insert(QStringLiteral("description"), QJsonValue(QStringLiteral("ObjectScene")));
objectScene.insert(QStringLiteral("maxScale"), QJsonValue(125));
objectScene.insert(QStringLiteral("minScale"), QJsonValue(-1));
objectScene.insert(QStringLiteral("altitudeOffset"), QJsonValue(0.5));
objectScene.insert(QStringLiteral("name"), QJsonValue(fileInfo.baseName()));
objectScene.insert(QStringLiteral("url"), QJsonValue(fileInfo.fileName()));
sceneObjectUrls.push_back(objectScene);
}
else if(fileInfo.suffix() == QStringLiteral("tpk"))
{
//Maps when WebMerc dann Scene sonst map
if(fileInfo.fileName().contains(QStringLiteral("WebMerc")))
{
QJsonObject scene;
scene.insert(QStringLiteral("description"), QJsonValue(QStringLiteral("Scene")));
scene.insert(QStringLiteral("maxScale"), QJsonValue(125));
scene.insert(QStringLiteral("minScale"), QJsonValue(-1));
scene.insert(QStringLiteral("name"), QJsonValue(fileInfo.baseName()));
scene.insert(QStringLiteral("url"), QJsonValue(fileInfo.fileName()));
sceneUrls.push_back(scene);
}
else
{
QJsonObject map;
map.insert(QStringLiteral("description"), QJsonValue(QStringLiteral("Map")));
map.insert(QStringLiteral("maxScale"), QJsonValue(125));
map.insert(QStringLiteral("minScale"), QJsonValue(-1));
map.insert(QStringLiteral("name"), QJsonValue(fileInfo.baseName()));
map.insert(QStringLiteral("url"), QJsonValue(fileInfo.fileName()));
mapUrls.push_back(map);
}
}
}
layers.insert(QStringLiteral("elevationUrls"), elevationUrls);
layers.insert(QStringLiteral("mapUrls"), mapUrls);
layers.insert(QStringLiteral("sceneObjectUrls"), sceneObjectUrls);
layers.insert(QStringLiteral("sceneUrls"), sceneUrls);
QFile layersMapping(getContentFolder(m_usbRoot) + QDir::separator() + QStringLiteral("layerMapping.json"));//getContentFolder
QFile layersMappingAtMaps(getContentFolder(m_usbRoot) + QDir::separator() + QStringLiteral("Maps") + QDir::separator() + QStringLiteral("layerMapping.json"));
if (!layersMapping.open(QIODevice::WriteOnly))
{
WARNING_LOG(m_logger) << "Couldn't open save file.";
return;
}
if (!layersMappingAtMaps.open(QIODevice::WriteOnly))
{
WARNING_LOG(m_logger) << "Couldn't open save file in folder Maps.";
return;
}
QJsonDocument doc(layers);
layersMapping.write(doc.toJson());
layersMappingAtMaps.write(doc.toJson());
}
QFileInfoList USBDialog::prepareFileInfoListForFolder(QString src, QFileInfoList fil)
{
QDir dir(src);
if (! dir.exists())
return fil;
for (QString d : dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
{
fil = prepareFileInfoListForFolder(src+ QDir::separator() + d, fil);
}
for (QString f : dir.entryList(QDir::Files))
{
fil += QString(src + QDir::separator() + f);
}
return fil;
}
void USBDialog::slotCopyWinBin()
{
if (m_usbRoot.isEmpty())
return;
QDir dstDir(getContentFolder(m_usbRoot) + QDir::separator()); //getContentFolder
if (!dstDir.exists())
{
dstDir.mkpath(QStringLiteral("."));
}
//TODO richtiger Pfad
QString src(QStringLiteral("/opt/THP/"));
QDir srcDir(src);
if (!srcDir.exists())
{
ERROR_LOG(m_logger) << "src dir " << src << " is not accessible";
return;
}
QFileInfoList fil;
fil = prepareFileInfoListForFolder(src, fil);
DEBUG_LOG(m_logger) << "XXXXXXXXXXX filsize is: " << fil.size();
auto cp = new CopyProcess(srcDir, dstDir, fil, false, this);
setOverlay(cp->process());
connect(cp, &CopyProcess::finished,
this, [this](bool success)
{
if (success)
{
// new LtsWidgets::LtsMessageDialogNew(this, tr("The files were copied successfully"));
slotCopyWinBinP2();
}
else
new LtsWidgets::LtsMessageDialogNew(this, tr("The files could not be copied successfully!"));
});
}
void USBDialog::slotCopyWinBinP2()
{
if (m_usbRoot.isEmpty())
return;
QDir dstDir(getContentFolder(m_usbRoot) + QDir::separator()); //getContentFolder
if (!dstDir.exists())
{
dstDir.mkpath(QStringLiteral("."));
}
const QString initFilePath = NGL::findFile(NGL::FileType::ConfigFile, QStringLiteral("situation_map_defaults.ini"));
if (initFilePath.isEmpty())
{
ERROR_LOG(m_logger) << "sitmap init is not accessible";
return;
}
QFileInfo fileInfo(initFilePath);
QFileInfoList fil2;
fil2.append(fileInfo);
DEBUG_LOG(m_logger) << "XXXXXXXXXXX sitmap is: " << fileInfo.absoluteFilePath();
ERROR_LOG(m_logger) << "XXXXXXXXXXX filsize is: " << fil2.size();
// QString x = QDir::separator() + QStringLiteral("thp") + QDir::separator() + QStringLiteral("share") + QDir::separator() + QStringLiteral("situation_Map");
const QDir dstDir2(dstDir.absolutePath() + QDir::separator() + QStringLiteral("thp") + QDir::separator() + QStringLiteral("share") + QDir::separator() + QStringLiteral("LTS") + QDir::separator() + QStringLiteral("situation_Map")) ;
DEBUG_LOG(m_logger) << "XXXXXXXXXXX sitmap dst is: " << dstDir2.absolutePath();
auto cp2 = new CopyProcess(fileInfo.absoluteDir(), dstDir2, fil2, false, this);
setOverlay(cp2->process());
connect(cp2, &CopyProcess::finished,
this, [this](bool success)
{
if (success)
{
// new LtsWidgets::LtsMessageDialogNew(this, tr("The files were copied successfully"));
slotCopyWinBinP3();
}
else
new LtsWidgets::LtsMessageDialogNew(this, tr("The files could not be copied successfully!"));
});
}
void USBDialog::slotCopyWinBinP3()
{
if (m_usbRoot.isEmpty())
return;
QDir dstDir(getContentFolder(m_usbRoot) + QDir::separator()); //getContentFolder
if (!dstDir.exists())
{
dstDir.mkpath(QStringLiteral("."));
}
const QString autorunFile = NGL::findFile(NGL::FileType::ConfigFile, QStringLiteral("autorun.inf"));
if (autorunFile.isEmpty())
{
ERROR_LOG(m_logger) << "autorunFile init is not accessible";
return;
}
QFileInfo fileInfo2(autorunFile);
QFileInfoList fil;
fil = prepareFileInfoListForFolder(fileInfo2.absoluteDir().path(), fil);
DEBUG_LOG(m_logger) << "XXXXXXXXXXX autofinFile is: " << fileInfo2.absoluteDir().path();
DEBUG_LOG(m_logger) << "XXXXXXXXXXX filsize is: " << fil.size();
auto cp3 = new CopyProcess(fileInfo2.absoluteDir(), dstDir, fil, false, this);
setOverlay(cp3->process());
connect(cp3, &CopyProcess::finished,
this, [this](bool success)
{
if (success)
{
// new LtsWidgets::LtsMessageDialogNew(this, tr("The files were copied successfully"));
initUsbModel();
}
else
new LtsWidgets::LtsMessageDialogNew(this, tr("The files could not be copied successfully!"));
});
}
class JsonHandler
{
public:
JsonHandler() // invalid
{}
// JsonHandler(JsonHandler &&o)
// {
// m_changesMade = o.m_changesMade;
// m_exists = o.m_exists;
// m_root = o.m_root;
// m_f = o.m_f;
// m_filepath = o.m_filepath;
// m_filename = o.m_filename;
// }
JsonHandler(const QString &filename, const QString &root, bool mustExist = true)
: m_f(new QFile)
, m_filename(filename)
{
m_filepath = QString(root + QDir::separator() + filename);
if (!QFile::exists(m_filepath) && mustExist)
throw QStringLiteral("%1 does not exist in given root").arg(filename);
m_f->setFileName(m_filepath);
if (!m_f->open(QIODevice::ReadWrite))
throw QStringLiteral("Cannot open %1").arg(filename);
qint64 s = m_f->size();
if (s == 0 && mustExist)
throw QStringLiteral("%1 is empty").arg(filename);
if (s == 0)
return;
QJsonParseError err;
QJsonDocument doc(QJsonDocument::fromJson(m_f->readAll(), &err));
if (err.error != QJsonParseError::NoError)
throw QStringLiteral("Json malformed: %1 - offset %2").arg(err.errorString(), err.offset);
m_root = doc.object();
if (m_root.isEmpty())
throw QStringLiteral("%1's object is empty").arg(filename);
m_exists = true;
// }
// else // since exericses.json is empty / did not exist, create the 'Exercises' array now
// m_root[s_exercisesObjectIdentifier] = QJsonObject();
// QJsonValue exercisesArrayValue = m_root[s_exercisesObjectIdentifier];
// if (s > 0 && exercisesArrayValue.isUndefined()) // aka. not found (even though the json file has valid json in it)
// throw "exercises.json's object is missing the 'Exercises' array";
// if (s == 0 && !mustExist)
// m_changesMade = true; // NOTE: can only be set if no throw might follow as the d_tor would write to the file is changesMade == true, despite an error
}
virtual ~JsonHandler()
{
std::shared_ptr<int> _(nullptr, [this](int *) { delete m_f; }); // TODO: QScopeGuard
if (m_f == nullptr || !m_f->isOpen() || !m_changesMade)
return;
//m_root[s_exercisesObjectIdentifier] = m_exercisesArray;
// move to start of file and set file size to zero
m_f->reset();
m_f->resize(0);
m_f->write(QJsonDocument(m_root).toJson(QJsonDocument::JsonFormat::Compact));
}
protected:
bool m_changesMade { false };
bool m_exists { false };
QJsonObject m_root;
private:
QFile *m_f { nullptr };
QString m_filepath;
QString m_filename;
};
class ExerciseJsonHandler : public JsonHandler
{
public:
ExerciseJsonHandler(const QString &root, bool mustExist = true)
: JsonHandler(QStringLiteral("exercises.json"), root, mustExist)
{
QJsonValue exercisesArrayValue(m_root[s_exercisesArrayIdentifier]);
if (m_exists && exercisesArrayValue.isUndefined()) // aka. not found (even though the json file has valid json in it)
throw "exercises.json's object is missing the 'Exercises' array";
m_exercisesArray = m_root[s_exercisesArrayIdentifier].toArray();
if (!m_exists)
m_changesMade = true; // NOTE: can only be set if no throw might follow as the d_tor would write to the file if changesMade == true, despite an error
}
~ExerciseJsonHandler()
{
m_root[s_exercisesArrayIdentifier] = m_exercisesArray;
}
void addExercise(int exerciseId)
{
m_exercisesArray.append(exerciseId);
m_changesMade = true;
}
bool removeExercise(int exerciseId)
{
auto it = std::find_if(m_exercisesArray.begin(), m_exercisesArray.end(),
[exerciseId](const QJsonValue &val)
{
bool k = false;
int v = val.toVariant().toInt(&k);
if (!k)
return false; // ouch
return (v == exerciseId);
});
bool ret = (it != m_exercisesArray.end());
if (ret)
{
m_exercisesArray.erase(it);
m_changesMade = true;
}
return ret;
}
private:
static const QString s_exercisesArrayIdentifier;
QJsonArray m_exercisesArray; // sadly a QJsonValueRef cannot be used here :(
};
const QString ExerciseJsonHandler::s_exercisesArrayIdentifier = QStringLiteral("Exercises");
class DataJsonHandler : public JsonHandler
{
public:
DataJsonHandler() // invalid
{}
// DataJsonHandler(DataJsonHandler &&o)
// {
// m_presentationsArray = o.m_presentationsArray;
// }
DataJsonHandler(const QString &root, int exerciseId/*, bool mustExist = true*/)
: JsonHandler(QStringLiteral("data.json"), QStringLiteral("%1/%2").arg(root).arg(USBDialog::exerciseDirectoryName(exerciseId)), true)
{
QJsonValue scriptsArrayValue(m_root[s_presentationsArrayIdentifier]);
if (m_exists && scriptsArrayValue.isUndefined()) // aka. not found (even though the json file has valid json in it)
throw "data.json's object is missing the 'presentations' array";
m_presentationsArray = m_root[s_presentationsArrayIdentifier].toArray();
if (!m_exists)
m_changesMade = true; // NOTE: can only be set if no throw might follow as the d_tor would write to the file if changesMade == true, despite an error
}
~DataJsonHandler()
{
m_root[s_presentationsArrayIdentifier] = m_presentationsArray;
}
// void addScript(int scriptId) nah... once deleted, data cannot be restored - re-copy data.json instead
// {
// m_presentationsArray.append(scriptId);
// m_changesMade = true;
// }
QVector<int> scripts()
{
QVector<int> ret;
for (const QJsonValue &val : qAsConst(m_presentationsArray))
{
QJsonObject scriptObject(val.toObject());
bool k = false;
int v = scriptObject[QStringLiteral("scriptId")].toVariant().toInt(&k);
if (!k)
continue; // ouch
ret += v;
}
return ret;
}
bool removeScript(int scriptId)
{
auto it = std::find_if(m_presentationsArray.begin(), m_presentationsArray.end(),
[scriptId](const QJsonValue &val)
{
QJsonObject scriptObject(val.toObject());
bool k = false;
int v = scriptObject[QStringLiteral("scriptId")].toVariant().toInt(&k);
if (!k)
return false; // ouch
return (v == scriptId);
});
bool ret = (it != m_presentationsArray.end());
if (ret)
{
m_presentationsArray.erase(it);
m_changesMade = true;
}
return ret;
}
private:
static const QString s_presentationsArrayIdentifier;
QJsonArray m_presentationsArray; // sadly a QJsonValueRef cannot be used here :(
};
const QString DataJsonHandler::s_presentationsArrayIdentifier = QStringLiteral("presentations");
void USBDialog::adjustJsonFiles(What what)
{
/* Problem: data.json has a weird location and has to be updated if a script was copied.
* As it has all presentations in it that were ever exported, data.json needs to be adjusted
* if a script was deleted or copied.
*
* Use-cases:
*
* Script was deleted from exercise:
* Check if other scripts exists in exercise, otherwise delete exercise directory, delete exercise from exercises.json
*
* Exercise diretory was deleted (by removing the last existing script from an exericse):
* New exercise directory was created (by copying a script):
* Rewrite exercises.json by checking what exercise directories exist
*
* Script was copied to an existing exercise:
* re-copy exercise's data.json and remove all scripts that don't exist in the exercise's directory
*
*/
switch (what)
{
case What::ScriptWasDeletedFromExercise:
{
// // look into exercise folder and check if there are script dirs left
// QDir dir(getContentFolder(m_usbRoot));
// dir.setFilter(QDir::Filter::Dirs | QDir::Filter::NoDotAndDotDot);
// const QFileInfoList fil(dir.entryInfoList());
// if (fil.isEmpty())
// {
// DEBUG_LOG(m_logger) << "no scripts left";
// /* ... determined by checking if there are directories, as scripts are
// * in their own directories and scripts are the only directories in an
// * exercise directory */
// // delete exercise directory
// dir.removeRecursively(); // TODO: hangs.. should be async?? + error handling
// // finally remove exercise from exercise.json
// try
// {
// ExerciseJsonHandler(m_usbRoot).removeExercise(m_exerciseId);
// }
// catch (const QString &str)
// {
// ERROR_LOG(m_logger) << "ExerciseJsonHandler failed: " << str;
// break;
// }
// break;
// }
// // there are scripts left, only remove script from exercise dir's data.json
// try
// {
// DataJsonHandler(m_usbRoot, m_exerciseId).removeScript(m_exerciseId);
// }
// catch (const QString &str)
// {
// ERROR_LOG(m_logger) << "ExerciseJsonHandler failed: " << str;
// break;
// }
// break;
}
case What::ExerciseDirectoryWasDeleted:
case What::NewExerciseDirectoryWasCreated:
{
break;
}
case What::ScriptWasCopiedToExercise:
break;
}
}
void USBDialog::scriptDeleted(int scriptId)
{
// look into exercise folder and check if there are script dirs left
QDir dir(m_usbRoot);
dir.setFilter(QDir::Filter::Dirs | QDir::Filter::NoDotAndDotDot);
const QFileInfoList fil(dir.entryInfoList());
if (fil.isEmpty())
{
DEBUG_LOG(m_logger) << "no scripts left";
/* ... determined by checking if there are directories, as scripts are
* in their own directories and scripts are the only directories in an
* exercise directory */
// delete exercise directory
dir.removeRecursively(); // TODO: hangs.. should be async?? + error handling
// finally remove exercise from exercise.json
try
{
ExerciseJsonHandler(m_usbRoot).removeExercise(m_exerciseId);
}
catch (const QString &str)
{
ERROR_LOG(m_logger) << "ExerciseJsonHandler failed: " << str;
return;
}
return;
}
// there are scripts left, only remove script from exercise dir's data.json
try
{
DataJsonHandler(m_usbRoot, m_exerciseId).removeScript(scriptId);
}
catch (const QString &str)
{
ERROR_LOG(m_logger) << "DataJsonHandler failed: " << str;
}
}
void USBDialog::scriptCopied(int /*scriptId*/)
{
compiler_warning("TODO: re-copy data.json ???")
// open data.json and remove all 'presentation's that do not exist on the USB
// get list of scripts that exist on the USB
QDir dir(getContentFolder(m_usbRoot));
dir.setFilter(QDir::Filter::Dirs | QDir::Filter::NoDotAndDotDot);
const QFileInfoList fil(dir.entryInfoList());
Q_ASSERT_X(!fil.isEmpty(), "", "no scripts on USB"); // Logic failure: No scripts on the USB, but missing presentations in data.json isn't possible as a deleted script would have triggered a deletion of the whole exercise directory
QVector<int> existingScripts;
for (const QFileInfo &fi : fil)
{
bool k = false;
int val = fi.fileName().toInt(&k);
if (!k)
continue; // hmm.. the only allowed directories are script directories, which have integer-convertible filenames
existingScripts += val;
}
QVector<int> usbScripts;
DataJsonHandler djh; // invalid
try
{
// get list of scripts on usb
djh = DataJsonHandler(m_usbRoot, m_exerciseId);
}
catch (const QString &str)
{
ERROR_LOG(m_logger) << "DataJsonHandler failed: " << str;
return;
}
usbScripts = djh.scripts();
// delete all scripts from data.json that do not exist on USB
// prepare usbScripts list to only have the script ids now that DON'T exist on usb
usbScripts.erase(std::remove_if(usbScripts.begin(), usbScripts.end(),
[existingScripts](int id)
{
return (std::find(existingScripts.begin(), existingScripts.end(), id) != existingScripts.end());
}), usbScripts.end());
// now really delete scripts from data.json
for (const int scriptId : qAsConst(usbScripts))
djh.removeScript(scriptId);
// delete all script directories of scripts that do not exist on USB
for (const QFileInfo &fi : fil)
{
bool k = false;
int val = fi.fileName().toInt(&k);
if (!k || !usbScripts.contains(val))
continue;
fi.absoluteDir().removeRecursively();
}
}
void USBDialog::slotCopy()
{
if (m_usbRoot.isEmpty())
return;
QDir dstDir(m_usbRoot);
if (!dstDir.exists())
{
ERROR_LOG(m_logger) << "dst dir " << m_usbRoot << " is not accessible";
return;
}
dstDir = QDir(getContentFolder(m_usbRoot));
if (!dstDir.mkpath(dstDir.absolutePath())) // NOTE: returns true if path already exists
{
ERROR_LOG(m_logger) << "Could not create destination path " << dstDir.absolutePath();
return;
}
qWarning() << "dst" << dstDir.absolutePath();
const QModelIndexList mil = m_ui->tvLocal->selectionModel()->selectedRows();
if (mil.size() != 1)
return;
ExportedScriptInformation esi = m_localThpModel->getRowData(mil.first().row());
if (!QDir(esi.rootDirectory).exists())
return;
QString src(getScriptFolder(esi.rootDirectory, esi.exerciseId, esi.scriptId));
DEBUG_LOG(m_logger) << "src" << src;
QDir srcDir(src);
QDir bldgDir( QStringLiteral("%1/BuildingModels").arg(getContentFolder(esi.rootDirectory, esi.exerciseId)));
if (!srcDir.exists())
{
ERROR_LOG(m_logger) << "src dir " << src << " is not accessible";
return;
}
auto cp = new CopyProcess(srcDir, dstDir, {}, true, this);
//copy buildings secretly
auto cpBuildings = new CopyProcess(bldgDir, dstDir, {}, true, this);
cpBuildings->process();
setOverlay(cp->process());
connect(cp, &CopyProcess::finished,
this, [this, esi](bool success)
{
if (!success)
{
new LtsWidgets::LtsMessageDialogNew(this, tr("The files could not be copied successfully!"));
return;
}
new LtsWidgets::LtsMessageDialogNew(this, tr("The files were copied successfully"));
TMP_WARNING_LOG(m_logger) << "GO GO GO";
ExportedScriptInformation esi2(esi);
esi2.rootDirectory = m_usbRoot; // edit esi to point to the new rootdir (the usb)
m_localThpModel->addDownloadData(esi2);
initUsbModel(); // fill !
// scriptCopied(esi.scriptId);
});
}
void USBDialog::slotRemove()
{
// this operation is fast enough to NOT do it async
if (m_usbRoot.isEmpty())
return;
const QModelIndexList mil = m_ui->tvUSB->selectionModel()->selectedRows();
if (mil.size() < 1)
return;
DEBUG_LOG(m_logger) << "mil.size()" << mil.size();
for (const QModelIndex &idx : mil)
{
int scriptId = idx.data(Qt::UserRole).toInt();
// qWarning() << "rm" << scriptId;
// qWarning() << "rm'd?" << QDir(getScriptFolder(m_usbRoot, m_exerciseId, scriptId)).removeRecursively();
scriptDeleted(scriptId);
}
initUsbModel(); // instead of deleting the rows, just reinit the whole model... ugh, but quickly done
}
void USBDialog::slotRemoveMaps()
{
// this operation is fast enough to NOT do it async
if (m_usbRoot.isEmpty())
return;
QDir dir(getContentFolder(m_usbRoot) + QDir::separator() + QStringLiteral("Maps")); //getContentFolder
if (!dir.exists())
{
ERROR_LOG(m_logger) << "dir " << m_usbRoot << " is not accessible";
return;
}
const QModelIndexList mil = m_ui->tvUSBMaps->selectionModel()->selectedRows();
if (mil.size() < 1)
return;
DEBUG_LOG(m_logger) << "mil.size()" << mil.size();
for (const QModelIndex &idx : mil)
{
DEBUG_LOG(m_logger) << "rm" << idx.data().toString();
QFile::remove(dir.absolutePath() + QDir::separator() + idx.data().toString());
}
initUsbModel(); // instead of deleting the rows, just reinit the whole model... ugh, but quickly done
generateLayerMappingXML();
}
void USBDialog::slotSelectionChanged()
{
const QModelIndexList mil = m_ui->tvLocal->selectionModel()->selectedRows();
// compiler_warning("TODO")
// if (mil.size() != 1)
// {
// m_buttonBox->getButton(LtsWidgets::DialogButton::Show)->setEnabled(false); // Show presentation Button
// m_buttonBox->getButton(LtsWidgets::DialogButton::Remove)->setEnabled(false); // local remove Button
// m_buttonBox->getButton(LtsWidgets::DialogButton::Save)->setEnabled(false); // download from Server
// m_buttonBox->getButton(LtsWidgets::DialogButton::Import)->setEnabled(false); // Remove from Server Button
// return;
// }
// const ExportedScriptInformation esi = m_localThpModel->getRowData(mil.first().row());
// if (m_session->app() != LtsAppDescriptor::App::OC)
// {
// if (esi.local)
// {
// m_buttonBox->getButton(LtsWidgets::DialogButton::Remove)->setEnabled(true); // local remove Button
// m_buttonBox->getButton(LtsWidgets::DialogButton::Save)->setEnabled(true); // upload to Server
// }
// else
// {
// m_buttonBox->getButton(LtsWidgets::DialogButton::Remove)->setEnabled(false); // local remove Button
// m_buttonBox->getButton(LtsWidgets::DialogButton::Save)->setEnabled(false); // upload to Server
// }
// if (esi.uploaded == ThpAlreadyUploaded)
// {
// m_buttonBox->getButton(LtsWidgets::DialogButton::Import)->setEnabled(true); // Remove from Server Button
// }
// else
// {
// m_buttonBox->getButton(LtsWidgets::DialogButton::Import)->setEnabled(false); // Remove from Server Button
// }
// }
// else // OC
// {
// if (esi.uploaded == ThpAlreadyUploaded)
// {
// m_buttonBox->getButton(LtsWidgets::DialogButton::Save)->setEnabled(true); // download from Server
// m_buttonBox->getButton(LtsWidgets::DialogButton::Import)->setEnabled(true); // Remove from Server Button
// }
// else
// {
// m_buttonBox->getButton(LtsWidgets::DialogButton::Import)->setEnabled(false); // Remove from Server Button
// }
// if (esi.local)
// {
// m_buttonBox->getButton(LtsWidgets::DialogButton::Show)->setEnabled(true); // Show presentation Button
// m_buttonBox->getButton(LtsWidgets::DialogButton::Remove)->setEnabled(true); // local remove Button
// }
// else
// {
// m_buttonBox->getButton(LtsWidgets::DialogButton::Show)->setEnabled(false); // Show presentation Button
// m_buttonBox->getButton(LtsWidgets::DialogButton::Remove)->setEnabled(false); // local remove Button
// }
// }
}
void USBDialog::retranslate()
{
translate(m_ui, tr("Manage exported scripts"));
}
void USBDialog::initModel()
{
DEBUG_LOG(m_logger) << "(re)initModel !!";
// TODO: move to model
// compiler_warning("TODO")
// m_fsWatcher->addPath(getRootFolder());
// m_fsWatcher->addPath(getContentFolder(m_session->exerciseId()));
if (!m_localThpModel->init(getRootFolder()))
{
throw "init model failed for Export";
if (!m_localThpModel->init(getRootFolder(true))) // Download directory
throw "init model failed for Download";
}
m_ui->tvLocal->setModel(m_localThpModel); // important to set model before setting hidden columns
m_ui->tvLocal->hideColumn(ExportedScriptsModel::ColId);
m_ui->tvLocal->hideColumn(ExportedScriptsModel::ColLocation);
m_ui->tvLocal->hideColumn(ExportedScriptsModel::ColUploaded);
m_ui->tvLocal->hideColumn(ExportedScriptsModel::ColUploadedTime);
// fill local maps
{
m_ui->tvLocalMaps->setRowCount(0);
m_ui->tvLocalMaps->clearContents();
//Maps when WebMerc dann Scene sonst map
QDirIterator tpit(QStringLiteral("/usr/share/arcgis/resources/TilePackage/"), QDir::Files | QDir::NoDotAndDotDot,
QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
while (tpit.hasNext())
{
QString file = tpit.next();
m_ui->tvLocalMaps->insertRow(m_ui->tvLocalMaps->rowCount());
QFileInfo mapFile(file);
m_ui->tvLocalMaps->setItem(m_ui->tvLocalMaps->rowCount() - 1, 0, mapFile.fileName().contains(QStringLiteral("WebMerc")) ? new QTableWidgetItem(tr("3D Map")) : new QTableWidgetItem(tr("2D Map")) );
m_ui->tvLocalMaps->setItem(m_ui->tvLocalMaps->rowCount() - 1, 1, new QTableWidgetItem(mapFile.fileName()));
m_ui->tvLocalMaps->setItem(m_ui->tvLocalMaps->rowCount() - 1, 2, new QTableWidgetItem(QFileInfo(file).absolutePath()));
}
//ObjectScene
QDirIterator slpkit(QStringLiteral("/usr/share/arcgis/resources/slpk/"), QDir::Files | QDir::NoDotAndDotDot,
QDirIterator::Subdirectories);
while (slpkit.hasNext())
{
QString file = slpkit.next();
if (!file.endsWith(QStringLiteral(".slpk")))
continue;
QFileInfo fi(file);
if(fi.isSymLink())
continue;
m_ui->tvLocalMaps->insertRow(m_ui->tvLocalMaps->rowCount());
m_ui->tvLocalMaps->setItem(m_ui->tvLocalMaps->rowCount() - 1, 0, new QTableWidgetItem(tr("3D Object")));
m_ui->tvLocalMaps->setItem(m_ui->tvLocalMaps->rowCount() - 1, 1, new QTableWidgetItem(QFileInfo(file).fileName()));
m_ui->tvLocalMaps->setItem(m_ui->tvLocalMaps->rowCount() - 1, 2, new QTableWidgetItem(QFileInfo(file).absolutePath()));
}
//Eleveation
// We will copy all elevations every time!
// QDirIterator eleit(QStringLiteral("/usr/share/arcgis/resources/elevation/"), QDir::Files | QDir::NoDotAndDotDot,
// QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
// while (eleit.hasNext())
// {
// QString file = eleit.next();
// m_ui->tvLocalMaps->insertRow(m_ui->tvLocalMaps->rowCount());
// m_ui->tvLocalMaps->setItem(m_ui->tvLocalMaps->rowCount() - 1, 0, new QTableWidgetItem(QStringLiteral("Eleveation")));
// m_ui->tvLocalMaps->setItem(m_ui->tvLocalMaps->rowCount() - 1, 1, new QTableWidgetItem(QFileInfo(file).fileName()));
// // m_ui->tvLocalMaps->setItem(m_ui->tvLocalMaps->rowCount() - 1, 2, new QTableWidgetItem(QFileInfo(file).absolutePath()));
// }
}
m_ui->tvLocalMaps->sortItems(0);
m_ui->tvLocalMaps->hideColumn(2);
slotSelectionChanged(); // aka. enaDisa
}
QString USBDialog::getContentFolder(const QString &rootFolder) const
{
return QStringLiteral("%1/%2").arg(rootFolder, exerciseDirectoryName());
}
QString USBDialog::getContentFolder() const
{
return getContentFolder(getRootFolder(), m_exerciseId);
}
/*static*/ QString USBDialog::exerciseDirectoryName(int exerciseId)
{
return QStringLiteral("Exercise_%1").arg(exerciseId);
}
QString USBDialog::exerciseDirectoryName() const
{
return exerciseDirectoryName(m_exerciseId);
}
/*static*/ QString USBDialog::getContentFolder(const QString &rootFolder, int exerciseId)
{
return QStringLiteral("%1/%2").arg(rootFolder, exerciseDirectoryName(exerciseId));
}
QString USBDialog::getContentFolder(int exerciseId) const
{
return getContentFolder(getRootFolder(), exerciseId);
}
/* static */ QString USBDialog::getScriptFolder(const QString &rootFolder, int exerciseId, int scriptId)
{
return QStringLiteral("%1/%2").arg(getContentFolder(rootFolder, exerciseId)).arg(scriptId);
}
QString USBDialog::getScriptFolder(const QString &rootFolder, int scriptId) const
{
return getScriptFolder(rootFolder, m_exerciseId, scriptId);
}
QString USBDialog::getScriptFolder(int scriptId) const
{
return getScriptFolder(getRootFolder(), m_exerciseId, scriptId);
}
QString USBDialog::getRootFolder(bool forceDownloadDir) const
{
if (m_session->app() == LtsAppDescriptor::App::OC || forceDownloadDir)
return QDir::tempPath() + QStringLiteral("/THP-Download/");
return QDir::tempPath() + QStringLiteral("/THP-Export/");
}
} // namespace TakeHomePackageManager
#include "tpm_usb_dialog.moc"