##// END OF EJS Templates
Adds the ability to force an acquisition pending for an operation (2)...
Adds the ability to force an acquisition pending for an operation (2) Handles flag in the test

File last commit:

r1194:73d5f3ef941a
r1250:a7d21961e1ef
Show More
CatalogueEventsModel.cpp
442 lines | 13.8 KiB | text/x-c | CppLexer
/ gui / src / Catalogue / CatalogueEventsModel.cpp
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 #include "Catalogue/CatalogueEventsModel.h"
#include <Common/DateUtils.h>
#include <Common/MimeTypesDef.h>
#include <DBEvent.h>
#include <DBEventProduct.h>
#include <DBTag.h>
#include <Data/SqpRange.h>
#include <SqpApplication.h>
#include <Time/TimeController.h>
#include <list>
#include <unordered_map>
#include <QHash>
#include <QMimeData>
"Apply" and "cancel" buttons on an event
r1194 Q_LOGGING_CATEGORY(LOG_CatalogueEventsModel, "CatalogueEventsModel")
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 const auto EVENT_ITEM_TYPE = 1;
const auto EVENT_PRODUCT_ITEM_TYPE = 2;
Edition of event products via the inspector
r1183 struct CatalogueEventsModel::CatalogueEventsModelPrivate {
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 QVector<std::shared_ptr<DBEvent> > m_Events;
std::unordered_map<DBEvent *, QVector<std::shared_ptr<DBEventProduct> > > m_EventProducts;
"Apply" and "cancel" buttons on an event
r1194 std::unordered_set<std::shared_ptr<DBEvent> > m_EventsWithChanges;
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182
QStringList columnNames()
{
"Apply" and "cancel" buttons on an event
r1194 return QStringList{tr("Event"), tr("TStart"), tr("TEnd"),
tr("Tags"), tr("Product"), tr("")};
}
QVariant sortData(int col, const std::shared_ptr<DBEvent> &event) const
{
if (col == (int)CatalogueEventsModel::Column::Validation) {
return m_EventsWithChanges.find(event) != m_EventsWithChanges.cend() ? true
: QVariant();
}
return eventData(col, event);
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 }
QVariant eventData(int col, const std::shared_ptr<DBEvent> &event) const
{
switch (static_cast<Column>(col)) {
"Apply" and "cancel" buttons on an event
r1194 case CatalogueEventsModel::Column::Name:
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 return event->getName();
"Apply" and "cancel" buttons on an event
r1194 case CatalogueEventsModel::Column::TStart:
Fix display of tstart & tend when an event has no event products
r1193 return nbEventProducts(event) > 0 ? DateUtils::dateTime(event->getTStart())
: QVariant{};
"Apply" and "cancel" buttons on an event
r1194 case CatalogueEventsModel::Column::TEnd:
Fix display of tstart & tend when an event has no event products
r1193 return nbEventProducts(event) > 0 ? DateUtils::dateTime(event->getTEnd())
: QVariant{};
"Apply" and "cancel" buttons on an event
r1194 case CatalogueEventsModel::Column::Product:
Fix display of tstart & tend when an event has no event products
r1193 return QString::number(nbEventProducts(event)) + " product(s)";
"Apply" and "cancel" buttons on an event
r1194 case CatalogueEventsModel::Column::Tags: {
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 QString tagList;
auto tags = event->getTags();
for (auto tag : tags) {
tagList += tag.getName();
tagList += ' ';
}
return tagList;
}
"Apply" and "cancel" buttons on an event
r1194 case CatalogueEventsModel::Column::Validation:
return QVariant();
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 default:
break;
}
Q_ASSERT(false);
return QStringLiteral("Unknown Data");
}
void parseEventProduct(const std::shared_ptr<DBEvent> &event)
{
for (auto product : event->getEventProducts()) {
m_EventProducts[event.get()].append(std::make_shared<DBEventProduct>(product));
}
}
Fix display of tstart & tend when an event has no event products
r1193 int nbEventProducts(const std::shared_ptr<DBEvent> &event) const
{
auto eventProductsIt = m_EventProducts.find(event.get());
if (eventProductsIt != m_EventProducts.cend()) {
return m_EventProducts.at(event.get()).count();
}
else {
return 0;
}
}
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 QVariant eventProductData(int col, const std::shared_ptr<DBEventProduct> &eventProduct) const
{
switch (static_cast<Column>(col)) {
"Apply" and "cancel" buttons on an event
r1194 case CatalogueEventsModel::Column::Name:
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 return eventProduct->getProductId();
"Apply" and "cancel" buttons on an event
r1194 case CatalogueEventsModel::Column::TStart:
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 return DateUtils::dateTime(eventProduct->getTStart());
"Apply" and "cancel" buttons on an event
r1194 case CatalogueEventsModel::Column::TEnd:
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 return DateUtils::dateTime(eventProduct->getTEnd());
"Apply" and "cancel" buttons on an event
r1194 case CatalogueEventsModel::Column::Product:
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 return eventProduct->getProductId();
"Apply" and "cancel" buttons on an event
r1194 case CatalogueEventsModel::Column::Tags:
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 return QString();
"Apply" and "cancel" buttons on an event
r1194 case CatalogueEventsModel::Column::Validation:
return QVariant();
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 default:
break;
}
Q_ASSERT(false);
return QStringLiteral("Unknown Data");
}
};
CatalogueEventsModel::CatalogueEventsModel(QObject *parent)
Edition of event products via the inspector
r1183 : QAbstractItemModel(parent), impl{spimpl::make_unique_impl<CatalogueEventsModelPrivate>()}
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 {
}
void CatalogueEventsModel::setEvents(const QVector<std::shared_ptr<DBEvent> > &events)
{
beginResetModel();
impl->m_Events = events;
Edition of event products via the inspector
r1183 impl->m_EventProducts.clear();
"Apply" and "cancel" buttons on an event
r1194 impl->m_EventsWithChanges.clear();
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 for (auto event : events) {
impl->parseEventProduct(event);
}
endResetModel();
}
Edition of event products via the inspector
r1183 std::shared_ptr<DBEvent> CatalogueEventsModel::getEvent(const QModelIndex &index) const
{
if (itemTypeOf(index) == CatalogueEventsModel::ItemType::Event) {
return impl->m_Events.value(index.row());
}
else {
return nullptr;
}
}
std::shared_ptr<DBEvent> CatalogueEventsModel::getParentEvent(const QModelIndex &index) const
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 {
Edition of event products via the inspector
r1183 if (itemTypeOf(index) == CatalogueEventsModel::ItemType::EventProduct) {
return getEvent(index.parent());
}
else {
return nullptr;
}
}
std::shared_ptr<DBEventProduct>
CatalogueEventsModel::getEventProduct(const QModelIndex &index) const
{
if (itemTypeOf(index) == CatalogueEventsModel::ItemType::EventProduct) {
auto event = static_cast<DBEvent *>(index.internalPointer());
return impl->m_EventProducts.at(event).value(index.row());
}
else {
return nullptr;
}
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 }
void CatalogueEventsModel::addEvent(const std::shared_ptr<DBEvent> &event)
{
beginInsertRows(QModelIndex(), impl->m_Events.count() - 1, impl->m_Events.count() - 1);
impl->m_Events.append(event);
impl->parseEventProduct(event);
endInsertRows();
}
void CatalogueEventsModel::removeEvent(const std::shared_ptr<DBEvent> &event)
{
auto index = impl->m_Events.indexOf(event);
if (index >= 0) {
beginRemoveRows(QModelIndex(), index, index);
impl->m_Events.removeAt(index);
impl->m_EventProducts.erase(event.get());
"Apply" and "cancel" buttons on an event
r1194 impl->m_EventsWithChanges.erase(event);
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 endRemoveRows();
}
}
"Apply" and "cancel" buttons on an event
r1194 QVector<std::shared_ptr<DBEvent> > CatalogueEventsModel::events() const
{
return impl->m_Events;
}
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 void CatalogueEventsModel::refreshEvent(const std::shared_ptr<DBEvent> &event)
{
"Apply" and "cancel" buttons on an event
r1194 auto eventIndex = indexOf(event);
if (eventIndex.isValid()) {
// Refreshes the event line
Edition of event products via the inspector
r1183 auto colCount = columnCount();
"Apply" and "cancel" buttons on an event
r1194 emit dataChanged(eventIndex, index(eventIndex.row(), colCount));
Edition of event products via the inspector
r1183
"Apply" and "cancel" buttons on an event
r1194 // Also refreshes its children event products
Edition of event products via the inspector
r1183 auto childCount = rowCount(eventIndex);
emit dataChanged(index(0, 0, eventIndex), index(childCount, colCount, eventIndex));
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 }
"Apply" and "cancel" buttons on an event
r1194 else {
qCWarning(LOG_CatalogueEventsModel()) << "refreshEvent: event not found.";
}
}
QModelIndex CatalogueEventsModel::indexOf(const std::shared_ptr<DBEvent> &event) const
{
auto row = impl->m_Events.indexOf(event);
if (row >= 0) {
return index(row, 0);
}
return QModelIndex();
}
void CatalogueEventsModel::setEventHasChanges(const std::shared_ptr<DBEvent> &event,
bool hasChanges)
{
if (hasChanges) {
impl->m_EventsWithChanges.insert(event);
}
else {
impl->m_EventsWithChanges.erase(event);
}
}
bool CatalogueEventsModel::eventsHasChanges(const std::shared_ptr<DBEvent> &event) const
{
return impl->m_EventsWithChanges.find(event) != impl->m_EventsWithChanges.cend();
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 }
QModelIndex CatalogueEventsModel::index(int row, int column, const QModelIndex &parent) const
{
if (!hasIndex(row, column, parent)) {
return QModelIndex();
}
Edition of event products via the inspector
r1183 switch (itemTypeOf(parent)) {
case CatalogueEventsModel::ItemType::Root:
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 return createIndex(row, column);
Edition of event products via the inspector
r1183 case CatalogueEventsModel::ItemType::Event: {
auto event = getEvent(parent);
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 return createIndex(row, column, event.get());
}
Edition of event products via the inspector
r1183 case CatalogueEventsModel::ItemType::EventProduct:
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 break;
default:
break;
}
return QModelIndex();
}
QModelIndex CatalogueEventsModel::parent(const QModelIndex &index) const
{
Edition of event products via the inspector
r1183 switch (itemTypeOf(index)) {
case CatalogueEventsModel::ItemType::EventProduct: {
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 auto parentEvent = static_cast<DBEvent *>(index.internalPointer());
auto it
= std::find_if(impl->m_Events.cbegin(), impl->m_Events.cend(),
[parentEvent](auto event) { return event.get() == parentEvent; });
if (it != impl->m_Events.cend()) {
return createIndex(it - impl->m_Events.cbegin(), 0);
}
else {
return QModelIndex();
}
}
Edition of event products via the inspector
r1183 case CatalogueEventsModel::ItemType::Root:
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 break;
Edition of event products via the inspector
r1183 case CatalogueEventsModel::ItemType::Event:
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 break;
default:
break;
}
return QModelIndex();
}
int CatalogueEventsModel::rowCount(const QModelIndex &parent) const
{
if (parent.column() > 0) {
return 0;
}
Edition of event products via the inspector
r1183 switch (itemTypeOf(parent)) {
case CatalogueEventsModel::ItemType::Root:
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 return impl->m_Events.count();
Edition of event products via the inspector
r1183 case CatalogueEventsModel::ItemType::Event: {
auto event = getEvent(parent);
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 return impl->m_EventProducts[event.get()].count();
}
Edition of event products via the inspector
r1183 case CatalogueEventsModel::ItemType::EventProduct:
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 break;
default:
break;
}
return 0;
}
int CatalogueEventsModel::columnCount(const QModelIndex &parent) const
{
"Apply" and "cancel" buttons on an event
r1194 return static_cast<int>(CatalogueEventsModel::Column::NbColumn);
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 }
Qt::ItemFlags CatalogueEventsModel::flags(const QModelIndex &index) const
{
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
}
QVariant CatalogueEventsModel::data(const QModelIndex &index, int role) const
{
if (index.isValid()) {
Edition of event products via the inspector
r1183 auto type = itemTypeOf(index);
if (type == CatalogueEventsModel::ItemType::Event) {
auto event = getEvent(index);
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 switch (role) {
case Qt::DisplayRole:
return impl->eventData(index.column(), event);
break;
}
}
Edition of event products via the inspector
r1183 else if (type == CatalogueEventsModel::ItemType::EventProduct) {
auto product = getEventProduct(index);
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 switch (role) {
case Qt::DisplayRole:
return impl->eventProductData(index.column(), product);
break;
}
}
}
return QVariant{};
}
QVariant CatalogueEventsModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
return impl->columnNames().value(section);
}
return QVariant();
}
void CatalogueEventsModel::sort(int column, Qt::SortOrder order)
{
std::sort(impl->m_Events.begin(), impl->m_Events.end(),
[this, column, order](auto e1, auto e2) {
"Apply" and "cancel" buttons on an event
r1194 auto data1 = impl->sortData(column, e1);
auto data2 = impl->sortData(column, e2);
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182
auto result = data1.toString() < data2.toString();
return order == Qt::AscendingOrder ? result : !result;
});
emit dataChanged(QModelIndex(), QModelIndex());
"Apply" and "cancel" buttons on an event
r1194 emit modelSorted();
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 }
Qt::DropActions CatalogueEventsModel::supportedDragActions() const
{
return Qt::CopyAction | Qt::MoveAction;
}
QStringList CatalogueEventsModel::mimeTypes() const
{
return {MIME_TYPE_EVENT_LIST, MIME_TYPE_TIME_RANGE};
}
QMimeData *CatalogueEventsModel::mimeData(const QModelIndexList &indexes) const
{
auto mimeData = new QMimeData;
Fix drag&drop on time widget with event products
r1184 bool isFirst = true;
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 QVector<std::shared_ptr<DBEvent> > eventList;
Fix drag&drop on time widget with event products
r1184 QVector<std::shared_ptr<DBEventProduct> > eventProductList;
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182
SqpRange firstTimeRange;
for (const auto &index : indexes) {
if (index.column() == 0) { // only the first column
Fix drag&drop on time widget with event products
r1184 auto type = itemTypeOf(index);
if (type == ItemType::Event) {
auto event = getEvent(index);
eventList << event;
if (isFirst) {
isFirst = false;
Displays TStart & TEnd for events
r1185 firstTimeRange.m_TStart = event->getTStart();
firstTimeRange.m_TEnd = event->getTEnd();
Fix drag&drop on time widget with event products
r1184 }
}
else if (type == ItemType::EventProduct) {
auto product = getEventProduct(index);
eventProductList << product;
if (isFirst) {
isFirst = false;
firstTimeRange.m_TStart = product->getTStart();
firstTimeRange.m_TEnd = product->getTEnd();
}
}
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 }
}
auto eventsEncodedData
= QByteArray{}; // sqpApp->catalogueController().->mimeDataForEvents(eventList); //TODO
mimeData->setData(MIME_TYPE_EVENT_LIST, eventsEncodedData);
Fix drag&drop on time widget with event products
r1184 if (eventList.count() + eventProductList.count() == 1) {
Change the event model to a treeview model + update the last version of CatalogueAPI
r1182 // No time range MIME data if multiple events are dragged
auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange);
mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData);
}
return mimeData;
}
Edition of event products via the inspector
r1183
CatalogueEventsModel::ItemType CatalogueEventsModel::itemTypeOf(const QModelIndex &index) const
{
if (!index.isValid()) {
return ItemType::Root;
}
else if (index.internalPointer() == nullptr) {
return ItemType::Event;
}
else {
return ItemType::EventProduct;
}
}