From 8040f48974d88c6d30dff720a2ffb27e0cf54814 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sun, 23 Sep 2018 16:13:37 +0200 Subject: Integrate channel map into file list in instrument editor. --- src/filelist.cc | 450 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 340 insertions(+), 110 deletions(-) (limited to 'src/filelist.cc') diff --git a/src/filelist.cc b/src/filelist.cc index 21b843e..c9e6a8a 100644 --- a/src/filelist.cc +++ b/src/filelist.cc @@ -35,35 +35,323 @@ #include "itemeditor.h" #include "project.h" -FileList::FileList(Instrument& instrument) - : instrument(instrument) +#include +#include + +#include + +#include +#include +#include +#include +#include + +class ChannelMapDeligate + : public QStyledItemDelegate { - setContextMenuPolicy(Qt::CustomContextMenu); +public: + ChannelMapDeligate(Instrument& instrument) + : instrument(instrument) + { + } - connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), - this, SLOT(popupMenu(const QPoint&))); + QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const override + { + // Name: + if(index.column() == 1) + { + auto w = new QLineEdit(parent); + return w; + } + + // Channel Map ID: + if(index.column() == 2) + { + auto w = new QComboBox(parent); + w->addItem(tr(""), -1); + auto channel_ids = instrument.getProject().getChannelList(); + for(auto channel_id : channel_ids) + { + const auto& channel = instrument.getProject().getChannel(channel_id); + w->addItem(channel.getChannelName(), channel.getId()); + } + return w; + } + + return QStyledItemDelegate::createEditor(parent, option, index); + } - connect(this, SIGNAL(itemDoubleClicked(QListWidgetItem*)), - this, SLOT(selectionChanged(QListWidgetItem*))); + void setEditorData(QWidget *editor, const QModelIndex &index) const override + { + // Name: + if(index.column() == 1) + { + auto w = static_cast(editor); + auto s = index.data(Qt::EditRole).toString(); + w->setText(s); + } + + // Channel Map ID: + if(index.column() == 2) + { + auto w = static_cast(editor); + auto i = w->findData(index.data(Qt::EditRole).toInt()); + w->setCurrentIndex(i); + } +} - createMenus(); + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const override + { // Name: + if(index.column() == 1) + { + model->setData(index, static_cast(editor)->text(), + Qt::EditRole); + } + + // Channel Map ID: + if(index.column() == 2) + { + model->setData(index, static_cast(editor)->currentData(), + Qt::EditRole); + } + } + +// void paint(QPainter * painter, +// const QStyleOptionViewItem & option, +// const QModelIndex & index ) const override +// { +// if(index.column() == 0) +// { +// painter->drawRect(option.rect); +// return; +// } +// QStyledItemDelegate::paint(painter, option, index); +// } + +private: + Instrument& instrument; +}; + +class FileDataModel + : public QAbstractItemModel +{ +public: + FileDataModel(Instrument& instrument) + : instrument(instrument) + { + } + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override + { + if(!hasIndex(row, column, parent)) + { + return QModelIndex(); + } + + auto audiofile_ids = instrument.getAudioFileList(); + if(!parent.isValid()) + { + if(row < audiofile_ids.size()) + { + return createIndex(row, column, &instrument); + } + else + { + return QModelIndex(); // row is out of bounds. + } + } + + return QModelIndex(); + } + + QModelIndex parent(const QModelIndex &index) const override + { + return QModelIndex(); // no parent + } - // Load files into list: - auto master_file = instrument.getMasterFile(); - auto files = instrument.getFileList(); - for(auto file : files) + int rowCount(const QModelIndex &parent = QModelIndex()) const override { - auto item = new QListWidgetItem(); - //item->setIcon(QPixmap(":icons/instrument.png")); - setItemFile(item, file.first); - setItemName(item, file.second); - setItemMaster(item, file.first == master_file); - addItem(item); + if(parent.column() > 0) // only return row count on first column + { + return 0; + } + + if(!parent.isValid()) + { + auto audiofile_ids = instrument.getAudioFileList(); + return audiofile_ids.size(); // root level + } + + return 0; // no children } + + int columnCount(const QModelIndex &parent = QModelIndex()) const override + { + return 4; + } + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override + { + if(!index.isValid()) + { + return QVariant(); + } + + auto audiofile_ids = instrument.getAudioFileList(); + + auto audiofile_id = audiofile_ids.begin() + index.row(); + const auto& audiofile = instrument.getAudioFile(*audiofile_id); + + if(role == Qt::DecorationRole ) + { + if(index.column() == 0) + { + if(audiofile.getAbsoluteFile() == instrument.getMasterFile()) + { + return QPixmap(":/icons/master.png"); + } + else + { + return QPixmap(":/icons/file.png"); + } + } + } + + if(role == Qt::DisplayRole) + { + switch(index.column()) + { + case 1: return audiofile.getName(); + case 2: + { + auto channelMapId = audiofile.getChannelMapId(); + if(channelMapId == -1) + { + return tr(""); + } + return instrument.getProject().getChannel(channelMapId).getChannelName(); + } + case 3: return audiofile.getFile(); + default: return QVariant(); + } + } + else if(role == Qt::EditRole) + { + switch(index.column()) + { + case 1: return audiofile.getName(); + case 2: return audiofile.getChannelMapId(); + case 3: return audiofile.getFile(); + default: return QVariant(); + } + } + else + + { + return QVariant(); + } + } + + QVariant headerData(int section, Qt::Orientation orientation, int role) const override + { + if(orientation == Qt::Horizontal && role == Qt::DisplayRole) + { + switch(section) + { + case 0: return tr("M"); + case 1: return tr("Name"); + case 2: return tr("Kit Channel"); + case 3: return tr("Filename"); + default: return QVariant(); + } + } + + return QVariant(); + } + + Qt::ItemFlags flags(const QModelIndex &index) const override + { + if(!index.isValid()) + { + return 0; + } + + switch(index.column()) + { + case 0: + return QAbstractItemModel::flags(index); + case 1: + case 2: + return Qt::ItemIsEditable | QAbstractItemModel::flags(index); + case 3: + return QAbstractItemModel::flags(index); // only column 1 is editable + } + } + + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole) override + { + auto audiofile_ids = instrument.getAudioFileList(); + + if(index.row() > audiofile_ids.size() || index.column() > 2) + { + return false; + } + + auto audiofile_id = audiofile_ids.begin() + index.row(); + auto& audiofile = instrument.getAudioFile(*audiofile_id); + + switch(index.column()) + { + case 0: break; + case 1: audiofile.setName(value.toString()); break; + case 2: audiofile.setChannelMapId(value.toInt()); break; + default: break; + } + + return true; + } + + void refresh() + { + beginResetModel(); + endResetModel(); + } + +private: + Instrument& instrument; +}; + +FileList::FileList(Instrument& instrument) + : instrument(instrument) +{ + model = new FileDataModel(instrument); + setModel(model); + setItemDelegate(new ChannelMapDeligate(instrument)); + setEditTriggers(QAbstractItemView::AllEditTriggers); // show list on click + + setContextMenuPolicy(Qt::CustomContextMenu); // enable context menu + connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), + this, SLOT(onCustomContextMenu(const QPoint &))); + setRootIsDecorated(false); + header()->resizeSection(0, 24); + + connect(this, SIGNAL(doubleClicked(const QModelIndex&)), + this, SLOT(selectionChanged(const QModelIndex&))); + + createMenus(); } void FileList::addFiles() { + auto root = instrument.getProject().getRawFileRoot(); + if(path.isEmpty()) + { + path = root; + } + QStringList files = QFileDialog::getOpenFileNames(this, tr("Open file"), path, tr("Audio Files (*.wav)")); @@ -74,38 +362,36 @@ void FileList::addFiles() QFileInfo fi(file); QString name = fi.baseName(); path = fi.absolutePath(); + if(root == file.left(root.length())) + { + file = file.mid(root.length() + 1); + } - QListWidgetItem* item = new QListWidgetItem(); - setItemFile(item, file); - setItemName(item, name); - setItemMaster(item, false); - addItem(item); - - emit fileAdded(file, name); + auto id = instrument.createAudioFile(); + auto& audiofile = instrument.getAudioFile(id); + audiofile.setName(name); + audiofile.setFile(file); + audiofile.setChannelMapId(-1); i++; } + + model->refresh(); } -void FileList::setMasterFile(QListWidgetItem* i) +void FileList::selectionChanged(const QModelIndex &index) { - QString filename = itemFile(i); - - for(int idx = 0; idx < count(); idx++) - { - setItemMaster(item(idx), false); - } + auto audiofile_ids = instrument.getAudioFileList(); + auto audiofile_id = audiofile_ids.begin() + index.row(); + const auto& audiofile = instrument.getAudioFile(*audiofile_id); - setItemMaster(i, true); - emit masterFileChanged(filename); -} + instrument.setMasterFile(audiofile.getFile()); -void FileList::selectionChanged(QListWidgetItem* i) -{ - setMasterFile(i); + emit masterFileChanged(audiofile.getAbsoluteFile()); + //setMasterFile(i); + model->refresh(); } - void FileList::createMenus() { menu = new QMenu(); @@ -113,9 +399,6 @@ void FileList::createMenus() setMasterAction = new QAction(tr("Set as Master (dbl-click)"), this); connect(setMasterAction, SIGNAL(triggered()), this, SLOT(setMaster())); - editAction = new QAction(tr("Edit name"), this); - connect(editAction, SIGNAL(triggered()), this, SLOT(editName())); - removeAction = new QAction(tr("Remove"), this); connect(removeAction, SIGNAL(triggered()), this, SLOT(removeFile())); @@ -123,96 +406,43 @@ void FileList::createMenus() connect(removeAllAction, SIGNAL(triggered()), this, SLOT(removeAllFiles())); menu->addAction(setMasterAction); - menu->addAction(editAction); menu->addAction(removeAction); menu->addSeparator(); menu->addAction(removeAllAction); - } -void FileList::popupMenu(const QPoint& pos) +void FileList::onCustomContextMenu(const QPoint &point) { - activeItem = itemAt(pos); - if(!activeItem) + QModelIndex index = indexAt(point); + if(index.isValid()) { - return; + menu->popup(viewport()->mapToGlobal(point)); } - menu->popup(mapToGlobal(pos)); } void FileList::setMaster() { - setMasterFile(activeItem); +// setMasterFile(activeItem); } void FileList::removeFile() { - QString file = itemFile(activeItem); - QString name = itemName(activeItem); - - printf("Removing: %s\n", file.toStdString().c_str()); - delete activeItem;//takeItem(row(activeItem)); - activeItem = NULL; - setCurrentRow(-1); + auto audiofile_ids = instrument.getAudioFileList(); + auto audiofile_id = audiofile_ids.begin() + currentIndex().row(); + instrument.deleteAudioFile(*audiofile_id); - emit fileRemoved(file, name); + //emit fileRemoved(file, name); } void FileList::removeAllFiles() { - activeItem = NULL; - - clear(); - - emit allFilesRemoved(); -} - -void FileList::editName() -{ - ItemEditor* e = new ItemEditor(activeItem, itemName(activeItem)); - connect(e, SIGNAL(updateItem(QListWidgetItem*, QString)), - this, SLOT(setItemName(QListWidgetItem*, QString))); -} - - -// Item utility functions. -QString FileList::itemFile(QListWidgetItem* i) -{ - return i->data(Qt::ToolTipRole).toString(); -} - -void FileList::setItemFile(QListWidgetItem* i, QString file) -{ - i->setData(Qt::ToolTipRole, file); - i->setData(Qt::DisplayRole, itemName(i) + "\t" + file); -} - -QString FileList::itemName(QListWidgetItem* i) -{ - return i->data(Qt::UserRole).toString(); -} - -void FileList::setItemName(QListWidgetItem* i, QString name) -{ - QString oldname = itemName(i); - - i->setData(Qt::UserRole, name); - i->setData(Qt::DisplayRole, name + "\t" + itemFile(i)); - - if(oldname != "" && oldname != name) + instrument.setMasterFile(""); + auto audiofile_ids = instrument.getAudioFileList(); + for(auto audiofile_id : audiofile_ids) { - emit nameChanged(itemFile(i), name); + instrument.deleteAudioFile(audiofile_id); } -} + reset(); -void FileList::setItemMaster(QListWidgetItem* i, bool master) -{ - if(master) - { - i->setIcon(QPixmap(":icons/master.png")); - } - else - { - i->setIcon(QPixmap(":icons/file.png")); - } + emit allFilesRemoved(); } -- cgit v1.2.3