LCOV - code coverage report
Current view: top level - muse/framework/workspace/internal - workspace.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 28.0 % 107 30
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) 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 "workspace.h"
      23              : 
      24              : #include "multiwindows/resourcelockguard.h"
      25              : 
      26              : #include "workspacefile.h"
      27              : #include "workspaceerrors.h"
      28              : 
      29              : #include "log.h"
      30              : 
      31              : using namespace muse;
      32              : using namespace muse::workspace;
      33              : 
      34            4 : Workspace::Workspace(const io::path_t& filePath, const modularity::ContextPtr& iocCtx)
      35            4 :     : Contextable(iocCtx)
      36              : {
      37            4 :     m_file = std::make_shared<WorkspaceFile>(filePath);
      38              : 
      39            4 :     multiwindowsProvider()->resourceChanged().onReceive(this, [this](const std::string& resourceName){
      40            0 :         if (resourceName == fileResourceName()) {
      41            0 :             reload();
      42              :         }
      43            0 :     });
      44            4 : }
      45              : 
      46            0 : Workspace::Workspace(const io::path_t& filePath, const Workspace* other, const modularity::ContextPtr& iocCtx)
      47            0 :     : Workspace(filePath, iocCtx)
      48              : {
      49            0 :     m_file = std::make_shared<WorkspaceFile>(filePath, other->m_file.get());
      50            0 : }
      51              : 
      52           16 : std::string Workspace::name() const
      53              : {
      54           16 :     return io::completeBasename(m_file->filePath()).toStdString();
      55              : }
      56              : 
      57            0 : bool Workspace::isBuiltin() const
      58              : {
      59            0 :     io::path_t builtinWorkspacePath = this->builtinWorkspacePath();
      60            0 :     return !builtinWorkspacePath.empty();
      61            0 : }
      62              : 
      63            0 : bool Workspace::isEdited() const
      64              : {
      65            0 :     if (!isBuiltin()) {
      66            0 :         return false;
      67              :     }
      68              : 
      69            0 :     if (m_file->isNeedSave()) {
      70            0 :         return true;
      71              :     }
      72              : 
      73            0 :     return io::absoluteDirpath(filePath()) == configuration()->userWorkspacesPath();
      74              : }
      75              : 
      76            0 : bool Workspace::isNeedSave() const
      77              : {
      78            0 :     return m_file ? m_file->isNeedSave() : false;
      79              : }
      80              : 
      81            1 : RetVal<QByteArray> Workspace::rawData(const DataKey& key) const
      82              : {
      83            2 :     TRACEFUNC;
      84              : 
      85            1 :     IF_ASSERT_FAILED(m_file->isLoaded()) {
      86            0 :         return RetVal<QByteArray>(make_ret(Err::NotLoaded));
      87              :     }
      88              : 
      89            1 :     RetVal<QByteArray> rv;
      90            1 :     rv.ret = make_ret(Ret::Code::Ok);
      91            2 :     rv.val = m_file->data(key);
      92            1 :     return rv;
      93            1 : }
      94              : 
      95            0 : Ret Workspace::setRawData(const DataKey& key, const QByteArray& data)
      96              : {
      97            0 :     m_file->setData(key, data);
      98            0 :     return make_ret(Ret::Code::Ok);
      99              : }
     100              : 
     101            0 : void Workspace::reset()
     102              : {
     103            0 :     if (!isEdited()) {
     104            0 :         return;
     105              :     }
     106              : 
     107            0 :     io::path_t builtinWorkspacePath = this->builtinWorkspacePath();
     108              : 
     109            0 :     if (builtinWorkspacePath == filePath()) {
     110              :         //! if the user made changes and they were not saved, then just reload file
     111            0 :         reload();
     112            0 :         return;
     113              :     }
     114              : 
     115              :     //! remove current file
     116            0 :     fileSystem()->remove(filePath());
     117              : 
     118              :     //! redirect to builtin workspace file
     119            0 :     m_file = std::make_shared<WorkspaceFile>(builtinWorkspacePath);
     120              : 
     121            0 :     reload();
     122            0 : }
     123              : 
     124            0 : void Workspace::assignNewName(const std::string& newName)
     125              : {
     126            0 :     io::path_t filePath = m_file->filePath();
     127            0 :     io::path_t newPath = io::absoluteDirpath(filePath) + "/" + newName + "." + io::suffix(filePath);
     128              : 
     129            0 :     if (filePath == newPath) {
     130            0 :         return;
     131              :     }
     132              : 
     133            0 :     Ret ret = doSave();
     134            0 :     if (!ret) {
     135            0 :         LOGE() << "Failed to save workspace, error: " << ret.toString();
     136              :     }
     137              : 
     138            0 :     fileSystem()->move(filePath, newPath);
     139              : 
     140            0 :     m_file = std::make_shared<WorkspaceFile>(newPath);
     141            0 :     load();
     142            0 : }
     143              : 
     144            4 : async::Notification Workspace::reloadNotification()
     145              : {
     146            4 :     return m_reloadNotification;
     147              : }
     148              : 
     149            5 : bool Workspace::isLoaded() const
     150              : {
     151            5 :     return m_file->isLoaded();
     152              : }
     153              : 
     154            3 : io::path_t Workspace::filePath() const
     155              : {
     156            3 :     return m_file->filePath();
     157              : }
     158              : 
     159            3 : Ret Workspace::load()
     160              : {
     161            3 :     mi::ReadResourceLockGuard resource_guard(multiwindowsProvider.get(), fileResourceName());
     162            6 :     return m_file->load();
     163            3 : }
     164              : 
     165            3 : Ret Workspace::save()
     166              : {
     167            3 :     if (!m_file->isNeedSave()) {
     168            3 :         return true;
     169              :     }
     170              : 
     171            0 :     if (isBuiltin()) {
     172            0 :         copyBuiltinWorkspaceToUserDir();
     173              :     }
     174              : 
     175            0 :     return doSave();
     176              : }
     177              : 
     178            0 : Ret Workspace::doSave()
     179              : {
     180            0 :     mi::WriteResourceLockGuard resource_guard(multiwindowsProvider.get(), fileResourceName());
     181            0 :     m_file->setMeta("app_version", Val(application()->version().toStdString()));
     182            0 :     return m_file->save();
     183            0 : }
     184              : 
     185            0 : void Workspace::reload()
     186              : {
     187            0 :     load();
     188            0 :     m_reloadNotification.notify();
     189            0 : }
     190              : 
     191            3 : std::string Workspace::fileResourceName() const
     192              : {
     193            3 :     return filePath().toStdString();
     194              : }
     195              : 
     196            0 : io::path_t Workspace::builtinWorkspacePath() const
     197              : {
     198            0 :     std::string currentWorkspaceName = name();
     199              : 
     200            0 :     io::paths_t builtinWorkspacesPaths = configuration()->builtinWorkspacesFilePaths();
     201            0 :     for (const io::path_t& builtinWorkspacePath : builtinWorkspacesPaths) {
     202            0 :         std::string builtinWorkspaceName = io::completeBasename(builtinWorkspacePath).toStdString();
     203            0 :         if (builtinWorkspaceName == currentWorkspaceName) {
     204            0 :             return builtinWorkspacePath;
     205              :         }
     206            0 :     }
     207              : 
     208            0 :     return {};
     209            0 : }
     210              : 
     211            0 : void Workspace::copyBuiltinWorkspaceToUserDir()
     212              : {
     213            0 :     io::path_t userFilePath = configuration()->userWorkspacesPath() + "/" + io::filename(filePath());
     214              : 
     215            0 :     fileSystem()->copy(m_file->filePath(), userFilePath);
     216            0 :     m_file->redirect(userFilePath);
     217              : 
     218            0 :     Ret ret = doSave();
     219            0 :     if (!ret) {
     220            0 :         LOGE() << "Failed to save workspace: " << ret.toString();
     221              :     }
     222              : 
     223            0 :     load();
     224            0 : }
        

Generated by: LCOV version 2.0-1