song info editing; switch data over to QString

portability/boost
zetaPRIME 2019-06-20 05:17:30 -04:00
parent c74cc70153
commit 12fcaa427c
17 changed files with 466 additions and 53 deletions

View File

@ -385,7 +385,7 @@ void AudioEngine::nextTick() {
for (size_t c = 0; c < cs; c++) {
auto& ch = pOld->channels[c];
if (!chTrack[c].valid) continue; // skip notes that aren't actually playing
if (ch.name.empty()) noteEndQueue.push_back(chTrack[c]); // end notes in unnamed channels right away
if (ch.name.isEmpty()) noteEndQueue.push_back(chTrack[c]); // end notes in unnamed channels right away
else nameTrack[&ch.name] = chTrack[c]; // otherwise keep track for later
}
}
@ -395,7 +395,7 @@ void AudioEngine::nextTick() {
size_t cs = p->channels.size();
for (size_t c = 0; c < cs; c++) {
auto& ch = p->channels[c];
if (ch.name.empty()) continue;
if (ch.name.isEmpty()) continue;
if (auto nt = nameTrack.find(&ch.name); nt != nameTrack.end() && nt->second.valid) {
chTrack[c] = nt->second; // carry over
nt->second.valid = false; // and invalidate

View File

@ -26,7 +26,8 @@ namespace Xybrid::Audio {
class AudioWorker;
template <typename T> struct PointerCompare {
bool operator()(T* a, T* b) const { return *a == *b; }
size_t operator()(T* a) const { return std::hash<T>()(*a); }
//size_t operator()(T* a) const { return std::hash<T>()(*a); }
size_t operator()(T* a) const { return qHash(*a); }
};
struct NoteInfo {
bool valid = false;
@ -76,14 +77,14 @@ namespace Xybrid::Audio {
std::array<uint16_t, 256> portLastNoteId;
std::vector<NoteInfo> chTrack;
std::vector<NoteInfo> noteEndQueue;
std::unordered_map<std::string*, NoteInfo, PointerCompare<std::string>, PointerCompare<std::string>> nameTrack;
std::unordered_map<QString*, NoteInfo, PointerCompare<QString>, PointerCompare<QString>> nameTrack;
std::vector<uint8_t> buf; /// preallocated buffer for building commands
uint8_t previewPort_ = 0;
uint16_t previewNote_ = 0;
// playback timing and position
float tempo = 140.0;
double tempo = 140.0;
int seqPos;
int curRow;
int curTick;

View File

@ -22,7 +22,7 @@ Row& Row::operator=(const Row& o) noexcept {
return *this;
}
Channel::Channel(int numRows, std::string name) : Channel() {
Channel::Channel(int numRows, QString name) : Channel() {
this->name = name;
rows.resize(static_cast<size_t>(numRows));
}

View File

@ -8,6 +8,8 @@
#include <vector>
#include <string>
#include <QString>
namespace Xybrid::Data {
class Project;
struct TimeSignature {
@ -89,12 +91,12 @@ namespace Xybrid::Data {
class Channel {
public:
std::string name;
QString name;
std::vector<Row> rows;
Channel() = default;
Channel(const Channel&) = default;
Channel(int numRows, std::string name = "");
Channel(int numRows, QString name = "");
};
private:
static Row fallbackRow;
@ -107,10 +109,10 @@ namespace Xybrid::Data {
Project* project;
size_t index; // index in project's pattern list
std::string name;
QString name;
int rows = 64;
float tempo = 0; // don't set playback tempo
double tempo = 0; // don't set playback tempo
TimeSignature time;
int fold = 0;

View File

@ -25,12 +25,12 @@ namespace Xybrid::Data {
UISocket* socket;
std::string title;
std::string artist;
QString title;
QString artist;
QString fileName;
float tempo = 140.0;
double tempo = 140.0;
TimeSignature time;
// default time signature

View File

@ -150,7 +150,7 @@ std::shared_ptr<Sample> Sample::fromFile(QString fileName) {
smp->sampleRate = fmt.sampleRate();
smp->uuid = QUuid::createUuid();
smp->name = QFileInfo(fileName).fileName();
smp->name = QFileInfo(fileName).baseName();
return smp;
}

View File

@ -49,7 +49,7 @@ void PatternDeltaCommand::undo() {
if (!composed) emit pattern->project->socket->rowUpdated(pattern.get(), ch, rw);
}
PatternRenameCommand::PatternRenameCommand(const std::shared_ptr<Pattern>& pattern, const std::string &to) {
PatternRenameCommand::PatternRenameCommand(const std::shared_ptr<Pattern>& pattern, const QString& to) {
this->pattern = pattern;
from = pattern->name;
this->to = to;
@ -179,7 +179,7 @@ void PatternChannelMoveCommand::undo() {
emit pattern->project->socket->patternUpdated(pattern.get());
}
PatternChannelRenameCommand::PatternChannelRenameCommand(const std::shared_ptr<Pattern>& pattern, int channel, const std::string &to) {
PatternChannelRenameCommand::PatternChannelRenameCommand(const std::shared_ptr<Pattern>& pattern, int channel, const QString& to) {
this->pattern = pattern;
idx = channel;
from = pattern->channel(idx).name;

View File

@ -35,10 +35,10 @@ namespace Xybrid::Editing {
};
class PatternRenameCommand : public PatternCommand {
std::string from, to;
QString from, to;
public:
PatternRenameCommand(const std::shared_ptr<Data::Pattern>& pattern, const std::string& to);
PatternRenameCommand(const std::shared_ptr<Data::Pattern>& pattern, const QString& to);
~PatternRenameCommand() override = default;
int id() const override { return 2070; }
@ -103,10 +103,10 @@ namespace Xybrid::Editing {
class PatternChannelRenameCommand : public PatternCommand {
int idx;
std::string from, to;
QString from, to;
public:
PatternChannelRenameCommand(const std::shared_ptr<Data::Pattern>& pattern, int channel, const std::string& to);
PatternChannelRenameCommand(const std::shared_ptr<Data::Pattern>& pattern, int channel, const QString& to);
~PatternChannelRenameCommand() override = default;
int id() const override { return 2101; }

View File

@ -71,8 +71,10 @@ bool FileOps::saveProject(std::shared_ptr<Project> project, QString fileName) {
{ /* Project metadata */ } {
QCborMap meta;
meta[qs("artist")] = QString::fromStdString(project->artist);
meta[qs("title")] = QString::fromStdString(project->title);
meta[qs("artist")] = project->artist;
meta[qs("title")] = project->title;
meta[qs("tempo")] = project->tempo;
main[qs("meta")] = meta;
}
@ -90,8 +92,9 @@ bool FileOps::saveProject(std::shared_ptr<Project> project, QString fileName) {
QCborArray ptns;
for (auto p : project->patterns) {
QCborMap pm;
pm[qs("name")] = QString::fromStdString(p->name);
pm[qs("name")] = p->name;
pm[qs("fold")] = p->fold;
pm[qs("tempo")] = p->tempo;
{
QCborArray ts;
@ -103,7 +106,7 @@ bool FileOps::saveProject(std::shared_ptr<Project> project, QString fileName) {
bool needsCount = true;
for (auto& ch : p->channels) {
QCborMap chm;
chm[qs("name")] = QString::fromStdString(ch.name);
chm[qs("name")] = ch.name;
QCborArray rows;
int skipped = 0;
for (auto& r : ch.rows) {
@ -179,8 +182,9 @@ std::shared_ptr<Project> FileOps::loadProject(QString fileName) {
{ /* Project metadata */ } {
QCborMap meta = main.value("meta").toMap();
project->artist = meta.value("artist").toString().toStdString();
project->title = meta.value("title").toString().toStdString();
project->artist = meta.value("artist").toString();
project->title = meta.value("title").toString();
project->tempo = meta.value("tempo").toDouble(project->tempo);
}
{ /* Patterns */ } {
@ -191,8 +195,9 @@ std::shared_ptr<Project> FileOps::loadProject(QString fileName) {
auto p = std::make_shared<Pattern>(pm.value("rows").toInteger(1));
p->project = project.get();
project->patterns.push_back(p);
p->name = pm.value("name").toString().toStdString();
p->name = pm.value("name").toString();
p->fold = static_cast<int>(pm.value("fold").toInteger(0));
p->tempo = pm.value("tempo").toDouble(p->tempo);
if (auto ts = pm.value("time").toArray(); !ts.empty())
p->time = Data::TimeSignature(static_cast<int>(ts[0].toInteger()), static_cast<int>(ts[1].toInteger()), static_cast<int>(ts[2].toInteger()));
@ -205,7 +210,7 @@ std::shared_ptr<Project> FileOps::loadProject(QString fileName) {
}
auto chm = chm_.toMap();
auto& ch = p->channels.emplace_back();
ch.name = chm.value("name").toString().toStdString();
ch.name = chm.value("name").toString();
auto rows = chm.value("rows").toArray();
ch.rows.reserve(static_cast<size_t>(rows.size()));

View File

@ -145,6 +145,19 @@ MainWindow::MainWindow(QWidget *parent) :
});//*/
}
{ /* Set up song info pane */ } {
ui->expandSongInfo->setIcon(ui->expandSongInfo->style()->standardIcon(QStyle::SP_ToolBarVerticalExtensionButton));
ui->collapseSongInfo->setIcon(ui->expandSongInfo->style()->standardIcon(QStyle::SP_ToolBarVerticalExtensionButton));
connect(ui->expandSongInfo, &QPushButton::pressed, this, [this] { setSongInfoPaneExpanded(true); });
connect(ui->collapseSongInfo, &QPushButton::pressed, this, [this] { setSongInfoPaneExpanded(false); });
connect(ui->editArtist, &QLineEdit::textEdited, this, [this](const QString& s) { project->artist = s; updateTitle(); });
connect(ui->editTitle, &QLineEdit::textEdited, this, [this](const QString& s) { project->title = s; updateTitle(); });
connect(ui->editTempo, qOverload<double>(&QDoubleSpinBox::valueChanged), this, [this](double t) { project->tempo = t; });
}
{ /* Set up sequencer */ } {
// model
ui->patternSequencer->setModel(new PatternSequencerModel(ui->patternSequencer, this));
@ -407,6 +420,11 @@ void MainWindow::menuFileSaveAs() {
}
}
void MainWindow::menuFileNewWindow() {
auto w = new MainWindow();
w->show();
}
void MainWindow::onNewProjectLoaded() {
undoStack->clear();
@ -426,7 +444,13 @@ void MainWindow::onNewProjectLoaded() {
openGraph(gg);
});
ui->editTempo->setValue(project->tempo);
ui->editArtist->setText(project->artist);
ui->editTitle->setText(project->title);
updateTitle();
setSongInfoPaneExpanded(false);
emit projectLoaded();
}
@ -465,14 +489,29 @@ void MainWindow::updatePatternLists() {
}
void MainWindow::updateTitle() {
//if (!isVisible()) return; // prevent stupid errors
if (!project) return;
QString title = u8"Xybrid - %1%2";
if (project->fileName.isEmpty()) title = title.arg("(new project)");
else title = title.arg(QFileInfo(project->fileName).baseName());
if (undoStack->isClean()) title = title.arg("");
else title = title.arg("*");
this->setWindowTitle(title);
QString songTitle;
if (project->title.isEmpty()) {
if (project->fileName.isEmpty()) songTitle = qs("(new project)");
else songTitle = QFileInfo(project->fileName).baseName();
} else {
if (!project->artist.isEmpty()) songTitle = qs("%1 - %2").arg(project->artist).arg(project->title);
else songTitle = project->title;
}
ui->labelSongInfo->setText(songTitle);
setWindowTitle(qs("Xybrid - %1%2").arg(songTitle).arg(undoStack->isClean() ? "" : "*"));
}
void MainWindow::setSongInfoPaneExpanded(bool open) {
if (open) {
ui->songInfoPane->setCurrentIndex(1);
} else {
ui->songInfoPane->setCurrentIndex(0);
}
auto s = ui->songInfoPane->currentWidget()->minimumHeight();
ui->songInfoPane->setMinimumHeight(s);
ui->songInfoPane->setMaximumHeight(s);
}
bool MainWindow::selectPatternForEditing(Pattern* pattern) {
@ -531,7 +570,7 @@ void MainWindow::openPatternProperties(const std::shared_ptr<Xybrid::Data::Patte
dlg->setLayout(dl);
//dlg->layout()->setMargin(3);
auto eName = new QLineEdit(QString::fromStdString(p->name));
auto eName = new QLineEdit(p->name);
dl->addWidget(eName);
//dlg->layout()->setAlignment(eName, Qt::AlignTop);
@ -578,7 +617,7 @@ void MainWindow::openPatternProperties(const std::shared_ptr<Xybrid::Data::Patte
connect(bbox, &QDialogButtonBox::rejected, dlg, &QDialog::reject);
connect(bbox, &QDialogButtonBox::accepted, dlg, [=] {
auto cc = new CompositeCommand();
if (auto n = eName->text().toStdString(); n != p->name) cc->compose(new PatternRenameCommand(p, n));
if (auto n = eName->text(); n != p->name) cc->compose(new PatternRenameCommand(p, n));
if (auto t = Data::TimeSignature(gTimeBeats->value(), gTimeRows->value(), gTimeTicks->value()); t != p->time)
cc->compose(new PatternTimeSignatureCommand(p, t));
if (auto nr = gLengthBox->value(); nr != p->rows) {

View File

@ -41,6 +41,8 @@ namespace Xybrid {
void updateTitle();
void setSongInfoPaneExpanded(bool);
public:
const std::shared_ptr<Data::Project>& getProject() const { return project; }
@ -59,6 +61,8 @@ namespace Xybrid {
void menuFileSave();
void menuFileSaveAs();
void menuFileNewWindow();
signals:
void projectLoaded();

View File

@ -33,7 +33,7 @@
<enum>Qt::NoFocus</enum>
</property>
<property name="currentIndex">
<number>2</number>
<number>0</number>
</property>
<property name="documentMode">
<bool>true</bool>
@ -118,6 +118,313 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QStackedWidget" name="songInfoPane">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>28</height>
</size>
</property>
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="collapsed">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>28</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>28</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelSongInfo">
<property name="margin">
<number>2</number>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="expandSongInfo">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>28</width>
<height>28</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>28</width>
<height>28</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="expanded">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>56</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>240</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="songInfo_row1" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>28</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelArtist">
<property name="text">
<string>Artist</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="editArtist">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>128</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelTitle">
<property name="text">
<string>Title</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="editTitle"/>
</item>
<item>
<widget class="QPushButton" name="collapseSongInfo">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>28</width>
<height>28</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>28</width>
<height>28</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="songInfo_row2" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>28</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelTempo">
<property name="text">
<string>Starting Tempo</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="editTempo">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="correctionMode">
<enum>QAbstractSpinBox::CorrectToNearestValue</enum>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>10.000000000000000</double>
</property>
<property name="maximum">
<double>2048.000000000000000</double>
</property>
<property name="value">
<double>140.000000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QTableView" name="patternSequencer">
<property name="sizePolicy">
@ -178,6 +485,12 @@
</item>
<item>
<widget class="Xybrid::UI::PatternEditorView" name="patternEditor">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Iosevka Term Light</family>
@ -379,9 +692,6 @@
</widget>
</item>
</layout>
<zorder>sampleList</zorder>
<zorder>sampleViewPane</zorder>
<zorder>sampleViewSplitter</zorder>
</widget>
<widget class="QWidget" name="extra_">
<attribute name="title">
@ -431,6 +741,9 @@
<addaction name="actionOpen"/>
<addaction name="actionSave"/>
<addaction name="actionSave_As"/>
<addaction name="separator"/>
<addaction name="actionNew_Window"/>
<addaction name="actionClose_Window"/>
</widget>
<widget class="QMenu" name="menuEdit">
<property name="title">
@ -490,6 +803,22 @@
<bool>true</bool>
</property>
</action>
<action name="actionNew_Window">
<property name="text">
<string>New Window</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+N</string>
</property>
</action>
<action name="actionClose_Window">
<property name="text">
<string>Close Window</string>
</property>
<property name="shortcut">
<string>Ctrl+W</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
@ -578,11 +907,44 @@
</hint>
</hints>
</connection>
<connection>
<sender>actionNew_Window</sender>
<signal>triggered()</signal>
<receiver>MainWindow</receiver>
<slot>menuFileNewWindow()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>459</x>
<y>305</y>
</hint>
</hints>
</connection>
<connection>
<sender>actionClose_Window</sender>
<signal>triggered()</signal>
<receiver>MainWindow</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>459</x>
<y>305</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>menuFileNew()</slot>
<slot>menuFileOpen()</slot>
<slot>menuFileSave()</slot>
<slot>menuFileSaveAs()</slot>
<slot>menuFileNewWindow()</slot>
</slots>
</ui>

View File

@ -142,7 +142,7 @@ QVariant PatternEditorModel::hdrData(int section, Qt::Orientation, int role) con
if (role == Qt::DisplayRole || role == Qt::ToolTipRole) {
if (pattern->channels.size() == 0) return QString("(no channels)");
if (static_cast<size_t>(section) >= pattern->channels.size()) return QString("");
auto n = QString::fromStdString(pattern->channels.at(static_cast<size_t>(section)).name);
auto n = pattern->channels.at(static_cast<size_t>(section)).name;
//if (n.length() == 0) return QString("(Channel %1)").arg(section);
if (n.length() == 0) return QString("(ch%1)").arg(section);
return n;
@ -207,7 +207,7 @@ void PatternEditorModel::updateColumnDisplay() {
opt.orientation = Qt::Horizontal;
opt.section = 0;
opt.fontMetrics = view->horizontalHeader()->fontMetrics();
opt.text = QString::fromStdString(c.name);
opt.text = c.name;
minWidth = view->horizontalHeader()->style()->sizeFromContents(QStyle::CT_HeaderSection, &opt, QSize(), view->horizontalHeader()).width();
}
int lsw = view->columnWidth(lastShown);

View File

@ -374,8 +374,8 @@ void PatternEditorView::startRenameChannel(int channel) {
auto c = &p->channel(channel);
bool ok = false;
auto capt = QString("Rename channel %1:").arg(channel);
auto n = QInputDialog::getText(this, "Rename...", capt, QLineEdit::Normal, QString::fromStdString(c->name), &ok);
auto n = QInputDialog::getText(this, "Rename...", capt, QLineEdit::Normal, c->name, &ok);
if (!ok) return; // canceled
if (p != mdl->getPattern() || c != &p->channel(channel)) return; // abort if this somehow isn't the channel it was before
(new PatternChannelRenameCommand(p, channel, n.toStdString()))->commit();
(new PatternChannelRenameCommand(p, channel, n))->commit();
}

View File

@ -32,10 +32,10 @@ QVariant PatternListModel::data(const QModelIndex &index, int role) const {
if (!project) return QVariant();
if (role == Qt::DisplayRole) {
auto pattern = project->patterns[static_cast<size_t>(index.row())];
return QString("%1: %2").arg(pattern->index, 1, 10, QChar('0')).arg(QString::fromStdString(pattern->name.empty() ? "(unnamed)" : pattern->name));
return QString("%1: %2").arg(pattern->index, 1, 10, QChar('0')).arg(pattern->name.isEmpty() ? "(unnamed)" : pattern->name);
}
if (role == Qt::EditRole) {
return QString::fromStdString(project->patterns[static_cast<size_t>(index.row())]->name);
return project->patterns[static_cast<size_t>(index.row())]->name;
}
return QVariant();
}
@ -46,7 +46,7 @@ bool PatternListModel::setData(const QModelIndex &index, const QVariant &value,
if (!project) return true;
auto pattern = project->patterns[static_cast<size_t>(index.row())];
//pattern->name = value.toString().toStdString();
return (new PatternRenameCommand(pattern, value.toString().toStdString()))->commit();
return (new PatternRenameCommand(pattern, value.toString()))->commit();
}
return true;
}

View File

@ -35,8 +35,8 @@ QVariant PatternSequencerModel::data(const QModelIndex &index, int role) const {
auto* pattern = project->sequence[static_cast<size_t>(index.column())];
if (!pattern) return !toolTip ? QString("-") : QString("(separator)");
if (!toolTip) return QString("%1").arg(pattern->index, 1, 10, QChar('0'));
if (pattern->name.empty()) return QVariant(); // no tool tip without name
return QString("(%1) %2").arg(pattern->index, 1, 10, QChar('0')).arg(QString::fromStdString(pattern->name));
if (pattern->name.isEmpty()) return QVariant(); // no tool tip without name
return QString("(%1) %2").arg(pattern->index, 1, 10, QChar('0')).arg(pattern->name);
}
if (role == Qt::TextAlignmentRole ) return Qt::AlignHCenter + Qt::AlignVCenter;
return QVariant();

View File

@ -6,9 +6,9 @@
#define qs QStringLiteral
namespace Xybrid::Util {
template<typename Num> inline QString numAndName(Num num, const std::string& name) {
if (name.empty()) return QString::number(num);
return qs("%1 (\"%2\")").arg(num).arg(QString::fromStdString(name));
template<typename Num> inline QString numAndName(Num num, const QString& name) {
if (name.isEmpty()) return QString::number(num);
return qs("%1 (\"%2\")").arg(num).arg(name);
}
inline QString hex(int num, int fw = 2) {