diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index 49e67e3fe..b4a76ad74 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -116,10 +116,10 @@ void MdiChild::showModelsListContextMenu(const QPoint & pos) QModelIndex modelIndex = ui->modelsList->indexAt(pos); QPoint globalPos = ui->modelsList->mapToGlobal(pos); QMenu contextMenu; + const QClipboard * clipboard = QApplication::clipboard(); + const QMimeData * mimeData = clipboard->mimeData(); + bool hasData = mimeData->hasFormat("application/x-companion"); if (modelsListModel->getModelIndex(modelIndex) >= 0) { - const QClipboard * clipboard = QApplication::clipboard(); - const QMimeData * mimeData = clipboard->mimeData(); - bool hasData = mimeData->hasFormat("application/x-companion"); contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"), this, SLOT(modelEdit())); contextMenu.addAction(CompanionIcon("open.png"), tr("&Restore from backup"), this, SLOT(loadBackup())); contextMenu.addAction(CompanionIcon("wizard.png"), tr("&Model Wizard"), this, SLOT(wizardEdit())); @@ -139,6 +139,7 @@ void MdiChild::showModelsListContextMenu(const QPoint & pos) else if (IS_HORUS(firmware->getBoard())) { if (modelsListModel->getCategoryIndex(modelIndex) >= 0) { contextMenu.addAction(CompanionIcon("add.png"), tr("&Add model"), this, SLOT(modelAdd())); + contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"), this, SLOT(paste()), tr("Ctrl+V"))->setEnabled(hasData); contextMenu.addSeparator(); contextMenu.addAction(CompanionIcon("rename.png"), tr("&Rename category"), this, SLOT(categoryRename())); contextMenu.addAction(CompanionIcon("delete.png"), tr("&Delete category"), this, SLOT(categoryDelete())); @@ -235,11 +236,13 @@ void MdiChild::doCopy(QByteArray * gmData) // gmData->append((char *) &radioData.generalSettings, sizeof(GeneralSettings)); } -void MdiChild::doPaste(QByteArray * gmData, int index) +void MdiChild::doPaste(QByteArray * gmData, int modelIdx, int categoryIdx) { char * gData = gmData->data(); bool modified = false; int size = 0; + bool pasteIntoCategory = modelIdx == -1; + int dstCategory; while (size < gmData->size()) { char c = *gData++; @@ -256,21 +259,35 @@ void MdiChild::doPaste(QByteArray * gmData, int index) size += sizeof(GeneralSettings); } else if (c == 'M') { - if (firmware->getCapability(Models) == 0 || index < firmware->getCapability(Models)) { + if (firmware->getCapability(Models) == 0 || modelIdx < firmware->getCapability(Models)) { // Model data int ret = QMessageBox::Yes; - if (!radioData.models[index].isEmpty()) { + if (pasteIntoCategory) { + // We're pasting into a category, so create a stubbed out model then + // use the regular paste-onto-model code path + ModelData blank; + blank.used = false; + blank.category = categoryIdx; + radioData.models.push_back(blank); + modelIdx = radioData.models.size() - 1; + } + + if (!radioData.models[modelIdx].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[index] = *((ModelData *)gData); - strcpy(radioData.models[index].filename, radioData.getNextModelFilename().toStdString().c_str()); + if (ret == QMessageBox::Yes) { + // Save and restore the category index, so a user can copy/paste + // across categories + dstCategory = radioData.models[modelIdx].category; + radioData.models[modelIdx] = *((ModelData *)gData); + radioData.models[modelIdx].category = dstCategory; + strcpy(radioData.models[modelIdx].filename, radioData.getNextModelFilename().toStdString().c_str()); modified = 1; } gData += sizeof(ModelData); size += sizeof(ModelData); - index++; + modelIdx++; } } else { @@ -289,7 +306,7 @@ void MdiChild::paste() const QClipboard * clipboard = QApplication::clipboard(); const QMimeData * mimeData = clipboard->mimeData(); QByteArray gmData = mimeData->data("application/x-companion"); - doPaste(&gmData, getCurrentRow()); + doPaste(&gmData, getCurrentModel(), getCurrentCategory()); } } @@ -447,7 +464,7 @@ void MdiChild::modelAdd() void MdiChild::modelEdit() { - int row = getCurrentRow(); + int row = getCurrentModel(); QApplication::setOverrideCursor(Qt::WaitCursor); checkAndInitModel(row); ModelData & model = radioData.models[row]; @@ -465,7 +482,7 @@ void MdiChild::modelEdit() void MdiChild::setDefault() { - int row = getCurrentRow(); + int row = getCurrentModel(); if (!radioData.models[row].isEmpty() && radioData.generalSettings.currModelIndex != (unsigned)row) { radioData.setCurrentModel(row); setModified(); @@ -474,7 +491,7 @@ void MdiChild::setDefault() void MdiChild::wizardEdit() { - int row = getCurrentRow(); + int row = getCurrentModel(); checkAndInitModel(row); WizardDialog * wizard = new WizardDialog(radioData.generalSettings, row+1, this); wizard->exec(); @@ -486,7 +503,7 @@ void MdiChild::wizardEdit() void MdiChild::openModelEditWindow() { - int row = getCurrentRow(); + int row = getCurrentModel(); if (row >= 0) { ModelData & model = radioData.models[row]; if (model.isEmpty() && g.useWizard()) { @@ -682,7 +699,7 @@ void MdiChild::radioSimulate() void MdiChild::modelSimulate() { - startSimulation(this, radioData, getCurrentRow()); + startSimulation(this, radioData, getCurrentModel()); } void MdiChild::print(int model, const QString & filename) @@ -693,8 +710,8 @@ void MdiChild::print(int model, const QString & filename) if (model>=0 && !filename.isEmpty()) { pd = new PrintDialog(this, firmware, radioData.generalSettings, radioData.models[model], filename); } - else if (getCurrentRow()) { - pd = new PrintDialog(this, firmware, radioData.generalSettings, radioData.models[getCurrentRow()]); + else if (getCurrentModel()) { + pd = new PrintDialog(this, firmware, radioData.generalSettings, radioData.models[getCurrentModel()]); } if (pd) { @@ -708,11 +725,16 @@ void MdiChild::viableModelSelected(bool viable) emit copyAvailable(viable); } -int MdiChild::getCurrentRow() const +int MdiChild::getCurrentModel() const { return modelsListModel->getModelIndex(ui->modelsList->currentIndex()); } +int MdiChild::getCurrentCategory() const +{ + return modelsListModel->getCategoryIndex(ui->modelsList->currentIndex()); +} + bool MdiChild::loadBackup() { QString fileName = QFileDialog::getOpenFileName(this, tr("Open backup Models and Settings file"), g.eepromDir(), tr(EEPROM_FILES_FILTER)); @@ -725,7 +747,7 @@ bool MdiChild::loadBackup() return false; } - // TODO int index = getCurrentRow(); + // TODO int index = getCurrentModel(); int eeprom_size = file.size(); if (!file.open(QFile::ReadOnly)) { //reading binary file - TODO HEX support diff --git a/companion/src/mdichild.h b/companion/src/mdichild.h index c4248327d..a39ffac81 100644 --- a/companion/src/mdichild.h +++ b/companion/src/mdichild.h @@ -51,7 +51,8 @@ class MdiChild : public QWidget QString userFriendlyCurrentFile() const; QString currentFile() const { return curFile; } void viableModelSelected(bool viable); - int getCurrentRow() const; + int getCurrentModel() const; + int getCurrentCategory() const; void refresh(bool expand=false); void keyPressEvent(QKeyEvent * event); @@ -100,7 +101,7 @@ class MdiChild : public QWidget bool maybeSave(); void setCurrentFile(const QString & fileName); void doCopy(QByteArray * gmData); - void doPaste(QByteArray * gmData, int index); + void doPaste(QByteArray * gmData, int modelIdx, int categoryIdx); void initModelsList(); MainWindow * parent;