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 "diagnosticnavigationmodel.h"
23 :
24 : #include <algorithm>
25 :
26 : #include <QGuiApplication>
27 : #include <QClipboard>
28 :
29 : #include "keynavdevsection.h"
30 : #include "keynavdevsubsection.h"
31 : #include "keynavdevcontrol.h"
32 :
33 : #include "log.h"
34 :
35 : using namespace muse::diagnostics;
36 : using namespace muse::ui;
37 :
38 : template<class T>
39 0 : static QList<T*> toQList(std::set<T*> set)
40 : {
41 0 : QList<T*> l;
42 0 : l.reserve(int(set.size()));
43 0 : for (T* s : set) {
44 0 : l.append(s);
45 : }
46 0 : return l;
47 0 : }
48 :
49 : template<class T>
50 0 : static void sortByIndex(QList<T*>& list)
51 : {
52 0 : std::sort(list.begin(), list.end(), [](T* f, T* s) {
53 0 : if (f->index().row != s->index().row) {
54 0 : return f->index().row < s->index().row;
55 : }
56 0 : return f->index().column < s->index().column;
57 : });
58 0 : }
59 :
60 0 : DiagnosticNavigationModel::DiagnosticNavigationModel(QObject* parent)
61 0 : : QObject(parent), Contextable(muse::iocCtxForQmlObject(this))
62 : {
63 0 : connect(&m_reloadDelayer, &QTimer::timeout, this, &DiagnosticNavigationModel::reload);
64 0 : m_reloadDelayer.setInterval(500);
65 0 : m_reloadDelayer.setSingleShot(true);
66 0 : }
67 :
68 0 : void DiagnosticNavigationModel::reload()
69 : {
70 0 : emit beforeReload();
71 0 : m_sections.clear();
72 0 : qDeleteAll(m_memstore);
73 0 : m_memstore.clear();
74 :
75 0 : const std::set<INavigationSection*>& sectionsSet = navigationController()->sections();
76 0 : QList<INavigationSection*> sectionsList = toQList(sectionsSet);
77 0 : sortByIndex(sectionsList);
78 :
79 0 : for (INavigationSection* s : std::as_const(sectionsList)) {
80 0 : m_sections << toWrap(s);
81 : }
82 :
83 0 : emit sectionsChanged();
84 0 : emit afterReload();
85 0 : }
86 :
87 0 : QVariant DiagnosticNavigationModel::toWrap(INavigationSection* s)
88 : {
89 0 : KeyNavDevSection* qs = new KeyNavDevSection(s);
90 0 : m_memstore.append(qs);
91 :
92 0 : QVariantList subVarList;
93 0 : const std::set<INavigationPanel*>& subsectionsSet = s->panels();
94 0 : QList<INavigationPanel*> subsectionsList = toQList(subsectionsSet);
95 0 : sortByIndex(subsectionsList);
96 0 : for (INavigationPanel* sub : std::as_const(subsectionsList)) {
97 0 : subVarList << toWrap(sub);
98 : }
99 :
100 0 : qs->setSubsections(subVarList);
101 :
102 0 : s->panelsListChanged().onNotify(this, [this]() {
103 0 : m_reloadDelayer.start();
104 0 : });
105 :
106 0 : return QVariant::fromValue(qs);
107 0 : }
108 :
109 0 : QVariant DiagnosticNavigationModel::toWrap(INavigationPanel* sub)
110 : {
111 0 : KeyNavDevSubSection* qsub = new KeyNavDevSubSection(sub);
112 0 : m_memstore.append(qsub);
113 :
114 0 : QVariantList conVarList;
115 0 : const std::set<INavigationControl*>& controlsSet = sub->controls();
116 0 : QList<INavigationControl*> controlsList = toQList(controlsSet);
117 0 : sortByIndex(controlsList);
118 0 : for (INavigationControl* ctrl : std::as_const(controlsList)) {
119 0 : conVarList << toWrap(ctrl);
120 : }
121 :
122 0 : qsub->setControls(conVarList);
123 :
124 0 : sub->controlsListChanged().onNotify(this, [this]() {
125 0 : m_reloadDelayer.start();
126 0 : });
127 :
128 0 : return QVariant::fromValue(qsub);
129 0 : }
130 :
131 0 : QVariant DiagnosticNavigationModel::toWrap(INavigationControl* ctrl)
132 : {
133 0 : KeyNavDevControl* qc = new KeyNavDevControl(ctrl);
134 0 : m_memstore.append(qc);
135 0 : return QVariant::fromValue(qc);
136 : }
137 :
138 0 : QVariantList DiagnosticNavigationModel::sections() const
139 : {
140 0 : return m_sections;
141 : }
142 :
143 0 : void DiagnosticNavigationModel::copyToClipboard(const QVariant& section, const QVariant& panel, const QVariant& control)
144 : {
145 0 : KeyNavDevSection* sec = section.value<KeyNavDevSection*>();
146 0 : IF_ASSERT_FAILED(sec) {
147 0 : return;
148 : }
149 :
150 0 : KeyNavDevSubSection* pan = panel.value<KeyNavDevSubSection*>();
151 0 : IF_ASSERT_FAILED(pan) {
152 0 : return;
153 : }
154 :
155 0 : KeyNavDevControl* ctrl = control.value<KeyNavDevControl*>();
156 0 : IF_ASSERT_FAILED(ctrl) {
157 0 : return;
158 : }
159 :
160 0 : QString text = "\"" + sec->name() + "\", \"" + pan->name() + "\", \"" + ctrl->name() + "\"";
161 0 : LOGD() << text;
162 :
163 0 : QClipboard* clipboard = QGuiApplication::clipboard();
164 0 : clipboard->setText(text);
165 0 : }
|