Skip to content

Commit

Permalink
Allow exporting MIDI files, and make a few improvements to file expor…
Browse files Browse the repository at this point in the history
…ters.

- For now, the MIDI files contain the minimum necessary data to be a
valid MIDI file.
- Refactored the file format manager to allow importers/exporters to be
stored in a specific order, instead of alphabetical order. This ensures
that the Save dialog defaults to .pt2 files.
- When saving to a format other than .pt2, don't mark the file as being
clean.

Bug: #55
  • Loading branch information
cameronwhite committed Jun 21, 2015
1 parent e84af24 commit 83a880e
Show file tree
Hide file tree
Showing 8 changed files with 261 additions and 83 deletions.
38 changes: 19 additions & 19 deletions source/app/powertabeditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ bool PowerTabEditor::saveFile(QString path)
{
QFileInfo info(path);
QString extension = info.suffix();
Q_ASSERT(extension == "pt2");
Q_ASSERT(!extension.isEmpty());

boost::optional<FileFormat> format =
myFileFormatManager->findFormat(extension.toStdString());
Expand All @@ -363,23 +363,29 @@ bool PowerTabEditor::saveFile(QString path)
const std::string path_str = path.toStdString();
Document &doc = myDocumentManager->getCurrentDocument();

if (!myFileFormatManager->exportFile(doc.getScore(), path_str, *format))
if (!myFileFormatManager->exportFile(doc.getScore(), path_str, *format,
this))
{
return false;
}

doc.setFilename(path_str);
if (extension == "pt2")
{
doc.setFilename(path_str);

// Update window title and tab bar.
updateWindowTitle();
const QString filename = info.fileName();
myTabWidget->setTabText(myTabWidget->currentIndex(), filename);
myTabWidget->setTabToolTip(myTabWidget->currentIndex(), filename);
// Update window title and tab bar.
updateWindowTitle();
const QString filename = info.fileName();
myTabWidget->setTabText(myTabWidget->currentIndex(), filename);
myTabWidget->setTabToolTip(myTabWidget->currentIndex(), filename);

// Add to the recent files list and update the last used directory.
myRecentFiles->add(path);
setPreviousDirectory(path);
// Add to the recent files list and update the last used directory.
myRecentFiles->add(path);
setPreviousDirectory(path);

// Mark the file as being in an unmodified state.
myUndoManager->setClean();
// Mark the file as being in an unmodified state.
myUndoManager->setClean();
}

return true;
}
Expand All @@ -394,12 +400,6 @@ bool PowerTabEditor::saveFileAs()
if (path.isEmpty())
return false;

// If the user didn't type the extension, add it in.
QFileInfo info(path);
QString extension = info.suffix();
if (extension.isEmpty())
path += "." + extension;

return saveFile(path);
}

Expand Down
3 changes: 3 additions & 0 deletions source/formats/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ add_library(pteformats
guitar_pro/guitarproimporter.h
guitar_pro/inputstream.h

midi/midiexporter.cpp
midi/midiexporter.h

powertab/powertabexporter.cpp
powertab/powertabimporter.cpp

Expand Down
5 changes: 3 additions & 2 deletions source/formats/fileformat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ FileFormat::FileFormat(const std::string &name,
{
}

bool FileFormat::operator<(const FileFormat &format) const
bool FileFormat::operator==(const FileFormat &format) const
{
return myName < format.myName;
return myName == format.myName &&
myFileExtensions == format.myFileExtensions;
}

std::string FileFormat::fileFilter() const
Expand Down
2 changes: 1 addition & 1 deletion source/formats/fileformat.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class FileFormat
FileFormat(const std::string &myName,
const std::vector<std::string> &myFileExtensions);

bool operator<(const FileFormat &format) const;
bool operator==(const FileFormat &format) const;

/// Returns a correctly formatted file filter for a Qt file dialog.
/// e.g. "FileType (*.ext1 *.ext2)".
Expand Down
103 changes: 61 additions & 42 deletions source/formats/fileformatmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,36 @@

#include <formats/gpx/gpximporter.h>
#include <formats/guitar_pro/guitarproimporter.h>
#include <formats/midi/midiexporter.h>
#include <formats/powertab/powertabimporter.h>
#include <formats/powertab/powertabexporter.h>
#include <formats/powertab_old/powertaboldimporter.h>
#include <QMessageBox>

FileFormatManager::FileFormatManager()
{
registerImporter<PowerTabImporter>();
registerImporter<PowerTabOldImporter>();
registerExporter<PowerTabExporter>();
registerImporter<GpxImporter>();
registerImporter<GuitarProImporter>();
myImporters.emplace_back(new PowerTabImporter());
myImporters.emplace_back(new PowerTabOldImporter());
myImporters.emplace_back(new GuitarProImporter());
myImporters.emplace_back(new GpxImporter());

myExporters.emplace_back(new PowerTabExporter());
myExporters.emplace_back(new MidiExporter());
}

boost::optional<FileFormat> FileFormatManager::findFormat(
const std::string &extension) const
{
for (auto importer = myImporters.begin(); importer != myImporters.end();
++importer)
for (auto &importer : myImporters)
{
if (importer->fileFormat().contains(extension))
return importer->fileFormat();
}

for (auto &exporter : myExporters)
{
if (importer->first.contains(extension))
return importer->first;
if (exporter->fileFormat().contains(extension))
return exporter->fileFormat();
}

return boost::none;
Expand All @@ -51,14 +59,14 @@ std::string FileFormatManager::importFileFilter() const
std::string filterAll = "All Supported Formats (";
std::string filterOther;

for (auto importer = myImporters.begin(); importer != myImporters.end();
++importer)
for (auto it = myImporters.begin(); it != myImporters.end(); ++it)
{
if (importer != myImporters.begin())
if (it != myImporters.begin())
filterAll += " ";

filterAll += importer->first.allExtensions();
filterOther += ";;" + importer->first.fileFilter();
const FileFormat &format = (*it)->fileFormat();
filterAll += format.allExtensions();
filterOther += ";;" + format.fileFilter();
}

filterAll += ")";
Expand All @@ -67,21 +75,26 @@ std::string FileFormatManager::importFileFilter() const
}

bool FileFormatManager::importFile(Score &score, const std::string &filename,
const FileFormat &format, QWidget *parentWindow)
const FileFormat &format,
QWidget *parent_window)
{
if (myImporters.find(format) != myImporters.end())
for (auto &importer : myImporters)
{
try
if (importer->fileFormat() == format)
{
myImporters.at(format)->load(filename, score);
return true;
}
catch (const std::exception &e)
{
QMessageBox msgBox(parentWindow);
msgBox.setText(QObject::tr("Error importing file - ") + QString(e.what()));
msgBox.exec();
return false;
try
{
importer->load(filename, score);
return true;
}
catch (const std::exception &e)
{
QMessageBox msg(parent_window);
msg.setText(QObject::tr("Error importing file - ") +
QString(e.what()));
msg.exec();
return false;
}
}
}

Expand All @@ -92,33 +105,39 @@ std::string FileFormatManager::exportFileFilter() const
{
std::string filter;

for (auto exporter = myExporters.begin(); exporter != myExporters.end();
++exporter)
for (auto it = myExporters.begin(); it != myExporters.end(); ++it)
{
if (exporter != myExporters.begin())
if (it != myExporters.begin())
filter += ";;";

filter += exporter->first.fileFilter();
filter += (*it)->fileFormat().fileFilter();
}

return filter;
}

bool FileFormatManager::exportFile(const Score &score, const std::string &filename,
const FileFormat &format)
bool FileFormatManager::exportFile(const Score &score,
const std::string &filename,
const FileFormat &format,
QWidget *parent_window)
{
if (myExporters.find(format) != myExporters.end())
for (auto &exporter : myExporters)
{
try
{
myExporters.at(format)->save(filename, score);
return true;
}
catch (const std::exception &e)
if (exporter->fileFormat() == format)
{
QMessageBox msgBox;
msgBox.setText(QObject::tr("Error saving file - ") + QString(e.what()));
msgBox.exec();
try
{
exporter->save(filename, score);
return true;
}
catch (const std::exception &e)
{
QMessageBox msg(parent_window);
msg.setText(QObject::tr("Error saving file - ") +
QString(e.what()));
msg.exec();
return false;
}
}
}

Expand Down
24 changes: 5 additions & 19 deletions source/formats/fileformatmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
#define FORMATS_FILEFORMATMANAGER_H

#include <boost/optional/optional.hpp>
#include <map>
#include <memory>
#include <vector>
#include "fileformat.h"

class FileFormatImporter;
Expand All @@ -43,14 +43,14 @@ class FileFormatManager

/// Imports a file into the given score.
bool importFile(Score &score, const std::string &filename,
const FileFormat &format, QWidget *parentWindow);
const FileFormat &format, QWidget *parent_window);

/// Returns a correctly formatted file filter for a Qt file dialog.
std::string exportFileFilter() const;

/// Exports the given score to a file.
bool exportFile(const Score &score, const std::string &filename,
const FileFormat &format);
const FileFormat &format, QWidget *parent_window);

private:
template <typename Importer>
Expand All @@ -59,22 +59,8 @@ class FileFormatManager
template <typename Exporter>
void registerExporter();

std::map<FileFormat, std::unique_ptr<FileFormatImporter>> myImporters;
std::map<FileFormat, std::unique_ptr<FileFormatExporter>> myExporters;
std::vector<std::unique_ptr<FileFormatImporter>> myImporters;
std::vector<std::unique_ptr<FileFormatExporter>> myExporters;
};

template <typename Importer>
void FileFormatManager::registerImporter()
{
FileFormat format = Importer().fileFormat();
myImporters[format].reset(new Importer());
}

template <typename Exporter>
void FileFormatManager::registerExporter()
{
FileFormat format = Exporter().fileFormat();
myExporters[format].reset(new Exporter());
}

#endif
Loading

0 comments on commit 83a880e

Please sign in to comment.