MuseScore/mscore/templateBrowser.cpp

220 lines
8.3 KiB
C++

//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2014 Werner Schweer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================
#include "templateBrowser.h"
#include "musescore.h"
#include "icons.h"
#include "libmscore/score.h"
namespace Ms {
//---------------------------------------------------------
// TemplateItem
//---------------------------------------------------------
class TemplateItem : public QTreeWidgetItem
{
ScoreInfo _info;
public:
TemplateItem(const ScoreInfo& i, QTreeWidgetItem* parent = 0);
const ScoreInfo& info() const { return _info; }
};
TemplateItem::TemplateItem(const ScoreInfo &i, QTreeWidgetItem *parent) : QTreeWidgetItem(parent, 0), _info(i)
{
setFlags(Qt::ItemFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemNeverHasChildren));
}
//---------------------------------------------------------
// TemplateCategory
//---------------------------------------------------------
class TemplateCategory : public QTreeWidgetItem
{
public:
TemplateCategory(QString name, QTreeWidget* parent = 0);
};
TemplateCategory::TemplateCategory(QString name, QTreeWidget *parent)
: QTreeWidgetItem(parent, 0)
{
const int nameCol = 0;
setText(nameCol, name);
// provide feedback to blind users that they have selected a category rather than a template
setData(nameCol, Qt::AccessibleTextRole, QVariant(QObject::tr("%1 category").arg(name))); // spoken by screen readers
QFont nameFont = QFont();
nameFont.setBold(true);
setFont(nameCol, nameFont);
setFlags(Qt::ItemIsEnabled);
}
//---------------------------------------------------------
// TemplateBrowser
//---------------------------------------------------------
TemplateBrowser::TemplateBrowser(QWidget* parent)
: QWidget(parent)
{
setupUi(this);
if (_showPreview) {
preview->displayInfo(false);
connect(preview, SIGNAL(doubleClicked(QString)), SIGNAL(scoreActivated(QString)));
}
else
preview->setVisible(false);
connect(templateTree, &QTreeWidget::itemSelectionChanged, this, &TemplateBrowser::scoreClicked);
connect(templateTree, &QTreeWidget::itemActivated, this, &TemplateBrowser::handleItemActivated);
templateSearch->setFilterableView(templateTree);
}
//---------------------------------------------------------
// genTemplateItem
//---------------------------------------------------------
TemplateItem* TemplateBrowser::genTemplateItem(QTreeWidgetItem* p, const QFileInfo& fi)
{
ScoreInfo si(fi);
QPixmap pm;
if (!QPixmapCache::find(fi.filePath(), &pm)) {
if (fi.completeBaseName() == "00-Blank" || fi.completeBaseName() == "Create_New_Score") {
// draw a custom thumbnail for these special templates
const QSize thumbnailSize = QSize(181,256); // A4 aspect ratio
const qreal pixelRatio = qApp->devicePixelRatio();
pm = QPixmap(thumbnailSize * pixelRatio);
pm.setDevicePixelRatio(pixelRatio);
pm.fill(Qt::transparent); // transparent at corners
QPainter painter(&pm);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(QPen(QColor(0, 0, 0, 128), 1));
painter.setBrush(Qt::white);
const qreal cornerRadius = 12.0;
painter.drawRoundedRect(QRect(QPoint(0, 0), thumbnailSize), cornerRadius, cornerRadius);
painter.end();
QPixmapCache::insert(fi.filePath(), pm);
}
}
si.setPixmap(pm);
TemplateItem* item = new TemplateItem(si, p);
if (fi.completeBaseName() == "00-Blank") {
item->setText(0, tr("Choose Instruments"));
}
else if (fi.completeBaseName() == "Create_New_Score") {
item->setText(0, tr("Create New Score…"));
}
else {
QString s(si.completeBaseName());
if (!s.isEmpty() && s[0].isNumber() && _stripNumbers)
s = s.mid(3);
s = s.replace('_', ' ');
item->setText(0, qApp->translate("Templates", s.toUtf8().constData()));
}
return item;
}
//---------------------------------------------------------
// setScores
//---------------------------------------------------------
void TemplateBrowser::setScores(QFileInfoList& s)
{
QStringList filter = { "*.mscz", "*.mscx" };
templateTree->clear(); // empty the tree
if (_showCustomCategory)
std::sort(s.begin(), s.end(), [](QFileInfo a, QFileInfo b)->bool { return a.fileName() < b.fileName(); });
TemplateCategory* customCategory = new TemplateCategory(tr("Custom Templates"));
QSet<QString> entries; //to avoid duplicates
for (const QFileInfo& fil : s) {
if (fil.isDir()) {
QString st(fil.fileName());
if (!st.isEmpty() && st[0].isNumber() && _stripNumbers)
st = st.mid(3);
st = st.replace('_', ' ');
TemplateCategory* category = new TemplateCategory(qApp->translate("Templates", st.toUtf8().data()), templateTree);
QDir dir(fil.filePath());
unsigned childCount = 0; //nbr of entries added
for (const QFileInfo& fi : dir.entryInfoList(filter, QDir::Files, QDir::Name)) {
if (entries.contains(fi.filePath()))
continue;
genTemplateItem(category, fi);
childCount++;
entries.insert(fi.filePath());
}
if (childCount == 0) {
// delete any unnecessary categories
delete category;
}
}
else if (fil.isFile()) {
QString st = fil.filePath();
if (entries.contains(st))
continue;
if (st.endsWith(".mscz") || st.endsWith(".mscx")) {
genTemplateItem(customCategory, fil);
entries.insert(st);
}
}
}
if (customCategory->childCount() > 0)
templateTree->insertTopLevelItem(1, customCategory);
templateTree->toInitialState();
templateTree->selectFirst();
}
//---------------------------------------------------------
// filter
// filter which scores are visible based on searchString
//---------------------------------------------------------
void TemplateBrowser::filter(const QString &searchString)
{
templateTree->filter(searchString);
}
//---------------------------------------------------------
// scoreClicked
//---------------------------------------------------------
void TemplateBrowser::scoreClicked()
{
QList<QTreeWidgetItem*> selectedItems = templateTree->selectedItems();
if (!selectedItems.isEmpty()) {
QTreeWidgetItem* selectedItem = selectedItems.first();
if (selectedItem) {
TemplateItem* selectedScore = static_cast<TemplateItem*>(selectedItem);
if (_showPreview)
preview->setScore(selectedScore->info());
emit scoreSelected(selectedScore->info().filePath());
return;
}
}
if (_showPreview)
preview->unsetScore();
emit scoreSelected(""); // no score selected
}
//---------------------------------------------------------
// handleItemActivated
//---------------------------------------------------------
void TemplateBrowser::handleItemActivated(QTreeWidgetItem* item)
{
if (item->flags() & Qt::ItemIsSelectable)
emit scoreActivated(static_cast<TemplateItem*>(item)->info().filePath());
}
}