feat(cpn): save model images with models and settings (#7234)
This commit is contained in:
@@ -232,6 +232,18 @@ int main(int argc, char *argv[])
|
||||
registerOpenTxFirmwares();
|
||||
SimulatorLoader::registerSimulators();
|
||||
|
||||
QTemporaryDir tempDir(QDir::tempPath() % "/etx-cpn-XXXXXX");
|
||||
|
||||
if (!tempDir.isValid()) {
|
||||
qDebug() << "Unable to create application temporary directory";
|
||||
gAppTempPath = "";
|
||||
} else {
|
||||
gAppTempPath = tempDir.path();
|
||||
|
||||
if (!QDir(gAppTempPath).mkdir("IMAGES"))
|
||||
qDebug() << "Unable to create images cache directory:" << Helpers::getImagesCacheDir();
|
||||
}
|
||||
|
||||
Profile & profile = g.currentProfile();
|
||||
if (profile.fwType().isEmpty()){
|
||||
profile.fwType(Firmware::getDefaultVariant()->getId());
|
||||
|
||||
@@ -78,7 +78,7 @@ static void writeYamlToByteArray(const YAML::Node& node, QByteArray& data, bool
|
||||
data_ostream << node;
|
||||
data = QByteArray::fromStdString(data_ostream.str());
|
||||
|
||||
qDebug() << "Saving YAML:";
|
||||
//qDebug() << "Saving YAML:";
|
||||
|
||||
if(addChecksum) {
|
||||
uint16_t checksum = 0xFFFF;
|
||||
@@ -88,7 +88,7 @@ static void writeYamlToByteArray(const YAML::Node& node, QByteArray& data, bool
|
||||
data.prepend(checksum_ostream.str().c_str());
|
||||
}
|
||||
|
||||
qDebug() << data.toStdString().c_str();
|
||||
//qDebug() << data.toStdString().c_str();
|
||||
}
|
||||
|
||||
bool loadLabelsListFromYaml(RadioData::ModelLabels& labels,
|
||||
|
||||
@@ -2334,3 +2334,42 @@ void ModelData::initTopBar()
|
||||
zone.widgetName = "Internal GPS";
|
||||
}
|
||||
}
|
||||
|
||||
QString ModelData::getImageFilename() const
|
||||
{
|
||||
if (!isBitmapEmpty()) {
|
||||
QString extn;
|
||||
|
||||
if (!getCurrentFirmware()->getCapability(ModelImageKeepExtn))
|
||||
extn = "." % getDefaultImageFileExtn();
|
||||
|
||||
return QString(bitmap).append(extn);
|
||||
} else {
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
QString ModelData::getImageFileExtn() const
|
||||
{
|
||||
if (getCurrentFirmware()->getCapability(ModelImageKeepExtn)) {
|
||||
QStringList strl = QString(bitmap).split(".");
|
||||
return strl.count() > 1 ? strl.at(strl.count() - 1) : "";
|
||||
} else {
|
||||
return getDefaultImageFileExtn();
|
||||
}
|
||||
}
|
||||
|
||||
QString ModelData::getDefaultImageFileExtn()
|
||||
{
|
||||
QString ret;
|
||||
|
||||
if (!getCurrentFirmware()->getCapability(ModelImageKeepExtn))
|
||||
ret = getCurrentFirmware()->getCapabilityStr(ModelImageFilters).replace("*.", "");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ModelData::isBitmapEmpty() const
|
||||
{
|
||||
return bitmap[0] == '\0';
|
||||
}
|
||||
|
||||
@@ -293,6 +293,10 @@ class ModelData {
|
||||
const Board::SwitchType getSwitchType(int sw, const GeneralSettings & gs) const;
|
||||
|
||||
QString getChecklistFilename() const;
|
||||
QString getImageFilename() const;
|
||||
QString getImageFileExtn() const;
|
||||
static QString getDefaultImageFileExtn();
|
||||
bool isBitmapEmpty() const;
|
||||
|
||||
enum ReferenceUpdateAction {
|
||||
REF_UPD_ACT_CLEAR,
|
||||
|
||||
@@ -107,7 +107,8 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
||||
case HasMixerNames:
|
||||
return (IS_TARANIS_X9(board) ? 8 : 6);
|
||||
case HasModelImage:
|
||||
return (board == BOARD_TARANIS_X9D || IS_TARANIS_PLUS(board) || board == BOARD_TARANIS_X9DP_2019 || IS_FAMILY_HORUS_OR_T16(board));
|
||||
return (board == BOARD_TARANIS_X9D || IS_TARANIS_PLUS(board) || board == BOARD_TARANIS_X9DP_2019 ||
|
||||
IS_FAMILY_HORUS_OR_T16(board) || Boards::getCapability(board, Board::HasColorLcd));
|
||||
case HasModelLabels:
|
||||
return IS_FAMILY_HORUS_OR_T16(board);
|
||||
case HasModelsList:
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#include <QtGlobal>
|
||||
#include <QFile>
|
||||
|
||||
QString gAppTempPath;
|
||||
|
||||
using namespace Helpers;
|
||||
|
||||
Stopwatch gStopwatch("global");
|
||||
@@ -366,6 +368,34 @@ QString Helpers::concatPath(QString & str1, const QString & str2, bool onlyonese
|
||||
return (str1 % ((!str1.endsWith("/") || !onlyonesep) ? "/" : "") % str2);
|
||||
}
|
||||
|
||||
QString Helpers::getImagesCacheDir()
|
||||
{
|
||||
if (gAppTempPath.isEmpty())
|
||||
return QString();
|
||||
|
||||
return QDir(gAppTempPath).filePath("IMAGES");
|
||||
}
|
||||
|
||||
QString Helpers::getImagePath(const QString & filename)
|
||||
{
|
||||
if (filename.isEmpty())
|
||||
return QString();
|
||||
|
||||
QString srcpath(Helpers::getImagesCacheDir() % "/" % filename);
|
||||
|
||||
if (srcpath.isEmpty() || !QFileInfo::exists(srcpath) || QFileInfo(srcpath).isDir()) {
|
||||
srcpath = g.currentProfile().sdPath() % "/IMAGES/" % filename;
|
||||
|
||||
if (!QFileInfo::exists(srcpath) || QFileInfo(srcpath).isDir()) {
|
||||
qDebug() << filename << "not found in image cache or sd path.";
|
||||
srcpath = "";
|
||||
}
|
||||
}
|
||||
|
||||
return srcpath;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Flag when simulator is running
|
||||
static bool simulatorRunning = false;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <QComboBox>
|
||||
|
||||
extern const QColor colors[CPN_MAX_CURVES];
|
||||
extern QString gAppTempPath;
|
||||
|
||||
#define TMR_NUM_OPTION (TMRMODE_COUNT+2*9+2*getCurrentFirmware()->getCapability(LogicalSwitches)-1)
|
||||
|
||||
@@ -118,6 +119,8 @@ namespace Helpers
|
||||
QString concatPath(const QString & str1, const QString & str2, bool onlyonesep = true);
|
||||
QString concatPath(const QString & str1, QString & str2, bool onlyonesep = true);
|
||||
QString concatPath(QString & str1, const QString & str2, bool onlyonesep = true);
|
||||
QString getImagesCacheDir();
|
||||
QString getImagePath(const QString & filename);
|
||||
} // namespace Helpers
|
||||
|
||||
// TODO : move globals to Helpers namespace
|
||||
|
||||
@@ -83,46 +83,23 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
|
||||
else {
|
||||
ui->imagePreview->setFixedSize(QSize(64, 32));
|
||||
}
|
||||
|
||||
QStringList items;
|
||||
items.append("");
|
||||
QString path = g.profile[g.id()].sdPath();
|
||||
path.append("/IMAGES/");
|
||||
QDir qd(path);
|
||||
if (qd.exists()) {
|
||||
QStringList filters = firmware->getCapabilityStr(ModelImageFilters).split("|");
|
||||
foreach ( QString file, qd.entryList(filters, QDir::Files) ) {
|
||||
QFileInfo fi(file);
|
||||
QString temp;
|
||||
if (firmware->getCapability(ModelImageKeepExtn))
|
||||
temp = fi.fileName();
|
||||
else
|
||||
temp = fi.completeBaseName();
|
||||
if (!items.contains(temp) && temp.length() <= firmware->getCapability(ModelImageNameLen))
|
||||
items.append(temp);
|
||||
}
|
||||
}
|
||||
if (!items.contains(model.bitmap)) {
|
||||
loadImageList(items, Helpers::getImagesCacheDir());
|
||||
loadImageList(items, g.currentProfile().sdPath() % "/IMAGES/");
|
||||
|
||||
if (!items.contains(model.bitmap))
|
||||
items.append(model.bitmap);
|
||||
}
|
||||
|
||||
items.sort(Qt::CaseInsensitive);
|
||||
|
||||
foreach (QString file, items) {
|
||||
ui->image->addItem(file);
|
||||
|
||||
if (file == model.bitmap) {
|
||||
ui->image->setCurrentIndex(ui->image->count() - 1);
|
||||
if (!file.isEmpty()) {
|
||||
QString fileName = path;
|
||||
fileName.append(model.bitmap);
|
||||
if (!firmware->getCapability(ModelImageKeepExtn)) {
|
||||
QString extn = firmware->getCapabilityStr(ModelImageFilters);
|
||||
if (extn.size() > 0)
|
||||
extn.remove(0, 1); // remove *
|
||||
fileName.append(extn);
|
||||
}
|
||||
QImage image(fileName);
|
||||
if (!image.isNull()) {
|
||||
ui->imagePreview->setPixmap(QPixmap::fromImage(image.scaled(ui->imagePreview->size())));
|
||||
}
|
||||
}
|
||||
loadImagePreview();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -392,25 +369,7 @@ void SetupPanel::on_image_currentIndexChanged(int index)
|
||||
if (!lock) {
|
||||
memset(model->bitmap, 0, CPN_MAX_BITMAP_LEN);
|
||||
strncpy(model->bitmap, ui->image->currentText().toLatin1(), CPN_MAX_BITMAP_LEN);
|
||||
if (model->bitmap[0] != '\0') {
|
||||
QString path = g.profile[g.id()].sdPath();
|
||||
path.append("/IMAGES/");
|
||||
path.append(model->bitmap);
|
||||
if (!firmware->getCapability(ModelImageKeepExtn)) {
|
||||
QString extn = firmware->getCapabilityStr(ModelImageFilters);
|
||||
if (extn.size() > 0)
|
||||
extn.remove(0, 1); // remove *
|
||||
path.append(extn);
|
||||
}
|
||||
QImage image(path);
|
||||
if (!image.isNull())
|
||||
ui->imagePreview->setPixmap(QPixmap::fromImage(image.scaled(ui->imagePreview->size())));
|
||||
else
|
||||
ui->imagePreview->clear();
|
||||
}
|
||||
else {
|
||||
ui->imagePreview->clear();
|
||||
}
|
||||
loadImagePreview();
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
@@ -829,3 +788,37 @@ void SetupPanel::onFunctionSwitchesUpdateItemModels()
|
||||
updateStartupSwitches();
|
||||
sharedItemModels->update(AbstractItemModel::IMUE_FunctionSwitches);
|
||||
}
|
||||
|
||||
void SetupPanel::loadImageList(QStringList &list, const QString & path)
|
||||
{
|
||||
QDir d(path);
|
||||
const int maxnamelen = firmware->getCapability(ModelImageNameLen);
|
||||
const bool keepextn = firmware->getCapability(ModelImageKeepExtn);
|
||||
|
||||
if (d.exists()) {
|
||||
QStringList filters = firmware->getCapabilityStr(ModelImageFilters).split("|");
|
||||
|
||||
foreach ( QString file, d.entryList(filters, QDir::Files) ) {
|
||||
QFileInfo fi(file);
|
||||
QString temp = keepextn ? fi.fileName() : fi.completeBaseName();
|
||||
|
||||
if (!list.contains(temp) && temp.length() <= maxnamelen)
|
||||
list.append(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetupPanel::loadImagePreview()
|
||||
{
|
||||
if (!model->isBitmapEmpty()) {
|
||||
QImage image;
|
||||
QString filename(model->getImageFilename());
|
||||
QString path(Helpers::getImagePath(filename));
|
||||
|
||||
if (!path.isEmpty() && image.load(path))
|
||||
ui->imagePreview->setPixmap(QPixmap::fromImage(image.scaled(ui->imagePreview->size())));
|
||||
else
|
||||
ui->imagePreview->clear();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,4 +115,6 @@ class SetupPanel : public ModelPanel
|
||||
void connectItemModelEvents(const FilteredItemModel * itemModel);
|
||||
CompoundItemModelFactory * panelItemModels;
|
||||
FilteredItemModelFactory * panelFilteredModels;
|
||||
void loadImageList(QStringList &list, const QString & dir);
|
||||
void loadImagePreview();
|
||||
};
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "translations.h"
|
||||
#include "version.h"
|
||||
#include "boardfactories.h"
|
||||
#include "helpers.h"
|
||||
|
||||
using namespace Simulator;
|
||||
|
||||
@@ -367,6 +368,21 @@ int main(int argc, char *argv[])
|
||||
Firmware::setCurrentVariant(Firmware::getFirmwareForId(simOptions.firmwareId));
|
||||
//qDebug() << "current firmware:" << getCurrentFirmware()->getId();
|
||||
|
||||
QString imgDir = Helpers::getImagesCacheDir();
|
||||
QDir dir(imgDir);
|
||||
|
||||
if (dir.exists()) {
|
||||
if (!dir.removeRecursively())
|
||||
qDebug() << "Unable to delete images cache directory" << imgDir;
|
||||
else
|
||||
qDebug() << "Deleted images cache directory" << imgDir;
|
||||
}
|
||||
|
||||
if (!QDir::temp().mkpath(imgDir))
|
||||
qDebug() << "Unable to create images cache directory" << imgDir;
|
||||
else
|
||||
qDebug() << "Created images cache directory" << imgDir;
|
||||
|
||||
int result = 0;
|
||||
SimulatorMainWindow * mainWindow = new SimulatorMainWindow(nullptr, simOptions.simulatorId, (simOptions.flags ? simOptions.flags : SIMULATOR_FLAGS_STANDALONE));
|
||||
if ((result = mainWindow->getExitStatus(&resultMsg))) {
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
*/
|
||||
|
||||
#include "etx.h"
|
||||
#include "helpers.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
#define MZ_ALLOCATION_SIZE (32*1024)
|
||||
@@ -94,14 +96,8 @@ bool EtxFormat::loadFile(QByteArray & filedata, const QString & filename, bool o
|
||||
{
|
||||
size_t size;
|
||||
void * data = mz_zip_reader_extract_file_to_heap(&zip_archive, qPrintable(filename), &size, 0);
|
||||
if (!data) {
|
||||
if (optional) {
|
||||
//qDebug() << "File not found:" << filename;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!data) return optional;
|
||||
|
||||
qDebug() << QString("Extracted file %1, size=%2").arg(filename).arg(size);
|
||||
filedata.clear();
|
||||
@@ -110,16 +106,77 @@ bool EtxFormat::loadFile(QByteArray & filedata, const QString & filename, bool o
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EtxFormat::writeFile(const QByteArray & filedata, const QString & filename)
|
||||
bool EtxFormat::loadImageFile(const QString & filename, bool optional)
|
||||
{
|
||||
if (!mz_zip_writer_add_mem(&zip_archive, filename.toStdString().c_str(), filedata.data(), filedata.size(), MZ_DEFAULT_LEVEL)) {
|
||||
setError(tr("Error adding %1 to EdgeTX archive").arg(filename));
|
||||
QString srcpath("IMAGES/" % filename);
|
||||
size_t size;
|
||||
void * data = mz_zip_reader_extract_file_to_heap(&zip_archive, qPrintable(srcpath), &size, 0);
|
||||
|
||||
if (!data) return optional;
|
||||
|
||||
QByteArray ba;
|
||||
ba.append((char *)data, size);
|
||||
mz_free(data);
|
||||
|
||||
QFile imgfile(Helpers::getImagesCacheDir() % "/" % filename);
|
||||
|
||||
if (imgfile.open(QIODevice::WriteOnly)) {
|
||||
if (imgfile.write(ba) != (qint64)size) {
|
||||
qDebug() << "Image data written does not match expected";
|
||||
return false;
|
||||
}
|
||||
|
||||
imgfile.close();
|
||||
} else {
|
||||
setError(tr("Unable to write %1 to cache").arg(filename));
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << QString("Extracted file %1, size=%2").arg(srcpath).arg(size);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EtxFormat::writeFile(const QByteArray & filedata, const QString & filename)
|
||||
{
|
||||
if (!mz_zip_writer_add_mem(&zip_archive, filename.toStdString().c_str(), filedata.data(), filedata.size(), MZ_DEFAULT_LEVEL)) {
|
||||
setError(tr("Error adding %1 to archive").arg(filename));
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "File" << filename << "written, size:" << filedata.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EtxFormat::writeImageFile(const QString & filename)
|
||||
{
|
||||
QString srcpath(Helpers::getImagePath(filename));
|
||||
|
||||
if (!srcpath.isEmpty()) {
|
||||
QByteArray ba;
|
||||
QFile imgfile(srcpath);
|
||||
|
||||
if (imgfile.open(QIODevice::ReadOnly)) {
|
||||
ba.append(imgfile.readAll());
|
||||
imgfile.close();
|
||||
} else {
|
||||
setError(tr("Unable to open image %1").arg(filename));
|
||||
return false;
|
||||
}
|
||||
|
||||
QString destpath("IMAGES/" % filename);
|
||||
|
||||
if (!mz_zip_writer_add_mem(&zip_archive, destpath.toStdString().c_str(), ba.data(), ba.size(), MZ_DEFAULT_LEVEL)) {
|
||||
setError(tr("Error adding file %1").arg(destpath));
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "File" << destpath << "written, size:" << ba.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EtxFormat::getFileList(std::list<std::string>& filelist)
|
||||
{
|
||||
int count = (int)mz_zip_reader_get_num_files(&zip_archive);
|
||||
|
||||
@@ -41,7 +41,9 @@ class EtxFormat : public LabelsStorageFormat
|
||||
|
||||
protected:
|
||||
virtual bool loadFile(QByteArray & fileData, const QString & fileName, bool optional = false);
|
||||
virtual bool loadImageFile(const QString & fileName, bool optional = false);
|
||||
virtual bool writeFile(const QByteArray & fileData, const QString & fileName);
|
||||
virtual bool writeImageFile(const QString & fileName);
|
||||
virtual bool getFileList(std::list<std::string>& filelist);
|
||||
virtual bool deleteFile(const QString & fileName) { return false; }
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ bool LabelsStorageFormat::load(RadioData & radioData)
|
||||
|
||||
QByteArray labelslistBuffer;
|
||||
int sortOrder = 0;
|
||||
|
||||
if (loadFile(labelslistBuffer, "MODELS/labels.yml")) {
|
||||
try {
|
||||
if (!loadLabelsListFromYaml(radioData.labels, sortOrder, modelFiles, labelslistBuffer)) {
|
||||
@@ -108,6 +109,8 @@ bool LabelsStorageFormat::load(RadioData & radioData)
|
||||
if (hasLabels)
|
||||
radioData.models.resize(modelFiles.size());
|
||||
|
||||
QList<QString> modelImages;
|
||||
|
||||
for (const auto& mc : modelFiles) {
|
||||
qDebug() << "Filename: " << mc.filename.c_str();
|
||||
|
||||
@@ -127,6 +130,7 @@ bool LabelsStorageFormat::load(RadioData & radioData)
|
||||
|
||||
QByteArray modelBuffer;
|
||||
QString filename = "MODELS/" + QString::fromStdString(mc.filename);
|
||||
|
||||
if (!loadFile(modelBuffer, filename)) {
|
||||
setError(tr("Cannot extract ") + filename);
|
||||
return false;
|
||||
@@ -150,6 +154,14 @@ bool LabelsStorageFormat::load(RadioData & radioData)
|
||||
if (!loadChecklist(model))
|
||||
return false;
|
||||
|
||||
if (!model.isBitmapEmpty()) {
|
||||
const QString fname(model.getImageFilename());
|
||||
|
||||
if (!modelImages.contains(fname)) {
|
||||
modelImages.append(fname);
|
||||
}
|
||||
}
|
||||
|
||||
model.modelIndex = modelIdx;
|
||||
strncpy(model.filename, mc.filename.c_str(), sizeof(model.filename)-1);
|
||||
|
||||
@@ -160,6 +172,11 @@ bool LabelsStorageFormat::load(RadioData & radioData)
|
||||
modelIdx++;
|
||||
}
|
||||
|
||||
for (const auto &fname : modelImages) {
|
||||
if (!loadImageFile(fname, true))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add the labels in the models
|
||||
if (hasLabels) {
|
||||
radioData.addLabelsFromModels();
|
||||
@@ -232,8 +249,9 @@ bool LabelsStorageFormat::write(RadioData & radioData)
|
||||
}
|
||||
|
||||
EtxModelfiles modelFiles;
|
||||
for (const auto& model : radioData.models) {
|
||||
QList<QString> modelImages;
|
||||
|
||||
for (const auto& model : radioData.models) {
|
||||
if (model.isEmpty())
|
||||
continue;
|
||||
|
||||
@@ -251,10 +269,23 @@ bool LabelsStorageFormat::write(RadioData & radioData)
|
||||
if (!writeFile(modelData, modelFilename))
|
||||
return false;
|
||||
|
||||
if (!model.isBitmapEmpty()) {
|
||||
const QString fname(model.getImageFilename());
|
||||
|
||||
if (!modelImages.contains(fname)) {
|
||||
modelImages.append(fname);
|
||||
}
|
||||
}
|
||||
|
||||
if (!writeChecklist(model))
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto &fname : modelImages) {
|
||||
if (!writeImageFile(fname))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hasLabels) {
|
||||
QByteArray labelsListBuffer;
|
||||
if (!writeLabelsListToYaml(radioData, labelsListBuffer) || !writeFile(labelsListBuffer, "MODELS/labels.yml"))
|
||||
@@ -279,11 +310,10 @@ bool LabelsStorageFormat::loadChecklist(ModelData & model)
|
||||
|
||||
bool LabelsStorageFormat::writeChecklist(const ModelData & model)
|
||||
{
|
||||
const QString fname("MODELS/" + model.getChecklistFilename());
|
||||
|
||||
// not every model has a checklist
|
||||
if (!model.checklistData.isEmpty()) {
|
||||
const QString fname("MODELS/" + model.getChecklistFilename());
|
||||
//qDebug() << "Writing checklist file:" << fname;
|
||||
|
||||
if (!writeFile(model.checklistData, fname)) {
|
||||
setError(tr("Cannot write ") + fname);
|
||||
return false;
|
||||
|
||||
@@ -46,7 +46,9 @@ class LabelsStorageFormat : public StorageFormat
|
||||
|
||||
protected:
|
||||
virtual bool loadFile(QByteArray & fileData, const QString & fileName, bool optional = false) = 0;
|
||||
virtual bool loadImageFile(const QString & fileName, bool optional = false) = 0;
|
||||
virtual bool writeFile(const QByteArray & fileData, const QString & fileName) = 0;
|
||||
virtual bool writeImageFile(const QString & fileName) = 0;
|
||||
virtual bool getFileList(std::list<std::string>& filelist) = 0;
|
||||
virtual bool deleteFile(const QString & fileName) = 0;
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
*/
|
||||
|
||||
#include "sdcard.h"
|
||||
#include "helpers.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
|
||||
@@ -28,6 +30,7 @@ bool SdcardFormat::write(RadioData & radioData)
|
||||
QDir dir(filename);
|
||||
dir.mkdir("RADIO");
|
||||
dir.mkdir("MODELS");
|
||||
dir.mkdir("IMAGES");
|
||||
return LabelsStorageFormat::write(radioData);
|
||||
}
|
||||
|
||||
@@ -35,6 +38,7 @@ bool SdcardFormat::loadFile(QByteArray & filedata, const QString & filename, boo
|
||||
{
|
||||
QString path = this->filename + "/" + filename;
|
||||
QFile file(path);
|
||||
|
||||
if (!file.exists()) {
|
||||
if (optional) {
|
||||
//qDebug() << "File not found:" << filename;
|
||||
@@ -45,11 +49,47 @@ bool SdcardFormat::loadFile(QByteArray & filedata, const QString & filename, boo
|
||||
}
|
||||
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
setError(tr("Error opening file %1:\n%2.").arg(path).arg(file.errorString()));
|
||||
setError(tr("Error opening file %1:\n%2.").arg(filename).arg(file.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
filedata = file.readAll();
|
||||
qDebug() << "File" << path << "read, size:" << filedata.size();
|
||||
qDebug() << "File" << filename << "read, size:" << filedata.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SdcardFormat::loadImageFile(const QString & filename, bool optional)
|
||||
{
|
||||
QString srcpath = this->filename + "/IMAGES/" + filename;
|
||||
QFile file(srcpath);
|
||||
|
||||
if (!file.exists()) return optional;
|
||||
|
||||
if (QDir(Helpers::getImagesCacheDir()).exists()) {
|
||||
QString destpath(Helpers::getImagesCacheDir() % "/" % filename);
|
||||
QFile destfile(destpath);
|
||||
|
||||
// QFile::copy fails if destination file exists
|
||||
if (destfile.exists()) {
|
||||
if (destfile.remove()) {
|
||||
qDebug() << "Deleted file from image cache" << filename;
|
||||
} else {
|
||||
qDebug() << "Unable to delete cached" << filename;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (file.copy(Helpers::getImagesCacheDir() % "/" % filename)) {
|
||||
qDebug() << "Cached image" << filename;
|
||||
} else {
|
||||
qDebug() << "Failed to cache image" << filename;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Failed to cache" << filename << ". Cache directory" << Helpers::getImagesCacheDir()
|
||||
<< "does not exist.";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -57,25 +97,59 @@ bool SdcardFormat::writeFile(const QByteArray & data, const QString & filename)
|
||||
{
|
||||
QString path = this->filename + "/" + filename;
|
||||
QFile file(path);
|
||||
|
||||
if (!file.open(QFile::WriteOnly)) {
|
||||
setError(tr("Error opening file %1 in write mode:\n%2.").arg(path).arg(file.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
file.write(data.data(), data.size());
|
||||
file.close();
|
||||
qDebug() << "File" << path << "written, size:" << data.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SdcardFormat::writeImageFile(const QString & filename)
|
||||
{
|
||||
QString srcpath(Helpers::getImagePath(filename));
|
||||
|
||||
if (!srcpath.isEmpty()) {
|
||||
QFileInfo srcinfo(srcpath);
|
||||
QString destpath(this->filename + "/IMAGES/" + filename);
|
||||
QFileInfo destinfo(destpath);
|
||||
|
||||
if (destinfo.exists()) {
|
||||
// for performance reasons avoid overwriting the same image
|
||||
if (destinfo.size() == srcinfo.size()) {
|
||||
qDebug() << "Image file" << filename << "skipped as same size";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!QFile(srcpath).copy(destpath)) {
|
||||
setError(tr("Error writing image file: %1").arg(filename));
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "File" << destpath << "written, size:" << srcinfo.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SdcardFormat::getFileList(std::list<std::string>& filelist)
|
||||
{
|
||||
QDir dir(filename);
|
||||
|
||||
if (!dir.cd("MODELS")) return false;
|
||||
|
||||
QStringList ql = dir.entryList();
|
||||
|
||||
for (const auto& str : ql) {
|
||||
filelist.push_back("MODELS/" + str.toStdString());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -92,6 +166,11 @@ bool SdcardFormat::deleteFile(const QString & filename)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
class SdcardStorageFactory
|
||||
*/
|
||||
|
||||
bool SdcardStorageFactory::probe(const QString & path)
|
||||
{
|
||||
return QDir(path).exists();
|
||||
|
||||
@@ -40,7 +40,9 @@ class SdcardFormat : public LabelsStorageFormat
|
||||
|
||||
protected:
|
||||
virtual bool loadFile(QByteArray & fileData, const QString & fileName, bool optional = false);
|
||||
virtual bool loadImageFile(const QString & fileName, bool optional = false);
|
||||
virtual bool writeFile(const QByteArray & fileData, const QString & fileName);
|
||||
virtual bool writeImageFile(const QString & fileName);
|
||||
virtual bool getFileList(std::list<std::string>& filelist);
|
||||
virtual bool deleteFile(const QString & fileName);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user