mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-07 11:05:33 +08:00
refs #368, filter for views
This commit is contained in:
@@ -34,6 +34,8 @@ SOURCES += $$PWD/components/*.cpp
|
||||
|
||||
FORMS += $$PWD/components/*.ui
|
||||
FORMS += $$PWD/*.ui
|
||||
FORMS += $$PWD/views/*.ui
|
||||
|
||||
|
||||
win32 {
|
||||
HEADERS += $$PWD/win/*.h
|
||||
|
||||
50
src/blackgui/models/aircraftmodelfilter.cpp
Normal file
50
src/blackgui/models/aircraftmodelfilter.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/* Copyright (C) 2013
|
||||
* 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 "aircraftmodelfilter.h"
|
||||
#include "blackmisc/simulation/aircraftmodel.h"
|
||||
|
||||
using namespace BlackMisc::Simulation;
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Models
|
||||
{
|
||||
|
||||
CAircraftModelFilter::CAircraftModelFilter(const QString &modelString, const QString &description) :
|
||||
m_model(modelString.trimmed()), m_description(description.trimmed())
|
||||
{ }
|
||||
|
||||
BlackMisc::Simulation::CAircraftModelList CAircraftModelFilter::filter(const CAircraftModelList &inContainer) const
|
||||
{
|
||||
if (!this->isValid()) { return inContainer; }
|
||||
CAircraftModelList outContainer;
|
||||
for (const CAircraftModel &model : inContainer)
|
||||
{
|
||||
if (!this->m_model.isEmpty())
|
||||
{
|
||||
if (!this->stringMatchesFilterExpression(model.getModelString(), this->m_model)) { continue; }
|
||||
}
|
||||
|
||||
if (!this->m_description.isEmpty())
|
||||
{
|
||||
if (!this->stringMatchesFilterExpression(model.getDescription(), this->m_description)) { continue; }
|
||||
}
|
||||
outContainer.push_back(model);
|
||||
}
|
||||
return outContainer;
|
||||
}
|
||||
|
||||
bool CAircraftModelFilter::isValid() const
|
||||
{
|
||||
return !(this->m_model.isEmpty() && this->m_description.isEmpty());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
46
src/blackgui/models/aircraftmodelfilter.h
Normal file
46
src/blackgui/models/aircraftmodelfilter.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* Copyright (C) 2013
|
||||
* 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_AIRCRAFTMODELFILTER_H
|
||||
#define BLACKGUI_AIRCRAFTMODELFILTER_H
|
||||
|
||||
#include "listmodelfilter.h"
|
||||
#include "blackmisc/simulation/aircraftmodellist.h"
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Models
|
||||
{
|
||||
|
||||
//! Filter for aircraft models
|
||||
class CAircraftModelFilter : public IModelFilter<BlackMisc::Simulation::CAircraftModelList>
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
CAircraftModelFilter(const QString &modelString, const QString &description);
|
||||
|
||||
//! \copydoc IModelFilter::filter
|
||||
virtual BlackMisc::Simulation::CAircraftModelList filter(const BlackMisc::Simulation::CAircraftModelList &inContainer) const override;
|
||||
|
||||
//! \copydoc IModelFilter::isValid
|
||||
virtual bool isValid() const override;
|
||||
|
||||
private:
|
||||
QString m_model;
|
||||
QString m_description;
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
|
||||
#endif // guard
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include "listmodelbase.h"
|
||||
#include "blackmisc/simulation/aircraftmodellist.h"
|
||||
#include "blackmisc/namevariantpairlist.h"
|
||||
#include "blackmisc/statusmessagelist.h"
|
||||
#include "blackmisc/avatcstationlist.h"
|
||||
@@ -16,11 +17,14 @@
|
||||
#include "blackmisc/nwserverlist.h"
|
||||
#include "blackmisc/nwuserlist.h"
|
||||
#include "blackmisc/nwclientlist.h"
|
||||
#include "blackmisc/nwaircraftmodellist.h"
|
||||
#include "blackmisc/nwaircraftmappinglist.h"
|
||||
#include "blackmisc/setkeyboardhotkeylist.h"
|
||||
#include "blackmisc/simulation/simulatedaircraftlist.h"
|
||||
#include "blackmisc/variant.h"
|
||||
#include "blackmisc/blackmiscfreefunctions.h"
|
||||
|
||||
using namespace BlackMisc;
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Models
|
||||
@@ -28,8 +32,9 @@ namespace BlackGui
|
||||
/*
|
||||
* Column count
|
||||
*/
|
||||
int CListModelBaseNonTemplate::columnCount(const QModelIndex & /** modelIndex **/) const
|
||||
int CListModelBaseNonTemplate::columnCount(const QModelIndex &modelIndex) const
|
||||
{
|
||||
Q_UNUSED(modelIndex);
|
||||
int c = this->m_columns.size();
|
||||
return c;
|
||||
}
|
||||
@@ -39,20 +44,20 @@ namespace BlackGui
|
||||
*/
|
||||
QVariant CListModelBaseNonTemplate::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal)
|
||||
if (orientation != Qt::Horizontal) { return QVariant(); }
|
||||
bool handled = (role == Qt::DisplayRole || role == Qt::ToolTipRole || role == Qt::InitialSortOrderRole);
|
||||
if (!handled) {return QVariant();}
|
||||
if (section < 0 || section >= this->m_columns.size()) { return QVariant(); }
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
if (section < 0 || section >= this->m_columns.size()) { return QVariant(); }
|
||||
QString header = this->m_columns.at(section).getColumnName(false);
|
||||
return QVariant(header);
|
||||
}
|
||||
else if (role == Qt::ToolTipRole)
|
||||
{
|
||||
if (section < 0 || section >= this->m_columns.size()) { return QVariant(); }
|
||||
QString header = this->m_columns.at(section).getColumnToolTip(false);
|
||||
return header.isEmpty() ? QVariant() : QVariant(header);
|
||||
}
|
||||
QString header = this->m_columns.at(section).getColumnName(false);
|
||||
return QVariant(header);
|
||||
}
|
||||
else if (role == Qt::ToolTipRole)
|
||||
{
|
||||
QString header = this->m_columns.at(section).getColumnToolTip(false);
|
||||
return header.isEmpty() ? QVariant() : QVariant(header);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
@@ -65,33 +70,83 @@ namespace BlackGui
|
||||
return this->m_columns.columnToPropertyIndex(column);
|
||||
}
|
||||
|
||||
/*
|
||||
* To column
|
||||
*/
|
||||
int CListModelBaseNonTemplate::propertyIndexToColumn(const CPropertyIndex &propertyIndex) const
|
||||
{
|
||||
return m_columns.propertyIndexToColumn(propertyIndex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Property index
|
||||
*/
|
||||
BlackMisc::CPropertyIndex CListModelBaseNonTemplate::modelIndexToPropertyIndex(const QModelIndex &index) const
|
||||
{
|
||||
return this->columnToPropertyIndex(index.column());
|
||||
}
|
||||
|
||||
/*
|
||||
* Sort column
|
||||
*/
|
||||
void CListModelBaseNonTemplate::setSortColumnByPropertyIndex(const BlackMisc::CPropertyIndex &propertyIndex)
|
||||
{
|
||||
this->m_sortedColumn = this->m_columns.propertyIndexToColumn(propertyIndex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sort column?
|
||||
*/
|
||||
bool CListModelBaseNonTemplate::hasValidSortColumn() const
|
||||
{
|
||||
return this->m_sortedColumn >= 0 && this->m_sortedColumn < this->m_columns.size();
|
||||
|
||||
if (!(this->m_sortedColumn >= 0 && this->m_sortedColumn < this->m_columns.size())) { return false; }
|
||||
return this->m_columns.isSortable(this->m_sortedColumn);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make editable
|
||||
* Flags
|
||||
*/
|
||||
Qt::ItemFlags CListModelBaseNonTemplate::flags(const QModelIndex &index) const
|
||||
{
|
||||
Qt::ItemFlags f = QAbstractListModel::flags(index);
|
||||
if (this->m_columns.isEditable(index))
|
||||
return f | Qt::ItemIsEditable;
|
||||
else
|
||||
return f;
|
||||
if (!index.isValid()) { return f; }
|
||||
bool editable = this->m_columns.isEditable(index);
|
||||
f = editable ? (f | Qt::ItemIsEditable) : (f ^ Qt::ItemIsEditable);
|
||||
const CDefaultFormatter *formatter = this->m_columns.getFormatter(index);
|
||||
if (formatter)
|
||||
{
|
||||
return formatter->flags(f, editable);
|
||||
}
|
||||
|
||||
// fallback behaviour with no formatter
|
||||
return f;
|
||||
}
|
||||
|
||||
/*
|
||||
* Translation context
|
||||
*/
|
||||
const QString &CListModelBaseNonTemplate::getTranslationContext() const
|
||||
{
|
||||
return m_columns.getTranslationContext();
|
||||
}
|
||||
|
||||
/*
|
||||
* Update
|
||||
*/
|
||||
int CListModelBaseNonTemplate::ps_updateContainer(const CVariant &variant, bool sort)
|
||||
{
|
||||
return this->performUpdateContainer(variant, sort);
|
||||
}
|
||||
|
||||
/*
|
||||
* Row count
|
||||
*/
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
int CListModelBase<ObjectType, ContainerType>::rowCount(const QModelIndex & /** parent */) const
|
||||
int CListModelBase<ObjectType, ContainerType>::rowCount(const QModelIndex &parentIndex) const
|
||||
{
|
||||
return this->m_container.size();
|
||||
Q_UNUSED(parentIndex);
|
||||
return this->getContainerOrFilteredContainer().size();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -100,8 +155,8 @@ namespace BlackGui
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
bool CListModelBase<ObjectType, ContainerType>::isValidIndex(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid()) return false;
|
||||
return (index.row() >= 0 && index.row() < this->m_container.size() &&
|
||||
if (!index.isValid()) { return false; }
|
||||
return (index.row() >= 0 && index.row() < this->rowCount(index) &&
|
||||
index.column() >= 0 && index.column() < this->columnCount(index));
|
||||
}
|
||||
|
||||
@@ -109,7 +164,7 @@ namespace BlackGui
|
||||
* Data
|
||||
*/
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
QVariant CListModelBase<ObjectType, ContainerType>::data(const QModelIndex &index, int role) const
|
||||
QVariant CListModelBase<ObjectType, ContainerType>::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
// check / init
|
||||
if (!this->isValidIndex(index)) { return QVariant(); }
|
||||
@@ -118,11 +173,46 @@ namespace BlackGui
|
||||
if (!formatter) { return QVariant(); }
|
||||
|
||||
//! Formatted data
|
||||
ObjectType obj = this->m_container[index.row()];
|
||||
ObjectType obj = this->getContainerOrFilteredContainer()[index.row()];
|
||||
BlackMisc::CPropertyIndex propertyIndex = this->columnToPropertyIndex(index.column());
|
||||
return formatter->data(role, obj.propertyByIndex(propertyIndex)).toQVariant();
|
||||
}
|
||||
|
||||
/*
|
||||
* Set data
|
||||
*/
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
bool CListModelBase<ObjectType, ContainerType>::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
Qt::ItemDataRole dataRole = static_cast<Qt::ItemDataRole>(role);
|
||||
if (!(dataRole == Qt::UserRole || dataRole == Qt::EditRole)) { return false; }
|
||||
|
||||
// check / init
|
||||
if (!this->isValidIndex(index)) { return false; }
|
||||
if (!this->m_columns.isEditable(index)) { return false; }
|
||||
const CDefaultFormatter *formatter = this->m_columns.getFormatter(index);
|
||||
Q_ASSERT(formatter);
|
||||
if (!formatter) { return false; }
|
||||
|
||||
ObjectType obj = this->m_container[index.row()];
|
||||
ObjectType currentObject(obj);
|
||||
BlackMisc::CPropertyIndex propertyIndex = this->columnToPropertyIndex(index.column());
|
||||
obj.setPropertyByIndex(value, propertyIndex);
|
||||
|
||||
if (obj != currentObject)
|
||||
{
|
||||
QModelIndex topLeft = index.sibling(index.row(), 0);
|
||||
QModelIndex bottomRight = index.sibling(index.row(), this->columnCount() - 1);
|
||||
this->m_container[index.row()] = obj;
|
||||
const CVariant co = CVariant::from(obj);
|
||||
emit objectChanged(co, propertyIndex);
|
||||
emit dataChanged(topLeft, bottomRight);
|
||||
this->updateFilteredContainer();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update
|
||||
*/
|
||||
@@ -135,15 +225,17 @@ namespace BlackGui
|
||||
bool performSort = sort && container.size() > 1 && this->hasValidSortColumn();
|
||||
if (performSort)
|
||||
{
|
||||
sortedContainer = this->sortContainerByColumn(container, this->getSortColumn(), this->m_sortOrder);
|
||||
int sortColumn = this->getSortColumn();
|
||||
sortedContainer = this->sortContainerByColumn(container, sortColumn, this->m_sortOrder);
|
||||
}
|
||||
|
||||
this->beginResetModel();
|
||||
this->m_container = performSort ? sortedContainer : container;
|
||||
this->updateFilteredContainer();
|
||||
this->endResetModel();
|
||||
|
||||
int newSize = this->m_container.size();
|
||||
if (oldSize != newSize) { rowCountChanged(newSize); }
|
||||
if (oldSize != newSize) { this->emitRowCountChanged(); }
|
||||
return newSize;
|
||||
}
|
||||
|
||||
@@ -153,7 +245,7 @@ namespace BlackGui
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
void CListModelBase<ObjectType, ContainerType>::update(const QModelIndex &index, const ObjectType &object)
|
||||
{
|
||||
if (index.row() >= this->m_container.size()) return;
|
||||
if (index.row() >= this->m_container.size()) { return; }
|
||||
this->m_container[index.row()] = object;
|
||||
|
||||
QModelIndex i1 = index.sibling(index.row(), 0);
|
||||
@@ -161,6 +253,12 @@ namespace BlackGui
|
||||
emit this->dataChanged(i1, i2); // which range has been changed
|
||||
}
|
||||
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
void CListModelBase<ObjectType, ContainerType>::update(int rowIndex, const ObjectType &object)
|
||||
{
|
||||
this->update(this->index(rowIndex), object);
|
||||
}
|
||||
|
||||
/*
|
||||
* Async update
|
||||
*/
|
||||
@@ -172,8 +270,8 @@ namespace BlackGui
|
||||
BlackMisc::CWorker *worker = BlackMisc::CWorker::fromTask(this, "ModelSort", [this, container, sort, sortColumn, sortOrder]()
|
||||
{
|
||||
ContainerType sortedContainer = this->sortContainerByColumn(container, sortColumn, sortOrder);
|
||||
QMetaObject::invokeMethod(this, "updateContainer",
|
||||
Q_ARG(BlackMisc::CVariant, sortedContainer.toCVariant()), Q_ARG(bool, false));
|
||||
QMetaObject::invokeMethod(this, "ps_updateContainer",
|
||||
Q_ARG(BlackMisc::CVariant, sortedContainer.toCVariant()), Q_ARG(bool, false));
|
||||
});
|
||||
worker->then(this, &CListModelBase::asyncUpdateFinished);
|
||||
return worker;
|
||||
@@ -196,23 +294,76 @@ namespace BlackGui
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Filter
|
||||
*/
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
bool CListModelBase<ObjectType, ContainerType>::hasFilter() const
|
||||
{
|
||||
return m_filter ? true : false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove filter
|
||||
*/
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
void CListModelBase<ObjectType, ContainerType>::removeFilter()
|
||||
{
|
||||
if (!this->hasFilter()) { return; }
|
||||
this->m_filter.reset(nullptr);
|
||||
this->beginResetModel();
|
||||
this->updateFilteredContainer();
|
||||
this->endResetModel();
|
||||
this->emitRowCountChanged();
|
||||
}
|
||||
|
||||
/*
|
||||
* Set filter
|
||||
*/
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
void CListModelBase<ObjectType, ContainerType>::setFilter(std::unique_ptr<IModelFilter<ContainerType> > &filter)
|
||||
{
|
||||
if (!filter) { this->removeFilter(); return; } // empty filter
|
||||
if (filter->isValid())
|
||||
{
|
||||
this->m_filter = std::move(filter);
|
||||
this->beginResetModel();
|
||||
this->updateFilteredContainer();
|
||||
this->endResetModel();
|
||||
this->emitRowCountChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->removeFilter();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* At
|
||||
*/
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
const ObjectType &CListModelBase<ObjectType, ContainerType>::at(const QModelIndex &index) const
|
||||
{
|
||||
if (index.row() < 0 || index.row() >= this->m_container.size())
|
||||
if (index.row() < 0 || index.row() >= this->rowCount())
|
||||
{
|
||||
static const ObjectType def {}; // default object
|
||||
return def;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->m_container[index.row()];
|
||||
return this->getContainerOrFilteredContainer()[index.row()];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Container
|
||||
*/
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
const ContainerType &CListModelBase<ObjectType, ContainerType>::getContainer() const
|
||||
{
|
||||
return this->m_container;
|
||||
}
|
||||
|
||||
/*
|
||||
* Push back
|
||||
*/
|
||||
@@ -222,11 +373,12 @@ namespace BlackGui
|
||||
beginInsertRows(QModelIndex(), this->m_container.size(), this->m_container.size());
|
||||
this->m_container.push_back(object);
|
||||
endInsertRows();
|
||||
emit rowCountChanged(this->m_container.size());
|
||||
this->updateFilteredContainer();
|
||||
this->emitRowCountChanged();
|
||||
}
|
||||
|
||||
/*
|
||||
* Push back
|
||||
* insert
|
||||
*/
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
void CListModelBase<ObjectType, ContainerType>::insert(const ObjectType &object)
|
||||
@@ -234,8 +386,14 @@ namespace BlackGui
|
||||
beginInsertRows(QModelIndex(), 0, 0);
|
||||
this->m_container.insert(this->m_container.begin(), object);
|
||||
endInsertRows();
|
||||
int newSize = this->m_container.size();
|
||||
emit rowCountChanged(newSize);
|
||||
|
||||
if (this->hasFilter())
|
||||
{
|
||||
this->beginResetModel();
|
||||
this->updateFilteredContainer();
|
||||
this->endResetModel();
|
||||
}
|
||||
this->emitRowCountChanged();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -249,42 +407,81 @@ namespace BlackGui
|
||||
this->m_container.remove(object);
|
||||
endRemoveRows();
|
||||
int newSize = this->m_container.size();
|
||||
if (oldSize != newSize) { emit rowCountChanged(newSize); }
|
||||
if (oldSize != newSize)
|
||||
{
|
||||
this->emitRowCountChanged();
|
||||
if (this->hasFilter())
|
||||
{
|
||||
this->beginResetModel();
|
||||
this->updateFilteredContainer();
|
||||
this->endResetModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear
|
||||
*/
|
||||
template <typename ObjectType, typename ContainerType> void CListModelBase<ObjectType, ContainerType>::clear()
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
void CListModelBase<ObjectType, ContainerType>::clear()
|
||||
{
|
||||
int oldSize = this->m_container.size();
|
||||
beginResetModel();
|
||||
this->m_container.clear();
|
||||
this->m_containerFiltered.clear();
|
||||
endResetModel();
|
||||
if (oldSize > 0) { emit rowCountChanged(0);}
|
||||
this->emitRowCountChanged();
|
||||
}
|
||||
|
||||
/*
|
||||
* Update on container
|
||||
*/
|
||||
template <typename ObjectType, typename ContainerType> int CListModelBase<ObjectType, ContainerType>::performUpdateContainer(const BlackMisc::CVariant &variant, bool sort)
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
int CListModelBase<ObjectType, ContainerType>::performUpdateContainer(const BlackMisc::CVariant &variant, bool sort)
|
||||
{
|
||||
ContainerType c;
|
||||
c.convertFromCVariant(variant);
|
||||
return this->update(c, sort);
|
||||
}
|
||||
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
const ContainerType &CListModelBase<ObjectType, ContainerType>::getContainerOrFilteredContainer() const
|
||||
{
|
||||
if (!this->hasFilter()) { return this->m_container; }
|
||||
return m_containerFiltered;
|
||||
}
|
||||
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
void CListModelBase<ObjectType, ContainerType>::updateFilteredContainer()
|
||||
{
|
||||
if (this->hasFilter())
|
||||
{
|
||||
this->m_containerFiltered = this->m_filter->filter(this->m_container);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_containerFiltered.clear();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
void CListModelBase<ObjectType, ContainerType>::emitRowCountChanged()
|
||||
{
|
||||
int n = this->getContainerOrFilteredContainer().size();
|
||||
emit this->rowCountChanged(n, this->hasFilter());
|
||||
}
|
||||
|
||||
/*
|
||||
* Sort requested by abstract model
|
||||
*/
|
||||
template <typename ObjectType, typename ContainerType> void CListModelBase<ObjectType, ContainerType>::sort(int column, Qt::SortOrder order)
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
void CListModelBase<ObjectType, ContainerType>::sort(int column, Qt::SortOrder order)
|
||||
{
|
||||
if (column == this->m_sortedColumn && order == this->m_sortOrder) { return; }
|
||||
|
||||
// new order
|
||||
this->m_sortedColumn = column;
|
||||
this->m_sortOrder = order;
|
||||
if (this->m_container.size() < 2) return; // nothing to do
|
||||
if (this->m_container.size() < 2) { return; } // nothing to do
|
||||
|
||||
// sort the values
|
||||
this->updateContainerMaybeAsync(this->m_container, true);
|
||||
@@ -293,14 +490,15 @@ namespace BlackGui
|
||||
/*
|
||||
* Sort list
|
||||
*/
|
||||
template <typename ObjectType, typename ContainerType> ContainerType CListModelBase<ObjectType, ContainerType>::sortContainerByColumn(const ContainerType &container, int column, Qt::SortOrder order) const
|
||||
template <typename ObjectType, typename ContainerType>
|
||||
ContainerType CListModelBase<ObjectType, ContainerType>::sortContainerByColumn(const ContainerType &container, int column, Qt::SortOrder order) const
|
||||
{
|
||||
if (container.size() < 2) return container; // nothing to do
|
||||
if (container.size() < 2 || !this->m_columns.isSortable(column)) { return container; } // nothing to do
|
||||
|
||||
// this is the only part not really thread safe, but columns do not change so far
|
||||
BlackMisc::CPropertyIndex propertyIndex = this->m_columns.columnToPropertyIndex(column);
|
||||
BlackMisc::CPropertyIndex propertyIndex = this->m_columns.columnToSortPropertyIndex(column);
|
||||
Q_ASSERT(!propertyIndex.isEmpty());
|
||||
if (propertyIndex.isEmpty()) return container; // at release build do nothing
|
||||
if (propertyIndex.isEmpty()) { return container; } // at release build do nothing
|
||||
|
||||
// sort the values
|
||||
const auto p = [ = ](const ObjectType & a, const ObjectType & b) -> bool
|
||||
@@ -310,11 +508,7 @@ namespace BlackGui
|
||||
return (order == Qt::AscendingOrder) ? (aQv < bQv) : (bQv < aQv);
|
||||
};
|
||||
|
||||
// KWB: qDebug() will be removed soon
|
||||
QTime t;
|
||||
t.start();
|
||||
const ContainerType sorted = container.sorted(p);
|
||||
qDebug() << "Sort" << this->objectName() << "column" << column << "index:" << propertyIndex.toQString() << "ms:" << t.elapsed() << "thread:" << QThread::currentThreadId();
|
||||
return sorted;
|
||||
}
|
||||
|
||||
@@ -328,8 +522,9 @@ namespace BlackGui
|
||||
template class CListModelBase<BlackMisc::Network::CServer, BlackMisc::Network::CServerList>;
|
||||
template class CListModelBase<BlackMisc::Network::CUser, BlackMisc::Network::CUserList>;
|
||||
template class CListModelBase<BlackMisc::Network::CClient, BlackMisc::Network::CClientList>;
|
||||
template class CListModelBase<BlackMisc::Network::CAircraftModel, BlackMisc::Network::CAircraftModelList>;
|
||||
template class CListModelBase<BlackMisc::Simulation::CAircraftModel, BlackMisc::Simulation::CAircraftModelList>;
|
||||
template class CListModelBase<BlackMisc::Network::CAircraftMapping, BlackMisc::Network::CAircraftMappingList>;
|
||||
template class CListModelBase<BlackMisc::Simulation::CSimulatedAircraft, BlackMisc::Simulation::CSimulatedAircraftList>;
|
||||
template class CListModelBase<BlackMisc::Settings::CSettingKeyboardHotkey, BlackMisc::Settings::CSettingKeyboardHotkeyList>;
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -13,10 +13,13 @@
|
||||
#define BLACKGUI_LISTMODELBASE_H
|
||||
|
||||
#include "blackgui/models/columns.h"
|
||||
#include "blackgui/models/listmodelfilter.h"
|
||||
#include "blackmisc/worker.h"
|
||||
#include "blackmisc/propertyindex.h"
|
||||
#include <QAbstractItemModel>
|
||||
#include <QThread>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
@@ -35,7 +38,7 @@ namespace BlackGui
|
||||
virtual ~CListModelBaseNonTemplate() {}
|
||||
|
||||
//! \copydoc QAbstractListModel::columnCount()
|
||||
virtual int columnCount(const QModelIndex &modelIndex) const override;
|
||||
virtual int columnCount(const QModelIndex &modelIndex = QModelIndex()) const override;
|
||||
|
||||
//! \copydoc QAbstractItemModel::headerData()
|
||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
@@ -43,11 +46,11 @@ namespace BlackGui
|
||||
//! 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
|
||||
{
|
||||
return this->columnToPropertyIndex(index.column());
|
||||
}
|
||||
virtual BlackMisc::CPropertyIndex modelIndexToPropertyIndex(const QModelIndex &index) const;
|
||||
|
||||
//! Set sort column
|
||||
virtual void setSortColumn(int column) { this->m_sortedColumn = column; }
|
||||
@@ -56,10 +59,7 @@ namespace BlackGui
|
||||
* Set column for sorting
|
||||
* \param propertyIndex index of column to be sorted
|
||||
*/
|
||||
virtual void setSortColumnByPropertyIndex(const BlackMisc::CPropertyIndex &propertyIndex)
|
||||
{
|
||||
this->m_sortedColumn = this->m_columns.propertyIndexToColumn(propertyIndex);
|
||||
}
|
||||
virtual void setSortColumnByPropertyIndex(const BlackMisc::CPropertyIndex &propertyIndex);
|
||||
|
||||
//! Get sort column property index
|
||||
virtual int getSortColumn() const { return this->m_sortedColumn; }
|
||||
@@ -74,26 +74,23 @@ namespace BlackGui
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
|
||||
//! Translation context
|
||||
virtual const QString &getTranslationContext() const
|
||||
{
|
||||
return m_columns.getTranslationContext();
|
||||
}
|
||||
virtual const QString &getTranslationContext() const;
|
||||
|
||||
signals:
|
||||
//! Asynchronous update finished
|
||||
void asyncUpdateFinished();
|
||||
|
||||
//! Number of elements changed
|
||||
void rowCountChanged(int count);
|
||||
void rowCountChanged(int count, bool withFilter);
|
||||
|
||||
//! Template free information, that object changed
|
||||
void objectChanged(const BlackMisc::CVariant &object, const BlackMisc::CPropertyIndex &changedIndex);
|
||||
|
||||
protected slots:
|
||||
//! Helper method with template free signature
|
||||
//! \param variant container is transferred in variant
|
||||
//! \param sort
|
||||
int updateContainer(const BlackMisc::CVariant &variant, bool sort)
|
||||
{
|
||||
return this->performUpdateContainer(variant, sort);
|
||||
}
|
||||
int ps_updateContainer(const BlackMisc::CVariant &variant, bool sort);
|
||||
|
||||
protected:
|
||||
/*!
|
||||
@@ -117,8 +114,7 @@ namespace BlackGui
|
||||
};
|
||||
|
||||
//! List model
|
||||
template <typename ObjectType, typename ContainerType> class CListModelBase :
|
||||
public CListModelBaseNonTemplate
|
||||
template <typename ObjectType, typename ContainerType> class CListModelBase : public CListModelBaseNonTemplate
|
||||
{
|
||||
|
||||
public:
|
||||
@@ -129,13 +125,17 @@ namespace BlackGui
|
||||
virtual bool isValidIndex(const QModelIndex &index) const;
|
||||
|
||||
//! Used container data
|
||||
virtual const ContainerType &getContainer() const { return this->m_container; }
|
||||
virtual const ContainerType &getContainer() const;
|
||||
|
||||
//! \copydoc QAbstractListModel::data()
|
||||
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
//! \copydoc QAbstractListModel::setData()
|
||||
//! \sa CListModelBaseNonTemplate::flags
|
||||
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
//! \copydoc QAbstractListModel::rowCount()
|
||||
virtual int rowCount(const QModelIndex &index = QModelIndex()) const override;
|
||||
virtual int rowCount(const QModelIndex &parentIndex = QModelIndex()) const override;
|
||||
|
||||
//! Update by new container
|
||||
//! \remarks a sorting is performed only if a valid sort column is set
|
||||
@@ -151,10 +151,7 @@ namespace BlackGui
|
||||
virtual void update(const QModelIndex &index, const ObjectType &object);
|
||||
|
||||
//! Update single element
|
||||
virtual void update(int rowIndex, const ObjectType &object)
|
||||
{
|
||||
this->update(this->index(rowIndex), object);
|
||||
}
|
||||
virtual void update(int rowIndex, const ObjectType &object);
|
||||
|
||||
//! Object at row position
|
||||
virtual const ObjectType &at(const QModelIndex &index) const;
|
||||
@@ -186,15 +183,25 @@ namespace BlackGui
|
||||
int removeIf(K0 k0, V0 v0, KeysValues... keysValues)
|
||||
{
|
||||
int c = m_container.removeIf(BlackMisc::Predicates::MemberEqual(k0, v0, keysValues...));
|
||||
if (c > 0) { emit rowCountChanged(this->rowCount());}
|
||||
if (c > 0) { this->emitRowCountChanged();}
|
||||
this->updateFilteredContainer();
|
||||
return c;
|
||||
}
|
||||
|
||||
//! Clear the list
|
||||
virtual void clear();
|
||||
|
||||
//! Filter available
|
||||
bool hasFilter() const;
|
||||
|
||||
//! Remove filter
|
||||
void removeFilter();
|
||||
|
||||
//! Set the filter
|
||||
void setFilter(std::unique_ptr<IModelFilter<ContainerType> > &filter);
|
||||
|
||||
protected:
|
||||
ContainerType m_container; //!< used container
|
||||
std::unique_ptr<IModelFilter<ContainerType> > m_filter; //!< Used filter
|
||||
|
||||
/*!
|
||||
* Constructor
|
||||
@@ -207,6 +214,18 @@ namespace BlackGui
|
||||
|
||||
//! \copydoc CModelBaseNonTemplate::performUpdateContainer
|
||||
virtual int performUpdateContainer(const BlackMisc::CVariant &variant, bool sort) override;
|
||||
|
||||
//! Full container or cached filtered container as approproiate
|
||||
const ContainerType &getContainerOrFilteredContainer() const;
|
||||
|
||||
//! Update filtered container
|
||||
void updateFilteredContainer();
|
||||
|
||||
//! Row count changed
|
||||
void emitRowCountChanged();
|
||||
ContainerType m_container; //!< used container
|
||||
ContainerType m_containerFiltered; //!< cache for filtered container data
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
68
src/blackgui/models/listmodelfilter.cpp
Normal file
68
src/blackgui/models/listmodelfilter.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/* Copyright (C) 2015
|
||||
* 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 "listmodelfilter.h"
|
||||
#include "blackmisc/simulation/aircraftmodellist.h"
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Models
|
||||
{
|
||||
template<class ContainerType>
|
||||
bool IModelFilter<ContainerType>::stringMatchesFilterExpression(const QString &value, const QString &filter, Qt::CaseSensitivity cs) const
|
||||
{
|
||||
QString v = value.trimmed();
|
||||
QString f = filter.trimmed();
|
||||
|
||||
if (v.isEmpty() && f.isEmpty()) { return true; }
|
||||
if (v.isEmpty()) { return false; }
|
||||
|
||||
// no wildcard, just string matching
|
||||
if (!filter.contains('*'))
|
||||
{
|
||||
return (v.indexOf(f, 0, cs) == 0) &&
|
||||
(v.length() == f.length());
|
||||
}
|
||||
|
||||
const QString filterNoWildcard = stripWildcard(f);
|
||||
|
||||
// included?
|
||||
if (f.startsWith('*') && f.endsWith('*'))
|
||||
{
|
||||
return v.contains(filterNoWildcard, cs);
|
||||
}
|
||||
|
||||
// starting with
|
||||
if (f.startsWith('*'))
|
||||
{
|
||||
return v.endsWith(filterNoWildcard, cs);
|
||||
}
|
||||
|
||||
if (f.endsWith('*'))
|
||||
{
|
||||
return v.startsWith(filterNoWildcard, cs);
|
||||
}
|
||||
|
||||
// should never happen
|
||||
Q_ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class ContainerType>
|
||||
QString IModelFilter<ContainerType>::stripWildcard(const QString &value) const
|
||||
{
|
||||
QString sw(value);
|
||||
return sw.remove('*');
|
||||
}
|
||||
|
||||
// Forward instantiations
|
||||
template class IModelFilter<BlackMisc::Simulation::CAircraftModelList>;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
47
src/blackgui/models/listmodelfilter.h
Normal file
47
src/blackgui/models/listmodelfilter.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* Copyright (C) 2015
|
||||
* 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_LISTMODELFILTER_H
|
||||
#define BLACKGUI_LISTMODELFILTER_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Models
|
||||
{
|
||||
//! Model filter interface
|
||||
template<class ContainerType> class IModelFilter
|
||||
{
|
||||
|
||||
public:
|
||||
//! Destructor
|
||||
virtual ~IModelFilter() {}
|
||||
|
||||
//! Used container data
|
||||
virtual ContainerType filter(const ContainerType &container) const = 0;
|
||||
|
||||
//! Anything to do?
|
||||
virtual bool isValid() const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
//! Standard string search supporting wildcard at begin and end: "*xyz", "abc*"
|
||||
bool stringMatchesFilterExpression(const QString &value, const QString &filter, Qt::CaseSensitivity cs = Qt::CaseInsensitive) const;
|
||||
|
||||
//! Remove the * wildcards
|
||||
QString stripWildcard(const QString &value) const;
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
#endif // guard
|
||||
13
src/blackgui/qss/filterdialog.qss
Normal file
13
src/blackgui/qss/filterdialog.qss
Normal file
@@ -0,0 +1,13 @@
|
||||
QDialog {
|
||||
background: black; /** background is background color here **/
|
||||
background-image: url(:/textures/icons/textures/texture-inner.jpg);
|
||||
}
|
||||
|
||||
QPushButton {
|
||||
background-color: rgba(0, 0, 255, 128);
|
||||
border-style: none;
|
||||
border-radius:3px;
|
||||
color: yellow;
|
||||
padding: 3px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
@@ -233,4 +233,13 @@ namespace BlackGui
|
||||
QPainter p(usedWidget);
|
||||
usedWidget->style()->drawPrimitive(element, &opt, &p, usedWidget);
|
||||
}
|
||||
|
||||
QString CStyleSheetUtility::styleForIconCheckBox(const QString &checkedIcon, const QString &uncheckedIcon, const QString &width, const QString &height)
|
||||
{
|
||||
Q_ASSERT(!checkedIcon.isEmpty());
|
||||
Q_ASSERT(!uncheckedIcon.isEmpty());
|
||||
|
||||
static const QString st = "QCheckBox::indicator { width: %1; height: %2; } QCheckBox::indicator:checked { image: url(%3); } QCheckBox::indicator:unchecked { image: url(%4); }";
|
||||
return st.arg(width).arg(height).arg(checkedIcon).arg(uncheckedIcon);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,14 @@ namespace BlackGui
|
||||
return f;
|
||||
}
|
||||
|
||||
//! File name maininfoarea.qss
|
||||
static const QString &fileNameFilterDialog()
|
||||
{
|
||||
static const QString f("filterdialog.qss");
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
//! Font weights
|
||||
static const QStringList &fontWeights()
|
||||
{
|
||||
@@ -133,6 +141,9 @@ namespace BlackGui
|
||||
//! \sa QWidget::paintEvent
|
||||
static void useStyleSheetInDerivedWidget(QWidget *derivedWidget, QStyle::PrimitiveElement element = QStyle::PE_Widget);
|
||||
|
||||
//! Stylesheet string for a checkbox displayed as 2 icons
|
||||
static QString styleForIconCheckBox(const QString &checkedIcon, const QString &uncheckedIcon, const QString &width = "16px", const QString &height = "16px");
|
||||
|
||||
signals:
|
||||
//! Sheets have been changed
|
||||
void styleSheetsChanged();
|
||||
|
||||
39
src/blackgui/views/aircraftmodelfilterform.cpp
Normal file
39
src/blackgui/views/aircraftmodelfilterform.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/* Copyright (C) 2013
|
||||
* 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 "aircraftmodelfilterform.h"
|
||||
#include "ui_aircraftmodelfilterform.h"
|
||||
|
||||
using namespace BlackGui::Models;
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Views
|
||||
{
|
||||
|
||||
CAircraftModelFilterForm::CAircraftModelFilterForm(QWidget *parent) :
|
||||
CFilterDialog(parent),
|
||||
ui(new Ui::CAircraftModelFilterForm)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->setWindowTitle("Filter models");
|
||||
}
|
||||
|
||||
CAircraftModelFilterForm::~CAircraftModelFilterForm()
|
||||
{ }
|
||||
|
||||
std::unique_ptr<CAircraftModelFilter> CAircraftModelFilterForm::getFilter() const
|
||||
{
|
||||
QString model(this->ui->le_ModelString->text());
|
||||
QString desc(this->ui->le_ModelDescription->text());
|
||||
return std::unique_ptr<CAircraftModelFilter>(new CAircraftModelFilter(model, desc));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
50
src/blackgui/views/aircraftmodelfilterform.h
Normal file
50
src/blackgui/views/aircraftmodelfilterform.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* Copyright (C) 2013
|
||||
* 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_AIRCRAFTMODELFILTERFORM_H
|
||||
#define BLACKGUI_AIRCRAFTMODELFILTERFORM_H
|
||||
|
||||
#include "filterdialog.h"
|
||||
#include "blackgui/models/aircraftmodelfilter.h"
|
||||
#include <QDialog>
|
||||
#include <QScopedPointer>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
namespace Ui { class CAircraftModelFilterForm; }
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Views
|
||||
{
|
||||
//! Form for a aircraft model filter
|
||||
class CAircraftModelFilterForm : public CFilterDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
explicit CAircraftModelFilterForm(QWidget *parent = nullptr);
|
||||
|
||||
//! Destructor
|
||||
~CAircraftModelFilterForm();
|
||||
|
||||
//! Get created filter
|
||||
std::unique_ptr<BlackGui::Models::CAircraftModelFilter> getFilter() const;
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::CAircraftModelFilterForm> ui;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
#endif // guard
|
||||
91
src/blackgui/views/aircraftmodelfilterform.ui
Normal file
91
src/blackgui/views/aircraftmodelfilterform.ui
Normal file
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CAircraftModelFilterForm</class>
|
||||
<widget class="QDialog" name="CAircraftModelFilterForm">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>336</width>
|
||||
<height>95</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="vl_AircraftModelFilterForm">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="fl_FilterLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbl_ModelString">
|
||||
<property name="text">
|
||||
<string>Model</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="le_ModelString"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbl_ModelDescription">
|
||||
<property name="text">
|
||||
<string>Description</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="le_ModelDescription"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="bb_ButtonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>bb_ButtonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>CAircraftModelFilterForm</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>bb_ButtonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>CAircraftModelFilterForm</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -8,9 +8,13 @@
|
||||
*/
|
||||
|
||||
#include "aircraftmodelview.h"
|
||||
#include "aircraftmodelfilterform.h"
|
||||
#include <QHeaderView>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::Simulation;
|
||||
using namespace BlackGui::Models;
|
||||
|
||||
namespace BlackGui
|
||||
@@ -22,11 +26,31 @@ namespace BlackGui
|
||||
this->m_withMenuItemClear = true;
|
||||
this->m_withMenuItemRefresh = true;
|
||||
this->standardInit(new CAircraftModelListModel(CAircraftModelListModel::ModelOnly, this));
|
||||
|
||||
// filter
|
||||
QWidget *mainWindow = this->mainApplicationWindowWidget();
|
||||
Q_ASSERT(mainWindow);
|
||||
this->setFilterDialog(new CAircraftModelFilterForm(mainWindow));
|
||||
}
|
||||
|
||||
void CAircraftModelView::setAircraftModelMode(CAircraftModelListModel::AircraftModelMode mode)
|
||||
{
|
||||
this->m_model->setAircraftModelMode(mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CAircraftModelView::ps_filterDialogFinished(int status)
|
||||
{
|
||||
if (CViewBase::ps_filterDialogFinished(status)) { return true; }
|
||||
if (!this->m_filterDialog) { this->derivedModel()->removeFilter(); return true; }
|
||||
std::unique_ptr<IModelFilter<CAircraftModelList>> filter(this->getFilterForm()->getFilter());
|
||||
this->derivedModel()->setFilter(filter);
|
||||
return true;
|
||||
}
|
||||
|
||||
CAircraftModelFilterForm *CAircraftModelView::getFilterForm() const
|
||||
{
|
||||
return static_cast<CAircraftModelFilterForm *>(this->m_filterDialog.data());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#ifndef BLACKGUI_AIRCRAFTMODELVIEW_H
|
||||
#define BLACKGUI_AIRCRAFTMODELVIEW_H
|
||||
|
||||
#include "aircraftmodelfilterform.h"
|
||||
#include "viewbase.h"
|
||||
#include "../models/aircraftmodellistmodel.h"
|
||||
|
||||
@@ -20,7 +21,7 @@ namespace BlackGui
|
||||
namespace Views
|
||||
{
|
||||
//! Aircrafts view
|
||||
class CAircraftModelView : public CViewBase<Models::CAircraftModelListModel, BlackMisc::Network::CAircraftModelList, BlackMisc::Network::CAircraftModel>
|
||||
class CAircraftModelView : public CViewBase<Models::CAircraftModelListModel, BlackMisc::Simulation::CAircraftModelList, BlackMisc::Simulation::CAircraftModel>
|
||||
{
|
||||
|
||||
public:
|
||||
@@ -31,6 +32,13 @@ namespace BlackGui
|
||||
//! Set display mode
|
||||
void setAircraftModelMode(Models::CAircraftModelListModel::AircraftModelMode mode);
|
||||
|
||||
protected slots:
|
||||
//! \copydoc CViewBaseNonTemplate::ps_filterDialogFinished
|
||||
virtual bool ps_filterDialogFinished(int status) override;
|
||||
|
||||
private:
|
||||
//! Filter form
|
||||
CAircraftModelFilterForm *getFilterForm() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
37
src/blackgui/views/filterdialog.cpp
Normal file
37
src/blackgui/views/filterdialog.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/* Copyright (C) 2013
|
||||
* 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 "filterdialog.h"
|
||||
#include "blackgui/stylesheetutility.h"
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Views
|
||||
{
|
||||
|
||||
CFilterDialog::CFilterDialog(QWidget *parent) : QDialog(parent, Qt::Tool)
|
||||
{
|
||||
this->setWindowTitle("Filter dialog");
|
||||
ps_onStyleSheetChanged();
|
||||
connect(&CStyleSheetUtility::instance(), &CStyleSheetUtility::styleSheetsChanged, this, &CFilterDialog::ps_onStyleSheetChanged);
|
||||
}
|
||||
|
||||
CFilterDialog::~CFilterDialog()
|
||||
{ }
|
||||
|
||||
void CFilterDialog::ps_onStyleSheetChanged()
|
||||
{
|
||||
const QString qss = CStyleSheetUtility::instance().style(CStyleSheetUtility::fileNameFilterDialog());
|
||||
this->setStyleSheet(qss);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
|
||||
39
src/blackgui/views/filterdialog.h
Normal file
39
src/blackgui/views/filterdialog.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* Copyright (C) 2013
|
||||
* 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_FILTERDIALOG_H
|
||||
#define BLACKGUI_FILTERDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Views
|
||||
{
|
||||
//! Base for filter dialog
|
||||
class CFilterDialog : public QDialog
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
CFilterDialog(QWidget *parent = nullptr);
|
||||
|
||||
//! Destructor
|
||||
virtual ~CFilterDialog();
|
||||
|
||||
private slots:
|
||||
//! Stylesheet changed
|
||||
void ps_onStyleSheetChanged();
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
#endif // guard
|
||||
@@ -18,14 +18,19 @@
|
||||
#include "../models/serverlistmodel.h"
|
||||
#include "../models/userlistmodel.h"
|
||||
#include "../models/clientlistmodel.h"
|
||||
#include "../models/simulatedaircraftlistmodel.h"
|
||||
#include "../models/keyboardkeylistmodel.h"
|
||||
#include "../guiutility.h"
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QModelIndex>
|
||||
#include <QTime>
|
||||
#include <QAction>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QDialog>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackGui;
|
||||
using namespace BlackGui::Models;
|
||||
|
||||
namespace BlackGui
|
||||
@@ -48,10 +53,36 @@ namespace BlackGui
|
||||
this->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
}
|
||||
|
||||
void CViewBaseNonTemplate::setFilterDialog(QDialog *filterDialog)
|
||||
{
|
||||
if (filterDialog)
|
||||
{
|
||||
this->m_withMenuFilter = true;
|
||||
this->m_filterDialog.reset(filterDialog);
|
||||
connect(filterDialog, &QDialog::finished, this, &CViewBaseNonTemplate::ps_filterDialogFinished);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this->m_filterDialog.isNull()) { disconnect(this->m_filterDialog.data()); }
|
||||
this->m_withMenuFilter = false;
|
||||
this->m_filterDialog.reset(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
QWidget *CViewBaseNonTemplate::mainApplicationWindowWidget() const
|
||||
{
|
||||
return CGuiUtility::mainApplicationWindowWidget();
|
||||
}
|
||||
|
||||
void CViewBaseNonTemplate::customMenu(QMenu &menu) const
|
||||
{
|
||||
if (this->m_withMenuItemRefresh) { menu.addAction(BlackMisc::CIcons::refresh16(), "Update", this, SIGNAL(requestUpdate())); }
|
||||
if (this->m_withMenuItemClear) { menu.addAction(BlackMisc::CIcons::delete16(), "Clear", this, SLOT(ps_clear())); }
|
||||
if (this->m_withMenuFilter)
|
||||
{
|
||||
menu.addAction(BlackMisc::CIcons::tableSheet16(), "Filter", this, SLOT(ps_displayFilterDialog()));
|
||||
menu.addAction(BlackMisc::CIcons::tableSheet16(), "Remove Filter", this, SLOT(ps_removeFilter()));
|
||||
}
|
||||
if (!menu.isEmpty()) { menu.addSeparator(); }
|
||||
menu.addAction(BlackMisc::CIcons::resize16(), "Full resize", this, SLOT(fullResizeToContents()));
|
||||
|
||||
@@ -91,11 +122,23 @@ namespace BlackGui
|
||||
int fh = qRound(1.5 * this->getHorizontalHeaderFontHeight());
|
||||
this->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); // faster mode
|
||||
this->horizontalHeader()->setStretchLastSection(true);
|
||||
this->verticalHeader()->setDefaultSectionSize(fh);
|
||||
this->verticalHeader()->setMinimumSectionSize(fh);
|
||||
this->verticalHeader()->setDefaultSectionSize(fh); // for height
|
||||
this->verticalHeader()->setMinimumSectionSize(fh); // for height
|
||||
this->initRowsResizeModeToInteractive();
|
||||
}
|
||||
|
||||
int CViewBaseNonTemplate::ps_updateContainer(const CVariant &variant, bool sort, bool resize)
|
||||
{
|
||||
return this->performUpdateContainer(variant, sort, resize);
|
||||
}
|
||||
|
||||
void CViewBaseNonTemplate::ps_displayFilterDialog()
|
||||
{
|
||||
if (!this->m_withMenuFilter) { return; }
|
||||
if (!this->m_filterDialog) { return; }
|
||||
this->m_filterDialog->show();
|
||||
}
|
||||
|
||||
void CViewBaseNonTemplate::initRowsResizeModeToInteractive()
|
||||
{
|
||||
const int height = this->verticalHeader()->minimumSectionSize();
|
||||
@@ -116,8 +159,8 @@ namespace BlackGui
|
||||
if (m_resizeMode == ResizingOnce) { return m_resizeCount < 1; }
|
||||
if (m_resizeMode == ResizingAuto)
|
||||
{
|
||||
if (reachedResizeThreshold()) return false;
|
||||
if (m_resizeAutoNthTime < 2) return true;
|
||||
if (reachedResizeThreshold()) { return false; }
|
||||
if (m_resizeAutoNthTime < 2) { return true; }
|
||||
return (m_resizeCount % m_resizeAutoNthTime) == 0;
|
||||
}
|
||||
return false;
|
||||
@@ -125,10 +168,6 @@ namespace BlackGui
|
||||
|
||||
void CViewBaseNonTemplate::fullResizeToContents()
|
||||
{
|
||||
// KWB remove
|
||||
QTime t;
|
||||
t.start();
|
||||
|
||||
m_resizeCount++;
|
||||
this->resizeColumnsToContents();
|
||||
this->resizeRowsToContents();
|
||||
@@ -177,7 +216,7 @@ namespace BlackGui
|
||||
BlackMisc::CWorker *worker = BlackMisc::CWorker::fromTask(this, "ViewSort", [this, model, container, sort, resize, sortColumn, sortOrder]()
|
||||
{
|
||||
ContainerType sortedContainer = model->sortContainerByColumn(container, sortColumn, sortOrder);
|
||||
QMetaObject::invokeMethod(this, "updateContainer",
|
||||
QMetaObject::invokeMethod(this, "ps_updateContainer",
|
||||
Q_ARG(BlackMisc::CVariant, sortedContainer.toCVariant()), Q_ARG(bool, false), Q_ARG(bool, resize));
|
||||
});
|
||||
worker->then(this, &CViewBase::asyncUpdateFinished);
|
||||
@@ -197,6 +236,25 @@ namespace BlackGui
|
||||
}
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType> void CViewBase<ModelClass, ContainerType, ObjectType>::insert(const ObjectType &value, bool resize)
|
||||
{
|
||||
Q_ASSERT(this->m_model);
|
||||
this->m_model->insert(value);
|
||||
if (resize) { this->performResizeToContents(); }
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType> const ObjectType &CViewBase<ModelClass, ContainerType, ObjectType>::at(const QModelIndex &index) const
|
||||
{
|
||||
Q_ASSERT(this->m_model);
|
||||
return this->m_model->at(index);
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType> const ContainerType &CViewBase<ModelClass, ContainerType, ObjectType>::getContainer() const
|
||||
{
|
||||
Q_ASSERT(this->m_model);
|
||||
return this->m_model->getContainer();
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType> ContainerType CViewBase<ModelClass, ContainerType, ObjectType>::selectedObjects() const
|
||||
{
|
||||
if (!this->hasSelection()) { return ContainerType(); }
|
||||
@@ -209,25 +267,29 @@ namespace BlackGui
|
||||
return c;
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType> int CViewBase<ModelClass, ContainerType, ObjectType>::rowCount() const
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
int CViewBase<ModelClass, ContainerType, ObjectType>::rowCount() const
|
||||
{
|
||||
Q_ASSERT(this->m_model);
|
||||
return this->m_model->rowCount();
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType> int CViewBase<ModelClass, ContainerType, ObjectType>::columnCount() const
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
int CViewBase<ModelClass, ContainerType, ObjectType>::columnCount() const
|
||||
{
|
||||
Q_ASSERT(this->m_model);
|
||||
return this->m_model->columnCount(QModelIndex());
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType> bool CViewBase<ModelClass, ContainerType, ObjectType>::isEmpty() const
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
bool CViewBase<ModelClass, ContainerType, ObjectType>::isEmpty() const
|
||||
{
|
||||
Q_ASSERT(this->m_model);
|
||||
return this->m_model->rowCount() < 1;
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType> void CViewBase<ModelClass, ContainerType, ObjectType>::setObjectName(const QString &name)
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
void CViewBase<ModelClass, ContainerType, ObjectType>::setObjectName(const QString &name)
|
||||
{
|
||||
// then name here is mainly set for debugging purposes so each model can be identified
|
||||
Q_ASSERT(m_model);
|
||||
@@ -236,7 +298,8 @@ namespace BlackGui
|
||||
this->m_model->setObjectName(modelName);
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType> void CViewBase<ModelClass, ContainerType, ObjectType>::setSortIndicator()
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
void CViewBase<ModelClass, ContainerType, ObjectType>::setSortIndicator()
|
||||
{
|
||||
if (this->m_model->hasValidSortColumn())
|
||||
{
|
||||
@@ -247,20 +310,24 @@ namespace BlackGui
|
||||
}
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType> void CViewBase<ModelClass, ContainerType, ObjectType>::standardInit(ModelClass *model)
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
void CViewBase<ModelClass, ContainerType, ObjectType>::standardInit(ModelClass *model)
|
||||
{
|
||||
Q_ASSERT(model || this->m_model);
|
||||
if (model)
|
||||
{
|
||||
this->m_model = model;
|
||||
connect(this->m_model, &ModelClass::rowCountChanged, this, &CViewBase::countChanged);
|
||||
connect(this->m_model, &ModelClass::rowCountChanged, this, &CViewBase::rowCountChanged);
|
||||
connect(this->m_model, &ModelClass::objectChanged, this, &CViewBase::objectChanged);
|
||||
}
|
||||
|
||||
this->setModel(this->m_model); // via QTableView
|
||||
CViewBaseNonTemplate::init();
|
||||
this->setSortIndicator();
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType> void CViewBase<ModelClass, ContainerType, ObjectType>::performResizeToContents()
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
void CViewBase<ModelClass, ContainerType, ObjectType>::performResizeToContents()
|
||||
{
|
||||
// small set or large set?
|
||||
if (this->performResizing())
|
||||
@@ -273,13 +340,32 @@ namespace BlackGui
|
||||
}
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType> int CViewBase<ModelClass, ContainerType, ObjectType>::performUpdateContainer(const BlackMisc::CVariant &variant, bool sort, bool resize)
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
int CViewBase<ModelClass, ContainerType, ObjectType>::performUpdateContainer(const BlackMisc::CVariant &variant, bool sort, bool resize)
|
||||
{
|
||||
ContainerType c;
|
||||
c.convertFromCVariant(variant);
|
||||
return this->updateContainer(c, sort, resize);
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
bool CViewBase<ModelClass, ContainerType, ObjectType>::ps_filterDialogFinished(int status)
|
||||
{
|
||||
QDialog::DialogCode statusCode = static_cast<QDialog::DialogCode>(status);
|
||||
if (statusCode == QDialog::Rejected)
|
||||
{
|
||||
this->derivedModel()->removeFilter();
|
||||
return true; // handled
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class ModelClass, class ContainerType, class ObjectType>
|
||||
void CViewBase<ModelClass, ContainerType, ObjectType>::ps_removeFilter()
|
||||
{
|
||||
this->derivedModel()->removeFilter();
|
||||
}
|
||||
|
||||
// see here for the reason of thess forward instantiations
|
||||
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
|
||||
template class CViewBase<BlackGui::Models::CStatusMessageListModel, BlackMisc::CStatusMessageList, BlackMisc::CStatusMessage>;
|
||||
@@ -290,7 +376,8 @@ namespace BlackGui
|
||||
template class CViewBase<BlackGui::Models::CServerListModel, BlackMisc::Network::CServerList, BlackMisc::Network::CServer>;
|
||||
template class CViewBase<BlackGui::Models::CUserListModel, BlackMisc::Network::CUserList, BlackMisc::Network::CUser>;
|
||||
template class CViewBase<BlackGui::Models::CClientListModel, BlackMisc::Network::CClientList, BlackMisc::Network::CClient>;
|
||||
template class CViewBase<BlackGui::Models::CAircraftModelListModel, BlackMisc::Network::CAircraftModelList, BlackMisc::Network::CAircraftModel>;
|
||||
template class CViewBase<BlackGui::Models::CSimulatedAircraftListModel, BlackMisc::Simulation::CSimulatedAircraftList, BlackMisc::Simulation::CSimulatedAircraft>;
|
||||
template class CViewBase<BlackGui::Models::CAircraftModelListModel, BlackMisc::Simulation::CAircraftModelList, BlackMisc::Simulation::CAircraftModel>;
|
||||
template class CViewBase<BlackGui::Models::CKeyboardKeyListModel, BlackMisc::Settings::CSettingKeyboardHotkeyList, BlackMisc::Settings::CSettingKeyboardHotkey>;
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "blackmisc/worker.h"
|
||||
#include "blackmisc/variant.h"
|
||||
#include <QTableView>
|
||||
#include <QWizardPage>
|
||||
#include <QHeaderView>
|
||||
#include <QMenu>
|
||||
#include <QPoint>
|
||||
@@ -70,6 +71,12 @@ namespace BlackGui
|
||||
//! Selected rows if any
|
||||
QModelIndexList selectedRows() const;
|
||||
|
||||
//! Filter dialog
|
||||
void setFilterDialog(QDialog *filterDialog);
|
||||
|
||||
//! Main application window widget if any
|
||||
QWidget *mainApplicationWindowWidget() const;
|
||||
|
||||
signals:
|
||||
//! Ask for new data
|
||||
void requestUpdate();
|
||||
@@ -78,7 +85,10 @@ namespace BlackGui
|
||||
void asyncUpdateFinished();
|
||||
|
||||
//! Number of elements changed
|
||||
void countChanged(int count);
|
||||
void rowCountChanged(int count, bool withFilter);
|
||||
|
||||
//! Single object was changed in model
|
||||
void objectChanged(const BlackMisc::CVariant &object, const BlackMisc::CPropertyIndex &changedIndex);
|
||||
|
||||
public slots:
|
||||
//! Resize to contents, strategy depends on container size
|
||||
@@ -127,13 +137,21 @@ namespace BlackGui
|
||||
bool m_forceStretchLastColumnWhenResized = false; //!< a small table might (few columns) might to fail stretching, force again
|
||||
bool m_withMenuItemClear = false; //!< allow clearing the view via menu
|
||||
bool m_withMenuItemRefresh = false; //!< allow refreshing the view via menu
|
||||
bool m_withMenuFilter = false; //!< filter can be opened
|
||||
QScopedPointer<QDialog> m_filterDialog; //!< filter dialog if any
|
||||
|
||||
protected slots:
|
||||
//! Helper method with template free signature serving as callback from threaded worker
|
||||
int updateContainer(const BlackMisc::CVariant &variant, bool sort, bool resize)
|
||||
{
|
||||
return this->performUpdateContainer(variant, sort, resize);
|
||||
}
|
||||
int ps_updateContainer(const BlackMisc::CVariant &variant, bool sort, bool resize);
|
||||
|
||||
//! Display the filter dialog
|
||||
void ps_displayFilterDialog();
|
||||
|
||||
//! Remove filter
|
||||
virtual void ps_removeFilter() = 0;
|
||||
|
||||
//! Filter dialog finished
|
||||
virtual bool ps_filterDialogFinished(int status) = 0;
|
||||
|
||||
private slots:
|
||||
//! Custom menu was requested
|
||||
@@ -173,19 +191,13 @@ namespace BlackGui
|
||||
void updateContainerMaybeAsync(const ContainerType &container, bool sort = true, bool performResizing = true);
|
||||
|
||||
//! Insert
|
||||
void insert(const ObjectType &value, bool resize = true)
|
||||
{
|
||||
Q_ASSERT(this->m_model);
|
||||
this->m_model->insert(value);
|
||||
if (resize) { this->performResizeToContents(); }
|
||||
}
|
||||
void insert(const ObjectType &value, bool resize = true);
|
||||
|
||||
//! Value object at
|
||||
const ObjectType &at(const QModelIndex &index) const
|
||||
{
|
||||
Q_ASSERT(this->m_model);
|
||||
return this->m_model->at(index);
|
||||
}
|
||||
const ObjectType &at(const QModelIndex &index) const;
|
||||
|
||||
//! Access to container
|
||||
const ContainerType &getContainer() const;
|
||||
|
||||
//! Selected objects
|
||||
ContainerType selectedObjects() const;
|
||||
@@ -227,6 +239,13 @@ namespace BlackGui
|
||||
//! \copydoc CViewBaseNonTemplate::performUpdateContainer
|
||||
virtual int performUpdateContainer(const BlackMisc::CVariant &variant, bool sort, bool performResizing) override;
|
||||
|
||||
//! \copydoc CViewBaseNonTemplate::ps_filterDialogFinished
|
||||
//! \remarks Actually a slot, but not defined as such as the template does not support Q_OBJECT
|
||||
virtual bool ps_filterDialogFinished(int status) override;
|
||||
|
||||
//! \copydoc CViewBaseNonTemplate::ps_removeFilter
|
||||
//! \remarks Actually a slot, but not defined as such as the template does not support Q_OBJECT
|
||||
virtual void ps_removeFilter() override;
|
||||
};
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user