LCOV - code coverage report
Current view: top level - src/propertiespanel/qml/MuseScore/PropertiesPanel - propertiespanelabstractproxymodel.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 113 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 "propertiespanelabstractproxymodel.h"
      23              : 
      24              : #include "propertiespanelabstractmodel.h"
      25              : #include "propertiespanelmodelfactory.h"
      26              : 
      27              : using namespace mu::propertiespanel;
      28              : 
      29            0 : PropertiesPanelAbstractProxyModel::PropertiesPanelAbstractProxyModel(QObject* parent, const muse::modularity::ContextPtr& iocCtx,
      30            0 :                                                                      IElementRepositoryService* repository)
      31            0 :     : PropertiesPanelAbstractModel(parent, iocCtx, repository)
      32              : {
      33            0 : }
      34              : 
      35            0 : QVariantList PropertiesPanelAbstractProxyModel::models() const
      36              : {
      37            0 :     QVariantList objects;
      38              : 
      39            0 :     for (PropertiesPanelAbstractModel* model : modelList()) {
      40            0 :         objects << QVariant::fromValue(qobject_cast<QObject*>(model));
      41            0 :     }
      42              : 
      43            0 :     return objects;
      44            0 : }
      45              : 
      46            0 : PropertiesPanelAbstractModel* PropertiesPanelAbstractProxyModel::modelByType(PropertiesPanelModelType type) const
      47              : {
      48            0 :     return m_models.value(type);
      49              : }
      50              : 
      51            0 : PropertiesPanelAbstractModel* PropertiesPanelAbstractProxyModel::firstModel() const
      52              : {
      53            0 :     if (m_models.empty()) {
      54            0 :         return nullptr;
      55              :     }
      56              : 
      57            0 :     return m_models.values().first();
      58              : }
      59              : 
      60            0 : PropertiesPanelModelType PropertiesPanelAbstractProxyModel::defaultSubModelType() const
      61              : {
      62            0 :     return m_defaultSubModelType;
      63              : }
      64              : 
      65            0 : void PropertiesPanelAbstractProxyModel::setDefaultSubModelType(PropertiesPanelModelType modelType)
      66              : {
      67            0 :     if (m_defaultSubModelType == modelType) {
      68            0 :         return;
      69              :     }
      70              : 
      71            0 :     m_defaultSubModelType = modelType;
      72            0 :     emit defaultSubModelTypeChanged();
      73              : }
      74              : 
      75            0 : bool PropertiesPanelAbstractProxyModel::isMultiModel() const
      76              : {
      77            0 :     return m_models.count() > 1;
      78              : }
      79              : 
      80            0 : void PropertiesPanelAbstractProxyModel::requestElements()
      81              : {
      82            0 :     for (PropertiesPanelAbstractModel* model : modelList()) {
      83            0 :         model->requestElements();
      84            0 :     }
      85            0 : }
      86              : 
      87            0 : void PropertiesPanelAbstractProxyModel::disconnectAll()
      88              : {
      89            0 :     for (PropertiesPanelAbstractModel* model : modelList()) {
      90            0 :         model->disconnectAll();
      91            0 :     }
      92              : 
      93            0 :     PropertiesPanelAbstractModel::disconnectAll();
      94            0 : }
      95              : 
      96            0 : bool PropertiesPanelAbstractProxyModel::isEmpty() const
      97              : {
      98            0 :     for (const PropertiesPanelAbstractModel* model : modelList()) {
      99            0 :         if (!model->isEmpty()) {
     100            0 :             return false;
     101              :         }
     102            0 :     }
     103              : 
     104            0 :     return true;
     105              : }
     106              : 
     107            0 : void PropertiesPanelAbstractProxyModel::setModels(const QList<PropertiesPanelAbstractModel*>& models)
     108              : {
     109            0 :     QList<PropertiesPanelAbstractModel*> currentModels = modelList();
     110              : 
     111            0 :     for (PropertiesPanelAbstractModel* model : currentModels) {
     112            0 :         if (models.contains(model)) {
     113            0 :             continue;
     114              :         }
     115              : 
     116            0 :         auto oldModel = m_models.take(model->modelType());
     117              : 
     118              :         //! NOTE: may run synchronously from a model's own property-change callback;
     119              :         //! deleting immediately would destroy "this" mid-call, so defer it.
     120              :         //! Disconnect now so it (and its submodels) doesn't react to further updates
     121              :         //! while it awaits destruction
     122            0 :         oldModel->disconnectAll();
     123            0 :         oldModel->deleteLater();
     124              :     }
     125              : 
     126            0 :     for (PropertiesPanelAbstractModel* model : models) {
     127            0 :         if (!model) {
     128            0 :             continue;
     129              :         }
     130              : 
     131            0 :         PropertiesPanelModelType modelType = model->modelType();
     132              : 
     133            0 :         if (m_models.contains(modelType)) {
     134            0 :             continue;
     135              :         }
     136              : 
     137            0 :         connect(model, &PropertiesPanelAbstractModel::isEmptyChanged, this, [this]() {
     138            0 :             emit isEmptyChanged();
     139            0 :         });
     140              : 
     141            0 :         connect(model, &PropertiesPanelAbstractModel::requestReloadPropertiesPanelListModel, this,
     142            0 :                 &PropertiesPanelAbstractModel::requestReloadPropertiesPanelListModel);
     143              : 
     144            0 :         m_models[modelType] = model;
     145              :     }
     146              : 
     147            0 :     emit modelsChanged();
     148            0 : }
     149              : 
     150            0 : void PropertiesPanelAbstractProxyModel::onCurrentNotationChanged()
     151              : {
     152            0 :     for (PropertiesPanelAbstractModel* model : modelList()) {
     153            0 :         model->onCurrentNotationChanged();
     154            0 :     }
     155              : 
     156            0 :     PropertiesPanelAbstractModel::onCurrentNotationChanged();
     157            0 : }
     158              : 
     159            0 : void PropertiesPanelAbstractProxyModel::onNotationChanged(const engraving::PropertyIdSet& changedPropertyIdSet,
     160              :                                                           const engraving::StyleIdSet& changedStyleIdSet)
     161              : {
     162            0 :     for (PropertiesPanelAbstractModel* model : modelList()) {
     163            0 :         if (!model->shouldUpdateOnScoreChange()) {
     164            0 :             continue;
     165              :         }
     166              : 
     167            0 :         if (!model->shouldUpdateWhenEmpty() && model->isEmpty()) {
     168            0 :             continue;
     169              :         }
     170              : 
     171            0 :         if (!model->shouldUpdateOnEmptyPropertyAndStyleIdSets()) {
     172            0 :             if (changedPropertyIdSet.empty() && changedStyleIdSet.empty()) {
     173            0 :                 continue;
     174              :             }
     175              :         }
     176              : 
     177            0 :         mu::engraving::PropertyIdSet expandedPropertyIdSet = model->propertyIdSetFromStyleIdSet(changedStyleIdSet);
     178            0 :         expandedPropertyIdSet.insert(changedPropertyIdSet.cbegin(), changedPropertyIdSet.cend());
     179            0 :         model->onNotationChanged(expandedPropertyIdSet, changedStyleIdSet);
     180            0 :     }
     181              : 
     182            0 :     PropertiesPanelAbstractModel::onNotationChanged(changedPropertyIdSet, changedStyleIdSet);
     183            0 : }
     184              : 
     185            0 : void PropertiesPanelAbstractProxyModel::updateModels(const ElementKeySet& newElementKeySet)
     186              : {
     187            0 :     QList<PropertiesPanelAbstractModel*> models;
     188              : 
     189            0 :     for (const ElementKey& elementKey : newElementKeySet) {
     190            0 :         PropertiesPanelModelType modelType = PropertiesPanelAbstractModel::modelTypeByElementKey(elementKey);
     191              : 
     192            0 :         if (modelType == PropertiesPanelModelType::TYPE_UNDEFINED) {
     193            0 :             continue;
     194              :         }
     195              : 
     196            0 :         auto model = dynamic_cast<PropertiesPanelAbstractModel*>(modelByType(modelType));
     197              : 
     198            0 :         if (!model) {
     199            0 :             model = PropertiesPanelModelFactory::newPropertiesPanelListModel(modelType, this, iocContext(), m_repository);
     200              :         }
     201              : 
     202            0 :         if (model) {
     203            0 :             models << model;
     204              :         }
     205              :     }
     206              : 
     207            0 :     setModels(models);
     208            0 : }
     209              : 
     210            0 : bool PropertiesPanelAbstractProxyModel::shouldUpdateWhenEmpty() const
     211              : {
     212            0 :     for (const PropertiesPanelAbstractModel* model : modelList()) {
     213            0 :         if (model->shouldUpdateWhenEmpty()) {
     214            0 :             return true;
     215              :         }
     216            0 :     }
     217            0 :     return false;
     218              : }
     219              : 
     220            0 : bool PropertiesPanelAbstractProxyModel::shouldUpdateOnEmptyPropertyAndStyleIdSets() const
     221              : {
     222            0 :     for (const PropertiesPanelAbstractModel* model : modelList()) {
     223            0 :         if (model->shouldUpdateOnEmptyPropertyAndStyleIdSets()) {
     224            0 :             return true;
     225              :         }
     226            0 :     }
     227            0 :     return false;
     228              : }
     229              : 
     230            0 : QList<PropertiesPanelAbstractModel*> PropertiesPanelAbstractProxyModel::modelList() const
     231              : {
     232            0 :     return m_models.values();
     233              : }
        

Generated by: LCOV version 2.0-1