LCOV - code coverage report
Current view: top level - src/palette/internal - paletteprovider.h Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 31 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              : 
      23              : #pragma once
      24              : 
      25              : #include <QAbstractItemModel>
      26              : 
      27              : #include "async/asyncable.h"
      28              : 
      29              : #include "modularity/ioc.h"
      30              : #include "interactive/iinteractive.h"
      31              : #include "ipaletteconfiguration.h"
      32              : #include "project/iprojectsession.h"
      33              : 
      34              : #include "ipaletteprovider.h"
      35              : #include "palettemodel.h"
      36              : 
      37              : namespace mu::palette {
      38              : class AbstractPaletteController;
      39              : class PaletteProvider;
      40              : 
      41              : // ========================================================
      42              : //   PaletteElementEditor
      43              : // ========================================================
      44              : 
      45              : class PaletteElementEditor : public QObject, public muse::async::Asyncable, public muse::Contextable
      46              : {
      47              :     Q_OBJECT
      48              : 
      49              :     Q_PROPERTY(bool valid READ valid CONSTANT)
      50              :     Q_PROPERTY(QString actionName READ actionName CONSTANT) // TODO: make NOTIFY instead of CONSTANT for retranslations
      51              : 
      52              :     muse::ContextInject<muse::IInteractive> interactive = { this };
      53              :     muse::ContextInject<IPaletteProvider> paletteProvider = { this };
      54              : public:
      55              :     PaletteElementEditor(const muse::modularity::ContextPtr& ctx, QObject* parent = nullptr)
      56              :         : QObject(parent), muse::Contextable(ctx) {}
      57            0 :     PaletteElementEditor(AbstractPaletteController* controller, QPersistentModelIndex paletteIndex,
      58              :                          Palette::Type type, const muse::modularity::ContextPtr& ctx, QObject* parent = nullptr)
      59            0 :         : QObject(parent), muse::Contextable(ctx),
      60            0 :         _controller(controller), _paletteIndex(paletteIndex), _type(type) {}
      61              : 
      62              :     bool valid() const;
      63              :     QString actionName() const;
      64              : 
      65              :     void setPaletteIndex(QPersistentModelIndex paletteIndex);
      66              : 
      67              :     Q_INVOKABLE void open();
      68              : 
      69              : private:
      70              :     void onElementAdded(const engraving::ElementPtr element);
      71              : 
      72              :     AbstractPaletteController* _controller = nullptr;
      73              :     QPersistentModelIndex _paletteIndex;
      74              :     Palette::Type _type = Palette::Type::Unknown;
      75              : };
      76              : 
      77              : // ========================================================
      78              : //   AbstractPaletteController
      79              : // ========================================================
      80              : 
      81              : class AbstractPaletteController : public QObject, public muse::Contextable
      82              : {
      83              :     Q_OBJECT
      84              : 
      85              :     /// Whether dropping new elements to this palette is generally allowed
      86              :     Q_PROPERTY(bool canDropElements READ canDropElements CONSTANT)
      87              : 
      88            0 :     virtual bool canDropElements() const { return false; }
      89              : 
      90              : public:
      91              :     enum class RemoveAction {
      92              :         NoAction,
      93              :         Hide,
      94              :         DeletePermanently,
      95              :         AutoAction
      96              :     };
      97              : 
      98            0 :     AbstractPaletteController(const muse::modularity::ContextPtr& ctx, QObject* parent = nullptr)
      99            0 :         : QObject(parent), muse::Contextable(ctx) {}
     100              : 
     101            0 :     Q_INVOKABLE virtual Qt::DropAction dropAction(const QVariantMap& mimeData, Qt::DropAction proposedAction,
     102              :                                                   const QModelIndex& parent, bool internal) const
     103              :     {
     104              :         Q_UNUSED(mimeData);
     105              :         Q_UNUSED(proposedAction);
     106              :         Q_UNUSED(parent);
     107              :         Q_UNUSED(internal);
     108            0 :         return Qt::IgnoreAction;
     109              :     }
     110              : 
     111              :     Q_INVOKABLE virtual bool move(const QModelIndex& sourceParent, int sourceRow, const QModelIndex& destinationParent,
     112              :                                   int destinationChild) = 0;
     113              :     Q_INVOKABLE virtual bool insert(const QModelIndex& parent, int row, const QVariantMap& mimeData, Qt::DropAction action) = 0;
     114              :     Q_INVOKABLE virtual bool insertNewItem(const QModelIndex& parent, int row, const QString& name) = 0;
     115              :     Q_INVOKABLE virtual void remove(const QModelIndex&) = 0;
     116              :     Q_INVOKABLE virtual void removeSelection(const QModelIndexList&, const QModelIndex& parent = QModelIndex()) = 0;
     117              : 
     118            0 :     Q_INVOKABLE virtual bool canEdit(const QModelIndex&) const { return false; }
     119              : 
     120            0 :     Q_INVOKABLE virtual void editPaletteProperties(const QModelIndex& index) { Q_UNUSED(index); }
     121            0 :     Q_INVOKABLE virtual void editCellProperties(const QModelIndex& index) { Q_UNUSED(index); }
     122              : 
     123            0 :     Q_INVOKABLE virtual bool applyPaletteElement(const QModelIndex& index, Qt::KeyboardModifiers modifiers)
     124              :     {
     125              :         Q_UNUSED(index);
     126              :         Q_UNUSED(modifiers);
     127            0 :         return false;
     128              :     }
     129              : 
     130              :     Q_INVOKABLE mu::palette::PaletteElementEditor* elementEditor(const QModelIndex& index);
     131              : 
     132              : private:
     133              :     QMap<Palette::Type, PaletteElementEditor*> m_paletteElementEditorMap;
     134              : };
     135              : 
     136              : // ========================================================
     137              : //   UserPaletteController
     138              : // ========================================================
     139              : 
     140              : class UserPaletteController : public AbstractPaletteController, public muse::async::Asyncable
     141              : {
     142              :     Q_OBJECT
     143              : 
     144              :     muse::GlobalInject<IPaletteConfiguration> configuration;
     145              :     muse::ContextInject<project::IProjectSession> projectSession = { this };
     146              :     muse::ContextInject<muse::IInteractive> interactive = { this };
     147              : 
     148              :     QAbstractItemModel* _model;
     149              :     PaletteTreeModel* _userPalette;
     150              : 
     151              :     bool _visible = true;
     152              :     bool _custom = false;
     153              :     bool _filterCustom = false;
     154              : 
     155              :     bool _userEditable = true;
     156              : 
     157            0 :     bool canDropElements() const override { return _userEditable; }
     158              : 
     159              :     muse::async::Promise<RemoveAction> showHideOrDeleteDialog(const std::string& question) const;
     160              :     void queryRemove(const QModelIndexList&, int customCount);
     161              : 
     162              :     enum RemoveActionConfirmationType {
     163              :         NoConfirmation,
     164              :         CustomCellHideDeleteConfirmation,
     165              :         CustomPaletteHideDeleteConfirmation
     166              :     };
     167              : 
     168              :     void remove(const QModelIndexList&, AbstractPaletteController::RemoveAction);
     169              : 
     170              : protected:
     171            0 :     QAbstractItemModel* model() { return _model; }
     172            0 :     const QAbstractItemModel* model() const { return _model; }
     173              : 
     174              : public:
     175            0 :     UserPaletteController(QAbstractItemModel* m, PaletteTreeModel* userPalette, const muse::modularity::ContextPtr& ctx,
     176              :                           QObject* parent = nullptr)
     177            0 :         : AbstractPaletteController(ctx, parent), _model(m), _userPalette(userPalette) {}
     178              : 
     179              :     bool visible() const { return _visible; }
     180            0 :     void setVisible(bool val) { _visible = val; }
     181              :     bool custom() const { return _custom; }
     182            0 :     void setCustom(bool val) { _custom = val; _filterCustom = true; }
     183              : 
     184              :     Qt::DropAction dropAction(const QVariantMap& mimeData, Qt::DropAction proposedAction, const QModelIndex& parent,
     185              :                               bool internal) const override;
     186              : 
     187              :     bool move(const QModelIndex& sourceParent, int sourceRow, const QModelIndex& destinationParent, int destinationChild) override;
     188              :     bool insert(const QModelIndex& parent, int row, const QVariantMap& mimeData, Qt::DropAction action) override;
     189              :     bool insertNewItem(const QModelIndex& parent, int row, const QString& name) override;
     190              :     void remove(const QModelIndex& index) override;
     191              :     void removeSelection(const QModelIndexList&, const QModelIndex& parent = QModelIndex()) override;
     192              : 
     193              :     void editPaletteProperties(const QModelIndex& index) override;
     194              :     void editCellProperties(const QModelIndex& index) override;
     195              : 
     196            0 :     bool userEditable() const { return _userEditable; }
     197            0 :     void setUserEditable(bool val) { _userEditable = val; }
     198              : 
     199              :     bool canEdit(const QModelIndex&) const override;
     200              : 
     201              :     bool applyPaletteElement(const QModelIndex& index, Qt::KeyboardModifiers modifiers) override;
     202              : };
     203              : 
     204              : // ========================================================
     205              : //   PaletteProvider
     206              : // ========================================================
     207              : 
     208              : class PaletteProvider : public QObject, public IPaletteProvider, public muse::async::Asyncable, public muse::Contextable
     209              : {
     210              :     Q_OBJECT
     211              : 
     212              :     Q_PROPERTY(QAbstractItemModel * mainPaletteModel READ mainPaletteModel NOTIFY mainPaletteChanged)
     213              :     Q_PROPERTY(mu::palette::AbstractPaletteController * mainPaletteController READ mainPaletteController NOTIFY mainPaletteChanged)
     214              : 
     215              :     Q_PROPERTY(mu::palette::FilterPaletteTreeModel * customElementsPaletteModel READ customElementsPaletteModel CONSTANT)
     216              :     Q_PROPERTY(mu::palette::AbstractPaletteController * customElementsPaletteController READ customElementsPaletteController CONSTANT)
     217              : 
     218              :     Q_PROPERTY(bool isSinglePalette READ isSinglePalette NOTIFY isSinglePaletteChanged)
     219              :     Q_PROPERTY(bool isSingleClickToOpenPalette READ isSingleClickToOpenPalette NOTIFY isSingleClickToOpenPaletteChanged)
     220              :     Q_PROPERTY(bool isPaletteDragEnabled READ isPaletteDragEnabled NOTIFY isPaletteDragEnabledChanged)
     221              : 
     222              :     muse::GlobalInject<IPaletteConfiguration> configuration;
     223              :     muse::ContextInject<muse::IInteractive> interactive = { this };
     224              : public:
     225              : 
     226            0 :     PaletteProvider(const muse::modularity::ContextPtr& ctx, QObject* parent = nullptr)
     227            0 :         : QObject(parent), muse::Contextable(ctx)
     228              :     {
     229            0 :     }
     230              : 
     231              :     void init() override;
     232              : 
     233              :     PaletteTreeModel* userPaletteModel() const { return m_userPaletteModel; }
     234            0 :     PaletteTreePtr userPaletteTree() const override { return m_userPaletteModel->paletteTreePtr(); }
     235            0 :     muse::async::Notification userPaletteTreeChanged() const override { return m_userPaletteChanged; }
     236              :     void setUserPaletteTree(PaletteTreePtr tree) override;
     237              : 
     238              :     void setDefaultPaletteTree(PaletteTreePtr tree) override;
     239              : 
     240              :     muse::async::Channel<engraving::ElementPtr> addCustomItemRequested() const override;
     241              : 
     242              :     Q_INVOKABLE QModelIndex poolPaletteIndex(const QModelIndex& index, mu::palette::FilterPaletteTreeModel* poolPalette) const;
     243              :     Q_INVOKABLE QModelIndex customElementsPaletteIndex(const QModelIndex& index);
     244              : 
     245              :     Q_INVOKABLE mu::palette::FilterPaletteTreeModel* poolPaletteModel(const QModelIndex& index) const;
     246              :     Q_INVOKABLE mu::palette::AbstractPaletteController* poolPaletteController(mu::palette::FilterPaletteTreeModel*,
     247              :                                                                               const QModelIndex& rootIndex) const;
     248              : 
     249              :     Q_INVOKABLE QAbstractItemModel* availableExtraPalettesModel() const;
     250              :     Q_INVOKABLE bool addPalette(const QPersistentModelIndex&);
     251              : 
     252              :     Q_INVOKABLE void resetPalette(const QModelIndex&);
     253              : 
     254              :     Q_INVOKABLE bool savePalette(const QModelIndex&);
     255              :     Q_INVOKABLE bool loadPalette(const QModelIndex&);
     256              : 
     257              :     Q_INVOKABLE void setSearching(bool searching);
     258              :     Q_INVOKABLE void setFilter(const QString&);
     259              : 
     260              :     bool paletteChanged() const { return m_userPaletteModel->paletteTreeChanged(); }
     261              : 
     262              :     void write(engraving::XmlWriter&, bool pasteMode) const;
     263              :     bool read(engraving::XmlReader&, bool pasteMode);
     264              : 
     265              :     void updateCellsState(const engraving::Selection& sel) { m_userPaletteModel->updateCellsState(sel); }
     266              :     void retranslate()
     267              :     {
     268              :         m_userPaletteModel->retranslate();
     269              :         m_masterPaletteModel->retranslate();
     270              :         m_defaultPaletteModel->retranslate();
     271              :     }
     272              : 
     273              :     bool isSinglePalette() const;
     274              :     bool isSingleClickToOpenPalette() const;
     275              :     bool isPaletteDragEnabled() const;
     276              : 
     277              : signals:
     278              :     void userPaletteChanged();
     279              :     void mainPaletteChanged();
     280              : 
     281              :     void isSinglePaletteChanged();
     282              :     void isSingleClickToOpenPaletteChanged();
     283              :     void isPaletteDragEnabledChanged();
     284              : 
     285              : private slots:
     286            0 :     void notifyAboutUserPaletteChanged()
     287              :     {
     288            0 :         m_userPaletteChanged.notify();
     289            0 :         emit userPaletteChanged();
     290            0 :     }
     291              : 
     292              : private:
     293              :     enum PalettesModelRoles {
     294              :         CustomRole = Qt::UserRole + 1,
     295              :         PaletteIndexRole
     296              :     };
     297              : 
     298              :     QAbstractItemModel* mainPaletteModel();
     299              :     AbstractPaletteController* mainPaletteController();
     300              : 
     301              :     FilterPaletteTreeModel* customElementsPaletteModel();
     302              :     AbstractPaletteController* customElementsPaletteController();
     303              : 
     304              :     QString getPaletteFilename(bool open, const QString& name = "") const;
     305              : 
     306              :     void doResetPalette(const QModelIndex& index);
     307              : 
     308              :     PaletteTreeModel* m_userPaletteModel = nullptr;
     309              :     PaletteTreeModel* m_masterPaletteModel = nullptr;
     310              :     PaletteTreeModel* m_defaultPaletteModel = nullptr; // palette used by "Reset palette" action
     311              : 
     312              :     muse::async::Notification m_userPaletteChanged;
     313              : 
     314              :     bool m_isSearching = false;
     315              : 
     316              :     QSortFilterProxyModel* m_visibilityFilterModel = nullptr;
     317              :     QSortFilterProxyModel* m_searchFilterModel = nullptr;
     318              : 
     319              :     QAbstractItemModel* m_mainPalette = nullptr; // visible userPalette entries
     320              :     // PaletteTreeModel* poolPalette; // masterPalette entries not yet added to mainPalette
     321              :     FilterPaletteTreeModel* m_customPoolPalette = nullptr; // invisible userPalette entries that do not belong to masterPalette
     322              : 
     323              :     UserPaletteController* m_mainPaletteController = nullptr;
     324              :     // PaletteController* m_masterPaletteController = nullptr;
     325              :     UserPaletteController* m_customElementsPaletteController = nullptr;
     326              : 
     327              :     muse::async::Channel<engraving::ElementPtr> m_addCustomItemRequested;
     328              : };
     329              : }
        

Generated by: LCOV version 2.0-1