sample tree context menu

portability/boost
zetaPRIME 2019-06-25 16:09:34 -04:00
parent 70898e33a1
commit 2661bcaa61
3 changed files with 47 additions and 23 deletions

View File

@ -60,6 +60,7 @@ DirectoryNode* DirectoryNode::placeData(QString name, QVariant data) {
QString DirectoryNode::path() {
if (!parent || parent->name.isEmpty()) return name;
if (name.isEmpty()) return parent->path(); // nameless nodes don't add an extra /
return parent->path() % "/" % name;
}
@ -81,6 +82,11 @@ DirectoryNode* DirectoryNode::findData(const QVariant& d) {
return nullptr;
}
void DirectoryNode::treeExec(const std::function<void(Xybrid::UI::DirectoryNode*)>& f) {
for (auto c : children) c->treeExec(f);
f(this);
}
/*void DirectoryNode::placeData(const QVector<std::pair<QString, QVariant>>& data) {
QHash<QString, DirectoryNode*> dirs; // lookup table for directories
dirs[""] = this;

View File

@ -1,5 +1,7 @@
#pragma once
#include <functional>
#include <QString>
#include <QVector>
#include <QVariant>
@ -33,6 +35,8 @@ namespace Xybrid::UI {
DirectoryNode* findPath(QString path);
DirectoryNode* findData(const QVariant&);
void treeExec(const std::function<void(DirectoryNode*)>&);
inline bool isDirectory() const { return data.isNull(); }
};
}

View File

@ -34,24 +34,46 @@ SampleListModel::SampleListModel(QObject* parent, MainWindow* window) : QAbstrac
refresh();
});
/*view->setContextMenuPolicy(Qt::CustomContextMenu);
connect(view, &QListView::customContextMenuRequested, this, [this, view](const QPoint& pt) {
size_t idx = static_cast<size_t>(view->indexAt(pt).row());
if (idx >= displayOrder.size()) return;
auto smp = displayOrder[idx];
view->setContextMenuPolicy(Qt::CustomContextMenu);
connect(view, &QTreeView::customContextMenuRequested, this, [this, view](const QPoint& pt) {
auto dn = static_cast<DirectoryNode*>(view->indexAt(pt).internalPointer());
if (!dn) return; // no items applicable yet
auto menu = new QMenu(view);
menu->addAction("Delete Sample", this, [this, smp, view] {
if (QMessageBox::warning(view, "Are you sure?", QString("Remove sample \"%1\"?\n(This cannot be undone!)").arg(smp->name), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) return;
smp->project->samples.remove(smp->uuid);
smp->project = nullptr;
refresh();
});
if (dn) {
if (dn->isDirectory()) {
menu->addAction("Unpack Folder", this, [this, dn] {
dn->name = "";
propagateSampleNames(dn);
refresh();
});
menu->addAction("Delete Folder", this, [this, dn, view] {
if (QMessageBox::warning(view, "Are you sure?", QString("Remove folder \"%1\"?\n(This cannot be undone!)").arg(dn->name), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) return;
auto* project = this->window->getProject().get();
dn->treeExec([project](DirectoryNode* dn) {
if (dn->isDirectory()) return;
auto smp = project->samples[dn->data.toUuid()];
smp->project->samples.remove(smp->uuid);
smp->project = nullptr;
});
refresh();
});
} else {
auto* project = this->window->getProject().get();
auto smp = project->samples[dn->data.toUuid()];
menu->addAction("Delete Sample", this, [this, dn, smp, view] {
if (QMessageBox::warning(view, "Are you sure?", QString("Remove sample \"%1\"?\n(This cannot be undone!)").arg(dn->name), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) return;
smp->project->samples.remove(smp->uuid);
smp->project = nullptr;
refresh();
});
}
}
menu->setAttribute(Qt::WA_DeleteOnClose);
menu->popup(view->mapToGlobal(pt));
});*/
});
connect(window->uiSocket(), &UISocket::updatePatternLists, this, [this] { refresh(); });
}
@ -70,7 +92,7 @@ void SampleListModel::refresh() {
auto view = static_cast<QTreeView*>(QObject::parent());
if (auto ind = view->currentIndex(); ind.isValid()) dn = static_cast<DirectoryNode*>(ind.internalPointer());
hold = root; // hold old tree alive until layout change goes through
hold = root; // hold old tree alive until next refresh
root = std::make_shared<DirectoryNode>();
auto* project = window->getProject().get();
if (!project) return;
@ -81,15 +103,8 @@ void SampleListModel::refresh() {
emit layoutChanged();
// TODO: do this by path instead
if (dn) {
if (auto f = root->findPath(dn->path()); f) view->setCurrentIndex(createIndex(f->index, 0, f));
}
/*if (dn && !dn->data.isNull()) {
if (auto f = root->findData(dn->data); f) {
view->setCurrentIndex(createIndex(f->index, 0, f));
}
}*/
// find previously selected path
if (dn) if (auto f = root->findPath(dn->path()); f) view->setCurrentIndex(createIndex(f->index, 0, f));
auto ii = view->currentIndex();
while (ii.isValid()) { // expand down to selected
@ -216,7 +231,6 @@ bool SampleListModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
if (!u.isLocalFile()) continue;
auto smp = Sample::fromFile(u.toLocalFile());
if (smp) { // valid sample returned
//qDebug() << "sample successfully imported:" << smp->name << "channels" << smp->numChannels() << "len" << smp->length();
auto prj = window->getProject();
smp->project = prj.get();
prj->samples[smp->uuid] = smp;