Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Pattern import/export #5891

Merged
merged 7 commits into from
Mar 21, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/DataFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class LMMS_EXPORT DataFile : public QDomDocument
ClipboardData,
JournalData,
EffectSettings,
NotePattern,
TypeCount
} ;
typedef Types Type;
Expand Down
4 changes: 4 additions & 0 deletions include/PianoRoll.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class QPixmap;
class QScrollBar;
class QString;
class QMenu;
class QToolButton;

class ComboBox;
class NotePlayHandle;
Expand Down Expand Up @@ -497,6 +498,8 @@ class PianoRollWindow : public Editor, SerializingObject
private slots:
void updateAfterPatternChange();
void ghostPatternSet( bool state );
void exportPattern();
void importPattern();

private:
void patternRenamed();
Expand All @@ -506,6 +509,7 @@ private slots:

PianoRoll* m_editor;

QToolButton* m_fileToolsButton;
ComboBox * m_zoomingComboBox;
ComboBox * m_zoomingYComboBox;
ComboBox * m_quantizeComboBox;
Expand Down
12 changes: 10 additions & 2 deletions src/core/DataFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ DataFile::typeDescStruct
{ DataFile::DragNDropData, "dnddata" },
{ DataFile::ClipboardData, "clipboard-data" },
{ DataFile::JournalData, "journaldata" },
{ DataFile::EffectSettings, "effectsettings" }
{ DataFile::EffectSettings, "effectsettings" },
{ DataFile::NotePattern, "pattern" }
} ;


Expand Down Expand Up @@ -184,6 +185,12 @@ bool DataFile::validate( QString extension )
return true;
}
break;
case Type::NotePattern:
if (extension == "xpt" || extension == "xptz")
{
return true;
}
break;
case Type::UnknownType:
if (! ( extension == "mmp" || extension == "mpt" || extension == "mmpz" ||
extension == "xpf" || extension == "xml" ||
Expand Down Expand Up @@ -285,7 +292,8 @@ bool DataFile::writeFile( const QString& filename )
return false;
}

if( fullName.section( '.', -1 ) == "mmpz" )
const QString extension = fullName.section('.', -1);
if (extension == "mmpz" || extension == "xptz")
{
QString xml;
QTextStream ts( &xml );
Expand Down
107 changes: 107 additions & 0 deletions src/gui/editors/PianoRoll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <QKeyEvent>
#include <QLabel>
#include <QLayout>
#include <QMessageBox>
#include <QMdiArea>
#include <QPainter>
#include <QPointer>
Expand Down Expand Up @@ -66,6 +67,7 @@
#include "StepRecorderWidget.h"
#include "TextFloat.h"
#include "TimeLineWidget.h"
#include "FileDialog.h"


using std::move;
Expand Down Expand Up @@ -4403,6 +4405,29 @@ PianoRollWindow::PianoRollWindow() :
notesActionsToolBar->addSeparator();
notesActionsToolBar->addAction( quantizeAction );

// -- File actions
DropToolBar* fileActionsToolBar = addDropToolBarToTop(tr("File actions"));

// -- File ToolButton
m_fileToolsButton = new QToolButton(m_toolBar);
m_fileToolsButton->setIcon(embed::getIconPixmap("file"));
m_fileToolsButton->setPopupMode(QToolButton::InstantPopup);

// Import / export
QAction* importAction = new QAction(embed::getIconPixmap("project_import"),
tr("Import pattern"), m_fileToolsButton);

QAction* exportAction = new QAction(embed::getIconPixmap("project_export"),
tr("Export pattern"), m_fileToolsButton);

m_fileToolsButton->addAction(importAction);
m_fileToolsButton->addAction(exportAction);
fileActionsToolBar->addWidget(m_fileToolsButton);

connect(importAction, SIGNAL(triggered()), this, SLOT(importPattern()));
connect(exportAction, SIGNAL(triggered()), this, SLOT(exportPattern()));
// -- End File actions

// Copy + paste actions
DropToolBar *copyPasteActionsToolBar = addDropToolBarToTop( tr( "Copy paste controls" ) );

Expand Down Expand Up @@ -4614,12 +4639,14 @@ void PianoRollWindow::setCurrentPattern( Pattern* pattern )
if ( pattern )
{
setWindowTitle( tr( "Piano-Roll - %1" ).arg( pattern->name() ) );
m_fileToolsButton->setEnabled(true);
connect( pattern->instrumentTrack(), SIGNAL( nameChanged() ), this, SLOT( updateAfterPatternChange()) );
connect( pattern, SIGNAL( dataChanged() ), this, SLOT( updateAfterPatternChange() ) );
}
else
{
setWindowTitle( tr( "Piano-Roll - no pattern" ) );
m_fileToolsButton->setEnabled(false);
}
}

Expand Down Expand Up @@ -4785,10 +4812,12 @@ void PianoRollWindow::patternRenamed()
if ( currentPattern() )
{
setWindowTitle( tr( "Piano-Roll - %1" ).arg( currentPattern()->name() ) );
m_fileToolsButton->setEnabled(true);
}
else
{
setWindowTitle( tr( "Piano-Roll - no pattern" ) );
m_fileToolsButton->setEnabled(false);
}
}

Expand All @@ -4803,6 +4832,84 @@ void PianoRollWindow::ghostPatternSet( bool state )



void PianoRollWindow::exportPattern()
{
QString extFilter("XML Pattern (*.xpt *.xptz)");
FileDialog exportDialog(this, tr("Export pattern"), "", extFilter);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some minor inconsistencies between exportPattern() and importPattern():

  • XML Pattern vs. XML pattern file. I'm not sure if XML pattern describe well what the file is.
  • This file extension filter in this function is not translatable while the one in importPattern() is. Also, only this function uses an explicit temporary QString.


exportDialog.setAcceptMode(FileDialog::AcceptSave);

if (exportDialog.exec() == QDialog::Accepted &&
!exportDialog.selectedFiles().isEmpty() &&
!exportDialog.selectedFiles().first().isEmpty())
{
QString suffix =
ConfigManager::inst()->value("app", "nommpz").toInt() == 0
? "xptz"
: "xpt";
exportDialog.setDefaultSuffix(suffix);

const QString fullPath = exportDialog.selectedFiles()[0];
DataFile dataFile(DataFile::NotePattern);
m_editor->m_pattern->saveSettings(dataFile, dataFile.content());

if (dataFile.writeFile(fullPath))
{
TextFloat::displayMessage(tr("Export pattern success"),
tr("Pattern saved to %1").arg(fullPath),
embed::getIconPixmap("project_export"), 4000);
}
}
}




void PianoRollWindow::importPattern()
{
// Overwrite confirmation.
if (!m_editor->m_pattern->empty() &&
QMessageBox::warning(
NULL,
tr("Import pattern."),
tr("You are about to import a pattern, this will "
"overwrite your current pattern. Do you want to "
"continue?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes
) != QMessageBox::Yes)
{
return;
}

FileDialog importDialog(this, tr("Open Pattern"), "",
tr("XML pattern file (*.xpt *.xptz)"));
importDialog.setFileMode(FileDialog::ExistingFile);

if (importDialog.exec() == QDialog::Accepted &&
!importDialog.selectedFiles().isEmpty())
{
const QString fullPath = importDialog.selectedFiles()[0];
DataFile dataFile(fullPath);

if (dataFile.head().isNull())
{
return;
}

TimePos pos = m_editor->m_pattern->startPosition(); // Backup position in timeline.

m_editor->m_pattern->loadSettings(dataFile.content());
m_editor->m_pattern->movePosition(pos);

TextFloat::displayMessage(tr("Import pattern success"),
tr("Imported pattern %1!").arg(fullPath),
embed::getIconPixmap("project_import"), 4000);
}
}




void PianoRollWindow::focusInEvent( QFocusEvent * event )
{
// when the window is given focus, also give focus to the actual piano roll
Expand Down