GCC Code Coverage Report


./
File: modules/ui/qt/com/signal_shortcut.cpp
Date: 2025-01-21 16:21:04
Lines:
41/73
56.2%
Functions:
6/10
60.0%
Branches:
48/178
27.0%

Line Branch Exec Source
1 /************************************************************************
2 *
3 * Copyright (C) 2018-2024 IRCAD France
4 * Copyright (C) 2018-2020 IHU Strasbourg
5 *
6 * This file is part of Sight.
7 *
8 * Sight is free software: you can redistribute it and/or modify it under
9 * the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * Sight is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with Sight. If not, see <https://www.gnu.org/licenses/>.
20 *
21 ***********************************************************************/
22
23 #include "signal_shortcut.hpp"
24
25 #include <core/base.hpp>
26 #include <core/com/signal.hxx>
27 #include <core/com/slot.hxx>
28 #include <core/com/slots.hxx>
29 #include <core/runtime/helper.hpp>
30
31 #include <service/macros.hpp>
32 #include <service/op.hpp>
33
34 #include <ui/__/container/widget.hpp>
35 #include <ui/__/registry.hpp>
36 #include <ui/__/service.hpp>
37 #include <ui/qt/container/widget.hpp>
38
39 #include <QKeySequence>
40 #include <QWidget>
41
42 #include <memory>
43
44 namespace sight::module::ui::qt::com
45 {
46
47 //-----------------------------------------------------------------------------
48
49 1 signal_shortcut::signal_shortcut() noexcept
50 {
51
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 new_signal<signals::bool_t>(signals::IS_ENABLED);
52
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 new_signal<signals::void_t>(signals::ENABLED);
53
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 new_signal<signals::void_t>(signals::DISABLED);
54
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 new_signal<signals::void_t>(signals::ACTIVATED);
55
56
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 new_slot(slots::SET_ENABLED, &signal_shortcut::set_enabled, this);
57
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 new_slot(slots::SET_DISABLED, [this](bool _disabled){this->set_enabled(!_disabled);});
58
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 new_slot(slots::ENABLE, [this](){this->set_enabled(true);});
59
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 new_slot(slots::DISABLE, [this](){this->set_enabled(false);});
60
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 new_slot(slots::APPLY_ENABLED, [this](){this->set_enabled(*m_enabled);});
61 1 }
62
63 //-----------------------------------------------------------------------------
64
65 2 signal_shortcut::~signal_shortcut() noexcept =
66 default;
67
68 //-----------------------------------------------------------------------------
69
70 1 void signal_shortcut::configuring()
71 {
72 1 const auto config_tree = this->get_config();
73
74
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 if(auto properties = config_tree.get_child_optional("properties"); not properties.has_value())
75 {
76 1 const auto enabled = m_enabled.lock();
77
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 *enabled = core::runtime::get_ptree_value(config_tree, "state.<xmlattr>.enabled", true);
78 1 }
79
80
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
1 const auto config_shortcut = config_tree.get_child("config.<xmlattr>");
81
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 m_shortcut = config_shortcut.get<std::string>("shortcut", m_shortcut);
82 1 SIGHT_ASSERT("Shortcut must not be empty", !m_shortcut.empty());
83
84
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 m_wid = config_shortcut.get<std::string>("wid", m_wid);
85
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 m_sid = config_shortcut.get<std::string>("sid", m_sid);
86 SIGHT_ASSERT(
87 "Either The wid or sid attribute must be specified for signal_shortcut",
88 !m_wid.empty() || !m_sid.empty()
89 1 );
90 1 }
91
92 //-----------------------------------------------------------------------------
93
94 void signal_shortcut::set_enabled(bool _enabled)
95 {
96 {
97 const auto enabled = m_enabled.lock();
98 *enabled = _enabled;
99
100 auto sig = enabled->signal<data::object::modified_signal_t>(data::object::MODIFIED_SIG);
101 core::com::connection::blocker block(sig->get_connection(slot(slots::APPLY_ENABLED)));
102 sig->async_emit();
103 }
104
105 if(_enabled)
106 {
107 auto sig = this->signal<signals::void_t>(signals::ENABLED);
108 sig->async_emit();
109 }
110 else
111 {
112 auto sig = this->signal<signals::void_t>(signals::DISABLED);
113 sig->async_emit();
114 }
115
116 auto sig = this->signal<signals::bool_t>(signals::IS_ENABLED);
117 sig->async_emit(_enabled);
118 }
119
120 //-----------------------------------------------------------------------------
121
122 1 void signal_shortcut::starting()
123 {
124
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 sight::ui::container::widget::sptr fwc = nullptr;
125
126 // Either get the container via a service id
127
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(!m_sid.empty())
128 {
129
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 bool sid_exists = core::id::exist(m_sid);
130
131
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(sid_exists)
132 {
133 service::base::sptr service = service::get(m_sid);
134 auto container_srv = std::dynamic_pointer_cast<sight::ui::service>(service);
135 fwc = container_srv->get_container();
136 }
137 else
138 {
139
5/10
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
2 SIGHT_ERROR("Invalid service id " << m_sid);
140 }
141 }
142 // or a window id
143 else if(!m_wid.empty())
144 {
145 fwc = sight::ui::registry::get_wid_container(m_wid);
146 if(!fwc)
147 {
148 SIGHT_ERROR("Invalid window id " << m_wid);
149 }
150 }
151
152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(fwc != nullptr)
153 {
154 auto qtc = std::dynamic_pointer_cast<sight::ui::qt::container::widget>(fwc);
155 if(qtc != nullptr)
156 {
157 if(m_shortcut_object == nullptr)
158 {
159 // Get the associated widget to use as parent for the shortcut
160 QWidget* widget = qtc->get_qt_container();
161 // Create a key sequence from the string and its associated QShortcut
162 QKeySequence shortcut_sequence = QKeySequence(QString::fromStdString(m_shortcut));
163 m_shortcut_object = new QShortcut(shortcut_sequence, widget);
164 }
165
166 // Connect the activated signal to the onActivation method of this class
167 QObject::connect(m_shortcut_object, &QShortcut::activated, this, &self_t::on_activation);
168 }
169 }
170 else
171 {
172
8/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
3 SIGHT_ERROR(
173 "Cannot setup shortcut " << m_shortcut << " on invalid "
174 << (!m_wid.empty() ? "wid " + m_wid : "sid " + m_sid)
175
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
2 );
176 }
177 1 }
178
179 //-----------------------------------------------------------------------------
180
181 1 void signal_shortcut::stopping()
182 {
183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(m_shortcut_object != nullptr)
184 {
185 // Connect the activated signal to the onActivation method of this class
186 QObject::disconnect(m_shortcut_object, &QShortcut::activated, this, &self_t::on_activation);
187 }
188 1 }
189
190 //-----------------------------------------------------------------------------
191 void signal_shortcut::updating()
192 {
193 }
194
195 //------------------------------------------------------------------------------
196
197 1 service::connections_t signal_shortcut::auto_connections() const
198 {
199
2/4
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3 return {{m_enabled, sight::data::object::MODIFIED_SIG, slots::APPLY_ENABLED}};
200
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 }
201
202 //------------------------------------------------------------------------------
203
204 void signal_shortcut::on_activation()
205 {
206 if(*m_enabled)
207 {
208 this->signal<signals::void_t>(signals::ACTIVATED)->async_emit();
209 }
210 }
211
212 } // namespace sight::module::ui::qt::com
213