mirror of
https://github.com/EdgeTX/edgetx.git
synced 2025-07-24 00:35:14 +03:00
[Companion] MdiChild now use a QTreeWidget instead of a QListWidget (… (#4096)
* [Companion] MdiChild now use a QTreeWidget instead of a QListWidget (for Horus compatibility) * [Companion] Horus models.txt parsing / writing implemented * Fix for QT53 (#4109)
This commit is contained in:
parent
dd77670007
commit
ec56d2dbdb
15 changed files with 443 additions and 385 deletions
|
@ -1079,7 +1079,9 @@ class ModelData {
|
|||
QVector<const MixData *> mixes(int channel) const;
|
||||
|
||||
bool used;
|
||||
char category[15+1];
|
||||
char name[15+1];
|
||||
char filename[16+1];
|
||||
TimerData timers[CPN_MAX_TIMERS];
|
||||
bool noGlobalFunctions;
|
||||
bool thrTrim; // Enable Throttle Trim
|
||||
|
@ -1208,7 +1210,8 @@ class GeneralSettings {
|
|||
int calibMid[CPN_MAX_STICKS+CPN_MAX_POTS+CPN_MAX_MOUSE_ANALOGS];
|
||||
int calibSpanNeg[CPN_MAX_STICKS+CPN_MAX_POTS+CPN_MAX_MOUSE_ANALOGS];
|
||||
int calibSpanPos[CPN_MAX_STICKS+CPN_MAX_POTS+CPN_MAX_MOUSE_ANALOGS];
|
||||
unsigned int currModel; // 0..15
|
||||
unsigned int currModelIndex;
|
||||
char currModelFilename[16+1];
|
||||
unsigned int contrast;
|
||||
unsigned int vBatWarn;
|
||||
int txVoltageCalibration;
|
||||
|
@ -1321,6 +1324,30 @@ class RadioData {
|
|||
public:
|
||||
GeneralSettings generalSettings;
|
||||
ModelData models[CPN_MAX_MODELS];
|
||||
|
||||
void setCurrentModel(unsigned int index)
|
||||
{
|
||||
generalSettings.currModelIndex = index;
|
||||
strcpy(generalSettings.currModelFilename, models[index].filename);
|
||||
}
|
||||
|
||||
QString getNextModelFilename()
|
||||
{
|
||||
char filename[sizeof(ModelData::filename)];
|
||||
int index = 0;
|
||||
bool found = true;
|
||||
while (found) {
|
||||
sprintf(filename, "model%d.bin", ++index);
|
||||
found = false;
|
||||
for (int i=0; i<CPN_MAX_MODELS; i++) {
|
||||
if (strcmp(filename, models[i].filename) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
};
|
||||
|
||||
enum Capability {
|
||||
|
|
|
@ -87,7 +87,7 @@ Er9xGeneral::operator GeneralSettings ()
|
|||
result.calibSpanPos[i] = calibSpanPos[i];
|
||||
}
|
||||
|
||||
result.currModel = currModel;
|
||||
result.currModelIndex = currModel;
|
||||
result.contrast = contrast;
|
||||
result.vBatWarn = vBatWarn;
|
||||
result.txVoltageCalibration = txVoltageCalibration;
|
||||
|
|
|
@ -99,7 +99,7 @@ Ersky9xGeneral::operator GeneralSettings ()
|
|||
result.calibSpanPos[i] = calibSpanPos[i];
|
||||
}
|
||||
|
||||
result.currModel = currModel;
|
||||
result.currModelIndex = currModel;
|
||||
result.contrast = contrast;
|
||||
result.vBatWarn = vBatWarn;
|
||||
result.txVoltageCalibration = txVoltageCalibration;
|
||||
|
|
|
@ -3394,9 +3394,9 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, BoardEnum board, unsigne
|
|||
|
||||
if (IS_HORUS(board)) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
internalField.Append(new CharField<610>(modelData.customScreenData[i], true, "Custom screen blob"));
|
||||
internalField.Append(new CharField<610>(modelData.customScreenData[i], false, "Custom screen blob"));
|
||||
}
|
||||
internalField.Append(new CharField<216>(modelData.topbarData, true, "Top bar blob"));
|
||||
internalField.Append(new CharField<216>(modelData.topbarData, false, "Top bar blob"));
|
||||
internalField.Append(new SpareBitsField<8>()); // current view
|
||||
}
|
||||
}
|
||||
|
@ -3512,7 +3512,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo
|
|||
|
||||
internalField.Append(new UnsignedField<16>(chkSum));
|
||||
if (!IS_HORUS(board)) {
|
||||
internalField.Append(new UnsignedField<8>(generalData.currModel));
|
||||
internalField.Append(new UnsignedField<8>(generalData.currModelIndex));
|
||||
internalField.Append(new UnsignedField<8>(generalData.contrast));
|
||||
}
|
||||
internalField.Append(new UnsignedField<8>(generalData.vBatWarn));
|
||||
|
@ -3711,8 +3711,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo
|
|||
for (int i=0; i<MAX_SLIDERS(board); ++i) {
|
||||
internalField.Append(new ZCharField<3>(generalData.sliderName[i], "Slider name"));
|
||||
}
|
||||
static char modelName[17+1] = "model1.bin\0 ";
|
||||
internalField.Append(new CharField<17>(modelName, true, "Model name"));
|
||||
internalField.Append(new CharField<17>(generalData.currModelFilename, true, "Current model filename"));
|
||||
}
|
||||
else if (IS_TARANIS(board) && version >= 217) {
|
||||
for (int i=0; i<MAX_SWITCHES(board, version); i++) {
|
||||
|
|
|
@ -228,22 +228,33 @@ int OpenTxEepromInterface::loadFile(RadioData & radioData, const QString & filen
|
|||
|
||||
storage.read(filename);
|
||||
|
||||
// models.txt
|
||||
QString modelList = QString(storage.modelList);
|
||||
qDebug() << "Models: size" << modelList.size() << "contents" << modelList;
|
||||
|
||||
// radio.bin
|
||||
// Radio settings
|
||||
qDebug() << "Radio settings:" << storage.radio.size();
|
||||
loadFromByteArray<GeneralSettings, OpenTxGeneralData>(radioData.generalSettings, storage.radio);
|
||||
|
||||
// all models
|
||||
QList<QString> models = storage.getModelsFileNames();
|
||||
qDebug() << "We have" << models.size() << "models:";
|
||||
|
||||
int index = 0;
|
||||
for (QList<ModelFile>::iterator it = storage.models.begin(); it != storage.models.end(); ++it, ++index) {
|
||||
loadFromByteArray<ModelData, OpenTxModelData>(radioData.models[index], it->data);
|
||||
radioData.models[index].used = true;
|
||||
// Models
|
||||
int modelIndex = 0;
|
||||
QString modelList = QString(storage.modelList);
|
||||
QList<QByteArray> lines = storage.modelList.split('\n');
|
||||
QString category = QObject::tr("Unknown");
|
||||
foreach (const QByteArray & line, lines) {
|
||||
if (!line.isEmpty()) {
|
||||
if (line.startsWith('[') && line.endsWith(']')) {
|
||||
category = line.mid(1, line.size() - 2);
|
||||
}
|
||||
else {
|
||||
qDebug() << "Loading" << line;
|
||||
foreach (const ModelFile &model, storage.models) {
|
||||
if (line == model.filename) {
|
||||
loadFromByteArray<ModelData, OpenTxModelData>(radioData.models[modelIndex], model.data);
|
||||
strncpy(radioData.models[modelIndex].filename, line.data(), sizeof(radioData.models[modelIndex].filename));
|
||||
strncpy(radioData.models[modelIndex].category, category.toStdString().c_str(), sizeof(radioData.models[modelIndex].category));
|
||||
radioData.models[modelIndex].used = true;
|
||||
modelIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -255,7 +266,8 @@ int OpenTxEepromInterface::saveFile(const RadioData & radioData, const QString &
|
|||
uint8_t version = getLastDataVersion(board);
|
||||
|
||||
// models.txt
|
||||
storage.modelList = QByteArray("[Models]\n");
|
||||
storage.modelList = QByteArray();
|
||||
QString currentCategory = "";
|
||||
|
||||
// radio.bin
|
||||
saveToByteArray<GeneralSettings, OpenTxGeneralData>(radioData.generalSettings, storage.radio, version);
|
||||
|
@ -264,12 +276,17 @@ int OpenTxEepromInterface::saveFile(const RadioData & radioData, const QString &
|
|||
for (int i=0; i<CPN_MAX_MODELS; i++) {
|
||||
const ModelData & model = radioData.models[i];
|
||||
if (!model.isEmpty()) {
|
||||
QString modelFilename = QString().sprintf("model%d.bin", i+1);
|
||||
QString modelFilename = model.filename;
|
||||
QByteArray modelData;
|
||||
saveToByteArray<ModelData, OpenTxModelData>(model, modelData, version);
|
||||
ModelFile modelFile = { modelFilename, modelData };
|
||||
storage.models.append(modelFile);
|
||||
storage.modelList.append(QString(" ") + modelFilename + "\n");
|
||||
QString modelCategory = model.category;
|
||||
if (currentCategory != modelCategory) {
|
||||
storage.modelList.append(QString().sprintf("[%s]\n", model.category));
|
||||
currentCategory = modelCategory;
|
||||
}
|
||||
storage.modelList.append(modelFilename + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -813,7 +813,7 @@ void startSimulation(QWidget * parent, RadioData & radioData, int modelIdx)
|
|||
unsigned int flags = 0;
|
||||
if (modelIdx >= 0) {
|
||||
flags |= SIMULATOR_FLAGS_NOTX;
|
||||
simuData->generalSettings.currModel = modelIdx;
|
||||
simuData->setCurrentModel(modelIdx);
|
||||
}
|
||||
if (radioData.generalSettings.stickMode & 1) {
|
||||
flags |= SIMULATOR_FLAGS_STICK_MODE_LEFT;
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
#include "wizarddialog.h"
|
||||
#include "flashfirmwaredialog.h"
|
||||
#include "storage_eeprom.h"
|
||||
#include "storage_sdcard.h"
|
||||
#include <QFileInfo>
|
||||
|
||||
#if defined WIN32 || !defined __GNUC__
|
||||
#include <windows.h>
|
||||
|
@ -45,19 +43,19 @@
|
|||
|
||||
MdiChild::MdiChild():
|
||||
QWidget(),
|
||||
ui(new Ui::mdiChild),
|
||||
ui(new Ui::MdiChild),
|
||||
firmware(GetCurrentFirmware()),
|
||||
isUntitled(true),
|
||||
fileChanged(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowIcon(CompanionIcon("open.png"));
|
||||
ui->SimulateTxButton->setIcon(CompanionIcon("simulate.png"));
|
||||
ui->simulateButton->setIcon(CompanionIcon("simulate.png"));
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
eepromInterfaceChanged();
|
||||
|
||||
if (!(this->isMaximized() || this->isMinimized())) {
|
||||
if (!(isMaximized() || isMinimized())) {
|
||||
adjustSize();
|
||||
}
|
||||
}
|
||||
|
@ -67,27 +65,14 @@ MdiChild::~MdiChild()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void MdiChild::qSleep(int ms)
|
||||
{
|
||||
if (ms<0)
|
||||
return;
|
||||
|
||||
#if defined WIN32 || !defined __GNUC__
|
||||
Sleep(uint(ms));
|
||||
#else
|
||||
struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
|
||||
nanosleep(&ts, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MdiChild::eepromInterfaceChanged()
|
||||
{
|
||||
ui->modelsList->refreshList();
|
||||
if (GetCurrentFirmware()->getBoard() == BOARD_HORUS && !HORUS_READY_FOR_RELEASE()) {
|
||||
ui->SimulateTxButton->setEnabled(false);
|
||||
}
|
||||
ui->simulateButton->setEnabled(false);
|
||||
}
|
||||
else {
|
||||
ui->SimulateTxButton->setEnabled(GetCurrentFirmware()->getCapability(Simulation));
|
||||
ui->simulateButton->setEnabled(GetCurrentFirmware()->getCapability(Simulation));
|
||||
}
|
||||
updateTitle();
|
||||
}
|
||||
|
@ -133,7 +118,7 @@ void MdiChild::setModified()
|
|||
documentWasModified();
|
||||
}
|
||||
|
||||
void MdiChild::on_SimulateTxButton_clicked()
|
||||
void MdiChild::on_simulateButton_clicked()
|
||||
{
|
||||
startSimulation(this, radioData, -1);
|
||||
}
|
||||
|
@ -158,7 +143,7 @@ void MdiChild::modelEdit()
|
|||
{
|
||||
int row = getCurrentRow();
|
||||
|
||||
if (row == 0){
|
||||
if (row == 0) {
|
||||
generalEdit();
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
#include "eeprominterface.h"
|
||||
|
||||
namespace Ui {
|
||||
class mdiChild;
|
||||
class MdiChild;
|
||||
}
|
||||
#define ER9X_EEPROM_FILE_TYPE "ER9X_EEPROM_FILE"
|
||||
|
||||
#define ER9X_EEPROM_FILE_TYPE "ER9X_EEPROM_FILE"
|
||||
#define EEPE_EEPROM_FILE_HEADER "EEPE EEPROM FILE"
|
||||
#define EEPE_MODEL_FILE_HEADER "EEPE MODEL FILE"
|
||||
|
||||
|
@ -65,8 +65,7 @@ class MdiChild : public QWidget
|
|||
|
||||
private slots:
|
||||
void documentWasModified();
|
||||
void on_SimulateTxButton_clicked();
|
||||
void qSleep(int ms);
|
||||
void on_simulateButton_clicked();
|
||||
|
||||
public slots:
|
||||
void checkAndInitModel(int row);
|
||||
|
@ -90,7 +89,7 @@ class MdiChild : public QWidget
|
|||
QString strippedName(const QString & fullFileName);
|
||||
bool loadOtxFile(const QString & fileName);
|
||||
|
||||
Ui::mdiChild * ui;
|
||||
Ui::MdiChild * ui;
|
||||
|
||||
QString curFile;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>mdiChild</class>
|
||||
<widget class="QWidget" name="mdiChild">
|
||||
<class>MdiChild</class>
|
||||
<widget class="QWidget" name="MdiChild">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
|
@ -18,7 +18,7 @@
|
|||
<widget class="ModelsListWidget" name="modelsList"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="SimulateTxButton">
|
||||
<widget class="QPushButton" name="simulateButton">
|
||||
<property name="text">
|
||||
<string>Simulate Tx</string>
|
||||
</property>
|
||||
|
|
|
@ -356,10 +356,10 @@ void ModulePanel::update()
|
|||
}
|
||||
ui->multiSubType->setCurrentIndex(module.subType);
|
||||
|
||||
ui->cb_autoBind->setVisible(mask & MASK_MULTIMODULE);
|
||||
ui->cb_autoBind->setChecked(module.multi.autoBindMode ? Qt::Checked : Qt::Unchecked);
|
||||
ui->cb_lowPower->setVisible(mask & MASK_MULTIMODULE);
|
||||
ui->cb_lowPower->setChecked(module.multi.lowPowerMode ? Qt::Checked : Qt::Unchecked);
|
||||
ui->autoBind->setVisible(mask & MASK_MULTIMODULE);
|
||||
ui->autoBind->setChecked(module.multi.autoBindMode ? Qt::Checked : Qt::Unchecked);
|
||||
ui->lowPower->setVisible(mask & MASK_MULTIMODULE);
|
||||
ui->lowPower->setChecked(module.multi.lowPowerMode ? Qt::Checked : Qt::Unchecked);
|
||||
|
||||
|
||||
if (firmware->getCapability(HasFailsafe)) {
|
||||
|
|
|
@ -609,14 +609,14 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="4" column="4">
|
||||
<widget class="QCheckBox" name="cb_autoBind">
|
||||
<widget class="QCheckBox" name="autoBind">
|
||||
<property name="text">
|
||||
<string>Bind on startup</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="5">
|
||||
<widget class="QCheckBox" name="cb_lowPower">
|
||||
<widget class="QCheckBox" name="lowPower">
|
||||
<property name="text">
|
||||
<string>Low Power</string>
|
||||
</property>
|
||||
|
|
|
@ -34,25 +34,43 @@ class DragDropHeader {
|
|||
uint8_t models[CPN_MAX_MODELS];
|
||||
};
|
||||
|
||||
ModelsListWidget::ModelsListWidget(QWidget *parent):
|
||||
QListWidget(parent)
|
||||
ModelsListWidget::ModelsListWidget(QWidget * parent):
|
||||
QTreeWidget(parent)
|
||||
{
|
||||
setFont(QFont("Courier New",12));
|
||||
radioData = &((MdiChild *)parent)->radioData;
|
||||
refreshList();
|
||||
BoardEnum board = GetCurrentFirmware()->getBoard();
|
||||
QStringList labels;
|
||||
labels << tr("Index") << tr("Name");
|
||||
if (!(IS_HORUS(board) || IS_SKY9X(board))) {
|
||||
labels << tr("Size");
|
||||
}
|
||||
setColumnCount(labels.size());
|
||||
setHeaderLabels(labels);
|
||||
setColumnWidth(0, 50);
|
||||
setColumnWidth(2, 100);
|
||||
|
||||
connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OpenEditWindow()));
|
||||
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(ShowContextMenu(const QPoint&)));
|
||||
connect(this, SIGNAL(currentRowChanged(int)), this, SLOT(viableModelSelected(int)));
|
||||
connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(onCurrentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
|
||||
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
setDragEnabled(true);
|
||||
setAcceptDrops(true);
|
||||
setDragDropOverwriteMode(true);
|
||||
setDropIndicatorShown(true);
|
||||
if (!IS_HORUS(board)) {
|
||||
setIndentation(0);
|
||||
}
|
||||
|
||||
active_highlight_color = palette().color(QPalette::Active, QPalette::Highlight);
|
||||
|
||||
radioData = &((MdiChild *)parent)->radioData;
|
||||
refreshList();
|
||||
|
||||
for (int i=0; i<labels.size(); i++) {
|
||||
resizeColumnToContents(i);
|
||||
}
|
||||
}
|
||||
|
||||
void ModelsListWidget::ShowContextMenu(const QPoint& pos)
|
||||
|
@ -65,29 +83,34 @@ void ModelsListWidget::ShowContextMenu(const QPoint& pos)
|
|||
const QMimeData *mimeData = clipboard->mimeData();
|
||||
bool hasData = mimeData->hasFormat("application/x-companion");
|
||||
|
||||
contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"),this,SLOT(EditModel()));
|
||||
contextMenu.addAction(CompanionIcon("open.png"), tr("&Restore from backup"),this,SLOT(LoadBackup()));
|
||||
contextMenu.addAction(CompanionIcon("wizard.png"), tr("&Model Wizard"),this,SLOT(OpenWizard()));
|
||||
contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"), this, SLOT(EditModel()));
|
||||
contextMenu.addAction(CompanionIcon("open.png"), tr("&Restore from backup"), this, SLOT(LoadBackup()));
|
||||
contextMenu.addAction(CompanionIcon("wizard.png"), tr("&Model Wizard"), this, SLOT(OpenWizard()));
|
||||
contextMenu.addSeparator();
|
||||
contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(confirmDelete()),tr("Delete"));
|
||||
contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(copy()),tr("Ctrl+C"));
|
||||
contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(cut()),tr("Ctrl+X"));
|
||||
contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(paste()),tr("Ctrl+V"))->setEnabled(hasData);
|
||||
contextMenu.addAction(CompanionIcon("duplicate.png"), tr("D&uplicate"),this,SLOT(duplicate()),tr("Ctrl+U"));
|
||||
contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"), this, SLOT(confirmDelete()), tr("Delete"));
|
||||
contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"), this, SLOT(copy()), tr("Ctrl+C"));
|
||||
contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"), this, SLOT(cut()), tr("Ctrl+X"));
|
||||
contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"), this, SLOT(paste()), tr("Ctrl+V"))->setEnabled(hasData);
|
||||
contextMenu.addAction(CompanionIcon("duplicate.png"), tr("D&uplicate"), this, SLOT(duplicate()), tr("Ctrl+U"));
|
||||
contextMenu.addSeparator();
|
||||
contextMenu.addAction(CompanionIcon("currentmodel.png"), tr("&Use as default"),this,SLOT(setdefault()));
|
||||
contextMenu.addAction(CompanionIcon("currentmodel.png"), tr("&Use as default"), this, SLOT(setdefault()));
|
||||
contextMenu.addSeparator();
|
||||
contextMenu.addAction(CompanionIcon("print.png"), tr("P&rint model"),this, SLOT(print()),QKeySequence(tr("Ctrl+P")));
|
||||
contextMenu.addAction(CompanionIcon("print.png"), tr("P&rint model"), this, SLOT(print()),QKeySequence(tr("Ctrl+P")));
|
||||
contextMenu.addSeparator();
|
||||
contextMenu.addAction(CompanionIcon("simulate.png"), tr("&Simulate model"),this, SLOT(simulate()),tr("Alt+S"));
|
||||
contextMenu.addAction(CompanionIcon("simulate.png"), tr("&Simulate model"), this, SLOT(simulate()), tr("Alt+S"));
|
||||
}
|
||||
else {
|
||||
// context menu for radio settings
|
||||
contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"),this,SLOT(EditModel()));
|
||||
contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"), this, SLOT(EditModel()));
|
||||
}
|
||||
contextMenu.exec(globalPos);
|
||||
}
|
||||
|
||||
int ModelsListWidget::currentRow() const
|
||||
{
|
||||
return indexOfTopLevelItem(currentItem());
|
||||
}
|
||||
|
||||
void ModelsListWidget::EditModel()
|
||||
{
|
||||
((MdiChild *)parent())->modelEdit();
|
||||
|
@ -120,188 +143,191 @@ void ModelsListWidget::print()
|
|||
|
||||
void ModelsListWidget::setdefault()
|
||||
{
|
||||
if (currentRow()==0) return;
|
||||
unsigned int currModel = currentRow() - 1;
|
||||
if (!radioData->models[currModel].isEmpty() && radioData->generalSettings.currModel != currModel) {
|
||||
radioData->generalSettings.currModel = currModel;
|
||||
refreshList();
|
||||
((MdiChild *)parent())->setModified();
|
||||
if (currentRow() > 0) {
|
||||
unsigned int currModel = currentRow() - 1;
|
||||
if (!radioData->models[currModel].isEmpty() && radioData->generalSettings.currModelIndex != currModel) {
|
||||
radioData->setCurrentModel(currModel);
|
||||
refreshList();
|
||||
((MdiChild *) parent())->setModified();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ModelsListWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
dragStartPosition = event->pos();
|
||||
if (event->button() == Qt::LeftButton)
|
||||
dragStartPosition = event->pos();
|
||||
|
||||
QListWidget::mousePressEvent(event);
|
||||
QTreeWidget::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void ModelsListWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (!(event->buttons() & Qt::LeftButton))
|
||||
return;
|
||||
if ((event->pos() - dragStartPosition).manhattanLength()
|
||||
< QApplication::startDragDistance())
|
||||
return;
|
||||
if (!(event->buttons() & Qt::LeftButton))
|
||||
return;
|
||||
|
||||
QDrag *drag = new QDrag(this);
|
||||
if ((event->pos() - dragStartPosition).manhattanLength() < QApplication::startDragDistance())
|
||||
return;
|
||||
|
||||
QByteArray gmData;
|
||||
doCopy(&gmData);
|
||||
QDrag * drag = new QDrag(this);
|
||||
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData("application/x-companion", gmData);
|
||||
QByteArray gmData;
|
||||
doCopy(&gmData);
|
||||
|
||||
drag->setMimeData(mimeData);
|
||||
QMimeData * mimeData = new QMimeData;
|
||||
mimeData->setData("application/x-companion", gmData);
|
||||
|
||||
//Qt::DropAction dropAction =
|
||||
drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction);
|
||||
drag->setMimeData(mimeData);
|
||||
|
||||
//if(dropAction==Qt::MoveAction)
|
||||
//Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction);
|
||||
|
||||
// QListWidget::mouseMoveEvent(event);
|
||||
//if(dropAction==Qt::MoveAction)
|
||||
|
||||
// QTreeWidget::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void ModelsListWidget::saveSelection()
|
||||
{
|
||||
currentSelection.current_item = currentItem();
|
||||
for (int i=0; i<GetEepromInterface()->getMaxModels()+1; ++i)
|
||||
currentSelection.selected[i] = item(i)->isSelected();
|
||||
for (int i=0; i<GetEepromInterface()->getMaxModels()+1; ++i) {
|
||||
currentSelection.selected[i] = selectionModel()->isSelected(model()->index(i, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void ModelsListWidget::restoreSelection()
|
||||
{
|
||||
setCurrentItem(currentSelection.current_item);
|
||||
for (int i=0; i<GetEepromInterface()->getMaxModels()+1; ++i)
|
||||
item(i)->setSelected(currentSelection.selected[i]);
|
||||
for (int i=0; i<GetEepromInterface()->getMaxModels()+1; ++i) {
|
||||
selectionModel()->select(model()->index(i, 0), currentSelection.selected[i] ? QItemSelectionModel::Select : QItemSelectionModel::Deselect);
|
||||
}
|
||||
}
|
||||
|
||||
void ModelsListWidget::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
if (event->mimeData()->hasFormat("application/x-companion"))
|
||||
{
|
||||
event->acceptProposedAction();
|
||||
saveSelection();
|
||||
}
|
||||
if (event->mimeData()->hasFormat("application/x-companion")) {
|
||||
event->acceptProposedAction();
|
||||
saveSelection();
|
||||
}
|
||||
}
|
||||
|
||||
void ModelsListWidget::dragLeaveEvent(QDragLeaveEvent *)
|
||||
{
|
||||
restoreSelection();
|
||||
restoreSelection();
|
||||
}
|
||||
|
||||
void ModelsListWidget::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
int row=this->indexAt(event->pos()).row();
|
||||
const QMimeData *mimeData = event->mimeData();
|
||||
if (mimeData->hasFormat("application/x-companion"))
|
||||
{
|
||||
QByteArray gmData = mimeData->data("application/x-companion");
|
||||
event->acceptProposedAction();
|
||||
clearSelection();
|
||||
DragDropHeader *header = (DragDropHeader *)gmData.data();
|
||||
if (row >= 0) {
|
||||
if (header->general_settings)
|
||||
item(0)->setSelected(true);
|
||||
for (int i=row, end=std::min(GetEepromInterface()->getMaxModels()+1, row+header->models_count); i<end; i++)
|
||||
item(i)->setSelected(true);
|
||||
}
|
||||
int row = indexAt(event->pos()).row();
|
||||
const QMimeData * mimeData = event->mimeData();
|
||||
if (mimeData->hasFormat("application/x-companion")) {
|
||||
QByteArray gmData = mimeData->data("application/x-companion");
|
||||
event->acceptProposedAction();
|
||||
clearSelection();
|
||||
DragDropHeader * header = (DragDropHeader *)gmData.data();
|
||||
if (row >= 0) {
|
||||
if (header->general_settings)
|
||||
selectionModel()->select(model()->index(0, 0), QItemSelectionModel::Select);
|
||||
for (int i=row, end=std::min(GetEepromInterface()->getMaxModels()+1, row+header->models_count); i<end; i++)
|
||||
selectionModel()->select(model()->index(i, 0), QItemSelectionModel::Select);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModelsListWidget::dropEvent(QDropEvent *event)
|
||||
{
|
||||
int row = this->indexAt(event->pos()).row();
|
||||
if (row < 0)
|
||||
return;
|
||||
int row = this->indexAt(event->pos()).row();
|
||||
if (row < 0)
|
||||
return;
|
||||
|
||||
// QMessageBox::warning(this, tr("Companion"),tr("Index :%1").arg(row));
|
||||
const QMimeData *mimeData = event->mimeData();
|
||||
// QMessageBox::warning(this, tr("Companion"), tr("Index :%1").arg(row));
|
||||
const QMimeData * mimeData = event->mimeData();
|
||||
|
||||
if(mimeData->hasFormat("application/x-companion"))
|
||||
{
|
||||
QByteArray gmData = mimeData->data("application/x-companion");
|
||||
if (event->source() && event->dropAction() == Qt::MoveAction)
|
||||
((ModelsListWidget*)event->source())->doCut(&gmData);
|
||||
doPaste(&gmData, row);
|
||||
clearSelection();
|
||||
setCurrentItem(item(row));
|
||||
DragDropHeader *header = (DragDropHeader *)gmData.data();
|
||||
if (header->general_settings)
|
||||
item(0)->setSelected(true);
|
||||
for (int i=row, end=std::min(GetEepromInterface()->getMaxModels()+1, row+header->models_count); i<end; i++)
|
||||
item(i)->setSelected(true);
|
||||
}
|
||||
event->acceptProposedAction();
|
||||
if (mimeData->hasFormat("application/x-companion")) {
|
||||
QByteArray gmData = mimeData->data("application/x-companion");
|
||||
if (event->source() && event->dropAction() == Qt::MoveAction)
|
||||
((ModelsListWidget*)event->source())->doCut(&gmData);
|
||||
doPaste(&gmData, row);
|
||||
clearSelection();
|
||||
setCurrentItem(topLevelItem(row));
|
||||
DragDropHeader * header = (DragDropHeader *)gmData.data();
|
||||
if (header->general_settings)
|
||||
selectionModel()->select(model()->index(0, 0), QItemSelectionModel::Select);
|
||||
for (int i=row, end=std::min(GetEepromInterface()->getMaxModels()+1, row+header->models_count); i<end; i++)
|
||||
selectionModel()->select(model()->index(i, 0), QItemSelectionModel::Select);
|
||||
}
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
void ModelsListWidget::focusInEvent ( QFocusEvent * event )
|
||||
{
|
||||
QListWidget::focusInEvent(event);
|
||||
QTreeWidget::focusInEvent(event);
|
||||
QPalette palette = this->palette();
|
||||
palette.setColor(QPalette::Active, QPalette::Highlight, active_highlight_color);
|
||||
palette.setColor(QPalette::Inactive, QPalette::Highlight, active_highlight_color);
|
||||
this->setPalette(palette);
|
||||
setPalette(palette);
|
||||
}
|
||||
|
||||
void ModelsListWidget::focusOutEvent ( QFocusEvent * event )
|
||||
{
|
||||
QListWidget::focusOutEvent(event);
|
||||
QTreeWidget::focusOutEvent(event);
|
||||
QPalette palette = this->palette();
|
||||
palette.setColor(QPalette::Active, QPalette::Highlight, palette.color(QPalette::Active, QPalette::Midlight));
|
||||
palette.setColor(QPalette::Inactive, QPalette::Highlight, palette.color(QPalette::Active, QPalette::Midlight));
|
||||
this->setPalette(palette);
|
||||
setPalette(palette);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ModelsListWidget::refreshList()
|
||||
{
|
||||
int current = std::max(0, indexOfTopLevelItem(currentItem()));
|
||||
|
||||
clear();
|
||||
addItem(tr("General Settings"));
|
||||
|
||||
QTreeWidgetItem * item = new QTreeWidgetItem();
|
||||
item->setText(1, tr("General Settings"));
|
||||
addTopLevelItem(item);
|
||||
|
||||
EEPROMInterface * eepromInterface = GetEepromInterface();
|
||||
BoardEnum board = eepromInterface->getBoard();
|
||||
|
||||
// TODO here we calculate the size used by the RLE format, this is clearly not the right place to do that...
|
||||
int availableEEpromSize = eepromInterface->getEEpromSize() - 64; // let's consider fat
|
||||
div_t divresult = div(eepromInterface->getSize(radioData->generalSettings), 15);
|
||||
divresult.quot += (divresult.rem != 0 ? 1 : 0);
|
||||
availableEEpromSize -= divresult.quot*16;
|
||||
|
||||
availableEEpromSize -= 16 * ((eepromInterface->getSize(radioData->generalSettings) + 14) / 15);
|
||||
for (uint8_t i=0; i<GetEepromInterface()->getMaxModels(); i++) {
|
||||
QString item = QString().sprintf("%02d: ", i+1);
|
||||
QTreeWidgetItem * item = new QTreeWidgetItem();
|
||||
item->setTextAlignment(0, Qt::AlignLeft);
|
||||
item->setText(0, QString().sprintf("%02d", i+1));
|
||||
if (!radioData->models[i].isEmpty()) {
|
||||
QString modelName;
|
||||
if (strlen(radioData->models[i].name) > 0)
|
||||
modelName = radioData->models[i].name;
|
||||
else
|
||||
modelName = QString().sprintf("Model%02d", i+1);
|
||||
item += modelName;
|
||||
item->setText(1, modelName);
|
||||
if (!IS_SKY9X(board) && !IS_HORUS(board)) {
|
||||
item += QString(GetCurrentFirmware()->getCapability(ModelName)-modelName.size(), ' ');
|
||||
int size = eepromInterface->getSize(radioData->models[i]);
|
||||
item += QString().sprintf("%5d", size);
|
||||
divresult = div(size, 15);
|
||||
divresult.quot += (divresult.rem != 0 ? 1 : 0);
|
||||
availableEEpromSize -= divresult.quot*16;
|
||||
if (i == radioData->generalSettings.currModel) {
|
||||
// TODO why?
|
||||
availableEEpromSize -= divresult.quot*16;
|
||||
item->setText(2, QString().sprintf("%5d", size));
|
||||
size = 16 * ((size + 14) / 15);
|
||||
availableEEpromSize -= size;
|
||||
if (i == radioData->generalSettings.currModelIndex) {
|
||||
// Because we need this space for a TEMP model each time we have to write it again
|
||||
availableEEpromSize -= size;
|
||||
}
|
||||
}
|
||||
if (i == radioData->generalSettings.currModelIndex) {
|
||||
QFont font = item->font(0);
|
||||
font.setBold(true);
|
||||
for (int j=0; j<columnCount(); j++) {
|
||||
item->setFont(j, font);
|
||||
}
|
||||
}
|
||||
}
|
||||
addItem(item);
|
||||
addTopLevelItem(item);
|
||||
}
|
||||
|
||||
|
||||
if (radioData->generalSettings.currModel < (unsigned int)eepromInterface->getMaxModels()) {
|
||||
QFont f = QFont("Courier New", 12);
|
||||
f.setBold(true);
|
||||
this->item(radioData->generalSettings.currModel+1)->setFont(f);
|
||||
}
|
||||
selectionModel()->select(model()->index(current, 0), QItemSelectionModel::Current | QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||
setCurrentItem(topLevelItem(current));
|
||||
|
||||
if (!IS_SKY9X(board) && !IS_HORUS(board)) {
|
||||
((MdiChild*)parent())->setEEpromAvail((availableEEpromSize/16)*15);
|
||||
|
@ -310,129 +336,140 @@ void ModelsListWidget::refreshList()
|
|||
|
||||
void ModelsListWidget::cut()
|
||||
{
|
||||
copy();
|
||||
deleteSelected(false);
|
||||
copy();
|
||||
deleteSelected(false);
|
||||
}
|
||||
|
||||
void ModelsListWidget::confirmDelete() {
|
||||
deleteSelected(true);
|
||||
void ModelsListWidget::confirmDelete()
|
||||
{
|
||||
deleteSelected(true);
|
||||
}
|
||||
|
||||
|
||||
void ModelsListWidget::deleteSelected(bool ask=true)
|
||||
{
|
||||
bool isModel=false;
|
||||
unsigned int selModel;
|
||||
QMessageBox::StandardButton ret = QMessageBox::Yes;
|
||||
if(ask) {
|
||||
foreach(QModelIndex index, this->selectionModel()->selectedIndexes()) {
|
||||
if (index.row()>0 && !radioData->models[index.row()-1].isEmpty()) {
|
||||
isModel=true;
|
||||
selModel=index.row()-1;
|
||||
}
|
||||
bool isModel=false;
|
||||
unsigned int selModel;
|
||||
QMessageBox::StandardButton ret = QMessageBox::Yes;
|
||||
if (ask) {
|
||||
foreach (QModelIndex index, this->selectionModel()->selectedIndexes()) {
|
||||
if (index.row()>0 && !radioData->models[index.row()-1].isEmpty()) {
|
||||
isModel = true;
|
||||
selModel=index.row()-1;
|
||||
}
|
||||
if (isModel==true) {
|
||||
if (radioData->generalSettings.currModel != selModel) {
|
||||
ret = QMessageBox::warning(this, "Companion", tr("Delete Selected Models?"), QMessageBox::Yes | QMessageBox::No);
|
||||
} else {
|
||||
ret = QMessageBox::warning(this, "Companion", tr("Cannot delete default model."), QMessageBox::Ok);
|
||||
}
|
||||
if (isModel) {
|
||||
if (radioData->generalSettings.currModelIndex != selModel) {
|
||||
ret = QMessageBox::warning(this, "Companion", tr("Delete Selected Models?"), QMessageBox::Yes | QMessageBox::No);
|
||||
}
|
||||
else {
|
||||
ret = QMessageBox::warning(this, "Companion", tr("Cannot delete default model."), QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret == QMessageBox::Yes) {
|
||||
foreach (QModelIndex index, this->selectionModel()->selectedIndexes()) {
|
||||
if (index.row() > 0 && radioData->generalSettings.currModelIndex != (unsigned int)(index.row()-1)) {
|
||||
radioData->models[index.row()-1].clear();
|
||||
((MdiChild *)parent())->setModified();
|
||||
}
|
||||
else if (index.row()>0) {
|
||||
if (ask) {
|
||||
QMessageBox::warning(this, "Companion", tr("Cannot delete default model."), QMessageBox::Ok);
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(this, "Companion", tr("Cannot cut default model."), QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret == QMessageBox::Yes) {
|
||||
foreach(QModelIndex index, this->selectionModel()->selectedIndexes()) {
|
||||
if (index.row()>0 && radioData->generalSettings.currModel!=(unsigned int)(index.row()-1)) {
|
||||
radioData->models[index.row()-1].clear();
|
||||
((MdiChild *)parent())->setModified();
|
||||
} else if (index.row()>0) {
|
||||
if (ask) {
|
||||
ret = QMessageBox::warning(this, "Companion", tr("Cannot delete default model."), QMessageBox::Ok);
|
||||
} else {
|
||||
ret = QMessageBox::warning(this, "Companion", tr("Cannot cut default model."), QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModelsListWidget::doCut(QByteArray *gmData)
|
||||
void ModelsListWidget::doCut(QByteArray * gmData)
|
||||
{
|
||||
bool modified=false;
|
||||
DragDropHeader *header = (DragDropHeader *)gmData->data();
|
||||
for (int i=0; i<header->models_count; i++) {
|
||||
if (radioData->generalSettings.currModel != (unsigned int)header->models[i]-1) {
|
||||
radioData->models[header->models[i]-1].clear();
|
||||
modified=true;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
((MdiChild *)parent())->setModified();
|
||||
bool modified = false;
|
||||
DragDropHeader * header = (DragDropHeader *)gmData->data();
|
||||
for (int i=0; i<header->models_count; i++) {
|
||||
if (radioData->generalSettings.currModelIndex != (unsigned int)header->models[i]-1) {
|
||||
radioData->models[header->models[i]-1].clear();
|
||||
modified=true;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
((MdiChild *)parent())->setModified();
|
||||
}
|
||||
}
|
||||
|
||||
void ModelsListWidget::doCopy(QByteArray *gmData)
|
||||
void ModelsListWidget::doCopy(QByteArray * gmData)
|
||||
{
|
||||
DragDropHeader header;
|
||||
DragDropHeader header;
|
||||
|
||||
foreach(QModelIndex index, this->selectionModel()->selectedIndexes())
|
||||
{
|
||||
char row = index.row();
|
||||
if(!row) {
|
||||
header.general_settings = true;
|
||||
gmData->append('G');
|
||||
gmData->append((char*)&radioData->generalSettings, sizeof(GeneralSettings));
|
||||
}
|
||||
else {
|
||||
header.models[header.models_count++] = row;
|
||||
gmData->append('M');
|
||||
gmData->append((char*)&radioData->models[row-1], sizeof(ModelData));
|
||||
}
|
||||
qDebug() << selectionModel()->selectedIndexes();
|
||||
foreach(QModelIndex index, selectionModel()->selectedIndexes()) {
|
||||
char column = index.column();
|
||||
if (column == 0) {
|
||||
char row = index.row();
|
||||
if (!row) {
|
||||
header.general_settings = true;
|
||||
gmData->append('G');
|
||||
gmData->append((char *) &radioData->generalSettings, sizeof(GeneralSettings));
|
||||
}
|
||||
else {
|
||||
header.models[header.models_count++] = row;
|
||||
gmData->append('M');
|
||||
gmData->append((char *) &radioData->models[row - 1], sizeof(ModelData));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gmData->prepend((char *)&header, sizeof(header));
|
||||
gmData->prepend((char *)&header, sizeof(header));
|
||||
}
|
||||
|
||||
void ModelsListWidget::copy()
|
||||
{
|
||||
QByteArray gmData;
|
||||
doCopy(&gmData);
|
||||
QByteArray gmData;
|
||||
doCopy(&gmData);
|
||||
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData("application/x-companion", gmData);
|
||||
QMimeData * mimeData = new QMimeData;
|
||||
mimeData->setData("application/x-companion", gmData);
|
||||
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
clipboard->setMimeData(mimeData,QClipboard::Clipboard);
|
||||
QClipboard * clipboard = QApplication::clipboard();
|
||||
clipboard->setMimeData(mimeData, QClipboard::Clipboard);
|
||||
}
|
||||
|
||||
void ModelsListWidget::doPaste(QByteArray *gmData, int index)
|
||||
void ModelsListWidget::doPaste(QByteArray * gmData, int index)
|
||||
{
|
||||
//QByteArray gmData = mimeD->data("application/x-companion");
|
||||
char *gData = gmData->data()+sizeof(DragDropHeader);//new char[gmData.size() + 1];
|
||||
// QByteArray gmData = mimeD->data("application/x-companion");
|
||||
char * gData = gmData->data() + sizeof(DragDropHeader); // new char[gmData.size() + 1];
|
||||
int i = sizeof(DragDropHeader);
|
||||
int id = index;
|
||||
int ret,modified=0;
|
||||
int ret, modified=0;
|
||||
if(!id) id++;
|
||||
|
||||
while((i<gmData->size()) && (id<=GetEepromInterface()->getMaxModels())) {
|
||||
while (i<gmData->size() && id<=GetEepromInterface()->getMaxModels()) {
|
||||
qDebug() << i << gmData->size();
|
||||
char c = *gData;
|
||||
i++;
|
||||
gData++;
|
||||
if(c=='G') { //General settings
|
||||
if (c == 'G') {
|
||||
// General settings
|
||||
ret = QMessageBox::question(this, "Companion", tr("Do you want to overwrite radio general settings?"),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if (ret == QMessageBox::Yes) {
|
||||
radioData->generalSettings = *((GeneralSettings *)gData);
|
||||
modified=1;
|
||||
modified = 1;
|
||||
}
|
||||
gData += sizeof(GeneralSettings);
|
||||
i += sizeof(GeneralSettings);
|
||||
}
|
||||
else { //model data
|
||||
else {
|
||||
// Model data
|
||||
if (!radioData->models[id-1].isEmpty()) {
|
||||
ret = QMessageBox::question(this, "Companion", tr("You are pasting on an not empty model, are you sure?"),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if (ret == QMessageBox::Yes) {
|
||||
radioData->models[id-1] = *((ModelData *)gData);
|
||||
strcpy(radioData->models[id-1].filename, radioData->getNextModelFilename().toStdString().c_str());
|
||||
gData += sizeof(ModelData);
|
||||
i += sizeof(ModelData);
|
||||
id++;
|
||||
|
@ -446,6 +483,7 @@ void ModelsListWidget::doPaste(QByteArray *gmData, int index)
|
|||
}
|
||||
else {
|
||||
radioData->models[id-1] = *((ModelData *)gData);
|
||||
strcpy(radioData->models[id-1].filename, radioData->getNextModelFilename().toStdString().c_str());
|
||||
gData += sizeof(ModelData);
|
||||
i += sizeof(ModelData);
|
||||
id++;
|
||||
|
@ -460,92 +498,85 @@ void ModelsListWidget::doPaste(QByteArray *gmData, int index)
|
|||
|
||||
bool ModelsListWidget::hasPasteData()
|
||||
{
|
||||
const QClipboard *clipboard = QApplication::clipboard();
|
||||
const QMimeData *mimeData = clipboard->mimeData();
|
||||
const QClipboard *clipboard = QApplication::clipboard();
|
||||
const QMimeData *mimeData = clipboard->mimeData();
|
||||
|
||||
return mimeData->hasFormat("application/x-companion");
|
||||
return mimeData->hasFormat("application/x-companion");
|
||||
}
|
||||
|
||||
void ModelsListWidget::paste()
|
||||
{
|
||||
if (hasPasteData()) {
|
||||
const QClipboard *clipboard = QApplication::clipboard();
|
||||
const QMimeData *mimeData = clipboard->mimeData();
|
||||
if (hasPasteData()) {
|
||||
const QClipboard * clipboard = QApplication::clipboard();
|
||||
const QMimeData * mimeData = clipboard->mimeData();
|
||||
|
||||
QByteArray gmData = mimeData->data("application/x-companion");
|
||||
doPaste(&gmData,this->currentRow());
|
||||
}
|
||||
QByteArray gmData = mimeData->data("application/x-companion");
|
||||
doPaste(&gmData, currentRow());
|
||||
}
|
||||
}
|
||||
|
||||
void ModelsListWidget::duplicate()
|
||||
{
|
||||
int i = this->currentRow();
|
||||
if(i && i<GetEepromInterface()->getMaxModels())
|
||||
{
|
||||
ModelData *model = &radioData->models[i-1];
|
||||
while(i<GetEepromInterface()->getMaxModels()) {
|
||||
if (radioData->models[i].isEmpty()) {
|
||||
radioData->models[i] = *model;
|
||||
((MdiChild *)parent())->setModified();
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (i==GetEepromInterface()->getMaxModels()) {
|
||||
QMessageBox::warning(this, "Companion", tr("No free slot available, cannot duplicate"), QMessageBox::Ok);
|
||||
}
|
||||
int i = this->currentRow();
|
||||
if (i && i<GetEepromInterface()->getMaxModels()) {
|
||||
ModelData * model = &radioData->models[i-1];
|
||||
while (i<GetEepromInterface()->getMaxModels()) {
|
||||
if (radioData->models[i].isEmpty()) {
|
||||
radioData->models[i] = *model;
|
||||
strcpy(radioData->models[i].filename, radioData->getNextModelFilename().toStdString().c_str());
|
||||
((MdiChild *)parent())->setModified();
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (i==GetEepromInterface()->getMaxModels()) {
|
||||
QMessageBox::warning(this, "Companion", tr("No free slot available, cannot duplicate"), QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ModelsListWidget::hasSelection()
|
||||
{
|
||||
return (this->selectionModel()->hasSelection());
|
||||
return (this->selectionModel()->hasSelection());
|
||||
}
|
||||
|
||||
void ModelsListWidget::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if(event->matches(QKeySequence::Delete))
|
||||
{
|
||||
deleteSelected();
|
||||
return;
|
||||
}
|
||||
if (event->matches(QKeySequence::Delete)) {
|
||||
deleteSelected();
|
||||
return;
|
||||
}
|
||||
|
||||
if(event->matches(QKeySequence::Cut))
|
||||
{
|
||||
cut();
|
||||
return;
|
||||
}
|
||||
if (event->matches(QKeySequence::Cut)) {
|
||||
cut();
|
||||
return;
|
||||
}
|
||||
|
||||
if(event->matches(QKeySequence::Copy))
|
||||
{
|
||||
copy();
|
||||
return;
|
||||
}
|
||||
if (event->matches(QKeySequence::Copy)) {
|
||||
copy();
|
||||
return;
|
||||
}
|
||||
|
||||
if(event->matches(QKeySequence::Paste))
|
||||
{
|
||||
paste();
|
||||
return;
|
||||
}
|
||||
if (event->matches(QKeySequence::Paste)) {
|
||||
paste();
|
||||
return;
|
||||
}
|
||||
|
||||
if(event->matches(QKeySequence::Underline))
|
||||
{
|
||||
duplicate();
|
||||
return;
|
||||
}
|
||||
if (event->matches(QKeySequence::Underline)) {
|
||||
duplicate();
|
||||
return;
|
||||
}
|
||||
|
||||
QListWidget::keyPressEvent(event);//run the standard event in case we didn't catch an action
|
||||
QTreeWidget::keyPressEvent(event);//run the standard event in case we didn't catch an action
|
||||
}
|
||||
|
||||
void ModelsListWidget::viableModelSelected(int idx)
|
||||
void ModelsListWidget::onCurrentItemChanged(QTreeWidgetItem * current, QTreeWidgetItem *)
|
||||
{
|
||||
int index = indexOfTopLevelItem(current);
|
||||
if (!isVisible())
|
||||
((MdiChild*)parent())->viableModelSelected(false);
|
||||
else if (idx<1)
|
||||
else if (index<1)
|
||||
((MdiChild*)parent())->viableModelSelected(false);
|
||||
else
|
||||
((MdiChild*)parent())->viableModelSelected(!radioData->models[currentRow()-1].isEmpty());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -26,20 +26,21 @@
|
|||
|
||||
struct CurrentSelection
|
||||
{
|
||||
QListWidgetItem *current_item;
|
||||
QTreeWidgetItem * current_item;
|
||||
bool selected[CPN_MAX_MODELS+1];
|
||||
};
|
||||
|
||||
class ModelsListWidget : public QListWidget
|
||||
class ModelsListWidget : public QTreeWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ModelsListWidget(QWidget *parent = 0);
|
||||
ModelsListWidget(QWidget * parent = 0);
|
||||
|
||||
bool hasSelection();
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
void keyPressEvent(QKeyEvent * event);
|
||||
bool hasPasteData();
|
||||
int currentRow() const;
|
||||
|
||||
protected:
|
||||
void dropEvent(QDropEvent *event);
|
||||
|
@ -69,7 +70,7 @@ public slots:
|
|||
void setdefault();
|
||||
void deleteSelected(bool ask);
|
||||
void confirmDelete();
|
||||
void viableModelSelected(int idx);
|
||||
void onCurrentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *);
|
||||
|
||||
private:
|
||||
void doCut(QByteArray *gmData);
|
||||
|
|
|
@ -72,8 +72,7 @@ int StorageSdcard::readOtx(const QString & path)
|
|||
|
||||
// go trough all files in an archive
|
||||
QRegularExpression regexModel("MODELS/\\w+.bin", QRegularExpression::CaseInsensitiveOption);
|
||||
for (unsigned int i = 0; i < mz_zip_reader_get_num_files(&zip_archive); i++)
|
||||
{
|
||||
for (unsigned int i = 0; i < mz_zip_reader_get_num_files(&zip_archive); i++) {
|
||||
mz_zip_archive_file_stat file_stat;
|
||||
if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) {
|
||||
lastErrorMessage = QObject::tr("mz_zip_reader_file_stat() failed!");
|
||||
|
@ -117,9 +116,9 @@ int StorageSdcard::readOtx(const QString & path)
|
|||
else {
|
||||
qDebug() << "Unknown file " << filename;
|
||||
}
|
||||
|
||||
}
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ void saveRadioSettings(GeneralSettings & settings, global_settings & gs)
|
|||
Calibration p3Calib(settings.calibMid[6], settings.calibSpanNeg[6], settings.calibSpanPos[6]);
|
||||
gs.calibration(calibration(rudderCalib, throttleCalib, aileronCalib, elevatorCalib, p1Calib, p2Calib, p3Calib));
|
||||
|
||||
// TODO BSS settings.currModel;
|
||||
// TODO BSS settings.currModelIndex;
|
||||
gs.contrast(settings.contrast);
|
||||
gs.battery(battery(settings.txVoltageCalibration, settings.vBatWarn));
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue