mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-16 18:35:35 +08:00
Split up listmodelbase
This is to reduce the number of symbols per single object file which caused MinGW 32 bit build to fail. - Moved CListModelBaseNonTemplate into its own file - Separated the template instantiations into domain specific source files
This commit is contained in:
committed by
Klaus Basan
parent
2bf9ff6d8b
commit
11f328b5c3
@@ -10,25 +10,16 @@
|
||||
// Drag and drop docu:
|
||||
// http://doc.qt.io/qt-5/model-view-programming.html#using-drag-and-drop-with-item-views
|
||||
|
||||
#include "blackgui/models/columnformatters.h"
|
||||
#include "blackgui/models/listmodelbase.h"
|
||||
#include "blackgui/models/allmodelcontainers.h"
|
||||
#include "blackgui/guiutility.h"
|
||||
#include "blackmisc/compare.h"
|
||||
#include "blackmisc/predicates.h"
|
||||
#include "blackmisc/propertyindex.h"
|
||||
#include "blackmisc/fileutils.h"
|
||||
#include "blackmisc/sequence.h"
|
||||
#include "blackmisc/variant.h"
|
||||
#include "blackmisc/verify.h"
|
||||
#include "blackmisc/worker.h"
|
||||
|
||||
#include <QFlags>
|
||||
#include <QJsonDocument>
|
||||
#include <QList>
|
||||
#include <QMimeData>
|
||||
#include <QtGlobal>
|
||||
#include <QFileInfo>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::Aviation;
|
||||
@@ -37,172 +28,6 @@ namespace BlackGui
|
||||
{
|
||||
namespace Models
|
||||
{
|
||||
int CListModelBaseNonTemplate::columnCount(const QModelIndex &modelIndex) const
|
||||
{
|
||||
Q_UNUSED(modelIndex);
|
||||
int c = m_columns.size();
|
||||
return c;
|
||||
}
|
||||
|
||||
QVariant CListModelBaseNonTemplate::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation != Qt::Horizontal) { return QVariant(); }
|
||||
const bool handled = (role == Qt::DisplayRole || role == Qt::ToolTipRole || role == Qt::InitialSortOrderRole);
|
||||
if (!handled) { return QVariant(); }
|
||||
if (section < 0 || section >= m_columns.size()) { return QVariant(); }
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
const QString header = m_columns.at(section).getColumnName(false);
|
||||
return QVariant(header);
|
||||
}
|
||||
if (role == Qt::ToolTipRole)
|
||||
{
|
||||
const QString header = m_columns.at(section).getColumnToolTip(false);
|
||||
return header.isEmpty() ? QVariant() : QVariant(header);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex CListModelBaseNonTemplate::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return QStandardItemModel::createIndex(row, column);
|
||||
}
|
||||
|
||||
QModelIndex CListModelBaseNonTemplate::parent(const QModelIndex &child) const
|
||||
{
|
||||
Q_UNUSED(child);
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
CPropertyIndex CListModelBaseNonTemplate::columnToPropertyIndex(int column) const
|
||||
{
|
||||
return m_columns.columnToPropertyIndex(column);
|
||||
}
|
||||
|
||||
int CListModelBaseNonTemplate::propertyIndexToColumn(const CPropertyIndex &propertyIndex) const
|
||||
{
|
||||
return m_columns.propertyIndexToColumn(propertyIndex);
|
||||
}
|
||||
|
||||
CPropertyIndex CListModelBaseNonTemplate::modelIndexToPropertyIndex(const QModelIndex &index) const
|
||||
{
|
||||
return this->columnToPropertyIndex(index.column());
|
||||
}
|
||||
|
||||
void CListModelBaseNonTemplate::sortByPropertyIndex(const CPropertyIndex &propertyIndex, Qt::SortOrder order)
|
||||
{
|
||||
const int column = this->propertyIndexToColumn(propertyIndex);
|
||||
this->sort(column, order);
|
||||
}
|
||||
|
||||
bool CListModelBaseNonTemplate::setSortColumnByPropertyIndex(const CPropertyIndex &propertyIndex)
|
||||
{
|
||||
const int column = m_columns.propertyIndexToColumn(propertyIndex);
|
||||
if (m_sortColumn == column) { return false; } // not changed
|
||||
m_sortColumn = column;
|
||||
return true; // changed
|
||||
}
|
||||
|
||||
bool CListModelBaseNonTemplate::setSorting(const CPropertyIndex &propertyIndex, Qt::SortOrder order)
|
||||
{
|
||||
const bool changedColumn = this->setSortColumnByPropertyIndex(propertyIndex);
|
||||
const bool changedOrder = (m_sortOrder == order);
|
||||
m_sortOrder = order;
|
||||
return changedColumn || changedOrder;
|
||||
}
|
||||
|
||||
bool CListModelBaseNonTemplate::hasValidSortColumn() const
|
||||
{
|
||||
|
||||
if (!(m_sortColumn >= 0 && m_sortColumn < m_columns.size())) { return false; }
|
||||
return m_columns.isSortable(m_sortColumn);
|
||||
}
|
||||
|
||||
Qt::ItemFlags CListModelBaseNonTemplate::flags(const QModelIndex &index) const
|
||||
{
|
||||
Qt::ItemFlags f = QStandardItemModel::flags(index);
|
||||
if (!index.isValid()) { return f; }
|
||||
const bool editable = m_columns.isEditable(index);
|
||||
f = editable ? (f | Qt::ItemIsEditable) : (f & ~Qt::ItemIsEditable);
|
||||
|
||||
// flags from formatter
|
||||
const CDefaultFormatter *formatter = m_columns.getFormatter(index);
|
||||
if (formatter) { f = formatter->flags(f, editable); }
|
||||
|
||||
// drag and drop
|
||||
f = f | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
|
||||
return f;
|
||||
}
|
||||
|
||||
const QString &CListModelBaseNonTemplate::getTranslationContext() const
|
||||
{
|
||||
return m_columns.getTranslationContext();
|
||||
}
|
||||
|
||||
Qt::DropActions CListModelBaseNonTemplate::supportedDragActions() const
|
||||
{
|
||||
return isOrderable() ? Qt::CopyAction | Qt::MoveAction : Qt::CopyAction;
|
||||
}
|
||||
|
||||
Qt::DropActions CListModelBaseNonTemplate::supportedDropActions() const
|
||||
{
|
||||
return m_dropActions;
|
||||
}
|
||||
|
||||
QStringList CListModelBaseNonTemplate::mimeTypes() const
|
||||
{
|
||||
static const QStringList mimes({ "application/swift.container.json" });
|
||||
return mimes;
|
||||
}
|
||||
|
||||
void CListModelBaseNonTemplate::markDestroyed()
|
||||
{
|
||||
m_modelDestroyed = true;
|
||||
}
|
||||
|
||||
bool CListModelBaseNonTemplate::isModelDestroyed()
|
||||
{
|
||||
return m_modelDestroyed;
|
||||
}
|
||||
|
||||
void CListModelBaseNonTemplate::clearHighlighting()
|
||||
{
|
||||
// can be overridden to delete highlighting
|
||||
}
|
||||
|
||||
bool CListModelBaseNonTemplate::hasHighlightedRows() const
|
||||
{
|
||||
return false;
|
||||
// can be overridden to enable highlighting based operations
|
||||
}
|
||||
|
||||
void CListModelBaseNonTemplate::emitDataChanged(int startRowIndex, int endRowIndex)
|
||||
{
|
||||
BLACK_VERIFY_X(startRowIndex <= endRowIndex, Q_FUNC_INFO, "check rows");
|
||||
BLACK_VERIFY_X(startRowIndex >= 0 && endRowIndex >= 0, Q_FUNC_INFO, "check rows");
|
||||
|
||||
const int columns = columnCount();
|
||||
const int rows = rowCount();
|
||||
if (columns < 1) { return; }
|
||||
if (startRowIndex < 0) { startRowIndex = 0; }
|
||||
if (endRowIndex >= rows) { endRowIndex = rows - 1; }
|
||||
const QModelIndex topLeft(createIndex(startRowIndex, 0));
|
||||
const QModelIndex bottomRight(createIndex(endRowIndex, columns - 1));
|
||||
emit this->dataChanged(topLeft, bottomRight);
|
||||
}
|
||||
|
||||
CListModelBaseNonTemplate::CListModelBaseNonTemplate(const QString &translationContext, QObject *parent)
|
||||
: QStandardItemModel(parent), m_columns(translationContext), m_sortColumn(-1), m_sortOrder(Qt::AscendingOrder)
|
||||
{
|
||||
// non unique default name, set translation context as default
|
||||
this->setObjectName(translationContext);
|
||||
|
||||
// connect
|
||||
connect(this, &CListModelBaseNonTemplate::dataChanged, this, &CListModelBaseNonTemplate::onDataChanged);
|
||||
}
|
||||
|
||||
template <typename ObjectType, typename ContainerType, bool UseCompare>
|
||||
CListModelBase<ObjectType, ContainerType, UseCompare>::CListModelBase(const QString &translationContext, QObject *parent)
|
||||
: CListModelBaseNonTemplate(translationContext, parent)
|
||||
@@ -770,33 +595,5 @@ namespace BlackGui
|
||||
return false;
|
||||
}
|
||||
|
||||
// see here for the reason of thess forward instantiations
|
||||
// https://isocpp.org/wiki/faq/templates#separate-template-fn-defn-from-decl
|
||||
template class CListModelBase<BlackMisc::CIdentifier, BlackMisc::CIdentifierList, false>;
|
||||
template class CListModelBase<BlackMisc::CApplicationInfo, BlackMisc::CApplicationInfoList, true>;
|
||||
template class CListModelBase<BlackMisc::CStatusMessage, BlackMisc::CStatusMessageList, true>;
|
||||
template class CListModelBase<BlackMisc::CNameVariantPair, BlackMisc::CNameVariantPairList, false>;
|
||||
template class CListModelBase<BlackMisc::CCountry, BlackMisc::CCountryList, true>;
|
||||
template class CListModelBase<BlackMisc::Aviation::CLivery, BlackMisc::Aviation::CLiveryList, true>;
|
||||
template class CListModelBase<BlackMisc::Aviation::CAtcStation, BlackMisc::Aviation::CAtcStationList, true>;
|
||||
template class CListModelBase<BlackMisc::Aviation::CAirport, BlackMisc::Aviation::CAirportList, true>;
|
||||
template class CListModelBase<BlackMisc::Aviation::CAircraftIcaoCode, BlackMisc::Aviation::CAircraftIcaoCodeList, true>;
|
||||
template class CListModelBase<BlackMisc::Aviation::CAirlineIcaoCode, BlackMisc::Aviation::CAirlineIcaoCodeList, true>;
|
||||
template class CListModelBase<BlackMisc::Aviation::CAircraftParts, BlackMisc::Aviation::CAircraftPartsList, true>;
|
||||
template class CListModelBase<BlackMisc::Aviation::CAircraftSituation, BlackMisc::Aviation::CAircraftSituationList, true>;
|
||||
template class CListModelBase<BlackMisc::Aviation::CAircraftSituationChange, BlackMisc::Aviation::CAircraftSituationChangeList, true>;
|
||||
template class CListModelBase<BlackMisc::Network::CServer, BlackMisc::Network::CServerList, true>;
|
||||
template class CListModelBase<BlackMisc::Network::CUser, BlackMisc::Network::CUserList, true>;
|
||||
template class CListModelBase<BlackMisc::Network::CTextMessage, BlackMisc::Network::CTextMessageList, false>;
|
||||
template class CListModelBase<BlackMisc::Network::CClient, BlackMisc::Network::CClientList, false>;
|
||||
template class CListModelBase<BlackMisc::Simulation::CAircraftModel, BlackMisc::Simulation::CAircraftModelList, true>;
|
||||
template class CListModelBase<BlackMisc::Simulation::CSimulatedAircraft, BlackMisc::Simulation::CSimulatedAircraftList, true>;
|
||||
template class CListModelBase<BlackMisc::Simulation::CDistributor, BlackMisc::Simulation::CDistributorList, true>;
|
||||
template class CListModelBase<BlackMisc::Simulation::CInterpolationAndRenderingSetupPerCallsign, BlackMisc::Simulation::CInterpolationSetupList, false>;
|
||||
template class CListModelBase<BlackMisc::Simulation::CMatchingStatisticsEntry, BlackMisc::Simulation::CMatchingStatistics, true>;
|
||||
template class CListModelBase<BlackMisc::Weather::CCloudLayer, BlackMisc::Weather::CCloudLayerList, false>;
|
||||
template class CListModelBase<BlackMisc::Weather::CTemperatureLayer, BlackMisc::Weather::CTemperatureLayerList, false>;
|
||||
template class CListModelBase<BlackMisc::Weather::CWindLayer, BlackMisc::Weather::CWindLayerList, false>;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -12,27 +12,23 @@
|
||||
#ifndef BLACKGUI_LISTMODELBASE_H
|
||||
#define BLACKGUI_LISTMODELBASE_H
|
||||
|
||||
#include "blackgui/models/columns.h"
|
||||
#include "blackgui/models/listmodelbasenontemplate.h"
|
||||
//#include "blackgui/models/columns.h"
|
||||
#include "blackgui/models/modelfilter.h"
|
||||
#include "blackgui/models/selectionmodel.h"
|
||||
#include "blackgui/dropbase.h"
|
||||
#include "blackgui/blackguiexport.h"
|
||||
#include "blackmisc/digestsignal.h"
|
||||
#include "blackmisc/variant.h"
|
||||
//#include "blackgui/dropbase.h"
|
||||
//#include "blackgui/blackguiexport.h"
|
||||
//#include "blackmisc/digestsignal.h"
|
||||
//#include "blackmisc/variant.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QModelIndex>
|
||||
#include <QModelIndexList>
|
||||
#include <QObject>
|
||||
#include <QStandardItemModel>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
#include <QVector>
|
||||
#include <Qt>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
class QMimeData;
|
||||
class QModelIndex;
|
||||
@@ -42,141 +38,6 @@ namespace BlackGui
|
||||
{
|
||||
namespace Models
|
||||
{
|
||||
//! Non templated base class, allows Q_OBJECT and signals to be used
|
||||
class BLACKGUI_EXPORT CListModelBaseNonTemplate :
|
||||
public QStandardItemModel,
|
||||
public CDropBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Number of elements when to use asynchronous updates
|
||||
static constexpr int asyncThreshold = 50;
|
||||
|
||||
//! Destructor
|
||||
virtual ~CListModelBaseNonTemplate() override {}
|
||||
|
||||
//! \name Functions from QStandardItemModel
|
||||
//! @{
|
||||
virtual int columnCount(const QModelIndex &modelIndex = QModelIndex()) const final override;
|
||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const final override;
|
||||
virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const final override;
|
||||
virtual QModelIndex parent(const QModelIndex &child) const final override;
|
||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const final override;
|
||||
virtual Qt::DropActions supportedDragActions() const final override;
|
||||
virtual Qt::DropActions supportedDropActions() const final override;
|
||||
virtual QStringList mimeTypes() const final override;
|
||||
//! @}
|
||||
|
||||
//! Column to property index
|
||||
virtual BlackMisc::CPropertyIndex columnToPropertyIndex(int column) const;
|
||||
|
||||
//! Property index to column number
|
||||
virtual int propertyIndexToColumn(const BlackMisc::CPropertyIndex &propertyIndex) const;
|
||||
|
||||
//! Index to property index
|
||||
virtual BlackMisc::CPropertyIndex modelIndexToPropertyIndex(const QModelIndex &index) const;
|
||||
|
||||
//! Set sort column
|
||||
virtual void setSortColumn(int column) { m_sortColumn = column; }
|
||||
|
||||
//! Sort by index
|
||||
void sortByPropertyIndex(const BlackMisc::CPropertyIndex &propertyIndex, Qt::SortOrder order = Qt::AscendingOrder);
|
||||
|
||||
//! Set column for sorting
|
||||
//! \param propertyIndex index of column to be sorted
|
||||
virtual bool setSortColumnByPropertyIndex(const BlackMisc::CPropertyIndex &propertyIndex);
|
||||
|
||||
//! Sorting
|
||||
virtual bool setSorting(const BlackMisc::CPropertyIndex &propertyIndex, Qt::SortOrder order = Qt::AscendingOrder);
|
||||
|
||||
//! Get sort column property index
|
||||
virtual int getSortColumn() const { return m_sortColumn; }
|
||||
|
||||
//! Has valid sort column?
|
||||
virtual bool hasValidSortColumn() const;
|
||||
|
||||
//! Get sort order
|
||||
virtual Qt::SortOrder getSortOrder() const { return m_sortOrder; }
|
||||
|
||||
//! Translation context
|
||||
virtual const QString &getTranslationContext() const;
|
||||
|
||||
//! Orderable, normally use a container BlackMisc::IOrderableList
|
||||
virtual bool isOrderable() const = 0;
|
||||
|
||||
//! Mark as about to be destroyed, normally marked from view
|
||||
void markDestroyed();
|
||||
|
||||
//! Model about to be destroyed?
|
||||
bool isModelDestroyed();
|
||||
|
||||
//! Remove all highlighting
|
||||
virtual void clearHighlighting();
|
||||
|
||||
//! Has highlighted rows?
|
||||
virtual bool hasHighlightedRows() const;
|
||||
|
||||
//! Drop actions
|
||||
void setDropActions(Qt::DropActions dropActions) { 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 emitDataChanged(int startRowIndex, int endRowIndex);
|
||||
|
||||
//! Convert to JSON
|
||||
virtual QJsonObject toJson(bool selectedOnly = false) const = 0;
|
||||
|
||||
//! Convert to JSON string
|
||||
virtual QString toJsonString(QJsonDocument::JsonFormat format = QJsonDocument::Indented, bool selectedOnly = false) const = 0;
|
||||
|
||||
//! The columns
|
||||
const CColumns &getColumns() const { return m_columns; }
|
||||
|
||||
signals:
|
||||
//! Asynchronous update finished
|
||||
void asyncUpdateFinished();
|
||||
|
||||
//! Data changed
|
||||
//! \remark passing back selected objects so they can be reselected
|
||||
//! \remark condsider modelDataChangedDigest for performance reasons
|
||||
void modelDataChanged(int count, bool withFilter);
|
||||
|
||||
//! Data changed, digest version
|
||||
void modelDataChangedDigest(int count, bool withFilter);
|
||||
|
||||
//! Model has been changed
|
||||
//! Triggered with each change, for performance consider using changedDigest
|
||||
void changed();
|
||||
|
||||
//! Model has been changed, digest signal
|
||||
void changedDigest();
|
||||
|
||||
//! Template free information, that object changed
|
||||
void objectChanged(const BlackMisc::CVariant &object, const BlackMisc::CPropertyIndex &changedIndex);
|
||||
|
||||
protected:
|
||||
//! Feedback when QStandardItemModel::dataChanged was called
|
||||
virtual void onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) = 0;
|
||||
|
||||
//! Digest signal
|
||||
virtual void onChangedDigest() = 0;
|
||||
|
||||
//! Constructor
|
||||
//! \param translationContext I18N context
|
||||
//! \param parent
|
||||
CListModelBaseNonTemplate(const QString &translationContext, QObject *parent = nullptr);
|
||||
|
||||
CColumns m_columns; //!< columns metadata
|
||||
int m_sortColumn; //!< currently sorted column
|
||||
bool m_modelDestroyed = false; //!< model is about to be destroyed
|
||||
Qt::SortOrder m_sortOrder; //!< sort order (asc/desc)
|
||||
Qt::DropActions m_dropActions = Qt::IgnoreAction; //!< drop actions
|
||||
|
||||
private:
|
||||
BlackMisc::CDigestSignal m_dsModelsChanged { this, &CListModelBaseNonTemplate::changed, &CListModelBaseNonTemplate::onChangedDigest, 500, 10 };
|
||||
};
|
||||
|
||||
//! List model
|
||||
template <typename ObjectType, typename ContainerType, bool UseCompare = false> class CListModelBase : public CListModelBaseNonTemplate
|
||||
{
|
||||
|
||||
27
src/blackgui/models/listmodelbaseaviation.cpp
Normal file
27
src/blackgui/models/listmodelbaseaviation.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
/* Copyright (C) 2018
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "listmodelbase.cpp"
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Models
|
||||
{
|
||||
// see here for the reason of thess forward instantiations
|
||||
// https://isocpp.org/wiki/faq/templates#separate-template-fn-defn-from-decl
|
||||
template class CListModelBase<BlackMisc::Aviation::CLivery, BlackMisc::Aviation::CLiveryList, true>;
|
||||
template class CListModelBase<BlackMisc::Aviation::CAtcStation, BlackMisc::Aviation::CAtcStationList, true>;
|
||||
template class CListModelBase<BlackMisc::Aviation::CAirport, BlackMisc::Aviation::CAirportList, true>;
|
||||
template class CListModelBase<BlackMisc::Aviation::CAircraftIcaoCode, BlackMisc::Aviation::CAircraftIcaoCodeList, true>;
|
||||
template class CListModelBase<BlackMisc::Aviation::CAirlineIcaoCode, BlackMisc::Aviation::CAirlineIcaoCodeList, true>;
|
||||
template class CListModelBase<BlackMisc::Aviation::CAircraftParts, BlackMisc::Aviation::CAircraftPartsList, true>;
|
||||
template class CListModelBase<BlackMisc::Aviation::CAircraftSituation, BlackMisc::Aviation::CAircraftSituationList, true>;
|
||||
template class CListModelBase<BlackMisc::Aviation::CAircraftSituationChange, BlackMisc::Aviation::CAircraftSituationChangeList, true>;
|
||||
} // namespace
|
||||
} // namespace
|
||||
25
src/blackgui/models/listmodelbasemisc.cpp
Normal file
25
src/blackgui/models/listmodelbasemisc.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/* Copyright (C) 2018
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "listmodelbase.cpp"
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Models
|
||||
{
|
||||
// see here for the reason of thess forward instantiations
|
||||
// https://isocpp.org/wiki/faq/templates#separate-template-fn-defn-from-decl
|
||||
template class CListModelBase<BlackMisc::CIdentifier, BlackMisc::CIdentifierList, false>;
|
||||
template class CListModelBase<BlackMisc::CApplicationInfo, BlackMisc::CApplicationInfoList, true>;
|
||||
template class CListModelBase<BlackMisc::CStatusMessage, BlackMisc::CStatusMessageList, true>;
|
||||
template class CListModelBase<BlackMisc::CNameVariantPair, BlackMisc::CNameVariantPairList, false>;
|
||||
template class CListModelBase<BlackMisc::CCountry, BlackMisc::CCountryList, true>;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
24
src/blackgui/models/listmodelbasenetwork.cpp
Normal file
24
src/blackgui/models/listmodelbasenetwork.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
/* Copyright (C) 2018
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "listmodelbase.cpp"
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Models
|
||||
{
|
||||
// see here for the reason of thess forward instantiations
|
||||
// https://isocpp.org/wiki/faq/templates#separate-template-fn-defn-from-decl
|
||||
template class CListModelBase<BlackMisc::Network::CServer, BlackMisc::Network::CServerList, true>;
|
||||
template class CListModelBase<BlackMisc::Network::CUser, BlackMisc::Network::CUserList, true>;
|
||||
template class CListModelBase<BlackMisc::Network::CTextMessage, BlackMisc::Network::CTextMessageList, false>;
|
||||
template class CListModelBase<BlackMisc::Network::CClient, BlackMisc::Network::CClientList, false>;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
206
src/blackgui/models/listmodelbasenontemplate.cpp
Normal file
206
src/blackgui/models/listmodelbasenontemplate.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
/* Copyright (C) 2018
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* 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 "blackgui/models/columnformatters.h"
|
||||
#include "blackgui/models/listmodelbasenontemplate.h"
|
||||
//#include "blackgui/models/allmodelcontainers.h"
|
||||
//#include "blackgui/guiutility.h"
|
||||
//#include "blackmisc/compare.h"
|
||||
//#include "blackmisc/predicates.h"
|
||||
//#include "blackmisc/propertyindex.h"
|
||||
//#include "blackmisc/fileutils.h"
|
||||
//#include "blackmisc/sequence.h"
|
||||
//#include "blackmisc/variant.h"
|
||||
#include "blackmisc/verify.h"
|
||||
//#include "blackmisc/worker.h"
|
||||
|
||||
//#include <QFlags>
|
||||
//#include <QJsonDocument>
|
||||
//#include <QList>
|
||||
//#include <QMimeData>
|
||||
//#include <QtGlobal>
|
||||
//#include <QFileInfo>
|
||||
|
||||
using namespace BlackMisc;
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Models
|
||||
{
|
||||
int CListModelBaseNonTemplate::columnCount(const QModelIndex &modelIndex) const
|
||||
{
|
||||
Q_UNUSED(modelIndex);
|
||||
int c = m_columns.size();
|
||||
return c;
|
||||
}
|
||||
|
||||
QVariant CListModelBaseNonTemplate::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation != Qt::Horizontal) { return QVariant(); }
|
||||
const bool handled = (role == Qt::DisplayRole || role == Qt::ToolTipRole || role == Qt::InitialSortOrderRole);
|
||||
if (!handled) { return QVariant(); }
|
||||
if (section < 0 || section >= m_columns.size()) { return QVariant(); }
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
const QString header = m_columns.at(section).getColumnName(false);
|
||||
return QVariant(header);
|
||||
}
|
||||
if (role == Qt::ToolTipRole)
|
||||
{
|
||||
const QString header = m_columns.at(section).getColumnToolTip(false);
|
||||
return header.isEmpty() ? QVariant() : QVariant(header);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex CListModelBaseNonTemplate::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return QStandardItemModel::createIndex(row, column);
|
||||
}
|
||||
|
||||
QModelIndex CListModelBaseNonTemplate::parent(const QModelIndex &child) const
|
||||
{
|
||||
Q_UNUSED(child);
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
CPropertyIndex CListModelBaseNonTemplate::columnToPropertyIndex(int column) const
|
||||
{
|
||||
return m_columns.columnToPropertyIndex(column);
|
||||
}
|
||||
|
||||
int CListModelBaseNonTemplate::propertyIndexToColumn(const CPropertyIndex &propertyIndex) const
|
||||
{
|
||||
return m_columns.propertyIndexToColumn(propertyIndex);
|
||||
}
|
||||
|
||||
CPropertyIndex CListModelBaseNonTemplate::modelIndexToPropertyIndex(const QModelIndex &index) const
|
||||
{
|
||||
return this->columnToPropertyIndex(index.column());
|
||||
}
|
||||
|
||||
void CListModelBaseNonTemplate::sortByPropertyIndex(const CPropertyIndex &propertyIndex, Qt::SortOrder order)
|
||||
{
|
||||
const int column = this->propertyIndexToColumn(propertyIndex);
|
||||
this->sort(column, order);
|
||||
}
|
||||
|
||||
bool CListModelBaseNonTemplate::setSortColumnByPropertyIndex(const CPropertyIndex &propertyIndex)
|
||||
{
|
||||
const int column = m_columns.propertyIndexToColumn(propertyIndex);
|
||||
if (m_sortColumn == column) { return false; } // not changed
|
||||
m_sortColumn = column;
|
||||
return true; // changed
|
||||
}
|
||||
|
||||
bool CListModelBaseNonTemplate::setSorting(const CPropertyIndex &propertyIndex, Qt::SortOrder order)
|
||||
{
|
||||
const bool changedColumn = this->setSortColumnByPropertyIndex(propertyIndex);
|
||||
const bool changedOrder = (m_sortOrder == order);
|
||||
m_sortOrder = order;
|
||||
return changedColumn || changedOrder;
|
||||
}
|
||||
|
||||
bool CListModelBaseNonTemplate::hasValidSortColumn() const
|
||||
{
|
||||
|
||||
if (!(m_sortColumn >= 0 && m_sortColumn < m_columns.size())) { return false; }
|
||||
return m_columns.isSortable(m_sortColumn);
|
||||
}
|
||||
|
||||
Qt::ItemFlags CListModelBaseNonTemplate::flags(const QModelIndex &index) const
|
||||
{
|
||||
Qt::ItemFlags f = QStandardItemModel::flags(index);
|
||||
if (!index.isValid()) { return f; }
|
||||
const bool editable = m_columns.isEditable(index);
|
||||
f = editable ? (f | Qt::ItemIsEditable) : (f & ~Qt::ItemIsEditable);
|
||||
|
||||
// flags from formatter
|
||||
const CDefaultFormatter *formatter = m_columns.getFormatter(index);
|
||||
if (formatter) { f = formatter->flags(f, editable); }
|
||||
|
||||
// drag and drop
|
||||
f = f | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
|
||||
return f;
|
||||
}
|
||||
|
||||
const QString &CListModelBaseNonTemplate::getTranslationContext() const
|
||||
{
|
||||
return m_columns.getTranslationContext();
|
||||
}
|
||||
|
||||
Qt::DropActions CListModelBaseNonTemplate::supportedDragActions() const
|
||||
{
|
||||
return isOrderable() ? Qt::CopyAction | Qt::MoveAction : Qt::CopyAction;
|
||||
}
|
||||
|
||||
Qt::DropActions CListModelBaseNonTemplate::supportedDropActions() const
|
||||
{
|
||||
return m_dropActions;
|
||||
}
|
||||
|
||||
QStringList CListModelBaseNonTemplate::mimeTypes() const
|
||||
{
|
||||
static const QStringList mimes({ "application/swift.container.json" });
|
||||
return mimes;
|
||||
}
|
||||
|
||||
void CListModelBaseNonTemplate::markDestroyed()
|
||||
{
|
||||
m_modelDestroyed = true;
|
||||
}
|
||||
|
||||
bool CListModelBaseNonTemplate::isModelDestroyed()
|
||||
{
|
||||
return m_modelDestroyed;
|
||||
}
|
||||
|
||||
void CListModelBaseNonTemplate::clearHighlighting()
|
||||
{
|
||||
// can be overridden to delete highlighting
|
||||
}
|
||||
|
||||
bool CListModelBaseNonTemplate::hasHighlightedRows() const
|
||||
{
|
||||
return false;
|
||||
// can be overridden to enable highlighting based operations
|
||||
}
|
||||
|
||||
void CListModelBaseNonTemplate::emitDataChanged(int startRowIndex, int endRowIndex)
|
||||
{
|
||||
BLACK_VERIFY_X(startRowIndex <= endRowIndex, Q_FUNC_INFO, "check rows");
|
||||
BLACK_VERIFY_X(startRowIndex >= 0 && endRowIndex >= 0, Q_FUNC_INFO, "check rows");
|
||||
|
||||
const int columns = columnCount();
|
||||
const int rows = rowCount();
|
||||
if (columns < 1) { return; }
|
||||
if (startRowIndex < 0) { startRowIndex = 0; }
|
||||
if (endRowIndex >= rows) { endRowIndex = rows - 1; }
|
||||
const QModelIndex topLeft(createIndex(startRowIndex, 0));
|
||||
const QModelIndex bottomRight(createIndex(endRowIndex, columns - 1));
|
||||
emit this->dataChanged(topLeft, bottomRight);
|
||||
}
|
||||
|
||||
CListModelBaseNonTemplate::CListModelBaseNonTemplate(const QString &translationContext, QObject *parent)
|
||||
: QStandardItemModel(parent), m_columns(translationContext), m_sortColumn(-1), m_sortOrder(Qt::AscendingOrder)
|
||||
{
|
||||
// non unique default name, set translation context as default
|
||||
this->setObjectName(translationContext);
|
||||
|
||||
// connect
|
||||
connect(this, &CListModelBaseNonTemplate::dataChanged, this, &CListModelBaseNonTemplate::onDataChanged);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
176
src/blackgui/models/listmodelbasenontemplate.h
Normal file
176
src/blackgui/models/listmodelbasenontemplate.h
Normal file
@@ -0,0 +1,176 @@
|
||||
/* Copyright (C) 2018
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef BLACKGUI_LISTMODELBASENONTEMPLATE_H
|
||||
#define BLACKGUI_LISTMODELBASENONTEMPLATE_H
|
||||
|
||||
#include "blackgui/models/columns.h"
|
||||
#include "blackgui/dropbase.h"
|
||||
#include "blackgui/blackguiexport.h"
|
||||
#include "blackmisc/digestsignal.h"
|
||||
#include "blackmisc/variant.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QModelIndex>
|
||||
#include <QModelIndexList>
|
||||
#include <QStandardItemModel>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
#include <QVector>
|
||||
|
||||
class QMimeData;
|
||||
class QModelIndex;
|
||||
|
||||
namespace BlackMisc { class CWorker; }
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Models
|
||||
{
|
||||
//! Non templated base class, allows Q_OBJECT and signals to be used
|
||||
class BLACKGUI_EXPORT CListModelBaseNonTemplate :
|
||||
public QStandardItemModel,
|
||||
public CDropBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Number of elements when to use asynchronous updates
|
||||
static constexpr int asyncThreshold = 50;
|
||||
|
||||
//! Destructor
|
||||
virtual ~CListModelBaseNonTemplate() override {}
|
||||
|
||||
//! \name Functions from QStandardItemModel
|
||||
//! @{
|
||||
virtual int columnCount(const QModelIndex &modelIndex = QModelIndex()) const final override;
|
||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const final override;
|
||||
virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const final override;
|
||||
virtual QModelIndex parent(const QModelIndex &child) const final override;
|
||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const final override;
|
||||
virtual Qt::DropActions supportedDragActions() const final override;
|
||||
virtual Qt::DropActions supportedDropActions() const final override;
|
||||
virtual QStringList mimeTypes() const final override;
|
||||
//! @}
|
||||
|
||||
//! Column to property index
|
||||
virtual BlackMisc::CPropertyIndex columnToPropertyIndex(int column) const;
|
||||
|
||||
//! Property index to column number
|
||||
virtual int propertyIndexToColumn(const BlackMisc::CPropertyIndex &propertyIndex) const;
|
||||
|
||||
//! Index to property index
|
||||
virtual BlackMisc::CPropertyIndex modelIndexToPropertyIndex(const QModelIndex &index) const;
|
||||
|
||||
//! Set sort column
|
||||
virtual void setSortColumn(int column) { m_sortColumn = column; }
|
||||
|
||||
//! Sort by index
|
||||
void sortByPropertyIndex(const BlackMisc::CPropertyIndex &propertyIndex, Qt::SortOrder order = Qt::AscendingOrder);
|
||||
|
||||
//! Set column for sorting
|
||||
//! \param propertyIndex index of column to be sorted
|
||||
virtual bool setSortColumnByPropertyIndex(const BlackMisc::CPropertyIndex &propertyIndex);
|
||||
|
||||
//! Sorting
|
||||
virtual bool setSorting(const BlackMisc::CPropertyIndex &propertyIndex, Qt::SortOrder order = Qt::AscendingOrder);
|
||||
|
||||
//! Get sort column property index
|
||||
virtual int getSortColumn() const { return m_sortColumn; }
|
||||
|
||||
//! Has valid sort column?
|
||||
virtual bool hasValidSortColumn() const;
|
||||
|
||||
//! Get sort order
|
||||
virtual Qt::SortOrder getSortOrder() const { return m_sortOrder; }
|
||||
|
||||
//! Translation context
|
||||
virtual const QString &getTranslationContext() const;
|
||||
|
||||
//! Orderable, normally use a container BlackMisc::IOrderableList
|
||||
virtual bool isOrderable() const = 0;
|
||||
|
||||
//! Mark as about to be destroyed, normally marked from view
|
||||
void markDestroyed();
|
||||
|
||||
//! Model about to be destroyed?
|
||||
bool isModelDestroyed();
|
||||
|
||||
//! Remove all highlighting
|
||||
virtual void clearHighlighting();
|
||||
|
||||
//! Has highlighted rows?
|
||||
virtual bool hasHighlightedRows() const;
|
||||
|
||||
//! Drop actions
|
||||
void setDropActions(Qt::DropActions dropActions) { 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 emitDataChanged(int startRowIndex, int endRowIndex);
|
||||
|
||||
//! Convert to JSON
|
||||
virtual QJsonObject toJson(bool selectedOnly = false) const = 0;
|
||||
|
||||
//! Convert to JSON string
|
||||
virtual QString toJsonString(QJsonDocument::JsonFormat format = QJsonDocument::Indented, bool selectedOnly = false) const = 0;
|
||||
|
||||
//! The columns
|
||||
const CColumns &getColumns() const { return m_columns; }
|
||||
|
||||
signals:
|
||||
//! Asynchronous update finished
|
||||
void asyncUpdateFinished();
|
||||
|
||||
//! Data changed
|
||||
//! \remark passing back selected objects so they can be reselected
|
||||
//! \remark condsider modelDataChangedDigest for performance reasons
|
||||
void modelDataChanged(int count, bool withFilter);
|
||||
|
||||
//! Data changed, digest version
|
||||
void modelDataChangedDigest(int count, bool withFilter);
|
||||
|
||||
//! Model has been changed
|
||||
//! Triggered with each change, for performance consider using changedDigest
|
||||
void changed();
|
||||
|
||||
//! Model has been changed, digest signal
|
||||
void changedDigest();
|
||||
|
||||
//! Template free information, that object changed
|
||||
void objectChanged(const BlackMisc::CVariant &object, const BlackMisc::CPropertyIndex &changedIndex);
|
||||
|
||||
protected:
|
||||
//! Feedback when QStandardItemModel::dataChanged was called
|
||||
virtual void onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) = 0;
|
||||
|
||||
//! Digest signal
|
||||
virtual void onChangedDigest() = 0;
|
||||
|
||||
//! Constructor
|
||||
//! \param translationContext I18N context
|
||||
//! \param parent
|
||||
CListModelBaseNonTemplate(const QString &translationContext, QObject *parent = nullptr);
|
||||
|
||||
CColumns m_columns; //!< columns metadata
|
||||
int m_sortColumn; //!< currently sorted column
|
||||
bool m_modelDestroyed = false; //!< model is about to be destroyed
|
||||
Qt::SortOrder m_sortOrder; //!< sort order (asc/desc)
|
||||
Qt::DropActions m_dropActions = Qt::IgnoreAction; //!< drop actions
|
||||
|
||||
private:
|
||||
BlackMisc::CDigestSignal m_dsModelsChanged { this, &CListModelBaseNonTemplate::changed, &CListModelBaseNonTemplate::onChangedDigest, 500, 10 };
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
#endif // guard
|
||||
25
src/blackgui/models/listmodelbasesimulation.cpp
Normal file
25
src/blackgui/models/listmodelbasesimulation.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/* Copyright (C) 2018
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "listmodelbase.cpp"
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Models
|
||||
{
|
||||
// see here for the reason of thess forward instantiations
|
||||
// https://isocpp.org/wiki/faq/templates#separate-template-fn-defn-from-decl
|
||||
template class CListModelBase<BlackMisc::Simulation::CAircraftModel, BlackMisc::Simulation::CAircraftModelList, true>;
|
||||
template class CListModelBase<BlackMisc::Simulation::CSimulatedAircraft, BlackMisc::Simulation::CSimulatedAircraftList, true>;
|
||||
template class CListModelBase<BlackMisc::Simulation::CDistributor, BlackMisc::Simulation::CDistributorList, true>;
|
||||
template class CListModelBase<BlackMisc::Simulation::CInterpolationAndRenderingSetupPerCallsign, BlackMisc::Simulation::CInterpolationSetupList, false>;
|
||||
template class CListModelBase<BlackMisc::Simulation::CMatchingStatisticsEntry, BlackMisc::Simulation::CMatchingStatistics, true>;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
24
src/blackgui/models/listmodelbaseweather.cpp
Normal file
24
src/blackgui/models/listmodelbaseweather.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
/* Copyright (C) 2018
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "listmodelbase.cpp"
|
||||
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Models
|
||||
{
|
||||
// see here for the reason of thess forward instantiations
|
||||
// https://isocpp.org/wiki/faq/templates#separate-template-fn-defn-from-decl
|
||||
template class CListModelBase<BlackMisc::Weather::CCloudLayer, BlackMisc::Weather::CCloudLayerList, false>;
|
||||
template class CListModelBase<BlackMisc::Weather::CTemperatureLayer, BlackMisc::Weather::CTemperatureLayerList, false>;
|
||||
template class CListModelBase<BlackMisc::Weather::CWindLayer, BlackMisc::Weather::CWindLayerList, false>;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user