LCOV - code coverage report
Current view: top level - src/palette/internal - palette.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 390 0
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2021 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : #include "palette.h"
      23              : 
      24              : #include <QMetaEnum>
      25              : 
      26              : #include "io/buffer.h"
      27              : #include "io/file.h"
      28              : #include "serialization/zipreader.h"
      29              : #include "serialization/zipwriter.h"
      30              : 
      31              : #include "translation.h"
      32              : #include "mimedatautils.h"
      33              : 
      34              : #include "engraving/dom/actionicon.h"
      35              : #include "engraving/dom/articulation.h"
      36              : #include "engraving/dom/bracket.h"
      37              : #include "engraving/dom/engravingitem.h"
      38              : #include "engraving/dom/image.h"
      39              : #include "engraving/dom/imageStore.h"
      40              : #include "engraving/dom/masterscore.h"
      41              : 
      42              : #include "palettecell.h"
      43              : #include "palettecompat.h"
      44              : 
      45              : #include "log.h"
      46              : 
      47              : using namespace mu;
      48              : using namespace mu::palette;
      49              : using namespace mu::engraving;
      50              : using namespace muse;
      51              : using namespace muse::io;
      52              : 
      53            0 : Palette::Palette(const muse::modularity::ContextPtr& iocCtx, Type t, QObject* parent)
      54            0 :     : QObject(parent), muse::Contextable(iocCtx), m_type(t)
      55              : {
      56              :     static int id = 0;
      57            0 :     m_id = QString::number(++id);
      58            0 : }
      59              : 
      60            0 : Palette::~Palette()
      61              : {
      62              :     //! NOTE Prevent double free
      63              :     //! 1. Deleting by deleting children of QObject
      64              :     //! 2. Deleting by deleting share pointer
      65            0 :     for (PaletteCellPtr& c : m_cells) {
      66            0 :         if (c->parent() == this) {
      67            0 :             c->setParent(nullptr);
      68              :         }
      69              :     }
      70            0 : }
      71              : 
      72            0 : QString Palette::id() const
      73              : {
      74            0 :     return m_id;
      75              : }
      76              : 
      77            0 : QString Palette::translatedName() const
      78              : {
      79            0 :     return muse::qtrc("palette", m_name.toUtf8());
      80              : }
      81              : 
      82            0 : void Palette::retranslate()
      83              : {
      84            0 :     for (const PaletteCellPtr& cell : m_cells) {
      85            0 :         cell->retranslate();
      86              :     }
      87            0 : }
      88              : 
      89              : /// Returns palette type if it is defined or deduces it from the palette content for
      90              : /// custom palettes.
      91            0 : Palette::Type Palette::contentType() const
      92              : {
      93            0 :     Type t = type();
      94            0 :     if (t == Type::Unknown || t == Type::Custom) {
      95            0 :         t = guessType();
      96              :     }
      97              : 
      98            0 :     if (t == Type::Unknown || t == Type::Custom) {
      99            0 :         return Type::Clef; // if no type can be deduced, use Clef type by default
     100              :     }
     101            0 :     return t;
     102              : }
     103              : 
     104            0 : PaletteCellPtr Palette::insertElement(size_t idx, ElementPtr element, const QString& name, qreal mag, const QPointF& offset,
     105              :                                       const QString& tag)
     106              : {
     107            0 :     if (element) {
     108              :         // layout may be important for comparing cells, e.g. filtering "More" popup content
     109            0 :         engravingRender()->layoutItem(element.get());
     110              :     }
     111              : 
     112            0 :     PaletteCellPtr cell = std::make_shared<PaletteCell>(iocContext(), element, name, mag, offset, tag, this);
     113              : 
     114            0 :     auto cellHandler = cellHandlerByPaletteType(m_type);
     115            0 :     if (cellHandler) {
     116            0 :         cellHandler(cell);
     117              :     }
     118              : 
     119            0 :     m_cells.emplace(m_cells.begin() + idx, cell);
     120            0 :     return cell;
     121            0 : }
     122              : 
     123            0 : PaletteCellPtr Palette::insertElement(size_t idx, ElementPtr element, const muse::TranslatableString& name, qreal mag,
     124              :                                       const QPointF& offset, const QString& tag)
     125              : {
     126            0 :     return insertElement(idx, element, name.str, mag, offset, tag);
     127              : }
     128              : 
     129            0 : PaletteCellPtr Palette::insertActionIcon(size_t idx, ActionIconType type, double mag)
     130              : {
     131            0 :     auto icon = std::make_shared<ActionIcon>(paletteScoreProvider()->paletteScore()->dummy());
     132            0 :     icon->setActionType(type);
     133            0 :     return insertElement(idx, icon, icon->title().qTranslated(), mag);
     134            0 : }
     135              : 
     136            0 : PaletteCellPtr Palette::appendElement(ElementPtr element, const QString& name, qreal mag, const QPointF& offset, const QString& tag)
     137              : {
     138            0 :     if (element) {
     139              :         // layout may be important for comparing cells, e.g. filtering "More" popup content
     140            0 :         engravingRender()->layoutItem(element.get());
     141              :     }
     142              : 
     143            0 :     PaletteCellPtr cell = std::make_shared<PaletteCell>(iocContext(), element, name, mag, offset, tag, this);
     144              : 
     145            0 :     auto cellHandler = cellHandlerByPaletteType(m_type);
     146            0 :     if (cellHandler) {
     147            0 :         cellHandler(cell);
     148              :     }
     149              : 
     150            0 :     m_cells.emplace_back(cell);
     151            0 :     return cell;
     152            0 : }
     153              : 
     154            0 : PaletteCellPtr Palette::appendElement(ElementPtr element, const muse::TranslatableString& name, qreal mag, const QPointF& offset,
     155              :                                       const QString& tag)
     156              : {
     157            0 :     return appendElement(element, name.str, mag, offset, tag);
     158              : }
     159              : 
     160            0 : PaletteCellPtr Palette::appendActionIcon(ActionIconType type, double mag)
     161              : {
     162            0 :     auto icon = std::make_shared<ActionIcon>(paletteScoreProvider()->paletteScore()->dummy());
     163            0 :     icon->setActionType(type);
     164            0 :     return appendElement(icon, icon->title().qTranslated(), mag);
     165            0 : }
     166              : 
     167            0 : bool Palette::insertCell(size_t idx, PaletteCellPtr cell)
     168              : {
     169            0 :     return insertCells(idx, { cell });
     170            0 : }
     171              : 
     172            0 : bool Palette::insertCells(size_t idx, std::vector<PaletteCellPtr> cells)
     173              : {
     174            0 :     if (idx > m_cells.size()) {
     175            0 :         return false;
     176              :     }
     177              : 
     178            0 :     for (PaletteCellPtr& c : cells) {
     179            0 :         c->setParent(this);
     180              :     }
     181              : 
     182            0 :     m_cells.insert(m_cells.begin() + idx, std::make_move_iterator(cells.begin()),
     183              :                    std::make_move_iterator(cells.end()));
     184              : 
     185            0 :     return true;
     186              : }
     187              : 
     188            0 : bool Palette::removeCell(PaletteCellPtr cell)
     189              : {
     190            0 :     return removeCells({ cell });
     191            0 : }
     192              : 
     193            0 : bool Palette::removeCells(std::vector<PaletteCellPtr> cells)
     194              : {
     195            0 :     for (PaletteCellPtr& c : cells) {
     196            0 :         c->setParent(nullptr);
     197            0 :         m_cells.erase(std::remove(m_cells.begin(), m_cells.end(), c), m_cells.end());
     198              :     }
     199              : 
     200            0 :     return true;
     201              : }
     202              : 
     203            0 : PaletteCellPtr Palette::takeCell(size_t idx)
     204              : {
     205            0 :     std::vector<PaletteCellPtr> cells = takeCells(idx, 1);
     206            0 :     return !cells.empty() ? cells.front() : nullptr;
     207            0 : }
     208              : 
     209            0 : std::vector<PaletteCellPtr> Palette::takeCells(size_t idx, size_t count)
     210              : {
     211            0 :     std::vector<PaletteCellPtr> removedCells;
     212            0 :     removedCells.reserve(count);
     213              : 
     214            0 :     if (idx + count > m_cells.size()) {
     215            0 :         return removedCells;
     216              :     }
     217              : 
     218            0 :     auto removeBegin = m_cells.begin() + idx;
     219            0 :     auto removeEnd = removeBegin + count;
     220              : 
     221            0 :     removedCells.insert(removedCells.end(), std::make_move_iterator(removeBegin), std::make_move_iterator(removeEnd));
     222            0 :     m_cells.erase(removeBegin, removeEnd);
     223              : 
     224            0 :     for (PaletteCellPtr& c : removedCells) {
     225            0 :         c->setParent(nullptr);
     226              :     }
     227              : 
     228            0 :     return removedCells;
     229            0 : }
     230              : 
     231              : // Helper function to compare two Elements
     232            0 : static bool isEquivalent(const EngravingItem& e1, const EngravingItem& e2)
     233              : {
     234            0 :     return e1.type() == e2.type()
     235            0 :            && e1.subtype() == e2.subtype()
     236            0 :            && e1.mimeData() == e2.mimeData();
     237              : }
     238              : 
     239            0 : int Palette::indexOfCell(const PaletteCell& cell, bool matchName) const
     240              : {
     241            0 :     const EngravingItem* el = cell.element.get();
     242            0 :     if (!el) {
     243            0 :         return -1;
     244              :     }
     245              : 
     246            0 :     for (size_t i = 0; i < m_cells.size(); ++i) {
     247            0 :         const PaletteCell& localCell = *m_cells[i];
     248            0 :         if (matchName && localCell.name != cell.name) {
     249            0 :             continue;
     250              :         }
     251              : 
     252            0 :         const EngravingItem* exElement = localCell.element.get();
     253            0 :         if (exElement && !isEquivalent(*exElement, *el)) {
     254            0 :             continue;
     255              :         }
     256              : 
     257            0 :         if (localCell.drawStaff != cell.drawStaff
     258            0 :             || localCell.xoffset != cell.xoffset
     259            0 :             || localCell.yoffset != cell.yoffset
     260            0 :             || localCell.mag != cell.mag
     261            0 :             || localCell.readOnly != cell.readOnly
     262            0 :             || localCell.visible != cell.visible
     263            0 :             || localCell.custom != cell.custom
     264              :             ) {
     265            0 :             continue;
     266              :         }
     267              : 
     268            0 :         return int(i);
     269              :     }
     270              : 
     271            0 :     return -1;
     272              : }
     273              : 
     274            0 : QSize Palette::scaledGridSize() const
     275              : {
     276            0 :     return gridSize() * configuration()->paletteScaling();
     277              : }
     278              : 
     279            0 : bool Palette::read(XmlReader& e, bool pasteMode)
     280              : {
     281            0 :     m_name = e.attribute("name");
     282            0 :     m_type = Type::Unknown;
     283            0 :     while (e.readNextStartElement()) {
     284            0 :         const AsciiStringView tag(e.name());
     285            0 :         if (tag == "gridWidth") {
     286            0 :             m_gridSize.setWidth(e.readDouble());
     287            0 :         } else if (tag == "gridHeight") {
     288            0 :             m_gridSize.setHeight(e.readDouble());
     289            0 :         } else if (tag == "mag") {
     290            0 :             m_mag = e.readDouble();
     291            0 :         } else if (tag == "grid") {
     292            0 :             m_drawGrid = e.readInt();
     293            0 :         } else if (tag == "yoffset") {
     294            0 :             m_yOffset = e.readDouble();
     295            0 :         } else if (tag == "drumPalette") { // obsolete
     296            0 :             e.skipCurrentElement();
     297            0 :         } else if (tag == "type") {
     298            0 :             ByteArray ba = e.readText().toAscii();
     299            0 :             bool ok = true;
     300            0 :             const int t = QMetaEnum::fromType<Type>().keyToValue(ba.constChar(), &ok);
     301            0 :             if (ok) {
     302            0 :                 m_type = Type(t);
     303              :             }
     304            0 :         } else if (tag == "visible") {
     305            0 :             m_isVisible = e.readBool();
     306            0 :         } else if (pasteMode && tag == "expanded") {
     307            0 :             m_isExpanded = e.readBool();
     308            0 :         } else if (tag == "editable") {
     309            0 :             m_isEditable = e.readBool();
     310            0 :         } else if (tag == "Cell") {
     311            0 :             PaletteCellPtr cell = std::make_shared<PaletteCell>(iocContext(), this);
     312            0 :             if (!cell->read(e, pasteMode)) {
     313            0 :                 continue;
     314              :             }
     315              : 
     316            0 :             auto cellHandler = cellHandlerByPaletteType(m_type);
     317            0 :             if (cellHandler) {
     318            0 :                 cellHandler(cell);
     319              :             }
     320              : 
     321            0 :             m_cells.push_back(cell);
     322            0 :         } else {
     323            0 :             e.unknown();
     324              :         }
     325              :     }
     326              :     // (from old palette): make sure hgrid and vgrid are not 0, we divide by them later
     327            0 :     if (m_gridSize.width() <= 0) {
     328            0 :         m_gridSize.setWidth(28);
     329              :     }
     330            0 :     if (m_gridSize.height() <= 0) {
     331            0 :         m_gridSize.setHeight(28);
     332              :     }
     333              : 
     334            0 :     if (m_type == Type::Unknown) {
     335            0 :         m_type = guessType();
     336              :     }
     337              : 
     338            0 :     PaletteCompat::removeOldItemsIfNeeded(*this);
     339            0 :     PaletteCompat::addNewItemsIfNeeded(*this, paletteScoreProvider()->paletteScore());
     340              : 
     341            0 :     return true;
     342              : }
     343              : 
     344            0 : QByteArray Palette::toMimeData() const
     345              : {
     346            0 :     return ::toMimeData(this);
     347              : }
     348              : 
     349            0 : void Palette::write(XmlWriter& xml, bool pasteMode) const
     350              : {
     351            0 :     xml.startElement("Palette", { { "name", m_name } });
     352            0 :     xml.tag("type", QMetaEnum::fromType<Type>().valueToKey(int(m_type)));
     353            0 :     xml.tag("gridWidth", m_gridSize.width());
     354            0 :     xml.tag("gridHeight", m_gridSize.height());
     355            0 :     xml.tag("mag", m_mag);
     356            0 :     if (m_drawGrid) {
     357            0 :         xml.tag("grid", m_drawGrid);
     358              :     }
     359              : 
     360            0 :     if (!RealIsNull(m_yOffset)) {
     361            0 :         xml.tag("yoffset", m_yOffset);
     362              :     }
     363              : 
     364            0 :     xml.tag("visible", m_isVisible, true);
     365            0 :     xml.tag("editable", m_isEditable, true);
     366              : 
     367            0 :     if (pasteMode) {
     368            0 :         xml.tag("expanded", m_isExpanded, false);
     369              :     }
     370              : 
     371            0 :     for (const PaletteCellPtr& cell : m_cells) {
     372            0 :         if (!cell) { // from old palette, not sure if it is still needed
     373            0 :             xml.tag("Cell");
     374            0 :             continue;
     375              :         }
     376            0 :         cell->write(xml, pasteMode);
     377              :     }
     378            0 :     xml.endElement();
     379            0 : }
     380              : 
     381            0 : PalettePtr Palette::fromMimeData(const QByteArray& data, const muse::modularity::ContextPtr& iocCtx)
     382              : {
     383            0 :     return ::fromMimeData<Palette>(data, "Palette", iocCtx);
     384              : }
     385              : 
     386            0 : bool Palette::readFromFile(const QString& p)
     387              : {
     388            0 :     QString path(p);
     389            0 :     if (!path.endsWith(".mpal", Qt::CaseInsensitive)) {
     390            0 :         path += ".mpal";
     391              :     }
     392              : 
     393            0 :     ZipReader f(path);
     394            0 :     if (!f.exists()) {
     395            0 :         LOGD("palette <%s> not found", qPrintable(path));
     396            0 :         return false;
     397              :     }
     398            0 :     m_cells.clear();
     399              : 
     400            0 :     ByteArray ba = f.fileData("META-INF/container.xml");
     401              : 
     402            0 :     XmlReader e(ba);
     403              :     // extract first rootfile
     404            0 :     QString rootfile;
     405            0 :     std::vector<std::string> images;
     406            0 :     while (e.readNextStartElement()) {
     407            0 :         if (e.name() != "container") {
     408            0 :             e.unknown();
     409            0 :             break;
     410              :         }
     411            0 :         while (e.readNextStartElement()) {
     412            0 :             if (e.name() != "rootfiles") {
     413            0 :                 e.unknown();
     414            0 :                 break;
     415              :             }
     416            0 :             while (e.readNextStartElement()) {
     417            0 :                 const AsciiStringView tag(e.name());
     418              : 
     419            0 :                 if (tag == "rootfile") {
     420            0 :                     if (rootfile.isEmpty()) {
     421            0 :                         rootfile = e.attribute("full-path");
     422              :                     }
     423            0 :                     e.readNext();
     424            0 :                 } else if (tag == "file") {
     425            0 :                     images.push_back(e.readAsciiText().ascii());
     426              :                 } else {
     427            0 :                     e.unknown();
     428              :                 }
     429              :             }
     430              :         }
     431              :     }
     432              :     //
     433              :     // load images
     434              :     //
     435            0 :     for (const std::string& s : images) {
     436            0 :         imageStore.add(s, f.fileData(s));
     437              :     }
     438              : 
     439            0 :     if (rootfile.isEmpty()) {
     440            0 :         LOGD("can't find rootfile in: %s", qPrintable(path));
     441            0 :         return false;
     442              :     }
     443              : 
     444            0 :     ba = f.fileData(rootfile.toStdString());
     445            0 :     e.setData(ba);
     446            0 :     while (e.readNextStartElement()) {
     447            0 :         if (e.name() == "museScore") {
     448            0 :             QString version = e.attribute("version");
     449            0 :             QStringList sl = version.split('.');
     450            0 :             int mscVersion = sl[0].toInt() * 100 + sl[1].toInt();
     451            0 :             paletteScoreProvider()->paletteScore()->setMscVersion(mscVersion);
     452              : 
     453            0 :             while (e.readNextStartElement()) {
     454            0 :                 if (e.name() == "Palette") {
     455            0 :                     read(e, false);
     456              :                 } else {
     457            0 :                     e.unknown();
     458              :                 }
     459              :             }
     460            0 :         } else {
     461            0 :             e.unknown();
     462              :         }
     463              :     }
     464            0 :     return true;
     465            0 : }
     466              : 
     467            0 : bool Palette::writeToFile(const QString& p) const
     468              : {
     469            0 :     std::set<ImageStoreItem*> images;
     470            0 :     for (const PaletteCellPtr& cell : m_cells) {
     471            0 :         if (!cell || !cell->element || !cell->element->isImage()) {
     472            0 :             continue;
     473              :         }
     474            0 :         images.insert(toImage(cell->element.get())->storeItem());
     475              :     }
     476              : 
     477            0 :     QString path(p);
     478            0 :     if (!path.endsWith(".mpal", Qt::CaseInsensitive)) {
     479            0 :         path += ".mpal";
     480              :     }
     481              : 
     482            0 :     auto zipBuf = Buffer::opened(IODevice::WriteOnly);
     483            0 :     ZipWriter f(&zipBuf);
     484            0 :     if (f.hasError()) {
     485            0 :         showWritingPaletteError(path);
     486            0 :         return false;
     487              :     }
     488              : 
     489            0 :     auto cbuf = Buffer::opened(IODevice::ReadWrite);
     490            0 :     XmlWriter xml(&cbuf);
     491            0 :     xml.startDocument();
     492            0 :     xml.startElement("container");
     493            0 :     xml.startElement("rootfiles");
     494            0 :     xml.startElement("rootfile", { { "full-path", "palette.xml" } });
     495            0 :     xml.endElement();
     496            0 :     for (const ImageStoreItem* ip : images) {
     497            0 :         std::string ipath = "Pictures/" + ip->hashName();
     498            0 :         xml.tag("file", ipath);
     499            0 :     }
     500            0 :     xml.endElement();
     501            0 :     xml.endElement();
     502            0 :     xml.flush();
     503            0 :     cbuf.seek(0);
     504              :     //f.addDirectory("META-INF");
     505              :     //f.addDirectory("Pictures");
     506            0 :     f.addFile("META-INF/container.xml", cbuf.data());
     507              : 
     508              :     // save images
     509            0 :     for (const ImageStoreItem* ip : images) {
     510            0 :         std::string ipath = "Pictures/" + ip->hashName();
     511            0 :         f.addFile(ipath, ip->buffer());
     512            0 :     }
     513              :     {
     514            0 :         Buffer cbuf1 = Buffer::opened(IODevice::ReadWrite);
     515            0 :         XmlWriter xml1(&cbuf1);
     516            0 :         xml1.startDocument();
     517            0 :         xml1.startElement("museScore", { { "version", Constants::MSC_VERSION_STR } });
     518            0 :         write(xml1, false);
     519            0 :         xml1.endElement();
     520            0 :         xml1.flush();
     521            0 :         cbuf1.close();
     522            0 :         f.addFile("palette.xml", cbuf1.data());
     523            0 :     }
     524            0 :     f.close();
     525            0 :     if (f.hasError()) {
     526            0 :         showWritingPaletteError(path);
     527            0 :         return false;
     528              :     }
     529              : 
     530            0 :     if (!File::writeFile(path, zipBuf.data())) {
     531            0 :         showWritingPaletteError(path);
     532            0 :         return false;
     533              :     }
     534              : 
     535            0 :     File::setPermissionsAllowedForAll(path);
     536            0 :     return true;
     537            0 : }
     538              : 
     539            0 : void Palette::showWritingPaletteError(const QString& path) const
     540              : {
     541            0 :     std::string title = muse::trc("palette", "Writing palette file");
     542            0 :     std::string message = muse::qtrc("palette", "Writing palette file\n%1\nfailed.").arg(path).toStdString();
     543            0 :     interactive()->error(title, message);
     544            0 : }
     545              : 
     546            0 : Palette::Type Palette::guessType() const
     547              : {
     548            0 :     if (m_cells.empty()) {
     549            0 :         return Type::Custom;
     550              :     }
     551              : 
     552            0 :     const EngravingItem* e = nullptr;
     553            0 :     for (const PaletteCellPtr& cell : m_cells) {
     554            0 :         if (cell->element) {
     555            0 :             e = cell->element.get();
     556            0 :             break;
     557              :         }
     558              :     }
     559              : 
     560            0 :     if (!e) {
     561            0 :         return Type::Custom;
     562              :     }
     563              : 
     564            0 :     switch (e->type()) {
     565            0 :     case ElementType::CLEF:
     566            0 :         return Type::Clef;
     567            0 :     case ElementType::KEYSIG:
     568            0 :         return Type::KeySig;
     569            0 :     case ElementType::TIMESIG:
     570            0 :         return Type::TimeSig;
     571            0 :     case ElementType::BRACKET:
     572              :     case ElementType::BRACKET_ITEM:
     573            0 :         return Type::Bracket;
     574            0 :     case ElementType::ACCIDENTAL:
     575            0 :         return Type::Accidental;
     576            0 :     case ElementType::ARTICULATION:
     577              :     case ElementType::BEND:
     578            0 :         return toArticulation(e)->isOrnament() ? Type::Ornament : Type::Articulation;
     579            0 :     case ElementType::FERMATA:
     580            0 :         return Type::Articulation;
     581            0 :     case ElementType::BREATH:
     582            0 :         return Type::Breath;
     583            0 :     case ElementType::NOTEHEAD:
     584            0 :         return Type::NoteHead;
     585            0 :     case ElementType::BAR_LINE:
     586            0 :         return Type::BarLine;
     587            0 :     case ElementType::ARPEGGIO:
     588              :     case ElementType::CHORD_BRACKET:
     589              :     case ElementType::GLISSANDO:
     590            0 :         return Type::Arpeggio;
     591            0 :     case ElementType::TREMOLO_SINGLECHORD:
     592              :     case ElementType::TREMOLO_TWOCHORD:
     593            0 :         return Type::Tremolo;
     594            0 :     case ElementType::TEMPO_TEXT:
     595            0 :         return Type::Tempo;
     596            0 :     case ElementType::DYNAMIC:
     597            0 :         return Type::Dynamic;
     598            0 :     case ElementType::FINGERING:
     599            0 :         return Type::Fingering;
     600            0 :     case ElementType::MARKER:
     601              :     case ElementType::JUMP:
     602              :     case ElementType::MEASURE_REPEAT:
     603            0 :         return Type::Repeat;
     604            0 :     case ElementType::FRET_DIAGRAM:
     605            0 :         return Type::FretboardDiagram;
     606            0 :     case ElementType::BAGPIPE_EMBELLISHMENT:
     607            0 :         return Type::BagpipeEmbellishment;
     608            0 :     case ElementType::LAYOUT_BREAK:
     609              :     case ElementType::SPACER:
     610            0 :         return Type::Layout;
     611            0 :     case ElementType::SYMBOL:
     612            0 :         return Type::Accordion;
     613            0 :     case ElementType::HARP_DIAGRAM:
     614            0 :         return Type::Harp;
     615            0 :     case ElementType::STRING_TUNINGS:
     616            0 :         return Type::StringTunings;
     617            0 :     case ElementType::ACTION_ICON: {
     618            0 :         const ActionIcon* action = toActionIcon(e);
     619            0 :         ActionIconType actionType = action->actionType();
     620              : 
     621              :         static const std::set<ActionIconType> beamTypes = {
     622              :             ActionIconType::BEAM_AUTO,
     623              :             ActionIconType::BEAM_NONE,
     624              :             ActionIconType::BEAM_BREAK_LEFT,
     625              :             ActionIconType::BEAM_BREAK_INNER_8TH,
     626              :             ActionIconType::BEAM_BREAK_INNER_16TH,
     627              :             ActionIconType::BEAM_JOIN,
     628              :             ActionIconType::BEAM_FEATHERED_DECELERATE,
     629              :             ActionIconType::BEAM_FEATHERED_ACCELERATE
     630            0 :         };
     631              : 
     632              :         static const std::set<ActionIconType> graceTypes = {
     633              :             ActionIconType::ACCIACCATURA,
     634              :             ActionIconType::APPOGGIATURA,
     635              :             ActionIconType::GRACE4,
     636              :             ActionIconType::GRACE16,
     637              :             ActionIconType::GRACE32,
     638              :             ActionIconType::GRACE8_AFTER,
     639              :             ActionIconType::GRACE16_AFTER,
     640              :             ActionIconType::GRACE32_AFTER
     641            0 :         };
     642              : 
     643              :         static const std::set<ActionIconType> layoutTypes = {
     644              :             ActionIconType::VFRAME,
     645              :             ActionIconType::HFRAME,
     646              :             ActionIconType::TFRAME,
     647              :             ActionIconType::FFRAME,
     648              :             ActionIconType::STAFF_TYPE_CHANGE,
     649              :             ActionIconType::MEASURE
     650            0 :         };
     651              : 
     652            0 :         if (beamTypes.contains(actionType)) {
     653            0 :             return Type::Beam;
     654              :         }
     655            0 :         if (graceTypes.contains(actionType)) {
     656            0 :             return Type::GraceNote;
     657              :         }
     658            0 :         if (layoutTypes.contains(actionType)) {
     659            0 :             return Type::Layout;
     660              :         }
     661            0 :         return Type::Custom;
     662              :     }
     663            0 :     default: {
     664            0 :         if (e->isSpanner()) {
     665            0 :             return Type::Line;
     666              :         }
     667            0 :         if (e->isTextBase()) {
     668            0 :             return Type::Text;
     669              :         }
     670              :     }
     671              :     }
     672              : 
     673            0 :     return Type::Custom;
     674              : }
     675              : 
     676            0 : std::function<void(PaletteCellPtr)> Palette::cellHandlerByPaletteType(const Palette::Type& type) const
     677              : {
     678            0 :     switch (type) {
     679            0 :     case Type::Bracket:
     680            0 :         return [](PaletteCellPtr cellPtr) {
     681            0 :             if (!cellPtr || !cellPtr->element || !cellPtr->element.get()->isBracket()) {
     682            0 :                 return;
     683              :             }
     684              : 
     685            0 :             Bracket* bracket = toBracket(cellPtr->element.get());
     686              : 
     687            0 :             if (bracket->bracketType() == BracketType::BRACE) {
     688            0 :                 bracket->setStaffSpan(0, 1);
     689            0 :                 cellPtr->mag = 1.2;
     690              :             }
     691            0 :         };
     692            0 :     default:
     693            0 :         return nullptr;
     694              :     }
     695              : }
        

Generated by: LCOV version 2.0-1