LCOV - code coverage report
Current view: top level - muse/framework/multiwindows/internal/singleprocess - singleprocessprovider.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 108 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) 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 "singleprocessprovider.h"
      24              : 
      25              :  #include <QCoreApplication>
      26              : 
      27              :  #include "../../iprojectprovider.h"
      28              :  #include "ui/imainwindow.h"
      29              :  #include "rcommand/icommanddispatcher.h"
      30              : 
      31              :  #include "multiwindowscommands.h"
      32              : 
      33              :  #include "log.h"
      34              : 
      35              : using namespace muse;
      36              : using namespace muse::mi;
      37              : 
      38              : static const std::string pname = "mi";
      39              : 
      40            0 : size_t SingleProcessProvider::windowCount() const
      41              : {
      42            0 :     return std::max(static_cast<size_t>(1), application()->contextCount());
      43              : }
      44              : 
      45            0 : bool SingleProcessProvider::isFirstWindow() const
      46              : {
      47            0 :     return windowCount() <= 1;
      48              : }
      49              : 
      50            0 : std::shared_ptr<IProjectProvider> SingleProcessProvider::projectProvider(const modularity::ContextPtr& ctx) const
      51              : {
      52            0 :     return modularity::ioc(ctx)->resolve<IProjectProvider>(pname);
      53              : }
      54              : 
      55            0 : std::shared_ptr<ui::IMainWindow> SingleProcessProvider::mainWindow(const modularity::ContextPtr& ctx) const
      56              : {
      57            0 :     return modularity::ioc(ctx)->resolve<ui::IMainWindow>(pname);
      58              : }
      59              : 
      60            0 : std::shared_ptr<rcommand::ICommandDispatcher> SingleProcessProvider::commandDispatcher(const modularity::ContextPtr& ctx) const
      61              : {
      62            0 :     return modularity::ioc(ctx)->resolve<rcommand::ICommandDispatcher>(pname);
      63              : }
      64              : 
      65            0 : bool SingleProcessProvider::isProjectAlreadyOpened(const muse::io::path_t& projectPath) const
      66              : {
      67            0 :     for (const auto& ctx : application()->contexts()) {
      68            0 :         std::shared_ptr<IProjectProvider> pp = projectProvider(ctx);
      69            0 :         if (!pp) {
      70            0 :             LOGW() << "Not found implementation of IProjectProvider for context: " << ctx->id;
      71            0 :             continue;
      72              :         }
      73              : 
      74            0 :         if (pp->isProjectOpened(projectPath)) {
      75            0 :             return true;
      76              :         }
      77            0 :     }
      78            0 :     return false;
      79              : }
      80              : 
      81            0 : void SingleProcessProvider::activateWindowWithProject(const muse::io::path_t& projectPath)
      82              : {
      83            0 :     for (const auto& ctx : application()->contexts()) {
      84            0 :         std::shared_ptr<IProjectProvider> pp = projectProvider(ctx);
      85            0 :         if (!pp) {
      86            0 :             LOGW() << "Not found implementation of IProjectProvider for context: " << ctx->id;
      87            0 :             continue;
      88              :         }
      89              : 
      90            0 :         if (!pp->isProjectOpened(projectPath)) {
      91            0 :             continue;
      92              :         }
      93              : 
      94            0 :         std::shared_ptr<ui::IMainWindow> w = mainWindow(ctx);
      95            0 :         IF_ASSERT_FAILED(w) {
      96            0 :             continue;
      97              :         }
      98              : 
      99            0 :         w->requestShowOnFront();
     100            0 :         break;
     101            0 :     }
     102            0 : }
     103              : 
     104            0 : bool SingleProcessProvider::isHasWindowWithoutProject() const
     105              : {
     106            0 :     for (const auto& ctx : application()->contexts()) {
     107            0 :         std::shared_ptr<IProjectProvider> pp = projectProvider(ctx);
     108            0 :         if (!pp) {
     109            0 :             LOGW() << "Not found implementation of IProjectProvider for context: " << ctx->id;
     110            0 :             continue;
     111              :         }
     112              : 
     113            0 :         if (!pp->isAnyProjectOpened()) {
     114            0 :             return true;
     115              :         }
     116            0 :     }
     117            0 :     return false;
     118              : }
     119              : 
     120            0 : void SingleProcessProvider::activateWindowWithoutProject(const QStringList& args)
     121              : {
     122            0 :     for (const auto& ctx : application()->contexts()) {
     123            0 :         std::shared_ptr<IProjectProvider> pp = projectProvider(ctx);
     124            0 :         if (!pp) {
     125            0 :             LOGW() << "Not found implementation of IProjectProvider for context: " << ctx->id;
     126            0 :             continue;
     127              :         }
     128              : 
     129            0 :         if (pp->isAnyProjectOpened()) {
     130            0 :             continue;
     131              :         }
     132              : 
     133            0 :         std::shared_ptr<ui::IMainWindow> w = mainWindow(ctx);
     134            0 :         IF_ASSERT_FAILED(w) {
     135            0 :             continue;
     136              :         }
     137              : 
     138            0 :         w->requestShowOnFront();
     139            0 :         if (args.count() > 0 && !args.at(0).isEmpty()) {
     140            0 :             std::shared_ptr<rcommand::ICommandDispatcher> d = commandDispatcher(ctx);
     141            0 :             IF_ASSERT_FAILED(d) {
     142            0 :                 break;
     143              :             }
     144            0 :             d->dispatch(rcommand::CommandQuery(args.at(0).toStdString()));
     145            0 :         }
     146              : 
     147            0 :         break;
     148            0 :     }
     149            0 : }
     150              : 
     151            0 : bool SingleProcessProvider::openNewWindow(const QStringList& args)
     152              : {
     153            0 :     LOGDA() << args;
     154              : 
     155            0 :     application()->setupNewContext(args);
     156              : 
     157            0 :     return true;
     158              : }
     159              : 
     160            0 : async::Promise<Ret> SingleProcessProvider::quitForAll(const modularity::ContextPtr& ctx)
     161              : {
     162            0 :     const std::vector<modularity::ContextPtr> all = application()->contexts();
     163              : 
     164            0 :     std::vector<modularity::ContextPtr> others;
     165            0 :     for (auto it = all.crbegin(); it != all.crend(); ++it) {
     166            0 :         const modularity::ContextPtr& c = *it;
     167            0 :         if (ctx && c->id == ctx->id) {
     168            0 :             continue;
     169              :         }
     170              : 
     171            0 :         others.push_back(c);
     172              :     }
     173              : 
     174              :     //! NOTE The current window quits first, then the others one by one
     175            0 :     quitWindow(ctx);
     176              : 
     177            0 :     return quitWindows(others);
     178            0 : }
     179              : 
     180            0 : async::Promise<Ret> SingleProcessProvider::quitWindows(const std::vector<modularity::ContextPtr>& ctxs)
     181              : {
     182            0 :     return async::make_promise<Ret>([this, ctxs](auto resolve) {
     183            0 :         if (ctxs.empty()) {
     184            0 :             return resolve(make_ok());
     185              :         }
     186              : 
     187            0 :         std::shared_ptr<rcommand::ICommandDispatcher> cd = commandDispatcher(ctxs.front());
     188            0 :         IF_ASSERT_FAILED(cd) {
     189            0 :             return resolve(make_ret(Ret::Code::InternalError));
     190              :         }
     191              : 
     192            0 :         std::shared_ptr<ui::IMainWindow> w = mainWindow(ctxs.front());
     193            0 :         IF_ASSERT_FAILED(w) {
     194            0 :             return resolve(make_ret(Ret::Code::InternalError));
     195              :         }
     196              : 
     197              :         //! NOTE Bring the window to the front, so that the user is asked about the window they see
     198            0 :         w->requestShowOnFront();
     199              : 
     200            0 :         std::vector<modularity::ContextPtr> rest(ctxs.cbegin() + 1, ctxs.cend());
     201              : 
     202            0 :         cd->dispatch(APP_QUIT_COMMAND, { { "all_instances", Val(false) } })
     203            0 :         .onResolve(this, [this, rest, resolve](const rcommand::Response& response) {
     204            0 :             if (!response.ret) {
     205            0 :                 LOGD() << "quit for all canceled: " << response.ret.toString();
     206            0 :                 (void)resolve(response.ret);
     207            0 :                 return;
     208              :             }
     209              : 
     210            0 :             quitWindows(rest).onResolve(this, [resolve](const Ret& ret) {
     211            0 :                 (void)resolve(ret);
     212              :             });
     213              :         });
     214              : 
     215            0 :         return async::Promise<Ret>::dummy_result();
     216            0 :     });
     217              : }
     218              : 
     219            0 : void SingleProcessProvider::quitWindow(const modularity::ContextPtr& ctx)
     220              : {
     221            0 :     if (application()->contextCount() <= 1) {
     222            0 :         QCoreApplication::exit();
     223              :     } else {
     224            0 :         application()->destroyContext(ctx);
     225              :     }
     226            0 : }
        

Generated by: LCOV version 2.0-1