• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

paulmthompson / WhiskerToolbox / 17805412062

17 Sep 2025 05:17PM UTC coverage: 71.661% (+0.01%) from 71.647%
17805412062

push

github

paulmthompson
add group coordinator to test

39210 of 54716 relevant lines covered (71.66%)

1302.09 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.57
/src/WhiskerToolbox/GroupManagementWidget/GroupManager.cpp
1
#include "GroupManager.hpp"
2
#include "DataManager/Entity/EntityGroupManager.hpp"
3

4
#include <QDebug>
5

6
QVector<QColor> const GroupManager::DEFAULT_COLORS = {
7
        QColor(31, 119, 180), // Blue
8
        QColor(255, 127, 14), // Orange
9
        QColor(44, 160, 44),  // Green
10
        QColor(214, 39, 40),  // Red
11
        QColor(148, 103, 189),// Purple
12
        QColor(140, 86, 75),  // Brown
13
        QColor(227, 119, 194),// Pink
14
        QColor(127, 127, 127),// Gray
15
        QColor(188, 189, 34), // Olive
16
        QColor(23, 190, 207)  // Cyan
17
};
18

19
GroupManager::GroupManager(EntityGroupManager* entity_group_manager, QObject * parent)
34✔
20
    : QObject(parent),
21
      m_entity_group_manager(entity_group_manager),
34✔
22
      m_next_group_id(1) {
34✔
23
    // Assert that we have a valid EntityGroupManager
24
    Q_ASSERT(m_entity_group_manager != nullptr);
34✔
25
}
34✔
26

27
int GroupManager::createGroup(QString const & name) {
19✔
28
    QColor color = getNextDefaultColor();
19✔
29
    return createGroup(name, color);
38✔
30
}
31

32
int GroupManager::createGroup(QString const & name, QColor const & color) {
19✔
33
    // Create group in EntityGroupManager
34
    GroupId entity_group_id = m_entity_group_manager->createGroup(name.toStdString());
57✔
35
    
36
    // Store color mapping
37
    int group_id = static_cast<int>(entity_group_id);
19✔
38
    m_group_colors[group_id] = color;
19✔
39

40
    qDebug() << "GroupManager: Created group" << group_id << "with name" << name;
19✔
41

42
    emit groupCreated(group_id);
19✔
43
    return group_id;
19✔
44
}
45

46
bool GroupManager::removeGroup(int group_id) {
3✔
47
    GroupId entity_group_id = static_cast<GroupId>(group_id);
3✔
48
    
49
    // Remove from EntityGroupManager
50
    if (!m_entity_group_manager->deleteGroup(entity_group_id)) {
3✔
51
        return false;
1✔
52
    }
53
    
54
    // Remove color mapping
55
    m_group_colors.remove(group_id);
2✔
56

57
    qDebug() << "GroupManager: Removed group" << group_id;
2✔
58

59
    emit groupRemoved(group_id);
2✔
60
    return true;
2✔
61
}
62

63
std::optional<GroupManager::Group> GroupManager::getGroup(int group_id) const {
19✔
64
    GroupId entity_group_id = static_cast<GroupId>(group_id);
19✔
65
    
66
    auto descriptor = m_entity_group_manager->getGroupDescriptor(entity_group_id);
19✔
67
    if (!descriptor.has_value()) {
19✔
68
        return std::nullopt;
×
69
    }
70
    
71
    Group group(group_id, 
19✔
72
                QString::fromStdString(descriptor->name),
38✔
73
                m_group_colors.value(group_id, QColor(128, 128, 128)));
57✔
74
    
75
    return group;
19✔
76
}
19✔
77

78
bool GroupManager::setGroupName(int group_id, QString const & name) {
11✔
79
    GroupId entity_group_id = static_cast<GroupId>(group_id);
11✔
80
    
81
    // Get current descriptor to preserve description
82
    auto descriptor = m_entity_group_manager->getGroupDescriptor(entity_group_id);
11✔
83
    if (!descriptor.has_value()) {
11✔
84
        return false;
×
85
    }
86

87
    // Avoid redundant updates/signals if the name is unchanged
88
    if (QString::fromStdString(descriptor->name) == name) {
11✔
89
        return true;
7✔
90
    }
91
    
92
    // Update group in EntityGroupManager
93
    if (!m_entity_group_manager->updateGroup(entity_group_id, name.toStdString(), descriptor->description)) {
4✔
94
        return false;
×
95
    }
96

97
    qDebug() << "GroupManager: Updated group" << group_id << "name to" << name;
4✔
98

99
    emit groupModified(group_id);
4✔
100
    return true;
4✔
101
}
11✔
102

103
bool GroupManager::setGroupColor(int group_id, QColor const & color) {
2✔
104
    GroupId entity_group_id = static_cast<GroupId>(group_id);
2✔
105
    
106
    // Check if group exists in EntityGroupManager
107
    if (!m_entity_group_manager->hasGroup(entity_group_id)) {
2✔
108
        return false;
×
109
    }
110
    
111
    // Update color mapping
112
    m_group_colors[group_id] = color;
2✔
113

114
    qDebug() << "GroupManager: Updated group" << group_id << "color";
2✔
115

116
    emit groupModified(group_id);
2✔
117
    return true;
2✔
118
}
119

120
QMap<int, GroupManager::Group> GroupManager::getGroups() const {
67✔
121
    QMap<int, Group> result;
67✔
122
    
123
    auto group_ids = m_entity_group_manager->getAllGroupIds();
67✔
124
    for (GroupId entity_group_id : group_ids) {
82✔
125
        auto descriptor = m_entity_group_manager->getGroupDescriptor(entity_group_id);
15✔
126
        if (descriptor.has_value()) {
15✔
127
            int group_id = static_cast<int>(entity_group_id);
15✔
128
            Group group(group_id,
15✔
129
                       QString::fromStdString(descriptor->name),
30✔
130
                       m_group_colors.value(group_id, QColor(128, 128, 128)));
45✔
131
            result[group_id] = group;
15✔
132
        }
15✔
133
    }
15✔
134
    
135
    return result;
67✔
136
}
67✔
137

138
// ===== EntityId-based API =====
139
bool GroupManager::assignEntitiesToGroup(int group_id, std::unordered_set<EntityId> const & entity_ids) {
13✔
140
    GroupId entity_group_id = static_cast<GroupId>(group_id);
13✔
141
    
142
    // Check if group exists
143
    if (!m_entity_group_manager->hasGroup(entity_group_id)) {
13✔
144
        return false;
×
145
    }
146
    
147
    // Convert to vector for EntityGroupManager API
148
    std::vector<EntityId> entity_vector(entity_ids.begin(), entity_ids.end());
39✔
149
    
150
    // Add entities to group
151
    std::size_t added_count = m_entity_group_manager->addEntitiesToGroup(entity_group_id, entity_vector);
13✔
152

153
    qDebug() << "GroupManager: Assigned" << added_count << "entities to group" << group_id;
13✔
154
    if (added_count > 0) {
13✔
155
        emit groupModified(group_id);
11✔
156
    }
157
    
158
    // For now, emit the old signal for compatibility
159
    //std::unordered_set<int> affected_groups = {group_id};
160
    //emit pointAssignmentsChanged(affected_groups);
161
    
162
    return added_count > 0;
13✔
163
}
13✔
164

165
bool GroupManager::removeEntitiesFromGroup(int group_id, std::unordered_set<EntityId> const & entity_ids) {
6✔
166
    GroupId entity_group_id = static_cast<GroupId>(group_id);
6✔
167
    
168
    // Check if group exists
169
    if (!m_entity_group_manager->hasGroup(entity_group_id)) {
6✔
170
        return false;
×
171
    }
172
    
173
    // Convert to vector for EntityGroupManager API
174
    std::vector<EntityId> entity_vector(entity_ids.begin(), entity_ids.end());
18✔
175
    
176
    // Remove entities from group
177
    std::size_t removed_count = m_entity_group_manager->removeEntitiesFromGroup(entity_group_id, entity_vector);
6✔
178

179
    if (removed_count > 0) {
6✔
180
        qDebug() << "GroupManager: Removed" << removed_count << "entities from group" << group_id;
4✔
181
        emit groupModified(group_id);
4✔
182
    }
183

184
    return removed_count > 0;
6✔
185
}
6✔
186

187
void GroupManager::ungroupEntities(std::unordered_set<EntityId> const & entity_ids) {
1✔
188
    std::unordered_set<int> affected_groups;
1✔
189

190
    // For each entity, find which groups it belongs to and remove it
191
    for (EntityId entity_id : entity_ids) {
2✔
192
        auto group_ids = m_entity_group_manager->getGroupsContainingEntity(entity_id);
1✔
193
        for (GroupId entity_group_id : group_ids) {
3✔
194
            int group_id = static_cast<int>(entity_group_id);
2✔
195
            affected_groups.insert(group_id);
2✔
196
            
197
            // Remove entity from this group
198
            std::vector<EntityId> single_entity = {entity_id};
6✔
199
            m_entity_group_manager->removeEntitiesFromGroup(entity_group_id, single_entity);
2✔
200
        }
2✔
201
    }
1✔
202

203
    if (!affected_groups.empty()) {
1✔
204
        qDebug() << "GroupManager: Ungrouped" << entity_ids.size() << "entities from" << affected_groups.size() << "groups";
1✔
205
        for (int gid : affected_groups) {
3✔
206
            emit groupModified(gid);
2✔
207
        }
208
    }
209
}
2✔
210

211
int GroupManager::getEntityGroup(EntityId id) const {
24✔
212
    auto group_ids = m_entity_group_manager->getGroupsContainingEntity(id);
24✔
213
    
214
    // Return the first group (assuming entities belong to at most one group for now)
215
    if (!group_ids.empty()) {
24✔
216
        return static_cast<int>(group_ids[0]);
4✔
217
    }
218
    
219
    return -1; // Not in any group
20✔
220
}
24✔
221

222
QColor GroupManager::getEntityColor(EntityId id, QColor const & default_color) const {
×
223
    int group_id = getEntityGroup(id);
×
224
    if (group_id == -1) {
×
225
        return default_color;
×
226
    }
227
    
228
    return m_group_colors.value(group_id, default_color);
×
229
}
230

231
int GroupManager::getGroupMemberCount(int group_id) const {
22✔
232
    GroupId entity_group_id = static_cast<GroupId>(group_id);
22✔
233
    return static_cast<int>(m_entity_group_manager->getGroupSize(entity_group_id));
22✔
234
}
235

236
void GroupManager::clearAllGroups() {
×
237
    qDebug() << "GroupManager: Clearing all groups";
×
238

239
    // Clear EntityGroupManager
240
    m_entity_group_manager->clear();
×
241
    
242
    // Clear our color mappings
243
    m_group_colors.clear();
×
244
    
245
    m_next_group_id = 1;
×
246

247
    // Note: We don't emit specific signals here since everything is being cleared
248
}
×
249

250
QColor GroupManager::getNextDefaultColor() const {
19✔
251
    if (DEFAULT_COLORS.isEmpty()) {
19✔
252
        return QColor(128, 128, 128);// Fallback gray
×
253
    }
254

255
    // Cycle through the default colors based on current group count
256
    auto group_ids = m_entity_group_manager->getAllGroupIds();
19✔
257
    int color_index = static_cast<int>(group_ids.size()) % DEFAULT_COLORS.size();
19✔
258
    return DEFAULT_COLORS[color_index];
19✔
259
}
19✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc