Issue #4224: Paste into and across categories in Companion (#4371)

* Issue #4224. Allow pasting models into and across categories.
* Issue #4224: Add "Paste" to category conext menu.
This commit is contained in:
Kelly Byrd
2017-02-02 09:05:26 +01:00
committed by Damjan Adamic
parent e7d7f9df95
commit bdd62104c1
2 changed files with 45 additions and 22 deletions
+42 -20
View File
@@ -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
+3 -2
View File
@@ -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;