/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * filelist.cc * * Mon Nov 30 15:35:52 CET 2009 * Copyright 2009 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of DrumGizmo. * * DrumGizmo is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * DrumGizmo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "filelist.h" #include #include #include #include #include "itemeditor.h" #include "project.h" #include #include #include #include #include #include #include #include class ChannelMapDeligate : public QStyledItemDelegate { public: ChannelMapDeligate(Instrument& instrument) : instrument(instrument) { } 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); } 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); } } 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 } int rowCount(const QModelIndex &parent = QModelIndex()) const override { 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)")); QStringList::Iterator i = files.begin(); while(i != files.end()) { QString file = *i; QFileInfo fi(file); QString name = fi.baseName(); path = fi.absolutePath(); if(root == file.left(root.length())) { file = file.mid(root.length() + 1); } auto id = instrument.createAudioFile(); auto& audiofile = instrument.getAudioFile(id); audiofile.setName(name); audiofile.setFile(file); audiofile.setChannelMapId(-1); i++; } model->refresh(); } void FileList::selectionChanged(const QModelIndex &index) { auto audiofile_ids = instrument.getAudioFileList(); auto audiofile_id = audiofile_ids.begin() + index.row(); const auto& audiofile = instrument.getAudioFile(*audiofile_id); instrument.setMasterFile(audiofile.getFile()); emit masterFileChanged(audiofile.getAbsoluteFile()); //setMasterFile(i); model->refresh(); } void FileList::createMenus() { menu = new QMenu(); setMasterAction = new QAction(tr("Set as Master (dbl-click)"), this); connect(setMasterAction, SIGNAL(triggered()), this, SLOT(setMaster())); removeAction = new QAction(tr("Remove"), this); connect(removeAction, SIGNAL(triggered()), this, SLOT(removeFile())); removeAllAction = new QAction(tr("Remove all"), this); connect(removeAllAction, SIGNAL(triggered()), this, SLOT(removeAllFiles())); menu->addAction(setMasterAction); menu->addAction(removeAction); menu->addSeparator(); menu->addAction(removeAllAction); } void FileList::onCustomContextMenu(const QPoint &point) { QModelIndex index = indexAt(point); if(index.isValid()) { menu->popup(viewport()->mapToGlobal(point)); } } void FileList::setMaster() { // setMasterFile(activeItem); } void FileList::removeFile() { auto audiofile_ids = instrument.getAudioFileList(); auto audiofile_id = audiofile_ids.begin() + currentIndex().row(); instrument.deleteAudioFile(*audiofile_id); //emit fileRemoved(file, name); } void FileList::removeAllFiles() { instrument.setMasterFile(""); auto audiofile_ids = instrument.getAudioFileList(); for(auto audiofile_id : audiofile_ids) { instrument.deleteAudioFile(audiofile_id); } reset(); emit allFilesRemoved(); }