4#pragma warning(disable : 4800)
5#pragma warning(disable : 4251)
6#pragma warning(disable : 4244)
7#pragma warning(disable : 4127)
8#include <QAbstractItemModel>
13#include "../../global.hpp"
14#include "../../utilities/system_info.hpp"
15#include "../../genapi/node_map.hpp"
16#include "detail_property.hpp"
17#include "detail_boolean_property.hpp"
18#include "detail_category_property.hpp"
19#include "detail_command_property.hpp"
20#include "detail_enum_property.hpp"
21#include "detail_float_property.hpp"
22#include "detail_integer_property.hpp"
23#include "detail_string_property.hpp"
35 class PropertyModel :
public QAbstractItemModel
41 explicit PropertyModel(QObject *parent = 0) noexcept
42 : QAbstractItemModel(parent)
47 , searchResultBGColor_(255, 255, 0)
52 explicit PropertyModel(
const NodeMapPtr &nodemap, QObject *parent = 0) noexcept
53 : QAbstractItemModel(parent)
58 , searchResultBGColor_(255, 255, 0)
64 PropertyModel(
const PropertyModel &other) =
delete;
65 PropertyModel &operator=(
const PropertyModel &other) =
delete;
66 PropertyModel(PropertyModel &&other) =
delete;
67 PropertyModel &operator=(PropertyModel &&other) =
delete;
73 Private::Property *Item(
const QModelIndex &index)
const
77 auto prop =
static_cast<Private::Property *
>(index.internalPointer());
84 int rowCount(
const QModelIndex &parent)
const override
86 auto prop = rootProperty_;
91 return prop->ChildCount();
95 int columnCount(
const QModelIndex & = QModelIndex())
const override
97 return defaultColumns_;
100 Qt::ItemFlags flags(
const QModelIndex &index)
const override
102 if (!index.isValid())
103 return Qt::NoItemFlags;
105 auto prop = Item(index);
107 return Qt::NoItemFlags;
110 return Qt::NoItemFlags;
111 else if (prop->IsReadOnly())
112 return Qt::ItemIsSelectable;
113 else if (prop->Type() == Private::Property::PT_Boolean)
114 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
116 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
119 QModelIndex index(
int row,
int column,
const QModelIndex &parent)
const override
121 if (!hasIndex(row, column, parent))
122 return QModelIndex();
124 auto item = rootProperty_;
125 if (parent.isValid())
126 item =
static_cast<Private::Property *
>(parent.internalPointer());
129 auto child = item->Child(row);
131 return createIndex(row, column, (
void *)child);
133 return QModelIndex();
136 QModelIndex parent(
const QModelIndex &child)
const override
138 if (!child.isValid())
139 return QModelIndex();
141 auto childProp =
static_cast<Private::Property *
>(child.internalPointer());
144 auto prop = childProp->Parent();
147 if (prop != rootProperty_)
148 return createIndex(prop->Position(), 0, (
void *)prop);
151 return QModelIndex();
154 QVariant data(
const QModelIndex &index,
int role)
const override
156 if (!index.isValid())
159 auto prop =
static_cast<Private::Property *
>(index.internalPointer());
169 case Qt::CheckStateRole:
170 if (prop->Type() == Private::Property::PT_Boolean && index.column() == 1)
171 return prop->Value(index.column(), role);
173 case Qt::ToolTipRole:
174 case Qt::DisplayRole:
176 return prop->Value(index.column(), role);
179 if (prop->Type() == Private::Property::PT_Category)
186 case Qt::ForegroundRole:
187 if (prop->Type() == Private::Property::PT_Category)
189 return QColor(Qt::black);
191 else if (prop->IsReadOnly())
193 return QColor(Qt::darkGray);
196 case Qt::BackgroundColorRole:
197 if (!searchText_.isEmpty())
199 auto param = prop->Value(0, Qt::DisplayRole).toString();
200 if (param.contains(searchText_, Qt::CaseInsensitive))
202 return searchResultBGColor_;
206 case Qt::DecorationRole:
207 if (prop->Type() == Private::Property::PT_Category)
210 if (index.column() == 0 && prop->NodeHasPolling())
212 auto by = QByteArray::fromBase64(pollingImg_.toLatin1());
213 auto img = QImage::fromData(by,
"PNG");
214 return QIcon(QPixmap::fromImage(img));
221 bool setData(
const QModelIndex &index,
const QVariant &value,
int role)
override
223 if (!index.isValid())
230 case Qt::CheckStateRole:
232 auto prop =
static_cast<Private::Property *
>(index.internalPointer());
236 prop->SetValue(value);
244 QVariant headerData(
int section, Qt::Orientation orientation,
int role)
const override
246 if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
252 auto header = QString(
"Property");
254 header.append(
" (Beginner)");
256 header.append(
" (Expert)");
258 header.append(
" (Guru)");
270 QModelIndex buddy(
const QModelIndex &index)
const override
272 if (index.isValid() && index.column() == 0)
273 return createIndex(index.row(), 1, index.internalPointer());
292 return maxVisibility_;
297 maxVisibility_ = visibility;
301 QModelIndexList Search(
const QString &text)
304 if (searchText_.isEmpty())
305 return QModelIndexList();
306 return match(index(0, 0, QModelIndex()), Qt::DisplayRole, QVariant::fromValue(searchText_), -1,
307 Qt::MatchRecursive | Qt::MatchContains);
310 QModelIndex FindExactMatch(
const QString &text)
313 return QModelIndex();
316 match(index(0, 0, QModelIndex()), Qt::DisplayRole, QVariant::fromValue(text), -1, Qt::MatchRecursive);
317 if (list.size() == 1)
320 return QModelIndex();
323 Private::Property *Property(
const QString &text)
325 auto index = FindExactMatch(text);
329 Private::Property *Property(
const QModelIndex &index)
345 void SetSearchResultBGColor(QColor color)
347 searchResultBGColor_ = color;
350 QColor SearchResultBGColor()
352 return searchResultBGColor_;
355 void UpdateProperty(
const QModelIndex &index)
357 dataChanged(index, index);
364 dataChanged(QModelIndex(), QModelIndex());
367 void ResetUpdateLock()
385 auto rootNode = nodeMap_->Node<CategoryNode>(CVB_LIT(
"Root"));
386 rootProperty_ =
new CategoryProperty(rootNode,
nullptr);
387 WalkTree(rootNode, rootProperty_, 1);
393 auto rootNode = rootProperty_->Node();
394 WalkTree(rootNode, rootProperty_, 1);
402 void WalkTree(
const NodePtr &parentNode, Private::Property *parentProperty,
405 if (depth >= maxDepth_)
408 auto children = Children(parentNode);
409 auto excludedNodes = ExcludedNodes(children);
412 for (
int i = 0; i < children.size(); i++)
414 auto child = children.at(i);
415 if (child ==
nullptr)
419 auto pos = parentProperty->FindChildProperty(child);
423 if (!IsValid(child) || !IsVisible(child, MaxVisibility()))
425 parentProperty->RemoveChild(pos);
429 if (
auto category = std::dynamic_pointer_cast<CategoryNode>(child))
430 WalkTree(category, parentProperty->ChildProperty(pos), depth + 1);
431 else if (
auto selector = std::dynamic_pointer_cast<SelectorNode>(child))
432 WalkTree(selector, parentProperty->ChildProperty(pos), depth + 1);
440 if (!IsValid(child) || !IsVisible(child, MaxVisibility()))
445 auto p = CreateProperty(child, parentProperty);
449 parentProperty->InsertChild(childCount, p);
451 QObject::connect(p, &Property::NodeUpdated, [=](Private::Property *property) {
452 auto index = Index(property, QModelIndex());
453 dataChanged(index, index);
456 QObject::connect(p, &Property::TimeoutOccurred, [=]() { updateLock_ =
true; });
458 if (
auto category = std::dynamic_pointer_cast<CategoryNode>(child))
459 WalkTree(category, p, depth + 1);
460 else if (
auto selector = std::dynamic_pointer_cast<SelectorNode>(child))
461 WalkTree(selector, p, depth + 1);
467 QVector<NodePtr> Children(
const NodePtr &parentNode)
const
469 QVector<NodePtr> children;
470 if (
auto catNode = std::dynamic_pointer_cast<CategoryNode>(parentNode))
472 std::vector<NodePtr> categoryNodes = catNode->Nodes();
473 for (std::size_t i = 0; i < categoryNodes.size(); i++)
474 children.push_back(categoryNodes.at(i));
476 else if (
auto selNode = std::dynamic_pointer_cast<SelectorNode>(parentNode))
478 auto selectedNodes = selNode->SelectedNodes();
479 for (std::size_t i = 0; i < selectedNodes.size(); i++)
480 children.push_back(selectedNodes.at(i));
485 QSet<QString> ExcludedNodes(QVector<NodePtr> nodelist)
const
487 QSet<QString> excluded;
488 for (
int i = 0; i < nodelist.size(); i++)
490 auto node = nodelist.at(i);
493 if (!node->IsFeature() || !node->IsImplemented())
497 if (
auto nodeSelector = std::dynamic_pointer_cast<SelectorNode>(node))
499 auto selectedNodes = nodeSelector->SelectedNodes();
500 for (std::size_t j = 0; j < selectedNodes.size(); j++)
502 auto selectedNode = selectedNodes.at(j);
505 if (selectedNode->IsFeature())
514 Private::Property *CreateProperty(
const NodePtr &node, Private::Property *parent)
516 if (!IsValid(node) || !IsVisible(node, MaxVisibility()))
519 if (
auto catNode = std::dynamic_pointer_cast<CategoryNode>(node))
520 return new CategoryProperty(catNode, parent);
521 else if (
auto strNode = std::dynamic_pointer_cast<StringNode>(node))
522 return new StringProperty(strNode, parent);
523 else if (
auto cmdNode = std::dynamic_pointer_cast<CommandNode>(node))
524 return new CommandProperty(cmdNode, parent);
525 else if (
auto fNode = std::dynamic_pointer_cast<FloatNode>(node))
526 return new FloatProperty(fNode, parent);
527 else if (
auto boolNode = std::dynamic_pointer_cast<BooleanNode>(node))
528 return new BooleanProperty(boolNode, parent);
529 else if (
auto enumNode = std::dynamic_pointer_cast<EnumerationNode>(node))
530 return new EnumProperty(enumNode, parent);
531 else if (
auto iNode = std::dynamic_pointer_cast<IntegerNode>(node))
532 return new IntegerProperty(iNode, parent);
537 static bool IsValid(
const NodePtr &node)
539 return !(!node || node->Visibility() == Visibility::Invisible || node->IsDeprecated()
540 || !node->IsImplemented());
543 QModelIndex Index(Private::Property *property,
const QModelIndex &parent)
const
545 int numRows = rowCount(parent);
546 for (
int row = 0; row < numRows; ++row)
548 auto index = this->index(row, 0, parent);
549 auto prop = Item(index);
550 if (prop == property)
556 return QModelIndex();
559 static bool IsVisible(
const NodePtr &node,
Visibility maxVisibility = Visibility::Guru)
561 return IsVisible(node ? node->Visibility() : Visibility::Invisible, maxVisibility);
566 return visibility != Visibility::Invisible && visibility <= maxVisibility;
577 delete rootProperty_;
578 rootProperty_ = NULL;
583 const int maxDepth_ = 20;
584 const int defaultColumns_ = 2;
585 Private::Property *rootProperty_;
589 QColor searchResultBGColor_;
591 const QString pollingImg_ = QString(
592 "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/"
593 "9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/"
594 "eHBhY2tldCBiZWdpbj0i77u/"
595 "IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+"
596 "IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNS"
597 "wgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIy"
598 "LXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb2"
599 "0veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxu"
600 "czp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo5YjExYzFmNC"
601 "0yMGVhLWZiNDgtOGVkYi1kN2JlYTA3MDkyZjEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzU4Q0ZGQjI0MDcxMTFFN0E4NUM5ODMx"
602 "RTEwQ0RGOEEiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzU4Q0ZGQjE0MDcxMTFFN0E4NUM5ODMxRTEwQ0RGOEEiIHhtcDpDcmVhdG"
603 "9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9"
604 "InhtcC5paWQ6OWIxMWMxZjQtMjBlYS1mYjQ4LThlZGItZDdiZWEwNzA5MmYxIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjliMTFjMW"
605 "Y0LTIwZWEtZmI0OC04ZWRiLWQ3YmVhMDcwOTJmMSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94"
606 "cGFja2V0IGVuZD0iciI/"
607 "PjRDl6wAAAL9SURBVHjadFNtSFNRGH7u165Tp9t00805t0ytkD6RMuhDTIqK0sp+REgpRhR9QD+DCPrRnygqLCoqrIj+"
608 "FEXQj8KoKMxUFHSllebHdNbmx+Z0H/dup3MXDlf0wOHc+/K+7znP87yHwV9I1RutRlthfbI2s5KAKSIgPMeyA0G/t2nC2X9z3PmjdX4+M/"
609 "fBchxMBUvr9Rb76WBYzhMFHjptGmgxpnzTmAkEoRIEX9DruTnU3XZGCs4G4g0YlsPCkg0XxDT9KYE22r21HFvL1iHfZqENOIyM/"
610 "cK7lnY8fPoCLvc4BIY0fW15XRWamZ6OnZ6zaHldccUesrG6lrR3fSZzaGh8RM5dvhH/d/"
611 "3ykJqTp0lRWSUpXFPeyHK8wtlgKd60a3TFlr2k09FD5mPHwWOkdOd+"
612 "EgyF4jFKh2yrOUqUAw15hRWs0VZ0OBSWTdXbK7BsSVGCoKKogloUE2LpmlQcr90HWZKgz7EdYZN1mVWKYNvKN/"
613 "xtCFiWAcMwEFWqhPi61auQa84Cq1KX8tSqggyqdq4pKyEpGArDPxOI7Y6vfUhRqxElUWjTNNBr02E1mzDodGXylBbPUquUNR8fWjvw5Vs/"
614 "kpJEVNadiPkVDktYvNCOZ3euxujRGeGUIXFSYXI9E1MxfnOw5piQk22EJEewfvVKCIIAWZZRYLeCpbRGxn6CZ7kpPuT3vooKybVvP7YhP8"
615 "8Sb6AkPr51CZIkw5xlSLhdp6MXfYNOICJ1sZ7hvgZRJczef/"
616 "IcnonJhESDXvdPsYJrjY8gRwl87tG7XMDvdWl0Bl0ggrWO3u8oKy2J8f4fzjfcxrOXb8Az0Zah7tZTnBL0T7rfZ1kXlA6Nue1vmj9Bl56G"
617 "bGMmtU+IFYWp5x2OHpy9eD1WnJKiHhnobK4K+CZ/xh9TUmq6xlpcckWl0R5QxLJQAa3mbPA8BzrCGHCOQo4QsFHp/"
618 "bCjvZ5evyfhNf4ZHA4Z1vzNerPtkDIkkWjUSK1ieY6boKPX5fO4HrgHeu+FA7PSXM1vAQYAJKlQ2kI6nbwAAAAASUVORK5CYII=");
std::shared_ptr< Node > NodePtr
Convenience shared pointer for Node.
Definition genapi.hpp:71
Visibility
Feature complexity level.
Definition genapi.hpp:238
@ Expert
More complex feature, that requires deeper knowledge about the feature.
Definition genapi.hpp:244
@ Beginner
Simple feature usable by everybody.
Definition genapi.hpp:242
@ Guru
Definition genapi.hpp:251
std::shared_ptr< NodeMap > NodeMapPtr
Convenience shared pointer for NodeMap.
Definition genapi.hpp:27
Namespace for user interface components.
Definition decl_image_scene.hpp:39
QString CvbToQt(const Cvb::String &text) noexcept
Convenience converter for strings.
Definition ui.hpp:257
Root namespace for the Image Manager interface.
Definition version.hpp:11