mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-19 12:06:57 +08:00
refs #452, model base class
* drag and drop support * model can be marked as destoyed when view is about to be destroyed (to cancel pending actions)
This commit is contained in:
committed by
Mathew Sutcliffe
parent
0d27351e11
commit
fb4baa0ef8
@@ -7,10 +7,17 @@
|
|||||||
* contained in the LICENSE file.
|
* contained in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Drag and drop docu:
|
||||||
|
// http://doc.qt.io/qt-5/model-view-programming.html#using-drag-and-drop-with-item-views
|
||||||
|
|
||||||
#include "listmodelbase.h"
|
#include "listmodelbase.h"
|
||||||
#include "allmodelcontainers.h"
|
#include "allmodelcontainers.h"
|
||||||
|
#include "blackgui/guiutility.h"
|
||||||
#include "blackmisc/variant.h"
|
#include "blackmisc/variant.h"
|
||||||
|
#include "blackmisc/json.h"
|
||||||
#include "blackmisc/blackmiscfreefunctions.h"
|
#include "blackmisc/blackmiscfreefunctions.h"
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
using namespace BlackMisc;
|
using namespace BlackMisc;
|
||||||
|
|
||||||
@@ -27,10 +34,19 @@ namespace BlackGui
|
|||||||
|
|
||||||
QVariant CListModelBaseNonTemplate::headerData(int section, Qt::Orientation orientation, int role) const
|
QVariant CListModelBaseNonTemplate::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
{
|
{
|
||||||
if (orientation != Qt::Horizontal) { return QVariant(); }
|
if (orientation != Qt::Horizontal)
|
||||||
|
{
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
bool handled = (role == Qt::DisplayRole || role == Qt::ToolTipRole || role == Qt::InitialSortOrderRole);
|
bool handled = (role == Qt::DisplayRole || role == Qt::ToolTipRole || role == Qt::InitialSortOrderRole);
|
||||||
if (!handled) {return QVariant();}
|
if (!handled)
|
||||||
if (section < 0 || section >= this->m_columns.size()) { return QVariant(); }
|
{
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
if (section < 0 || section >= this->m_columns.size())
|
||||||
|
{
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
if (role == Qt::DisplayRole)
|
if (role == Qt::DisplayRole)
|
||||||
{
|
{
|
||||||
@@ -90,13 +106,14 @@ namespace BlackGui
|
|||||||
if (!index.isValid()) { return f; }
|
if (!index.isValid()) { return f; }
|
||||||
bool editable = this->m_columns.isEditable(index);
|
bool editable = this->m_columns.isEditable(index);
|
||||||
f = editable ? (f | Qt::ItemIsEditable) : (f ^ Qt::ItemIsEditable);
|
f = editable ? (f | Qt::ItemIsEditable) : (f ^ Qt::ItemIsEditable);
|
||||||
const CDefaultFormatter *formatter = this->m_columns.getFormatter(index);
|
|
||||||
if (formatter)
|
|
||||||
{
|
|
||||||
return formatter->flags(f, editable);
|
|
||||||
}
|
|
||||||
|
|
||||||
// fallback behaviour with no formatter
|
// flags from formatter
|
||||||
|
const CDefaultFormatter *formatter = this->m_columns.getFormatter(index);
|
||||||
|
if (formatter) { f = formatter->flags(f, editable); }
|
||||||
|
|
||||||
|
// drag and rop
|
||||||
|
f = f | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,11 +122,44 @@ namespace BlackGui
|
|||||||
return m_columns.getTranslationContext();
|
return m_columns.getTranslationContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Qt::DropActions CListModelBaseNonTemplate::supportedDragActions() const
|
||||||
|
{
|
||||||
|
return Qt::CopyAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::DropActions CListModelBaseNonTemplate::supportedDropActions() const
|
||||||
|
{
|
||||||
|
return QAbstractItemModel::supportedDropActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList CListModelBaseNonTemplate::mimeTypes() const
|
||||||
|
{
|
||||||
|
static const QStringList mimes( { "application/swift.container.json" });
|
||||||
|
return mimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CListModelBaseNonTemplate::markDestroyed()
|
||||||
|
{
|
||||||
|
this->m_modelDestroyed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CListModelBaseNonTemplate::isModelDestroyed()
|
||||||
|
{
|
||||||
|
return m_modelDestroyed;
|
||||||
|
}
|
||||||
|
|
||||||
int CListModelBaseNonTemplate::ps_updateContainer(const CVariant &variant, bool sort)
|
int CListModelBaseNonTemplate::ps_updateContainer(const CVariant &variant, bool sort)
|
||||||
{
|
{
|
||||||
return this->performUpdateContainer(variant, sort);
|
return this->performUpdateContainer(variant, sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CListModelBaseNonTemplate::CListModelBaseNonTemplate(const QString &translationContext, QObject *parent)
|
||||||
|
: QAbstractItemModel(parent), m_columns(translationContext), m_sortedColumn(-1), m_sortOrder(Qt::AscendingOrder)
|
||||||
|
{
|
||||||
|
// non unique default name, set translation context as default
|
||||||
|
this->setObjectName(translationContext);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename ObjectType, typename ContainerType>
|
template <typename ObjectType, typename ContainerType>
|
||||||
int CListModelBase<ObjectType, ContainerType>::rowCount(const QModelIndex &parentIndex) const
|
int CListModelBase<ObjectType, ContainerType>::rowCount(const QModelIndex &parentIndex) const
|
||||||
{
|
{
|
||||||
@@ -144,14 +194,26 @@ namespace BlackGui
|
|||||||
bool CListModelBase<ObjectType, ContainerType>::setData(const QModelIndex &index, const QVariant &value, int role)
|
bool CListModelBase<ObjectType, ContainerType>::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
{
|
{
|
||||||
Qt::ItemDataRole dataRole = static_cast<Qt::ItemDataRole>(role);
|
Qt::ItemDataRole dataRole = static_cast<Qt::ItemDataRole>(role);
|
||||||
if (!(dataRole == Qt::UserRole || dataRole == Qt::EditRole)) { return false; }
|
if (!(dataRole == Qt::UserRole || dataRole == Qt::EditRole))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// check / init
|
// check / init
|
||||||
if (!this->isValidIndex(index)) { return false; }
|
if (!this->isValidIndex(index))
|
||||||
if (!this->m_columns.isEditable(index)) { return false; }
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!this->m_columns.isEditable(index))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const CDefaultFormatter *formatter = this->m_columns.getFormatter(index);
|
const CDefaultFormatter *formatter = this->m_columns.getFormatter(index);
|
||||||
Q_ASSERT(formatter);
|
Q_ASSERT(formatter);
|
||||||
if (!formatter) { return false; }
|
if (!formatter)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ObjectType obj = this->m_container[index.row()];
|
ObjectType obj = this->m_container[index.row()];
|
||||||
ObjectType currentObject(obj);
|
ObjectType currentObject(obj);
|
||||||
@@ -175,6 +237,8 @@ namespace BlackGui
|
|||||||
template <typename ObjectType, typename ContainerType>
|
template <typename ObjectType, typename ContainerType>
|
||||||
int CListModelBase<ObjectType, ContainerType>::update(const ContainerType &container, bool sort)
|
int CListModelBase<ObjectType, ContainerType>::update(const ContainerType &container, bool sort)
|
||||||
{
|
{
|
||||||
|
if (m_modelDestroyed) { return 0; }
|
||||||
|
|
||||||
// Keep sorting out of begin/end reset model
|
// Keep sorting out of begin/end reset model
|
||||||
ContainerType sortedContainer;
|
ContainerType sortedContainer;
|
||||||
int oldSize = this->m_container.size();
|
int oldSize = this->m_container.size();
|
||||||
@@ -191,13 +255,17 @@ namespace BlackGui
|
|||||||
this->endResetModel();
|
this->endResetModel();
|
||||||
|
|
||||||
int newSize = this->m_container.size();
|
int newSize = this->m_container.size();
|
||||||
if (oldSize != newSize) { this->emitRowCountChanged(); }
|
if (oldSize != newSize)
|
||||||
|
{
|
||||||
|
this->emitRowCountChanged();
|
||||||
|
}
|
||||||
return newSize;
|
return newSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ObjectType, typename ContainerType>
|
template <typename ObjectType, typename ContainerType>
|
||||||
void CListModelBase<ObjectType, ContainerType>::update(const QModelIndex &index, const ObjectType &object)
|
void CListModelBase<ObjectType, ContainerType>::update(const QModelIndex &index, const ObjectType &object)
|
||||||
{
|
{
|
||||||
|
if (m_modelDestroyed) { return; }
|
||||||
if (index.row() >= this->m_container.size()) { return; }
|
if (index.row() >= this->m_container.size()) { return; }
|
||||||
this->m_container[index.row()] = object;
|
this->m_container[index.row()] = object;
|
||||||
|
|
||||||
@@ -216,6 +284,7 @@ namespace BlackGui
|
|||||||
CWorker *CListModelBase<ObjectType, ContainerType>::updateAsync(const ContainerType &container, bool sort)
|
CWorker *CListModelBase<ObjectType, ContainerType>::updateAsync(const ContainerType &container, bool sort)
|
||||||
{
|
{
|
||||||
Q_UNUSED(sort);
|
Q_UNUSED(sort);
|
||||||
|
if (m_modelDestroyed) { return nullptr; }
|
||||||
auto sortColumn = this->getSortColumn();
|
auto sortColumn = this->getSortColumn();
|
||||||
auto sortOrder = this->getSortOrder();
|
auto sortOrder = this->getSortOrder();
|
||||||
CWorker *worker = BlackMisc::CWorker::fromTask(this, "ModelSort", [this, container, sortColumn, sortOrder]()
|
CWorker *worker = BlackMisc::CWorker::fromTask(this, "ModelSort", [this, container, sortColumn, sortOrder]()
|
||||||
@@ -224,6 +293,7 @@ namespace BlackGui
|
|||||||
});
|
});
|
||||||
worker->thenWithResult<ContainerType>(this, [this](const ContainerType &sortedContainer)
|
worker->thenWithResult<ContainerType>(this, [this](const ContainerType &sortedContainer)
|
||||||
{
|
{
|
||||||
|
if (this->m_modelDestroyed) { return; }
|
||||||
this->ps_updateContainer(CVariant::from(sortedContainer), false);
|
this->ps_updateContainer(CVariant::from(sortedContainer), false);
|
||||||
});
|
});
|
||||||
worker->then(this, &CListModelBase::asyncUpdateFinished);
|
worker->then(this, &CListModelBase::asyncUpdateFinished);
|
||||||
@@ -233,6 +303,7 @@ namespace BlackGui
|
|||||||
template <typename ObjectType, typename ContainerType>
|
template <typename ObjectType, typename ContainerType>
|
||||||
void CListModelBase<ObjectType, ContainerType>::updateContainerMaybeAsync(const ContainerType &container, bool sort)
|
void CListModelBase<ObjectType, ContainerType>::updateContainerMaybeAsync(const ContainerType &container, bool sort)
|
||||||
{
|
{
|
||||||
|
if (m_modelDestroyed) { return; }
|
||||||
if (container.size() > asyncThreshold && sort)
|
if (container.size() > asyncThreshold && sort)
|
||||||
{
|
{
|
||||||
// larger container with sorting
|
// larger container with sorting
|
||||||
@@ -247,7 +318,7 @@ namespace BlackGui
|
|||||||
template <typename ObjectType, typename ContainerType>
|
template <typename ObjectType, typename ContainerType>
|
||||||
bool CListModelBase<ObjectType, ContainerType>::hasFilter() const
|
bool CListModelBase<ObjectType, ContainerType>::hasFilter() const
|
||||||
{
|
{
|
||||||
return m_filter ? true : false;
|
return m_filter && m_filter->isValid() ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ObjectType, typename ContainerType>
|
template <typename ObjectType, typename ContainerType>
|
||||||
@@ -262,9 +333,13 @@ namespace BlackGui
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ObjectType, typename ContainerType>
|
template <typename ObjectType, typename ContainerType>
|
||||||
void CListModelBase<ObjectType, ContainerType>::setFilter(std::unique_ptr<IModelFilter<ContainerType> > &filter)
|
void CListModelBase<ObjectType, ContainerType>::takeFilterOwnership(std::unique_ptr<IModelFilter<ContainerType> > &filter)
|
||||||
{
|
{
|
||||||
if (!filter) { this->removeFilter(); return; } // empty filter
|
if (!filter)
|
||||||
|
{
|
||||||
|
this->removeFilter(); // empty filter
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (filter->isValid())
|
if (filter->isValid())
|
||||||
{
|
{
|
||||||
this->m_filter = std::move(filter);
|
this->m_filter = std::move(filter);
|
||||||
@@ -371,7 +446,10 @@ namespace BlackGui
|
|||||||
template <typename ObjectType, typename ContainerType>
|
template <typename ObjectType, typename ContainerType>
|
||||||
const ContainerType &CListModelBase<ObjectType, ContainerType>::getContainerOrFilteredContainer() const
|
const ContainerType &CListModelBase<ObjectType, ContainerType>::getContainerOrFilteredContainer() const
|
||||||
{
|
{
|
||||||
if (!this->hasFilter()) { return this->m_container; }
|
if (!this->hasFilter())
|
||||||
|
{
|
||||||
|
return this->m_container;
|
||||||
|
}
|
||||||
return m_containerFiltered;
|
return m_containerFiltered;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,7 +487,10 @@ namespace BlackGui
|
|||||||
// new order
|
// new order
|
||||||
this->m_sortedColumn = column;
|
this->m_sortedColumn = column;
|
||||||
this->m_sortOrder = order;
|
this->m_sortOrder = order;
|
||||||
if (this->m_container.size() < 2) { return; } // nothing to do
|
if (this->m_container.size() < 2)
|
||||||
|
{
|
||||||
|
return; // nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
// sort the values
|
// sort the values
|
||||||
this->updateContainerMaybeAsync(this->m_container, true);
|
this->updateContainerMaybeAsync(this->m_container, true);
|
||||||
@@ -419,7 +500,10 @@ namespace BlackGui
|
|||||||
void CListModelBase<ObjectType, ContainerType>::truncate(int maxNumber, bool forceSort)
|
void CListModelBase<ObjectType, ContainerType>::truncate(int maxNumber, bool forceSort)
|
||||||
{
|
{
|
||||||
if (this->rowCount() <= maxNumber) { return; }
|
if (this->rowCount() <= maxNumber) { return; }
|
||||||
if (forceSort) { this->sort(); } // make sure container is sorted
|
if (forceSort)
|
||||||
|
{
|
||||||
|
this->sort(); // make sure container is sorted
|
||||||
|
}
|
||||||
ContainerType container(this->getContainer());
|
ContainerType container(this->getContainer());
|
||||||
container.truncate(maxNumber);
|
container.truncate(maxNumber);
|
||||||
this->updateContainerMaybeAsync(container, false);
|
this->updateContainerMaybeAsync(container, false);
|
||||||
@@ -428,12 +512,19 @@ namespace BlackGui
|
|||||||
template <typename ObjectType, typename ContainerType>
|
template <typename ObjectType, typename ContainerType>
|
||||||
ContainerType CListModelBase<ObjectType, ContainerType>::sortContainerByColumn(const ContainerType &container, int column, Qt::SortOrder order) const
|
ContainerType CListModelBase<ObjectType, ContainerType>::sortContainerByColumn(const ContainerType &container, int column, Qt::SortOrder order) const
|
||||||
{
|
{
|
||||||
if (container.size() < 2 || !this->m_columns.isSortable(column)) { return container; } // nothing to do
|
if (m_modelDestroyed) { return container; }
|
||||||
|
if (container.size() < 2 || !this->m_columns.isSortable(column))
|
||||||
|
{
|
||||||
|
return container; // nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
// this is the only part not really thread safe, but columns do not change so far
|
// this is the only part not really thread safe, but columns do not change so far
|
||||||
BlackMisc::CPropertyIndex propertyIndex = this->m_columns.columnToSortPropertyIndex(column);
|
BlackMisc::CPropertyIndex propertyIndex = this->m_columns.columnToSortPropertyIndex(column);
|
||||||
Q_ASSERT(!propertyIndex.isEmpty());
|
Q_ASSERT(!propertyIndex.isEmpty());
|
||||||
if (propertyIndex.isEmpty()) { return container; } // at release build do nothing
|
if (propertyIndex.isEmpty())
|
||||||
|
{
|
||||||
|
return container; // at release build do nothing
|
||||||
|
}
|
||||||
|
|
||||||
// sort the values
|
// sort the values
|
||||||
const auto p = [ = ](const ObjectType & a, const ObjectType & b) -> bool
|
const auto p = [ = ](const ObjectType & a, const ObjectType & b) -> bool
|
||||||
@@ -447,20 +538,48 @@ namespace BlackGui
|
|||||||
return sorted;
|
return sorted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename ObjectType, typename ContainerType>
|
||||||
|
QMimeData *CListModelBase<ObjectType, ContainerType>::mimeData(const QModelIndexList &indexes) const
|
||||||
|
{
|
||||||
|
QMimeData *mimeData = new QMimeData();
|
||||||
|
if (indexes.isEmpty()) { return mimeData; }
|
||||||
|
|
||||||
|
ContainerType container;
|
||||||
|
QList<int> rows; // avoid redundant objects
|
||||||
|
|
||||||
|
// Indexes are per row and column
|
||||||
|
for (const QModelIndex &index : indexes)
|
||||||
|
{
|
||||||
|
if (!index.isValid()) { continue; }
|
||||||
|
int r = index.row();
|
||||||
|
if (rows.contains(r)) { continue; }
|
||||||
|
container.push_back(this->at(index));
|
||||||
|
rows.append(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
// to JSON via CVariant
|
||||||
|
const QJsonDocument containerJson(CVariant::fromValue(container).toJson());
|
||||||
|
const QString jsonString(containerJson.toJson(QJsonDocument::Compact));
|
||||||
|
|
||||||
|
mimeData->setData(CGuiUtility::swiftJsonDragAndDropMimeType(), jsonString.toUtf8());
|
||||||
|
return mimeData;
|
||||||
|
}
|
||||||
|
|
||||||
// see here for the reason of thess forward instantiations
|
// see here for the reason of thess forward instantiations
|
||||||
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
|
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
|
||||||
template class CListModelBase<BlackMisc::CIdentifier, BlackMisc::CIdentifierList>;
|
template class CListModelBase<BlackMisc::CIdentifier, BlackMisc::CIdentifierList>;
|
||||||
template class CListModelBase<BlackMisc::CStatusMessage, BlackMisc::CStatusMessageList>;
|
template class CListModelBase<BlackMisc::CStatusMessage, BlackMisc::CStatusMessageList>;
|
||||||
template class CListModelBase<BlackMisc::CNameVariantPair, BlackMisc::CNameVariantPairList>;
|
template class CListModelBase<BlackMisc::CNameVariantPair, BlackMisc::CNameVariantPairList>;
|
||||||
|
template class CListModelBase<BlackMisc::CCountry, BlackMisc::CCountryList>;
|
||||||
template class CListModelBase<BlackMisc::Aviation::CAtcStation, BlackMisc::Aviation::CAtcStationList>;
|
template class CListModelBase<BlackMisc::Aviation::CAtcStation, BlackMisc::Aviation::CAtcStationList>;
|
||||||
template class CListModelBase<BlackMisc::Aviation::CAircraft, BlackMisc::Aviation::CAircraftList>;
|
|
||||||
template class CListModelBase<BlackMisc::Aviation::CAirport, BlackMisc::Aviation::CAirportList>;
|
template class CListModelBase<BlackMisc::Aviation::CAirport, BlackMisc::Aviation::CAirportList>;
|
||||||
template class CListModelBase<BlackMisc::Aviation::CLivery, BlackMisc::Aviation::CLiveryList>;
|
template class CListModelBase<BlackMisc::Aviation::CLivery, BlackMisc::Aviation::CLiveryList>;
|
||||||
|
template class CListModelBase<BlackMisc::Aviation::CAircraftIcaoCode, BlackMisc::Aviation::CAircraftIcaoCodeList>;
|
||||||
|
template class CListModelBase<BlackMisc::Aviation::CAirlineIcaoCode, BlackMisc::Aviation::CAirlineIcaoCodeList>;
|
||||||
template class CListModelBase<BlackMisc::Network::CServer, BlackMisc::Network::CServerList>;
|
template class CListModelBase<BlackMisc::Network::CServer, BlackMisc::Network::CServerList>;
|
||||||
template class CListModelBase<BlackMisc::Network::CUser, BlackMisc::Network::CUserList>;
|
template class CListModelBase<BlackMisc::Network::CUser, BlackMisc::Network::CUserList>;
|
||||||
template class CListModelBase<BlackMisc::Network::CTextMessage, BlackMisc::Network::CTextMessageList>;
|
template class CListModelBase<BlackMisc::Network::CTextMessage, BlackMisc::Network::CTextMessageList>;
|
||||||
template class CListModelBase<BlackMisc::Network::CClient, BlackMisc::Network::CClientList>;
|
template class CListModelBase<BlackMisc::Network::CClient, BlackMisc::Network::CClientList>;
|
||||||
template class CListModelBase<BlackMisc::Network::CAircraftMapping, BlackMisc::Network::CAircraftMappingList>;
|
|
||||||
template class CListModelBase<BlackMisc::Simulation::CAircraftModel, BlackMisc::Simulation::CAircraftModelList>;
|
template class CListModelBase<BlackMisc::Simulation::CAircraftModel, BlackMisc::Simulation::CAircraftModelList>;
|
||||||
template class CListModelBase<BlackMisc::Simulation::CSimulatedAircraft, BlackMisc::Simulation::CSimulatedAircraftList>;
|
template class CListModelBase<BlackMisc::Simulation::CSimulatedAircraft, BlackMisc::Simulation::CSimulatedAircraftList>;
|
||||||
template class CListModelBase<BlackMisc::Simulation::CDistributor, BlackMisc::Simulation::CDistributorList>;
|
template class CListModelBase<BlackMisc::Simulation::CDistributor, BlackMisc::Simulation::CDistributorList>;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#include "blackgui/blackguiexport.h"
|
#include "blackgui/blackguiexport.h"
|
||||||
#include "blackgui/models/columns.h"
|
#include "blackgui/models/columns.h"
|
||||||
#include "blackgui/models/listmodelfilter.h"
|
#include "blackgui/models/modelfilter.h"
|
||||||
#include "blackmisc/worker.h"
|
#include "blackmisc/worker.h"
|
||||||
#include "blackmisc/propertyindex.h"
|
#include "blackmisc/propertyindex.h"
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
@@ -75,12 +75,27 @@ namespace BlackGui
|
|||||||
//! Get sort order
|
//! Get sort order
|
||||||
virtual Qt::SortOrder getSortOrder() const { return this->m_sortOrder; }
|
virtual Qt::SortOrder getSortOrder() const { return this->m_sortOrder; }
|
||||||
|
|
||||||
//! \copydoc QAbstractTableModel::flags
|
|
||||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
|
||||||
|
|
||||||
//! Translation context
|
//! Translation context
|
||||||
virtual const QString &getTranslationContext() const;
|
virtual const QString &getTranslationContext() const;
|
||||||
|
|
||||||
|
//! \copydoc QAbstractItemModel::flags
|
||||||
|
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||||
|
|
||||||
|
//! \copydoc QAbstractItemModel::supportedDragActions
|
||||||
|
virtual Qt::DropActions supportedDragActions() const override;
|
||||||
|
|
||||||
|
//! \copydoc QAbstractItemModel::supportedDropActions
|
||||||
|
virtual Qt::DropActions supportedDropActions() const override;
|
||||||
|
|
||||||
|
//! \copydoc QAbstractItemModel::supportedDropActions
|
||||||
|
virtual QStringList mimeTypes() const override;
|
||||||
|
|
||||||
|
//! Mark as about to be destroyed, normally marked from view
|
||||||
|
void markDestroyed();
|
||||||
|
|
||||||
|
//! Model about to be destroyed?
|
||||||
|
bool isModelDestroyed();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
//! Asynchronous update finished
|
//! Asynchronous update finished
|
||||||
void asyncUpdateFinished();
|
void asyncUpdateFinished();
|
||||||
@@ -101,19 +116,15 @@ namespace BlackGui
|
|||||||
//! Constructor
|
//! Constructor
|
||||||
//! \param translationContext I18N context
|
//! \param translationContext I18N context
|
||||||
//! \param parent
|
//! \param parent
|
||||||
CListModelBaseNonTemplate(const QString &translationContext, QObject *parent = nullptr)
|
CListModelBaseNonTemplate(const QString &translationContext, QObject *parent = nullptr);
|
||||||
: QAbstractItemModel(parent), m_columns(translationContext), m_sortedColumn(-1), m_sortOrder(Qt::AscendingOrder)
|
|
||||||
{
|
|
||||||
// non unique default name, set translation context as default
|
|
||||||
this->setObjectName(translationContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Helper method with template free signature
|
//! Helper method with template free signature
|
||||||
virtual int performUpdateContainer(const BlackMisc::CVariant &variant, bool sort) = 0;
|
virtual int performUpdateContainer(const BlackMisc::CVariant &variant, bool sort) = 0;
|
||||||
|
|
||||||
CColumns m_columns; //!< columns metadata
|
CColumns m_columns; //!< columns metadata
|
||||||
int m_sortedColumn; //!< current sort column
|
int m_sortedColumn; //!< current sort column
|
||||||
Qt::SortOrder m_sortOrder; //!< sort order (asc/desc)
|
Qt::SortOrder m_sortOrder; //!< sort order (asc/desc)
|
||||||
|
bool m_modelDestroyed = false; //!< model is about to be destroyed
|
||||||
};
|
};
|
||||||
|
|
||||||
//! List model
|
//! List model
|
||||||
@@ -201,6 +212,9 @@ namespace BlackGui
|
|||||||
//! Empty?
|
//! Empty?
|
||||||
virtual bool isEmpty() const;
|
virtual bool isEmpty() const;
|
||||||
|
|
||||||
|
//! \copydoc QAbstractItemModel::mimeData
|
||||||
|
virtual QMimeData *mimeData(const QModelIndexList &indexes) const override;
|
||||||
|
|
||||||
//! Filter available
|
//! Filter available
|
||||||
bool hasFilter() const;
|
bool hasFilter() const;
|
||||||
|
|
||||||
@@ -208,7 +222,7 @@ namespace BlackGui
|
|||||||
void removeFilter();
|
void removeFilter();
|
||||||
|
|
||||||
//! Set the filter
|
//! Set the filter
|
||||||
void setFilter(std::unique_ptr<IModelFilter<ContainerType> > &filter);
|
void takeFilterOwnership(std::unique_ptr<IModelFilter<ContainerType> > &filter);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::unique_ptr<IModelFilter<ContainerType> > m_filter; //!< Used filter
|
std::unique_ptr<IModelFilter<ContainerType> > m_filter; //!< Used filter
|
||||||
@@ -233,7 +247,6 @@ namespace BlackGui
|
|||||||
void emitRowCountChanged();
|
void emitRowCountChanged();
|
||||||
ContainerType m_container; //!< used container
|
ContainerType m_container; //!< used container
|
||||||
ContainerType m_containerFiltered; //!< cache for filtered container data
|
ContainerType m_containerFiltered; //!< cache for filtered container data
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
Reference in New Issue
Block a user