Allow export of only the selected notes (#7991)

Users can now choose if they only want to export the selected notes when
exporting a MIDI clip as an `xpt` or `xptz` file in the piano roll. The
export file dialog now shows a checkbox with the label "Export only
selected notes".

## Technical details
Add the new public method `exportToXML` to `MidiClip`. Compared to
`saveSettings` it has an additional parameter `onlySelectedNotes` which
controls which notes are exported. The default is to export all notes.
The method `saveSettings` now simply delegates to `exportToXML` using the
default.

`PianoRollWindow::exportMidiClip` now adds a check box to the export
dialog which lets users select if they only want to export the selected
notes or all notes. The default is to export all notes. The method now
uses the new method `exportToXML` for the export and passes the state of
the check box into the method.
This commit is contained in:
Michael Gregorius
2025-07-06 08:42:54 +02:00
committed by GitHub
parent 05a5264870
commit 5c7131aa45
3 changed files with 41 additions and 17 deletions

View File

@@ -99,6 +99,7 @@ public:
MidiClip * nextMidiClip() const;
// settings-management
void exportToXML(QDomDocument& doc, QDomElement& midiClipElement, bool onlySelectedNotes = false);
void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override;
void loadSettings( const QDomElement & _this ) override;
inline QString nodeName() const override

View File

@@ -28,6 +28,8 @@
#include <QtMath>
#include <QApplication>
#include <QCheckBox>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QInputDialog>
#include <QKeyEvent>
@@ -5476,6 +5478,14 @@ void PianoRollWindow::exportMidiClip()
FileDialog exportDialog(this, tr("Export clip"), "",
tr("XML clip file (*.xpt *.xptz)"));
auto layout = dynamic_cast<QGridLayout*>(exportDialog.layout());
QCheckBox* onlySelectedNotesCheckBox = nullptr;
if (layout)
{
onlySelectedNotesCheckBox = new QCheckBox(tr("Export only selected notes"), &exportDialog);
layout->addWidget(onlySelectedNotesCheckBox);
}
exportDialog.setAcceptMode(FileDialog::AcceptSave);
if (exportDialog.exec() == QDialog::Accepted &&
@@ -5489,8 +5499,14 @@ void PianoRollWindow::exportMidiClip()
exportDialog.setDefaultSuffix(suffix);
const QString fullPath = exportDialog.selectedFiles()[0];
// Check if only the selected notes should be exported
auto* midiClip = m_editor->m_midiClip;
const bool onlySelectedNotes = onlySelectedNotesCheckBox && onlySelectedNotesCheckBox->isChecked();
DataFile dataFile(DataFile::Type::MidiClip);
m_editor->m_midiClip->saveSettings(dataFile, dataFile.content());
midiClip->exportToXML(dataFile, dataFile.content(), onlySelectedNotes);
if (dataFile.writeFile(fullPath))
{

View File

@@ -442,43 +442,50 @@ void MidiClip::checkType()
}
void MidiClip::saveSettings( QDomDocument & _doc, QDomElement & _this )
void MidiClip::exportToXML(QDomDocument& doc, QDomElement& midiClipElement, bool onlySelectedNotes)
{
_this.setAttribute( "type", static_cast<int>(m_clipType) );
_this.setAttribute( "name", name() );
_this.setAttribute("autoresize", QString::number(getAutoResize()));
_this.setAttribute("off", startTimeOffset());
midiClipElement.setAttribute("type", static_cast<int>(m_clipType));
midiClipElement.setAttribute("name", name());
midiClipElement.setAttribute("autoresize", QString::number(getAutoResize()));
midiClipElement.setAttribute("off", startTimeOffset());
if (const auto& c = color())
{
_this.setAttribute("color", c->name());
midiClipElement.setAttribute("color", c->name());
}
// as the target of copied/dragged MIDI clip is always an existing
// MIDI clip, we must not store actual position, instead we store -1
// which tells loadSettings() not to mess around with position
if( _this.parentNode().nodeName() == "clipboard" ||
_this.parentNode().nodeName() == "dnddata" )
if (midiClipElement.parentNode().nodeName() == "clipboard" ||
midiClipElement.parentNode().nodeName() == "dnddata")
{
_this.setAttribute( "pos", -1 );
midiClipElement.setAttribute("pos", -1);
}
else
{
_this.setAttribute( "pos", startPosition() );
midiClipElement.setAttribute("pos", startPosition());
}
_this.setAttribute( "muted", isMuted() );
_this.setAttribute( "steps", m_steps );
_this.setAttribute( "len", length() );
midiClipElement.setAttribute("muted", isMuted());
midiClipElement.setAttribute("steps", m_steps);
midiClipElement.setAttribute("len", length());
// now save settings of all notes
for (auto& note : m_notes)
{
note->saveState(_doc, _this);
if (!onlySelectedNotes || note->selected())
{
note->saveState(doc, midiClipElement);
}
}
}
void MidiClip::saveSettings( QDomDocument & _doc, QDomElement & _this )
{
exportToXML(_doc, _this);
}
void MidiClip::loadSettings( const QDomElement & _this )