mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 14:55:36 +08:00
refs #641, support for IOrderable in specialized views/models
* menu to order objects per drag and drop * changed model/views to specialized model/views
This commit is contained in:
@@ -20,7 +20,7 @@ namespace BlackGui
|
||||
namespace Models
|
||||
{
|
||||
CAircraftModelListModel::CAircraftModelListModel(AircraftModelMode mode, QObject *parent) :
|
||||
CListModelDbObjects("CAircraftModelListModel", parent)
|
||||
COrderableListModelDbObjects("CAircraftModelListModel", parent)
|
||||
{
|
||||
this->setAircraftModelMode(mode);
|
||||
|
||||
@@ -60,16 +60,23 @@ namespace BlackGui
|
||||
this->m_sortOrder = Qt::AscendingOrder;
|
||||
break;
|
||||
|
||||
case OwnModelSet:
|
||||
// intentional fall thru
|
||||
this->m_columns.addColumn(CColumn::orderColumn());
|
||||
|
||||
case OwnSimulatorModelMapping:
|
||||
this->m_columns.addColumn(CColumn::standardString("model", CAircraftModel::IndexModelString));
|
||||
this->m_columns.addColumn(CColumn("DB", "DB metadata", CAircraftModel::IndexDatabaseIcon, new CPixmapFormatter()));
|
||||
this->m_columns.addColumn(CColumn("mode", "model mode(include, exclude)", CAircraftModel::IndexModelModeAsIcon, new CPixmapFormatter()));
|
||||
// this->m_columns.addColumn(CColumn::standardValueObject("call", "callsign", CAircraftModel::IndexCallsign));
|
||||
this->m_columns.addColumn(CColumn::standardString("dist.", "distributor", { CAircraftModel::IndexDistributor, CDistributor::IndexDbStringKey}));
|
||||
if (mode == OwnModelSet)
|
||||
{
|
||||
this->m_columns.addColumn(CColumn::standardString("d#", "distributor order", { CAircraftModel::IndexDistributor, CDistributor::IndexOrderString}));
|
||||
}
|
||||
this->m_columns.addColumn(CColumn::standardString("ac", "aircraft ICAO", { CAircraftModel::IndexAircraftIcaoCode, CAircraftIcaoCode::IndexAircraftDesignator}));
|
||||
this->m_columns.addColumn(CColumn::standardString("fam.", "aircraft family", { CAircraftModel::IndexAircraftIcaoCode, CAircraftIcaoCode::IndexFamily}));
|
||||
this->m_columns.addColumn(CColumn::standardString("al", "airline ICAO", { CAircraftModel::IndexLivery, CLivery::IndexAirlineIcaoCode, CAirlineIcaoCode::IndexAirlineDesignator}));
|
||||
// this->m_columns.addColumn(CColumn::standardString("ct", "combined type", { CAircraftModel::IndexIcao, CAircraftIcaoData::IndexCombinedAircraftType}));
|
||||
this->m_columns.addColumn(CColumn::standardString("description", CAircraftModel::IndexDescription));
|
||||
this->m_columns.addColumn(CColumn::standardString("filename", CAircraftModel::IndexFileName));
|
||||
this->m_columns.addColumn(CColumn::standardString("icon", CAircraftModel::IndexIconPath));
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace BlackGui
|
||||
{
|
||||
//! Aircraft model list model
|
||||
class BLACKGUI_EXPORT CAircraftModelListModel :
|
||||
public CListModelDbObjects<BlackMisc::Simulation::CAircraftModel, BlackMisc::Simulation::CAircraftModelList, int, true>
|
||||
public COrderableListModelDbObjects<BlackMisc::Simulation::CAircraftModel, BlackMisc::Simulation::CAircraftModelList, int, true>
|
||||
{
|
||||
public:
|
||||
//! How to display
|
||||
@@ -34,6 +34,7 @@ namespace BlackGui
|
||||
{
|
||||
NotSet,
|
||||
OwnSimulatorModel, //!< models existing for my simulator
|
||||
OwnModelSet, //!< own model set
|
||||
OwnSimulatorModelMapping, //!< models of my simulator, but in mapping mode
|
||||
Database, //!< Database entry
|
||||
VPilotRuleModel, //!< vPilot rule turned into model
|
||||
@@ -73,11 +74,14 @@ namespace BlackGui
|
||||
//! \copydoc QAbstractItemModel::data
|
||||
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
//! \copydoc BlackGui::Models::CListModelBaseNonTemplate::isOrderable
|
||||
virtual bool isOrderable() const override { return true; }
|
||||
|
||||
private:
|
||||
AircraftModelMode m_mode = NotSet; //!< current mode
|
||||
bool m_highlightModelStrings = false; //!< highlight in in model strings
|
||||
QStringList m_highlightStrings; //!< model strings to highlight
|
||||
QBrush m_highlightColor{Qt::yellow}; //!< how to highlight
|
||||
AircraftModelMode m_mode = NotSet; //!< current mode
|
||||
bool m_highlightModelStrings = false; //!< highlight in in model strings
|
||||
QStringList m_highlightStrings; //!< model strings to highlight
|
||||
QBrush m_highlightColor{Qt::yellow}; //!< how to highlight
|
||||
};
|
||||
} // ns
|
||||
} // ns
|
||||
|
||||
@@ -88,6 +88,11 @@ namespace BlackGui
|
||||
return CColumn(headerName, toolTip, propertyIndex, new CStringFormatter(alignment));
|
||||
}
|
||||
|
||||
CColumn CColumn::orderColumn(const CPropertyIndex &propertyIndex, int alignment)
|
||||
{
|
||||
return CColumn("#", "order", propertyIndex, new CStringFormatter(alignment));
|
||||
}
|
||||
|
||||
// --------------- columns ----------------------------------------------
|
||||
|
||||
CColumns::CColumns(const QString &translationContext, QObject *parent) :
|
||||
|
||||
@@ -100,6 +100,9 @@ namespace BlackGui
|
||||
//! Get a standard string object formatted column
|
||||
static CColumn standardString(const QString &headerName, const QString &toolTip, const BlackMisc::CPropertyIndex &propertyIndex, int alignment = CDefaultFormatter::alignDefault());
|
||||
|
||||
//! Get a standard string object formatted column
|
||||
static CColumn orderColumn(const BlackMisc::CPropertyIndex &propertyIndex = BlackMisc::CPropertyIndex::GlobalIndexIOrderable, int alignment = CDefaultFormatter::alignRightVCenter());
|
||||
|
||||
private:
|
||||
QString m_translationContext;
|
||||
QString m_columnName;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace BlackGui
|
||||
namespace Models
|
||||
{
|
||||
CDistributorListModel::CDistributorListModel(QObject *parent) :
|
||||
CListModelDbObjects("ModelDistributorList", parent)
|
||||
COrderableListModelDbObjects("ModelDistributorList", parent)
|
||||
{
|
||||
this->setDistributorMode(Normal);
|
||||
|
||||
@@ -36,6 +36,8 @@ namespace BlackGui
|
||||
this->m_columns.clear();
|
||||
switch (distributorMode)
|
||||
{
|
||||
case NormalWithOrder:
|
||||
this->m_columns.addColumn(CColumn::orderColumn());
|
||||
case NotSet:
|
||||
case Normal:
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace BlackGui
|
||||
{
|
||||
//! Distributor list model
|
||||
class BLACKGUI_EXPORT CDistributorListModel :
|
||||
public CListModelDbObjects<BlackMisc::Simulation::CDistributor, BlackMisc::Simulation::CDistributorList, QString, true>
|
||||
public COrderableListModelDbObjects<BlackMisc::Simulation::CDistributor, BlackMisc::Simulation::CDistributorList, QString, true>
|
||||
{
|
||||
public:
|
||||
//! What kind of stations
|
||||
@@ -31,6 +31,7 @@ namespace BlackGui
|
||||
{
|
||||
NotSet,
|
||||
Normal,
|
||||
NormalWithOrder,
|
||||
Minimal
|
||||
};
|
||||
|
||||
@@ -46,6 +47,9 @@ namespace BlackGui
|
||||
//! Mode
|
||||
DistributorMode getDistributorMode() const { return this->m_distributorMode; }
|
||||
|
||||
//! \copydoc BlackGui::Models::CListModelBaseNonTemplate::isOrderable
|
||||
virtual bool isOrderable() const override { return true; }
|
||||
|
||||
private:
|
||||
DistributorMode m_distributorMode = NotSet;
|
||||
};
|
||||
|
||||
@@ -96,6 +96,12 @@ namespace BlackGui
|
||||
this->m_sortedColumn = this->m_columns.propertyIndexToColumn(propertyIndex);
|
||||
}
|
||||
|
||||
void CListModelBaseNonTemplate::setSorting(const CPropertyIndex &propertyIndex, Qt::SortOrder order)
|
||||
{
|
||||
this->setSortColumnByPropertyIndex(propertyIndex);
|
||||
this->m_sortOrder = order;
|
||||
}
|
||||
|
||||
bool CListModelBaseNonTemplate::hasValidSortColumn() const
|
||||
{
|
||||
|
||||
@@ -107,7 +113,7 @@ namespace BlackGui
|
||||
{
|
||||
Qt::ItemFlags f = QStandardItemModel::flags(index);
|
||||
if (!index.isValid()) { return f; }
|
||||
bool editable = this->m_columns.isEditable(index);
|
||||
const bool editable = this->m_columns.isEditable(index);
|
||||
f = editable ? (f | Qt::ItemIsEditable) : (f & ~Qt::ItemIsEditable);
|
||||
|
||||
// flags from formatter
|
||||
@@ -127,12 +133,12 @@ namespace BlackGui
|
||||
|
||||
Qt::DropActions CListModelBaseNonTemplate::supportedDragActions() const
|
||||
{
|
||||
return Qt::CopyAction;
|
||||
return isOrderable() ? Qt::CopyAction | Qt::MoveAction : Qt::CopyAction;
|
||||
}
|
||||
|
||||
Qt::DropActions CListModelBaseNonTemplate::supportedDropActions() const
|
||||
{
|
||||
return QStandardItemModel::supportedDropActions();
|
||||
return this->m_dropActions;
|
||||
}
|
||||
|
||||
QStringList CListModelBaseNonTemplate::mimeTypes() const
|
||||
@@ -161,8 +167,8 @@ namespace BlackGui
|
||||
if (columns < 1) { return; }
|
||||
if (startRowIndex < 0) { startRowIndex = 0; }
|
||||
if (endRowIndex >= rows) { endRowIndex = rows - 1; }
|
||||
QModelIndex topLeft(createIndex(startRowIndex, 0));
|
||||
QModelIndex bottomRight(createIndex(endRowIndex, columns - 1));
|
||||
const QModelIndex topLeft(createIndex(startRowIndex, 0));
|
||||
const QModelIndex bottomRight(createIndex(endRowIndex, columns - 1));
|
||||
emit dataChanged(topLeft, bottomRight);
|
||||
}
|
||||
|
||||
@@ -190,6 +196,38 @@ namespace BlackGui
|
||||
return this->containerOrFilteredContainer().size();
|
||||
}
|
||||
|
||||
template <typename ObjectType, typename ContainerType, bool UseCompare>
|
||||
bool CListModelBase<ObjectType, ContainerType, UseCompare>::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(action);
|
||||
Q_UNUSED(row);
|
||||
Q_UNUSED(column);
|
||||
Q_UNUSED(parent);
|
||||
if (!this->isDropAllowed()) { return false; }
|
||||
if (!this->acceptDrop(data)) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ObjectType, typename ContainerType, bool UseCompare>
|
||||
bool CListModelBase<ObjectType, ContainerType, UseCompare>::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
|
||||
{
|
||||
Q_UNUSED(row);
|
||||
Q_UNUSED(column);
|
||||
if (!this->isOrderable() || !this->acceptDrop(data)) { return false; }
|
||||
const CVariant valueVariant(this->toCVariant(data));
|
||||
if (valueVariant.isValid())
|
||||
{
|
||||
if (action == Qt::MoveAction)
|
||||
{
|
||||
const ContainerType container(valueVariant.value<ContainerType>());
|
||||
if (container.isEmpty()) { return false; }
|
||||
const int position = parent.row();
|
||||
this->moveItems(container, position);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ObjectType, typename ContainerType, bool UseCompare>
|
||||
bool CListModelBase<ObjectType, ContainerType, UseCompare>::isValidIndex(const QModelIndex &index) const
|
||||
{
|
||||
@@ -370,7 +408,7 @@ namespace BlackGui
|
||||
{
|
||||
if (!filter)
|
||||
{
|
||||
this->removeFilter(); // clear filter
|
||||
this->removeFilter(); // clear filter
|
||||
return;
|
||||
}
|
||||
if (filter->isValid())
|
||||
@@ -528,6 +566,14 @@ namespace BlackGui
|
||||
emit this->changed();
|
||||
}
|
||||
|
||||
template <typename ObjectType, typename ContainerType, bool UseCompare>
|
||||
void CListModelBase<ObjectType, ContainerType, UseCompare>::moveItems(const ContainerType &items, int position)
|
||||
{
|
||||
// overridden in specialized class
|
||||
Q_UNUSED(items);
|
||||
Q_UNUSED(position);
|
||||
}
|
||||
|
||||
template <typename ObjectType, typename ContainerType, bool UseCompare>
|
||||
void CListModelBase<ObjectType, ContainerType, UseCompare>::sort()
|
||||
{
|
||||
@@ -630,6 +676,12 @@ namespace BlackGui
|
||||
return container().toJsonString(format);
|
||||
}
|
||||
|
||||
template <typename ObjectType, typename ContainerType, bool UseCompare>
|
||||
bool CListModelBase<ObjectType, ContainerType, UseCompare>::isOrderable() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// see here for the reason of thess forward instantiations
|
||||
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
|
||||
template class CListModelBase<BlackMisc::Aviation::CLivery, BlackMisc::Aviation::CLiveryList, true>;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "blackgui/blackguiexport.h"
|
||||
#include "blackgui/models/columns.h"
|
||||
#include "blackgui/models/modelfilter.h"
|
||||
#include "blackgui/dropbase.h"
|
||||
#include "blackmisc/worker.h"
|
||||
#include <QStandardItemModel>
|
||||
#include <QThread>
|
||||
@@ -27,7 +28,9 @@ namespace BlackGui
|
||||
namespace Models
|
||||
{
|
||||
//! Non templated base class, allows Q_OBJECT and signals to be used
|
||||
class BLACKGUI_EXPORT CListModelBaseNonTemplate : public QStandardItemModel
|
||||
class BLACKGUI_EXPORT CListModelBaseNonTemplate :
|
||||
public QStandardItemModel,
|
||||
public BlackGui::CDropBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -38,17 +41,17 @@ namespace BlackGui
|
||||
//! Destructor
|
||||
virtual ~CListModelBaseNonTemplate() {}
|
||||
|
||||
//! \copydoc QStandardItemModel::columnCount()
|
||||
//! \name Functions from QStandardItemModel
|
||||
//! @{
|
||||
virtual int columnCount(const QModelIndex &modelIndex = QModelIndex()) const override;
|
||||
|
||||
//! \copydoc QStandardItemModel::headerData()
|
||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
|
||||
//! \copydoc QStandardItemModel::headerData()
|
||||
virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
//! \copydoc QStandardItemModel::parent()
|
||||
virtual QModelIndex parent(const QModelIndex &child) const override;
|
||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
virtual Qt::DropActions supportedDragActions() const override;
|
||||
virtual Qt::DropActions supportedDropActions() const override;
|
||||
virtual QStringList mimeTypes() const override;
|
||||
//! @}
|
||||
|
||||
//! Column to property index
|
||||
virtual BlackMisc::CPropertyIndex columnToPropertyIndex(int column) const;
|
||||
@@ -66,6 +69,9 @@ namespace BlackGui
|
||||
//! \param propertyIndex index of column to be sorted
|
||||
virtual void setSortColumnByPropertyIndex(const BlackMisc::CPropertyIndex &propertyIndex);
|
||||
|
||||
//! Sorting
|
||||
virtual void setSorting(const BlackMisc::CPropertyIndex &propertyIndex, Qt::SortOrder order = Qt::AscendingOrder);
|
||||
|
||||
//! Get sort column property index
|
||||
virtual int getSortColumn() const { return this->m_sortedColumn; }
|
||||
|
||||
@@ -78,17 +84,8 @@ namespace BlackGui
|
||||
//! Translation context
|
||||
virtual const QString &getTranslationContext() const;
|
||||
|
||||
//! \copydoc QStandardItemModel::flags
|
||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
|
||||
//! \copydoc QStandardItemModel::supportedDragActions
|
||||
virtual Qt::DropActions supportedDragActions() const override;
|
||||
|
||||
//! \copydoc QStandardItemModel::supportedDropActions
|
||||
virtual Qt::DropActions supportedDropActions() const override;
|
||||
|
||||
//! \copydoc QStandardItemModel::mimeTypes
|
||||
virtual QStringList mimeTypes() const override;
|
||||
//! Orderable, normally use a container BlackMisc::IOrderableList
|
||||
virtual bool isOrderable() const = 0;
|
||||
|
||||
//! Mark as about to be destroyed, normally marked from view
|
||||
void markDestroyed();
|
||||
@@ -96,6 +93,9 @@ namespace BlackGui
|
||||
//! Model about to be destroyed?
|
||||
bool isModelDestroyed();
|
||||
|
||||
//! Drop actions
|
||||
void setDropActions(Qt::DropActions dropActions) { this->m_dropActions = dropActions; }
|
||||
|
||||
//! Send signal that data have been changed.
|
||||
//! \note Meant for scenarios where the container is directly updated and a subsequent signal is required
|
||||
void sendDataChanged(int startRowIndex, int endRowIndex);
|
||||
@@ -127,17 +127,18 @@ namespace BlackGui
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
//! \param translationContext I18N context
|
||||
//! \param translationContext I18N context
|
||||
//! \param parent
|
||||
CListModelBaseNonTemplate(const QString &translationContext, QObject *parent = nullptr);
|
||||
|
||||
//! Helper method with template free signature
|
||||
virtual int performUpdateContainer(const BlackMisc::CVariant &variant, bool sort) = 0;
|
||||
|
||||
CColumns m_columns; //!< columns metadata
|
||||
int m_sortedColumn; //!< current sort column
|
||||
Qt::SortOrder m_sortOrder; //!< sort order (asc/desc)
|
||||
bool m_modelDestroyed = false; //!< model is about to be destroyed
|
||||
CColumns m_columns; //!< columns metadata
|
||||
int m_sortedColumn; //!< current sort column
|
||||
Qt::SortOrder m_sortOrder; //!< sort order (asc/desc)
|
||||
bool m_modelDestroyed = false; //!< model is about to be destroyed
|
||||
Qt::DropActions m_dropActions = Qt::IgnoreAction; //!< drop actions
|
||||
};
|
||||
|
||||
//! List model
|
||||
@@ -147,6 +148,24 @@ namespace BlackGui
|
||||
//! Destructor
|
||||
virtual ~CListModelBase() {}
|
||||
|
||||
//! \name Functions from QStandardItemModel
|
||||
//! @{
|
||||
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||
virtual QMimeData *mimeData(const QModelIndexList &indexes) const override;
|
||||
virtual void sort(int column, Qt::SortOrder order) override;
|
||||
virtual int rowCount(const QModelIndex &parentIndex = QModelIndex()) const override;
|
||||
virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override;
|
||||
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
|
||||
//! @}
|
||||
|
||||
//! \name Functions from CListModelBaseNonTemplate
|
||||
//! @{
|
||||
virtual QJsonObject toJson() const override;
|
||||
virtual QString toJsonString(QJsonDocument::JsonFormat format = QJsonDocument::Indented) const override;
|
||||
virtual bool isOrderable() const override;
|
||||
//! @}
|
||||
|
||||
//! Valid index (in range)
|
||||
virtual bool isValidIndex(const QModelIndex &index) const;
|
||||
|
||||
@@ -156,20 +175,10 @@ namespace BlackGui
|
||||
//! Full container or cached filtered container as approproiate
|
||||
const ContainerType &containerOrFilteredContainer() const;
|
||||
|
||||
//! \copydoc QStandardItemModel::data()
|
||||
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
//! \copydoc QStandardItemModel::setData()
|
||||
//! \sa CListModelBaseNonTemplate::flags
|
||||
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
//! Simple set of data in container, using class is responsible for firing signals etc.
|
||||
//! \sa sendDataChanged
|
||||
bool setInContainer(const QModelIndex &index, const ObjectType &obj);
|
||||
|
||||
//! \copydoc QStandardItemModel::rowCount()
|
||||
virtual int rowCount(const QModelIndex &parentIndex = QModelIndex()) const override;
|
||||
|
||||
//! Update by new container
|
||||
//! \return int size after update
|
||||
//! \remarks a sorting is performed only if a valid sort column is set
|
||||
@@ -187,15 +196,15 @@ namespace BlackGui
|
||||
//! Update single element
|
||||
virtual void update(int rowIndex, const ObjectType &object);
|
||||
|
||||
//! Move items to position
|
||||
virtual void moveItems(const ContainerType &items, int position);
|
||||
|
||||
//! Object at row position
|
||||
virtual const ObjectType &at(const QModelIndex &index) const;
|
||||
|
||||
//! Sort by given sort order \sa getSortColumn() \sa getSortOrder()
|
||||
void sort();
|
||||
|
||||
//! \copydoc QStandardItemModel::sort()
|
||||
virtual void sort(int column, Qt::SortOrder order) override;
|
||||
|
||||
//! Truncate to given number
|
||||
void truncate(int maxNumber, bool forceSort = false);
|
||||
|
||||
@@ -235,15 +244,6 @@ namespace BlackGui
|
||||
//! Empty?
|
||||
virtual bool isEmpty() const;
|
||||
|
||||
//! \copydoc QStandardItemModel::mimeData
|
||||
virtual QMimeData *mimeData(const QModelIndexList &indexes) const override;
|
||||
|
||||
//! \copydoc BlackGui::Models::CListModelBaseNonTemplate::toJson
|
||||
virtual QJsonObject toJson() const override;
|
||||
|
||||
//! \copydoc BlackGui::Models::CListModelBaseNonTemplate::toJsonString
|
||||
virtual QString toJsonString(QJsonDocument::JsonFormat format = QJsonDocument::Indented) const override;
|
||||
|
||||
//! Filter available
|
||||
bool hasFilter() const;
|
||||
|
||||
@@ -286,9 +286,8 @@ namespace BlackGui
|
||||
template <typename ObjectType>
|
||||
bool compareForModelSort(const ObjectType &a, const ObjectType &b, Qt::SortOrder order, const BlackMisc::CPropertyIndex &index, std::false_type)
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
BlackMisc::CVariant aQv = a.propertyByIndex(index);
|
||||
BlackMisc::CVariant bQv = b.propertyByIndex(index);
|
||||
const BlackMisc::CVariant aQv = a.propertyByIndex(index);
|
||||
const BlackMisc::CVariant bQv = b.propertyByIndex(index);
|
||||
return (order == Qt::AscendingOrder) ? (aQv < bQv) : (bQv < aQv);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -57,6 +57,37 @@ namespace BlackGui
|
||||
return m_highlightKeys.contains(dbKeyForIndex(index));
|
||||
}
|
||||
|
||||
template <typename ObjectType, typename ContainerType, typename KeyType, bool UseCompare>
|
||||
COrderableListModelDbObjects<ObjectType, ContainerType, KeyType, UseCompare>::COrderableListModelDbObjects(const QString &translationContext, QObject *parent)
|
||||
: CListModelDbObjects<ObjectType, ContainerType, KeyType, UseCompare>(translationContext, parent)
|
||||
{ }
|
||||
|
||||
template <typename ObjectType, typename ContainerType, typename KeyType, bool UseCompare>
|
||||
void COrderableListModelDbObjects<ObjectType, ContainerType, KeyType, UseCompare>::moveItems(const ContainerType &items, int position)
|
||||
{
|
||||
if (items.isEmpty()) { return; }
|
||||
ContainerType container(this->container());
|
||||
int order = 0;
|
||||
if (position >= 0 && position < container.size())
|
||||
{
|
||||
order = container[position].getOrder();
|
||||
}
|
||||
container.moveTo(items, order);
|
||||
this->updateContainerMaybeAsync(container);
|
||||
}
|
||||
|
||||
template <typename ObjectType, typename ContainerType, typename KeyType, bool UseCompare>
|
||||
int COrderableListModelDbObjects<ObjectType, ContainerType, KeyType, UseCompare>::update(const ContainerType &container, bool sort)
|
||||
{
|
||||
if (container.needsOrder())
|
||||
{
|
||||
ContainerType orderable(container);
|
||||
orderable.resetOrder();
|
||||
return CListModelDbObjects<ObjectType, ContainerType, KeyType, UseCompare>::update(orderable, sort);
|
||||
}
|
||||
return CListModelDbObjects<ObjectType, ContainerType, KeyType, UseCompare>::update(container, sort);
|
||||
}
|
||||
|
||||
// see here for the reason of thess forward instantiations
|
||||
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
|
||||
template class CListModelDbObjects<BlackMisc::Aviation::CLivery, BlackMisc::Aviation::CLiveryList, int, true>;
|
||||
@@ -65,6 +96,8 @@ namespace BlackGui
|
||||
template class CListModelDbObjects<BlackMisc::Aviation::CAirlineIcaoCode, BlackMisc::Aviation::CAirlineIcaoCodeList, int, true>;
|
||||
template class CListModelDbObjects<BlackMisc::Simulation::CAircraftModel, BlackMisc::Simulation::CAircraftModelList, int, true>;
|
||||
template class CListModelDbObjects<BlackMisc::Simulation::CDistributor, BlackMisc::Simulation::CDistributorList, QString, true>;
|
||||
template class COrderableListModelDbObjects<BlackMisc::Simulation::CAircraftModel, BlackMisc::Simulation::CAircraftModelList, int, true>;
|
||||
template class COrderableListModelDbObjects<BlackMisc::Simulation::CDistributor, BlackMisc::Simulation::CDistributorList, QString, true>;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -58,6 +58,25 @@ namespace BlackGui
|
||||
QColor m_highlightColor = Qt::green;
|
||||
};
|
||||
|
||||
|
||||
//! List model for DB objects
|
||||
template <typename ObjectType, typename ContainerType, typename KeyType, bool UseCompare = false> class COrderableListModelDbObjects :
|
||||
public CListModelDbObjects<ObjectType, ContainerType, KeyType, UseCompare>
|
||||
{
|
||||
public:
|
||||
//! Destructor
|
||||
virtual ~COrderableListModelDbObjects() {}
|
||||
|
||||
//! \name specialized BlackGui::Models::CListModelDbObjects functions for ordering
|
||||
//! @{
|
||||
virtual int update(const ContainerType &container, bool sort) override;
|
||||
virtual void moveItems(const ContainerType &items, int position) override;
|
||||
//! @}
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
COrderableListModelDbObjects(const QString &translationContext, QObject *parent = nullptr);
|
||||
};
|
||||
} // namespace
|
||||
} // namespace
|
||||
#endif // guard
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace BlackGui
|
||||
{
|
||||
namespace Views
|
||||
{
|
||||
CAircraftModelView::CAircraftModelView(QWidget *parent) : CViewWithDbObjects(parent)
|
||||
CAircraftModelView::CAircraftModelView(QWidget *parent) : COrderableViewWithDbObjects(parent)
|
||||
{
|
||||
// default
|
||||
this->standardInit(new CAircraftModelListModel(CAircraftModelListModel::OwnSimulatorModel, this));
|
||||
@@ -105,9 +105,10 @@ namespace BlackGui
|
||||
return m_menus.testFlag(MenuCanStashModels) && hasSelection();
|
||||
}
|
||||
|
||||
void CAircraftModelView::setImplementedMetaTypeIds()
|
||||
void CAircraftModelView::setAcceptedMetaTypeIds()
|
||||
{
|
||||
this->setAcceptedMetaTypeIds(
|
||||
Q_ASSERT(this->m_model);
|
||||
this->m_model->setAcceptedMetaTypeIds(
|
||||
{
|
||||
qMetaTypeId<CAirlineIcaoCode>(), qMetaTypeId<CAirlineIcaoCodeList>(),
|
||||
qMetaTypeId<CAircraftIcaoCode>(), qMetaTypeId<CAircraftIcaoCodeList>(),
|
||||
@@ -176,7 +177,8 @@ namespace BlackGui
|
||||
|
||||
void CAircraftModelView::dropEvent(QDropEvent *event)
|
||||
{
|
||||
if (!isDropAllowed()) { return; }
|
||||
|
||||
if (!this->isDropAllowed()) { return; }
|
||||
if (!event) { return; }
|
||||
const QMimeData *mime = event->mimeData();
|
||||
if (!mime) { return; }
|
||||
@@ -290,7 +292,7 @@ namespace BlackGui
|
||||
menu.addMenu(stashMenu);
|
||||
stashMenu->setIcon(CIcons::appDbStash16());
|
||||
}
|
||||
CViewWithDbObjects::customMenu(menu);
|
||||
COrderableViewWithDbObjects::customMenu(menu);
|
||||
}
|
||||
|
||||
CStatusMessage CAircraftModelView::modifyLoadedJsonData(CAircraftModelList &models) const
|
||||
@@ -338,7 +340,7 @@ namespace BlackGui
|
||||
if (sim.isSingleSimulator()) { return ok; }
|
||||
return CStatusMessage(this, CStatusMessage::SeverityError, "data need to be from one simulator");
|
||||
}
|
||||
return CViewWithDbObjects::validateLoadedJsonData(models);
|
||||
return COrderableViewWithDbObjects::validateLoadedJsonData(models);
|
||||
}
|
||||
|
||||
void CAircraftModelView::jsonLoadedAndModelUpdated(const CAircraftModelList &models)
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace BlackGui
|
||||
{
|
||||
//! Aircraft view
|
||||
class BLACKGUI_EXPORT CAircraftModelView :
|
||||
public CViewWithDbObjects<Models::CAircraftModelListModel, BlackMisc::Simulation::CAircraftModelList, BlackMisc::Simulation::CAircraftModel, int>
|
||||
public COrderableViewWithDbObjects<Models::CAircraftModelListModel, BlackMisc::Simulation::CAircraftModelList, BlackMisc::Simulation::CAircraftModel, int>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace BlackGui
|
||||
bool hasSelectedModelsToStash() const;
|
||||
|
||||
//! Add the technically supported metatypes allowed for drag and drop
|
||||
void setImplementedMetaTypeIds();
|
||||
void setAcceptedMetaTypeIds();
|
||||
|
||||
//! Add my own filter dialog
|
||||
void addFilterDialog();
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace BlackGui
|
||||
namespace Views
|
||||
{
|
||||
CDistributorView::CDistributorView(QWidget *parent) :
|
||||
CViewWithDbObjects(parent)
|
||||
COrderableViewWithDbObjects(parent)
|
||||
{
|
||||
this->standardInit(new CDistributorListModel(this));
|
||||
this->setMenu(MenuDefaultDbViews);
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace BlackGui
|
||||
{
|
||||
//! Distributors
|
||||
class BLACKGUI_EXPORT CDistributorView :
|
||||
public CViewWithDbObjects<BlackGui::Models::CDistributorListModel, BlackMisc::Simulation::CDistributorList, BlackMisc::Simulation::CDistributor, QString>
|
||||
public COrderableViewWithDbObjects<BlackGui::Models::CDistributorListModel, BlackMisc::Simulation::CDistributorList, BlackMisc::Simulation::CDistributor, QString>
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
|
||||
@@ -94,7 +94,6 @@ namespace BlackGui
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CViewBaseNonTemplate::setFilterDialog(CFilterDialog *filterDialog)
|
||||
{
|
||||
this->setFilterWidgetImpl(filterDialog);
|
||||
@@ -303,25 +302,6 @@ namespace BlackGui
|
||||
QTableView::showEvent(event);
|
||||
}
|
||||
|
||||
void CViewBaseNonTemplate::allowDragDropValueObjects(bool allowDrag, bool allowDrop)
|
||||
{
|
||||
// see model for implementing logic of drag
|
||||
this->setAcceptDrops(allowDrop);
|
||||
this->setDragEnabled(allowDrag);
|
||||
this->setDropIndicatorShown(allowDrop);
|
||||
CDropBase::allowDrop(allowDrop);
|
||||
}
|
||||
|
||||
void CViewBaseNonTemplate::allowDrop(bool allow)
|
||||
{
|
||||
this->allowDragDropValueObjects(this->dragEnabled(), allow);
|
||||
}
|
||||
|
||||
bool CViewBaseNonTemplate::isDropAllowed() const
|
||||
{
|
||||
return this->acceptDrops();
|
||||
}
|
||||
|
||||
int CViewBaseNonTemplate::getHorizontalHeaderFontHeight() const
|
||||
{
|
||||
QFontMetrics m(this->getHorizontalHeaderFont());
|
||||
@@ -518,10 +498,10 @@ namespace BlackGui
|
||||
this->setVisible(false);
|
||||
// magic trick from:
|
||||
// http://stackoverflow.com/q/3433664/356726
|
||||
const QRect vporig = this->viewport()->geometry();
|
||||
QRect vpnew = vporig;
|
||||
vpnew.setWidth(std::numeric_limits<int>::max());
|
||||
this->viewport()->setGeometry(vpnew);
|
||||
const QRect vpOriginal = this->viewport()->geometry();
|
||||
QRect vpNew = vpOriginal;
|
||||
vpNew.setWidth(std::numeric_limits<int>::max());
|
||||
this->viewport()->setGeometry(vpNew);
|
||||
|
||||
this->m_resizeCount++;
|
||||
this->resizeColumnsToContents(); // columns
|
||||
@@ -531,16 +511,10 @@ namespace BlackGui
|
||||
// re-stretch
|
||||
this->horizontalHeader()->setStretchLastSection(true);
|
||||
}
|
||||
|
||||
this->viewport()->setGeometry(vporig);
|
||||
this->viewport()->setGeometry(vpOriginal);
|
||||
this->setVisible(true);
|
||||
}
|
||||
|
||||
void CViewBaseNonTemplate::presizeOrFullResizeToContents()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CViewBaseNonTemplate::ps_customMenuRequested(QPoint pos)
|
||||
{
|
||||
QMenu menu;
|
||||
@@ -601,14 +575,14 @@ namespace BlackGui
|
||||
|
||||
void CViewBaseNonTemplate::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
if (!event || !acceptDrop(event->mimeData())) { return; }
|
||||
if (!event || !this->acceptDrop(event->mimeData())) { return; }
|
||||
setBackgroundRole(QPalette::Highlight);
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void CViewBaseNonTemplate::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
if (!event || !acceptDrop(event->mimeData())) { return; }
|
||||
if (!event || !this->acceptDrop(event->mimeData())) { return; }
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
@@ -618,11 +592,6 @@ namespace BlackGui
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void CViewBaseNonTemplate::dropEvent(QDropEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
CViewBase<ModelClass, ContainerType, ObjectType>::CViewBase(QWidget *parent, ModelClass *model) : CViewBaseNonTemplate(parent), m_model(model)
|
||||
{
|
||||
@@ -646,7 +615,7 @@ namespace BlackGui
|
||||
|
||||
// we have data
|
||||
this->showLoadIndicator(container.size());
|
||||
bool reallyResize = resize && isResizeConditionMet(container.size()); // do we really perform resizing
|
||||
const bool reallyResize = resize && isResizeConditionMet(container.size()); // do we really perform resizing
|
||||
bool presize = (m_resizeMode == PresizeSubset) &&
|
||||
this->isEmpty() && // only when no data yet
|
||||
!reallyResize; // not when we resize later
|
||||
@@ -894,6 +863,47 @@ namespace BlackGui
|
||||
return this->m_model->rowCount() < 1;
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
bool CViewBase<ModelClass, ContainerType, ObjectType>::isOrderable() const
|
||||
{
|
||||
Q_ASSERT(this->m_model);
|
||||
return this->m_model->isOrderable();
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
void CViewBase<ModelClass, ContainerType, ObjectType>::allowDragDrop(bool allowDrag, bool allowDrop)
|
||||
{
|
||||
Q_ASSERT(this->m_model);
|
||||
|
||||
// see model for implementing logic of drag
|
||||
this->viewport()->setAcceptDrops(allowDrop);
|
||||
this->setDragEnabled(allowDrag);
|
||||
this->setDropIndicatorShown(allowDrop);
|
||||
this->m_model->allowDrop(allowDrop);
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
bool CViewBase<ModelClass, ContainerType, ObjectType>::isDropAllowed() const
|
||||
{
|
||||
Q_ASSERT(this->m_model);
|
||||
return this->m_model->isDropAllowed();
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
bool CViewBase<ModelClass, ContainerType, ObjectType>::acceptDrop(const QMimeData *mimeData) const
|
||||
{
|
||||
Q_ASSERT(this->m_model);
|
||||
const bool a = this->m_model->acceptDrop(mimeData);
|
||||
return a;
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
void CViewBase<ModelClass, ContainerType, ObjectType>::setSorting(const CPropertyIndex &propertyIndex, Qt::SortOrder order)
|
||||
{
|
||||
Q_ASSERT(this->m_model);
|
||||
this->m_model->setSorting(propertyIndex, order);
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
QJsonObject CViewBase<ModelClass, ContainerType, ObjectType>::toJson() const
|
||||
{
|
||||
@@ -936,6 +946,23 @@ namespace BlackGui
|
||||
return derivedModel()->hasFilter();
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
void CViewBase<ModelClass, ContainerType, ObjectType>::addContainerTypesAsDropTypes(bool objectType, bool containerType)
|
||||
{
|
||||
if (objectType) { this->m_model->addAcceptedMetaTypeId(qMetaTypeId<ObjectType>()); }
|
||||
if (containerType) { this->m_model->addAcceptedMetaTypeId(qMetaTypeId<ContainerType>()); }
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
void CViewBase<ModelClass, ContainerType, ObjectType>::initAsOrderable()
|
||||
{
|
||||
Q_ASSERT_X(isOrderable(), Q_FUNC_INFO, "Model not orderable");
|
||||
this->allowDragDrop(true, true);
|
||||
this->setDragDropMode(InternalMove);
|
||||
this->setDropActions(Qt::MoveAction);
|
||||
this->addContainerTypesAsDropTypes(true, true);
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
void CViewBase<ModelClass, ContainerType, ObjectType>::setSortIndicator()
|
||||
{
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "blackgui/models/modelfilter.h"
|
||||
#include "blackgui/menus/menudelegate.h"
|
||||
#include "blackgui/loadindicator.h"
|
||||
#include "blackgui/dropbase.h"
|
||||
#include "blackgui/blackguiexport.h"
|
||||
#include "blackmisc/icons.h"
|
||||
#include "blackmisc/worker.h"
|
||||
@@ -39,8 +38,7 @@ namespace BlackGui
|
||||
//! Non templated base class, allows Q_OBJECT and signals / slots to be used
|
||||
class BLACKGUI_EXPORT CViewBaseNonTemplate :
|
||||
public QTableView,
|
||||
public BlackGui::Components::CEnableForDockWidgetInfoArea,
|
||||
public BlackGui::CDropBase
|
||||
public BlackGui::Components::CEnableForDockWidgetInfoArea
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -79,6 +77,7 @@ namespace BlackGui
|
||||
MenuSave = 1 << 6, //!< save as JSON
|
||||
MenuLoad = 1 << 7, //!< load from JSON
|
||||
MenuToggleSelectionMode = 1 << 8, //!< allow to toggle selection mode
|
||||
MenuOrderable = 1 << 9, //!< items can be ordered (if container is BlackMisc::IOrderableList
|
||||
MenuStandard = MenuClear | MenuRemoveSelectedRows | MenuRefresh | MenuBackend |
|
||||
MenuDisplayAutomatically | MenuFilter | MenuSave | MenuLoad | MenuToggleSelectionMode,
|
||||
MenuLoadAndSave = MenuLoad | MenuSave,
|
||||
@@ -87,9 +86,9 @@ namespace BlackGui
|
||||
MenuDefaultDbViews = MenuToggleSelectionMode | MenuBackend,
|
||||
// special menus, should be in derived classes, but enums cannot be inherited
|
||||
// maybe shifted in the future to elsewhere
|
||||
MenuHighlightDbData = 1 << 9, //!< highlight DB data
|
||||
MenuHighlightStashed = 1 << 10, //!< highlight stashed models
|
||||
MenuCanStashModels = 1 << 11, //!< stash models
|
||||
MenuHighlightDbData = 1 << 10, //!< highlight DB data
|
||||
MenuHighlightStashed = 1 << 11, //!< highlight stashed models
|
||||
MenuCanStashModels = 1 << 12, //!< stash models
|
||||
MenuStashing = MenuHighlightStashed | MenuCanStashModels,
|
||||
};
|
||||
Q_DECLARE_FLAGS(Menu, MenuFlag)
|
||||
@@ -106,21 +105,27 @@ namespace BlackGui
|
||||
//! Empty?
|
||||
virtual bool isEmpty() const = 0 ;
|
||||
|
||||
//! Elements in container
|
||||
virtual int rowCount() const = 0;
|
||||
|
||||
//! Is the corresponding model orderable, BlackMisc::Models::CListModelBaseNonTemplate::isOrderable
|
||||
virtual bool isOrderable() const = 0;
|
||||
|
||||
//! \copydoc BlackGui::Models::CListModelBaseNonTemplate::setSorting
|
||||
virtual void setSorting(const BlackMisc::CPropertyIndex &propertyIndex, Qt::SortOrder order = Qt::AscendingOrder) = 0;
|
||||
|
||||
//! Allow to drag and/or drop value objects
|
||||
virtual void allowDragDropValueObjects(bool allowDrag, bool allowDrop);
|
||||
virtual void allowDragDrop(bool allowDrag, bool allowDrop) = 0;
|
||||
|
||||
//! \copydoc CDropBase::allowDrop
|
||||
virtual void allowDrop(bool allow) override;
|
||||
//! Drop allowed?
|
||||
virtual bool isDropAllowed() const = 0;
|
||||
|
||||
//! \copydoc CDropBase::isDropAllowed
|
||||
virtual bool isDropAllowed() const override;
|
||||
//! Accept drop data?
|
||||
virtual bool acceptDrop(const QMimeData *mimeData) const = 0;
|
||||
|
||||
//! \copydoc Components::CEnableForDockWidgetInfoArea::setParentDockWidgetInfoArea
|
||||
virtual bool setParentDockWidgetInfoArea(BlackGui::CDockWidgetInfoArea *parentDockableWidget) override;
|
||||
|
||||
//! Elements in container
|
||||
virtual int rowCount() const = 0;
|
||||
|
||||
//! Resize mode
|
||||
ResizeMode getResizeMode() const { return m_resizeMode; }
|
||||
|
||||
@@ -278,23 +283,14 @@ namespace BlackGui
|
||||
//! \sa BlackGui::Views::CViewBaseNonTemplate::ps_customMenuRequested
|
||||
virtual void customMenu(QMenu &menu) const;
|
||||
|
||||
//! \copydoc QTableView::paintEvent
|
||||
//! \name Functions from QTableView
|
||||
//! @{
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
//! \copydoc QTableView::showEvent
|
||||
virtual void showEvent(QShowEvent *event) override;
|
||||
|
||||
//! \copydoc QTableView::dragEnterEvent
|
||||
virtual void dragEnterEvent(QDragEnterEvent *event) override;
|
||||
|
||||
//! \copydoc QTableView::dragMoveEvent
|
||||
virtual void dragMoveEvent(QDragMoveEvent *event) override;
|
||||
|
||||
//! \copydoc QTableView::dragLeaveEvent
|
||||
virtual void dragLeaveEvent(QDragLeaveEvent *event) override;
|
||||
|
||||
//! \copydoc QTableView::dropEvent
|
||||
virtual void dropEvent(QDropEvent *event) override;
|
||||
//! @}
|
||||
|
||||
//! Perform resizing / non slot method for template
|
||||
virtual void performModeBasedResizeToContent() = 0;
|
||||
@@ -341,7 +337,7 @@ namespace BlackGui
|
||||
QWidget *m_filterWidget = nullptr; //!< filter widget or dialog
|
||||
Menu m_menus = MenuDefault; //!< Default menu settings
|
||||
BlackGui::Menus::IMenuDelegate *m_menu = nullptr; //!< custom menu if any
|
||||
BlackGui::CLoadIndicator *m_loadIndicator = nullptr; //!< load indicator if neeeded
|
||||
BlackGui::CLoadIndicator *m_loadIndicator = nullptr; //!< load indicator if needed
|
||||
|
||||
protected slots:
|
||||
//! Helper method with template free signature serving as callback from threaded worker
|
||||
@@ -428,9 +424,6 @@ namespace BlackGui
|
||||
//! Model
|
||||
const ModelClass *derivedModel() const { return this->m_model; }
|
||||
|
||||
//! \copydoc BlackGui::Views::CViewBaseNonTemplate::clear
|
||||
virtual void clear() override { Q_ASSERT(this->m_model); this->m_model->clear(); }
|
||||
|
||||
//! Update whole container
|
||||
//! \return int size after update
|
||||
int updateContainer(const ContainerType &container, bool sort = true, bool resize = true);
|
||||
@@ -459,12 +452,6 @@ namespace BlackGui
|
||||
//! Selected objects
|
||||
ContainerType selectedObjects() const;
|
||||
|
||||
//! \name Slot overrides from base class
|
||||
//! @{
|
||||
virtual int removeSelectedRows() override;
|
||||
virtual void presizeOrFullResizeToContents() override;
|
||||
//! @}
|
||||
|
||||
//! Update selected objects
|
||||
int updateSelected(const BlackMisc::CVariant &variant, const BlackMisc::CPropertyIndex &index);
|
||||
|
||||
@@ -495,15 +482,27 @@ namespace BlackGui
|
||||
this->updateContainerMaybeAsync(copy);
|
||||
}
|
||||
|
||||
//! \copydoc BlackGui::Views::CViewBaseNonTemplate::rowCount
|
||||
//! \name Slot overrides from base class
|
||||
//! @{
|
||||
virtual int removeSelectedRows() override;
|
||||
virtual void presizeOrFullResizeToContents() override;
|
||||
//! @}
|
||||
|
||||
//! \name BlackGui::Views::CViewBaseNonTemplate implementations
|
||||
//! @{
|
||||
virtual void clear() override { Q_ASSERT(this->m_model); this->m_model->clear(); }
|
||||
virtual int rowCount() const override;
|
||||
virtual bool isEmpty() const override;
|
||||
virtual bool isOrderable() const override;
|
||||
virtual void allowDragDrop(bool allowDrag, bool allowDrop) override;
|
||||
virtual bool isDropAllowed() const override;
|
||||
virtual bool acceptDrop(const QMimeData *mimeData) const override;
|
||||
virtual void setSorting(const BlackMisc::CPropertyIndex &propertyIndex, Qt::SortOrder order = Qt::AscendingOrder) override;
|
||||
//! @}
|
||||
|
||||
//! Column count
|
||||
int columnCount() const;
|
||||
|
||||
//! \copydoc BlackGui::Views::CViewBaseNonTemplate::isEmpty
|
||||
virtual bool isEmpty() const override;
|
||||
|
||||
//! Convert to JSON
|
||||
QJsonObject toJson() const;
|
||||
|
||||
@@ -522,6 +521,15 @@ namespace BlackGui
|
||||
//! Has filter set?
|
||||
bool hasFilter() const;
|
||||
|
||||
//! Add the object and container type as accepted drop types CDropBase::addAcceptedMetaTypeId
|
||||
void addContainerTypesAsDropTypes(bool objectType = true, bool containerType = true);
|
||||
|
||||
//! Init so items can be ordered
|
||||
void initAsOrderable();
|
||||
|
||||
//! Drop actions
|
||||
void setDropActions(Qt::DropActions dropActions) { Q_ASSERT(this->m_model); this->m_model->setDropActions(dropActions); }
|
||||
|
||||
protected:
|
||||
ModelClass *m_model = nullptr; //!< corresponding model
|
||||
|
||||
@@ -534,14 +542,12 @@ namespace BlackGui
|
||||
//! Standard initialization
|
||||
void standardInit(ModelClass *model = nullptr);
|
||||
|
||||
//! \copydoc BlackGui::Views::CViewBaseNonTemplate::reachedResizeThreshold
|
||||
//! \name base class implementations
|
||||
//! @{
|
||||
virtual bool reachedResizeThreshold(int containrerSize = -1) const override;
|
||||
|
||||
//! \copydoc BlackGui::Views::CViewBaseNonTemplate::performModeBasedResizeToContent
|
||||
virtual void performModeBasedResizeToContent() override;
|
||||
|
||||
//! \copydoc BlackGui::Views::CViewBaseNonTemplate::performUpdateContainer
|
||||
virtual int performUpdateContainer(const BlackMisc::CVariant &variant, bool sort, bool resize) override;
|
||||
//! @}
|
||||
|
||||
//! Modify JSON data loaded in BlackGui::Views::CViewBaseNonTemplate::ps_loadJson
|
||||
virtual BlackMisc::CStatusMessage modifyLoadedJsonData(ContainerType &data) const;
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
#include "viewdbobjects.h"
|
||||
#include "blackgui/models/allmodels.h"
|
||||
#include <QAction>
|
||||
#include <QWidgetAction>
|
||||
#include <QLineEdit>
|
||||
#include <QIntValidator>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackGui;
|
||||
@@ -84,7 +87,7 @@ namespace BlackGui
|
||||
template <class ModelClass, class ContainerType, class ObjectType, class KeyType>
|
||||
void CViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>::customMenu(QMenu &menu) const
|
||||
{
|
||||
if (this->m_menus.testFlag(CViewBase<ModelClass, ContainerType, ObjectType>::MenuHighlightDbData))
|
||||
if (this->m_menus.testFlag(CViewBaseNonTemplate::MenuHighlightDbData))
|
||||
{
|
||||
QAction *a = menu.addAction(CIcons::database16(), "Highlight DB data", this, &CViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>::ps_toggleHighlightDbData);
|
||||
a->setCheckable(true);
|
||||
@@ -100,14 +103,91 @@ namespace BlackGui
|
||||
this->derivedModel()->setHighlightDbData(!h);
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType, class KeyType>
|
||||
COrderableViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>::COrderableViewWithDbObjects(QWidget *parent) :
|
||||
CViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>::CViewWithDbObjects(parent)
|
||||
{
|
||||
// void
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType, class KeyType>
|
||||
void COrderableViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>::customMenu(QMenu &menu) const
|
||||
{
|
||||
if (this->m_menus.testFlag(CViewBaseNonTemplate::MenuOrderable) && this->hasSelection())
|
||||
{
|
||||
const int maxOrder = this->rowCount() - 1;
|
||||
QMenu *menuOrder = menu.addMenu(CIcons::arrowMediumEast16(), "Order");
|
||||
|
||||
QLineEdit *leOrder = new QLineEdit(&menu);
|
||||
leOrder->setPlaceholderText("New order 0-" + QString::number(maxOrder));
|
||||
const QIntValidator *v = new QIntValidator(0, maxOrder, leOrder);
|
||||
leOrder->setValidator(v);
|
||||
QWidgetAction *orderAction = new QWidgetAction(&menu);
|
||||
orderAction->setDefaultWidget(leOrder);
|
||||
menuOrder->addAction(orderAction);
|
||||
QObject::connect(leOrder, &QLineEdit::returnPressed, this, &COrderableViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>::ps_orderToLineEdit);
|
||||
|
||||
menuOrder->addAction(CIcons::arrowMediumNorth16(), "To top", this, &COrderableViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>::ps_orderToTop);
|
||||
menuOrder->addAction(CIcons::arrowMediumSouth16(), "To bottom", this, &COrderableViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>::ps_orderToBottom);
|
||||
menuOrder->addAction(CIcons::arrowMediumWest16(), "Freeze current order", this, &COrderableViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>::ps_freezeCurrentOrder);
|
||||
menu.addSeparator();
|
||||
}
|
||||
CViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>::customMenu(menu);
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType, class KeyType>
|
||||
void COrderableViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>::moveSelectedItems(int order)
|
||||
{
|
||||
if (this->isEmpty()) { return; }
|
||||
const ContainerType objs(this->selectedObjects());
|
||||
if (objs.isEmpty()) { return; }
|
||||
this->m_model->moveItems(objs, order);
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType, class KeyType>
|
||||
void COrderableViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>::ps_orderToTop()
|
||||
{
|
||||
this->moveSelectedItems(0);
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType, class KeyType>
|
||||
void COrderableViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>::ps_orderToBottom()
|
||||
{
|
||||
int c = this->model()->rowCount() - 1;
|
||||
if (c >= 0)
|
||||
{
|
||||
this->moveSelectedItems(c);
|
||||
}
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType, class KeyType>
|
||||
void COrderableViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>::ps_orderToLineEdit()
|
||||
{
|
||||
if (this->isEmpty()) { return; }
|
||||
QLineEdit *le = qobject_cast<QLineEdit *>(QObject::sender());
|
||||
if (!le || le->text().isEmpty()) { return; }
|
||||
const int order = le->text().toInt();
|
||||
this->moveSelectedItems(order);
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType, class KeyType>
|
||||
void COrderableViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>::ps_freezeCurrentOrder()
|
||||
{
|
||||
ContainerType objects = this->container();
|
||||
objects.freezeOrder();
|
||||
this->updateContainerAsync(objects, false);
|
||||
}
|
||||
|
||||
// see here for the reason of thess forward instantiations
|
||||
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
|
||||
template class CViewWithDbObjects<BlackGui::Models::CAircraftIcaoCodeListModel, BlackMisc::Aviation::CAircraftIcaoCodeList, BlackMisc::Aviation::CAircraftIcaoCode, int>;
|
||||
template class CViewWithDbObjects<BlackGui::Models::CAircraftModelListModel, BlackMisc::Simulation::CAircraftModelList, BlackMisc::Simulation::CAircraftModel, int>;
|
||||
template class CViewWithDbObjects<BlackGui::Models::CAirlineIcaoCodeListModel, BlackMisc::Aviation::CAirlineIcaoCodeList, BlackMisc::Aviation::CAirlineIcaoCode, int>;
|
||||
template class CViewWithDbObjects<BlackGui::Models::CCountryListModel, BlackMisc::CCountryList, BlackMisc::CCountry, QString>;
|
||||
template class CViewWithDbObjects<BlackGui::Models::CDistributorListModel, BlackMisc::Simulation::CDistributorList, BlackMisc::Simulation::CDistributor, QString>;
|
||||
template class CViewWithDbObjects<BlackGui::Models::CLiveryListModel, BlackMisc::Aviation::CLiveryList, BlackMisc::Aviation::CLivery, int>;
|
||||
template class CViewWithDbObjects<BlackGui::Models::CDistributorListModel, BlackMisc::Simulation::CDistributorList, BlackMisc::Simulation::CDistributor, QString>;
|
||||
template class CViewWithDbObjects<BlackGui::Models::CAircraftModelListModel, BlackMisc::Simulation::CAircraftModelList, BlackMisc::Simulation::CAircraftModel, int>;
|
||||
template class COrderableViewWithDbObjects<BlackGui::Models::CDistributorListModel, BlackMisc::Simulation::CDistributorList, BlackMisc::Simulation::CDistributor, QString>;
|
||||
template class COrderableViewWithDbObjects<BlackGui::Models::CAircraftModelListModel, BlackMisc::Simulation::CAircraftModelList, BlackMisc::Simulation::CAircraftModel, int>;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -51,6 +51,37 @@ namespace BlackGui
|
||||
//! \copydoc BlackGui::Views::CViewBase::ps_toggleHighlightDbData
|
||||
virtual void ps_toggleHighlightDbData() override;
|
||||
};
|
||||
|
||||
//! Base class for views with DB objects
|
||||
template <class ModelClass, class ContainerType, class ObjectType, class KeyType> class COrderableViewWithDbObjects :
|
||||
public CViewWithDbObjects<ModelClass, ContainerType, ObjectType, KeyType>
|
||||
{
|
||||
protected:
|
||||
//! Constructor
|
||||
explicit COrderableViewWithDbObjects(QWidget *parent = nullptr);
|
||||
|
||||
//! \copydoc BlackGui::Views::CViewBaseNonTemplate::customMenu
|
||||
virtual void customMenu(QMenu &menu) const override;
|
||||
|
||||
//! Move selected items
|
||||
void moveSelectedItems(int order);
|
||||
|
||||
protected slots:
|
||||
//! Order to top
|
||||
void ps_orderToTop();
|
||||
|
||||
//! Order to bottom
|
||||
void ps_orderToBottom();
|
||||
|
||||
//! Order to line edit
|
||||
void ps_orderToLineEdit();
|
||||
|
||||
//! Current order set as order
|
||||
void ps_freezeCurrentOrder();
|
||||
|
||||
private:
|
||||
QList<QAction *> m_menuActions;
|
||||
};
|
||||
} // namespace
|
||||
} // namespace
|
||||
#endif // guard
|
||||
|
||||
Reference in New Issue
Block a user