##// END OF EJS Templates
Corrects the problem of refreshing synchronized graphs from TimeWidget (1)...
Corrects the problem of refreshing synchronized graphs from TimeWidget (1) Introduces graph flags to set options for the widget

File last commit:

r961:15899f42a907
r1271:87a145505c37
Show More
VariableModel.cpp
396 lines | 12.1 KiB | text/x-c | CppLexer
Alexandre Leroux
Changes Variable from struct to class
r163 #include <Variable/Variable.h>
Drag of variables
r849 #include <Variable/VariableController.h>
Alexandre Leroux
Creates the variable model...
r112 #include <Variable/VariableModel.h>
Alexandre Leroux
Uses DateUtils
r488 #include <Common/DateUtils.h>
Drag of variables
r849 #include <Common/MimeTypesDef.h>
Alexandre Leroux
Generates unique name for variable duplicate
r709 #include <Common/StringUtils.h>
Alexandre Leroux
Uses DateUtils
r488
Alexandre Leroux
Updates VariableModel::createVariable() method...
r165 #include <Data/IDataSeries.h>
Alexandre Leroux
Creates the variable model...
r112
Drop of variable, graph and zones on the time widget
r878 #include <DataSource/DataSourceController.h>
#include <Time/TimeController.h>
Drag of variables
r849 #include <QMimeData>
Alexandre Leroux
Updates headerData() method to return column width/size for role Qt::SizeHintRole
r277 #include <QSize>
Drop TIME mime data on a variable
r933 #include <QTimer>
Add implementation of progress bar on variable inspector connected to...
r401 #include <unordered_map>
Alexandre Leroux
Replaces unit and mission columns by datetime columns
r274
Alexandre Leroux
Creates the variable model...
r112 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
Alexandre Leroux
Adapts VariableModel to be a QabstractTableModel...
r149 namespace {
Alexandre Leroux
Implements headerData() method
r150 // Column indexes
const auto NAME_COLUMN = 0;
Alexandre Leroux
Replaces unit and mission columns by datetime columns
r274 const auto TSTART_COLUMN = 1;
const auto TEND_COLUMN = 2;
Alexandre Leroux
Adds column to display nb points in variable widget
r719 const auto NBPOINTS_COLUMN = 3;
const auto UNIT_COLUMN = 4;
const auto MISSION_COLUMN = 5;
const auto PLUGIN_COLUMN = 6;
const auto NB_COLUMNS = 7;
Alexandre Leroux
Adapts VariableModel to be a QabstractTableModel...
r149
Alexandre Leroux
Creates struct for column properties...
r275 // Column properties
Alexandre Leroux
Adds width and height properties
r276 const auto DEFAULT_HEIGHT = 25;
const auto DEFAULT_WIDTH = 100;
Alexandre Leroux
Creates struct for column properties...
r275
struct ColumnProperties {
Alexandre Leroux
Adds width and height properties
r276 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
int height = DEFAULT_HEIGHT)
: m_Name{name}, m_Width{width}, m_Height{height}
{
}
Alexandre Leroux
Creates struct for column properties...
r275
QString m_Name;
Alexandre Leroux
Adds width and height properties
r276 int m_Width;
int m_Height;
Alexandre Leroux
Creates struct for column properties...
r275 };
Alexandre Leroux
Adds "unit" and "mission" columns to variable widget
r550 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
Alexandre Leroux
Adds column to display nb points in variable widget
r719 {NAME_COLUMN, {QObject::tr("Name")}}, {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
{TEND_COLUMN, {QObject::tr("tEnd"), 180}}, {NBPOINTS_COLUMN, {QObject::tr("Nb points")}},
{UNIT_COLUMN, {QObject::tr("Unit")}}, {MISSION_COLUMN, {QObject::tr("Mission")}},
{PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
Alexandre Leroux
Creates struct for column properties...
r275
Alexandre Leroux
Replaces unit and mission columns by datetime columns
r274 /// Format for datetimes
const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
Alexandre Leroux
Generates unique name for variable duplicate
r709 QString uniqueName(const QString &defaultName,
const std::vector<std::shared_ptr<Variable> > &variables)
{
auto forbiddenNames = std::vector<QString>(variables.size());
std::transform(variables.cbegin(), variables.cend(), forbiddenNames.begin(),
[](const auto &variable) { return variable->name(); });
auto uniqueName = StringUtils::uniqueName(defaultName, forbiddenNames);
Q_ASSERT(!uniqueName.isEmpty());
return uniqueName;
}
Add implementation of progress bar on variable inspector connected to...
r401
Alexandre Leroux
Adapts VariableModel to be a QabstractTableModel...
r149 } // namespace
Alexandre Leroux
Creates the variable model...
r112 struct VariableModel::VariableModelPrivate {
/// Variables created in SciQlop
Alexandre Leroux
Updates VariableModel::createVariable() method...
r165 std::vector<std::shared_ptr<Variable> > m_Variables;
Alexandre Leroux
Corrects regression on variable destruction
r421 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
Drag of variables
r849 VariableController *m_VariableController;
Add implementation of progress bar on variable inspector connected to...
r401
Correction MR
r402 /// Return the row index of the variable. -1 if it's not found
Add implementation of progress bar on variable inspector connected to...
r401 int indexOfVariable(Variable *variable) const noexcept;
Alexandre Leroux
Creates the variable model...
r112 };
Drag of variables
r849 VariableModel::VariableModel(VariableController *parent)
Alexandre Leroux
Adapts VariableModel to be a QabstractTableModel...
r149 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
Alexandre Leroux
Creates the variable model...
r112 {
Drag of variables
r849 impl->m_VariableController = parent;
Alexandre Leroux
Creates the variable model...
r112 }
Alexandre Leroux
Adds variable to model
r708 void VariableModel::addVariable(std::shared_ptr<Variable> variable) noexcept
Alexandre Leroux
Creates the variable model...
r112 {
Alexandre Leroux
Notifies view when a variable is added to the model
r153 auto insertIndex = rowCount();
beginInsertRows({}, insertIndex, insertIndex);
Alexandre Leroux
Generates unique name for variable duplicate
r709 // Generates unique name for the variable
variable->setName(uniqueName(variable->name(), impl->m_Variables));
Alexandre Leroux
Updates VariableModel::createVariable() method...
r165 impl->m_Variables.push_back(variable);
Alexandre Leroux
Fixes refresh problem in Variable widget
r368 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
Alexandre Leroux
Creates the variable model...
r112
Alexandre Leroux
Notifies view when a variable is added to the model
r153 endInsertRows();
Alexandre Leroux
Adds variable to model
r708 }
Alexandre Leroux
Creates duplicate only if the variable is in the model
r710 bool VariableModel::containsVariable(std::shared_ptr<Variable> variable) const noexcept
{
auto end = impl->m_Variables.cend();
return std::find(impl->m_Variables.cbegin(), end, variable) != end;
}
Alexandre Leroux
Adds variable to model
r708 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
const QVariantHash &metadata) noexcept
{
Fix bug when creating two variables crash the app. ...
r756 auto variable = std::make_shared<Variable>(name, metadata);
Alexandre Leroux
Adds variable to model
r708 addVariable(variable);
Alexandre Leroux
Notifies view when a variable is added to the model
r153
Alexandre Leroux
Updates VariableModel::createVariable() method...
r165 return variable;
Alexandre Leroux
Creates the variable model...
r112 }
Alexandre Leroux
Adapts VariableModel to be a QabstractTableModel...
r149
Alexandre Leroux
Variable deletion (3)...
r332 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
{
if (!variable) {
qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
return;
}
// Finds variable in the model
auto begin = impl->m_Variables.cbegin();
auto end = impl->m_Variables.cend();
auto it = std::find(begin, end, variable);
if (it != end) {
auto removeIndex = std::distance(begin, it);
// Deletes variable
beginRemoveRows({}, removeIndex, removeIndex);
impl->m_Variables.erase(it);
endRemoveRows();
}
else {
qCritical(LOG_VariableModel())
<< tr("Can't delete variable %1 from the model: the variable is not in the model")
.arg(variable->name());
}
Alexandre Leroux
Corrects regression on variable destruction
r421
// Removes variable from progress map
impl->m_VariableToProgress.erase(variable);
Alexandre Leroux
Variable deletion (3)...
r332 }
Add implementation of progress bar on variable inspector connected to...
r401
Alexandre Leroux
Retrieves the current selected variable when clicking on the variable widget
r246 std::shared_ptr<Variable> VariableModel::variable(int index) const
{
Alexandre Leroux
Removes compilation warnings (with Meson)
r961 return (index >= 0u && static_cast<size_t>(index) < impl->m_Variables.size())
? impl->m_Variables[index]
: nullptr;
Alexandre Leroux
Retrieves the current selected variable when clicking on the variable widget
r246 }
Alexandre Leroux
Adds method to get all variables from model...
r684 std::vector<std::shared_ptr<Variable> > VariableModel::variables() const
{
return impl->m_Variables;
}
Add implementation of progress bar on variable inspector connected to...
r401 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
{
Remove abort button validity when the progress is finished (eg. == 0)
r432 if (progress > 0.0) {
impl->m_VariableToProgress[variable] = progress;
}
else {
impl->m_VariableToProgress.erase(variable);
}
Add implementation of progress bar on variable inspector connected to...
r401 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
emit dataChanged(modelIndex, modelIndex);
}
Alexandre Leroux
Adapts VariableModel to be a QabstractTableModel...
r149 int VariableModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return NB_COLUMNS;
}
int VariableModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return impl->m_Variables.size();
}
QVariant VariableModel::data(const QModelIndex &index, int role) const
{
Alexandre Leroux
Implements data() method
r151 if (!index.isValid()) {
return QVariant{};
}
if (index.row() < 0 || index.row() >= rowCount()) {
return QVariant{};
}
if (role == Qt::DisplayRole) {
Alexandre Leroux
Removes useless const ref
r157 if (auto variable = impl->m_Variables.at(index.row()).get()) {
Alexandre Leroux
Implements data() method
r151 switch (index.column()) {
case NAME_COLUMN:
Alexandre Leroux
Changes Variable from struct to class
r163 return variable->name();
Alexandre Leroux
Fixed untimely update of the range to be displayed in the variable widget
r654 case TSTART_COLUMN: {
auto range = variable->realRange();
return range != INVALID_RANGE
? DateUtils::dateTime(range.m_TStart).toString(DATETIME_FORMAT)
: QVariant{};
}
case TEND_COLUMN: {
auto range = variable->realRange();
return range != INVALID_RANGE
? DateUtils::dateTime(range.m_TEnd).toString(DATETIME_FORMAT)
: QVariant{};
}
Alexandre Leroux
Adds column to display nb points in variable widget
r719 case NBPOINTS_COLUMN:
return variable->nbPoints();
Alexandre Leroux
Adds "unit" and "mission" columns to variable widget
r550 case UNIT_COLUMN:
return variable->metadata().value(QStringLiteral("units"));
case MISSION_COLUMN:
return variable->metadata().value(QStringLiteral("mission"));
Alexandre Leroux
Adds plugin column to variable widget...
r551 case PLUGIN_COLUMN:
return variable->metadata().value(QStringLiteral("plugin"));
Alexandre Leroux
Implements data() method
r151 default:
// No action
break;
}
qWarning(LOG_VariableModel())
<< tr("Can't get data (unknown column %1)").arg(index.column());
}
else {
qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
}
}
Correction MR
r402 else if (role == VariableRoles::ProgressRole) {
Add implementation of progress bar on variable inspector connected to...
r401 if (auto variable = impl->m_Variables.at(index.row())) {
Alexandre Leroux
Corrects regression on variable destruction
r421 auto it = impl->m_VariableToProgress.find(variable);
Add implementation of progress bar on variable inspector connected to...
r401 if (it != impl->m_VariableToProgress.cend()) {
return it->second;
}
}
}
Alexandre Leroux
Implements data() method
r151
Alexandre Leroux
Adapts VariableModel to be a QabstractTableModel...
r149 return QVariant{};
}
QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
Alexandre Leroux
Updates headerData() method to return column width/size for role Qt::SizeHintRole
r277 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
Alexandre Leroux
Implements headerData() method
r150 return QVariant{};
}
if (orientation == Qt::Horizontal) {
Alexandre Leroux
Creates struct for column properties...
r275 auto propertiesIt = COLUMN_PROPERTIES.find(section);
if (propertiesIt != COLUMN_PROPERTIES.cend()) {
// Role is either DisplayRole or SizeHintRole
Alexandre Leroux
Updates headerData() method to return column width/size for role Qt::SizeHintRole
r277 return (role == Qt::DisplayRole)
? QVariant{propertiesIt->m_Name}
: QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
Alexandre Leroux
Creates struct for column properties...
r275 }
else {
qWarning(LOG_VariableModel())
<< tr("Can't get header data (unknown column %1)").arg(section);
Alexandre Leroux
Implements headerData() method
r150 }
}
Alexandre Leroux
Adapts VariableModel to be a QabstractTableModel...
r149
return QVariant{};
}
Alexandre Leroux
Fixes refresh problem in Variable widget
r368
Drag of variables
r849 Qt::ItemFlags VariableModel::flags(const QModelIndex &index) const
{
return QAbstractTableModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
}
Qt::DropActions VariableModel::supportedDropActions() const
{
Drop of product in variables
r870 return Qt::CopyAction | Qt::MoveAction;
Drag of variables
r849 }
Qt::DropActions VariableModel::supportedDragActions() const
{
return Qt::CopyAction | Qt::MoveAction;
}
QStringList VariableModel::mimeTypes() const
{
Drop of variable, graph and zones on the time widget
r878 return {MIME_TYPE_VARIABLE_LIST, MIME_TYPE_TIME_RANGE};
Drag of variables
r849 }
QMimeData *VariableModel::mimeData(const QModelIndexList &indexes) const
{
auto mimeData = new QMimeData;
QList<std::shared_ptr<Variable> > variableList;
Drop of variable, graph and zones on the time widget
r878
SqpRange firstTimeRange;
Drag of variables
r849 for (const auto &index : indexes) {
drop of variables in the visualization
r850 if (index.column() == 0) { // only the first column
auto variable = impl->m_Variables.at(index.row());
if (variable.get() && index.isValid()) {
Drop of variable, graph and zones on the time widget
r878
if (variableList.isEmpty()) {
// Gets the range of the first variable
firstTimeRange = std::move(variable->range());
}
drop of variables in the visualization
r850 variableList << variable;
}
Drag of variables
r849 }
}
Drop of variable, graph and zones on the time widget
r878 auto variablesEncodedData = impl->m_VariableController->mimeDataForVariables(variableList);
mimeData->setData(MIME_TYPE_VARIABLE_LIST, variablesEncodedData);
if (variableList.count() == 1) {
// No time range MIME data if multiple variables are dragged
auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange);
mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData);
}
Drag of variables
r849
return mimeData;
}
bool VariableModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row,
int column, const QModelIndex &parent) const
{
Drop of product in variables
r870 // drop of a product
Drop TIME mime data on a variable
r933 return data->hasFormat(MIME_TYPE_PRODUCT_LIST)
|| (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid()
&& !data->hasFormat(MIME_TYPE_VARIABLE_LIST));
Drag of variables
r849 }
bool VariableModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
const QModelIndex &parent)
{
Improves reliability
r874 auto dropDone = false;
Drop of product in variables
r870
if (data->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
Drop of variable, graph and zones on the time widget
r878 auto productList
= DataSourceController::productsDataForMimeData(data->data(MIME_TYPE_PRODUCT_LIST));
Drop of product in variables
r870
for (auto metaData : productList) {
emit requestVariable(metaData.toHash());
}
dropDone = true;
}
Drop TIME mime data on a variable
r933 else if (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid()) {
auto variable = this->variable(parent.row());
auto range = TimeController::timeRangeForMimeData(data->data(MIME_TYPE_TIME_RANGE));
emit requestVariableRangeUpdate(variable, range);
dropDone = true;
}
Drop of product in variables
r870
return dropDone;
Drag of variables
r849 }
Implement of the abort download process
r422 void VariableModel::abortProgress(const QModelIndex &index)
{
if (auto variable = impl->m_Variables.at(index.row())) {
emit abortProgessRequested(variable);
}
}
Alexandre Leroux
Fixes refresh problem in Variable widget
r368 void VariableModel::onVariableUpdated() noexcept
{
// Finds variable that has been updated in the model
if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
Add implementation of progress bar on variable inspector connected to...
r401 auto updatedVariableIndex = impl->indexOfVariable(updatedVariable);
if (updatedVariableIndex > -1) {
emit dataChanged(createIndex(updatedVariableIndex, 0),
createIndex(updatedVariableIndex, columnCount() - 1));
Alexandre Leroux
Fixes refresh problem in Variable widget
r368 }
}
}
Add implementation of progress bar on variable inspector connected to...
r401
int VariableModel::VariableModelPrivate::indexOfVariable(Variable *variable) const noexcept
{
auto begin = std::cbegin(m_Variables);
auto end = std::cend(m_Variables);
auto it
= std::find_if(begin, end, [variable](const auto &var) { return var.get() == variable; });
if (it != end) {
// Gets the index of the variable in the model: we assume here that views have the same
// order as the model
return std::distance(begin, it);
}
else {
return -1;
}
}