LCOV - code coverage report
Current view: top level - muse/framework/ui/internal - uistate.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 101 0
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2026 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              : #include "uistate.h"
      24              : 
      25              : #include "global/async/async.h"
      26              : 
      27              : using namespace muse;
      28              : using namespace muse::ui;
      29              : using namespace muse::async;
      30              : 
      31              : static const QString WINDOW_GEOMETRY_KEY("window");
      32              : 
      33            0 : void UiState::init()
      34              : {
      35            0 :     m_uiArrangement.stateChanged(WINDOW_GEOMETRY_KEY).onNotify(this, [this]() {
      36            0 :         m_windowGeometryChanged.notify();
      37            0 :     });
      38              : 
      39            0 :     m_uiArrangement.load();
      40            0 : }
      41              : 
      42            0 : QByteArray UiState::windowGeometry() const
      43              : {
      44            0 :     return m_uiArrangement.state(WINDOW_GEOMETRY_KEY);
      45              : }
      46              : 
      47            0 : void UiState::setWindowGeometry(const QByteArray& geometry)
      48              : {
      49            0 :     m_uiArrangement.setState(WINDOW_GEOMETRY_KEY, geometry);
      50            0 : }
      51              : 
      52            0 : muse::async::Notification UiState::windowGeometryChanged() const
      53              : {
      54            0 :     return m_windowGeometryChanged;
      55              : }
      56              : 
      57            0 : ValNt<QByteArray> UiState::pageState(const QString& pageName) const
      58              : {
      59            0 :     ValNt<QByteArray> result;
      60            0 :     result.val = m_uiArrangement.state(pageName);
      61            0 :     result.notification = m_uiArrangement.stateChanged(pageName);
      62              : 
      63            0 :     return result;
      64            0 : }
      65              : 
      66            0 : void UiState::setPageState(const QString& pageName, const QByteArray& state)
      67              : {
      68            0 :     m_uiArrangement.setState(pageName, state);
      69            0 : }
      70              : 
      71            0 : ToolConfig UiState::toolConfig(const QString& toolName, const ToolConfig& defaultConfig) const
      72              : {
      73            0 :     ToolConfig config = m_uiArrangement.toolConfig(toolName);
      74            0 :     if (!config.isValid()) {
      75            0 :         return defaultConfig;
      76              :     }
      77              : 
      78            0 :     updateToolConfig(toolName, config, defaultConfig);
      79            0 :     return config;
      80            0 : }
      81              : 
      82            0 : void UiState::setToolConfig(const QString& toolName, const ToolConfig& config)
      83              : {
      84            0 :     m_uiArrangement.setToolConfig(toolName, config);
      85            0 : }
      86              : 
      87            0 : async::Notification UiState::toolConfigChanged(const QString& toolName) const
      88              : {
      89            0 :     return m_uiArrangement.toolConfigChanged(toolName);
      90              : }
      91              : 
      92            0 : void UiState::updateToolConfig(const QString& toolName, ToolConfig& userConfig, const ToolConfig& defaultConfig) const
      93              : {
      94            0 :     bool hasChanged = false;
      95              : 
      96              :     // Remove items that are not in the default config
      97              :     {
      98            0 :         QList<ToolConfig::Item> itemsToRemove;
      99            0 :         for (const auto& item : userConfig.items) {
     100            0 :             if (item.isSeparator()) {
     101            0 :                 continue;
     102              :             }
     103              : 
     104            0 :             if (std::find_if(defaultConfig.items.cbegin(), defaultConfig.items.cend(), [item](const auto& defaultItem) {
     105            0 :                 return item.intent == defaultItem.intent;
     106            0 :             }) == defaultConfig.items.cend()) {
     107            0 :                 itemsToRemove << item;
     108              :             }
     109              :         }
     110              : 
     111            0 :         for (const auto& itemToRemove : itemsToRemove) {
     112            0 :             hasChanged = true;
     113            0 :             userConfig.items.removeAll(itemToRemove);
     114              :         }
     115            0 :     }
     116              : 
     117              :     // Insert items that are missing in the user config
     118              :     {
     119            0 :         for (const auto& defaultItem : defaultConfig.items) {
     120            0 :             if (defaultItem.isSeparator()) {
     121            0 :                 continue;
     122              :             }
     123              : 
     124            0 :             if (std::find_if(userConfig.items.cbegin(), userConfig.items.cend(), [defaultItem](const auto& item) {
     125            0 :                 return defaultItem.intent == item.intent;
     126            0 :             }) == userConfig.items.cend()) {
     127            0 :                 hasChanged = true;
     128              : 
     129              :                 // Try to find a good place to insert the item
     130            0 :                 int indexOfDefaultItem = defaultConfig.items.indexOf(defaultItem);
     131              : 
     132              :                 // If it was at the start of the default items...
     133            0 :                 if (indexOfDefaultItem == 0) {
     134              :                     // insert it at the start of the user items
     135            0 :                     userConfig.items.prepend(defaultItem);
     136            0 :                     continue;
     137              :                 }
     138              : 
     139              :                 // If it was at the end of the default items...
     140            0 :                 if (indexOfDefaultItem == defaultConfig.items.size() - 1) {
     141              :                     // insert it at the end of the user items
     142            0 :                     userConfig.items.append(defaultItem);
     143            0 :                     continue;
     144              :                 }
     145              : 
     146              :                 // Look at the item before it...
     147              :                 {
     148            0 :                     const auto& itemBefore = defaultConfig.items[indexOfDefaultItem - 1];
     149            0 :                     if (!itemBefore.isSeparator()) {
     150            0 :                         auto it = std::find_if(userConfig.items.begin(), userConfig.items.end(), [itemBefore](const auto& item) {
     151            0 :                             return item.intent == itemBefore.intent;
     152              :                         });
     153              : 
     154            0 :                         if (it != userConfig.items.end()) {
     155            0 :                             userConfig.items.insert(++it, defaultItem);
     156            0 :                             continue;
     157              :                         }
     158              :                     }
     159              :                 }
     160              : 
     161              :                 // Look at the item after it...
     162              :                 {
     163            0 :                     const auto& itemAfter  = defaultConfig.items[indexOfDefaultItem + 1];
     164            0 :                     if (!itemAfter.isSeparator()) {
     165            0 :                         auto it = std::find_if(userConfig.items.begin(), userConfig.items.end(), [itemAfter](const auto& item) {
     166            0 :                             return item.intent == itemAfter.intent;
     167              :                         });
     168              : 
     169            0 :                         userConfig.items.insert(it, defaultItem);
     170            0 :                         continue;
     171            0 :                     }
     172              :                 }
     173              : 
     174              :                 // Last resort: just insert at the end
     175            0 :                 userConfig.items.append(defaultItem);
     176              :             }
     177              :         }
     178              :     }
     179              : 
     180            0 :     if (hasChanged) {
     181              :         // Save for later
     182            0 :         auto self = const_cast<UiState*>(this);
     183              : 
     184            0 :         Async::call(self, [self, toolName, userConfig]() {
     185            0 :             self->setToolConfig(toolName, userConfig);
     186            0 :         });
     187              :     }
     188            0 : }
     189              : 
     190            0 : QString UiState::uiItemState(const QString& itemName) const
     191              : {
     192            0 :     return m_uiArrangement.value(itemName);
     193              : }
     194              : 
     195            0 : void UiState::setUiItemState(const QString& itemName, const QString& value)
     196              : {
     197            0 :     m_uiArrangement.setValue(itemName, value);
     198            0 : }
     199              : 
     200            0 : Notification UiState::uiItemStateChanged(const QString& itemName) const
     201              : {
     202            0 :     return m_uiArrangement.valueChanged(itemName);
     203              : }
     204              : 
     205            0 : bool UiState::isVisible(const QString& key, bool def) const
     206              : {
     207            0 :     QString val = m_uiArrangement.value(key);
     208            0 :     bool ok = false;
     209            0 :     int valInt = val.toInt(&ok);
     210            0 :     return ok ? bool(valInt) : def;
     211            0 : }
     212              : 
     213            0 : void UiState::setIsVisible(const QString& key, bool val)
     214              : {
     215            0 :     m_uiArrangement.setValue(key, QString::number(val ? 1 : 0));
     216            0 : }
     217              : 
     218            0 : async::Notification UiState::isVisibleChanged(const QString& key) const
     219              : {
     220            0 :     return m_uiArrangement.valueChanged(key);
     221              : }
        

Generated by: LCOV version 2.0-1