##// END OF EJS Templates
Fix sorting with event products
trabillard -
r1264:17c80e548bb4
parent child
Show More
@@ -1,444 +1,456
1 #include "Catalogue/CatalogueEventsModel.h"
1 #include "Catalogue/CatalogueEventsModel.h"
2
2
3 #include <Catalogue/CatalogueController.h>
3 #include <Catalogue/CatalogueController.h>
4 #include <Common/DateUtils.h>
4 #include <Common/DateUtils.h>
5 #include <Common/MimeTypesDef.h>
5 #include <Common/MimeTypesDef.h>
6 #include <DBEvent.h>
6 #include <DBEvent.h>
7 #include <DBEventProduct.h>
7 #include <DBEventProduct.h>
8 #include <DBTag.h>
8 #include <DBTag.h>
9 #include <Data/SqpRange.h>
9 #include <Data/SqpRange.h>
10 #include <SqpApplication.h>
10 #include <SqpApplication.h>
11 #include <Time/TimeController.h>
11 #include <Time/TimeController.h>
12
12
13 #include <list>
13 #include <list>
14 #include <unordered_map>
14 #include <unordered_map>
15
15
16 #include <QHash>
16 #include <QHash>
17 #include <QMimeData>
17 #include <QMimeData>
18
18
19 Q_LOGGING_CATEGORY(LOG_CatalogueEventsModel, "CatalogueEventsModel")
19 Q_LOGGING_CATEGORY(LOG_CatalogueEventsModel, "CatalogueEventsModel")
20
20
21 const auto EVENT_ITEM_TYPE = 1;
21 const auto EVENT_ITEM_TYPE = 1;
22 const auto EVENT_PRODUCT_ITEM_TYPE = 2;
22 const auto EVENT_PRODUCT_ITEM_TYPE = 2;
23
23
24 struct CatalogueEventsModel::CatalogueEventsModelPrivate {
24 struct CatalogueEventsModel::CatalogueEventsModelPrivate {
25 QVector<std::shared_ptr<DBEvent> > m_Events;
25 QVector<std::shared_ptr<DBEvent> > m_Events;
26 std::unordered_map<DBEvent *, QVector<std::shared_ptr<DBEventProduct> > > m_EventProducts;
26 std::unordered_map<DBEvent *, QVector<std::shared_ptr<DBEventProduct> > > m_EventProducts;
27 std::unordered_set<std::shared_ptr<DBEvent> > m_EventsWithChanges;
27 std::unordered_set<std::shared_ptr<DBEvent> > m_EventsWithChanges;
28
28
29 QStringList columnNames()
29 QStringList columnNames()
30 {
30 {
31 return QStringList{tr("Event"), tr("TStart"), tr("TEnd"),
31 return QStringList{tr("Event"), tr("TStart"), tr("TEnd"),
32 tr("Tags"), tr("Product"), tr("")};
32 tr("Tags"), tr("Product"), tr("")};
33 }
33 }
34
34
35 QVariant sortData(int col, const std::shared_ptr<DBEvent> &event) const
35 QVariant sortData(int col, const std::shared_ptr<DBEvent> &event) const
36 {
36 {
37 if (col == (int)CatalogueEventsModel::Column::Validation) {
37 if (col == (int)CatalogueEventsModel::Column::Validation) {
38 return m_EventsWithChanges.find(event) != m_EventsWithChanges.cend() ? true
38 return m_EventsWithChanges.find(event) != m_EventsWithChanges.cend() ? true
39 : QVariant();
39 : QVariant();
40 }
40 }
41
41
42 return eventData(col, event);
42 return eventData(col, event);
43 }
43 }
44
44
45 QVariant eventData(int col, const std::shared_ptr<DBEvent> &event) const
45 QVariant eventData(int col, const std::shared_ptr<DBEvent> &event) const
46 {
46 {
47 switch (static_cast<Column>(col)) {
47 switch (static_cast<Column>(col)) {
48 case CatalogueEventsModel::Column::Name:
48 case CatalogueEventsModel::Column::Name:
49 return event->getName();
49 return event->getName();
50 case CatalogueEventsModel::Column::TStart:
50 case CatalogueEventsModel::Column::TStart:
51 return nbEventProducts(event) > 0 ? DateUtils::dateTime(event->getTStart())
51 return nbEventProducts(event) > 0 ? DateUtils::dateTime(event->getTStart())
52 : QVariant{};
52 : QVariant{};
53 case CatalogueEventsModel::Column::TEnd:
53 case CatalogueEventsModel::Column::TEnd:
54 return nbEventProducts(event) > 0 ? DateUtils::dateTime(event->getTEnd())
54 return nbEventProducts(event) > 0 ? DateUtils::dateTime(event->getTEnd())
55 : QVariant{};
55 : QVariant{};
56 case CatalogueEventsModel::Column::Product:
56 case CatalogueEventsModel::Column::Product:
57 return QString::number(nbEventProducts(event)) + " product(s)";
57 return QString::number(nbEventProducts(event)) + " product(s)";
58 case CatalogueEventsModel::Column::Tags: {
58 case CatalogueEventsModel::Column::Tags: {
59 QString tagList;
59 QString tagList;
60 auto tags = event->getTags();
60 auto tags = event->getTags();
61 for (auto tag : tags) {
61 for (auto tag : tags) {
62 tagList += tag.getName();
62 tagList += tag.getName();
63 tagList += ' ';
63 tagList += ' ';
64 }
64 }
65
65
66 return tagList;
66 return tagList;
67 }
67 }
68 case CatalogueEventsModel::Column::Validation:
68 case CatalogueEventsModel::Column::Validation:
69 return QVariant();
69 return QVariant();
70 default:
70 default:
71 break;
71 break;
72 }
72 }
73
73
74 Q_ASSERT(false);
74 Q_ASSERT(false);
75 return QStringLiteral("Unknown Data");
75 return QStringLiteral("Unknown Data");
76 }
76 }
77
77
78 void parseEventProduct(const std::shared_ptr<DBEvent> &event)
78 void parseEventProduct(const std::shared_ptr<DBEvent> &event)
79 {
79 {
80 for (auto product : event->getEventProducts()) {
80 for (auto product : event->getEventProducts()) {
81 m_EventProducts[event.get()].append(std::make_shared<DBEventProduct>(product));
81 m_EventProducts[event.get()].append(std::make_shared<DBEventProduct>(product));
82 }
82 }
83 }
83 }
84
84
85 int nbEventProducts(const std::shared_ptr<DBEvent> &event) const
85 int nbEventProducts(const std::shared_ptr<DBEvent> &event) const
86 {
86 {
87 auto eventProductsIt = m_EventProducts.find(event.get());
87 auto eventProductsIt = m_EventProducts.find(event.get());
88 if (eventProductsIt != m_EventProducts.cend()) {
88 if (eventProductsIt != m_EventProducts.cend()) {
89 return m_EventProducts.at(event.get()).count();
89 return m_EventProducts.at(event.get()).count();
90 }
90 }
91 else {
91 else {
92 return 0;
92 return 0;
93 }
93 }
94 }
94 }
95
95
96 QVariant eventProductData(int col, const std::shared_ptr<DBEventProduct> &eventProduct) const
96 QVariant eventProductData(int col, const std::shared_ptr<DBEventProduct> &eventProduct) const
97 {
97 {
98 switch (static_cast<Column>(col)) {
98 switch (static_cast<Column>(col)) {
99 case CatalogueEventsModel::Column::Name:
99 case CatalogueEventsModel::Column::Name:
100 return eventProduct->getProductId();
100 return eventProduct->getProductId();
101 case CatalogueEventsModel::Column::TStart:
101 case CatalogueEventsModel::Column::TStart:
102 return DateUtils::dateTime(eventProduct->getTStart());
102 return DateUtils::dateTime(eventProduct->getTStart());
103 case CatalogueEventsModel::Column::TEnd:
103 case CatalogueEventsModel::Column::TEnd:
104 return DateUtils::dateTime(eventProduct->getTEnd());
104 return DateUtils::dateTime(eventProduct->getTEnd());
105 case CatalogueEventsModel::Column::Product:
105 case CatalogueEventsModel::Column::Product:
106 return eventProduct->getProductId();
106 return eventProduct->getProductId();
107 case CatalogueEventsModel::Column::Tags:
107 case CatalogueEventsModel::Column::Tags:
108 return QString();
108 return QString();
109 case CatalogueEventsModel::Column::Validation:
109 case CatalogueEventsModel::Column::Validation:
110 return QVariant();
110 return QVariant();
111 default:
111 default:
112 break;
112 break;
113 }
113 }
114
114
115 Q_ASSERT(false);
115 Q_ASSERT(false);
116 return QStringLiteral("Unknown Data");
116 return QStringLiteral("Unknown Data");
117 }
117 }
118
119 void refreshChildrenOfIndex(CatalogueEventsModel *model, const QModelIndex &index) const
120 {
121 auto childCount = model->rowCount(index);
122 auto colCount = model->columnCount();
123 emit model->dataChanged(model->index(0, 0, index),
124 model->index(childCount, colCount, index));
125 }
118 };
126 };
119
127
120 CatalogueEventsModel::CatalogueEventsModel(QObject *parent)
128 CatalogueEventsModel::CatalogueEventsModel(QObject *parent)
121 : QAbstractItemModel(parent), impl{spimpl::make_unique_impl<CatalogueEventsModelPrivate>()}
129 : QAbstractItemModel(parent), impl{spimpl::make_unique_impl<CatalogueEventsModelPrivate>()}
122 {
130 {
123 }
131 }
124
132
125 void CatalogueEventsModel::setEvents(const QVector<std::shared_ptr<DBEvent> > &events)
133 void CatalogueEventsModel::setEvents(const QVector<std::shared_ptr<DBEvent> > &events)
126 {
134 {
127 beginResetModel();
135 beginResetModel();
128
136
129 impl->m_Events = events;
137 impl->m_Events = events;
130 impl->m_EventProducts.clear();
138 impl->m_EventProducts.clear();
131 impl->m_EventsWithChanges.clear();
139 impl->m_EventsWithChanges.clear();
132 for (auto event : events) {
140 for (auto event : events) {
133 impl->parseEventProduct(event);
141 impl->parseEventProduct(event);
134 }
142 }
135
143
136 endResetModel();
144 endResetModel();
137 }
145 }
138
146
139 std::shared_ptr<DBEvent> CatalogueEventsModel::getEvent(const QModelIndex &index) const
147 std::shared_ptr<DBEvent> CatalogueEventsModel::getEvent(const QModelIndex &index) const
140 {
148 {
141 if (itemTypeOf(index) == CatalogueEventsModel::ItemType::Event) {
149 if (itemTypeOf(index) == CatalogueEventsModel::ItemType::Event) {
142 return impl->m_Events.value(index.row());
150 return impl->m_Events.value(index.row());
143 }
151 }
144 else {
152 else {
145 return nullptr;
153 return nullptr;
146 }
154 }
147 }
155 }
148
156
149 std::shared_ptr<DBEvent> CatalogueEventsModel::getParentEvent(const QModelIndex &index) const
157 std::shared_ptr<DBEvent> CatalogueEventsModel::getParentEvent(const QModelIndex &index) const
150 {
158 {
151 if (itemTypeOf(index) == CatalogueEventsModel::ItemType::EventProduct) {
159 if (itemTypeOf(index) == CatalogueEventsModel::ItemType::EventProduct) {
152 return getEvent(index.parent());
160 return getEvent(index.parent());
153 }
161 }
154 else {
162 else {
155 return nullptr;
163 return nullptr;
156 }
164 }
157 }
165 }
158
166
159 std::shared_ptr<DBEventProduct>
167 std::shared_ptr<DBEventProduct>
160 CatalogueEventsModel::getEventProduct(const QModelIndex &index) const
168 CatalogueEventsModel::getEventProduct(const QModelIndex &index) const
161 {
169 {
162 if (itemTypeOf(index) == CatalogueEventsModel::ItemType::EventProduct) {
170 if (itemTypeOf(index) == CatalogueEventsModel::ItemType::EventProduct) {
163 auto event = static_cast<DBEvent *>(index.internalPointer());
171 auto event = static_cast<DBEvent *>(index.internalPointer());
164 return impl->m_EventProducts.at(event).value(index.row());
172 return impl->m_EventProducts.at(event).value(index.row());
165 }
173 }
166 else {
174 else {
167 return nullptr;
175 return nullptr;
168 }
176 }
169 }
177 }
170
178
171 void CatalogueEventsModel::addEvent(const std::shared_ptr<DBEvent> &event)
179 void CatalogueEventsModel::addEvent(const std::shared_ptr<DBEvent> &event)
172 {
180 {
173 beginInsertRows(QModelIndex(), impl->m_Events.count() - 1, impl->m_Events.count() - 1);
181 beginInsertRows(QModelIndex(), impl->m_Events.count(), impl->m_Events.count());
174 impl->m_Events.append(event);
182 impl->m_Events.append(event);
175 impl->parseEventProduct(event);
183 impl->parseEventProduct(event);
176 endInsertRows();
184 endInsertRows();
185
186 // Also refreshes its children event products
187 auto eventIndex = index(impl->m_Events.count(), 0);
188 impl->refreshChildrenOfIndex(this, eventIndex);
177 }
189 }
178
190
179 void CatalogueEventsModel::removeEvent(const std::shared_ptr<DBEvent> &event)
191 void CatalogueEventsModel::removeEvent(const std::shared_ptr<DBEvent> &event)
180 {
192 {
181 auto index = impl->m_Events.indexOf(event);
193 auto index = impl->m_Events.indexOf(event);
182 if (index >= 0) {
194 if (index >= 0) {
183 beginRemoveRows(QModelIndex(), index, index);
195 beginRemoveRows(QModelIndex(), index, index);
184 impl->m_Events.removeAt(index);
196 impl->m_Events.removeAt(index);
185 impl->m_EventProducts.erase(event.get());
197 impl->m_EventProducts.erase(event.get());
186 impl->m_EventsWithChanges.erase(event);
198 impl->m_EventsWithChanges.erase(event);
187 endRemoveRows();
199 endRemoveRows();
188 }
200 }
189 }
201 }
190
202
191 QVector<std::shared_ptr<DBEvent> > CatalogueEventsModel::events() const
203 QVector<std::shared_ptr<DBEvent> > CatalogueEventsModel::events() const
192 {
204 {
193 return impl->m_Events;
205 return impl->m_Events;
194 }
206 }
195
207
196 void CatalogueEventsModel::refreshEvent(const std::shared_ptr<DBEvent> &event)
208 void CatalogueEventsModel::refreshEvent(const std::shared_ptr<DBEvent> &event)
197 {
209 {
198 auto eventIndex = indexOf(event);
210 auto eventIndex = indexOf(event);
199 if (eventIndex.isValid()) {
211 if (eventIndex.isValid()) {
200
212
201 // Refreshes the event line
213 // Refreshes the event line
202 auto colCount = columnCount();
214 auto colCount = columnCount();
203 emit dataChanged(eventIndex, index(eventIndex.row(), colCount));
215 emit dataChanged(eventIndex, index(eventIndex.row(), colCount));
204
216
205 // Also refreshes its children event products
217 // Also refreshes its children event products
206 auto childCount = rowCount(eventIndex);
218 impl->refreshChildrenOfIndex(this, eventIndex);
207 emit dataChanged(index(0, 0, eventIndex), index(childCount, colCount, eventIndex));
208 }
219 }
209 else {
220 else {
210 qCWarning(LOG_CatalogueEventsModel()) << "refreshEvent: event not found.";
221 qCWarning(LOG_CatalogueEventsModel()) << "refreshEvent: event not found.";
211 }
222 }
212 }
223 }
213
224
214 QModelIndex CatalogueEventsModel::indexOf(const std::shared_ptr<DBEvent> &event) const
225 QModelIndex CatalogueEventsModel::indexOf(const std::shared_ptr<DBEvent> &event) const
215 {
226 {
216 auto row = impl->m_Events.indexOf(event);
227 auto row = impl->m_Events.indexOf(event);
217 if (row >= 0) {
228 if (row >= 0) {
218 return index(row, 0);
229 return index(row, 0);
219 }
230 }
220
231
221 return QModelIndex();
232 return QModelIndex();
222 }
233 }
223
234
224 void CatalogueEventsModel::setEventHasChanges(const std::shared_ptr<DBEvent> &event,
235 void CatalogueEventsModel::setEventHasChanges(const std::shared_ptr<DBEvent> &event,
225 bool hasChanges)
236 bool hasChanges)
226 {
237 {
227 if (hasChanges) {
238 if (hasChanges) {
228 impl->m_EventsWithChanges.insert(event);
239 impl->m_EventsWithChanges.insert(event);
229 }
240 }
230 else {
241 else {
231 impl->m_EventsWithChanges.erase(event);
242 impl->m_EventsWithChanges.erase(event);
232 }
243 }
233 }
244 }
234
245
235 bool CatalogueEventsModel::eventsHasChanges(const std::shared_ptr<DBEvent> &event) const
246 bool CatalogueEventsModel::eventsHasChanges(const std::shared_ptr<DBEvent> &event) const
236 {
247 {
237 return impl->m_EventsWithChanges.find(event) != impl->m_EventsWithChanges.cend();
248 return impl->m_EventsWithChanges.find(event) != impl->m_EventsWithChanges.cend();
238 }
249 }
239
250
240 QModelIndex CatalogueEventsModel::index(int row, int column, const QModelIndex &parent) const
251 QModelIndex CatalogueEventsModel::index(int row, int column, const QModelIndex &parent) const
241 {
252 {
242 if (!hasIndex(row, column, parent)) {
253 if (!hasIndex(row, column, parent)) {
243 return QModelIndex();
254 return QModelIndex();
244 }
255 }
245
256
246 switch (itemTypeOf(parent)) {
257 switch (itemTypeOf(parent)) {
247 case CatalogueEventsModel::ItemType::Root:
258 case CatalogueEventsModel::ItemType::Root:
248 return createIndex(row, column);
259 return createIndex(row, column);
249 case CatalogueEventsModel::ItemType::Event: {
260 case CatalogueEventsModel::ItemType::Event: {
250 auto event = getEvent(parent);
261 auto event = getEvent(parent);
251 return createIndex(row, column, event.get());
262 return createIndex(row, column, event.get());
252 }
263 }
253 case CatalogueEventsModel::ItemType::EventProduct:
264 case CatalogueEventsModel::ItemType::EventProduct:
254 break;
265 break;
255 default:
266 default:
256 break;
267 break;
257 }
268 }
258
269
259 return QModelIndex();
270 return QModelIndex();
260 }
271 }
261
272
262 QModelIndex CatalogueEventsModel::parent(const QModelIndex &index) const
273 QModelIndex CatalogueEventsModel::parent(const QModelIndex &index) const
263 {
274 {
264 switch (itemTypeOf(index)) {
275 switch (itemTypeOf(index)) {
265 case CatalogueEventsModel::ItemType::EventProduct: {
276 case CatalogueEventsModel::ItemType::EventProduct: {
266 auto parentEvent = static_cast<DBEvent *>(index.internalPointer());
277 auto parentEvent = static_cast<DBEvent *>(index.internalPointer());
267 auto it
278 auto it
268 = std::find_if(impl->m_Events.cbegin(), impl->m_Events.cend(),
279 = std::find_if(impl->m_Events.cbegin(), impl->m_Events.cend(),
269 [parentEvent](auto event) { return event.get() == parentEvent; });
280 [parentEvent](auto event) { return event.get() == parentEvent; });
270
281
271 if (it != impl->m_Events.cend()) {
282 if (it != impl->m_Events.cend()) {
272 return createIndex(it - impl->m_Events.cbegin(), 0);
283 return createIndex(it - impl->m_Events.cbegin(), 0);
273 }
284 }
274 else {
285 else {
275 return QModelIndex();
286 return QModelIndex();
276 }
287 }
277 }
288 }
278 case CatalogueEventsModel::ItemType::Root:
289 case CatalogueEventsModel::ItemType::Root:
279 break;
290 break;
280 case CatalogueEventsModel::ItemType::Event:
291 case CatalogueEventsModel::ItemType::Event:
281 break;
292 break;
282 default:
293 default:
283 break;
294 break;
284 }
295 }
285
296
286 return QModelIndex();
297 return QModelIndex();
287 }
298 }
288
299
289 int CatalogueEventsModel::rowCount(const QModelIndex &parent) const
300 int CatalogueEventsModel::rowCount(const QModelIndex &parent) const
290 {
301 {
291 if (parent.column() > 0) {
302 if (parent.column() > 0) {
292 return 0;
303 return 0;
293 }
304 }
294
305
295 switch (itemTypeOf(parent)) {
306 switch (itemTypeOf(parent)) {
296 case CatalogueEventsModel::ItemType::Root:
307 case CatalogueEventsModel::ItemType::Root:
297 return impl->m_Events.count();
308 return impl->m_Events.count();
298 case CatalogueEventsModel::ItemType::Event: {
309 case CatalogueEventsModel::ItemType::Event: {
299 auto event = getEvent(parent);
310 auto event = getEvent(parent);
300 return impl->m_EventProducts[event.get()].count();
311 return impl->m_EventProducts[event.get()].count();
301 }
312 }
302 case CatalogueEventsModel::ItemType::EventProduct:
313 case CatalogueEventsModel::ItemType::EventProduct:
303 break;
314 break;
304 default:
315 default:
305 break;
316 break;
306 }
317 }
307
318
308 return 0;
319 return 0;
309 }
320 }
310
321
311 int CatalogueEventsModel::columnCount(const QModelIndex &parent) const
322 int CatalogueEventsModel::columnCount(const QModelIndex &parent) const
312 {
323 {
313 return static_cast<int>(CatalogueEventsModel::Column::NbColumn);
324 return static_cast<int>(CatalogueEventsModel::Column::NbColumn);
314 }
325 }
315
326
316 Qt::ItemFlags CatalogueEventsModel::flags(const QModelIndex &index) const
327 Qt::ItemFlags CatalogueEventsModel::flags(const QModelIndex &index) const
317 {
328 {
318 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
329 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
319 }
330 }
320
331
321 QVariant CatalogueEventsModel::data(const QModelIndex &index, int role) const
332 QVariant CatalogueEventsModel::data(const QModelIndex &index, int role) const
322 {
333 {
323 if (index.isValid()) {
334 if (index.isValid()) {
324
335
325 auto type = itemTypeOf(index);
336 auto type = itemTypeOf(index);
326 if (type == CatalogueEventsModel::ItemType::Event) {
337 if (type == CatalogueEventsModel::ItemType::Event) {
327 auto event = getEvent(index);
338 auto event = getEvent(index);
328 switch (role) {
339 switch (role) {
329 case Qt::DisplayRole:
340 case Qt::DisplayRole:
330 return impl->eventData(index.column(), event);
341 return impl->eventData(index.column(), event);
331 break;
342 break;
332 }
343 }
333 }
344 }
334 else if (type == CatalogueEventsModel::ItemType::EventProduct) {
345 else if (type == CatalogueEventsModel::ItemType::EventProduct) {
335 auto product = getEventProduct(index);
346 auto product = getEventProduct(index);
336 switch (role) {
347 switch (role) {
337 case Qt::DisplayRole:
348 case Qt::DisplayRole:
338 return impl->eventProductData(index.column(), product);
349 return impl->eventProductData(index.column(), product);
339 break;
350 break;
340 }
351 }
341 }
352 }
342 }
353 }
343
354
344 return QVariant{};
355 return QVariant{};
345 }
356 }
346
357
347 QVariant CatalogueEventsModel::headerData(int section, Qt::Orientation orientation, int role) const
358 QVariant CatalogueEventsModel::headerData(int section, Qt::Orientation orientation, int role) const
348 {
359 {
349 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
360 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
350 return impl->columnNames().value(section);
361 return impl->columnNames().value(section);
351 }
362 }
352
363
353 return QVariant();
364 return QVariant();
354 }
365 }
355
366
356 void CatalogueEventsModel::sort(int column, Qt::SortOrder order)
367 void CatalogueEventsModel::sort(int column, Qt::SortOrder order)
357 {
368 {
369 beginResetModel();
358 std::sort(impl->m_Events.begin(), impl->m_Events.end(),
370 std::sort(impl->m_Events.begin(), impl->m_Events.end(),
359 [this, column, order](auto e1, auto e2) {
371 [this, column, order](auto e1, auto e2) {
360 auto data1 = impl->sortData(column, e1);
372 auto data1 = impl->sortData(column, e1);
361 auto data2 = impl->sortData(column, e2);
373 auto data2 = impl->sortData(column, e2);
362
374
363 auto result = data1.toString() < data2.toString();
375 auto result = data1.toString() < data2.toString();
364
376
365 return order == Qt::AscendingOrder ? result : !result;
377 return order == Qt::AscendingOrder ? result : !result;
366 });
378 });
367
379
368 emit dataChanged(QModelIndex(), QModelIndex());
380 endResetModel();
369 emit modelSorted();
381 emit modelSorted();
370 }
382 }
371
383
372 Qt::DropActions CatalogueEventsModel::supportedDragActions() const
384 Qt::DropActions CatalogueEventsModel::supportedDragActions() const
373 {
385 {
374 return Qt::CopyAction;
386 return Qt::CopyAction;
375 }
387 }
376
388
377 QStringList CatalogueEventsModel::mimeTypes() const
389 QStringList CatalogueEventsModel::mimeTypes() const
378 {
390 {
379 return {MIME_TYPE_EVENT_LIST, MIME_TYPE_TIME_RANGE};
391 return {MIME_TYPE_EVENT_LIST, MIME_TYPE_TIME_RANGE};
380 }
392 }
381
393
382 QMimeData *CatalogueEventsModel::mimeData(const QModelIndexList &indexes) const
394 QMimeData *CatalogueEventsModel::mimeData(const QModelIndexList &indexes) const
383 {
395 {
384 auto mimeData = new QMimeData;
396 auto mimeData = new QMimeData;
385
397
386 bool isFirst = true;
398 bool isFirst = true;
387
399
388 QVector<std::shared_ptr<DBEvent> > eventList;
400 QVector<std::shared_ptr<DBEvent> > eventList;
389 QVector<std::shared_ptr<DBEventProduct> > eventProductList;
401 QVector<std::shared_ptr<DBEventProduct> > eventProductList;
390
402
391 SqpRange firstTimeRange;
403 SqpRange firstTimeRange;
392 for (const auto &index : indexes) {
404 for (const auto &index : indexes) {
393 if (index.column() == 0) { // only the first column
405 if (index.column() == 0) { // only the first column
394
406
395 auto type = itemTypeOf(index);
407 auto type = itemTypeOf(index);
396 if (type == ItemType::Event) {
408 if (type == ItemType::Event) {
397 auto event = getEvent(index);
409 auto event = getEvent(index);
398 eventList << event;
410 eventList << event;
399
411
400 if (isFirst) {
412 if (isFirst) {
401 isFirst = false;
413 isFirst = false;
402 firstTimeRange.m_TStart = event->getTStart();
414 firstTimeRange.m_TStart = event->getTStart();
403 firstTimeRange.m_TEnd = event->getTEnd();
415 firstTimeRange.m_TEnd = event->getTEnd();
404 }
416 }
405 }
417 }
406 else if (type == ItemType::EventProduct) {
418 else if (type == ItemType::EventProduct) {
407 auto product = getEventProduct(index);
419 auto product = getEventProduct(index);
408 eventProductList << product;
420 eventProductList << product;
409
421
410 if (isFirst) {
422 if (isFirst) {
411 isFirst = false;
423 isFirst = false;
412 firstTimeRange.m_TStart = product->getTStart();
424 firstTimeRange.m_TStart = product->getTStart();
413 firstTimeRange.m_TEnd = product->getTEnd();
425 firstTimeRange.m_TEnd = product->getTEnd();
414 }
426 }
415 }
427 }
416 }
428 }
417 }
429 }
418
430
419 if (!eventList.isEmpty() && eventProductList.isEmpty()) {
431 if (!eventList.isEmpty() && eventProductList.isEmpty()) {
420 auto eventsEncodedData = sqpApp->catalogueController().mimeDataForEvents(eventList);
432 auto eventsEncodedData = sqpApp->catalogueController().mimeDataForEvents(eventList);
421 mimeData->setData(MIME_TYPE_EVENT_LIST, eventsEncodedData);
433 mimeData->setData(MIME_TYPE_EVENT_LIST, eventsEncodedData);
422 }
434 }
423
435
424 if (eventList.count() + eventProductList.count() == 1) {
436 if (eventList.count() + eventProductList.count() == 1) {
425 // No time range MIME data if multiple events are dragged
437 // No time range MIME data if multiple events are dragged
426 auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange);
438 auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange);
427 mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData);
439 mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData);
428 }
440 }
429
441
430 return mimeData;
442 return mimeData;
431 }
443 }
432
444
433 CatalogueEventsModel::ItemType CatalogueEventsModel::itemTypeOf(const QModelIndex &index) const
445 CatalogueEventsModel::ItemType CatalogueEventsModel::itemTypeOf(const QModelIndex &index) const
434 {
446 {
435 if (!index.isValid()) {
447 if (!index.isValid()) {
436 return ItemType::Root;
448 return ItemType::Root;
437 }
449 }
438 else if (index.internalPointer() == nullptr) {
450 else if (index.internalPointer() == nullptr) {
439 return ItemType::Event;
451 return ItemType::Event;
440 }
452 }
441 else {
453 else {
442 return ItemType::EventProduct;
454 return ItemType::EventProduct;
443 }
455 }
444 }
456 }
General Comments 0
You need to be logged in to leave comments. Login now