From 68f8af621a1491c7b7c2e4f7f6377cacaee5ca19 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Sun, 13 Jul 2025 20:43:34 +0330 Subject: [PATCH 001/124] Graph window with floating toolbar --- examples/CMakeLists.txt | 1 + examples/epen_graph_editor/CMakeLists.txt | 14 + .../include/FloatingToolbar.hpp | 41 +++ .../include/GraphEditorWindow.hpp | 41 +++ .../include/SimpleGraphModel.hpp | 109 +++++++ .../epen_graph_editor/src/FloatingToolbar.cpp | 165 ++++++++++ .../src/GraphEditorWindow.cpp | 146 +++++++++ .../src/SimpleGraphModel.cpp | 294 ++++++++++++++++++ examples/epen_graph_editor/src/main.cpp | 12 + 9 files changed, 823 insertions(+) create mode 100644 examples/epen_graph_editor/CMakeLists.txt create mode 100644 examples/epen_graph_editor/include/FloatingToolbar.hpp create mode 100644 examples/epen_graph_editor/include/GraphEditorWindow.hpp create mode 100644 examples/epen_graph_editor/include/SimpleGraphModel.hpp create mode 100644 examples/epen_graph_editor/src/FloatingToolbar.cpp create mode 100644 examples/epen_graph_editor/src/GraphEditorWindow.cpp create mode 100644 examples/epen_graph_editor/src/SimpleGraphModel.cpp create mode 100644 examples/epen_graph_editor/src/main.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 49494da2e..154279c0c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -16,3 +16,4 @@ add_subdirectory(dynamic_ports) add_subdirectory(lock_nodes_and_connections) +add_subdirectory(epen_graph_editor) \ No newline at end of file diff --git a/examples/epen_graph_editor/CMakeLists.txt b/examples/epen_graph_editor/CMakeLists.txt new file mode 100644 index 000000000..55b61b5d5 --- /dev/null +++ b/examples/epen_graph_editor/CMakeLists.txt @@ -0,0 +1,14 @@ +file(GLOB_RECURSE CPPS ./src/*.cpp ) +file(GLOB_RECURSE HPPS ./include/*.hpp ) + +find_package(Qt6 REQUIRED COMPONENTS Core Widgets) + +add_executable(epen_graph_editor ${CPPS} ${HPPS}) + +target_include_directories(epen_graph_editor + PUBLIC + include +) + +target_link_libraries(epen_graph_editor QtNodes Qt6::Core + Qt6::Widgets) diff --git a/examples/epen_graph_editor/include/FloatingToolbar.hpp b/examples/epen_graph_editor/include/FloatingToolbar.hpp new file mode 100644 index 000000000..aef5d583f --- /dev/null +++ b/examples/epen_graph_editor/include/FloatingToolbar.hpp @@ -0,0 +1,41 @@ +#ifndef FLOATING_TOOLBAR_HPP +#define FLOATING_TOOLBAR_HPP + +#include + +class QVBoxLayout; +class GraphEditorWindow; + +class FloatingToolbar : public QWidget +{ + Q_OBJECT + +public: + explicit FloatingToolbar(GraphEditorWindow *parent = nullptr); + ~FloatingToolbar() = default; + + // Position the toolbar relative to the main window + void positionRelativeToParent(); + +signals: + void rectangleRequested(); + void circleRequested(); + void nodeRequested(); + void fillColorChanged(const QColor &color); + void zoomInRequested(); + void zoomOutRequested(); + void resetViewRequested(); + +protected: + // Override to maintain position relative to parent + void showEvent(QShowEvent *event) override; + +private: + void setupUI(); + void connectSignals(); + + GraphEditorWindow *m_graphEditor; + QVBoxLayout *m_layout; +}; + +#endif // FLOATING_TOOLBAR_HPP \ No newline at end of file diff --git a/examples/epen_graph_editor/include/GraphEditorWindow.hpp b/examples/epen_graph_editor/include/GraphEditorWindow.hpp new file mode 100644 index 000000000..dec9c29a8 --- /dev/null +++ b/examples/epen_graph_editor/include/GraphEditorWindow.hpp @@ -0,0 +1,41 @@ +#ifndef GRAPH_EDITOR_WINDOW +#define GRAPH_EDITOR_WINDOW + +#include "QtNodes/GraphicsView" +#include + +using QtNodes::GraphicsView; + +class FloatingToolbar; +class SimpleGraphModel; + +class GraphEditorWindow : public GraphicsView +{ + Q_OBJECT +public: + GraphEditorWindow(); + ~GraphEditorWindow(); + +public slots: + // Slot for creating a node at a specific position + void createNodeAtPosition(const QPointF &scenePos); + + // Slot for creating a node at cursor position + void createNodeAtCursor(); + +protected: + // Override to maintain toolbar position + void moveEvent(QMoveEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void showEvent(QShowEvent *event) override; + +private: + void createFloatingToolbar(); + void setupNodeCreation(); + + QPointer m_toolbar; + SimpleGraphModel *m_graphModel; + bool m_toolbarCreated; // This was missing! +}; + +#endif // GRAPH_EDITOR_WINDOW \ No newline at end of file diff --git a/examples/epen_graph_editor/include/SimpleGraphModel.hpp b/examples/epen_graph_editor/include/SimpleGraphModel.hpp new file mode 100644 index 000000000..e3d07213c --- /dev/null +++ b/examples/epen_graph_editor/include/SimpleGraphModel.hpp @@ -0,0 +1,109 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include + +using ConnectionId = QtNodes::ConnectionId; +using ConnectionPolicy = QtNodes::ConnectionPolicy; +using NodeFlag = QtNodes::NodeFlag; +using NodeId = QtNodes::NodeId; +using NodeRole = QtNodes::NodeRole; +using PortIndex = QtNodes::PortIndex; +using PortRole = QtNodes::PortRole; +using PortType = QtNodes::PortType; +using StyleCollection = QtNodes::StyleCollection; +using QtNodes::InvalidNodeId; + +/** + * The class implements a bare minimum required to demonstrate a model-based + * graph. + */ +class SimpleGraphModel : public QtNodes::AbstractGraphModel +{ + Q_OBJECT +public: + struct NodeGeometryData + { + QSize size; + QPointF pos; + }; + +public: + SimpleGraphModel(); + + ~SimpleGraphModel() override; + + std::unordered_set allNodeIds() const override; + + std::unordered_set allConnectionIds(NodeId const nodeId) const override; + + std::unordered_set connections(NodeId nodeId, + PortType portType, + PortIndex portIndex) const override; + + bool connectionExists(ConnectionId const connectionId) const override; + + NodeId addNode(QString const nodeType = QString()) override; + + /** + * Connection is possible when graph contains no connectivity data + * in both directions `Out -> In` and `In -> Out`. + */ + bool connectionPossible(ConnectionId const connectionId) const override; + + void addConnection(ConnectionId const connectionId) override; + + bool nodeExists(NodeId const nodeId) const override; + + QVariant nodeData(NodeId nodeId, NodeRole role) const override; + + bool setNodeData(NodeId nodeId, NodeRole role, QVariant value) override; + + QVariant portData(NodeId nodeId, + PortType portType, + PortIndex portIndex, + PortRole role) const override; + + bool setPortData(NodeId nodeId, + PortType portType, + PortIndex portIndex, + QVariant const &value, + PortRole role = PortRole::Data) override; + + bool deleteConnection(ConnectionId const connectionId) override; + + bool deleteNode(NodeId const nodeId) override; + + QJsonObject saveNode(NodeId const) const override; + + /// @brief Creates a new node based on the informatoin in `nodeJson`. + /** + * @param nodeJson conains a `NodeId`, node's position, internal node + * information. + */ + void loadNode(QJsonObject const &nodeJson) override; + + NodeId newNodeId() override { return _nextNodeId++; } + +private: + std::unordered_set _nodeIds; + + /// [Important] This is a user defined data structure backing your model. + /// In your case it could be anything else representing a graph, for example, a + /// table. Or a collection of structs with pointers to each other. Or an + /// abstract syntax tree, you name it. + /// + /// This data structure contains the graph connectivity information in both + /// directions, i.e. from Node1 to Node2 and from Node2 to Node1. + std::unordered_set _connectivity; + + mutable std::unordered_map _nodeGeometryData; + + /// A convenience variable needed for generating unique node ids. + NodeId _nextNodeId; +}; diff --git a/examples/epen_graph_editor/src/FloatingToolbar.cpp b/examples/epen_graph_editor/src/FloatingToolbar.cpp new file mode 100644 index 000000000..83a2156a9 --- /dev/null +++ b/examples/epen_graph_editor/src/FloatingToolbar.cpp @@ -0,0 +1,165 @@ +#include "FloatingToolbar.hpp" +#include "GraphEditorWindow.hpp" +#include +#include +#include +#include +#include +#include +#include + +FloatingToolbar::FloatingToolbar(GraphEditorWindow *parent) + : QWidget(nullptr) // Note: parent is nullptr for top-level window + , m_graphEditor(parent) +{ + // Set window flags for a tool window + setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); + + setWindowTitle("Tools"); + setFixedWidth(150); + + setupUI(); + connectSignals(); + + // Set a minimum height to ensure visibility + setMinimumHeight(400); + + // Position the toolbar initially + if (parent) { + positionRelativeToParent(); + } +} + +void FloatingToolbar::setupUI() +{ + m_layout = new QVBoxLayout(this); + m_layout->setContentsMargins(5, 5, 5, 5); + + // Add title + QLabel *title = new QLabel("Node Editor Tools"); + title->setAlignment(Qt::AlignCenter); + title->setStyleSheet("font-weight: bold; padding: 5px; background-color: #f0f0f0;"); + m_layout->addWidget(title); + + // Node creation section + m_layout->addSpacing(10); + QLabel *nodeLabel = new QLabel("Nodes:"); + nodeLabel->setStyleSheet("font-weight: bold;"); + m_layout->addWidget(nodeLabel); + + QPushButton *btnNode = new QPushButton("Create Node"); + btnNode->setToolTip("Create a new node at cursor position"); + m_layout->addWidget(btnNode); + + // Shape tools section (for future use) + m_layout->addSpacing(10); + QLabel *shapeLabel = new QLabel("Shapes:"); + shapeLabel->setStyleSheet("font-weight: bold;"); + m_layout->addWidget(shapeLabel); + + QPushButton *btnRect = new QPushButton("Rectangle"); + btnRect->setEnabled(false); // Disable for now + m_layout->addWidget(btnRect); + + QPushButton *btnCircle = new QPushButton("Circle"); + btnCircle->setEnabled(false); // Disable for now + m_layout->addWidget(btnCircle); + + // Color section + m_layout->addSpacing(10); + QLabel *colorLabel = new QLabel("Colors:"); + colorLabel->setStyleSheet("font-weight: bold;"); + m_layout->addWidget(colorLabel); + + QPushButton *btnRed = new QPushButton("Red Fill"); + btnRed->setStyleSheet("QPushButton { background-color: #ffcccc; }"); + m_layout->addWidget(btnRed); + + QPushButton *btnBlue = new QPushButton("Blue Fill"); + btnBlue->setStyleSheet("QPushButton { background-color: #ccccff; }"); + m_layout->addWidget(btnBlue); + + QPushButton *btnGreen = new QPushButton("Green Fill"); + btnGreen->setStyleSheet("QPushButton { background-color: #ccffcc; }"); + m_layout->addWidget(btnGreen); + + // View controls section + m_layout->addSpacing(10); + QLabel *viewLabel = new QLabel("View:"); + viewLabel->setStyleSheet("font-weight: bold;"); + m_layout->addWidget(viewLabel); + + QPushButton *btnZoomIn = new QPushButton("Zoom In"); + m_layout->addWidget(btnZoomIn); + + QPushButton *btnZoomOut = new QPushButton("Zoom Out"); + m_layout->addWidget(btnZoomOut); + + QPushButton *btnResetView = new QPushButton("Reset View"); + m_layout->addWidget(btnResetView); + + // Add stretch to push everything to the top + m_layout->addStretch(); + + // Store button references for signal connections + connect(btnNode, &QPushButton::clicked, this, &FloatingToolbar::nodeRequested); + connect(btnRect, &QPushButton::clicked, this, &FloatingToolbar::rectangleRequested); + connect(btnCircle, &QPushButton::clicked, this, &FloatingToolbar::circleRequested); + connect(btnRed, &QPushButton::clicked, [this]() { emit fillColorChanged(Qt::red); }); + connect(btnBlue, &QPushButton::clicked, [this]() { emit fillColorChanged(Qt::blue); }); + connect(btnGreen, &QPushButton::clicked, [this]() { emit fillColorChanged(Qt::green); }); + connect(btnZoomIn, &QPushButton::clicked, this, &FloatingToolbar::zoomInRequested); + connect(btnZoomOut, &QPushButton::clicked, this, &FloatingToolbar::zoomOutRequested); + connect(btnResetView, &QPushButton::clicked, this, &FloatingToolbar::resetViewRequested); +} + +void FloatingToolbar::connectSignals() +{ + // Connect toolbar signals to graphEditor slots + if (m_graphEditor) { + // Connect zoom controls + connect(this, &FloatingToolbar::zoomInRequested, [this]() { + m_graphEditor->scale(1.2, 1.2); + }); + + connect(this, &FloatingToolbar::zoomOutRequested, [this]() { + m_graphEditor->scale(0.8, 0.8); + }); + + connect(this, &FloatingToolbar::resetViewRequested, [this]() { + m_graphEditor->resetTransform(); + }); + + // Node creation is handled in GraphEditorWindow + // You'll need to add a slot in GraphEditorWindow to handle this + } +} + +void FloatingToolbar::positionRelativeToParent() +{ + if (m_graphEditor && m_graphEditor->isVisible()) { + // Get the global position of the parent window + QPoint parentPos = m_graphEditor->mapToGlobal(QPoint(0, 0)); + + // Position the toolbar to the right of the main window with some padding + int x = parentPos.x() + m_graphEditor->width() + 10; + int y = parentPos.y(); + + // Ensure the toolbar stays on screen + QRect screenGeometry = QApplication::primaryScreen()->availableGeometry(); + if (x + width() > screenGeometry.right()) { + // If toolbar would go off screen, position it to the left instead + x = parentPos.x() - width() - 10; + } + + move(x, y); + + qDebug() << "Toolbar repositioned to:" << QPoint(x, y); + } +} + +void FloatingToolbar::showEvent(QShowEvent *event) +{ + QWidget::showEvent(event); + positionRelativeToParent(); +} \ No newline at end of file diff --git a/examples/epen_graph_editor/src/GraphEditorWindow.cpp b/examples/epen_graph_editor/src/GraphEditorWindow.cpp new file mode 100644 index 000000000..257122dcf --- /dev/null +++ b/examples/epen_graph_editor/src/GraphEditorWindow.cpp @@ -0,0 +1,146 @@ +#include "GraphEditorWindow.hpp" +#include "FloatingToolbar.hpp" +#include "SimpleGraphModel.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using QtNodes::BasicGraphicsScene; +using QtNodes::ConnectionStyle; +using QtNodes::NodeRole; +using QtNodes::StyleCollection; + +GraphEditorWindow::GraphEditorWindow() + : GraphicsView() + , m_toolbar(nullptr) + , m_toolbarCreated(false) +{ + // Create the graph model + m_graphModel = new SimpleGraphModel(); + + // Create and set the scene + auto scene = new BasicGraphicsScene(*m_graphModel); + setScene(scene); + + // Setup context menu + setupNodeCreation(); + + setWindowTitle("Simple Node Graph"); + resize(800, 600); + + // Don't create toolbar here - wait for showEvent +} + +GraphEditorWindow::~GraphEditorWindow() +{ + // The toolbar will be automatically deleted as it's a child of this window + delete m_graphModel; +} + +void GraphEditorWindow::showEvent(QShowEvent *event) +{ + GraphicsView::showEvent(event); + + // Create toolbar only when window is shown for the first time + if (!m_toolbarCreated && isVisible()) { + m_toolbarCreated = true; + // Use a timer to ensure the window is fully rendered + QTimer::singleShot(100, this, [this]() { + createFloatingToolbar(); + }); + } +} + +void GraphEditorWindow::setupNodeCreation() +{ + setContextMenuPolicy(Qt::ActionsContextMenu); + + QAction *createNodeAction = new QAction(QStringLiteral("Create Node"), this); + connect(createNodeAction, &QAction::triggered, this, &GraphEditorWindow::createNodeAtCursor); + + // Insert at the beginning of the actions list + if (!actions().isEmpty()) { + insertAction(actions().front(), createNodeAction); + } else { + addAction(createNodeAction); + } +} + +void GraphEditorWindow::createFloatingToolbar() +{ + qDebug() << "Creating floating toolbar..."; + qDebug() << "Main window geometry:" << geometry(); + qDebug() << "Main window visible:" << isVisible(); + + // Create the floating toolbar + m_toolbar = new FloatingToolbar(this); + + if (!m_toolbar) { + qDebug() << "Failed to create toolbar!"; + return; + } + + // Connect toolbar signals + connect(m_toolbar, &FloatingToolbar::nodeRequested, + this, &GraphEditorWindow::createNodeAtCursor); + + // Connect other signals as needed + connect(m_toolbar, &FloatingToolbar::fillColorChanged, [this](const QColor &color) { + qDebug() << "Color changed to:" << color.name(); + }); + + // Set initial position before showing + QPoint mainPos = mapToGlobal(QPoint(0, 0)); + m_toolbar->move(mainPos.x() + width() + 10, mainPos.y()); + + // Show the toolbar + m_toolbar->show(); + m_toolbar->raise(); + m_toolbar->activateWindow(); + + qDebug() << "Toolbar created. Visible:" << m_toolbar->isVisible() + << "Geometry:" << m_toolbar->geometry(); +} + +void GraphEditorWindow::createNodeAtPosition(const QPointF &scenePos) +{ + if (m_graphModel) { + NodeId const newId = m_graphModel->addNode(); + m_graphModel->setNodeData(newId, NodeRole::Position, scenePos); + } +} + +void GraphEditorWindow::createNodeAtCursor() +{ + // Get mouse position in scene coordinates + QPointF posView = mapToScene(mapFromGlobal(QCursor::pos())); + createNodeAtPosition(posView); +} + +void GraphEditorWindow::moveEvent(QMoveEvent *event) +{ + GraphicsView::moveEvent(event); + + // Update toolbar position when main window moves + if (m_toolbar && m_toolbar->isVisible()) { + m_toolbar->positionRelativeToParent(); + } +} + +void GraphEditorWindow::resizeEvent(QResizeEvent *event) +{ + GraphicsView::resizeEvent(event); + + // Update toolbar position when main window resizes + if (m_toolbar && m_toolbar->isVisible()) { + m_toolbar->positionRelativeToParent(); + } +} \ No newline at end of file diff --git a/examples/epen_graph_editor/src/SimpleGraphModel.cpp b/examples/epen_graph_editor/src/SimpleGraphModel.cpp new file mode 100644 index 000000000..7c04440f0 --- /dev/null +++ b/examples/epen_graph_editor/src/SimpleGraphModel.cpp @@ -0,0 +1,294 @@ +#include "SimpleGraphModel.hpp" + +SimpleGraphModel::SimpleGraphModel() + : _nextNodeId{0} +{} + +SimpleGraphModel::~SimpleGraphModel() +{ + // +} + +std::unordered_set SimpleGraphModel::allNodeIds() const +{ + return _nodeIds; +} + +std::unordered_set SimpleGraphModel::allConnectionIds(NodeId const nodeId) const +{ + std::unordered_set result; + + std::copy_if(_connectivity.begin(), + _connectivity.end(), + std::inserter(result, std::end(result)), + [&nodeId](ConnectionId const &cid) { + return cid.inNodeId == nodeId || cid.outNodeId == nodeId; + }); + + return result; +} + +std::unordered_set SimpleGraphModel::connections(NodeId nodeId, + PortType portType, + PortIndex portIndex) const +{ + std::unordered_set result; + + std::copy_if(_connectivity.begin(), + _connectivity.end(), + std::inserter(result, std::end(result)), + [&portType, &portIndex, &nodeId](ConnectionId const &cid) { + return (getNodeId(portType, cid) == nodeId + && getPortIndex(portType, cid) == portIndex); + }); + + return result; +} + +bool SimpleGraphModel::connectionExists(ConnectionId const connectionId) const +{ + return (_connectivity.find(connectionId) != _connectivity.end()); +} + +NodeId SimpleGraphModel::addNode(QString const nodeType) +{ + NodeId newId = newNodeId(); + // Create new node. + _nodeIds.insert(newId); + + Q_EMIT nodeCreated(newId); + + return newId; +} + +bool SimpleGraphModel::connectionPossible(ConnectionId const connectionId) const +{ + return _connectivity.find(connectionId) == _connectivity.end(); +} + +void SimpleGraphModel::addConnection(ConnectionId const connectionId) +{ + _connectivity.insert(connectionId); + + Q_EMIT connectionCreated(connectionId); +} + +bool SimpleGraphModel::nodeExists(NodeId const nodeId) const +{ + return (_nodeIds.find(nodeId) != _nodeIds.end()); +} + +QVariant SimpleGraphModel::nodeData(NodeId nodeId, NodeRole role) const +{ + Q_UNUSED(nodeId); + + QVariant result; + + switch (role) { + case NodeRole::Type: + result = QString("Default Node Type"); + break; + + case NodeRole::Position: + result = _nodeGeometryData[nodeId].pos; + break; + + case NodeRole::Size: + result = _nodeGeometryData[nodeId].size; + break; + + case NodeRole::CaptionVisible: + result = true; + break; + + case NodeRole::Caption: + result = QString("Node"); + break; + + case NodeRole::Style: { + auto style = StyleCollection::nodeStyle(); + result = style.toJson().toVariantMap(); + } break; + + case NodeRole::InternalData: + break; + + case NodeRole::InPortCount: + result = 1u; + break; + + case NodeRole::OutPortCount: + result = 1u; + break; + + case NodeRole::Widget: + result = QVariant(); + break; + } + + return result; +} + +bool SimpleGraphModel::setNodeData(NodeId nodeId, NodeRole role, QVariant value) +{ + bool result = false; + + switch (role) { + case NodeRole::Type: + break; + case NodeRole::Position: { + _nodeGeometryData[nodeId].pos = value.value(); + + Q_EMIT nodePositionUpdated(nodeId); + + result = true; + } break; + + case NodeRole::Size: { + _nodeGeometryData[nodeId].size = value.value(); + result = true; + } break; + + case NodeRole::CaptionVisible: + break; + + case NodeRole::Caption: + break; + + case NodeRole::Style: + break; + + case NodeRole::InternalData: + break; + + case NodeRole::InPortCount: + break; + + case NodeRole::OutPortCount: + break; + + case NodeRole::Widget: + break; + } + + return result; +} + +QVariant SimpleGraphModel::portData(NodeId nodeId, + PortType portType, + PortIndex portIndex, + PortRole role) const +{ + switch (role) { + case PortRole::Data: + return QVariant(); + break; + + case PortRole::DataType: + return QVariant(); + break; + + case PortRole::ConnectionPolicyRole: + return QVariant::fromValue(ConnectionPolicy::One); + break; + + case PortRole::CaptionVisible: + return true; + break; + + case PortRole::Caption: + if (portType == PortType::In) + return QString::fromUtf8("Port In"); + else + return QString::fromUtf8("Port Out"); + + break; + } + + return QVariant(); +} + +bool SimpleGraphModel::setPortData( + NodeId nodeId, PortType portType, PortIndex portIndex, QVariant const &value, PortRole role) +{ + Q_UNUSED(nodeId); + Q_UNUSED(portType); + Q_UNUSED(portIndex); + Q_UNUSED(value); + Q_UNUSED(role); + + return false; +} + +bool SimpleGraphModel::deleteConnection(ConnectionId const connectionId) +{ + bool disconnected = false; + + auto it = _connectivity.find(connectionId); + + if (it != _connectivity.end()) { + disconnected = true; + + _connectivity.erase(it); + } + + if (disconnected) + Q_EMIT connectionDeleted(connectionId); + + return disconnected; +} + +bool SimpleGraphModel::deleteNode(NodeId const nodeId) +{ + // Delete connections to this node first. + auto connectionIds = allConnectionIds(nodeId); + + for (auto &cId : connectionIds) { + deleteConnection(cId); + } + + _nodeIds.erase(nodeId); + _nodeGeometryData.erase(nodeId); + + Q_EMIT nodeDeleted(nodeId); + + return true; +} + +QJsonObject SimpleGraphModel::saveNode(NodeId const nodeId) const +{ + QJsonObject nodeJson; + + nodeJson["id"] = static_cast(nodeId); + + { + QPointF const pos = nodeData(nodeId, NodeRole::Position).value(); + + QJsonObject posJson; + posJson["x"] = pos.x(); + posJson["y"] = pos.y(); + nodeJson["position"] = posJson; + } + + return nodeJson; +} + +void SimpleGraphModel::loadNode(QJsonObject const &nodeJson) +{ + NodeId restoredNodeId = static_cast(nodeJson["id"].toInt()); + + // Next NodeId must be larger that any id existing in the graph + _nextNodeId = std::max(_nextNodeId, restoredNodeId + 1); + + // Create new node. + _nodeIds.insert(restoredNodeId); + + Q_EMIT nodeCreated(restoredNodeId); + + { + QJsonObject posJson = nodeJson["position"].toObject(); + QPointF const pos(posJson["x"].toDouble(), posJson["y"].toDouble()); + + setNodeData(restoredNodeId, NodeRole::Position, pos); + } +} diff --git a/examples/epen_graph_editor/src/main.cpp b/examples/epen_graph_editor/src/main.cpp new file mode 100644 index 000000000..cda863c3f --- /dev/null +++ b/examples/epen_graph_editor/src/main.cpp @@ -0,0 +1,12 @@ +#include "GraphEditorWindow.hpp" +#include + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + GraphEditorWindow view; + view.showNormal(); + + return app.exec(); +} From db93af5dc5d98721f3c2d51ed2f6cc7522f29a71 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Sun, 13 Jul 2025 20:46:59 +0330 Subject: [PATCH 002/124] Limit floating window to main windows boundaries --- .../include/FloatingToolbar.hpp | 25 ++- .../epen_graph_editor/src/FloatingToolbar.cpp | 199 +++++++++++++----- .../src/GraphEditorWindow.cpp | 17 +- 3 files changed, 173 insertions(+), 68 deletions(-) diff --git a/examples/epen_graph_editor/include/FloatingToolbar.hpp b/examples/epen_graph_editor/include/FloatingToolbar.hpp index aef5d583f..834d30823 100644 --- a/examples/epen_graph_editor/include/FloatingToolbar.hpp +++ b/examples/epen_graph_editor/include/FloatingToolbar.hpp @@ -14,8 +14,12 @@ class FloatingToolbar : public QWidget explicit FloatingToolbar(GraphEditorWindow *parent = nullptr); ~FloatingToolbar() = default; - // Position the toolbar relative to the main window - void positionRelativeToParent(); + // Position the toolbar within the parent window + void updatePosition(); + + // Set whether the toolbar is docked to right or left + void setDockedRight(bool right); + bool isDockedRight() const { return m_dockedRight; } signals: void rectangleRequested(); @@ -27,8 +31,13 @@ class FloatingToolbar : public QWidget void resetViewRequested(); protected: - // Override to maintain position relative to parent - void showEvent(QShowEvent *event) override; + // Override for custom painting + void paintEvent(QPaintEvent *event) override; + + // Mouse events for dragging + void mousePressEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; private: void setupUI(); @@ -36,6 +45,14 @@ class FloatingToolbar : public QWidget GraphEditorWindow *m_graphEditor; QVBoxLayout *m_layout; + + // Dragging support + bool m_dragging; + QPoint m_dragStartPosition; + + // Docking position + bool m_dockedRight; + int m_margin; }; #endif // FLOATING_TOOLBAR_HPP \ No newline at end of file diff --git a/examples/epen_graph_editor/src/FloatingToolbar.cpp b/examples/epen_graph_editor/src/FloatingToolbar.cpp index 83a2156a9..354ea5e3e 100644 --- a/examples/epen_graph_editor/src/FloatingToolbar.cpp +++ b/examples/epen_graph_editor/src/FloatingToolbar.cpp @@ -3,90 +3,129 @@ #include #include #include -#include -#include +#include +#include +#include #include #include FloatingToolbar::FloatingToolbar(GraphEditorWindow *parent) - : QWidget(nullptr) // Note: parent is nullptr for top-level window + : QWidget(parent) // Parent is set, making this an embedded widget , m_graphEditor(parent) + , m_dragging(false) + , m_dockedRight(true) + , m_margin(10) { - // Set window flags for a tool window - setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); - setWindowTitle("Tools"); setFixedWidth(150); + // Make it stay on top within the parent widget + setWindowFlags(Qt::SubWindow | Qt::FramelessWindowHint); + setAttribute(Qt::WA_TranslucentBackground); + setupUI(); connectSignals(); - // Set a minimum height to ensure visibility - setMinimumHeight(400); - - // Position the toolbar initially - if (parent) { - positionRelativeToParent(); - } + // Initial position + updatePosition(); } void FloatingToolbar::setupUI() { - m_layout = new QVBoxLayout(this); - m_layout->setContentsMargins(5, 5, 5, 5); + // Create main widget with background + QWidget *contentWidget = new QWidget(this); + contentWidget->setObjectName("ToolbarContent"); + contentWidget->setStyleSheet( + "#ToolbarContent {" + " background-color: #f5f5f5;" + " border: 1px solid #ccc;" + " border-radius: 6px;" + "}" + "QPushButton {" + " padding: 5px;" + " margin: 2px;" + " border: 1px solid #bbb;" + " border-radius: 4px;" + " background-color: white;" + "}" + "QPushButton:hover {" + " background-color: #e0e0e0;" + " border-color: #999;" + "}" + "QPushButton:pressed {" + " background-color: #d0d0d0;" + "}" + ); + + // Main layout for the widget + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->addWidget(contentWidget); - // Add title - QLabel *title = new QLabel("Node Editor Tools"); + // Content layout + m_layout = new QVBoxLayout(contentWidget); + m_layout->setContentsMargins(8, 8, 8, 8); + m_layout->setSpacing(4); + + // Add title (acts as drag handle) + QLabel *title = new QLabel("Tools"); title->setAlignment(Qt::AlignCenter); - title->setStyleSheet("font-weight: bold; padding: 5px; background-color: #f0f0f0;"); + title->setStyleSheet( + "font-weight: bold;" + "padding: 8px;" + "background-color: #e0e0e0;" + "border-radius: 4px;" + "margin-bottom: 5px;" + ); + title->setCursor(Qt::SizeAllCursor); m_layout->addWidget(title); // Node creation section - m_layout->addSpacing(10); + m_layout->addSpacing(5); QLabel *nodeLabel = new QLabel("Nodes:"); - nodeLabel->setStyleSheet("font-weight: bold;"); + nodeLabel->setStyleSheet("font-weight: bold; color: #333;"); m_layout->addWidget(nodeLabel); QPushButton *btnNode = new QPushButton("Create Node"); btnNode->setToolTip("Create a new node at cursor position"); m_layout->addWidget(btnNode); - // Shape tools section (for future use) + // Shape tools section m_layout->addSpacing(10); QLabel *shapeLabel = new QLabel("Shapes:"); - shapeLabel->setStyleSheet("font-weight: bold;"); + shapeLabel->setStyleSheet("font-weight: bold; color: #333;"); m_layout->addWidget(shapeLabel); QPushButton *btnRect = new QPushButton("Rectangle"); - btnRect->setEnabled(false); // Disable for now + btnRect->setEnabled(false); m_layout->addWidget(btnRect); QPushButton *btnCircle = new QPushButton("Circle"); - btnCircle->setEnabled(false); // Disable for now + btnCircle->setEnabled(false); m_layout->addWidget(btnCircle); // Color section m_layout->addSpacing(10); QLabel *colorLabel = new QLabel("Colors:"); - colorLabel->setStyleSheet("font-weight: bold;"); + colorLabel->setStyleSheet("font-weight: bold; color: #333;"); m_layout->addWidget(colorLabel); QPushButton *btnRed = new QPushButton("Red Fill"); - btnRed->setStyleSheet("QPushButton { background-color: #ffcccc; }"); + btnRed->setStyleSheet(btnRed->styleSheet() + "QPushButton { background-color: #ffdddd; }"); m_layout->addWidget(btnRed); QPushButton *btnBlue = new QPushButton("Blue Fill"); - btnBlue->setStyleSheet("QPushButton { background-color: #ccccff; }"); + btnBlue->setStyleSheet(btnBlue->styleSheet() + "QPushButton { background-color: #ddddff; }"); m_layout->addWidget(btnBlue); QPushButton *btnGreen = new QPushButton("Green Fill"); - btnGreen->setStyleSheet("QPushButton { background-color: #ccffcc; }"); + btnGreen->setStyleSheet(btnGreen->styleSheet() + "QPushButton { background-color: #ddffdd; }"); m_layout->addWidget(btnGreen); // View controls section m_layout->addSpacing(10); QLabel *viewLabel = new QLabel("View:"); - viewLabel->setStyleSheet("font-weight: bold;"); + viewLabel->setStyleSheet("font-weight: bold; color: #333;"); m_layout->addWidget(viewLabel); QPushButton *btnZoomIn = new QPushButton("Zoom In"); @@ -101,7 +140,7 @@ void FloatingToolbar::setupUI() // Add stretch to push everything to the top m_layout->addStretch(); - // Store button references for signal connections + // Connect signals connect(btnNode, &QPushButton::clicked, this, &FloatingToolbar::nodeRequested); connect(btnRect, &QPushButton::clicked, this, &FloatingToolbar::rectangleRequested); connect(btnCircle, &QPushButton::clicked, this, &FloatingToolbar::circleRequested); @@ -111,13 +150,15 @@ void FloatingToolbar::setupUI() connect(btnZoomIn, &QPushButton::clicked, this, &FloatingToolbar::zoomInRequested); connect(btnZoomOut, &QPushButton::clicked, this, &FloatingToolbar::zoomOutRequested); connect(btnResetView, &QPushButton::clicked, this, &FloatingToolbar::resetViewRequested); + + // Calculate height based on content + adjustSize(); + setFixedHeight(sizeHint().height()); } void FloatingToolbar::connectSignals() { - // Connect toolbar signals to graphEditor slots if (m_graphEditor) { - // Connect zoom controls connect(this, &FloatingToolbar::zoomInRequested, [this]() { m_graphEditor->scale(1.2, 1.2); }); @@ -129,37 +170,89 @@ void FloatingToolbar::connectSignals() connect(this, &FloatingToolbar::resetViewRequested, [this]() { m_graphEditor->resetTransform(); }); - - // Node creation is handled in GraphEditorWindow - // You'll need to add a slot in GraphEditorWindow to handle this } } -void FloatingToolbar::positionRelativeToParent() +void FloatingToolbar::updatePosition() +{ + if (!m_graphEditor) return; + + int x, y; + + if (m_dockedRight) { + x = m_graphEditor->width() - width() - m_margin; + } else { + x = m_margin; + } + + y = m_margin; + + // Ensure toolbar stays within bounds + x = qMax(m_margin, qMin(x, m_graphEditor->width() - width() - m_margin)); + y = qMax(m_margin, qMin(y, m_graphEditor->height() - height() - m_margin)); + + move(x, y); +} + +void FloatingToolbar::setDockedRight(bool right) +{ + m_dockedRight = right; + updatePosition(); +} + +void FloatingToolbar::paintEvent(QPaintEvent *event) +{ + // Draw shadow + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + // Shadow + QRect shadowRect = rect().adjusted(4, 4, -4, -4); + painter.fillRect(shadowRect, QColor(0, 0, 0, 30)); + + QWidget::paintEvent(event); +} + +void FloatingToolbar::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + QLabel *title = findChild(); + if (title && title->geometry().contains(event->pos())) { + m_dragging = true; + m_dragStartPosition = event->pos(); + } + } + QWidget::mousePressEvent(event); +} + +void FloatingToolbar::mouseMoveEvent(QMouseEvent *event) { - if (m_graphEditor && m_graphEditor->isVisible()) { - // Get the global position of the parent window - QPoint parentPos = m_graphEditor->mapToGlobal(QPoint(0, 0)); + if (m_dragging && (event->buttons() & Qt::LeftButton)) { + QPoint newPos = pos() + event->pos() - m_dragStartPosition; - // Position the toolbar to the right of the main window with some padding - int x = parentPos.x() + m_graphEditor->width() + 10; - int y = parentPos.y(); + // Keep toolbar within parent bounds + int maxX = parentWidget()->width() - width() - m_margin; + int maxY = parentWidget()->height() - height() - m_margin; - // Ensure the toolbar stays on screen - QRect screenGeometry = QApplication::primaryScreen()->availableGeometry(); - if (x + width() > screenGeometry.right()) { - // If toolbar would go off screen, position it to the left instead - x = parentPos.x() - width() - 10; - } + newPos.setX(qMax(m_margin, qMin(newPos.x(), maxX))); + newPos.setY(qMax(m_margin, qMin(newPos.y(), maxY))); - move(x, y); + move(newPos); - qDebug() << "Toolbar repositioned to:" << QPoint(x, y); + // Update docked state based on position + if (newPos.x() < parentWidget()->width() / 2) { + m_dockedRight = false; + } else { + m_dockedRight = true; + } } + QWidget::mouseMoveEvent(event); } -void FloatingToolbar::showEvent(QShowEvent *event) +void FloatingToolbar::mouseReleaseEvent(QMouseEvent *event) { - QWidget::showEvent(event); - positionRelativeToParent(); + if (event->button() == Qt::LeftButton) { + m_dragging = false; + } + QWidget::mouseReleaseEvent(event); } \ No newline at end of file diff --git a/examples/epen_graph_editor/src/GraphEditorWindow.cpp b/examples/epen_graph_editor/src/GraphEditorWindow.cpp index 257122dcf..4ab3fbc4c 100644 --- a/examples/epen_graph_editor/src/GraphEditorWindow.cpp +++ b/examples/epen_graph_editor/src/GraphEditorWindow.cpp @@ -80,7 +80,7 @@ void GraphEditorWindow::createFloatingToolbar() qDebug() << "Main window geometry:" << geometry(); qDebug() << "Main window visible:" << isVisible(); - // Create the floating toolbar + // Create the floating toolbar as a child widget m_toolbar = new FloatingToolbar(this); if (!m_toolbar) { @@ -97,14 +97,12 @@ void GraphEditorWindow::createFloatingToolbar() qDebug() << "Color changed to:" << color.name(); }); - // Set initial position before showing - QPoint mainPos = mapToGlobal(QPoint(0, 0)); - m_toolbar->move(mainPos.x() + width() + 10, mainPos.y()); - // Show the toolbar m_toolbar->show(); m_toolbar->raise(); - m_toolbar->activateWindow(); + + // Update position + m_toolbar->updatePosition(); qDebug() << "Toolbar created. Visible:" << m_toolbar->isVisible() << "Geometry:" << m_toolbar->geometry(); @@ -129,10 +127,7 @@ void GraphEditorWindow::moveEvent(QMoveEvent *event) { GraphicsView::moveEvent(event); - // Update toolbar position when main window moves - if (m_toolbar && m_toolbar->isVisible()) { - m_toolbar->positionRelativeToParent(); - } + // No need to update toolbar position as it's now a child widget } void GraphEditorWindow::resizeEvent(QResizeEvent *event) @@ -141,6 +136,6 @@ void GraphEditorWindow::resizeEvent(QResizeEvent *event) // Update toolbar position when main window resizes if (m_toolbar && m_toolbar->isVisible()) { - m_toolbar->positionRelativeToParent(); + m_toolbar->updatePosition(); } } \ No newline at end of file From 31c8f1ced509e16d1cae9e397979a3665823da30 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Sun, 13 Jul 2025 21:21:32 +0330 Subject: [PATCH 003/124] Setup glyph buttons --- .../include/FloatingToolbar.hpp | 6 + .../epen_graph_editor/src/FloatingToolbar.cpp | 314 +++++++++++------- 2 files changed, 209 insertions(+), 111 deletions(-) diff --git a/examples/epen_graph_editor/include/FloatingToolbar.hpp b/examples/epen_graph_editor/include/FloatingToolbar.hpp index 834d30823..234b122dd 100644 --- a/examples/epen_graph_editor/include/FloatingToolbar.hpp +++ b/examples/epen_graph_editor/include/FloatingToolbar.hpp @@ -4,6 +4,7 @@ #include class QVBoxLayout; +class QPushButton; class GraphEditorWindow; class FloatingToolbar : public QWidget @@ -38,10 +39,15 @@ class FloatingToolbar : public QWidget void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; + + // Override to update position when shown + void showEvent(QShowEvent *event) override; private: void setupUI(); void connectSignals(); + QString createSafeButtonText(const QString &icon, const QString &text); + QPushButton* createRichTextButton(const QString &icon, const QString &text); GraphEditorWindow *m_graphEditor; QVBoxLayout *m_layout; diff --git a/examples/epen_graph_editor/src/FloatingToolbar.cpp b/examples/epen_graph_editor/src/FloatingToolbar.cpp index 354ea5e3e..48662d5e2 100644 --- a/examples/epen_graph_editor/src/FloatingToolbar.cpp +++ b/examples/epen_graph_editor/src/FloatingToolbar.cpp @@ -1,16 +1,18 @@ #include "FloatingToolbar.hpp" #include "GraphEditorWindow.hpp" -#include -#include +#include +#include +#include +#include #include +#include #include #include -#include -#include -#include +#include +#include FloatingToolbar::FloatingToolbar(GraphEditorWindow *parent) - : QWidget(parent) // Parent is set, making this an embedded widget + : QWidget(parent) , m_graphEditor(parent) , m_dragging(false) , m_dockedRight(true) @@ -18,139 +20,222 @@ FloatingToolbar::FloatingToolbar(GraphEditorWindow *parent) { setWindowTitle("Tools"); setFixedWidth(150); - + // Make it stay on top within the parent widget setWindowFlags(Qt::SubWindow | Qt::FramelessWindowHint); setAttribute(Qt::WA_TranslucentBackground); - + setupUI(); connectSignals(); - + // Initial position updatePosition(); } +QString FloatingToolbar::createSafeButtonText(const QString &icon, const QString &text) +{ + // Check if system supports the icon by testing font metrics + QFont testFont = QApplication::font(); + QFontMetrics fm(testFont); + + // Test if the icon character renders properly + QRect boundingRect = fm.boundingRect(icon); + + // If the icon doesn't render properly (too small or empty), use fallback + if (boundingRect.width() < 5 || boundingRect.height() < 5) { + // Use fallback ASCII characters + if (text.contains("Video Input")) + return "< " + text; + if (text.contains("Video Output")) + return "> " + text; + if (text.contains("Process")) + return "* " + text; + if (text.contains("Image")) + return "# " + text; + if (text.contains("Buffer")) + return "= " + text; + if (text.contains("Zoom In")) + return "+ " + text; + if (text.contains("Zoom Out")) + return "- " + text; + if (text.contains("Reset")) + return "R " + text; + return text; + } + + return icon + " " + text; +} + +QPushButton *FloatingToolbar::createRichTextButton(const QString &icon, const QString &text) +{ + QPushButton *button = new QPushButton(); + + // For now, just use the safe text method + button->setText(createSafeButtonText(icon, text)); + + return button; +} + void FloatingToolbar::setupUI() { // Create main widget with background QWidget *contentWidget = new QWidget(this); contentWidget->setObjectName("ToolbarContent"); - contentWidget->setStyleSheet( - "#ToolbarContent {" - " background-color: #f5f5f5;" - " border: 1px solid #ccc;" - " border-radius: 6px;" - "}" - "QPushButton {" - " padding: 5px;" - " margin: 2px;" - " border: 1px solid #bbb;" - " border-radius: 4px;" - " background-color: white;" - "}" - "QPushButton:hover {" - " background-color: #e0e0e0;" - " border-color: #999;" - "}" - "QPushButton:pressed {" - " background-color: #d0d0d0;" - "}" - ); - + + // Platform-specific font settings for better icon support + QFont buttonFont = QApplication::font(); +#ifdef Q_OS_MAC + buttonFont.setFamily("Helvetica Neue"); +#elif defined(Q_OS_WIN) + buttonFont.setFamily("Segoe UI"); +#endif + buttonFont.setPointSize(11); + + contentWidget->setStyleSheet("#ToolbarContent {" + " background-color: #f5f5f5;" + " border: 1px solid #ccc;" + " border-radius: 6px;" + "}" + "QPushButton {" + " padding: 6px 8px;" + " margin: 2px;" + " border: 1px solid #bbb;" + " border-radius: 4px;" + " background-color: white;" + " text-align: left;" + " font-size: 11px;" + "}" + "QPushButton:hover {" + " background-color: #e0e0e0;" + " border-color: #999;" + "}" + "QPushButton:pressed {" + " background-color: #d0d0d0;" + "}" + "QPushButton:disabled {" + " background-color: #f0f0f0;" + " color: #999;" + "}"); + // Main layout for the widget QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->setContentsMargins(0, 0, 0, 0); mainLayout->addWidget(contentWidget); - + // Content layout m_layout = new QVBoxLayout(contentWidget); m_layout->setContentsMargins(8, 8, 8, 8); m_layout->setSpacing(4); - + // Add title (acts as drag handle) QLabel *title = new QLabel("Tools"); title->setAlignment(Qt::AlignCenter); - title->setStyleSheet( - "font-weight: bold;" - "padding: 8px;" - "background-color: #e0e0e0;" - "border-radius: 4px;" - "margin-bottom: 5px;" - ); + title->setStyleSheet("font-weight: bold;" + "padding: 8px;" + "background-color: #e0e0e0;" + "border-radius: 4px;" + "margin-bottom: 5px;"); title->setCursor(Qt::SizeAllCursor); m_layout->addWidget(title); - + // Node creation section m_layout->addSpacing(5); QLabel *nodeLabel = new QLabel("Nodes:"); nodeLabel->setStyleSheet("font-weight: bold; color: #333;"); m_layout->addWidget(nodeLabel); - - QPushButton *btnNode = new QPushButton("Create Node"); - btnNode->setToolTip("Create a new node at cursor position"); - m_layout->addWidget(btnNode); - - // Shape tools section - m_layout->addSpacing(10); - QLabel *shapeLabel = new QLabel("Shapes:"); - shapeLabel->setStyleSheet("font-weight: bold; color: #333;"); - m_layout->addWidget(shapeLabel); - - QPushButton *btnRect = new QPushButton("Rectangle"); - btnRect->setEnabled(false); - m_layout->addWidget(btnRect); - - QPushButton *btnCircle = new QPushButton("Circle"); - btnCircle->setEnabled(false); - m_layout->addWidget(btnCircle); - - // Color section + + // Define icons - using Unicode code points for safety + struct NodeType + { + QString name; + QString icon; + QString fallback; + QString tooltip; + bool enabled; + }; + + QVector nodeTypes = { + {"Video Input", QString::fromUtf8("\u25C0"), "<", "Create a video input node", true}, // ◀ + {"Video Output", QString::fromUtf8("\u25B6"), ">", "Create a video output node", false}, // ▶ + {"Process", QString::fromUtf8("\u2666"), "*", "Create a processing node", true}, // ♦ + {"Image", QString::fromUtf8("\u25A1"), "#", "Create an image node", true}, // □ + {"Buffer", QString::fromUtf8("\u25AC"), "=", "Create a buffer node", true} // ▬ + }; + + // Create buttons with proper icon handling + for (const auto &nodeType : nodeTypes) { + QPushButton *btn = new QPushButton(); + + // Try to use the Unicode icon, fall back to ASCII if needed + QString buttonText = createSafeButtonText(nodeType.icon, nodeType.name); + btn->setText(buttonText); + btn->setToolTip(nodeType.tooltip); + btn->setEnabled(nodeType.enabled); + btn->setFont(buttonFont); + + // Store the node type in a property for later use + btn->setProperty("nodeType", nodeType.name); + + m_layout->addWidget(btn); + + // Connect signal + connect(btn, &QPushButton::clicked, [this, nodeType]() { + emit nodeRequested(); + // You can emit a specific signal with node type info if needed + // emit specificNodeRequested(nodeType.name); + }); + } + + // Separator m_layout->addSpacing(10); - QLabel *colorLabel = new QLabel("Colors:"); - colorLabel->setStyleSheet("font-weight: bold; color: #333;"); - m_layout->addWidget(colorLabel); - - QPushButton *btnRed = new QPushButton("Red Fill"); - btnRed->setStyleSheet(btnRed->styleSheet() + "QPushButton { background-color: #ffdddd; }"); - m_layout->addWidget(btnRed); - - QPushButton *btnBlue = new QPushButton("Blue Fill"); - btnBlue->setStyleSheet(btnBlue->styleSheet() + "QPushButton { background-color: #ddddff; }"); - m_layout->addWidget(btnBlue); - - QPushButton *btnGreen = new QPushButton("Green Fill"); - btnGreen->setStyleSheet(btnGreen->styleSheet() + "QPushButton { background-color: #ddffdd; }"); - m_layout->addWidget(btnGreen); - + QFrame *separator = new QFrame(); + separator->setFrameShape(QFrame::HLine); + separator->setFrameShadow(QFrame::Sunken); + m_layout->addWidget(separator); + m_layout->addSpacing(5); + // View controls section - m_layout->addSpacing(10); QLabel *viewLabel = new QLabel("View:"); viewLabel->setStyleSheet("font-weight: bold; color: #333;"); m_layout->addWidget(viewLabel); - - QPushButton *btnZoomIn = new QPushButton("Zoom In"); + + // View control buttons with safe icons + struct ViewControl + { + QString name; + QString icon; + QString fallback; + }; + + QVector viewControls = { + {"Zoom In", QString::fromUtf8("\u2295"), "+"}, // ⊕ + {"Zoom Out", QString::fromUtf8("\u2296"), "-"}, // ⊖ + {"Reset View", QString::fromUtf8("\u21BA"), "R"} // ↺ + }; + + QPushButton *btnZoomIn = new QPushButton( + createSafeButtonText(viewControls[0].icon, viewControls[0].name)); + QPushButton *btnZoomOut = new QPushButton( + createSafeButtonText(viewControls[1].icon, viewControls[1].name)); + QPushButton *btnResetView = new QPushButton( + createSafeButtonText(viewControls[2].icon, viewControls[2].name)); + + btnZoomIn->setFont(buttonFont); + btnZoomOut->setFont(buttonFont); + btnResetView->setFont(buttonFont); + m_layout->addWidget(btnZoomIn); - - QPushButton *btnZoomOut = new QPushButton("Zoom Out"); m_layout->addWidget(btnZoomOut); - - QPushButton *btnResetView = new QPushButton("Reset View"); m_layout->addWidget(btnResetView); - - // Add stretch to push everything to the top - m_layout->addStretch(); - - // Connect signals - connect(btnNode, &QPushButton::clicked, this, &FloatingToolbar::nodeRequested); - connect(btnRect, &QPushButton::clicked, this, &FloatingToolbar::rectangleRequested); - connect(btnCircle, &QPushButton::clicked, this, &FloatingToolbar::circleRequested); - connect(btnRed, &QPushButton::clicked, [this]() { emit fillColorChanged(Qt::red); }); - connect(btnBlue, &QPushButton::clicked, [this]() { emit fillColorChanged(Qt::blue); }); - connect(btnGreen, &QPushButton::clicked, [this]() { emit fillColorChanged(Qt::green); }); + + // Connect view control signals connect(btnZoomIn, &QPushButton::clicked, this, &FloatingToolbar::zoomInRequested); connect(btnZoomOut, &QPushButton::clicked, this, &FloatingToolbar::zoomOutRequested); connect(btnResetView, &QPushButton::clicked, this, &FloatingToolbar::resetViewRequested); - + + // Add stretch to push everything to the top + m_layout->addStretch(); + // Calculate height based on content adjustSize(); setFixedHeight(sizeHint().height()); @@ -162,11 +247,11 @@ void FloatingToolbar::connectSignals() connect(this, &FloatingToolbar::zoomInRequested, [this]() { m_graphEditor->scale(1.2, 1.2); }); - + connect(this, &FloatingToolbar::zoomOutRequested, [this]() { m_graphEditor->scale(0.8, 0.8); }); - + connect(this, &FloatingToolbar::resetViewRequested, [this]() { m_graphEditor->resetTransform(); }); @@ -175,22 +260,23 @@ void FloatingToolbar::connectSignals() void FloatingToolbar::updatePosition() { - if (!m_graphEditor) return; - + if (!m_graphEditor) + return; + int x, y; - + if (m_dockedRight) { x = m_graphEditor->width() - width() - m_margin; } else { x = m_margin; } - + y = m_margin; - + // Ensure toolbar stays within bounds x = qMax(m_margin, qMin(x, m_graphEditor->width() - width() - m_margin)); y = qMax(m_margin, qMin(y, m_graphEditor->height() - height() - m_margin)); - + move(x, y); } @@ -205,18 +291,18 @@ void FloatingToolbar::paintEvent(QPaintEvent *event) // Draw shadow QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); - + // Shadow QRect shadowRect = rect().adjusted(4, 4, -4, -4); painter.fillRect(shadowRect, QColor(0, 0, 0, 30)); - + QWidget::paintEvent(event); } void FloatingToolbar::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { - QLabel *title = findChild(); + QLabel *title = findChild(); if (title && title->geometry().contains(event->pos())) { m_dragging = true; m_dragStartPosition = event->pos(); @@ -229,16 +315,16 @@ void FloatingToolbar::mouseMoveEvent(QMouseEvent *event) { if (m_dragging && (event->buttons() & Qt::LeftButton)) { QPoint newPos = pos() + event->pos() - m_dragStartPosition; - + // Keep toolbar within parent bounds int maxX = parentWidget()->width() - width() - m_margin; int maxY = parentWidget()->height() - height() - m_margin; - + newPos.setX(qMax(m_margin, qMin(newPos.x(), maxX))); newPos.setY(qMax(m_margin, qMin(newPos.y(), maxY))); - + move(newPos); - + // Update docked state based on position if (newPos.x() < parentWidget()->width() / 2) { m_dockedRight = false; @@ -255,4 +341,10 @@ void FloatingToolbar::mouseReleaseEvent(QMouseEvent *event) m_dragging = false; } QWidget::mouseReleaseEvent(event); +} + +void FloatingToolbar::showEvent(QShowEvent *event) +{ + QWidget::showEvent(event); + updatePosition(); } \ No newline at end of file From 9a0490d26d835191904f3b3cd9f8039fae66c814 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Sun, 13 Jul 2025 23:00:00 +0330 Subject: [PATCH 004/124] Draggable toolbar buttons. --- examples/epen_graph_editor/include/.DS_Store | Bin 0 -> 6148 bytes .../include/DraggableButton.hpp | 14 ++++ .../include/FloatingToolbar.hpp | 14 ++-- .../include/GraphEditorWindow.hpp | 14 +++- examples/epen_graph_editor/src/.DS_Store | Bin 0 -> 6148 bytes .../epen_graph_editor/src/DraggableButton.cpp | 25 ++++++ .../epen_graph_editor/src/FloatingToolbar.cpp | 52 ++++++------ .../src/GraphEditorWindow.cpp | 79 ++++++++++++------ 8 files changed, 134 insertions(+), 64 deletions(-) create mode 100644 examples/epen_graph_editor/include/.DS_Store create mode 100644 examples/epen_graph_editor/include/DraggableButton.hpp create mode 100644 examples/epen_graph_editor/src/.DS_Store create mode 100644 examples/epen_graph_editor/src/DraggableButton.cpp diff --git a/examples/epen_graph_editor/include/.DS_Store b/examples/epen_graph_editor/include/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..18f8c01379d4e2639d42145250c4ca946e6eeb61 GIT binary patch literal 6148 zcmeHK!Ab)`41Lia3SJ5-coF6c3jV=bTE&B>3SMoyVujT$rQ&t}$WPRlWR!MYuOgDb z%u6%L+t~-5*#MByOL+zi0Q5N&MV$`QaOcuqPTnVqacuC2XFT8rbqCR34C&qvae<0E zo?(0cHDhze))-=m6;@YOy_i?^oE4NyPKm>JGkdXPTrzjY%q1o$slcK zCY-mJjxc4-6PYU9Z?RsJqhzG|f#P_82y!uf2rUq>M$z#*r&D@lv9fN^UX4%Nb8OugKUqdO0LF zACjN^*}RB7o&3qtA%$bip+G3GtAO^tw1M9L6aHm7n|w=&DHI3={;LAg8&Ah0zFods zzrCm4wTa`7LrwDb^!21Z^NNg(qq1n+%8BtIV1mRH3jBfsAD&1- Awg3PC literal 0 HcmV?d00001 diff --git a/examples/epen_graph_editor/include/DraggableButton.hpp b/examples/epen_graph_editor/include/DraggableButton.hpp new file mode 100644 index 000000000..2a7f8b9fd --- /dev/null +++ b/examples/epen_graph_editor/include/DraggableButton.hpp @@ -0,0 +1,14 @@ +#ifndef DRAGGABLE_BUTTON +#define DRAGGABLE_BUTTON +#include + +class DraggableButton : public QPushButton +{ +public: + explicit DraggableButton(QString actionName, QWidget *parent = nullptr); + void mousePressEvent(QMouseEvent *event) override; + +private: + QString _actionName; +}; +#endif \ No newline at end of file diff --git a/examples/epen_graph_editor/include/FloatingToolbar.hpp b/examples/epen_graph_editor/include/FloatingToolbar.hpp index 234b122dd..41ca0f220 100644 --- a/examples/epen_graph_editor/include/FloatingToolbar.hpp +++ b/examples/epen_graph_editor/include/FloatingToolbar.hpp @@ -1,6 +1,7 @@ #ifndef FLOATING_TOOLBAR_HPP #define FLOATING_TOOLBAR_HPP +#include "DraggableButton.hpp" #include class QVBoxLayout; @@ -17,7 +18,7 @@ class FloatingToolbar : public QWidget // Position the toolbar within the parent window void updatePosition(); - + // Set whether the toolbar is docked to right or left void setDockedRight(bool right); bool isDockedRight() const { return m_dockedRight; } @@ -25,7 +26,7 @@ class FloatingToolbar : public QWidget signals: void rectangleRequested(); void circleRequested(); - void nodeRequested(); + void specificNodeRequested(QString actionName); void fillColorChanged(const QColor &color); void zoomInRequested(); void zoomOutRequested(); @@ -34,12 +35,12 @@ class FloatingToolbar : public QWidget protected: // Override for custom painting void paintEvent(QPaintEvent *event) override; - + // Mouse events for dragging void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; - + // Override to update position when shown void showEvent(QShowEvent *event) override; @@ -47,15 +48,14 @@ class FloatingToolbar : public QWidget void setupUI(); void connectSignals(); QString createSafeButtonText(const QString &icon, const QString &text); - QPushButton* createRichTextButton(const QString &icon, const QString &text); GraphEditorWindow *m_graphEditor; QVBoxLayout *m_layout; - + // Dragging support bool m_dragging; QPoint m_dragStartPosition; - + // Docking position bool m_dockedRight; int m_margin; diff --git a/examples/epen_graph_editor/include/GraphEditorWindow.hpp b/examples/epen_graph_editor/include/GraphEditorWindow.hpp index dec9c29a8..a42e5f3b3 100644 --- a/examples/epen_graph_editor/include/GraphEditorWindow.hpp +++ b/examples/epen_graph_editor/include/GraphEditorWindow.hpp @@ -3,6 +3,8 @@ #include "QtNodes/GraphicsView" #include +#include +#include using QtNodes::GraphicsView; @@ -19,23 +21,29 @@ class GraphEditorWindow : public GraphicsView public slots: // Slot for creating a node at a specific position void createNodeAtPosition(const QPointF &scenePos); - + // Slot for creating a node at cursor position void createNodeAtCursor(); + void goToMode(QString mode); protected: // Override to maintain toolbar position void moveEvent(QMoveEvent *event) override; void resizeEvent(QResizeEvent *event) override; void showEvent(QShowEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void dragEnterEvent(QDragEnterEvent *event) override; + void dropEvent(QDropEvent *event) override; + void dragMoveEvent(QDragMoveEvent *event) override; private: void createFloatingToolbar(); void setupNodeCreation(); - + QPointer m_toolbar; SimpleGraphModel *m_graphModel; - bool m_toolbarCreated; // This was missing! + bool m_toolbarCreated; // This was missing! + QString _currentMode; }; #endif // GRAPH_EDITOR_WINDOW \ No newline at end of file diff --git a/examples/epen_graph_editor/src/.DS_Store b/examples/epen_graph_editor/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..aeb2d1c7faa2bbe9d7b1a3b487b7c19388a11a10 GIT binary patch literal 6148 zcmeHK!AiqG5Peg7h3SMm*Q6V*@RJ`Wy$M}i*W_BrU60b#c z24>!7GBcZfSu$AwGI}d6fB}Gns@OZE=@7lI+LB)M^oe3M)_B1yo^Xe%7444S$bi1P zV_c!+8=GPK{Z;hk^sO+&97`;3%4(jMRn81<7x^F#zf5dlr?_V9jFHcnpx{nev*rr- zwkHaX-@7Z}vQa6)f^~E!bM*In;j9zf&5|3L?amzUiddluPa^9$8%W&fiI0MeW zKVX18TO~OP=++r<2AqKn1NwbPsft;|I-q?zXzU0;)Za)Gj`b{|IcdZ!VjYloC=ybM zAywiLLqa +#include +#include +#include +#include + +DraggableButton::DraggableButton(QString actionName, QWidget *parent) + : QPushButton(parent) + , _actionName(actionName) +{ + setMinimumSize(20, 20); + setStyleSheet("background-color: lightgray; border: 1px solid black;"); +} + +void DraggableButton::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + QDrag *drag = new QDrag(this); + QMimeData *mimeData = new QMimeData; + mimeData->setText(_actionName); + drag->setMimeData(mimeData); + drag->exec(Qt::CopyAction); + } +} \ No newline at end of file diff --git a/examples/epen_graph_editor/src/FloatingToolbar.cpp b/examples/epen_graph_editor/src/FloatingToolbar.cpp index 48662d5e2..5c28a9fb7 100644 --- a/examples/epen_graph_editor/src/FloatingToolbar.cpp +++ b/examples/epen_graph_editor/src/FloatingToolbar.cpp @@ -1,5 +1,6 @@ #include "FloatingToolbar.hpp" #include "GraphEditorWindow.hpp" +#include "QPushButton" #include #include #include @@ -8,7 +9,6 @@ #include #include #include -#include #include FloatingToolbar::FloatingToolbar(GraphEditorWindow *parent) @@ -66,16 +66,6 @@ QString FloatingToolbar::createSafeButtonText(const QString &icon, const QString return icon + " " + text; } -QPushButton *FloatingToolbar::createRichTextButton(const QString &icon, const QString &text) -{ - QPushButton *button = new QPushButton(); - - // For now, just use the safe text method - button->setText(createSafeButtonText(icon, text)); - - return button; -} - void FloatingToolbar::setupUI() { // Create main widget with background @@ -96,7 +86,7 @@ void FloatingToolbar::setupUI() " border: 1px solid #ccc;" " border-radius: 6px;" "}" - "QPushButton {" + "DraggableButton {" " padding: 6px 8px;" " margin: 2px;" " border: 1px solid #bbb;" @@ -105,14 +95,14 @@ void FloatingToolbar::setupUI() " text-align: left;" " font-size: 11px;" "}" - "QPushButton:hover {" + "DraggableButton:hover {" " background-color: #e0e0e0;" " border-color: #999;" "}" - "QPushButton:pressed {" + "DraggableButton:pressed {" " background-color: #d0d0d0;" "}" - "QPushButton:disabled {" + "DraggableButton:disabled {" " background-color: #f0f0f0;" " color: #999;" "}"); @@ -152,38 +142,44 @@ void FloatingToolbar::setupUI() QString fallback; QString tooltip; bool enabled; + QString actionName; }; QVector nodeTypes = { - {"Video Input", QString::fromUtf8("\u25C0"), "<", "Create a video input node", true}, // ◀ - {"Video Output", QString::fromUtf8("\u25B6"), ">", "Create a video output node", false}, // ▶ - {"Process", QString::fromUtf8("\u2666"), "*", "Create a processing node", true}, // ♦ - {"Image", QString::fromUtf8("\u25A1"), "#", "Create an image node", true}, // □ - {"Buffer", QString::fromUtf8("\u25AC"), "=", "Create a buffer node", true} // ▬ + {"Video Input", + QString::fromUtf8("\u25C0"), + "<", + "Create a video input node", + true, + "input"}, // ◀ + {"Video Output", + QString::fromUtf8("\u25B6"), + ">", + "Create a video output node", + false, + "output"}, // ▶ + {"Process", QString::fromUtf8("\u2666"), "*", "Create a processing node", true, "process"}, // ♦ + {"Image", QString::fromUtf8("\u25A1"), "#", "Create an image node", true, "image"}, // □ + {"Buffer", QString::fromUtf8("\u25AC"), "=", "Create a buffer node", true, "buffer"} // ▬ }; // Create buttons with proper icon handling for (const auto &nodeType : nodeTypes) { - QPushButton *btn = new QPushButton(); + DraggableButton *btn = new DraggableButton(nodeType.actionName, this); // Try to use the Unicode icon, fall back to ASCII if needed QString buttonText = createSafeButtonText(nodeType.icon, nodeType.name); btn->setText(buttonText); btn->setToolTip(nodeType.tooltip); btn->setEnabled(nodeType.enabled); + btn->setCheckable(true); + btn->setChecked(true); btn->setFont(buttonFont); // Store the node type in a property for later use btn->setProperty("nodeType", nodeType.name); m_layout->addWidget(btn); - - // Connect signal - connect(btn, &QPushButton::clicked, [this, nodeType]() { - emit nodeRequested(); - // You can emit a specific signal with node type info if needed - // emit specificNodeRequested(nodeType.name); - }); } // Separator diff --git a/examples/epen_graph_editor/src/GraphEditorWindow.cpp b/examples/epen_graph_editor/src/GraphEditorWindow.cpp index 4ab3fbc4c..5b9b77113 100644 --- a/examples/epen_graph_editor/src/GraphEditorWindow.cpp +++ b/examples/epen_graph_editor/src/GraphEditorWindow.cpp @@ -1,17 +1,17 @@ #include "GraphEditorWindow.hpp" #include "FloatingToolbar.hpp" #include "SimpleGraphModel.hpp" -#include -#include -#include -#include #include +#include #include +#include #include #include #include #include -#include +#include +#include +#include using QtNodes::BasicGraphicsScene; using QtNodes::ConnectionStyle; @@ -22,6 +22,7 @@ GraphEditorWindow::GraphEditorWindow() : GraphicsView() , m_toolbar(nullptr) , m_toolbarCreated(false) + , _currentMode("pan") { // Create the graph model m_graphModel = new SimpleGraphModel(); @@ -29,13 +30,14 @@ GraphEditorWindow::GraphEditorWindow() // Create and set the scene auto scene = new BasicGraphicsScene(*m_graphModel); setScene(scene); - + // Setup context menu setupNodeCreation(); - + setWindowTitle("Simple Node Graph"); resize(800, 600); - + + setAcceptDrops(true); // Don't create toolbar here - wait for showEvent } @@ -48,24 +50,22 @@ GraphEditorWindow::~GraphEditorWindow() void GraphEditorWindow::showEvent(QShowEvent *event) { GraphicsView::showEvent(event); - + // Create toolbar only when window is shown for the first time if (!m_toolbarCreated && isVisible()) { m_toolbarCreated = true; // Use a timer to ensure the window is fully rendered - QTimer::singleShot(100, this, [this]() { - createFloatingToolbar(); - }); + QTimer::singleShot(100, this, [this]() { createFloatingToolbar(); }); } } void GraphEditorWindow::setupNodeCreation() { setContextMenuPolicy(Qt::ActionsContextMenu); - + QAction *createNodeAction = new QAction(QStringLiteral("Create Node"), this); connect(createNodeAction, &QAction::triggered, this, &GraphEditorWindow::createNodeAtCursor); - + // Insert at the beginning of the actions list if (!actions().isEmpty()) { insertAction(actions().front(), createNodeAction); @@ -79,32 +79,31 @@ void GraphEditorWindow::createFloatingToolbar() qDebug() << "Creating floating toolbar..."; qDebug() << "Main window geometry:" << geometry(); qDebug() << "Main window visible:" << isVisible(); - + // Create the floating toolbar as a child widget m_toolbar = new FloatingToolbar(this); - + if (!m_toolbar) { qDebug() << "Failed to create toolbar!"; return; } - + // Connect toolbar signals - connect(m_toolbar, &FloatingToolbar::nodeRequested, - this, &GraphEditorWindow::createNodeAtCursor); - + connect(m_toolbar, &FloatingToolbar::specificNodeRequested, this, &GraphEditorWindow::goToMode); + // Connect other signals as needed connect(m_toolbar, &FloatingToolbar::fillColorChanged, [this](const QColor &color) { qDebug() << "Color changed to:" << color.name(); }); - + // Show the toolbar m_toolbar->show(); m_toolbar->raise(); - + // Update position m_toolbar->updatePosition(); - - qDebug() << "Toolbar created. Visible:" << m_toolbar->isVisible() + + qDebug() << "Toolbar created. Visible:" << m_toolbar->isVisible() << "Geometry:" << m_toolbar->geometry(); } @@ -126,16 +125,44 @@ void GraphEditorWindow::createNodeAtCursor() void GraphEditorWindow::moveEvent(QMoveEvent *event) { GraphicsView::moveEvent(event); - + // No need to update toolbar position as it's now a child widget } void GraphEditorWindow::resizeEvent(QResizeEvent *event) { GraphicsView::resizeEvent(event); - + // Update toolbar position when main window resizes if (m_toolbar && m_toolbar->isVisible()) { m_toolbar->updatePosition(); } +} + +void GraphEditorWindow::goToMode(QString mode) +{ + _currentMode = mode; +} + +void GraphEditorWindow::mousePressEvent(QMouseEvent *event) +{ + GraphicsView::mousePressEvent(event); +} + +void GraphEditorWindow::dragEnterEvent(QDragEnterEvent *event) +{ + event->acceptProposedAction(); +} + +void GraphEditorWindow::dropEvent(QDropEvent *event) +{ + qDebug() << event->mimeData()->text(); + event->acceptProposedAction(); + QPointF scenePos = mapToScene(event->position().toPoint()); + createNodeAtPosition(scenePos); +} + +void GraphEditorWindow::dragMoveEvent(QDragMoveEvent *event) +{ + event->acceptProposedAction(); } \ No newline at end of file From f41bd81ef147be752851bb5b5a287d4e1fee163c Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Mon, 14 Jul 2025 00:53:20 +0330 Subject: [PATCH 005/124] Toolbox Docking --- .../include/FloatingToolbar.hpp | 41 +- .../epen_graph_editor/src/FloatingToolbar.cpp | 354 +++++++++++++----- .../src/GraphEditorWindow.cpp | 22 +- 3 files changed, 296 insertions(+), 121 deletions(-) diff --git a/examples/epen_graph_editor/include/FloatingToolbar.hpp b/examples/epen_graph_editor/include/FloatingToolbar.hpp index 41ca0f220..d157afcc2 100644 --- a/examples/epen_graph_editor/include/FloatingToolbar.hpp +++ b/examples/epen_graph_editor/include/FloatingToolbar.hpp @@ -7,25 +7,32 @@ class QVBoxLayout; class QPushButton; class GraphEditorWindow; +class QPropertyAnimation; +class QScrollArea; class FloatingToolbar : public QWidget { Q_OBJECT public: + enum DockPosition { + Floating, + DockedLeft, + DockedRight + }; + explicit FloatingToolbar(GraphEditorWindow *parent = nullptr); ~FloatingToolbar() = default; // Position the toolbar within the parent window void updatePosition(); - // Set whether the toolbar is docked to right or left - void setDockedRight(bool right); - bool isDockedRight() const { return m_dockedRight; } + // Docking functions + void setDockPosition(DockPosition position); + DockPosition getDockPosition() const { return m_dockPosition; } + bool isDocked() const { return m_dockPosition != Floating; } signals: - void rectangleRequested(); - void circleRequested(); void specificNodeRequested(QString actionName); void fillColorChanged(const QColor &color); void zoomInRequested(); @@ -43,22 +50,38 @@ class FloatingToolbar : public QWidget // Override to update position when shown void showEvent(QShowEvent *event) override; + void resizeEvent(QResizeEvent *event) override; private: void setupUI(); void connectSignals(); QString createSafeButtonText(const QString &icon, const QString &text); - + + // Docking helpers + DockPosition checkDockingZone(const QPoint &pos); + void applyDocking(DockPosition position); + void updateDockedGeometry(); + GraphEditorWindow *m_graphEditor; QVBoxLayout *m_layout; + QWidget *m_contentWidget; + QScrollArea *m_scrollArea; // Dragging support bool m_dragging; QPoint m_dragStartPosition; + QRect m_floatingGeometry; // Remember size and position when floating - // Docking position - bool m_dockedRight; - int m_margin; + // Docking state + DockPosition m_dockPosition; + DockPosition m_previewDockPosition; + int m_dockMargin; + int m_dockingDistance; // Distance from edge to trigger docking + int m_dockedWidth; // Width when docked + int _floatHeight; + + // Animation + QPropertyAnimation *m_geometryAnimation; }; #endif // FLOATING_TOOLBAR_HPP \ No newline at end of file diff --git a/examples/epen_graph_editor/src/FloatingToolbar.cpp b/examples/epen_graph_editor/src/FloatingToolbar.cpp index 5c28a9fb7..07585cd2a 100644 --- a/examples/epen_graph_editor/src/FloatingToolbar.cpp +++ b/examples/epen_graph_editor/src/FloatingToolbar.cpp @@ -9,41 +9,54 @@ #include #include #include +#include +#include #include FloatingToolbar::FloatingToolbar(GraphEditorWindow *parent) - : QWidget(parent) + : QWidget(parent) // Always a child widget , m_graphEditor(parent) , m_dragging(false) - , m_dockedRight(true) - , m_margin(10) + , m_dockPosition(Floating) + , m_previewDockPosition(Floating) + , m_dockMargin(0) // No margin when docked + , m_dockingDistance(40) + , m_dockedWidth(200) // Wider when docked { - setWindowTitle("Tools"); - setFixedWidth(150); - - // Make it stay on top within the parent widget + // Keep it as a child widget with these flags setWindowFlags(Qt::SubWindow | Qt::FramelessWindowHint); setAttribute(Qt::WA_TranslucentBackground); + // Create animation for smooth transitions + m_geometryAnimation = new QPropertyAnimation(this, "geometry"); + m_geometryAnimation->setDuration(200); + m_geometryAnimation->setEasingCurve(QEasingCurve::OutCubic); + setupUI(); connectSignals(); - // Initial position - updatePosition(); + // Initial floating size and position + setFixedWidth(150); + if (parent) { + m_floatingGeometry = QRect((parent->width() - 150) / 2, + (parent->height() - height()) / 2, + 150, + height()); + setGeometry(m_floatingGeometry); + } + + // Ensure toolbar is on top + raise(); + _floatHeight = height(); } QString FloatingToolbar::createSafeButtonText(const QString &icon, const QString &text) { - // Check if system supports the icon by testing font metrics QFont testFont = QApplication::font(); QFontMetrics fm(testFont); - - // Test if the icon character renders properly QRect boundingRect = fm.boundingRect(icon); - // If the icon doesn't render properly (too small or empty), use fallback if (boundingRect.width() < 5 || boundingRect.height() < 5) { - // Use fallback ASCII characters if (text.contains("Video Input")) return "< " + text; if (text.contains("Video Output")) @@ -68,11 +81,16 @@ QString FloatingToolbar::createSafeButtonText(const QString &icon, const QString void FloatingToolbar::setupUI() { - // Create main widget with background - QWidget *contentWidget = new QWidget(this); - contentWidget->setObjectName("ToolbarContent"); + // Create scroll area for when docked + m_scrollArea = new QScrollArea(this); + m_scrollArea->setWidgetResizable(true); + m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + m_scrollArea->setFrameShape(QFrame::NoFrame); + + m_contentWidget = new QWidget(); + m_contentWidget->setObjectName("ToolbarContent"); - // Platform-specific font settings for better icon support QFont buttonFont = QApplication::font(); #ifdef Q_OS_MAC buttonFont.setFamily("Helvetica Neue"); @@ -81,43 +99,64 @@ void FloatingToolbar::setupUI() #endif buttonFont.setPointSize(11); - contentWidget->setStyleSheet("#ToolbarContent {" - " background-color: #f5f5f5;" - " border: 1px solid #ccc;" - " border-radius: 6px;" - "}" - "DraggableButton {" - " padding: 6px 8px;" - " margin: 2px;" - " border: 1px solid #bbb;" - " border-radius: 4px;" - " background-color: white;" - " text-align: left;" - " font-size: 11px;" - "}" - "DraggableButton:hover {" - " background-color: #e0e0e0;" - " border-color: #999;" - "}" - "DraggableButton:pressed {" - " background-color: #d0d0d0;" - "}" - "DraggableButton:disabled {" - " background-color: #f0f0f0;" - " color: #999;" - "}"); - - // Main layout for the widget + m_scrollArea->setStyleSheet("QScrollArea {" + " background: transparent;" + " border: none;" + "}" + "QScrollBar:vertical {" + " background: #f0f0f0;" + " width: 10px;" + " border-radius: 5px;" + "}" + "QScrollBar::handle:vertical {" + " background: #c0c0c0;" + " border-radius: 5px;" + " min-height: 20px;" + "}" + "QScrollBar::handle:vertical:hover {" + " background: #a0a0a0;" + "}"); + + m_contentWidget->setStyleSheet("#ToolbarContent {" + " background-color: #f5f5f5;" + " border: 1px solid #ccc;" + " border-radius: 6px;" + "}" + "DraggableButton {" + " padding: 6px 8px;" + " margin: 2px;" + " border: 1px solid #bbb;" + " border-radius: 4px;" + " background-color: white;" + " text-align: left;" + " font-size: 11px;" + "}" + "DraggableButton:hover {" + " background-color: #e0e0e0;" + " border-color: #999;" + "}" + "DraggableButton:pressed {" + " background-color: #d0d0d0;" + "}" + "DraggableButton:disabled {" + " background-color: #f0f0f0;" + " color: #999;" + "}"); + + // Set scroll area content + m_scrollArea->setWidget(m_contentWidget); + + // Main layout for this widget QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->setContentsMargins(0, 0, 0, 0); - mainLayout->addWidget(contentWidget); + mainLayout->addWidget(m_scrollArea); // Content layout - m_layout = new QVBoxLayout(contentWidget); + m_layout = new QVBoxLayout(m_contentWidget); m_layout->setContentsMargins(8, 8, 8, 8); m_layout->setSpacing(4); - // Add title (acts as drag handle) + // Title bar for dragging QLabel *title = new QLabel("Tools"); title->setAlignment(Qt::AlignCenter); title->setStyleSheet("font-weight: bold;" @@ -134,7 +173,6 @@ void FloatingToolbar::setupUI() nodeLabel->setStyleSheet("font-weight: bold; color: #333;"); m_layout->addWidget(nodeLabel); - // Define icons - using Unicode code points for safety struct NodeType { QString name; @@ -146,28 +184,19 @@ void FloatingToolbar::setupUI() }; QVector nodeTypes = { - {"Video Input", - QString::fromUtf8("\u25C0"), - "<", - "Create a video input node", - true, - "input"}, // ◀ + {"Video Input", QString::fromUtf8("\u25C0"), "<", "Create a video input node", true, "input"}, {"Video Output", QString::fromUtf8("\u25B6"), ">", "Create a video output node", false, - "output"}, // ▶ - {"Process", QString::fromUtf8("\u2666"), "*", "Create a processing node", true, "process"}, // ♦ - {"Image", QString::fromUtf8("\u25A1"), "#", "Create an image node", true, "image"}, // □ - {"Buffer", QString::fromUtf8("\u25AC"), "=", "Create a buffer node", true, "buffer"} // ▬ - }; + "output"}, + {"Process", QString::fromUtf8("\u2666"), "*", "Create a processing node", true, "process"}, + {"Image", QString::fromUtf8("\u25A1"), "#", "Create an image node", true, "image"}, + {"Buffer", QString::fromUtf8("\u25AC"), "=", "Create a buffer node", true, "buffer"}}; - // Create buttons with proper icon handling for (const auto &nodeType : nodeTypes) { DraggableButton *btn = new DraggableButton(nodeType.actionName, this); - - // Try to use the Unicode icon, fall back to ASCII if needed QString buttonText = createSafeButtonText(nodeType.icon, nodeType.name); btn->setText(buttonText); btn->setToolTip(nodeType.tooltip); @@ -175,10 +204,7 @@ void FloatingToolbar::setupUI() btn->setCheckable(true); btn->setChecked(true); btn->setFont(buttonFont); - - // Store the node type in a property for later use btn->setProperty("nodeType", nodeType.name); - m_layout->addWidget(btn); } @@ -190,12 +216,11 @@ void FloatingToolbar::setupUI() m_layout->addWidget(separator); m_layout->addSpacing(5); - // View controls section + // View controls QLabel *viewLabel = new QLabel("View:"); viewLabel->setStyleSheet("font-weight: bold; color: #333;"); m_layout->addWidget(viewLabel); - // View control buttons with safe icons struct ViewControl { QString name; @@ -203,11 +228,9 @@ void FloatingToolbar::setupUI() QString fallback; }; - QVector viewControls = { - {"Zoom In", QString::fromUtf8("\u2295"), "+"}, // ⊕ - {"Zoom Out", QString::fromUtf8("\u2296"), "-"}, // ⊖ - {"Reset View", QString::fromUtf8("\u21BA"), "R"} // ↺ - }; + QVector viewControls = {{"Zoom In", QString::fromUtf8("\u2295"), "+"}, + {"Zoom Out", QString::fromUtf8("\u2296"), "-"}, + {"Reset View", QString::fromUtf8("\u21BA"), "R"}}; QPushButton *btnZoomIn = new QPushButton( createSafeButtonText(viewControls[0].icon, viewControls[0].name)); @@ -224,17 +247,15 @@ void FloatingToolbar::setupUI() m_layout->addWidget(btnZoomOut); m_layout->addWidget(btnResetView); - // Connect view control signals connect(btnZoomIn, &QPushButton::clicked, this, &FloatingToolbar::zoomInRequested); connect(btnZoomOut, &QPushButton::clicked, this, &FloatingToolbar::zoomOutRequested); connect(btnResetView, &QPushButton::clicked, this, &FloatingToolbar::resetViewRequested); - // Add stretch to push everything to the top m_layout->addStretch(); - // Calculate height based on content + // Initial size + m_contentWidget->adjustSize(); adjustSize(); - setFixedHeight(sizeHint().height()); } void FloatingToolbar::connectSignals() @@ -256,42 +277,121 @@ void FloatingToolbar::connectSignals() void FloatingToolbar::updatePosition() { - if (!m_graphEditor) + if (m_dockPosition != Floating) { + updateDockedGeometry(); + } +} + +void FloatingToolbar::setDockPosition(DockPosition position) +{ + if (m_dockPosition == position) return; - int x, y; + m_dockPosition = position; - if (m_dockedRight) { - x = m_graphEditor->width() - width() - m_margin; + if (position == Floating) { + // Restore floating geometry + setMinimumSize(0, 0); + setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + setFixedWidth(150); + + if (m_geometryAnimation->state() == QAbstractAnimation::Running) { + m_geometryAnimation->stop(); + } + m_geometryAnimation->setStartValue(geometry()); + m_geometryAnimation->setEndValue(m_floatingGeometry); + m_geometryAnimation->start(); } else { - x = m_margin; + // Apply docked geometry + updateDockedGeometry(); } +} - y = m_margin; +FloatingToolbar::DockPosition FloatingToolbar::checkDockingZone(const QPoint &pos) +{ + if (!parentWidget()) + return Floating; + + int parentWidth = parentWidget()->width(); - // Ensure toolbar stays within bounds - x = qMax(m_margin, qMin(x, m_graphEditor->width() - width() - m_margin)); - y = qMax(m_margin, qMin(y, m_graphEditor->height() - height() - m_margin)); + // Check left edge + if (pos.x() <= m_dockingDistance) { + return DockedLeft; + } - move(x, y); + // Check right edge + if (pos.x() + width() >= parentWidth - m_dockingDistance) { + return DockedRight; + } + + return Floating; } -void FloatingToolbar::setDockedRight(bool right) +void FloatingToolbar::applyDocking(DockPosition position) { - m_dockedRight = right; - updatePosition(); + setDockPosition(position); +} + +void FloatingToolbar::updateDockedGeometry() +{ + if (!parentWidget() || m_dockPosition == Floating) { + return; + } + + QRect targetGeometry; + int parentHeight = parentWidget()->height(); + + // Remove size constraints for docking + setMinimumSize(0, 0); + setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + + switch (m_dockPosition) { + case DockedLeft: + targetGeometry = QRect(m_dockMargin, + m_dockMargin, + m_dockedWidth, + parentHeight - 2 * m_dockMargin); + break; + case DockedRight: + targetGeometry = QRect(parentWidget()->width() - m_dockedWidth - m_dockMargin, + m_dockMargin, + m_dockedWidth, + parentHeight - 2 * m_dockMargin); + break; + default: + return; + } + + if (m_geometryAnimation->state() == QAbstractAnimation::Running) { + m_geometryAnimation->stop(); + } + m_geometryAnimation->setStartValue(geometry()); + m_geometryAnimation->setEndValue(targetGeometry); + m_geometryAnimation->start(); + + m_contentWidget->setStyleSheet("#ToolbarContent {" + " background-color: #f5f5f5;" + " border: 1px solid #ccc;" + " border-radius: 0px;" + "}"); } void FloatingToolbar::paintEvent(QPaintEvent *event) { - // Draw shadow QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); - // Shadow + // Draw shadow QRect shadowRect = rect().adjusted(4, 4, -4, -4); painter.fillRect(shadowRect, QColor(0, 0, 0, 30)); + // Draw docking preview + if (m_dragging && m_previewDockPosition != Floating && m_previewDockPosition != m_dockPosition) { + painter.setPen(QPen(QColor(0, 120, 215), 2)); + painter.setBrush(QColor(0, 120, 215, 20)); + painter.drawRoundedRect(rect().adjusted(1, 1, -1, -1), 6, 6); + } + QWidget::paintEvent(event); } @@ -302,6 +402,13 @@ void FloatingToolbar::mousePressEvent(QMouseEvent *event) if (title && title->geometry().contains(event->pos())) { m_dragging = true; m_dragStartPosition = event->pos(); + + // Store current geometry if floating + if (m_dockPosition == Floating) { + m_floatingGeometry = geometry(); + } + + raise(); // Bring to front when dragging } } QWidget::mousePressEvent(event); @@ -312,29 +419,59 @@ void FloatingToolbar::mouseMoveEvent(QMouseEvent *event) if (m_dragging && (event->buttons() & Qt::LeftButton)) { QPoint newPos = pos() + event->pos() - m_dragStartPosition; - // Keep toolbar within parent bounds - int maxX = parentWidget()->width() - width() - m_margin; - int maxY = parentWidget()->height() - height() - m_margin; + // If currently docked, undock first + if (m_dockPosition != Floating) { + m_dockPosition = Floating; + setFixedWidth(150); + // Adjust position to keep mouse on title bar + newPos = QPoint(event->globalPos().x() - m_dragStartPosition.x(), + event->globalPos().y() - m_dragStartPosition.y()); + if (parentWidget()) { + newPos = parentWidget()->mapFromGlobal(newPos); + } + setFixedHeight(_floatHeight); + m_contentWidget->setStyleSheet("#ToolbarContent {" + " background-color: #f5f5f5;" + " border: 1px solid #ccc;" + " border-radius: 6px;" + "}"); + } - newPos.setX(qMax(m_margin, qMin(newPos.x(), maxX))); - newPos.setY(qMax(m_margin, qMin(newPos.y(), maxY))); + // Keep within parent bounds + if (parentWidget()) { + int maxX = parentWidget()->width() - width(); + int maxY = parentWidget()->height() - height(); + newPos.setX(qMax(0, qMin(newPos.x(), maxX))); + newPos.setY(qMax(0, qMin(newPos.y(), maxY))); + } move(newPos); - // Update docked state based on position - if (newPos.x() < parentWidget()->width() / 2) { - m_dockedRight = false; - } else { - m_dockedRight = true; + // Check for docking zones + m_previewDockPosition = checkDockingZone(newPos); + + // Remember floating position + if (m_previewDockPosition == Floating) { + m_floatingGeometry = QRect(newPos, size()); } + + update(); // Repaint for preview } QWidget::mouseMoveEvent(event); } void FloatingToolbar::mouseReleaseEvent(QMouseEvent *event) { - if (event->button() == Qt::LeftButton) { + if (event->button() == Qt::LeftButton && m_dragging) { m_dragging = false; + + // Apply docking if in zone + if (m_previewDockPosition != Floating) { + applyDocking(m_previewDockPosition); + } + + m_previewDockPosition = Floating; + update(); } QWidget::mouseReleaseEvent(event); } @@ -343,4 +480,15 @@ void FloatingToolbar::showEvent(QShowEvent *event) { QWidget::showEvent(event); updatePosition(); + raise(); // Ensure toolbar is on top +} + +void FloatingToolbar::resizeEvent(QResizeEvent *event) +{ + QWidget::resizeEvent(event); + + // If docked, maintain the docked state + if (m_dockPosition != Floating) { + updateDockedGeometry(); + } } \ No newline at end of file diff --git a/examples/epen_graph_editor/src/GraphEditorWindow.cpp b/examples/epen_graph_editor/src/GraphEditorWindow.cpp index 5b9b77113..aec489ec8 100644 --- a/examples/epen_graph_editor/src/GraphEditorWindow.cpp +++ b/examples/epen_graph_editor/src/GraphEditorWindow.cpp @@ -38,6 +38,8 @@ GraphEditorWindow::GraphEditorWindow() resize(800, 600); setAcceptDrops(true); + viewport()->setAcceptDrops(true); // Important for drag and drop + // Don't create toolbar here - wait for showEvent } @@ -80,7 +82,7 @@ void GraphEditorWindow::createFloatingToolbar() qDebug() << "Main window geometry:" << geometry(); qDebug() << "Main window visible:" << isVisible(); - // Create the floating toolbar as a child widget + // Create the floating toolbar m_toolbar = new FloatingToolbar(this); if (!m_toolbar) { @@ -100,8 +102,8 @@ void GraphEditorWindow::createFloatingToolbar() m_toolbar->show(); m_toolbar->raise(); - // Update position - m_toolbar->updatePosition(); + // Set initial dock position (optional - start docked to right) + // m_toolbar->setDockPosition(FloatingToolbar::DockedRight); qDebug() << "Toolbar created. Visible:" << m_toolbar->isVisible() << "Geometry:" << m_toolbar->geometry(); @@ -125,16 +127,16 @@ void GraphEditorWindow::createNodeAtCursor() void GraphEditorWindow::moveEvent(QMoveEvent *event) { GraphicsView::moveEvent(event); - - // No need to update toolbar position as it's now a child widget + + // The toolbar will handle its own position updates through event filter } void GraphEditorWindow::resizeEvent(QResizeEvent *event) { GraphicsView::resizeEvent(event); - - // Update toolbar position when main window resizes - if (m_toolbar && m_toolbar->isVisible()) { + + // Update toolbar position if it's docked + if (m_toolbar && m_toolbar->isVisible() && m_toolbar->isDocked()) { m_toolbar->updatePosition(); } } @@ -142,6 +144,7 @@ void GraphEditorWindow::resizeEvent(QResizeEvent *event) void GraphEditorWindow::goToMode(QString mode) { _currentMode = mode; + qDebug() << "Mode changed to:" << mode; } void GraphEditorWindow::mousePressEvent(QMouseEvent *event) @@ -151,12 +154,13 @@ void GraphEditorWindow::mousePressEvent(QMouseEvent *event) void GraphEditorWindow::dragEnterEvent(QDragEnterEvent *event) { + qDebug() << "DragEnter - MIME formats:" << event->mimeData()->formats(); event->acceptProposedAction(); } void GraphEditorWindow::dropEvent(QDropEvent *event) { - qDebug() << event->mimeData()->text(); + qDebug() << "Drop event - Text:" << event->mimeData()->text(); event->acceptProposedAction(); QPointF scenePos = mapToScene(event->position().toPoint()); createNodeAtPosition(scenePos); From 52b735e31a69fb7413d3d2cebfe05483d9b3a041 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Mon, 14 Jul 2025 02:55:52 +0330 Subject: [PATCH 006/124] Scene creation separation --- .../include/GraphEditorWindow.hpp | 6 ++-- .../src/GraphEditorWindow.cpp | 32 +++++-------------- examples/epen_graph_editor/src/main.cpp | 9 +++++- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/examples/epen_graph_editor/include/GraphEditorWindow.hpp b/examples/epen_graph_editor/include/GraphEditorWindow.hpp index a42e5f3b3..7c278c8f5 100644 --- a/examples/epen_graph_editor/include/GraphEditorWindow.hpp +++ b/examples/epen_graph_editor/include/GraphEditorWindow.hpp @@ -5,8 +5,10 @@ #include #include #include +#include using QtNodes::GraphicsView; +using QtNodes::BasicGraphicsScene; class FloatingToolbar; class SimpleGraphModel; @@ -15,7 +17,7 @@ class GraphEditorWindow : public GraphicsView { Q_OBJECT public: - GraphEditorWindow(); + GraphEditorWindow(BasicGraphicsScene* scene); ~GraphEditorWindow(); public slots: @@ -41,7 +43,7 @@ public slots: void setupNodeCreation(); QPointer m_toolbar; - SimpleGraphModel *m_graphModel; + //SimpleGraphModel *m_graphModel; bool m_toolbarCreated; // This was missing! QString _currentMode; }; diff --git a/examples/epen_graph_editor/src/GraphEditorWindow.cpp b/examples/epen_graph_editor/src/GraphEditorWindow.cpp index aec489ec8..598a4243b 100644 --- a/examples/epen_graph_editor/src/GraphEditorWindow.cpp +++ b/examples/epen_graph_editor/src/GraphEditorWindow.cpp @@ -1,6 +1,5 @@ #include "GraphEditorWindow.hpp" #include "FloatingToolbar.hpp" -#include "SimpleGraphModel.hpp" #include #include #include @@ -9,28 +8,19 @@ #include #include #include -#include #include #include -using QtNodes::BasicGraphicsScene; using QtNodes::ConnectionStyle; using QtNodes::NodeRole; using QtNodes::StyleCollection; -GraphEditorWindow::GraphEditorWindow() - : GraphicsView() +GraphEditorWindow::GraphEditorWindow(BasicGraphicsScene *scene) + : GraphicsView(scene) , m_toolbar(nullptr) , m_toolbarCreated(false) , _currentMode("pan") { - // Create the graph model - m_graphModel = new SimpleGraphModel(); - - // Create and set the scene - auto scene = new BasicGraphicsScene(*m_graphModel); - setScene(scene); - // Setup context menu setupNodeCreation(); @@ -39,15 +29,11 @@ GraphEditorWindow::GraphEditorWindow() setAcceptDrops(true); viewport()->setAcceptDrops(true); // Important for drag and drop - + // Don't create toolbar here - wait for showEvent } -GraphEditorWindow::~GraphEditorWindow() -{ - // The toolbar will be automatically deleted as it's a child of this window - delete m_graphModel; -} +GraphEditorWindow::~GraphEditorWindow() {} void GraphEditorWindow::showEvent(QShowEvent *event) { @@ -111,10 +97,8 @@ void GraphEditorWindow::createFloatingToolbar() void GraphEditorWindow::createNodeAtPosition(const QPointF &scenePos) { - if (m_graphModel) { - NodeId const newId = m_graphModel->addNode(); - m_graphModel->setNodeData(newId, NodeRole::Position, scenePos); - } + QtNodes::NodeId newId = nodeScene()->graphModel().addNode(); + nodeScene()->graphModel().setNodeData(newId, NodeRole::Position, scenePos); } void GraphEditorWindow::createNodeAtCursor() @@ -127,14 +111,14 @@ void GraphEditorWindow::createNodeAtCursor() void GraphEditorWindow::moveEvent(QMoveEvent *event) { GraphicsView::moveEvent(event); - + // The toolbar will handle its own position updates through event filter } void GraphEditorWindow::resizeEvent(QResizeEvent *event) { GraphicsView::resizeEvent(event); - + // Update toolbar position if it's docked if (m_toolbar && m_toolbar->isVisible() && m_toolbar->isDocked()) { m_toolbar->updatePosition(); diff --git a/examples/epen_graph_editor/src/main.cpp b/examples/epen_graph_editor/src/main.cpp index cda863c3f..5d029e4a9 100644 --- a/examples/epen_graph_editor/src/main.cpp +++ b/examples/epen_graph_editor/src/main.cpp @@ -1,11 +1,18 @@ #include "GraphEditorWindow.hpp" +#include "SimpleGraphModel.hpp" #include int main(int argc, char *argv[]) { QApplication app(argc, argv); - GraphEditorWindow view; + // Create the graph model + SimpleGraphModel *graphModel = new SimpleGraphModel(); + + // Create and set the scene + auto scene = new BasicGraphicsScene(*graphModel); + + GraphEditorWindow view(scene); view.showNormal(); return app.exec(); From e93d25d031ee55b686251df4bc740fdab0b0d014 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Mon, 14 Jul 2025 03:00:31 +0330 Subject: [PATCH 007/124] DataFlowGraphicsScene --- .../include/GraphEditorWindow.hpp | 4 +- .../include/ImageShowModel.hpp | 55 ++++++++++++ .../epen_graph_editor/include/PixmapData.hpp | 31 +++++++ .../src/GraphEditorWindow.cpp | 2 +- .../epen_graph_editor/src/ImageShowModel.cpp | 89 +++++++++++++++++++ examples/epen_graph_editor/src/main.cpp | 34 +++++-- 6 files changed, 208 insertions(+), 7 deletions(-) create mode 100644 examples/epen_graph_editor/include/ImageShowModel.hpp create mode 100644 examples/epen_graph_editor/include/PixmapData.hpp create mode 100644 examples/epen_graph_editor/src/ImageShowModel.cpp diff --git a/examples/epen_graph_editor/include/GraphEditorWindow.hpp b/examples/epen_graph_editor/include/GraphEditorWindow.hpp index 7c278c8f5..e26db17b7 100644 --- a/examples/epen_graph_editor/include/GraphEditorWindow.hpp +++ b/examples/epen_graph_editor/include/GraphEditorWindow.hpp @@ -6,9 +6,11 @@ #include #include #include +#include using QtNodes::GraphicsView; using QtNodes::BasicGraphicsScene; +using QtNodes::DataFlowGraphicsScene; class FloatingToolbar; class SimpleGraphModel; @@ -17,7 +19,7 @@ class GraphEditorWindow : public GraphicsView { Q_OBJECT public: - GraphEditorWindow(BasicGraphicsScene* scene); + GraphEditorWindow(DataFlowGraphicsScene* scene); ~GraphEditorWindow(); public slots: diff --git a/examples/epen_graph_editor/include/ImageShowModel.hpp b/examples/epen_graph_editor/include/ImageShowModel.hpp new file mode 100644 index 000000000..7e4c8a06c --- /dev/null +++ b/examples/epen_graph_editor/include/ImageShowModel.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include + +#include +#include + +#include +#include + +using QtNodes::NodeData; +using QtNodes::NodeDataType; +using QtNodes::NodeDelegateModel; +using QtNodes::PortIndex; +using QtNodes::PortType; + +/// The model dictates the number of inputs and outputs for the Node. +/// In this example it has no logic. +class ImageShowModel : public NodeDelegateModel +{ + Q_OBJECT + +public: + ImageShowModel(); + + ~ImageShowModel() = default; + +public: + QString caption() const override { return QString("Image Display"); } + + QString name() const override { return QString("ImageShowModel"); } + +public: + virtual QString modelName() const { return QString("Resulting Image"); } + + unsigned int nPorts(PortType const portType) const override; + + NodeDataType dataType(PortType const portType, PortIndex const portIndex) const override; + + std::shared_ptr outData(PortIndex const port) override; + + void setInData(std::shared_ptr nodeData, PortIndex const port) override; + + QWidget *embeddedWidget() override { return _label; } + + bool resizable() const override { return true; } + +protected: + bool eventFilter(QObject *object, QEvent *event) override; + +private: + QLabel *_label; + + std::shared_ptr _nodeData; +}; diff --git a/examples/epen_graph_editor/include/PixmapData.hpp b/examples/epen_graph_editor/include/PixmapData.hpp new file mode 100644 index 000000000..a907857a8 --- /dev/null +++ b/examples/epen_graph_editor/include/PixmapData.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include + +#include + +using QtNodes::NodeData; +using QtNodes::NodeDataType; + +/// The class can potentially incapsulate any user data which +/// need to be transferred within the Node Editor graph +class PixmapData : public NodeData +{ +public: + PixmapData() {} + + PixmapData(QPixmap const &pixmap) + : _pixmap(pixmap) + {} + + NodeDataType type() const override + { + // id name + return {"pixmap", "P"}; + } + + QPixmap pixmap() const { return _pixmap; } + +private: + QPixmap _pixmap; +}; diff --git a/examples/epen_graph_editor/src/GraphEditorWindow.cpp b/examples/epen_graph_editor/src/GraphEditorWindow.cpp index 598a4243b..21bd4db86 100644 --- a/examples/epen_graph_editor/src/GraphEditorWindow.cpp +++ b/examples/epen_graph_editor/src/GraphEditorWindow.cpp @@ -15,7 +15,7 @@ using QtNodes::ConnectionStyle; using QtNodes::NodeRole; using QtNodes::StyleCollection; -GraphEditorWindow::GraphEditorWindow(BasicGraphicsScene *scene) +GraphEditorWindow::GraphEditorWindow(DataFlowGraphicsScene *scene) : GraphicsView(scene) , m_toolbar(nullptr) , m_toolbarCreated(false) diff --git a/examples/epen_graph_editor/src/ImageShowModel.cpp b/examples/epen_graph_editor/src/ImageShowModel.cpp new file mode 100644 index 000000000..1d62f9f3f --- /dev/null +++ b/examples/epen_graph_editor/src/ImageShowModel.cpp @@ -0,0 +1,89 @@ +#include "ImageShowModel.hpp" + +#include "PixmapData.hpp" + +#include + +#include +#include +#include + +ImageShowModel::ImageShowModel() + : _label(new QLabel("Image will appear here")) +{ + _label->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter); + + QFont f = _label->font(); + f.setBold(true); + f.setItalic(true); + + _label->setFont(f); + + _label->setMinimumSize(200, 200); + + _label->installEventFilter(this); +} + +unsigned int ImageShowModel::nPorts(PortType portType) const +{ + unsigned int result = 1; + + switch (portType) { + case PortType::In: + result = 1; + break; + + case PortType::Out: + result = 1; + + default: + break; + } + + return result; +} + +bool ImageShowModel::eventFilter(QObject *object, QEvent *event) +{ + if (object == _label) { + int w = _label->width(); + int h = _label->height(); + + if (event->type() == QEvent::Resize) { + auto d = std::dynamic_pointer_cast(_nodeData); + if (d) { + _label->setPixmap(d->pixmap().scaled(w, h, Qt::KeepAspectRatio)); + } + } + } + + return false; +} + +NodeDataType ImageShowModel::dataType(PortType const, PortIndex const) const +{ + return PixmapData().type(); +} + +std::shared_ptr ImageShowModel::outData(PortIndex) +{ + return _nodeData; +} + +void ImageShowModel::setInData(std::shared_ptr nodeData, PortIndex const) +{ + _nodeData = nodeData; + + if (_nodeData) { + auto d = std::dynamic_pointer_cast(_nodeData); + + int w = _label->width(); + int h = _label->height(); + + _label->setPixmap(d->pixmap().scaled(w, h, Qt::KeepAspectRatio)); + } else { + _label->setPixmap(QPixmap()); + } + + Q_EMIT dataUpdated(0); +} diff --git a/examples/epen_graph_editor/src/main.cpp b/examples/epen_graph_editor/src/main.cpp index 5d029e4a9..c96b9e74b 100644 --- a/examples/epen_graph_editor/src/main.cpp +++ b/examples/epen_graph_editor/src/main.cpp @@ -1,18 +1,42 @@ #include "GraphEditorWindow.hpp" #include "SimpleGraphModel.hpp" +#include +#include +#include +#include +#include #include +#include +#include + +#include "ImageShowModel.hpp" + +using QtNodes::ConnectionStyle; +using QtNodes::DataFlowGraphicsScene; +using QtNodes::DataFlowGraphModel; +using QtNodes::GraphicsView; +using QtNodes::NodeDelegateModelRegistry; + +static std::shared_ptr registerDataModels() +{ + auto ret = std::make_shared(); + ret->registerModel(); + + return ret; +} + int main(int argc, char *argv[]) { QApplication app(argc, argv); - // Create the graph model - SimpleGraphModel *graphModel = new SimpleGraphModel(); + std::shared_ptr registry = registerDataModels(); + + DataFlowGraphModel dataFlowGraphModel(registry); - // Create and set the scene - auto scene = new BasicGraphicsScene(*graphModel); + DataFlowGraphicsScene scene(dataFlowGraphModel); - GraphEditorWindow view(scene); + GraphEditorWindow view(&scene); view.showNormal(); return app.exec(); From da69d2a17bfd9fd37b1b725486087475afa7acd5 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Mon, 14 Jul 2025 04:08:08 +0330 Subject: [PATCH 008/124] Model basics --- ...orWindow.hpp => GraphEditorMainWindow.hpp} | 13 ++- .../{ => data_models}/ImageShowModel.hpp | 2 +- .../data_models/OperationDataModel.hpp | 45 +++++++++ .../include/data_models/VideoData.hpp | 29 ++++++ .../include/data_models/VideoInput.hpp | 40 ++++++++ .../include/data_models/VideoOutput.hpp | 40 ++++++++ .../epen_graph_editor/src/FloatingToolbar.cpp | 8 +- ...orWindow.cpp => GraphEditorMainWindow.cpp} | 95 +++++++++---------- .../src/{ => data_models}/ImageShowModel.cpp | 2 +- .../src/data_models/OperationDataModel.cpp | 40 ++++++++ examples/epen_graph_editor/src/main.cpp | 10 +- .../resizable_images/ImageLoaderModel.hpp | 2 +- examples/resizable_images/ImageShowModel.hpp | 2 +- 13 files changed, 264 insertions(+), 64 deletions(-) rename examples/epen_graph_editor/include/{GraphEditorWindow.hpp => GraphEditorMainWindow.hpp} (83%) rename examples/epen_graph_editor/include/{ => data_models}/ImageShowModel.hpp (94%) create mode 100644 examples/epen_graph_editor/include/data_models/OperationDataModel.hpp create mode 100644 examples/epen_graph_editor/include/data_models/VideoData.hpp create mode 100644 examples/epen_graph_editor/include/data_models/VideoInput.hpp create mode 100644 examples/epen_graph_editor/include/data_models/VideoOutput.hpp rename examples/epen_graph_editor/src/{GraphEditorWindow.cpp => GraphEditorMainWindow.cpp} (91%) rename examples/epen_graph_editor/src/{ => data_models}/ImageShowModel.cpp (97%) create mode 100644 examples/epen_graph_editor/src/data_models/OperationDataModel.cpp diff --git a/examples/epen_graph_editor/include/GraphEditorWindow.hpp b/examples/epen_graph_editor/include/GraphEditorMainWindow.hpp similarity index 83% rename from examples/epen_graph_editor/include/GraphEditorWindow.hpp rename to examples/epen_graph_editor/include/GraphEditorMainWindow.hpp index e26db17b7..03acfbec1 100644 --- a/examples/epen_graph_editor/include/GraphEditorWindow.hpp +++ b/examples/epen_graph_editor/include/GraphEditorMainWindow.hpp @@ -2,15 +2,17 @@ #define GRAPH_EDITOR_WINDOW #include "QtNodes/GraphicsView" -#include -#include #include +#include +#include #include +#include #include -using QtNodes::GraphicsView; using QtNodes::BasicGraphicsScene; using QtNodes::DataFlowGraphicsScene; +using QtNodes::DataFlowGraphModel; +using QtNodes::GraphicsView; class FloatingToolbar; class SimpleGraphModel; @@ -19,12 +21,12 @@ class GraphEditorWindow : public GraphicsView { Q_OBJECT public: - GraphEditorWindow(DataFlowGraphicsScene* scene); + GraphEditorWindow(DataFlowGraphicsScene *scene, DataFlowGraphModel *model); ~GraphEditorWindow(); public slots: // Slot for creating a node at a specific position - void createNodeAtPosition(const QPointF &scenePos); + void createNodeAtPosition(const QPointF &scenePos,const QString nodeType); // Slot for creating a node at cursor position void createNodeAtCursor(); @@ -48,6 +50,7 @@ public slots: //SimpleGraphModel *m_graphModel; bool m_toolbarCreated; // This was missing! QString _currentMode; + DataFlowGraphModel *_model; }; #endif // GRAPH_EDITOR_WINDOW \ No newline at end of file diff --git a/examples/epen_graph_editor/include/ImageShowModel.hpp b/examples/epen_graph_editor/include/data_models/ImageShowModel.hpp similarity index 94% rename from examples/epen_graph_editor/include/ImageShowModel.hpp rename to examples/epen_graph_editor/include/data_models/ImageShowModel.hpp index 7e4c8a06c..5218caaa6 100644 --- a/examples/epen_graph_editor/include/ImageShowModel.hpp +++ b/examples/epen_graph_editor/include/data_models/ImageShowModel.hpp @@ -28,7 +28,7 @@ class ImageShowModel : public NodeDelegateModel public: QString caption() const override { return QString("Image Display"); } - QString name() const override { return QString("ImageShowModel"); } + QString name() const override { return QString("Image"); } public: virtual QString modelName() const { return QString("Resulting Image"); } diff --git a/examples/epen_graph_editor/include/data_models/OperationDataModel.hpp b/examples/epen_graph_editor/include/data_models/OperationDataModel.hpp new file mode 100644 index 000000000..937cd97ff --- /dev/null +++ b/examples/epen_graph_editor/include/data_models/OperationDataModel.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include + +#include +#include +#include +#include "VideoData.hpp" +#include + +class VideoData; + +using QtNodes::NodeData; +using QtNodes::NodeDataType; +using QtNodes::NodeDelegateModel; +using QtNodes::PortIndex; +using QtNodes::PortType; + +/// The model dictates the number of inputs and outputs for the Node. +/// In this example it has no logic. +class OperationDataModel : public NodeDelegateModel +{ + Q_OBJECT + +public: + ~OperationDataModel() = default; + +public: + unsigned int nPorts(PortType portType) const override; + + NodeDataType dataType(PortType portType, PortIndex portIndex) const override; + + std::shared_ptr outData(PortIndex port) override; + + void setInData(std::shared_ptr data, PortIndex portIndex) override; + + QWidget *embeddedWidget() override { return nullptr; } + + +protected: + std::weak_ptr _number1; + std::weak_ptr _number2; + + std::shared_ptr _result; +}; diff --git a/examples/epen_graph_editor/include/data_models/VideoData.hpp b/examples/epen_graph_editor/include/data_models/VideoData.hpp new file mode 100644 index 000000000..406635775 --- /dev/null +++ b/examples/epen_graph_editor/include/data_models/VideoData.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include + +using QtNodes::NodeData; +using QtNodes::NodeDataType; + +/// The class can potentially incapsulate any user data which +/// need to be transferred within the Node Editor graph +class VideoData : public NodeData +{ +public: + VideoData() + : _number(0.0) + {} + + VideoData(double const number) + : _number(number) + {} + + NodeDataType type() const override { return NodeDataType{"decimal", "Decimal"}; } + + double number() const { return _number; } + + QString numberAsText() const { return QString::number(_number, 'f'); } + +private: + double _number; +}; diff --git a/examples/epen_graph_editor/include/data_models/VideoInput.hpp b/examples/epen_graph_editor/include/data_models/VideoInput.hpp new file mode 100644 index 000000000..3833c5446 --- /dev/null +++ b/examples/epen_graph_editor/include/data_models/VideoInput.hpp @@ -0,0 +1,40 @@ +#pragma once +#include "OperationDataModel.hpp" + +class VideoInput : public OperationDataModel +{ +public: + virtual ~VideoInput() {} + +public: + QString caption() const override { return QStringLiteral("Video Input"); } + + bool portCaptionVisible(PortType portType, PortIndex portIndex) const override + { + Q_UNUSED(portType); + Q_UNUSED(portIndex); + return true; + } + + QString portCaption(PortType portType, PortIndex portIndex) const override + { + switch (portType) { + case PortType::In: + if (portIndex == 0) + return QStringLiteral("Dividend"); + else if (portIndex == 1) + return QStringLiteral("Divisor"); + + break; + + case PortType::Out: + return QStringLiteral("Result"); + + default: + break; + } + return QString(); + } + + QString name() const override { return QStringLiteral("VideoInput"); } +}; \ No newline at end of file diff --git a/examples/epen_graph_editor/include/data_models/VideoOutput.hpp b/examples/epen_graph_editor/include/data_models/VideoOutput.hpp new file mode 100644 index 000000000..eb94edca6 --- /dev/null +++ b/examples/epen_graph_editor/include/data_models/VideoOutput.hpp @@ -0,0 +1,40 @@ +#pragma once +#include "OperationDataModel.hpp" + +class VideoOutput : public OperationDataModel +{ +public: + virtual ~VideoOutput() {} + +public: + QString caption() const override { return QStringLiteral("Video Output"); } + + bool portCaptionVisible(PortType portType, PortIndex portIndex) const override + { + Q_UNUSED(portType); + Q_UNUSED(portIndex); + return true; + } + + QString portCaption(PortType portType, PortIndex portIndex) const override + { + switch (portType) { + case PortType::In: + if (portIndex == 0) + return QStringLiteral("Dividend"); + else if (portIndex == 1) + return QStringLiteral("Divisor"); + + break; + + case PortType::Out: + return QStringLiteral("Result"); + + default: + break; + } + return QString(); + } + + QString name() const override { return QStringLiteral("VideoOutput"); } +}; \ No newline at end of file diff --git a/examples/epen_graph_editor/src/FloatingToolbar.cpp b/examples/epen_graph_editor/src/FloatingToolbar.cpp index 07585cd2a..d39771c74 100644 --- a/examples/epen_graph_editor/src/FloatingToolbar.cpp +++ b/examples/epen_graph_editor/src/FloatingToolbar.cpp @@ -1,5 +1,5 @@ #include "FloatingToolbar.hpp" -#include "GraphEditorWindow.hpp" +#include "GraphEditorMainWindow.hpp" #include "QPushButton" #include #include @@ -184,15 +184,15 @@ void FloatingToolbar::setupUI() }; QVector nodeTypes = { - {"Video Input", QString::fromUtf8("\u25C0"), "<", "Create a video input node", true, "input"}, + {"Video Input", QString::fromUtf8("\u25C0"), "<", "Create a video input node", true, "VideoInput"}, {"Video Output", QString::fromUtf8("\u25B6"), ">", "Create a video output node", false, - "output"}, + "VideoOutput"}, {"Process", QString::fromUtf8("\u2666"), "*", "Create a processing node", true, "process"}, - {"Image", QString::fromUtf8("\u25A1"), "#", "Create an image node", true, "image"}, + {"Image", QString::fromUtf8("\u25A1"), "#", "Create an image node", true, "Image"}, {"Buffer", QString::fromUtf8("\u25AC"), "=", "Create a buffer node", true, "buffer"}}; for (const auto &nodeType : nodeTypes) { diff --git a/examples/epen_graph_editor/src/GraphEditorWindow.cpp b/examples/epen_graph_editor/src/GraphEditorMainWindow.cpp similarity index 91% rename from examples/epen_graph_editor/src/GraphEditorWindow.cpp rename to examples/epen_graph_editor/src/GraphEditorMainWindow.cpp index 21bd4db86..0ef8ce35f 100644 --- a/examples/epen_graph_editor/src/GraphEditorWindow.cpp +++ b/examples/epen_graph_editor/src/GraphEditorMainWindow.cpp @@ -1,4 +1,4 @@ -#include "GraphEditorWindow.hpp" +#include "GraphEditorMainWindow.hpp" #include "FloatingToolbar.hpp" #include #include @@ -15,14 +15,15 @@ using QtNodes::ConnectionStyle; using QtNodes::NodeRole; using QtNodes::StyleCollection; -GraphEditorWindow::GraphEditorWindow(DataFlowGraphicsScene *scene) +GraphEditorWindow::GraphEditorWindow(DataFlowGraphicsScene *scene, DataFlowGraphModel *model) : GraphicsView(scene) , m_toolbar(nullptr) , m_toolbarCreated(false) , _currentMode("pan") + , _model(model) { // Setup context menu - setupNodeCreation(); + //setupNodeCreation(); setWindowTitle("Simple Node Graph"); resize(800, 600); @@ -46,6 +47,45 @@ void GraphEditorWindow::showEvent(QShowEvent *event) QTimer::singleShot(100, this, [this]() { createFloatingToolbar(); }); } } +void GraphEditorWindow::moveEvent(QMoveEvent *event) +{ + GraphicsView::moveEvent(event); + + // The toolbar will handle its own position updates through event filter +} + +void GraphEditorWindow::resizeEvent(QResizeEvent *event) +{ + GraphicsView::resizeEvent(event); + + // Update toolbar position if it's docked + if (m_toolbar && m_toolbar->isVisible() && m_toolbar->isDocked()) { + m_toolbar->updatePosition(); + } +} + +void GraphEditorWindow::mousePressEvent(QMouseEvent *event) +{ + GraphicsView::mousePressEvent(event); +} + +void GraphEditorWindow::dragEnterEvent(QDragEnterEvent *event) +{ + qDebug() << "DragEnter - MIME formats:" << event->mimeData()->formats(); + event->acceptProposedAction(); +} + +void GraphEditorWindow::dropEvent(QDropEvent *event) +{ + event->acceptProposedAction(); + QPointF scenePos = mapToScene(event->position().toPoint()); + createNodeAtPosition(scenePos, event->mimeData()->text()); +} + +void GraphEditorWindow::dragMoveEvent(QDragMoveEvent *event) +{ + event->acceptProposedAction(); +} void GraphEditorWindow::setupNodeCreation() { @@ -95,34 +135,17 @@ void GraphEditorWindow::createFloatingToolbar() << "Geometry:" << m_toolbar->geometry(); } -void GraphEditorWindow::createNodeAtPosition(const QPointF &scenePos) +void GraphEditorWindow::createNodeAtPosition(const QPointF &scenePos, const QString nodeType) { - QtNodes::NodeId newId = nodeScene()->graphModel().addNode(); - nodeScene()->graphModel().setNodeData(newId, NodeRole::Position, scenePos); + QtNodes::NodeId newId = _model->addNode(nodeType); + _model->setNodeData(newId, NodeRole::Position, scenePos); } void GraphEditorWindow::createNodeAtCursor() { // Get mouse position in scene coordinates QPointF posView = mapToScene(mapFromGlobal(QCursor::pos())); - createNodeAtPosition(posView); -} - -void GraphEditorWindow::moveEvent(QMoveEvent *event) -{ - GraphicsView::moveEvent(event); - - // The toolbar will handle its own position updates through event filter -} - -void GraphEditorWindow::resizeEvent(QResizeEvent *event) -{ - GraphicsView::resizeEvent(event); - - // Update toolbar position if it's docked - if (m_toolbar && m_toolbar->isVisible() && m_toolbar->isDocked()) { - m_toolbar->updatePosition(); - } + createNodeAtPosition(posView, "ImageShowModel"); } void GraphEditorWindow::goToMode(QString mode) @@ -130,27 +153,3 @@ void GraphEditorWindow::goToMode(QString mode) _currentMode = mode; qDebug() << "Mode changed to:" << mode; } - -void GraphEditorWindow::mousePressEvent(QMouseEvent *event) -{ - GraphicsView::mousePressEvent(event); -} - -void GraphEditorWindow::dragEnterEvent(QDragEnterEvent *event) -{ - qDebug() << "DragEnter - MIME formats:" << event->mimeData()->formats(); - event->acceptProposedAction(); -} - -void GraphEditorWindow::dropEvent(QDropEvent *event) -{ - qDebug() << "Drop event - Text:" << event->mimeData()->text(); - event->acceptProposedAction(); - QPointF scenePos = mapToScene(event->position().toPoint()); - createNodeAtPosition(scenePos); -} - -void GraphEditorWindow::dragMoveEvent(QDragMoveEvent *event) -{ - event->acceptProposedAction(); -} \ No newline at end of file diff --git a/examples/epen_graph_editor/src/ImageShowModel.cpp b/examples/epen_graph_editor/src/data_models/ImageShowModel.cpp similarity index 97% rename from examples/epen_graph_editor/src/ImageShowModel.cpp rename to examples/epen_graph_editor/src/data_models/ImageShowModel.cpp index 1d62f9f3f..4dad20fe9 100644 --- a/examples/epen_graph_editor/src/ImageShowModel.cpp +++ b/examples/epen_graph_editor/src/data_models/ImageShowModel.cpp @@ -1,4 +1,4 @@ -#include "ImageShowModel.hpp" +#include "data_models/ImageShowModel.hpp" #include "PixmapData.hpp" diff --git a/examples/epen_graph_editor/src/data_models/OperationDataModel.cpp b/examples/epen_graph_editor/src/data_models/OperationDataModel.cpp new file mode 100644 index 000000000..8fb77b034 --- /dev/null +++ b/examples/epen_graph_editor/src/data_models/OperationDataModel.cpp @@ -0,0 +1,40 @@ +#include "data_models/OperationDataModel.hpp" + +#include "data_models/VideoData.hpp" + +unsigned int OperationDataModel::nPorts(PortType portType) const +{ + unsigned int result; + + if (portType == PortType::In) + result = 2; + else + result = 1; + + return result; +} + +NodeDataType OperationDataModel::dataType(PortType, PortIndex) const +{ + return VideoData().type(); +} + +std::shared_ptr OperationDataModel::outData(PortIndex) +{ + return std::static_pointer_cast(_result); +} + +void OperationDataModel::setInData(std::shared_ptr data, PortIndex portIndex) +{ + auto numberData = std::dynamic_pointer_cast(data); + + if (!data) { + Q_EMIT dataInvalidated(0); + } + + if (portIndex == 0) { + _number1 = numberData; + } else { + _number2 = numberData; + } +} diff --git a/examples/epen_graph_editor/src/main.cpp b/examples/epen_graph_editor/src/main.cpp index c96b9e74b..5da0454ea 100644 --- a/examples/epen_graph_editor/src/main.cpp +++ b/examples/epen_graph_editor/src/main.cpp @@ -1,4 +1,4 @@ -#include "GraphEditorWindow.hpp" +#include "GraphEditorMainWindow.hpp" #include "SimpleGraphModel.hpp" #include #include @@ -10,7 +10,9 @@ #include #include -#include "ImageShowModel.hpp" +#include "data_models/ImageShowModel.hpp" +#include "data_models/VideoOutput.hpp" +#include "data_models/VideoInput.hpp" using QtNodes::ConnectionStyle; using QtNodes::DataFlowGraphicsScene; @@ -22,6 +24,8 @@ static std::shared_ptr registerDataModels() { auto ret = std::make_shared(); ret->registerModel(); + ret->registerModel(); + ret->registerModel(); return ret; } @@ -36,7 +40,7 @@ int main(int argc, char *argv[]) DataFlowGraphicsScene scene(dataFlowGraphModel); - GraphEditorWindow view(&scene); + GraphEditorWindow view(&scene, &dataFlowGraphModel); view.showNormal(); return app.exec(); diff --git a/examples/resizable_images/ImageLoaderModel.hpp b/examples/resizable_images/ImageLoaderModel.hpp index 394cf28a9..50cf31f21 100644 --- a/examples/resizable_images/ImageLoaderModel.hpp +++ b/examples/resizable_images/ImageLoaderModel.hpp @@ -30,7 +30,7 @@ class ImageLoaderModel : public NodeDelegateModel public: QString caption() const override { return QString("Image Source"); } - QString name() const override { return QString("ImageLoaderModel"); } + QString name() const override { return QString(">ImageLoaderModel"); } public: virtual QString modelName() const { return QString("Source Image"); } diff --git a/examples/resizable_images/ImageShowModel.hpp b/examples/resizable_images/ImageShowModel.hpp index 7e4c8a06c..23ea37b08 100644 --- a/examples/resizable_images/ImageShowModel.hpp +++ b/examples/resizable_images/ImageShowModel.hpp @@ -28,7 +28,7 @@ class ImageShowModel : public NodeDelegateModel public: QString caption() const override { return QString("Image Display"); } - QString name() const override { return QString("ImageShowModel"); } + QString name() const override { return QString(">ImageShowModel"); } public: virtual QString modelName() const { return QString("Resulting Image"); } From 18e1453f3d071cf9ec2d745a843ea5317675efc7 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Mon, 14 Jul 2025 04:29:33 +0330 Subject: [PATCH 009/124] Video input/output models --- .../include/data_models/ImageShowModel.hpp | 2 +- .../include/data_models/VideoInput.hpp | 22 +++++++++++-------- .../include/data_models/VideoOutput.hpp | 19 +++++++++++----- .../epen_graph_editor/src/FloatingToolbar.cpp | 2 ++ .../src/GraphEditorMainWindow.cpp | 13 +++++++++-- .../src/data_models/ImageShowModel.cpp | 2 +- .../src/data_models/OperationDataModel.cpp | 2 +- 7 files changed, 42 insertions(+), 20 deletions(-) diff --git a/examples/epen_graph_editor/include/data_models/ImageShowModel.hpp b/examples/epen_graph_editor/include/data_models/ImageShowModel.hpp index 5218caaa6..4cc4bf6e0 100644 --- a/examples/epen_graph_editor/include/data_models/ImageShowModel.hpp +++ b/examples/epen_graph_editor/include/data_models/ImageShowModel.hpp @@ -26,7 +26,7 @@ class ImageShowModel : public NodeDelegateModel ~ImageShowModel() = default; public: - QString caption() const override { return QString("Image Display"); } + QString caption() const override { return QString("Image"); } QString name() const override { return QString("Image"); } diff --git a/examples/epen_graph_editor/include/data_models/VideoInput.hpp b/examples/epen_graph_editor/include/data_models/VideoInput.hpp index 3833c5446..129f381b7 100644 --- a/examples/epen_graph_editor/include/data_models/VideoInput.hpp +++ b/examples/epen_graph_editor/include/data_models/VideoInput.hpp @@ -19,16 +19,8 @@ class VideoInput : public OperationDataModel QString portCaption(PortType portType, PortIndex portIndex) const override { switch (portType) { - case PortType::In: - if (portIndex == 0) - return QStringLiteral("Dividend"); - else if (portIndex == 1) - return QStringLiteral("Divisor"); - - break; - case PortType::Out: - return QStringLiteral("Result"); + return QStringLiteral("Video"); default: break; @@ -37,4 +29,16 @@ class VideoInput : public OperationDataModel } QString name() const override { return QStringLiteral("VideoInput"); } + + unsigned int nPorts(PortType portType) const override + { + unsigned int result; + + if (portType == PortType::In) + result = 0; + else + result = 1; + + return result; + } }; \ No newline at end of file diff --git a/examples/epen_graph_editor/include/data_models/VideoOutput.hpp b/examples/epen_graph_editor/include/data_models/VideoOutput.hpp index eb94edca6..673552b93 100644 --- a/examples/epen_graph_editor/include/data_models/VideoOutput.hpp +++ b/examples/epen_graph_editor/include/data_models/VideoOutput.hpp @@ -21,15 +21,10 @@ class VideoOutput : public OperationDataModel switch (portType) { case PortType::In: if (portIndex == 0) - return QStringLiteral("Dividend"); - else if (portIndex == 1) - return QStringLiteral("Divisor"); + return QStringLiteral("Video"); break; - case PortType::Out: - return QStringLiteral("Result"); - default: break; } @@ -37,4 +32,16 @@ class VideoOutput : public OperationDataModel } QString name() const override { return QStringLiteral("VideoOutput"); } + + unsigned int nPorts(PortType portType) const override + { + unsigned int result; + + if (portType == PortType::In) + result = 1; + else + result = 0; + + return result; + } }; \ No newline at end of file diff --git a/examples/epen_graph_editor/src/FloatingToolbar.cpp b/examples/epen_graph_editor/src/FloatingToolbar.cpp index d39771c74..50d0fb581 100644 --- a/examples/epen_graph_editor/src/FloatingToolbar.cpp +++ b/examples/epen_graph_editor/src/FloatingToolbar.cpp @@ -48,6 +48,8 @@ FloatingToolbar::FloatingToolbar(GraphEditorWindow *parent) // Ensure toolbar is on top raise(); _floatHeight = height(); + + setDockPosition(DockPosition::DockedLeft); } QString FloatingToolbar::createSafeButtonText(const QString &icon, const QString &text) diff --git a/examples/epen_graph_editor/src/GraphEditorMainWindow.cpp b/examples/epen_graph_editor/src/GraphEditorMainWindow.cpp index 0ef8ce35f..c1bcf0c6d 100644 --- a/examples/epen_graph_editor/src/GraphEditorMainWindow.cpp +++ b/examples/epen_graph_editor/src/GraphEditorMainWindow.cpp @@ -14,6 +14,7 @@ using QtNodes::ConnectionStyle; using QtNodes::NodeRole; using QtNodes::StyleCollection; +using QtNodes::ConnectionId; GraphEditorWindow::GraphEditorWindow(DataFlowGraphicsScene *scene, DataFlowGraphModel *model) : GraphicsView(scene) @@ -31,7 +32,16 @@ GraphEditorWindow::GraphEditorWindow(DataFlowGraphicsScene *scene, DataFlowGraph setAcceptDrops(true); viewport()->setAcceptDrops(true); // Important for drag and drop - // Don't create toolbar here - wait for showEvent + QtNodes::NodeId newIdInput = _model->addNode("VideoInput"); + QPointF inputScenePos = mapToScene(0, 0); + _model->setNodeData(newIdInput, NodeRole::Position, inputScenePos); + + QtNodes::NodeId newIdOutput = _model->addNode("VideoOutput"); + QPointF outputScenePos = mapToScene(400, 0); + _model->setNodeData(newIdOutput, NodeRole::Position, outputScenePos); + + _model->addConnection(ConnectionId{newIdInput, 0, newIdOutput, 0}); + setupScale(0.8); } GraphEditorWindow::~GraphEditorWindow() {} @@ -71,7 +81,6 @@ void GraphEditorWindow::mousePressEvent(QMouseEvent *event) void GraphEditorWindow::dragEnterEvent(QDragEnterEvent *event) { - qDebug() << "DragEnter - MIME formats:" << event->mimeData()->formats(); event->acceptProposedAction(); } diff --git a/examples/epen_graph_editor/src/data_models/ImageShowModel.cpp b/examples/epen_graph_editor/src/data_models/ImageShowModel.cpp index 4dad20fe9..f090fbb59 100644 --- a/examples/epen_graph_editor/src/data_models/ImageShowModel.cpp +++ b/examples/epen_graph_editor/src/data_models/ImageShowModel.cpp @@ -30,7 +30,7 @@ unsigned int ImageShowModel::nPorts(PortType portType) const switch (portType) { case PortType::In: - result = 1; + result = 0; break; case PortType::Out: diff --git a/examples/epen_graph_editor/src/data_models/OperationDataModel.cpp b/examples/epen_graph_editor/src/data_models/OperationDataModel.cpp index 8fb77b034..4ef677a12 100644 --- a/examples/epen_graph_editor/src/data_models/OperationDataModel.cpp +++ b/examples/epen_graph_editor/src/data_models/OperationDataModel.cpp @@ -7,7 +7,7 @@ unsigned int OperationDataModel::nPorts(PortType portType) const unsigned int result; if (portType == PortType::In) - result = 2; + result = 1; else result = 1; From fd1be0d0610f1a0b8ff49107934c9a881bea2259 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Mon, 14 Jul 2025 23:30:58 +0330 Subject: [PATCH 010/124] Control mandatory nodes deletion --- .../include/DataFlowModel.hpp | 106 ++++++++++++++++++ .../include/GraphEditorMainWindow.hpp | 5 +- .../epen_graph_editor/include/PixmapData.hpp | 31 ----- .../include/{data_models => }/VideoData.hpp | 0 .../include/data_models/Buffer.hpp | 44 ++++++++ .../include/data_models/Image.hpp | 44 ++++++++ .../include/data_models/ImageShowModel.hpp | 55 --------- .../data_models/OperationDataModel.hpp | 7 +- .../include/data_models/Process.hpp | 44 ++++++++ .../epen_graph_editor/src/FloatingToolbar.cpp | 8 +- .../src/GraphEditorMainWindow.cpp | 10 +- .../src/data_models/ImageShowModel.cpp | 89 --------------- .../src/data_models/OperationDataModel.cpp | 2 +- examples/epen_graph_editor/src/main.cpp | 14 ++- 14 files changed, 262 insertions(+), 197 deletions(-) create mode 100644 examples/epen_graph_editor/include/DataFlowModel.hpp delete mode 100644 examples/epen_graph_editor/include/PixmapData.hpp rename examples/epen_graph_editor/include/{data_models => }/VideoData.hpp (100%) create mode 100644 examples/epen_graph_editor/include/data_models/Buffer.hpp create mode 100644 examples/epen_graph_editor/include/data_models/Image.hpp delete mode 100644 examples/epen_graph_editor/include/data_models/ImageShowModel.hpp create mode 100644 examples/epen_graph_editor/include/data_models/Process.hpp delete mode 100644 examples/epen_graph_editor/src/data_models/ImageShowModel.cpp diff --git a/examples/epen_graph_editor/include/DataFlowModel.hpp b/examples/epen_graph_editor/include/DataFlowModel.hpp new file mode 100644 index 000000000..cce5fce5a --- /dev/null +++ b/examples/epen_graph_editor/include/DataFlowModel.hpp @@ -0,0 +1,106 @@ +#pragma once + +#include + +using QtNodes::ConnectionId; +using QtNodes::DataFlowGraphModel; +using QtNodes::InvalidNodeId; +using QtNodes::NodeDelegateModelRegistry; +using QtNodes::NodeFlag; +using QtNodes::NodeFlags; +using QtNodes::NodeId; + +enum class NodeTypes { Video_Input, Video_Output, Image, Buffer, Process }; + +const QMap nodeTypeToName = {{NodeTypes::Video_Input, "VideoInput"}, + {NodeTypes::Video_Output, "VideoOutput"}, + {NodeTypes::Image, "Image"}, + {NodeTypes::Buffer, "Buffer"}, + {NodeTypes::Process, "Process"}}; + +namespace std { +template<> +struct hash +{ + std::size_t operator()(NodeTypes c) const { return static_cast(c); } +}; +} // namespace std + +class DataFlowModel : public DataFlowGraphModel +{ +public: + DataFlowModel(std::shared_ptr registry) + : DataFlowGraphModel(std::move(registry)) + {} + + bool detachPossible(ConnectionId const) const override { return true; } + + /*NodeFlags nodeFlags(NodeId nodeId) const override + { + auto basicFlags = DataFlowGraphModel::nodeFlags(nodeId); + QVariant nodeTypeName = nodeData(nodeId, QtNodes::NodeRole::Type); + + return basicFlags; + }*/ + + NodeId addNodeType(NodeTypes type) + { + QString nodeTypeName = nodeTypeToName[type]; + NodeId newNodeId = addNode(nodeTypeName); + nodesMap[type].insert(newNodeId); + return newNodeId; + } + + NodeId addNodeName(QString const nodeTypeName) + { + auto nodeType = stringToNodeType(nodeTypeName); + if (nodeType) { + NodeTypes type = *nodeType; + return addNodeType(type); + } + return QtNodes::InvalidNodeId; + } + + bool deleteNode(NodeId const nodeId) override + { + QVariant nodeTypeName = nodeData(nodeId, QtNodes::NodeRole::Type); + if (nodeTypeName == "VideoOutput") { + return false; + } else if (nodeTypeName == "VideoInput") { + auto nodeType = stringToNodeType(nodeTypeName.toString()); + if (nodeType) { + NodeTypes type = *nodeType; + auto it = nodesMap.find(type); + if (it != nodesMap.end()) { + const std::unordered_set &nodeSet = it->second; + if (nodeSet.size() == 1) { + return false; + } + } + } + } + return DataFlowGraphModel::deleteNode(nodeId); + } + + bool deleteConnection(ConnectionId const connectionId) override { return false; } + +private: + std::unordered_map> nodesMap; + + std::optional stringToNodeType(const QString &str) const + { + static const QHash map = [] { + QHash m; + for (auto it = nodeTypeToName.begin(); it != nodeTypeToName.end(); ++it) + m[it.value()] = it.key(); + return m; + }(); + + auto it = map.find(str); + if (it != map.end()) { + return it.value(); + } else { + return std::nullopt; + } + } +}; diff --git a/examples/epen_graph_editor/include/GraphEditorMainWindow.hpp b/examples/epen_graph_editor/include/GraphEditorMainWindow.hpp index 03acfbec1..c5deb9c84 100644 --- a/examples/epen_graph_editor/include/GraphEditorMainWindow.hpp +++ b/examples/epen_graph_editor/include/GraphEditorMainWindow.hpp @@ -8,6 +8,7 @@ #include #include #include +#include "DataFlowModel.hpp" using QtNodes::BasicGraphicsScene; using QtNodes::DataFlowGraphicsScene; @@ -21,7 +22,7 @@ class GraphEditorWindow : public GraphicsView { Q_OBJECT public: - GraphEditorWindow(DataFlowGraphicsScene *scene, DataFlowGraphModel *model); + GraphEditorWindow(DataFlowGraphicsScene *scene, DataFlowModel *model); ~GraphEditorWindow(); public slots: @@ -50,7 +51,7 @@ public slots: //SimpleGraphModel *m_graphModel; bool m_toolbarCreated; // This was missing! QString _currentMode; - DataFlowGraphModel *_model; + DataFlowModel *_model; }; #endif // GRAPH_EDITOR_WINDOW \ No newline at end of file diff --git a/examples/epen_graph_editor/include/PixmapData.hpp b/examples/epen_graph_editor/include/PixmapData.hpp deleted file mode 100644 index a907857a8..000000000 --- a/examples/epen_graph_editor/include/PixmapData.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include - -#include - -using QtNodes::NodeData; -using QtNodes::NodeDataType; - -/// The class can potentially incapsulate any user data which -/// need to be transferred within the Node Editor graph -class PixmapData : public NodeData -{ -public: - PixmapData() {} - - PixmapData(QPixmap const &pixmap) - : _pixmap(pixmap) - {} - - NodeDataType type() const override - { - // id name - return {"pixmap", "P"}; - } - - QPixmap pixmap() const { return _pixmap; } - -private: - QPixmap _pixmap; -}; diff --git a/examples/epen_graph_editor/include/data_models/VideoData.hpp b/examples/epen_graph_editor/include/VideoData.hpp similarity index 100% rename from examples/epen_graph_editor/include/data_models/VideoData.hpp rename to examples/epen_graph_editor/include/VideoData.hpp diff --git a/examples/epen_graph_editor/include/data_models/Buffer.hpp b/examples/epen_graph_editor/include/data_models/Buffer.hpp new file mode 100644 index 000000000..2bdf79a62 --- /dev/null +++ b/examples/epen_graph_editor/include/data_models/Buffer.hpp @@ -0,0 +1,44 @@ +#pragma once +#include "OperationDataModel.hpp" + +class Buffer : public OperationDataModel +{ +public: + virtual ~Buffer() {} + +public: + QString caption() const override { return QStringLiteral("Buffer"); } + + bool portCaptionVisible(PortType portType, PortIndex portIndex) const override + { + Q_UNUSED(portType); + Q_UNUSED(portIndex); + return true; + } + + QString portCaption(PortType portType, PortIndex portIndex) const override + { + switch (portType) { + case PortType::Out: + return QStringLiteral("Video"); + + default: + break; + } + return QString(); + } + + QString name() const override { return QStringLiteral("Buffer"); } + + unsigned int nPorts(PortType portType) const override + { + unsigned int result; + + if (portType == PortType::In) + result = 0; + else + result = 1; + + return result; + } +}; \ No newline at end of file diff --git a/examples/epen_graph_editor/include/data_models/Image.hpp b/examples/epen_graph_editor/include/data_models/Image.hpp new file mode 100644 index 000000000..1597db37c --- /dev/null +++ b/examples/epen_graph_editor/include/data_models/Image.hpp @@ -0,0 +1,44 @@ +#pragma once +#include "OperationDataModel.hpp" + +class Image : public OperationDataModel +{ +public: + virtual ~Image() {} + +public: + QString caption() const override { return QStringLiteral("Image"); } + + bool portCaptionVisible(PortType portType, PortIndex portIndex) const override + { + Q_UNUSED(portType); + Q_UNUSED(portIndex); + return true; + } + + QString portCaption(PortType portType, PortIndex portIndex) const override + { + switch (portType) { + case PortType::Out: + return QStringLiteral("Video"); + + default: + break; + } + return QString(); + } + + QString name() const override { return QStringLiteral("Image"); } + + unsigned int nPorts(PortType portType) const override + { + unsigned int result; + + if (portType == PortType::In) + result = 0; + else + result = 1; + + return result; + } +}; \ No newline at end of file diff --git a/examples/epen_graph_editor/include/data_models/ImageShowModel.hpp b/examples/epen_graph_editor/include/data_models/ImageShowModel.hpp deleted file mode 100644 index 4cc4bf6e0..000000000 --- a/examples/epen_graph_editor/include/data_models/ImageShowModel.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include - -#include -#include - -#include -#include - -using QtNodes::NodeData; -using QtNodes::NodeDataType; -using QtNodes::NodeDelegateModel; -using QtNodes::PortIndex; -using QtNodes::PortType; - -/// The model dictates the number of inputs and outputs for the Node. -/// In this example it has no logic. -class ImageShowModel : public NodeDelegateModel -{ - Q_OBJECT - -public: - ImageShowModel(); - - ~ImageShowModel() = default; - -public: - QString caption() const override { return QString("Image"); } - - QString name() const override { return QString("Image"); } - -public: - virtual QString modelName() const { return QString("Resulting Image"); } - - unsigned int nPorts(PortType const portType) const override; - - NodeDataType dataType(PortType const portType, PortIndex const portIndex) const override; - - std::shared_ptr outData(PortIndex const port) override; - - void setInData(std::shared_ptr nodeData, PortIndex const port) override; - - QWidget *embeddedWidget() override { return _label; } - - bool resizable() const override { return true; } - -protected: - bool eventFilter(QObject *object, QEvent *event) override; - -private: - QLabel *_label; - - std::shared_ptr _nodeData; -}; diff --git a/examples/epen_graph_editor/include/data_models/OperationDataModel.hpp b/examples/epen_graph_editor/include/data_models/OperationDataModel.hpp index 937cd97ff..73ecab350 100644 --- a/examples/epen_graph_editor/include/data_models/OperationDataModel.hpp +++ b/examples/epen_graph_editor/include/data_models/OperationDataModel.hpp @@ -2,11 +2,11 @@ #include +#include "VideoData.hpp" +#include #include #include #include -#include "VideoData.hpp" -#include class VideoData; @@ -16,8 +16,6 @@ using QtNodes::NodeDelegateModel; using QtNodes::PortIndex; using QtNodes::PortType; -/// The model dictates the number of inputs and outputs for the Node. -/// In this example it has no logic. class OperationDataModel : public NodeDelegateModel { Q_OBJECT @@ -36,7 +34,6 @@ class OperationDataModel : public NodeDelegateModel QWidget *embeddedWidget() override { return nullptr; } - protected: std::weak_ptr _number1; std::weak_ptr _number2; diff --git a/examples/epen_graph_editor/include/data_models/Process.hpp b/examples/epen_graph_editor/include/data_models/Process.hpp new file mode 100644 index 000000000..2d059a0a5 --- /dev/null +++ b/examples/epen_graph_editor/include/data_models/Process.hpp @@ -0,0 +1,44 @@ +#pragma once +#include "OperationDataModel.hpp" + +class Process : public OperationDataModel +{ +public: + virtual ~Process() {} + +public: + QString caption() const override { return QStringLiteral("Process"); } + + bool portCaptionVisible(PortType portType, PortIndex portIndex) const override + { + Q_UNUSED(portType); + Q_UNUSED(portIndex); + return true; + } + + QString portCaption(PortType portType, PortIndex portIndex) const override + { + switch (portType) { + case PortType::Out: + return QStringLiteral("Video"); + + default: + break; + } + return QString(); + } + + QString name() const override { return QStringLiteral("Process"); } + + unsigned int nPorts(PortType portType) const override + { + unsigned int result; + + if (portType == PortType::In) + result = 0; + else + result = 1; + + return result; + } +}; \ No newline at end of file diff --git a/examples/epen_graph_editor/src/FloatingToolbar.cpp b/examples/epen_graph_editor/src/FloatingToolbar.cpp index 50d0fb581..9a12e3d42 100644 --- a/examples/epen_graph_editor/src/FloatingToolbar.cpp +++ b/examples/epen_graph_editor/src/FloatingToolbar.cpp @@ -193,9 +193,9 @@ void FloatingToolbar::setupUI() "Create a video output node", false, "VideoOutput"}, - {"Process", QString::fromUtf8("\u2666"), "*", "Create a processing node", true, "process"}, + {"Process", QString::fromUtf8("\u2666"), "*", "Create a processing node", true, "Process"}, {"Image", QString::fromUtf8("\u25A1"), "#", "Create an image node", true, "Image"}, - {"Buffer", QString::fromUtf8("\u25AC"), "=", "Create a buffer node", true, "buffer"}}; + {"Buffer", QString::fromUtf8("\u25AC"), "=", "Create a buffer node", true, "Buffer"}}; for (const auto &nodeType : nodeTypes) { DraggableButton *btn = new DraggableButton(nodeType.actionName, this); @@ -426,8 +426,8 @@ void FloatingToolbar::mouseMoveEvent(QMouseEvent *event) m_dockPosition = Floating; setFixedWidth(150); // Adjust position to keep mouse on title bar - newPos = QPoint(event->globalPos().x() - m_dragStartPosition.x(), - event->globalPos().y() - m_dragStartPosition.y()); + newPos = QPoint(event->globalPosition().x() - m_dragStartPosition.x(), + event->globalPosition().y() - m_dragStartPosition.y()); if (parentWidget()) { newPos = parentWidget()->mapFromGlobal(newPos); } diff --git a/examples/epen_graph_editor/src/GraphEditorMainWindow.cpp b/examples/epen_graph_editor/src/GraphEditorMainWindow.cpp index c1bcf0c6d..16c67fb18 100644 --- a/examples/epen_graph_editor/src/GraphEditorMainWindow.cpp +++ b/examples/epen_graph_editor/src/GraphEditorMainWindow.cpp @@ -11,12 +11,12 @@ #include #include +using QtNodes::ConnectionId; using QtNodes::ConnectionStyle; using QtNodes::NodeRole; using QtNodes::StyleCollection; -using QtNodes::ConnectionId; -GraphEditorWindow::GraphEditorWindow(DataFlowGraphicsScene *scene, DataFlowGraphModel *model) +GraphEditorWindow::GraphEditorWindow(DataFlowGraphicsScene *scene, DataFlowModel *model) : GraphicsView(scene) , m_toolbar(nullptr) , m_toolbarCreated(false) @@ -32,11 +32,11 @@ GraphEditorWindow::GraphEditorWindow(DataFlowGraphicsScene *scene, DataFlowGraph setAcceptDrops(true); viewport()->setAcceptDrops(true); // Important for drag and drop - QtNodes::NodeId newIdInput = _model->addNode("VideoInput"); + QtNodes::NodeId newIdInput = _model->addNodeType(NodeTypes::Video_Input); QPointF inputScenePos = mapToScene(0, 0); _model->setNodeData(newIdInput, NodeRole::Position, inputScenePos); - QtNodes::NodeId newIdOutput = _model->addNode("VideoOutput"); + QtNodes::NodeId newIdOutput = _model->addNodeType(NodeTypes::Video_Output); QPointF outputScenePos = mapToScene(400, 0); _model->setNodeData(newIdOutput, NodeRole::Position, outputScenePos); @@ -146,7 +146,7 @@ void GraphEditorWindow::createFloatingToolbar() void GraphEditorWindow::createNodeAtPosition(const QPointF &scenePos, const QString nodeType) { - QtNodes::NodeId newId = _model->addNode(nodeType); + QtNodes::NodeId newId = _model->addNodeName(nodeType); _model->setNodeData(newId, NodeRole::Position, scenePos); } diff --git a/examples/epen_graph_editor/src/data_models/ImageShowModel.cpp b/examples/epen_graph_editor/src/data_models/ImageShowModel.cpp deleted file mode 100644 index f090fbb59..000000000 --- a/examples/epen_graph_editor/src/data_models/ImageShowModel.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#include "data_models/ImageShowModel.hpp" - -#include "PixmapData.hpp" - -#include - -#include -#include -#include - -ImageShowModel::ImageShowModel() - : _label(new QLabel("Image will appear here")) -{ - _label->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter); - - QFont f = _label->font(); - f.setBold(true); - f.setItalic(true); - - _label->setFont(f); - - _label->setMinimumSize(200, 200); - - _label->installEventFilter(this); -} - -unsigned int ImageShowModel::nPorts(PortType portType) const -{ - unsigned int result = 1; - - switch (portType) { - case PortType::In: - result = 0; - break; - - case PortType::Out: - result = 1; - - default: - break; - } - - return result; -} - -bool ImageShowModel::eventFilter(QObject *object, QEvent *event) -{ - if (object == _label) { - int w = _label->width(); - int h = _label->height(); - - if (event->type() == QEvent::Resize) { - auto d = std::dynamic_pointer_cast(_nodeData); - if (d) { - _label->setPixmap(d->pixmap().scaled(w, h, Qt::KeepAspectRatio)); - } - } - } - - return false; -} - -NodeDataType ImageShowModel::dataType(PortType const, PortIndex const) const -{ - return PixmapData().type(); -} - -std::shared_ptr ImageShowModel::outData(PortIndex) -{ - return _nodeData; -} - -void ImageShowModel::setInData(std::shared_ptr nodeData, PortIndex const) -{ - _nodeData = nodeData; - - if (_nodeData) { - auto d = std::dynamic_pointer_cast(_nodeData); - - int w = _label->width(); - int h = _label->height(); - - _label->setPixmap(d->pixmap().scaled(w, h, Qt::KeepAspectRatio)); - } else { - _label->setPixmap(QPixmap()); - } - - Q_EMIT dataUpdated(0); -} diff --git a/examples/epen_graph_editor/src/data_models/OperationDataModel.cpp b/examples/epen_graph_editor/src/data_models/OperationDataModel.cpp index 4ef677a12..c77a51d1a 100644 --- a/examples/epen_graph_editor/src/data_models/OperationDataModel.cpp +++ b/examples/epen_graph_editor/src/data_models/OperationDataModel.cpp @@ -1,6 +1,6 @@ #include "data_models/OperationDataModel.hpp" -#include "data_models/VideoData.hpp" +#include "VideoData.hpp" unsigned int OperationDataModel::nPorts(PortType portType) const { diff --git a/examples/epen_graph_editor/src/main.cpp b/examples/epen_graph_editor/src/main.cpp index 5da0454ea..72c978e5b 100644 --- a/examples/epen_graph_editor/src/main.cpp +++ b/examples/epen_graph_editor/src/main.cpp @@ -9,10 +9,12 @@ #include #include - -#include "data_models/ImageShowModel.hpp" -#include "data_models/VideoOutput.hpp" +#include "DataFlowModel.hpp" +#include "data_models/Buffer.hpp" +#include "data_models/Image.hpp" +#include "data_models/Process.hpp" #include "data_models/VideoInput.hpp" +#include "data_models/VideoOutput.hpp" using QtNodes::ConnectionStyle; using QtNodes::DataFlowGraphicsScene; @@ -23,9 +25,11 @@ using QtNodes::NodeDelegateModelRegistry; static std::shared_ptr registerDataModels() { auto ret = std::make_shared(); - ret->registerModel(); + ret->registerModel(); ret->registerModel(); ret->registerModel(); + ret->registerModel(); + ret->registerModel(); return ret; } @@ -36,7 +40,7 @@ int main(int argc, char *argv[]) std::shared_ptr registry = registerDataModels(); - DataFlowGraphModel dataFlowGraphModel(registry); + DataFlowModel dataFlowGraphModel(registry); DataFlowGraphicsScene scene(dataFlowGraphModel); From b4f47166328a062814c4176d253952551f1e2564 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Tue, 15 Jul 2025 00:10:15 +0330 Subject: [PATCH 011/124] Dynamic ports --- .../include/DataFlowModel.hpp | 119 +++++++++++- .../include/PortAddRemoveWidget.hpp | 88 +++++++++ .../include/data_models/Process.hpp | 2 +- .../src/PortAddRemoveWidget.cpp | 170 ++++++++++++++++++ 4 files changed, 369 insertions(+), 10 deletions(-) create mode 100644 examples/epen_graph_editor/include/PortAddRemoveWidget.hpp create mode 100644 examples/epen_graph_editor/src/PortAddRemoveWidget.cpp diff --git a/examples/epen_graph_editor/include/DataFlowModel.hpp b/examples/epen_graph_editor/include/DataFlowModel.hpp index cce5fce5a..740ccec7e 100644 --- a/examples/epen_graph_editor/include/DataFlowModel.hpp +++ b/examples/epen_graph_editor/include/DataFlowModel.hpp @@ -1,5 +1,6 @@ #pragma once +#include "PortAddRemoveWidget.hpp" #include using QtNodes::ConnectionId; @@ -9,6 +10,9 @@ using QtNodes::NodeDelegateModelRegistry; using QtNodes::NodeFlag; using QtNodes::NodeFlags; using QtNodes::NodeId; +using QtNodes::NodeRole; +using QtNodes::PortIndex; +using QtNodes::PortType; enum class NodeTypes { Video_Input, Video_Output, Image, Buffer, Process }; @@ -35,14 +39,6 @@ class DataFlowModel : public DataFlowGraphModel bool detachPossible(ConnectionId const) const override { return true; } - /*NodeFlags nodeFlags(NodeId nodeId) const override - { - auto basicFlags = DataFlowGraphModel::nodeFlags(nodeId); - QVariant nodeTypeName = nodeData(nodeId, QtNodes::NodeRole::Type); - - return basicFlags; - }*/ - NodeId addNodeType(NodeTypes type) { QString nodeTypeName = nodeTypeToName[type]; @@ -79,10 +75,96 @@ class DataFlowModel : public DataFlowGraphModel } } } + _nodeWidgets.erase(nodeId); + _nodePortCounts.erase(nodeId); return DataFlowGraphModel::deleteNode(nodeId); } - bool deleteConnection(ConnectionId const connectionId) override { return false; } + bool deleteConnection(ConnectionId const connectionId) override { return true; } + + QVariant nodeData(NodeId nodeId, NodeRole role) const override + { + QVariant nodeTypeName = DataFlowGraphModel::nodeData(nodeId, QtNodes::NodeRole::Type); + if (nodeTypeName == "Process") { + switch (role) { + case NodeRole::InPortCount: + return _nodePortCounts[nodeId].in; + + case NodeRole::OutPortCount: + return _nodePortCounts[nodeId].out; + + case NodeRole::Widget: { + return QVariant::fromValue(widget(nodeId)); + } + } + } + + return DataFlowGraphModel::nodeData(nodeId, role); + } + + bool setNodeData(NodeId nodeId, NodeRole role, QVariant value) override + { + QVariant nodeTypeName = DataFlowGraphModel::nodeData(nodeId, QtNodes::NodeRole::Type); + if (nodeTypeName == "Process") { + switch (role) { + case NodeRole::InPortCount: + _nodePortCounts[nodeId].in = value.toUInt(); + widget(nodeId)->populateButtons(PortType::In, value.toUInt()); + return false; + + case NodeRole::OutPortCount: + _nodePortCounts[nodeId].out = value.toUInt(); + widget(nodeId)->populateButtons(PortType::Out, value.toUInt()); + return false; + + case NodeRole::Widget: + return false; + } + } + + return DataFlowGraphModel::setNodeData(nodeId, role, value); + } + + void addPort(NodeId nodeId, PortType portType, PortIndex portIndex) + { + // STAGE 1. + // Compute new addresses for the existing connections that are shifted and + // placed after the new ones + PortIndex first = portIndex; + PortIndex last = first; + portsAboutToBeInserted(nodeId, portType, first, last); + + // STAGE 2. Change the number of connections in your model + if (portType == PortType::In) + _nodePortCounts[nodeId].in++; + else + _nodePortCounts[nodeId].out++; + + // STAGE 3. Re-create previouly existed and now shifted connections + portsInserted(); + + Q_EMIT nodeUpdated(nodeId); + } + + void removePort(NodeId nodeId, PortType portType, PortIndex portIndex) + { + // STAGE 1. + // Compute new addresses for the existing connections that are shifted upwards + // instead of the deleted ports. + PortIndex first = portIndex; + PortIndex last = first; + portsAboutToBeDeleted(nodeId, portType, first, last); + + // STAGE 2. Change the number of connections in your model + if (portType == PortType::In) + _nodePortCounts[nodeId].in--; + else + _nodePortCounts[nodeId].out--; + + portsDeleted(); + + Q_EMIT nodeUpdated(nodeId); + } private: std::unordered_map> nodesMap; @@ -103,4 +185,23 @@ class DataFlowModel : public DataFlowGraphModel return std::nullopt; } } + struct NodePortCount + { + unsigned int in = 0; + unsigned int out = 0; + }; + mutable std::unordered_map _nodePortCounts; + mutable std::unordered_map _nodeWidgets; + PortAddRemoveWidget *widget(NodeId nodeId) const + { + auto it = _nodeWidgets.find(nodeId); + if (it == _nodeWidgets.end()) { + _nodeWidgets[nodeId] = new PortAddRemoveWidget(0, + 0, + nodeId, + *const_cast(this)); + } + + return _nodeWidgets[nodeId]; + } }; diff --git a/examples/epen_graph_editor/include/PortAddRemoveWidget.hpp b/examples/epen_graph_editor/include/PortAddRemoveWidget.hpp new file mode 100644 index 000000000..f0b979545 --- /dev/null +++ b/examples/epen_graph_editor/include/PortAddRemoveWidget.hpp @@ -0,0 +1,88 @@ +#pragma once + +#include +#include + +#include + +#include +#include + +using QtNodes::NodeId; +using QtNodes::PortIndex; +using QtNodes::PortType; + +class DataFlowModel; + +/** + * PortAddRemoveWidget + * + * ``` + * _left _right + * layout layout + * ---------------------------------------- + * | | | | + * | [+] [-] | | [+] [-] | + * | | | | + * | [+] [-] | | [+] [-] | + * | | | | + * | [+] [-] | | [+] [-] | + * | | | | + * | [+] [-] | | | + * | | | | + * |_________|__________________|_________| + * ``` + * + * The widget has two main vertical layouts containing groups of buttons for + * adding and removing ports. Each such a `[+] [-]` group is contained in a + * dedicated QHVBoxLayout. + * + */ +class PortAddRemoveWidget : public QWidget +{ + Q_OBJECT +public: + PortAddRemoveWidget(unsigned int nInPorts, + unsigned int nOutPorts, + NodeId nodeId, + DataFlowModel &model, + QWidget *parent = nullptr); + + ~PortAddRemoveWidget(); + + /** + * Called from constructor, creates all button groups according to models'port + * counts. + */ + void populateButtons(PortType portType, unsigned int nPorts); + + /** + * Adds a single `[+][-]` button group to a given layout. + */ + QHBoxLayout *addButtonGroupToLayout(QVBoxLayout *vbl, unsigned int portIndex); + + /** + * Removes a single `[+][-]` button group from a given layout. + */ + void removeButtonGroupFromLayout(QVBoxLayout *vbl, unsigned int portIndex); + +private Q_SLOTS: + void onPlusClicked(); + + void onMinusClicked(); + +private: + /** + * @param buttonIndex is the index of a button in the layout. + * Plus button has the index 0. + * Minus button has the index 1. + */ + std::pair findWhichPortWasClicked(QObject *sender, int const buttonIndex); + +private: + NodeId const _nodeId; + DataFlowModel &_model; + + QVBoxLayout *_left; + QVBoxLayout *_right; +}; diff --git a/examples/epen_graph_editor/include/data_models/Process.hpp b/examples/epen_graph_editor/include/data_models/Process.hpp index 2d059a0a5..19ab12278 100644 --- a/examples/epen_graph_editor/include/data_models/Process.hpp +++ b/examples/epen_graph_editor/include/data_models/Process.hpp @@ -35,7 +35,7 @@ class Process : public OperationDataModel unsigned int result; if (portType == PortType::In) - result = 0; + result = 1; else result = 1; diff --git a/examples/epen_graph_editor/src/PortAddRemoveWidget.cpp b/examples/epen_graph_editor/src/PortAddRemoveWidget.cpp new file mode 100644 index 000000000..73e31f506 --- /dev/null +++ b/examples/epen_graph_editor/src/PortAddRemoveWidget.cpp @@ -0,0 +1,170 @@ +#include "PortAddRemoveWidget.hpp" + +#include "DataFlowModel.hpp" + +PortAddRemoveWidget::PortAddRemoveWidget(unsigned int nInPorts, + unsigned int nOutPorts, + NodeId nodeId, + DataFlowModel &model, + QWidget *parent) + : QWidget(parent) + , _nodeId(nodeId) + , _model(model) +{ + setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Minimum); + + QHBoxLayout *hl = new QHBoxLayout(this); + hl->setContentsMargins(0, 0, 0, 0); + hl->setSpacing(0); + + _left = new QVBoxLayout(); + _left->setSpacing(0); + _left->setContentsMargins(0, 0, 0, 0); + _left->addStretch(); + + _right = new QVBoxLayout(); + _right->setSpacing(0); + _right->setContentsMargins(0, 0, 0, 0); + _right->addStretch(); + + hl->addLayout(_left); + hl->addSpacing(50); + hl->addLayout(_right); +} + +PortAddRemoveWidget::~PortAddRemoveWidget() +{ + // +} + +void PortAddRemoveWidget::populateButtons(PortType portType, unsigned int nPorts) +{ + QVBoxLayout *vl = (portType == PortType::In) ? _left : _right; + + // we use [-1} in the expression `vl->count() - 1` because + // one element - a spacer - is alvays present in this layout. + + if (vl->count() - 1 < nPorts) + while (vl->count() - 1 < nPorts) { + addButtonGroupToLayout(vl, 0); + } + + if (vl->count() - 1 > nPorts) { + while (vl->count() - 1 > nPorts) { + removeButtonGroupFromLayout(vl, 0); + } + } +} + +QHBoxLayout *PortAddRemoveWidget::addButtonGroupToLayout(QVBoxLayout *vbl, unsigned int portIndex) +{ + auto l = new QHBoxLayout(); + l->setContentsMargins(0, 0, 0, 0); + + auto button = new QPushButton("+"); + button->setFixedHeight(25); + l->addWidget(button); + connect(button, &QPushButton::clicked, this, &PortAddRemoveWidget::onPlusClicked); + + button = new QPushButton("-"); + button->setFixedHeight(25); + l->addWidget(button); + connect(button, &QPushButton::clicked, this, &PortAddRemoveWidget::onMinusClicked); + + vbl->insertLayout(portIndex, l); + + return l; +} + +void PortAddRemoveWidget::removeButtonGroupFromLayout(QVBoxLayout *vbl, unsigned int portIndex) +{ + // Last item in the layout is always a spacer + if (vbl->count() > 1) { + auto item = vbl->itemAt(portIndex); + + // Delete [+] and [-] QPushButton widgets + item->layout()->itemAt(0)->widget()->deleteLater(); + item->layout()->itemAt(1)->widget()->deleteLater(); + + vbl->removeItem(item); + + delete item; + } +} + +void PortAddRemoveWidget::onPlusClicked() +{ + // index of the plus button in the QHBoxLayout + int const plusButtonIndex = 0; + + PortType portType; + PortIndex portIndex; + + // All existing "plus" buttons trigger the same slot. We need to find out which + // button has been actually clicked. + std::tie(portType, portIndex) = findWhichPortWasClicked(QObject::sender(), plusButtonIndex); + + // We add new "plus-minus" button group to the chosen layout. + addButtonGroupToLayout((portType == PortType::In) ? _left : _right, portIndex + 1); + + // Trigger changes in the model + _model.addPort(_nodeId, portType, portIndex + 1); + + adjustSize(); +} + +void PortAddRemoveWidget::onMinusClicked() +{ + // index of the minus button in the QHBoxLayout + int const minusButtonIndex = 1; + + PortType portType; + PortIndex portIndex; + + std::tie(portType, portIndex) = findWhichPortWasClicked(QObject::sender(), minusButtonIndex); + + removeButtonGroupFromLayout((portType == PortType::In) ? _left : _right, portIndex); + + // Trigger changes in the model + _model.removePort(_nodeId, portType, portIndex); + + adjustSize(); +} + +std::pair PortAddRemoveWidget::findWhichPortWasClicked(QObject *sender, + int const buttonIndex) +{ + PortType portType = PortType::None; + PortIndex portIndex = QtNodes::InvalidPortIndex; + + auto checkOneSide = [&portType, &portIndex, &sender, &buttonIndex](QVBoxLayout *sideLayout) { + for (int i = 0; i < sideLayout->count(); ++i) { + auto layoutItem = sideLayout->itemAt(i); + auto hLayout = dynamic_cast(layoutItem); + + if (!hLayout) + continue; + + auto widget = static_cast(hLayout->itemAt(buttonIndex))->widget(); + + if (sender == widget) { + portIndex = i; + break; + } + } + }; + + checkOneSide(_left); + + if (portIndex != QtNodes::InvalidPortIndex) { + portType = PortType::In; + } else { + checkOneSide(_right); + + if (portIndex != QtNodes::InvalidPortIndex) { + portType = PortType::Out; + } + } + + return std::make_pair(portType, portIndex); +} From af76a475c6796080cf7715f0fc873c3bb9c48f23 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Tue, 15 Jul 2025 00:50:09 +0330 Subject: [PATCH 012/124] Delete unused model --- .../include/DataFlowModel.hpp | 4 +- .../include/PortAddRemoveWidget.hpp | 6 +- .../include/SimpleGraphModel.hpp | 109 ------- .../src/PortAddRemoveWidget.cpp | 4 +- .../src/SimpleGraphModel.cpp | 294 ------------------ examples/epen_graph_editor/src/main.cpp | 1 - 6 files changed, 3 insertions(+), 415 deletions(-) delete mode 100644 examples/epen_graph_editor/include/SimpleGraphModel.hpp delete mode 100644 examples/epen_graph_editor/src/SimpleGraphModel.cpp diff --git a/examples/epen_graph_editor/include/DataFlowModel.hpp b/examples/epen_graph_editor/include/DataFlowModel.hpp index 740ccec7e..060d88ea2 100644 --- a/examples/epen_graph_editor/include/DataFlowModel.hpp +++ b/examples/epen_graph_editor/include/DataFlowModel.hpp @@ -196,9 +196,7 @@ class DataFlowModel : public DataFlowGraphModel { auto it = _nodeWidgets.find(nodeId); if (it == _nodeWidgets.end()) { - _nodeWidgets[nodeId] = new PortAddRemoveWidget(0, - 0, - nodeId, + _nodeWidgets[nodeId] = new PortAddRemoveWidget(nodeId, *const_cast(this)); } diff --git a/examples/epen_graph_editor/include/PortAddRemoveWidget.hpp b/examples/epen_graph_editor/include/PortAddRemoveWidget.hpp index f0b979545..4b2f9519c 100644 --- a/examples/epen_graph_editor/include/PortAddRemoveWidget.hpp +++ b/examples/epen_graph_editor/include/PortAddRemoveWidget.hpp @@ -42,11 +42,7 @@ class PortAddRemoveWidget : public QWidget { Q_OBJECT public: - PortAddRemoveWidget(unsigned int nInPorts, - unsigned int nOutPorts, - NodeId nodeId, - DataFlowModel &model, - QWidget *parent = nullptr); + PortAddRemoveWidget(NodeId nodeId, DataFlowModel &model, QWidget *parent = nullptr); ~PortAddRemoveWidget(); diff --git a/examples/epen_graph_editor/include/SimpleGraphModel.hpp b/examples/epen_graph_editor/include/SimpleGraphModel.hpp deleted file mode 100644 index e3d07213c..000000000 --- a/examples/epen_graph_editor/include/SimpleGraphModel.hpp +++ /dev/null @@ -1,109 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include -#include - -using ConnectionId = QtNodes::ConnectionId; -using ConnectionPolicy = QtNodes::ConnectionPolicy; -using NodeFlag = QtNodes::NodeFlag; -using NodeId = QtNodes::NodeId; -using NodeRole = QtNodes::NodeRole; -using PortIndex = QtNodes::PortIndex; -using PortRole = QtNodes::PortRole; -using PortType = QtNodes::PortType; -using StyleCollection = QtNodes::StyleCollection; -using QtNodes::InvalidNodeId; - -/** - * The class implements a bare minimum required to demonstrate a model-based - * graph. - */ -class SimpleGraphModel : public QtNodes::AbstractGraphModel -{ - Q_OBJECT -public: - struct NodeGeometryData - { - QSize size; - QPointF pos; - }; - -public: - SimpleGraphModel(); - - ~SimpleGraphModel() override; - - std::unordered_set allNodeIds() const override; - - std::unordered_set allConnectionIds(NodeId const nodeId) const override; - - std::unordered_set connections(NodeId nodeId, - PortType portType, - PortIndex portIndex) const override; - - bool connectionExists(ConnectionId const connectionId) const override; - - NodeId addNode(QString const nodeType = QString()) override; - - /** - * Connection is possible when graph contains no connectivity data - * in both directions `Out -> In` and `In -> Out`. - */ - bool connectionPossible(ConnectionId const connectionId) const override; - - void addConnection(ConnectionId const connectionId) override; - - bool nodeExists(NodeId const nodeId) const override; - - QVariant nodeData(NodeId nodeId, NodeRole role) const override; - - bool setNodeData(NodeId nodeId, NodeRole role, QVariant value) override; - - QVariant portData(NodeId nodeId, - PortType portType, - PortIndex portIndex, - PortRole role) const override; - - bool setPortData(NodeId nodeId, - PortType portType, - PortIndex portIndex, - QVariant const &value, - PortRole role = PortRole::Data) override; - - bool deleteConnection(ConnectionId const connectionId) override; - - bool deleteNode(NodeId const nodeId) override; - - QJsonObject saveNode(NodeId const) const override; - - /// @brief Creates a new node based on the informatoin in `nodeJson`. - /** - * @param nodeJson conains a `NodeId`, node's position, internal node - * information. - */ - void loadNode(QJsonObject const &nodeJson) override; - - NodeId newNodeId() override { return _nextNodeId++; } - -private: - std::unordered_set _nodeIds; - - /// [Important] This is a user defined data structure backing your model. - /// In your case it could be anything else representing a graph, for example, a - /// table. Or a collection of structs with pointers to each other. Or an - /// abstract syntax tree, you name it. - /// - /// This data structure contains the graph connectivity information in both - /// directions, i.e. from Node1 to Node2 and from Node2 to Node1. - std::unordered_set _connectivity; - - mutable std::unordered_map _nodeGeometryData; - - /// A convenience variable needed for generating unique node ids. - NodeId _nextNodeId; -}; diff --git a/examples/epen_graph_editor/src/PortAddRemoveWidget.cpp b/examples/epen_graph_editor/src/PortAddRemoveWidget.cpp index 73e31f506..cdd16ea16 100644 --- a/examples/epen_graph_editor/src/PortAddRemoveWidget.cpp +++ b/examples/epen_graph_editor/src/PortAddRemoveWidget.cpp @@ -2,9 +2,7 @@ #include "DataFlowModel.hpp" -PortAddRemoveWidget::PortAddRemoveWidget(unsigned int nInPorts, - unsigned int nOutPorts, - NodeId nodeId, +PortAddRemoveWidget::PortAddRemoveWidget(NodeId nodeId, DataFlowModel &model, QWidget *parent) : QWidget(parent) diff --git a/examples/epen_graph_editor/src/SimpleGraphModel.cpp b/examples/epen_graph_editor/src/SimpleGraphModel.cpp deleted file mode 100644 index 7c04440f0..000000000 --- a/examples/epen_graph_editor/src/SimpleGraphModel.cpp +++ /dev/null @@ -1,294 +0,0 @@ -#include "SimpleGraphModel.hpp" - -SimpleGraphModel::SimpleGraphModel() - : _nextNodeId{0} -{} - -SimpleGraphModel::~SimpleGraphModel() -{ - // -} - -std::unordered_set SimpleGraphModel::allNodeIds() const -{ - return _nodeIds; -} - -std::unordered_set SimpleGraphModel::allConnectionIds(NodeId const nodeId) const -{ - std::unordered_set result; - - std::copy_if(_connectivity.begin(), - _connectivity.end(), - std::inserter(result, std::end(result)), - [&nodeId](ConnectionId const &cid) { - return cid.inNodeId == nodeId || cid.outNodeId == nodeId; - }); - - return result; -} - -std::unordered_set SimpleGraphModel::connections(NodeId nodeId, - PortType portType, - PortIndex portIndex) const -{ - std::unordered_set result; - - std::copy_if(_connectivity.begin(), - _connectivity.end(), - std::inserter(result, std::end(result)), - [&portType, &portIndex, &nodeId](ConnectionId const &cid) { - return (getNodeId(portType, cid) == nodeId - && getPortIndex(portType, cid) == portIndex); - }); - - return result; -} - -bool SimpleGraphModel::connectionExists(ConnectionId const connectionId) const -{ - return (_connectivity.find(connectionId) != _connectivity.end()); -} - -NodeId SimpleGraphModel::addNode(QString const nodeType) -{ - NodeId newId = newNodeId(); - // Create new node. - _nodeIds.insert(newId); - - Q_EMIT nodeCreated(newId); - - return newId; -} - -bool SimpleGraphModel::connectionPossible(ConnectionId const connectionId) const -{ - return _connectivity.find(connectionId) == _connectivity.end(); -} - -void SimpleGraphModel::addConnection(ConnectionId const connectionId) -{ - _connectivity.insert(connectionId); - - Q_EMIT connectionCreated(connectionId); -} - -bool SimpleGraphModel::nodeExists(NodeId const nodeId) const -{ - return (_nodeIds.find(nodeId) != _nodeIds.end()); -} - -QVariant SimpleGraphModel::nodeData(NodeId nodeId, NodeRole role) const -{ - Q_UNUSED(nodeId); - - QVariant result; - - switch (role) { - case NodeRole::Type: - result = QString("Default Node Type"); - break; - - case NodeRole::Position: - result = _nodeGeometryData[nodeId].pos; - break; - - case NodeRole::Size: - result = _nodeGeometryData[nodeId].size; - break; - - case NodeRole::CaptionVisible: - result = true; - break; - - case NodeRole::Caption: - result = QString("Node"); - break; - - case NodeRole::Style: { - auto style = StyleCollection::nodeStyle(); - result = style.toJson().toVariantMap(); - } break; - - case NodeRole::InternalData: - break; - - case NodeRole::InPortCount: - result = 1u; - break; - - case NodeRole::OutPortCount: - result = 1u; - break; - - case NodeRole::Widget: - result = QVariant(); - break; - } - - return result; -} - -bool SimpleGraphModel::setNodeData(NodeId nodeId, NodeRole role, QVariant value) -{ - bool result = false; - - switch (role) { - case NodeRole::Type: - break; - case NodeRole::Position: { - _nodeGeometryData[nodeId].pos = value.value(); - - Q_EMIT nodePositionUpdated(nodeId); - - result = true; - } break; - - case NodeRole::Size: { - _nodeGeometryData[nodeId].size = value.value(); - result = true; - } break; - - case NodeRole::CaptionVisible: - break; - - case NodeRole::Caption: - break; - - case NodeRole::Style: - break; - - case NodeRole::InternalData: - break; - - case NodeRole::InPortCount: - break; - - case NodeRole::OutPortCount: - break; - - case NodeRole::Widget: - break; - } - - return result; -} - -QVariant SimpleGraphModel::portData(NodeId nodeId, - PortType portType, - PortIndex portIndex, - PortRole role) const -{ - switch (role) { - case PortRole::Data: - return QVariant(); - break; - - case PortRole::DataType: - return QVariant(); - break; - - case PortRole::ConnectionPolicyRole: - return QVariant::fromValue(ConnectionPolicy::One); - break; - - case PortRole::CaptionVisible: - return true; - break; - - case PortRole::Caption: - if (portType == PortType::In) - return QString::fromUtf8("Port In"); - else - return QString::fromUtf8("Port Out"); - - break; - } - - return QVariant(); -} - -bool SimpleGraphModel::setPortData( - NodeId nodeId, PortType portType, PortIndex portIndex, QVariant const &value, PortRole role) -{ - Q_UNUSED(nodeId); - Q_UNUSED(portType); - Q_UNUSED(portIndex); - Q_UNUSED(value); - Q_UNUSED(role); - - return false; -} - -bool SimpleGraphModel::deleteConnection(ConnectionId const connectionId) -{ - bool disconnected = false; - - auto it = _connectivity.find(connectionId); - - if (it != _connectivity.end()) { - disconnected = true; - - _connectivity.erase(it); - } - - if (disconnected) - Q_EMIT connectionDeleted(connectionId); - - return disconnected; -} - -bool SimpleGraphModel::deleteNode(NodeId const nodeId) -{ - // Delete connections to this node first. - auto connectionIds = allConnectionIds(nodeId); - - for (auto &cId : connectionIds) { - deleteConnection(cId); - } - - _nodeIds.erase(nodeId); - _nodeGeometryData.erase(nodeId); - - Q_EMIT nodeDeleted(nodeId); - - return true; -} - -QJsonObject SimpleGraphModel::saveNode(NodeId const nodeId) const -{ - QJsonObject nodeJson; - - nodeJson["id"] = static_cast(nodeId); - - { - QPointF const pos = nodeData(nodeId, NodeRole::Position).value(); - - QJsonObject posJson; - posJson["x"] = pos.x(); - posJson["y"] = pos.y(); - nodeJson["position"] = posJson; - } - - return nodeJson; -} - -void SimpleGraphModel::loadNode(QJsonObject const &nodeJson) -{ - NodeId restoredNodeId = static_cast(nodeJson["id"].toInt()); - - // Next NodeId must be larger that any id existing in the graph - _nextNodeId = std::max(_nextNodeId, restoredNodeId + 1); - - // Create new node. - _nodeIds.insert(restoredNodeId); - - Q_EMIT nodeCreated(restoredNodeId); - - { - QJsonObject posJson = nodeJson["position"].toObject(); - QPointF const pos(posJson["x"].toDouble(), posJson["y"].toDouble()); - - setNodeData(restoredNodeId, NodeRole::Position, pos); - } -} diff --git a/examples/epen_graph_editor/src/main.cpp b/examples/epen_graph_editor/src/main.cpp index 72c978e5b..41ca00e31 100644 --- a/examples/epen_graph_editor/src/main.cpp +++ b/examples/epen_graph_editor/src/main.cpp @@ -1,5 +1,4 @@ #include "GraphEditorMainWindow.hpp" -#include "SimpleGraphModel.hpp" #include #include #include From f40667e2f6908f2430199316d5c3fd70ab312a28 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Tue, 15 Jul 2025 01:18:12 +0330 Subject: [PATCH 013/124] Multi Port Process node --- .../epen_graph_editor/include/DataFlowModel.hpp | 15 +++++++++++++-- .../include/PortAddRemoveWidget.hpp | 2 +- .../src/PortAddRemoveWidget.cpp | 16 +++++++--------- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/examples/epen_graph_editor/include/DataFlowModel.hpp b/examples/epen_graph_editor/include/DataFlowModel.hpp index 060d88ea2..b39d54f6e 100644 --- a/examples/epen_graph_editor/include/DataFlowModel.hpp +++ b/examples/epen_graph_editor/include/DataFlowModel.hpp @@ -44,6 +44,13 @@ class DataFlowModel : public DataFlowGraphModel QString nodeTypeName = nodeTypeToName[type]; NodeId newNodeId = addNode(nodeTypeName); nodesMap[type].insert(newNodeId); + if (type == NodeTypes::Process) { + _nodePortCounts[newNodeId].in = 1; + widget(newNodeId)->populateButtons(PortType::In, 1); + _nodePortCounts[newNodeId].out = 1; + widget(newNodeId)->populateButtons(PortType::Out, 1); + _nodeSize[newNodeId] = QSize(250, 130); + } return newNodeId; } @@ -80,13 +87,13 @@ class DataFlowModel : public DataFlowGraphModel return DataFlowGraphModel::deleteNode(nodeId); } - bool deleteConnection(ConnectionId const connectionId) override { return true; } - QVariant nodeData(NodeId nodeId, NodeRole role) const override { QVariant nodeTypeName = DataFlowGraphModel::nodeData(nodeId, QtNodes::NodeRole::Type); if (nodeTypeName == "Process") { switch (role) { + case NodeRole::Size: + return _nodeSize[nodeId]; case NodeRole::InPortCount: return _nodePortCounts[nodeId].in; @@ -107,6 +114,9 @@ class DataFlowModel : public DataFlowGraphModel QVariant nodeTypeName = DataFlowGraphModel::nodeData(nodeId, QtNodes::NodeRole::Type); if (nodeTypeName == "Process") { switch (role) { + case NodeRole::Size: + _nodeSize[nodeId] = value.value(); + return true; case NodeRole::InPortCount: _nodePortCounts[nodeId].in = value.toUInt(); widget(nodeId)->populateButtons(PortType::In, value.toUInt()); @@ -192,6 +202,7 @@ class DataFlowModel : public DataFlowGraphModel }; mutable std::unordered_map _nodePortCounts; mutable std::unordered_map _nodeWidgets; + mutable std::unordered_map _nodeSize; PortAddRemoveWidget *widget(NodeId nodeId) const { auto it = _nodeWidgets.find(nodeId); diff --git a/examples/epen_graph_editor/include/PortAddRemoveWidget.hpp b/examples/epen_graph_editor/include/PortAddRemoveWidget.hpp index 4b2f9519c..c9f19a760 100644 --- a/examples/epen_graph_editor/include/PortAddRemoveWidget.hpp +++ b/examples/epen_graph_editor/include/PortAddRemoveWidget.hpp @@ -55,7 +55,7 @@ class PortAddRemoveWidget : public QWidget /** * Adds a single `[+][-]` button group to a given layout. */ - QHBoxLayout *addButtonGroupToLayout(QVBoxLayout *vbl, unsigned int portIndex); + QHBoxLayout *addButtonGroupToLayout(QVBoxLayout *vbl, unsigned int portIndex, bool deletable); /** * Removes a single `[+][-]` button group from a given layout. diff --git a/examples/epen_graph_editor/src/PortAddRemoveWidget.cpp b/examples/epen_graph_editor/src/PortAddRemoveWidget.cpp index cdd16ea16..0295b0be2 100644 --- a/examples/epen_graph_editor/src/PortAddRemoveWidget.cpp +++ b/examples/epen_graph_editor/src/PortAddRemoveWidget.cpp @@ -2,9 +2,7 @@ #include "DataFlowModel.hpp" -PortAddRemoveWidget::PortAddRemoveWidget(NodeId nodeId, - DataFlowModel &model, - QWidget *parent) +PortAddRemoveWidget::PortAddRemoveWidget(NodeId nodeId, DataFlowModel &model, QWidget *parent) : QWidget(parent) , _nodeId(nodeId) , _model(model) @@ -39,12 +37,9 @@ void PortAddRemoveWidget::populateButtons(PortType portType, unsigned int nPorts { QVBoxLayout *vl = (portType == PortType::In) ? _left : _right; - // we use [-1} in the expression `vl->count() - 1` because - // one element - a spacer - is alvays present in this layout. - if (vl->count() - 1 < nPorts) while (vl->count() - 1 < nPorts) { - addButtonGroupToLayout(vl, 0); + addButtonGroupToLayout(vl, 0, false); } if (vl->count() - 1 > nPorts) { @@ -54,7 +49,9 @@ void PortAddRemoveWidget::populateButtons(PortType portType, unsigned int nPorts } } -QHBoxLayout *PortAddRemoveWidget::addButtonGroupToLayout(QVBoxLayout *vbl, unsigned int portIndex) +QHBoxLayout *PortAddRemoveWidget::addButtonGroupToLayout(QVBoxLayout *vbl, + unsigned int portIndex, + bool deletable) { auto l = new QHBoxLayout(); l->setContentsMargins(0, 0, 0, 0); @@ -67,6 +64,7 @@ QHBoxLayout *PortAddRemoveWidget::addButtonGroupToLayout(QVBoxLayout *vbl, unsig button = new QPushButton("-"); button->setFixedHeight(25); l->addWidget(button); + button->setEnabled(deletable); connect(button, &QPushButton::clicked, this, &PortAddRemoveWidget::onMinusClicked); vbl->insertLayout(portIndex, l); @@ -103,7 +101,7 @@ void PortAddRemoveWidget::onPlusClicked() std::tie(portType, portIndex) = findWhichPortWasClicked(QObject::sender(), plusButtonIndex); // We add new "plus-minus" button group to the chosen layout. - addButtonGroupToLayout((portType == PortType::In) ? _left : _right, portIndex + 1); + addButtonGroupToLayout((portType == PortType::In) ? _left : _right, portIndex + 1, true); // Trigger changes in the model _model.addPort(_nodeId, portType, portIndex + 1); From defa4f3dacc23066293d4e1a7a16f3d8adb715b7 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Tue, 15 Jul 2025 03:28:14 +0330 Subject: [PATCH 014/124] Implementing node limitations. --- .../include/DataFlowModel.hpp | 39 +++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/examples/epen_graph_editor/include/DataFlowModel.hpp b/examples/epen_graph_editor/include/DataFlowModel.hpp index b39d54f6e..e6dd5042e 100644 --- a/examples/epen_graph_editor/include/DataFlowModel.hpp +++ b/examples/epen_graph_editor/include/DataFlowModel.hpp @@ -37,14 +37,19 @@ class DataFlowModel : public DataFlowGraphModel : DataFlowGraphModel(std::move(registry)) {} - bool detachPossible(ConnectionId const) const override { return true; } - - NodeId addNodeType(NodeTypes type) + NodeId addNode(QString const nodeType) override { - QString nodeTypeName = nodeTypeToName[type]; - NodeId newNodeId = addNode(nodeTypeName); - nodesMap[type].insert(newNodeId); - if (type == NodeTypes::Process) { + if (nodeType == "VideoOutput") { + auto it = nodesMap.find(NodeTypes::Video_Output); + if (it != nodesMap.end()) { + const std::unordered_set &nodeSet = it->second; + if (nodeSet.size() > 0) { + return InvalidNodeId; + } + } + } + NodeId newNodeId = DataFlowGraphModel::addNode(nodeType); + if (nodeType == "Process") { _nodePortCounts[newNodeId].in = 1; widget(newNodeId)->populateButtons(PortType::In, 1); _nodePortCounts[newNodeId].out = 1; @@ -54,6 +59,16 @@ class DataFlowModel : public DataFlowGraphModel return newNodeId; } + bool detachPossible(ConnectionId const) const override { return true; } + + NodeId addNodeType(NodeTypes type) + { + QString nodeTypeName = nodeTypeToName[type]; + NodeId newNodeId = addNode(nodeTypeName); + nodesMap[type].insert(newNodeId); + return newNodeId; + } + NodeId addNodeName(QString const nodeTypeName) { auto nodeType = stringToNodeType(nodeTypeName); @@ -67,10 +82,10 @@ class DataFlowModel : public DataFlowGraphModel bool deleteNode(NodeId const nodeId) override { QVariant nodeTypeName = nodeData(nodeId, QtNodes::NodeRole::Type); + auto nodeType = stringToNodeType(nodeTypeName.toString()); if (nodeTypeName == "VideoOutput") { return false; } else if (nodeTypeName == "VideoInput") { - auto nodeType = stringToNodeType(nodeTypeName.toString()); if (nodeType) { NodeTypes type = *nodeType; auto it = nodesMap.find(type); @@ -84,6 +99,14 @@ class DataFlowModel : public DataFlowGraphModel } _nodeWidgets.erase(nodeId); _nodePortCounts.erase(nodeId); + if (nodeType) { + NodeTypes type = *nodeType; + auto it = nodesMap.find(type); + if (it != nodesMap.end()) { + it->second.erase(nodeId); + } + } + return DataFlowGraphModel::deleteNode(nodeId); } From 801808974314fbb95bce98886c94d4d3cfb854cd Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Tue, 15 Jul 2025 21:34:08 +0330 Subject: [PATCH 015/124] Refactor DataFlowModel --- .../include/DataFlowModel.hpp | 200 ++---------------- .../epen_graph_editor/src/DataFlowModel.cpp | 182 ++++++++++++++++ 2 files changed, 199 insertions(+), 183 deletions(-) create mode 100644 examples/epen_graph_editor/src/DataFlowModel.cpp diff --git a/examples/epen_graph_editor/include/DataFlowModel.hpp b/examples/epen_graph_editor/include/DataFlowModel.hpp index e6dd5042e..4126dae66 100644 --- a/examples/epen_graph_editor/include/DataFlowModel.hpp +++ b/examples/epen_graph_editor/include/DataFlowModel.hpp @@ -33,191 +33,34 @@ struct hash class DataFlowModel : public DataFlowGraphModel { public: - DataFlowModel(std::shared_ptr registry) - : DataFlowGraphModel(std::move(registry)) - {} + DataFlowModel(std::shared_ptr registry); - NodeId addNode(QString const nodeType) override - { - if (nodeType == "VideoOutput") { - auto it = nodesMap.find(NodeTypes::Video_Output); - if (it != nodesMap.end()) { - const std::unordered_set &nodeSet = it->second; - if (nodeSet.size() > 0) { - return InvalidNodeId; - } - } - } - NodeId newNodeId = DataFlowGraphModel::addNode(nodeType); - if (nodeType == "Process") { - _nodePortCounts[newNodeId].in = 1; - widget(newNodeId)->populateButtons(PortType::In, 1); - _nodePortCounts[newNodeId].out = 1; - widget(newNodeId)->populateButtons(PortType::Out, 1); - _nodeSize[newNodeId] = QSize(250, 130); - } - return newNodeId; - } + NodeId addNode(QString const nodeType) override; + bool detachPossible(ConnectionId const) const override { return true; } - NodeId addNodeType(NodeTypes type) - { - QString nodeTypeName = nodeTypeToName[type]; - NodeId newNodeId = addNode(nodeTypeName); - nodesMap[type].insert(newNodeId); - return newNodeId; - } + NodeId addNodeType(NodeTypes type); - NodeId addNodeName(QString const nodeTypeName) - { - auto nodeType = stringToNodeType(nodeTypeName); - if (nodeType) { - NodeTypes type = *nodeType; - return addNodeType(type); - } - return QtNodes::InvalidNodeId; - } - - bool deleteNode(NodeId const nodeId) override - { - QVariant nodeTypeName = nodeData(nodeId, QtNodes::NodeRole::Type); - auto nodeType = stringToNodeType(nodeTypeName.toString()); - if (nodeTypeName == "VideoOutput") { - return false; - } else if (nodeTypeName == "VideoInput") { - if (nodeType) { - NodeTypes type = *nodeType; - auto it = nodesMap.find(type); - if (it != nodesMap.end()) { - const std::unordered_set &nodeSet = it->second; - if (nodeSet.size() == 1) { - return false; - } - } - } - } - _nodeWidgets.erase(nodeId); - _nodePortCounts.erase(nodeId); - if (nodeType) { - NodeTypes type = *nodeType; - auto it = nodesMap.find(type); - if (it != nodesMap.end()) { - it->second.erase(nodeId); - } - } - - return DataFlowGraphModel::deleteNode(nodeId); - } - - QVariant nodeData(NodeId nodeId, NodeRole role) const override - { - QVariant nodeTypeName = DataFlowGraphModel::nodeData(nodeId, QtNodes::NodeRole::Type); - if (nodeTypeName == "Process") { - switch (role) { - case NodeRole::Size: - return _nodeSize[nodeId]; - case NodeRole::InPortCount: - return _nodePortCounts[nodeId].in; - - case NodeRole::OutPortCount: - return _nodePortCounts[nodeId].out; - - case NodeRole::Widget: { - return QVariant::fromValue(widget(nodeId)); - } - } - } - - return DataFlowGraphModel::nodeData(nodeId, role); - } - - bool setNodeData(NodeId nodeId, NodeRole role, QVariant value) override - { - QVariant nodeTypeName = DataFlowGraphModel::nodeData(nodeId, QtNodes::NodeRole::Type); - if (nodeTypeName == "Process") { - switch (role) { - case NodeRole::Size: - _nodeSize[nodeId] = value.value(); - return true; - case NodeRole::InPortCount: - _nodePortCounts[nodeId].in = value.toUInt(); - widget(nodeId)->populateButtons(PortType::In, value.toUInt()); - return false; - - case NodeRole::OutPortCount: - _nodePortCounts[nodeId].out = value.toUInt(); - widget(nodeId)->populateButtons(PortType::Out, value.toUInt()); - return false; - - case NodeRole::Widget: - return false; - } - } - - return DataFlowGraphModel::setNodeData(nodeId, role, value); - } - - void addPort(NodeId nodeId, PortType portType, PortIndex portIndex) - { - // STAGE 1. - // Compute new addresses for the existing connections that are shifted and - // placed after the new ones - PortIndex first = portIndex; - PortIndex last = first; - portsAboutToBeInserted(nodeId, portType, first, last); - - // STAGE 2. Change the number of connections in your model - if (portType == PortType::In) - _nodePortCounts[nodeId].in++; - else - _nodePortCounts[nodeId].out++; - - // STAGE 3. Re-create previouly existed and now shifted connections - portsInserted(); - - Q_EMIT nodeUpdated(nodeId); - } - - void removePort(NodeId nodeId, PortType portType, PortIndex portIndex) - { - // STAGE 1. - // Compute new addresses for the existing connections that are shifted upwards - // instead of the deleted ports. - PortIndex first = portIndex; - PortIndex last = first; - portsAboutToBeDeleted(nodeId, portType, first, last); + NodeId addNodeName(QString const nodeTypeName); + + bool deleteNode(NodeId const nodeId) override; + - // STAGE 2. Change the number of connections in your model - if (portType == PortType::In) - _nodePortCounts[nodeId].in--; - else - _nodePortCounts[nodeId].out--; + QVariant nodeData(NodeId nodeId, NodeRole role) const override; + - portsDeleted(); + bool setNodeData(NodeId nodeId, NodeRole role, QVariant value) override; + - Q_EMIT nodeUpdated(nodeId); - } + void addPort(NodeId nodeId, PortType portType, PortIndex portIndex); + + void removePort(NodeId nodeId, PortType portType, PortIndex portIndex); private: std::unordered_map> nodesMap; - std::optional stringToNodeType(const QString &str) const - { - static const QHash map = [] { - QHash m; - for (auto it = nodeTypeToName.begin(); it != nodeTypeToName.end(); ++it) - m[it.value()] = it.key(); - return m; - }(); - - auto it = map.find(str); - if (it != map.end()) { - return it.value(); - } else { - return std::nullopt; - } - } + std::optional stringToNodeType(const QString &str) const; struct NodePortCount { unsigned int in = 0; @@ -226,14 +69,5 @@ class DataFlowModel : public DataFlowGraphModel mutable std::unordered_map _nodePortCounts; mutable std::unordered_map _nodeWidgets; mutable std::unordered_map _nodeSize; - PortAddRemoveWidget *widget(NodeId nodeId) const - { - auto it = _nodeWidgets.find(nodeId); - if (it == _nodeWidgets.end()) { - _nodeWidgets[nodeId] = new PortAddRemoveWidget(nodeId, - *const_cast(this)); - } - - return _nodeWidgets[nodeId]; - } + PortAddRemoveWidget *widget(NodeId nodeId) const; }; diff --git a/examples/epen_graph_editor/src/DataFlowModel.cpp b/examples/epen_graph_editor/src/DataFlowModel.cpp new file mode 100644 index 000000000..baa9074d9 --- /dev/null +++ b/examples/epen_graph_editor/src/DataFlowModel.cpp @@ -0,0 +1,182 @@ +#include "DataFlowModel.hpp" + +DataFlowModel::DataFlowModel(std::shared_ptr registry) + : DataFlowGraphModel(std::move(registry)) +{} + +NodeId DataFlowModel::addNode(QString const nodeType) +{ + if (nodeType == "VideoOutput") { + auto it = nodesMap.find(NodeTypes::Video_Output); + if (it != nodesMap.end()) { + const std::unordered_set &nodeSet = it->second; + if (nodeSet.size() > 0) { + return InvalidNodeId; + } + } + } + NodeId newNodeId = DataFlowGraphModel::addNode(nodeType); + if (nodeType == "Process") { + _nodePortCounts[newNodeId].in = 1; + widget(newNodeId)->populateButtons(PortType::In, 1); + _nodePortCounts[newNodeId].out = 1; + widget(newNodeId)->populateButtons(PortType::Out, 1); + _nodeSize[newNodeId] = QSize(250, 130); + } + return newNodeId; +} + +NodeId DataFlowModel::addNodeType(NodeTypes type) +{ + QString nodeTypeName = nodeTypeToName[type]; + NodeId newNodeId = addNode(nodeTypeName); + nodesMap[type].insert(newNodeId); + return newNodeId; +} + +NodeId DataFlowModel::addNodeName(QString const nodeTypeName) +{ + auto nodeType = stringToNodeType(nodeTypeName); + if (nodeType) { + NodeTypes type = *nodeType; + return addNodeType(type); + } + return QtNodes::InvalidNodeId; +} + +bool DataFlowModel::deleteNode(NodeId const nodeId) +{ + QVariant nodeTypeName = nodeData(nodeId, QtNodes::NodeRole::Type); + auto nodeType = stringToNodeType(nodeTypeName.toString()); + if (nodeTypeName == "VideoOutput") { + return false; + } else if (nodeTypeName == "VideoInput") { + if (nodeType) { + NodeTypes type = *nodeType; + auto it = nodesMap.find(type); + if (it != nodesMap.end()) { + const std::unordered_set &nodeSet = it->second; + if (nodeSet.size() == 1) { + return false; + } + } + } + } + _nodeWidgets.erase(nodeId); + _nodePortCounts.erase(nodeId); + if (nodeType) { + NodeTypes type = *nodeType; + auto it = nodesMap.find(type); + if (it != nodesMap.end()) { + it->second.erase(nodeId); + } + } + + return DataFlowGraphModel::deleteNode(nodeId); +} + +std::optional DataFlowModel::stringToNodeType(const QString &str) const +{ + static const QHash map = [] { + QHash m; + for (auto it = nodeTypeToName.begin(); it != nodeTypeToName.end(); ++it) + m[it.value()] = it.key(); + return m; + }(); + + auto it = map.find(str); + if (it != map.end()) { + return it.value(); + } else { + return std::nullopt; + } +} + +PortAddRemoveWidget *DataFlowModel::widget(NodeId nodeId) const +{ + auto it = _nodeWidgets.find(nodeId); + if (it == _nodeWidgets.end()) { + _nodeWidgets[nodeId] = new PortAddRemoveWidget(nodeId, *const_cast(this)); + } + + return _nodeWidgets[nodeId]; +} + +QVariant DataFlowModel::nodeData(NodeId nodeId, NodeRole role) const +{ + QVariant nodeTypeName = DataFlowGraphModel::nodeData(nodeId, QtNodes::NodeRole::Type); + if (nodeTypeName == "Process") { + switch (role) { + case NodeRole::Size: + return _nodeSize[nodeId]; + case NodeRole::InPortCount: + return _nodePortCounts[nodeId].in; + + case NodeRole::OutPortCount: + return _nodePortCounts[nodeId].out; + + case NodeRole::Widget: { + return QVariant::fromValue(widget(nodeId)); + } + } + } + + return DataFlowGraphModel::nodeData(nodeId, role); +} + +bool DataFlowModel::setNodeData(NodeId nodeId, NodeRole role, QVariant value) +{ + QVariant nodeTypeName = DataFlowGraphModel::nodeData(nodeId, QtNodes::NodeRole::Type); + if (nodeTypeName == "Process") { + switch (role) { + case NodeRole::Size: + _nodeSize[nodeId] = value.value(); + return true; + case NodeRole::InPortCount: + _nodePortCounts[nodeId].in = value.toUInt(); + widget(nodeId)->populateButtons(PortType::In, value.toUInt()); + return false; + + case NodeRole::OutPortCount: + _nodePortCounts[nodeId].out = value.toUInt(); + widget(nodeId)->populateButtons(PortType::Out, value.toUInt()); + return false; + + case NodeRole::Widget: + return false; + } + } + + return DataFlowGraphModel::setNodeData(nodeId, role, value); +} + +void DataFlowModel::addPort(NodeId nodeId, PortType portType, PortIndex portIndex) +{ + PortIndex first = portIndex; + PortIndex last = first; + portsAboutToBeInserted(nodeId, portType, first, last); + + if (portType == PortType::In) + _nodePortCounts[nodeId].in++; + else + _nodePortCounts[nodeId].out++; + portsInserted(); + + Q_EMIT nodeUpdated(nodeId); +} + +void DataFlowModel::removePort(NodeId nodeId, PortType portType, PortIndex portIndex) +{ + PortIndex first = portIndex; + PortIndex last = first; + portsAboutToBeDeleted(nodeId, portType, first, last); + + if (portType == PortType::In) + _nodePortCounts[nodeId].in--; + else + _nodePortCounts[nodeId].out--; + + portsDeleted(); + + Q_EMIT nodeUpdated(nodeId); +} \ No newline at end of file From 0bedfa9528ca131c5d1a55ae2e3122512129608d Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Wed, 16 Jul 2025 15:18:54 +0330 Subject: [PATCH 016/124] Add QtPropertyBrowser as external library --- examples/epen_graph_editor/CMakeLists.txt | 2 +- .../include/DataFlowModel.hpp | 9 +- .../epen_graph_editor/src/DataFlowModel.cpp | 11 +- .../src/PortAddRemoveWidget.cpp | 4 +- external/.DS_Store | Bin 0 -> 6148 bytes external/CMakeLists.txt | 2 + external/QtPropertyBrowser/.DS_Store | Bin 0 -> 8196 bytes external/QtPropertyBrowser/CMakeLists.txt | 37 + external/QtPropertyBrowser/INSTALL.TXT | 254 + external/QtPropertyBrowser/README.TXT | 93 + external/QtPropertyBrowser/common.cmake | 27 + external/QtPropertyBrowser/config.cmake | 9 + external/QtPropertyBrowser/configure | 25 + external/QtPropertyBrowser/configure.bat | 80 + .../QtPropertyBrowser/doc/html/classic.css | 284 + .../doc/html/images/canvas_typed.png | Bin 0 -> 16376 bytes .../doc/html/images/canvas_variant.png | Bin 0 -> 15293 bytes .../doc/html/images/decoration.png | Bin 0 -> 6620 bytes .../doc/html/images/demo.png | Bin 0 -> 76351 bytes .../doc/html/images/extension.png | Bin 0 -> 3994 bytes .../doc/html/images/object_controller.png | Bin 0 -> 39658 bytes .../doc/html/images/qt-logo.png | Bin 0 -> 4075 bytes .../html/images/qtbuttonpropertybrowser.png | Bin 0 -> 7181 bytes .../html/images/qtgroupboxpropertybrowser.png | Bin 0 -> 5819 bytes .../images/qtpropertybrowser-duplicate.png | Bin 0 -> 1620 bytes .../doc/html/images/qtpropertybrowser.png | Bin 0 -> 9677 bytes .../doc/html/images/qttreepropertybrowser.png | Bin 0 -> 7250 bytes .../doc/html/images/simple.png | Bin 0 -> 9548 bytes .../QtPropertyBrowser/doc/html/index.html | 98 + .../html/qtabstracteditorfactory-members.html | 83 + .../doc/html/qtabstracteditorfactory.html | 129 + .../qtabstracteditorfactorybase-members.html | 76 + .../doc/html/qtabstracteditorfactorybase.html | 84 + .../qtabstractpropertybrowser-members.html | 384 + .../doc/html/qtabstractpropertybrowser.html | 221 + .../qtabstractpropertymanager-members.html | 89 + .../doc/html/qtabstractpropertymanager.html | 160 + .../html/qtboolpropertymanager-members.html | 92 + .../doc/html/qtboolpropertymanager.html | 110 + .../doc/html/qtbrowseritem-members.html | 29 + .../doc/html/qtbrowseritem.html | 59 + .../html/qtbuttonpropertybrowser-members.html | 388 + .../doc/html/qtbuttonpropertybrowser.html | 120 + .../doc/html/qtchareditorfactory-members.html | 84 + .../doc/html/qtchareditorfactory.html | 61 + .../html/qtcharpropertymanager-members.html | 92 + .../doc/html/qtcharpropertymanager.html | 107 + .../doc/html/qtcheckboxfactory-members.html | 84 + .../doc/html/qtcheckboxfactory.html | 61 + .../html/qtcoloreditorfactory-members.html | 84 + .../doc/html/qtcoloreditorfactory.html | 61 + .../html/qtcolorpropertymanager-members.html | 93 + .../doc/html/qtcolorpropertymanager.html | 117 + .../html/qtcursoreditorfactory-members.html | 84 + .../doc/html/qtcursoreditorfactory.html | 61 + .../html/qtcursorpropertymanager-members.html | 92 + .../doc/html/qtcursorpropertymanager.html | 110 + .../doc/html/qtdateeditfactory-members.html | 84 + .../doc/html/qtdateeditfactory.html | 61 + .../html/qtdatepropertymanager-members.html | 98 + .../doc/html/qtdatepropertymanager.html | 138 + .../html/qtdatetimeeditfactory-members.html | 84 + .../doc/html/qtdatetimeeditfactory.html | 61 + .../qtdatetimepropertymanager-members.html | 92 + .../doc/html/qtdatetimepropertymanager.html | 106 + .../html/qtdoublepropertymanager-members.html | 104 + .../doc/html/qtdoublepropertymanager.html | 165 + .../html/qtdoublespinboxfactory-members.html | 84 + .../doc/html/qtdoublespinboxfactory.html | 61 + .../doc/html/qtenumeditorfactory-members.html | 84 + .../doc/html/qtenumeditorfactory.html | 61 + .../html/qtenumpropertymanager-members.html | 98 + .../doc/html/qtenumpropertymanager.html | 139 + .../html/qtflagpropertymanager-members.html | 96 + .../doc/html/qtflagpropertymanager.html | 128 + .../doc/html/qtfonteditorfactory-members.html | 84 + .../doc/html/qtfonteditorfactory.html | 61 + .../html/qtfontpropertymanager-members.html | 95 + .../doc/html/qtfontpropertymanager.html | 127 + .../qtgroupboxpropertybrowser-members.html | 384 + .../doc/html/qtgroupboxpropertybrowser.html | 97 + .../html/qtgrouppropertymanager-members.html | 89 + .../doc/html/qtgrouppropertymanager.html | 80 + .../html/qtintpropertymanager-members.html | 101 + .../doc/html/qtintpropertymanager.html | 152 + .../qtkeysequenceeditorfactory-members.html | 84 + .../doc/html/qtkeysequenceeditorfactory.html | 61 + .../qtkeysequencepropertymanager-members.html | 92 + .../html/qtkeysequencepropertymanager.html | 107 + .../doc/html/qtlineeditfactory-members.html | 84 + .../doc/html/qtlineeditfactory.html | 61 + .../html/qtlocalepropertymanager-members.html | 93 + .../doc/html/qtlocalepropertymanager.html | 114 + .../html/qtpointfpropertymanager-members.html | 96 + .../doc/html/qtpointfpropertymanager.html | 127 + .../html/qtpointpropertymanager-members.html | 93 + .../doc/html/qtpointpropertymanager.html | 114 + .../doc/html/qtproperty-members.html | 51 + .../doc/html/qtproperty.html | 152 + ...tpropertybrowser-example-canvas-typed.html | 49 + ...ropertybrowser-example-canvas-variant.html | 49 + .../qtpropertybrowser-example-decoration.html | 26 + .../html/qtpropertybrowser-example-demo.html | 27 + .../qtpropertybrowser-example-extension.html | 26 + ...ertybrowser-example-object-controller.html | 25 + .../qtpropertybrowser-example-simple.html | 25 + .../doc/html/qtpropertybrowser.dcf | 586 ++ .../doc/html/qtpropertybrowser.index | 1425 ++++ .../doc/html/qtpropertybrowser.qhp | 574 ++ .../html/qtrectfpropertymanager-members.html | 99 + .../doc/html/qtrectfpropertymanager.html | 142 + .../html/qtrectpropertymanager-members.html | 96 + .../doc/html/qtrectpropertymanager.html | 129 + .../doc/html/qtscrollbarfactory-members.html | 84 + .../doc/html/qtscrollbarfactory.html | 61 + .../html/qtsizefpropertymanager-members.html | 102 + .../doc/html/qtsizefpropertymanager.html | 157 + .../qtsizepolicypropertymanager-members.html | 94 + .../doc/html/qtsizepolicypropertymanager.html | 119 + .../html/qtsizepropertymanager-members.html | 99 + .../doc/html/qtsizepropertymanager.html | 144 + .../doc/html/qtsliderfactory-members.html | 84 + .../doc/html/qtsliderfactory.html | 61 + .../doc/html/qtspinboxfactory-members.html | 84 + .../doc/html/qtspinboxfactory.html | 61 + .../html/qtstringpropertymanager-members.html | 95 + .../doc/html/qtstringpropertymanager.html | 123 + .../doc/html/qttimeeditfactory-members.html | 84 + .../doc/html/qttimeeditfactory.html | 61 + .../html/qttimepropertymanager-members.html | 92 + .../doc/html/qttimepropertymanager.html | 108 + .../html/qttreepropertybrowser-members.html | 409 + .../doc/html/qttreepropertybrowser.html | 248 + .../html/qtvarianteditorfactory-members.html | 84 + .../doc/html/qtvarianteditorfactory.html | 77 + .../doc/html/qtvariantproperty-members.html | 57 + .../doc/html/qtvariantproperty.html | 96 + .../qtvariantpropertymanager-members.html | 106 + .../doc/html/qtvariantpropertymanager.html | 251 + .../doc/images/canvas_typed.png | Bin 0 -> 16376 bytes .../doc/images/canvas_variant.png | Bin 0 -> 15293 bytes .../doc/images/decoration.png | Bin 0 -> 6620 bytes .../QtPropertyBrowser/doc/images/demo.png | Bin 0 -> 76351 bytes .../doc/images/extension.png | Bin 0 -> 3994 bytes .../doc/images/object_controller.png | Bin 0 -> 39658 bytes .../QtPropertyBrowser/doc/images/qt-logo.png | Bin 0 -> 4075 bytes .../doc/images/qtbuttonpropertybrowser.png | Bin 0 -> 7181 bytes .../doc/images/qtgroupboxpropertybrowser.png | Bin 0 -> 5819 bytes .../images/qtpropertybrowser-duplicate.png | Bin 0 -> 1620 bytes .../doc/images/qtpropertybrowser.png | Bin 0 -> 9677 bytes .../doc/images/qttreepropertybrowser.png | Bin 0 -> 7250 bytes .../QtPropertyBrowser/doc/images/simple.png | Bin 0 -> 9548 bytes external/QtPropertyBrowser/doc/index.qdoc | 97 + .../src/QtAbstractEditorFactoryBase | 1 + .../src/QtAbstractPropertyBrowser | 1 + .../src/QtAbstractPropertyManager | 1 + .../src/QtBoolPropertyManager | 1 + external/QtPropertyBrowser/src/QtBrowserItem | 1 + .../src/QtButtonPropertyBrowser | 1 + .../QtPropertyBrowser/src/QtCharEditorFactory | 1 + .../src/QtCharPropertyManager | 1 + .../QtPropertyBrowser/src/QtCheckBoxFactory | 1 + .../src/QtColorEditorFactory | 1 + .../src/QtColorPropertyManager | 1 + .../src/QtCursorEditorFactory | 1 + .../src/QtCursorPropertyManager | 1 + .../QtPropertyBrowser/src/QtDateEditFactory | 1 + .../src/QtDatePropertyManager | 1 + .../src/QtDateTimeEditFactory | 1 + .../src/QtDateTimePropertyManager | 1 + .../src/QtDoublePropertyManager | 1 + .../src/QtDoubleSpinBoxFactory | 1 + .../QtPropertyBrowser/src/QtEnumEditorFactory | 1 + .../src/QtEnumPropertyManager | 1 + .../src/QtFlagPropertyManager | 1 + .../QtPropertyBrowser/src/QtFontEditorFactory | 1 + .../src/QtFontPropertyManager | 1 + .../src/QtGroupBoxPropertyBrowser | 1 + .../src/QtGroupPropertyManager | 1 + .../src/QtIntPropertyManager | 1 + .../src/QtKeySequenceEditorFactory | 1 + .../src/QtKeySequencePropertyManager | 1 + .../QtPropertyBrowser/src/QtLineEditFactory | 1 + .../src/QtLocalePropertyManager | 1 + .../src/QtPointFPropertyManager | 1 + .../src/QtPointPropertyManager | 1 + external/QtPropertyBrowser/src/QtProperty | 1 + .../src/QtRectFPropertyManager | 1 + .../src/QtRectPropertyManager | 1 + .../QtPropertyBrowser/src/QtScrollBarFactory | 1 + .../src/QtSizeFPropertyManager | 1 + .../src/QtSizePolicyPropertyManager | 1 + .../src/QtSizePropertyManager | 1 + .../QtPropertyBrowser/src/QtSliderFactory | 1 + .../QtPropertyBrowser/src/QtSpinBoxFactory | 1 + .../src/QtStringPropertyManager | 1 + .../QtPropertyBrowser/src/QtTimeEditFactory | 1 + .../src/QtTimePropertyManager | 1 + .../src/QtTreePropertyBrowser | 1 + .../src/QtVariantEditorFactory | 1 + .../QtPropertyBrowser/src/QtVariantProperty | 1 + .../src/QtVariantPropertyManager | 1 + .../src/images/button-reset.ico | Bin 0 -> 9622 bytes .../src/images/cursor-arrow.png | Bin 0 -> 171 bytes .../src/images/cursor-busy.png | Bin 0 -> 201 bytes .../src/images/cursor-closedhand.png | Bin 0 -> 147 bytes .../src/images/cursor-cross.png | Bin 0 -> 130 bytes .../src/images/cursor-forbidden.png | Bin 0 -> 199 bytes .../src/images/cursor-hand.png | Bin 0 -> 159 bytes .../src/images/cursor-hsplit.png | Bin 0 -> 155 bytes .../src/images/cursor-ibeam.png | Bin 0 -> 124 bytes .../src/images/cursor-openhand.png | Bin 0 -> 160 bytes .../src/images/cursor-sizeall.png | Bin 0 -> 174 bytes .../src/images/cursor-sizeb.png | Bin 0 -> 161 bytes .../src/images/cursor-sizef.png | Bin 0 -> 161 bytes .../src/images/cursor-sizeh.png | Bin 0 -> 145 bytes .../src/images/cursor-sizev.png | Bin 0 -> 141 bytes .../src/images/cursor-uparrow.png | Bin 0 -> 132 bytes .../src/images/cursor-vsplit.png | Bin 0 -> 161 bytes .../src/images/cursor-wait.png | Bin 0 -> 172 bytes .../src/images/cursor-whatsthis.png | Bin 0 -> 191 bytes .../src/qtbuttonpropertybrowser.cpp | 614 ++ .../src/qtbuttonpropertybrowser.h | 83 + .../QtPropertyBrowser/src/qteditorfactory.cpp | 2592 +++++++ .../QtPropertyBrowser/src/qteditorfactory.h | 396 + .../src/qtgroupboxpropertybrowser.cpp | 520 ++ .../src/qtgroupboxpropertybrowser.h | 74 + .../src/qtpropertybrowser.cmake | 66 + .../src/qtpropertybrowser.cpp | 1951 +++++ .../QtPropertyBrowser/src/qtpropertybrowser.h | 319 + .../src/qtpropertybrowser.pri | 32 + .../src/qtpropertybrowser.qrc | 24 + .../src/qtpropertybrowserutils.cpp | 686 ++ .../src/qtpropertybrowserutils_p.h | 292 + .../src/qtpropertymanager.cpp | 6864 +++++++++++++++++ .../QtPropertyBrowser/src/qtpropertymanager.h | 850 ++ .../src/qttreepropertybrowser.cpp | 1037 +++ .../src/qttreepropertybrowser.h | 132 + .../src/qtvariantproperty.cpp | 2215 ++++++ .../QtPropertyBrowser/src/qtvariantproperty.h | 177 + 240 files changed, 33870 insertions(+), 12 deletions(-) create mode 100644 external/.DS_Store create mode 100644 external/QtPropertyBrowser/.DS_Store create mode 100644 external/QtPropertyBrowser/CMakeLists.txt create mode 100644 external/QtPropertyBrowser/INSTALL.TXT create mode 100644 external/QtPropertyBrowser/README.TXT create mode 100644 external/QtPropertyBrowser/common.cmake create mode 100644 external/QtPropertyBrowser/config.cmake create mode 100644 external/QtPropertyBrowser/configure create mode 100644 external/QtPropertyBrowser/configure.bat create mode 100644 external/QtPropertyBrowser/doc/html/classic.css create mode 100644 external/QtPropertyBrowser/doc/html/images/canvas_typed.png create mode 100644 external/QtPropertyBrowser/doc/html/images/canvas_variant.png create mode 100644 external/QtPropertyBrowser/doc/html/images/decoration.png create mode 100644 external/QtPropertyBrowser/doc/html/images/demo.png create mode 100644 external/QtPropertyBrowser/doc/html/images/extension.png create mode 100644 external/QtPropertyBrowser/doc/html/images/object_controller.png create mode 100644 external/QtPropertyBrowser/doc/html/images/qt-logo.png create mode 100644 external/QtPropertyBrowser/doc/html/images/qtbuttonpropertybrowser.png create mode 100644 external/QtPropertyBrowser/doc/html/images/qtgroupboxpropertybrowser.png create mode 100644 external/QtPropertyBrowser/doc/html/images/qtpropertybrowser-duplicate.png create mode 100644 external/QtPropertyBrowser/doc/html/images/qtpropertybrowser.png create mode 100644 external/QtPropertyBrowser/doc/html/images/qttreepropertybrowser.png create mode 100644 external/QtPropertyBrowser/doc/html/images/simple.png create mode 100644 external/QtPropertyBrowser/doc/html/index.html create mode 100644 external/QtPropertyBrowser/doc/html/qtabstracteditorfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtabstracteditorfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtabstracteditorfactorybase-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtabstracteditorfactorybase.html create mode 100644 external/QtPropertyBrowser/doc/html/qtabstractpropertybrowser-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtabstractpropertybrowser.html create mode 100644 external/QtPropertyBrowser/doc/html/qtabstractpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtabstractpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtboolpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtboolpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtbrowseritem-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtbrowseritem.html create mode 100644 external/QtPropertyBrowser/doc/html/qtbuttonpropertybrowser-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtbuttonpropertybrowser.html create mode 100644 external/QtPropertyBrowser/doc/html/qtchareditorfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtchareditorfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtcharpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtcharpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtcheckboxfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtcheckboxfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtcoloreditorfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtcoloreditorfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtcolorpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtcolorpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtcursoreditorfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtcursoreditorfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtcursorpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtcursorpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtdateeditfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtdateeditfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtdatepropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtdatepropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtdatetimeeditfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtdatetimeeditfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtdatetimepropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtdatetimepropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtdoublepropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtdoublepropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtdoublespinboxfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtdoublespinboxfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtenumeditorfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtenumeditorfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtenumpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtenumpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtflagpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtflagpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtfonteditorfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtfonteditorfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtfontpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtfontpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtgroupboxpropertybrowser-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtgroupboxpropertybrowser.html create mode 100644 external/QtPropertyBrowser/doc/html/qtgrouppropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtgrouppropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtintpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtintpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtkeysequenceeditorfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtkeysequenceeditorfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtkeysequencepropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtkeysequencepropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtlineeditfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtlineeditfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtlocalepropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtlocalepropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtpointfpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtpointfpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtpointpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtpointpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtproperty-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtproperty.html create mode 100644 external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-canvas-typed.html create mode 100644 external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-canvas-variant.html create mode 100644 external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-decoration.html create mode 100644 external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-demo.html create mode 100644 external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-extension.html create mode 100644 external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-object-controller.html create mode 100644 external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-simple.html create mode 100644 external/QtPropertyBrowser/doc/html/qtpropertybrowser.dcf create mode 100644 external/QtPropertyBrowser/doc/html/qtpropertybrowser.index create mode 100644 external/QtPropertyBrowser/doc/html/qtpropertybrowser.qhp create mode 100644 external/QtPropertyBrowser/doc/html/qtrectfpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtrectfpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtrectpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtrectpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtscrollbarfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtscrollbarfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtsizefpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtsizefpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtsizepolicypropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtsizepolicypropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtsizepropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtsizepropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qtsliderfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtsliderfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtspinboxfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtspinboxfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtstringpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtstringpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qttimeeditfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qttimeeditfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qttimepropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qttimepropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/html/qttreepropertybrowser-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qttreepropertybrowser.html create mode 100644 external/QtPropertyBrowser/doc/html/qtvarianteditorfactory-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtvarianteditorfactory.html create mode 100644 external/QtPropertyBrowser/doc/html/qtvariantproperty-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtvariantproperty.html create mode 100644 external/QtPropertyBrowser/doc/html/qtvariantpropertymanager-members.html create mode 100644 external/QtPropertyBrowser/doc/html/qtvariantpropertymanager.html create mode 100644 external/QtPropertyBrowser/doc/images/canvas_typed.png create mode 100644 external/QtPropertyBrowser/doc/images/canvas_variant.png create mode 100644 external/QtPropertyBrowser/doc/images/decoration.png create mode 100644 external/QtPropertyBrowser/doc/images/demo.png create mode 100644 external/QtPropertyBrowser/doc/images/extension.png create mode 100644 external/QtPropertyBrowser/doc/images/object_controller.png create mode 100644 external/QtPropertyBrowser/doc/images/qt-logo.png create mode 100644 external/QtPropertyBrowser/doc/images/qtbuttonpropertybrowser.png create mode 100644 external/QtPropertyBrowser/doc/images/qtgroupboxpropertybrowser.png create mode 100644 external/QtPropertyBrowser/doc/images/qtpropertybrowser-duplicate.png create mode 100644 external/QtPropertyBrowser/doc/images/qtpropertybrowser.png create mode 100644 external/QtPropertyBrowser/doc/images/qttreepropertybrowser.png create mode 100644 external/QtPropertyBrowser/doc/images/simple.png create mode 100644 external/QtPropertyBrowser/doc/index.qdoc create mode 100644 external/QtPropertyBrowser/src/QtAbstractEditorFactoryBase create mode 100644 external/QtPropertyBrowser/src/QtAbstractPropertyBrowser create mode 100644 external/QtPropertyBrowser/src/QtAbstractPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtBoolPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtBrowserItem create mode 100644 external/QtPropertyBrowser/src/QtButtonPropertyBrowser create mode 100644 external/QtPropertyBrowser/src/QtCharEditorFactory create mode 100644 external/QtPropertyBrowser/src/QtCharPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtCheckBoxFactory create mode 100644 external/QtPropertyBrowser/src/QtColorEditorFactory create mode 100644 external/QtPropertyBrowser/src/QtColorPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtCursorEditorFactory create mode 100644 external/QtPropertyBrowser/src/QtCursorPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtDateEditFactory create mode 100644 external/QtPropertyBrowser/src/QtDatePropertyManager create mode 100644 external/QtPropertyBrowser/src/QtDateTimeEditFactory create mode 100644 external/QtPropertyBrowser/src/QtDateTimePropertyManager create mode 100644 external/QtPropertyBrowser/src/QtDoublePropertyManager create mode 100644 external/QtPropertyBrowser/src/QtDoubleSpinBoxFactory create mode 100644 external/QtPropertyBrowser/src/QtEnumEditorFactory create mode 100644 external/QtPropertyBrowser/src/QtEnumPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtFlagPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtFontEditorFactory create mode 100644 external/QtPropertyBrowser/src/QtFontPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtGroupBoxPropertyBrowser create mode 100644 external/QtPropertyBrowser/src/QtGroupPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtIntPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtKeySequenceEditorFactory create mode 100644 external/QtPropertyBrowser/src/QtKeySequencePropertyManager create mode 100644 external/QtPropertyBrowser/src/QtLineEditFactory create mode 100644 external/QtPropertyBrowser/src/QtLocalePropertyManager create mode 100644 external/QtPropertyBrowser/src/QtPointFPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtPointPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtProperty create mode 100644 external/QtPropertyBrowser/src/QtRectFPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtRectPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtScrollBarFactory create mode 100644 external/QtPropertyBrowser/src/QtSizeFPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtSizePolicyPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtSizePropertyManager create mode 100644 external/QtPropertyBrowser/src/QtSliderFactory create mode 100644 external/QtPropertyBrowser/src/QtSpinBoxFactory create mode 100644 external/QtPropertyBrowser/src/QtStringPropertyManager create mode 100644 external/QtPropertyBrowser/src/QtTimeEditFactory create mode 100644 external/QtPropertyBrowser/src/QtTimePropertyManager create mode 100644 external/QtPropertyBrowser/src/QtTreePropertyBrowser create mode 100644 external/QtPropertyBrowser/src/QtVariantEditorFactory create mode 100644 external/QtPropertyBrowser/src/QtVariantProperty create mode 100644 external/QtPropertyBrowser/src/QtVariantPropertyManager create mode 100644 external/QtPropertyBrowser/src/images/button-reset.ico create mode 100644 external/QtPropertyBrowser/src/images/cursor-arrow.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-busy.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-closedhand.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-cross.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-forbidden.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-hand.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-hsplit.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-ibeam.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-openhand.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-sizeall.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-sizeb.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-sizef.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-sizeh.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-sizev.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-uparrow.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-vsplit.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-wait.png create mode 100644 external/QtPropertyBrowser/src/images/cursor-whatsthis.png create mode 100644 external/QtPropertyBrowser/src/qtbuttonpropertybrowser.cpp create mode 100644 external/QtPropertyBrowser/src/qtbuttonpropertybrowser.h create mode 100644 external/QtPropertyBrowser/src/qteditorfactory.cpp create mode 100644 external/QtPropertyBrowser/src/qteditorfactory.h create mode 100644 external/QtPropertyBrowser/src/qtgroupboxpropertybrowser.cpp create mode 100644 external/QtPropertyBrowser/src/qtgroupboxpropertybrowser.h create mode 100644 external/QtPropertyBrowser/src/qtpropertybrowser.cmake create mode 100644 external/QtPropertyBrowser/src/qtpropertybrowser.cpp create mode 100644 external/QtPropertyBrowser/src/qtpropertybrowser.h create mode 100644 external/QtPropertyBrowser/src/qtpropertybrowser.pri create mode 100644 external/QtPropertyBrowser/src/qtpropertybrowser.qrc create mode 100644 external/QtPropertyBrowser/src/qtpropertybrowserutils.cpp create mode 100644 external/QtPropertyBrowser/src/qtpropertybrowserutils_p.h create mode 100644 external/QtPropertyBrowser/src/qtpropertymanager.cpp create mode 100644 external/QtPropertyBrowser/src/qtpropertymanager.h create mode 100644 external/QtPropertyBrowser/src/qttreepropertybrowser.cpp create mode 100644 external/QtPropertyBrowser/src/qttreepropertybrowser.h create mode 100644 external/QtPropertyBrowser/src/qtvariantproperty.cpp create mode 100644 external/QtPropertyBrowser/src/qtvariantproperty.h diff --git a/examples/epen_graph_editor/CMakeLists.txt b/examples/epen_graph_editor/CMakeLists.txt index 55b61b5d5..f4e0a16d9 100644 --- a/examples/epen_graph_editor/CMakeLists.txt +++ b/examples/epen_graph_editor/CMakeLists.txt @@ -10,5 +10,5 @@ target_include_directories(epen_graph_editor include ) -target_link_libraries(epen_graph_editor QtNodes Qt6::Core +target_link_libraries(epen_graph_editor PRIVATE Qt6PropertyBrowser QtNodes Qt6::Core Qt6::Widgets) diff --git a/examples/epen_graph_editor/include/DataFlowModel.hpp b/examples/epen_graph_editor/include/DataFlowModel.hpp index 4126dae66..e9d6788aa 100644 --- a/examples/epen_graph_editor/include/DataFlowModel.hpp +++ b/examples/epen_graph_editor/include/DataFlowModel.hpp @@ -36,7 +36,6 @@ class DataFlowModel : public DataFlowGraphModel DataFlowModel(std::shared_ptr registry); NodeId addNode(QString const nodeType) override; - bool detachPossible(ConnectionId const) const override { return true; } @@ -45,17 +44,14 @@ class DataFlowModel : public DataFlowGraphModel NodeId addNodeName(QString const nodeTypeName); bool deleteNode(NodeId const nodeId) override; - QVariant nodeData(NodeId nodeId, NodeRole role) const override; - bool setNodeData(NodeId nodeId, NodeRole role, QVariant value) override; - - void addPort(NodeId nodeId, PortType portType, PortIndex portIndex); + void addProcessNodePort(NodeId nodeId, PortType portType, PortIndex portIndex); - void removePort(NodeId nodeId, PortType portType, PortIndex portIndex); + void removeProcessNodePort(NodeId nodeId, PortType portType, PortIndex portIndex); private: std::unordered_map> nodesMap; @@ -69,5 +65,6 @@ class DataFlowModel : public DataFlowGraphModel mutable std::unordered_map _nodePortCounts; mutable std::unordered_map _nodeWidgets; mutable std::unordered_map _nodeSize; + mutable std::unordered_map _nodeNames; PortAddRemoveWidget *widget(NodeId nodeId) const; }; diff --git a/examples/epen_graph_editor/src/DataFlowModel.cpp b/examples/epen_graph_editor/src/DataFlowModel.cpp index baa9074d9..6294f0a2d 100644 --- a/examples/epen_graph_editor/src/DataFlowModel.cpp +++ b/examples/epen_graph_editor/src/DataFlowModel.cpp @@ -23,6 +23,7 @@ NodeId DataFlowModel::addNode(QString const nodeType) widget(newNodeId)->populateButtons(PortType::Out, 1); _nodeSize[newNodeId] = QSize(250, 130); } + _nodeNames[newNodeId]=QString(nodeType) ;// + newNodeId; return newNodeId; } @@ -120,7 +121,11 @@ QVariant DataFlowModel::nodeData(NodeId nodeId, NodeRole role) const } } } - + if (role == NodeRole::Caption && nodeTypeName != "VideoOutput") { + QString fullCaption = DataFlowGraphModel::nodeData(nodeId, role).toString() + "
[" + + _nodeNames[nodeId] + "]"; + return fullCaption; + } return DataFlowGraphModel::nodeData(nodeId, role); } @@ -150,7 +155,7 @@ bool DataFlowModel::setNodeData(NodeId nodeId, NodeRole role, QVariant value) return DataFlowGraphModel::setNodeData(nodeId, role, value); } -void DataFlowModel::addPort(NodeId nodeId, PortType portType, PortIndex portIndex) +void DataFlowModel::addProcessNodePort(NodeId nodeId, PortType portType, PortIndex portIndex) { PortIndex first = portIndex; PortIndex last = first; @@ -165,7 +170,7 @@ void DataFlowModel::addPort(NodeId nodeId, PortType portType, PortIndex portInde Q_EMIT nodeUpdated(nodeId); } -void DataFlowModel::removePort(NodeId nodeId, PortType portType, PortIndex portIndex) +void DataFlowModel::removeProcessNodePort(NodeId nodeId, PortType portType, PortIndex portIndex) { PortIndex first = portIndex; PortIndex last = first; diff --git a/examples/epen_graph_editor/src/PortAddRemoveWidget.cpp b/examples/epen_graph_editor/src/PortAddRemoveWidget.cpp index 0295b0be2..f0807880c 100644 --- a/examples/epen_graph_editor/src/PortAddRemoveWidget.cpp +++ b/examples/epen_graph_editor/src/PortAddRemoveWidget.cpp @@ -104,7 +104,7 @@ void PortAddRemoveWidget::onPlusClicked() addButtonGroupToLayout((portType == PortType::In) ? _left : _right, portIndex + 1, true); // Trigger changes in the model - _model.addPort(_nodeId, portType, portIndex + 1); + _model.addProcessNodePort(_nodeId, portType, portIndex + 1); adjustSize(); } @@ -122,7 +122,7 @@ void PortAddRemoveWidget::onMinusClicked() removeButtonGroupFromLayout((portType == PortType::In) ? _left : _right, portIndex); // Trigger changes in the model - _model.removePort(_nodeId, portType, portIndex); + _model.removeProcessNodePort(_nodeId, portType, portIndex); adjustSize(); } diff --git a/external/.DS_Store b/external/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..7c0e90289bbdad0c523cedf7df7f843f62106261 GIT binary patch literal 6148 zcmeHKUu)Dr5T9+Yy_}_Tf`SObg0E-)*gF+`iP!odv@b^V!Im@W1sj@X&r8lI$3Z@T zeiq;TAbuVF&F&T&PeJ=2<=BCl-|pM}ynb2OY%tv;u ze~U(Gk{4TB-^J2$V`a7JHN7?OC^%7NP=v)K?}y_z+`+?PEuO;{G-|W@5R9`_W$)nUoa!N$OXK2fCmC91$vuOROJdxeGh3V*@YFW&}aIk_|g zc13t=m#*Lv9RrSmMP-2Z2MJ~LEmj8g)&Zlh0Kf*^TF~Z$kaMI(-(qDDBM@OyfhJYh zD~2%X@Jk!#TdWM4bQ1RRA?%Zdy`c#GbkvtRoP=-CS;v55pw7Uu>9+a&fA;75e?7_d z90QJlgWzl8t* literal 0 HcmV?d00001 diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index d7fbfcca7..6890af652 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -5,3 +5,5 @@ if(BUILD_TESTING) add_subdirectory(Catch2) endif() endif() + +add_subdirectory(QtPropertyBrowser) \ No newline at end of file diff --git a/external/QtPropertyBrowser/.DS_Store b/external/QtPropertyBrowser/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..118db734a0652e8dc357978bcccaabb8885f728a GIT binary patch literal 8196 zcmeHM&2JM&6n~S1vL+jZ04(f6+Wj~j(ZsswU9CsY451{52dJ!s-1kE6b=jH;!+>GHFkl!k3>XGJ4F>R? zEt+-Adta@Z(J){b_#zn)&j$y)kU1@zO3FtE4zdJ5*@x4zp^kNc#5h{!v}`IVq3Bap z4@5(WE-{FLd z{UVMJAZhpABQWW`oCY5_?BX8>h8Q0;>8Twj_Cy9#IVc>1EsR$^9w*|p;W9E_3s;8- zXnQ1hi939eiZsxTz<3_+vLiS0O$V|UDwvhu?q8mbwEuosfnT8jMYxLWT}R(VC_%9u zC3#DuPQf}XBVq}eUp^Wm_S2SoFP@d?sQnye0juyvp4V9= zme_(?urgMrY@glVzc4emFgxXZKYuXg>@UntPdW2*mk$my)_C^P59{TfaF=m$VPhlu zZ2|-8`2F|x+j2%u$Uq3~ZvRln#WX3U^v$w86#Eem!!;fUNx<3W?HD;;N$Bnh+u|5;5BXiKiKTdhMls4ROli}N zB9~QZ{^6a_^=P=t@;piSuCNr|Fp;&03Qsb2q2~Glt7fnKt4Pe|)>_JUO0glU6o725 z`Aq88SZhj4Qe>RbOeUNAMbB6;iC62-c%5%U1D?Wj_#Ixs8~6+Uf&WM!IYYiBlVqO! zNUo4;-@`7NuxlzQAvnl#9HlJBQNI6&A?gmA3QSJR Wrjj^=?PGliFzOpen Solution from .pro file' on the .pro files in the +example and plugin directories, and then build from within Visual +Studio. + +Unpacking and installation +-------------------------- + +1. Unpacking the archive (if you have not done so already). + + On Unix and Mac OS X (in a terminal window): + + cd your-install-dir + gunzip some-package.tar.gz + tar xvf some-package.tar + + This creates the subdirectory some-package containing the files. + + On Windows: + + Unpack the .zip archive by right-clicking it in explorer and + choosing "Extract All...". If your version of Windows does not + have zip support, you can use the infozip tools available + from www.info-zip.org. + + If you are using the infozip tools (in a command prompt window): + cd your-install-dir + unzip some-package.zip + +2. Configuring the package. + + The configure script is called "configure" on unix/mac and + "configure.bat" on Windows. It should be run from a command line + after cd'ing to the package directory. + + You can choose whether you want to use the component by including + its source code directly into your project, or build the component + as a dynamic shared library (DLL) that is loaded into the + application at run-time. The latter may be preferable for + technical or licensing (LGPL) reasons. If you want to build a DLL, + run the configure script with the argument "-library". Also see + the note about usage below. + + (Components that are Qt plugins, e.g. styles and image formats, + are by default built as a plugin DLL.) + + The configure script will prompt you in some cases for further + information. Answer these questions and carefully read the license text + before accepting the license conditions. The package cannot be used if + you do not accept the license conditions. + +3. Building the component and examples (when required). + + If a DLL is to be built, or if you would like to build the + examples, next give the commands + + qmake + make [or nmake if your are using Microsoft Visual C++] + + The example program(s) can be found in the directory called + "examples" or "example". + + Components that are Qt plugins, e.g. styles and image formats, are + ready to be used as soon as they are built, so the rest of this + installation instruction can be skipped. + +4. Building the Qt Designer plugin (optional). + + Some of the widget components are provided with plugins for Qt + Designer. To build and install the plugin, cd into the + some-package/plugin directory and give the commands + + qmake + make [or nmake if your are using Microsoft Visual C++] + + Restart Qt Designer to make it load the new widget plugin. + + Note: If you are using the built-in Qt Designer from the Qt Visual + Studio Integration, you will need to manually copy the plugin DLL + file, i.e. copy + %QTDIR%\plugins\designer\some-component.dll + to the Qt Visual Studio Integration plugin path, typically: + C:\Program Files\Trolltech\Qt VS Integration\plugins + + Note: If you for some reason are using a Qt Designer that is built + in debug mode, you will need to build the plugin in debug mode + also. Edit the file plugin.pro in the plugin directory, changing + 'release' to 'debug' in the CONFIG line, before running qmake. + + + +Solutions components are intended to be used directly from the package +directory during development, so there is no 'make install' procedure. + + +Using a component in your project +--------------------------------- + +To use this component in your project, add the following line to the +project's .pro file (or do the equivalent in your IDE): + + include(your-install-dir/some-package/src/some-package.pri) + +This adds the package's sources and headers to the SOURCES and HEADERS +project variables respectively (or, if the component has been +configured as a DLL, it adds that library to the LIBS variable), and +updates INCLUDEPATH to contain the package's src +directory. Additionally, the .pri file may include some dependencies +needed by the package. + +To include a header file from the package in your sources, you can now +simply use: + + #include + +or alternatively, in pre-Qt 4 style: + + #include + +Refer to the documentation to see the classes and headers this +components provides. + + + +Install documentation (optional) +-------------------------------- + +The HTML documentation for the package's classes is located in the +your-install-dir/some-package/doc/html/index.html. You can open this +file and read the documentation with any web browser. + +To install the documentation into Qt Assistant (for Qt version 4.4 and +later): + +1. In Assistant, open the Edit->Preferences dialog and choose the + Documentation tab. Click the Add... button and select the file + your-install-dir/some-package/doc/html/some-package.qch + +For Qt versions prior to 4.4, do instead the following: + +1. The directory your-install-dir/some-package/doc/html contains a + file called some-package.dcf. Execute the following commands in a + shell, command prompt or terminal window: + + cd your-install-dir/some-package/doc/html/ + assistant -addContentFile some-package.dcf + +The next time you start Qt Assistant, you can access the package's +documentation. + + +Removing the documentation from assistant +----------------------------------------- + +If you have installed the documentation into Qt Assistant, and want to uninstall it, do as follows, for Qt version 4.4 and later: + +1. In Assistant, open the Edit->Preferences dialog and choose the + Documentation tab. In the list of Registered Documentation, select + the item com.nokia.qtsolutions.some-package_version, and click + the Remove button. + +For Qt versions prior to 4.4, do instead the following: + +1. The directory your-install-dir/some-package/doc/html contains a + file called some-package.dcf. Execute the following commands in a + shell, command prompt or terminal window: + + cd your-install-dir/some-package/doc/html/ + assistant -removeContentFile some-package.dcf + + + +Using the component as a DLL +---------------------------- + +1. Normal components + + The shared library (DLL) is built and placed in the + some-package/lib directory. It is intended to be used directly + from there during development. When appropriate, both debug and + release versions are built, since the run-time linker will in some + cases refuse to load a debug-built DLL into a release-built + application or vice versa. + + The following steps are taken by default to help the dynamic + linker to locate the DLL at run-time (during development): + + Unix: The some-package.pri file will add linker instructions to + add the some-package/lib directory to the rpath of the + executable. (When distributing, or if your system does not support + rpath, you can copy the shared library to another place that is + searched by the dynamic linker, e.g. the "lib" directory of your + Qt installation.) + + Mac: The full path to the library is hardcoded into the library + itself, from where it is copied into the executable at link time, + and ready by the dynamic linker at run-time. (When distributing, + you will want to edit these hardcoded paths in the same way as for + the Qt DLLs. Refer to the document "Deploying an Application on + Mac OS X" in the Qt Reference Documentation.) + + Windows: the .dll file(s) are copied into the "bin" directory of + your Qt installation. The Qt installation will already have set up + that directory to be searched by the dynamic linker. + + +2. Plugins + + For Qt Solutions plugins (e.g. image formats), both debug and + release versions of the plugin are built by default when + appropriate, since in some cases the release Qt library will not + load a debug plugin, and vice versa. The plugins are automatically + copied into the plugins directory of your Qt installation when + built, so no further setup is required. + + Plugins may also be built statically, i.e. as a library that will be + linked into your application executable, and so will not need to + be redistributed as a separate plugin DLL to end users. Static + building is required if Qt itself is built statically. To do it, + just add "static" to the CONFIG variable in the plugin/plugin.pro + file before building. Refer to the "Static Plugins" section in the + chapter "How to Create Qt Plugins" for explanation of how to use a + static plugin in your application. The source code of the example + program(s) will also typically contain the relevant instructions + as comments. + + + +Uninstalling +------------ + + The following command will remove any fils that have been + automatically placed outside the package directory itself during + installation and building + + make distclean [or nmake if your are using Microsoft Visual C++] + + If Qt Assistant documentation or Qt Designer plugins have been + installed, they can be uninstalled manually, ref. above. + + +Enjoy! :) + +- The Qt Solutions Team. diff --git a/external/QtPropertyBrowser/README.TXT b/external/QtPropertyBrowser/README.TXT new file mode 100644 index 000000000..148c47b4b --- /dev/null +++ b/external/QtPropertyBrowser/README.TXT @@ -0,0 +1,93 @@ +Qt Solutions Component: Property Browser + +A property browser framework enabling the user to edit a set of +properties. + +The framework provides a browser widget that displays the given +properties with labels and corresponding editing widgets (e.g. +line edits or comboboxes). The various types of editing widgets +are provided by the framework's editor factories: For each +property type, the framework provides a property manager (e.g. +QtIntPropertyManager and QtStringPropertyManager) which can be +associated with the preferred editor factory (e.g. +QtSpinBoxFactory and QtLineEditFactory). The framework also +provides a variant based property type with corresponding variant +manager and factory. Finally, the framework provides three +ready-made implementations of the browser widget: +QtTreePropertyBrowser, QtButtonPropertyBrowser and +QtGroupBoxPropertyBrowser. + +Version history: + +2.1: - QtTreePropertyBrowser - tooltip of property applied to + first column, while second column shows the value text of property + in its tooltip + - QtAbstractPropertyManager - initializeProperty() and + uninitializeProperty() without const modifier now + - QtTreePropertyBrowser and QtGroupBoxPropertyBrowser - internal + margin set to 0 + - QtProperty - setEnabled() and isEnabled() methods added + - QtTreePropertyBrowser - "rootIsDecorated", "indentation" and + "headerVisible" properties added + - QtProperty - hasValue() method added, useful for group + properties + +2.2: - FocusOut event now filtered out in case of + Qt::ActiveWindowFocusReason reason. In that case editor is not + closed when its sub dialog is executed + - Removed bug in color icon generation + - Decimals attribute added to "double" property type + - PointF, SizeF and RectF types supported + - Proper translation calls for tree property browser + - QtProperty - ensure inserted subproperty is different from + "this" property + - QtBrowserItem class introduced, useful for identifying browser's + gui elements + - Possibility to control expanded state of QtTreePropertyBrowser's + items from code + - QtTreePropertyBrowser - "resizeMode" and "splitterPosition" + properties added + - QtGroupBoxPropertyBrowser - fixed crash in case of deleting the + editor factory and then deleting the manager + - "Decoration" example added - it shows how to add new + responsibilities to the existing managers and editor factories + +2.3: - Various bugfixes and improvements + - QtProperty - setModified() and isModified() methods added + - QtTreePropertyBrowser - disabling an item closes its editor + - KeySequence, Char, Locale and Cursor types supported + - Support for icons in enum type added + - Kerning subproperty exposed in Font type + - New property browser class added - QtButtonPropertyBrowser with + drop down button as a grouping element + +2.4: - Fixed memory leak of QtProperty + - QtTreePropertyBrowser - group items are rendered better + - QtTreePropertyBrowser - propertiesWithoutValueMarked and + alternatingRowColors features added + - QtTreePropertyBrowser - possibility of coloring properties added + - QtTreePropertyBrowser - keyboard navigation improved + - New factories providing popup dialogs added: + QtColorEditorFactory and QtFontEditorFactory + - Single step attribute added to: QtIntPropertyManager and + QtDoublePropertyManager + +2.5: - "Object Controller" example added. It implements a similar + widget to the property editor in QDesigner + - Compile with QT_NO_CURSOR + - Expand root item with single click on the '+' icon + - QtRectPropertyManager and QtRectFPropertyManager - by default + constraint is null rect meaning no constraint is applied + +2.6: - QtGroupPropertyBrowser - don't force the layout to show the + whole labels' contents for read only properties, show tooltips for + them in addition. + - QtTreePropertyBrowser - fixed painting of the editor for color + property type when style sheet is used (QTSOLBUG-64). + - Make it possible to change the style of the checkboxes with a + stylesheet (QTSOLBUG-61). + - Change the minimum size of a combobox so that it can show at + least one character and an icon. + - Make it possible to properly style custom embedded editors (e.g. + the color editor provided with the solution). + diff --git a/external/QtPropertyBrowser/common.cmake b/external/QtPropertyBrowser/common.cmake new file mode 100644 index 000000000..c0e5c9c95 --- /dev/null +++ b/external/QtPropertyBrowser/common.cmake @@ -0,0 +1,27 @@ +# common.cmake - Common settings for QtPropertyBrowser + +# Check if config.cmake exists and read SOLUTIONS_LIBRARY setting +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/config.cmake") + include(config.cmake) + if(DEFINED SOLUTIONS_LIBRARY AND SOLUTIONS_LIBRARY STREQUAL "yes") + set(QTPROPERTYBROWSER_USELIB ON CACHE BOOL "Use QtPropertyBrowser as a library" FORCE) + endif() +endif() + +# Set library name (equivalent to qtLibraryTarget) +# In Qt6, we typically just use the library name directly +set(QTPROPERTYBROWSER_LIBNAME "Qt6PropertyBrowser") + +# Set library directory +set(QTPROPERTYBROWSER_LIBDIR "${CMAKE_CURRENT_SOURCE_DIR}/lib") + +# Add RPATH for Unix systems when using the library but not building it +if(UNIX AND QTPROPERTYBROWSER_USELIB AND NOT QTPROPERTYBROWSER_BUILDLIB) + list(APPEND CMAKE_INSTALL_RPATH "${QTPROPERTYBROWSER_LIBDIR}") + set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) + set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) +endif() + +# Export these variables for use in subdirectories +set(QTPROPERTYBROWSER_LIBNAME ${QTPROPERTYBROWSER_LIBNAME} PARENT_SCOPE) +set(QTPROPERTYBROWSER_LIBDIR ${QTPROPERTYBROWSER_LIBDIR} PARENT_SCOPE) \ No newline at end of file diff --git a/external/QtPropertyBrowser/config.cmake b/external/QtPropertyBrowser/config.cmake new file mode 100644 index 000000000..fdd3fc813 --- /dev/null +++ b/external/QtPropertyBrowser/config.cmake @@ -0,0 +1,9 @@ +# config.cmake - Configuration file for QtPropertyBrowser +# This file is the CMake equivalent of config.pri + +# Set to "yes" to build and use QtPropertyBrowser as a library +set(SOLUTIONS_LIBRARY "yes") + +# Add any other configuration options here +# For example: +# set(SOME_OTHER_OPTION "value") \ No newline at end of file diff --git a/external/QtPropertyBrowser/configure b/external/QtPropertyBrowser/configure new file mode 100644 index 000000000..3c4edfff2 --- /dev/null +++ b/external/QtPropertyBrowser/configure @@ -0,0 +1,25 @@ +#!/bin/sh + +if [ "x$1" != "x" -a "x$1" != "x-library" ]; then + echo "Usage: $0 [-library]" + echo + echo "-library: Build the component as a dynamic library (DLL). Default is to" + echo " include the component source code directly in the application." + echo + exit 0 +fi + +rm -f config.pri +if [ "x$1" = "x-library" ]; then + echo "Configuring to build this component as a dynamic library." + echo "SOLUTIONS_LIBRARY = yes" > config.pri +fi + +echo +echo "This component is now configured." +echo +echo "To build the component library (if requested) and example(s)," +echo "run qmake and your make command." +echo +echo "To remove or reconfigure, run make distclean." +echo diff --git a/external/QtPropertyBrowser/configure.bat b/external/QtPropertyBrowser/configure.bat new file mode 100644 index 000000000..9bf19870b --- /dev/null +++ b/external/QtPropertyBrowser/configure.bat @@ -0,0 +1,80 @@ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: +:: Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +:: Contact: http://www.qt-project.org/legal +:: +:: This file is part of the Qt Solutions component. +:: +:: $QT_BEGIN_LICENSE:BSD$ +:: You may use this file under the terms of the BSD license as follows: +:: +:: "Redistribution and use in source and binary forms, with or without +:: modification, are permitted provided that the following conditions are +:: met: +:: * Redistributions of source code must retain the above copyright +:: notice, this list of conditions and the following disclaimer. +:: * Redistributions in binary form must reproduce the above copyright +:: notice, this list of conditions and the following disclaimer in +:: the documentation and/or other materials provided with the +:: distribution. +:: * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +:: of its contributors may be used to endorse or promote products derived +:: from this software without specific prior written permission. +:: +:: +:: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +:: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +:: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +:: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +:: OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +:: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +:: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +:: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +:: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +:: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +:: OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +:: +:: $QT_END_LICENSE$ +:: +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +@echo off + +rem +rem "Main" +rem + +if not "%1"=="" ( + if not "%1"=="-library" ( + call :PrintUsage + goto EOF + ) +) + +if exist config.pri. del config.pri +if "%1"=="-library" ( + echo Configuring to build this component as a dynamic library. + echo SOLUTIONS_LIBRARY = yes > config.pri +) + +echo . +echo This component is now configured. +echo . +echo To build the component library (if requested) and example(s), +echo run qmake and your make or nmake command. +echo . +echo To remove or reconfigure, run make (nmake) distclean. +echo . +goto EOF + +:PrintUsage +echo Usage: configure.bat [-library] +echo . +echo -library: Build the component as a dynamic library (DLL). Default is to +echo include the component source directly in the application. +echo A DLL may be preferable for technical or licensing (LGPL) reasons. +echo . +goto EOF + + +:EOF diff --git a/external/QtPropertyBrowser/doc/html/classic.css b/external/QtPropertyBrowser/doc/html/classic.css new file mode 100644 index 000000000..b8cae8e1e --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/classic.css @@ -0,0 +1,284 @@ +BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { + font-family: Arial, Geneva, Helvetica, sans-serif; +} +H1 { + text-align: center; + font-size: 160%; +} +H2 { + font-size: 120%; +} +H3 { + font-size: 100%; +} + +h3.fn,span.fn +{ + background-color: #eee; + border-width: 1px; + border-style: solid; + border-color: #ddd; + font-weight: bold; + padding: 6px 0px 6px 10px; + margin: 42px 0px 0px 0px; +} + +hr { + border: 0; + color: #a0a0a0; + background-color: #ccc; + height: 1px; + width: 100%; + text-align: left; + margin: 34px 0px 34px 0px; +} + +table.valuelist { + border-width: 1px 1px 1px 1px; + border-style: solid; + border-color: #dddddd; + border-collapse: collapse; + background-color: #f0f0f0; +} + +table.indextable { + border-width: 1px 1px 1px 1px; + border-style: solid; + border-collapse: collapse; + background-color: #f0f0f0; + border-color:#555; + font-size: 100%; +} + +table td.largeindex { + border-width: 1px 1px 1px 1px; + border-collapse: collapse; + background-color: #f0f0f0; + border-color:#555; + font-size: 120%; +} + +table.valuelist th { + border-width: 1px 1px 1px 2px; + padding: 4px; + border-style: solid; + border-color: #666; + color:white; + background-color:#666; +} + +th.titleheader { + border-width: 1px 0px 1px 0px; + padding: 2px; + border-style: solid; + border-color: #666; + color:white; + background-color:#555; + background-image:url('images/gradient.png')}; + background-repeat: repeat-x; + font-size: 100%; +} + + +th.largeheader { + border-width: 1px 0px 1px 0px; + padding: 4px; + border-style: solid; + border-color: #444; + color:white; + background-color:#555555; + font-size: 120%; +} + +p { + + margin-left: 4px; + margin-top: 8px; + margin-bottom: 8px; +} + +a:link +{ + color: #0046ad; + text-decoration: none +} + +a:visited +{ + color: #672967; + text-decoration: none +} + +a.obsolete +{ + color: #661100; + text-decoration: none +} + +a.compat +{ + color: #661100; + text-decoration: none +} + +a.obsolete:visited +{ + color: #995500; + text-decoration: none +} + +a.compat:visited +{ + color: #995500; + text-decoration: none +} + +body +{ + background: #ffffff; + color: black +} + +table.generic, table.annotated +{ + border-width: 1px; + border-color:#bbb; + border-style:solid; + border-collapse:collapse; +} + +table td.memItemLeft { + width: 180px; + padding: 2px 0px 0px 8px; + margin: 4px; + border-width: 1px; + border-color: #E0E0E0; + border-style: none; + font-size: 100%; + white-space: nowrap +} + +table td.memItemRight { + padding: 2px 8px 0px 8px; + margin: 4px; + border-width: 1px; + border-color: #E0E0E0; + border-style: none; + font-size: 100%; +} + +table tr.odd { + background: #f0f0f0; + color: black; +} + +table tr.even { + background: #e4e4e4; + color: black; +} + +table.annotated th { + padding: 3px; + text-align: left +} + +table.annotated td { + padding: 3px; +} + +table tr pre +{ + padding-top: 0px; + padding-bottom: 0px; + padding-left: 0px; + padding-right: 0px; + border: none; + background: none +} + +tr.qt-style +{ + background: #96E066; + color: black +} + +body pre +{ + padding: 0.2em; + border: #e7e7e7 1px solid; + background: #f1f1f1; + color: black +} + +table tr.qt-code pre +{ + padding: 0.2em; + border: #e7e7e7 1px solid; + background: #f1f1f1; + color: black +} + +span.preprocessor, span.preprocessor a +{ + color: darkblue; +} + +span.comment +{ + color: darkred; + font-style: italic +} + +span.string,span.char +{ + color: darkgreen; +} + +.title +{ + text-align: center +} + +.subtitle +{ + font-size: 0.8em +} + +.small-subtitle +{ + font-size: 0.65em +} + +.qmlitem { + padding: 0; +} + +.qmlname { + white-space: nowrap; +} + +.qmltype { + text-align: center; + font-size: 160%; +} + +.qmlproto { + background-color: #eee; + border-width: 1px; + border-style: solid; + border-color: #ddd; + font-weight: bold; + padding: 6px 10px 6px 10px; + margin: 42px 0px 0px 0px; +} + +.qmlreadonly { + float: right; + color: red +} + +.qmldoc { +} + +*.qmlitem p { +} diff --git a/external/QtPropertyBrowser/doc/html/images/canvas_typed.png b/external/QtPropertyBrowser/doc/html/images/canvas_typed.png new file mode 100644 index 0000000000000000000000000000000000000000..888cb6a0e1e2c3081b3c5dd82bbc1ab3ca0c7eb0 GIT binary patch literal 16376 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 literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/html/images/decoration.png b/external/QtPropertyBrowser/doc/html/images/decoration.png new file mode 100644 index 0000000000000000000000000000000000000000..92db0fc60f85e9a9e2862c50367d8788ac7145b5 GIT binary patch literal 6620 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�tNNt{hvpw4vjnQ^nGmzSua%t*RO z1Xq>){g_F2U3v*u0G-oxB30nkc&)=!e}8}R;OdMGET+zwKl}h%7NW=kKAe0L1}eFo<1l)m+DdI z4K!xO->8Zp9@ykf?8I`(7js%m^RmjI&*;m*i8@*1aNIPz20aB##$z#V>M#MIF8O0T z)aM{ErO-7G$F}Oo($W&l{UIXaEqiM6+TlY?rDM-68+RI8hQ&{3=u=Zzrv8_+r9NGv z-90_9&TUWWkgm<2iuc2t4+m;Kjt8%@%Dl{n@ceA+Z|y^uzHxi%_c5JGH)8Q2rHF1_ zCDpYK_4d}Au^i&1XjkL;NY=kyGO$Oj^}7|?97Mp}&A2Z;Zj=mdzH)|CzhunD(}9w5 zuJ#&#R!p-aQ=Z>898aN6C9dbt00L|;7e$#L06hGFg|~R|AQH1trfsX>X#P?!2zCp< zCk39_t6KQ&DENMaG+vg{=SvtiC{DlJ4IWd${63=nJYOSfkEw0dW*y9>{DV97IS@~m z8i&a%-sXweL^aLP3N2rus}8np-fs+d$L8{=<5HU;T^qU?5r>Q3DL*!D?G+fRbQHL&ey*gIO%WEtcucU~oCMLN` z8)$z;g+~12S1&APLm+3gE7@Gd zLYhs_wag^>nK5VVamgzVQPDbF z)4stTv9~gikz(Btus<-(a2OCyTcZaS3iiQL@Dv%A$@y$aWw=p)DvdDOBw2nja(@oe z{D5jOvL8z2>+G+iDX1RMjMcdu6fBH1{iT8u zuJ3B*+)wFPNr5Q)X-X?b74v<^`o*l>v*C|iBTDWWT=#*>U!Um3Mrh@^0sy$^4Ruqo z7r=RKVH+Li&o+tn5CrB3rSn}Bqkx_9#Urjg!Qt&nT02ddLrJs0)1(jpWV4~_5Z>Qq z$f(83fmexv__}M1N^` zk(j!m7fg?>Kz+xRGnzUiSDX|?h+&+NXUr&ag1>}mc2WWW5IY1zOr(FzVuwIAm@yLW z-vZ|IKg7lSf9PR)_*d~S;s4S5)5E_8{|Nt&9)=YEWAHEGf9w76{a=@%r2yo?fxC@4 z2PpwJP9&ipx2}YgRC*Q07?kMmLj%lVf);@eBrFW7p{RKD9)@Z2r7nZah5 literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/html/images/demo.png b/external/QtPropertyBrowser/doc/html/images/demo.png new file mode 100644 index 0000000000000000000000000000000000000000..767e77f66cf09217830b556d211a9029395abd79 GIT binary patch literal 76351 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�YJiQ*E#{%7dHn@ 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 F_a8dJpCkYP literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/html/images/object_controller.png b/external/QtPropertyBrowser/doc/html/images/object_controller.png new file mode 100644 index 0000000000000000000000000000000000000000..e490e6d5371adf0afd0928ce3ff97601f7048024 GIT binary patch literal 39658 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 Yu8XGlt*q6I_7=Rfj_RpDRI?8GKW8Fbv;Y7A literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/html/images/qt-logo.png b/external/QtPropertyBrowser/doc/html/images/qt-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..794162f5af58e7b38beebf472842fc9703ede19b GIT binary patch literal 4075 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 literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/html/images/qtbuttonpropertybrowser.png b/external/QtPropertyBrowser/doc/html/images/qtbuttonpropertybrowser.png new file mode 100644 index 0000000000000000000000000000000000000000..7890fdb04d942505e8198a02b913e76fd75800e8 GIT binary patch literal 7181 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 NQIJ)YDU&ks|1T1HXA1xT literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/html/images/qtgroupboxpropertybrowser.png b/external/QtPropertyBrowser/doc/html/images/qtgroupboxpropertybrowser.png new file mode 100644 index 0000000000000000000000000000000000000000..203c50f06dcdbc38cd4231b4df74879eed1a2fdf GIT binary patch literal 5819 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 literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/html/images/qtpropertybrowser-duplicate.png b/external/QtPropertyBrowser/doc/html/images/qtpropertybrowser-duplicate.png new file mode 100644 index 0000000000000000000000000000000000000000..0a939fc3066d2891fc14f6dc6286c12c29cf84c1 GIT binary patch literal 1620 zcmZvcdoZd$rYM4t#Kcw`KiXuugn8u_~=&>e}OpQT_VP?6#=0{Adq|{Y6 zGG2)uq?E_?N-8QN@@5{)FinhiXvF=w-F5%EXPtHSUVDGnI^Xp^tN`; z74x`bm|}WSB&I3;)2@J8`s*u|gv6BNBkqUop8Qam6wJ8>=I<%8=+a<_N8YupfaMAw zSJv$icD!gVHbrZ_ctoq3wL=fc5aZ#qp<6+x8av>))E~`_VSyFz>man|FuJ=?Ewc{S z{k9G&zNS-pBjg_B5K^N{x15AQJ;3^z{I;sKx-rleRDGuNUDDHN3fUp-WuaC@29 z?^Ria#tmcOa8OaWRh>>}PB0vC(&NWTq#dVg_M$8OG}25C;w*3fvf3QS0_Px)#nrSI zW)<48E{9{BG4QgN1oa@s^61R(8q<3E0PZuxai`ba*QDCPD=e^~L)Ek(mvT9Td*70V zPIruh00qj(Bd^YZxKRTuM15UKgAd<$#8rgVn+I+oyb(F}{HCp6f zQnmB@O$~U(4h)?6*x_TmCTxPF{C`2DNq&K_um1(&d}0z2(ia%9E!IX6to|Z}u%Voq zy*B6L36 z++E2DROgj%eG4A|(shCoR}ic5Czv)_qtNLM1<93n#EIMDDVwCFr()xL?Q|M{2S_{+ zOWXn$G&3+(8F0|_o&|F}@D%37qBUg`mieg-fQv8{!&0v8a%erVZP?xu_l3wE)@o$zeJmyDjAaov&~K-EoyHV%|& zQbeEn>O_7ob2jh1U>p4AgLEO$=Rhg@i0=25R$A2u$&Am6<^Z6?Aop8nTIlKR&Yyg} zpF5Hgeb$we-2vntY!o5cEga+h3(Huk+Y0oA!wD+~p*$+6KjpE)V>R>}|D^|cXHKJk zAzd1lwtWY>SffT-TXm;Zc&dn+UFOzo_u6u|5aOQ(x3Z!&6wMQd8u^ipEwkB#oN9?v zqTK$|7Tt;GhI)ES@J1V8M6eO`VW@cyD=y!{5%ZK*qmJkNYz8B4246JO9klNm>kiOV zG`BfG*5xh#y&rSN6Zct%V~lwA?NWFoc*S(nOpSTe9GrQmC3qxe-Bz=70`MZs)~PBi zZ43i`=LP^5DdFvyVnuU{$%so{<^#L?%3IdDx8kcTavMx!EsGEAj-zf@t<0)-*xYMR z^U50(H(KN-82c8x9o-|(*o_UKY>PNG9`QK&`G=r7b&-Ql`^Q{c}xH(bzV-*AB^y922IX$#+J(es2-X6*{NNL2ozlw^=R8 zc1(2AG2p4`oP+AFb3n`W!#lI_QphWR{{RBv+@W4!-c;&z18f literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/html/images/qtpropertybrowser.png b/external/QtPropertyBrowser/doc/html/images/qtpropertybrowser.png new file mode 100644 index 0000000000000000000000000000000000000000..1f0403af24777f12af953f7da6383420625f0c46 GIT binary patch literal 9677 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 I%yZxW0Z@#nLjV8( literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/html/images/simple.png b/external/QtPropertyBrowser/doc/html/images/simple.png new file mode 100644 index 0000000000000000000000000000000000000000..56048d5dfd2f447805f1fbf7cb8e3e7a764e90e3 GIT binary patch literal 9548 zcmaia2Rv2(|G#ykW9JyzBOEJ|LPpoMbK@FCHp$3N_8!+rMaYP_H!>S~=hkO@zrX+g@&7$MIOp-c@Ao;c@q9gBQ9H#~@ls6634mxxVF3Zvmg^1GT>RmlfQXiiFr-He|7NJMmINmE71 zz-MITsee4?n*k=p65l`RmZ0mdtN%3#Pnj>P}mrS(_So5InvYwZbyfVT_z2 zJsW-8RkdDecX>GWTv3%y)n;h8Dcy1XmfLZ=+(qmABCCUJLBSM2_Udr-xr()(^yB#m zN5kjkMx6z$BtuI0*{%mHGi5Z-+*>;`%V?~7AF)AZ0Ur8gfF49^~HZ{<~*Nqo(npYb?%wob>mY%zn}e_3?UGbi%N z60XP3+i;Ap$l}6Mla}EtqxE;Bv}mUq`;X4YCJpae`^3%V=Qn%>gO&_?2MDK+x?Xq$ z_usTDDdM}peuo8^sUPCs(o9is``p4TZd_)6bhy`?`-#nar*-62vaI(fi`P?C9b*VuPp-?W35;KhQ@biRSiy%+f=ctV2D`pL8oKP;s9Xoz`ikRj$M+jqvWKbN?Ca&1 zxPtCO(yy#`TfBqzDb=avf*lG~(6Og<&lVCCLmviJHsy^Sj`bwFXRF6Cnaa3)OmcVj z5PW*Ux&PVZi=iej&e8S5*N8Z-;00ja5It|=OATaQ_I*1{R`~R@n6$j-=LYABQX@m- zW<&MvO9%eqs(@+?{6;08T}0*a_reK1xhZPG*SA zy0bj&pr5Dxs}<2%{?f9Xw%>8LsZFPPcF)Zhb1JAHmGOq5v4>BnI2B5%PS9xS++^Tl zLYB+#H-=LjdDQRd<*a2WK`euAJ>=DHOL+}G{g)ruGX%GkL7F2`Fl^jfY2OZT`c6FH zQ!i&9m-OsN5;||!#UAuoaz$9?L;0GVZR@9|$<$I5I<|qY*jHZCFo|6v(I{{%K{<7I z!@=<00G~(mV@fEx$yn1zha~1I`AbV|+r)1F^UI@7FuKYj`Px2S+R04e#XeI>VjIMi za)-6kzqi;@>^CLHo)50loF2qB(0S9e>10YfHQm=t6u6opyo1!+u?B0Kh-3>MOZuBcR7QIr2F{lq6OpDGmK`>heJ zgpN(f36$CNYQm%jOy-`^sa=T^D`e1Sk(=GDv0&R7pNwNUUw;e3XQGo;wS24Pp3H|{ ztzVicg-+Gm>uY1pu$Tp$fJItQ=BDHux3!J3Q5s#O=-8=eYBqaSVF($c+i?vG3!TT= z-CfpZ4%El;wu8(577xLDr*vJ6!reMm$qzs^GoSQSrhok-F?)1XFU#}Ch<={Mn54_s z-SkYVE85j_DK~W-7(ayVM%+34xGl8f$zK?oDDU^^Fn8)(wTPgo0@xZwn|}7nn_6&G z()6fQy)wWPRRhUxFVmdknY(wgB#T|NT&HetK_qB`d3#9Eg7MdsWzRGDH#sm?VdN}m z1qC0`TF{szMc-*=ZT(oS6)@OyXMLso)HyNOa%BX@k=Q!oEamC$J0GQ@NA&f_p!(7kwrg4RXz->HWbv!TN{n`V8)F97A}s- zgqit&N&ERyh$DUCtYNuSTm_Tf3@7V812YmH|hsAhbVD zaP@q{&!1RI=7);Mxehz7K#ERXv12Qv^jVAg!-sOKRY#FOGJ~3L_71owsM0ps0=-KJZeLI03k zS>g8>pN`&R^D6uGh0@~8{qXYj>co_W-jd~mIK}<%%Cri1#~aS31+-DF-*QWsk){a_ z-n5@C&g%Q@H;#vX^}eo{Hhfj)f4V?E)xY%(GjAshw(_v2)0PE+`w4a`yTdnLEol%4 zkLSo_sjuj*YZD^2tLm4I=H=GRTAKm>*dJ*Zj<-**aLkMb+pl}9cKD5boxERVJ-a@C zH@cxw#ZotDjzc`U!Fpe-c{D7+K)jh-=C)o91O{VUuB&`%%x&%@5Zl~|SVRr@>Y53W zNWffScff(+uYXcd>Yk;z%M-!Ly|241I`?Zg8lSXi>9VA;fw_J+!kaE1c7D$m{M2_n zv+VLCgj+)Q+pV;{hQ-QKqoF^!PxkU+3%?sRa4hr8+29~tN+VlgX2MW#a(g*Uy&|XF zNb4^Jtp?-#-A~F-M+$0Zc*b&v?TX|�$toe<)*el)a`rbqO*$=46wbE%2_BS&tM{ ztGo;y-E&|i%e%t?+8*1SZ>{=z0$`aTgAU!tA9~ZF9uJW=1f77mBSJ_}6#t(~yAE{M z%gc*9LjDoOa4Sm52}w1(uOAUFc#7Du3&93atVMr{7xf7opIX}s`XVhK*4VT(Sjf;v z9Tm1)b8FPZgnXhk=mvZF)ZOW|J^x)2-sO=}oh8fZIVGiK>*GO=Ve#X=7DE!qZMRl2 zKtP2q$a71HU5XJ1G?{oGBuj-bZk}uwBsqHeH2CvdBFJfV^5HKy^Oi+6MCl-{+D2>2 z&yoSImJOz~2-f#Q&4ReK*7P5@&4@t1gA=bUXp}<-*LK!ULQWh$BFj9=kt$arC__-) zbI!x!QFx@|uKz9>xL@H^?Asm%Fayj)*sFD;85{BOPpWl?MwF%{K>3jsA3l*MX*eN)mV+Z^a|Y_j>s_e8V*-G)zSk`m1UZ&5R|u0!x~*$ z*o`JE(kfP;)9K;&yMZ@9Xe9v6v%UP!A8YNj(GMwG#j0!HHd-LQQgct7M%hZ)uy_!G z#5?LY=rcvhDsr4PsO>Lu)U~onrle7BED!AC9LrITzZ>!~u7I$8W#6TcGNh?>RWXmf z-X)5XuT#U~iebz*l0n9|GZG;Cn8M2XW6oDOq&7k5KzA14<&aZ9!HC~SmXlh}4KfMT zQKe{6Qj5HLtT7}uW(CPq`3tle`sL)Pe>zOv|0)5hyi2e8f-!0+84`+}DHKEdoj#kw z#Cn}2NyG4NqZL$D9kn>a=3ug=d;W56eU;ZPRSbp#^vl?oS|4PNELHc!m&rR2uVhwD z`9YgLb}hPzoH&EFkwEe&@d5G4^j{($JlXuN+;k6;F}k)&ql`yK74y>2WKlGelGCIf zI}3w@MUw`su^L{lUyN}?qS9zARN2|DpA2*`zKqNwOr?CY+9dZoR_b>&WPGh?vSsQS8OHaY2e%(h-WkUB* zf!F(+eeS!^^(T>1VMDz7NF?ziA#PkqJ4lB?+5i*~?$j+nnGS{c@EL7I%DJh82{lE6pAR;emi_X1e_gUXDPb|yeKBG?r$eQ{ngoWL`?sK{dnTzp+-WSLB zR!{GKP9{RArJ0B2daKX3m2zc8>(%up`W+nIN<_`#j+7(y)h0E=G)LH|Q4`U;`kDi4l?r zTu2B>8vH{7uc+DrR54hLuCo0}!2flpy!jlM9%C!v8 zVp0@66#PYR6;$k%IQLqQq!diN^73qckuV~Ab0*zz^f24B1+CP-U5|b?c4%~^TWsM` zsSG_ezUOes?I8x!@U-lKllT2swCeQ_T=kr%F_3RA_w7;f#FLv zY8B>nN|^k|>HRvnQ)J-w>Ua&#{8^4WrpG*V1&6EC(WXSKoJ}(@x(?-xb2Url(6908 zzYcBkm%MOEU*oZUP6xOV7UpSzT)^XuL@2?JFZuQDWk9b^gZ`E99~cdPg^%6d-r&%GN^oUXLy&UIR{K}KX!O5sTjP}wW)$p|PTvgh z(}JA%Ga}`9<+m3f)401RvG0N%F{?N-1_-0S*Q!=ZGPh@gs?yaj42Yq zNRdP=vE#pTJV1uRVAJT@5)M9d`sn%9+IWgH`cs`+jGsU{_yI(OS3}&tkJJ4=O##IV zfsceF&M=`=V_-~?R`RNOs3D2h$H>VDNB$9Z%GMxNUad|KBjLL!%Bv4~qI!SsehA6eYFapdN+SLdvhmlucx^2{L5Cs>E87id zpEy%Z2M#uLQ%w@4r(TH=z+w;?!@6a(it6s0(+y<;W=^4S*sQSuBL@_T=*C}kgeXHQ zF%ltpX2cj_6&b+<7hYisMDZj&9E7MNOnm(-3NXiv=eKPTsKkF^yX>nMKQ zYmXg^ayT1bB7{EdFA4}Y+@ISA)Ks1sMjt(8*U+4*!6A8{NfEgCAJ`#2NW%`B5=!ZU znjSavFFyh7A$fwZNnO-!aTR2+v;T{zLc-e8!k&P$kzu^DyfmSx=lJ;T{Tnn;{*Sz9 zW!V10WC({za`?qarM}1ZiqdaV#WC?-#T$=uIx#+W^A=?%fTFuYCG!-JK`f%);&SN! z5E5Po0M~|t%)zTz5@l;1gCuq=Nw}S)n~3lg0;j?Lf=%=H%?;dZ^`(0#o}hbzPd7EY zOV&7!9O4CAjc^ahKpp!kZHrWu|UxN6S?>ln}h zvXUXT9uJZLi#-=!^~l3;gwZM`tlv%vFx8QkCvieaw1C{iMBxS463RIzV^!7p;JcvU zecWngX_YVBvspk!-crJ=lsS$L_?{kHp>KURaF_)&KA_{A&&N>gKh7fquOP5y#-y<3 z!em(K$&u$52nK*aazx~NRQ~Yva7OrF2J)J^PH;5|>~wBM(CaoeY^!`au;RyX!Jjj` zwAik$E}Arz>K381fjNFQ)9sR{`BZ9D$+L|QAitXZ=PU7d?@C?_YN@_{2Z|nr@wSDni1j_sY zEqDUIRy0_TvidPmN4dy>2)iAfFl!Ty0TFC+as3w=RWgPBPmKGJ_rwqZpp3riV z&_EvT;@GG>k)9`c?n+nLcYA{|MVkeGEd=7Hg7lt-9?f0M3x+JqT6Qby20|hLekO6K~^}%Fg%cx|BQ2CDC|Ahx!f?y2#zG6>Wl<$oJJ)j zBNx}3%uRb=P8M451r2t2s9WQ%?^B_7B((UoU(|`hBX{?3yBK+BNvVq)^%fgRG^B zrqigsudFn}pq<1-f$dU4tcyQA0i^MM;jL(H`ydA`k5-DKL)*(zU$%pmp_G{Kqjw~B z!((zBaPe$l&Sy?piF!LAn8P3yae(kR`>4k5 zu~e0#NGngQ7hiWn_nDA>63&T{)^8aWILbhw}hMq zSRtE^!vTCI$TJ&)($i?0tlzF{hQY9bZlnY1cZ55~Fh{vA!>OKY`$o+DfKY@#2GURPWKt1*dw~78iP`iUJ!bc`G#RQeb@7 zHFl@Owd;n@QZ?>*ctBFT`j|130{UEP+h)0J0VjG$h8kPvzjHP}1^SRGWG~LVSSqoQ zP*krn4^yBb_JoqssAJ-bI03EPo(QphO6-I2z(0I@yJsc*BKSPdvXzFC0n!kU8T3}Z z8i`sBJo{;k7vn|`)ZDtQorQYg=)-`+9re7YyFK#rf>stPnUn5ktJ54)A+r||kY2vc z_*X^k+m`-JQ^6`g4H&^F?UB>h z`)7;xc#>w7PfJhg^5a5GLr@;|QThT<72FF^o2A1=O#8wT8zB?oB2jq5|LNTSq+miZ zVL*=EVk4A3f6+C{6W^2lCub62Gf4QHGrlnz3T$bleAxKzy;3@VzFrPT3cjGg+M1Uo z;^LV<-wFN!b9E9m&>Q=D)0nlP^~n&<>=hD<*ujje`0|UllK@K>H|+`G5-F9FNTSA} zagXjAc`9#Ef9E$!geu>ASE$UD4CZFNTL2RVV=>%^QtB*F+Z4)=$zBO30$^5597N)Y zAdQ=?tiaqCmE?DwG}wUi%w%B42}JA@k0?}tRU#Whq9S5zg%sx4$E)`D#j`51&j~H& zn8iIrHog^SB1U`@p?j2vF{%lIA4W`!y`qFS`D2^^s1#xE5gNt+k*OR9Jsp1+6d?Ha zKl9pO2Yc4?CE^nA$2n>HG1csmYF*{Ln6)jY;>FE(Aw=5)x3)iW7EUa=@9euyXOSU( z?w3ZHW^<|1f+1l$m}s@?oe z{eVsf=nteLcn1Iq?i?6kB&v^0oQBANUhfn>P|_IKT&x4AvGSLZrdJNS}KPVA>4Q~vQ{y|`Tg%Y?axj7381*h+|?3i$;RR^ zbEddTvOv(`^n%CI%Eb=8Z@(g%E-{c|1(fh<%+3pvH?}QG&YBV`Y)+PS5xbn%+e0?f zIjAk`0$luzzu>nJ7`@!o3ppXW7HN#`{DnLP#)(($baq2gCvlbC9WPM_-YGF%}sJXqudhY9b=cB#5y0Vy6V*!kEw?68&yq2$L0V zeQtQt5{hn2Lx=K|&n`EyAKC_7!Z0 z(RAg;Ge0yQU$u`0#w;hSZQzguxq1_89p*JwV)^%$Lx8M28LaLY*qJbn6f z*8_(t#+Czq{dNZ6S;fw+Q?pF-&$cz}G8$CDtuK zEHEI>w%+RDO3n}fQeYG8;FG^3(~wH;K{;Vz`?oP71{Ntf7>QSB3T#&xWz2nzgH-P} zofKpbK3uo9hG))E99~9_j*j&_x7R21Z-oh@=l>coUrVQzlf=^EUh4?RK^o1Ydf09c&qQP! zr@vEcx<_mT04M# z<|%F!xCZ@9U&ppY(Ptfu&G%dQZvScnsrOY9(Zs$~SVME)*~OQ|=H<7q1z5Q=@Yohy z4u=jq<*&LNH%*E+1R_@@DIUQQjSIQQOc?L9NBtGa@K}YVit*f&^YF-LUhzLCsc;xKX)x-v(nck;PiBJ)Swq9N^eISgR zq68@mZs_BwP18+DgB(LXe2?YhNFHjXSLo*gs1zU=~kIH-sn!^f+TtF~q)DM}UU zz&U^fD?Jea7fSKvd^mRu#$fo6(la?o{~HZhK~u|EA>;Pwlof7@9n`z_odo0#Q-_owOQTY!;SK#n%^ZD+*=U7^Z2VTjt-G_|A~7SZ$!b!Pahts0)L0V zBA*y)qN^);IDU6!2<~*?mgptlb3(&B8x=OKlNZjz_`7??N3Vl25=df3O2mAtKBQ!s zpOxuyN+VM(Wjg!&bo30y%|#w7X(o2HYxjedTOB4G@8H?ui(A2Rur!jmskfUr-?u ztMfnq5ot@P=X1VuTKh`4RW?2n)mTl?8o^kQBs-2zZM2zg^&-CM*kYs8>LYt`H_`Sy+R(8)Y?!v9SXX{u_g6rn7`{tva(*HZuh literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/html/index.html b/external/QtPropertyBrowser/doc/html/index.html new file mode 100644 index 000000000..edb60410c --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/index.html @@ -0,0 +1,98 @@ + + + + + + Property Browser + + + + + + + +
  Home

Property Browser
+

+
+

Description

+

A property browser framework enabling the user to edit a set of properties.

+

The framework provides a browser widget that displays the given properties with labels and corresponding editing widgets (e.g. line edits or comboboxes). The various types of editing widgets are provided by the framework's editor factories: For each property type, the framework provides a property manager (e.g. QtIntPropertyManager and QtStringPropertyManager) which can be associated with the preferred editor factory (e.g. QtSpinBoxFactory and QtLineEditFactory). The framework also provides a variant based property type with corresponding variant manager and factory. Finally, the framework provides three ready-made implementations of the browser widget: QtTreePropertyBrowser, QtButtonPropertyBrowser and QtGroupBoxPropertyBrowser.

+ +

Classes

+ + +

Examples

+ + +

Tested platforms

+
    +
  • Qt 4.4, 4.5 / Windows XP / MSVC.NET 2008
  • +
  • Qt 4.4, 4.5 / Linux / gcc
  • +
  • Qt 4.4, 4.5 / MacOS X 10.5 / gcc
  • +
+ +

Screenshots

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtabstracteditorfactory-members.html b/external/QtPropertyBrowser/doc/html/qtabstracteditorfactory-members.html new file mode 100644 index 000000000..204d8b111 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtabstracteditorfactory-members.html @@ -0,0 +1,83 @@ + + + + + + List of All Members for QtAbstractEditorFactory + + + + + + + +
  Home

List of All Members for QtAbstractEditorFactory

+

This is the complete list of members for QtAbstractEditorFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtabstracteditorfactory.html b/external/QtPropertyBrowser/doc/html/qtabstracteditorfactory.html new file mode 100644 index 000000000..76700d04f --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtabstracteditorfactory.html @@ -0,0 +1,129 @@ + + + + + + QtAbstractEditorFactory Class Reference + + + + + + + +
  Home

QtAbstractEditorFactory Class Reference

+

The QtAbstractEditorFactory is the base template class for editor factories. More...

+
 #include <QtAbstractEditorFactory>

Inherits QtAbstractEditorFactoryBase.

+

Inherited by QtCharEditorFactory, QtCheckBoxFactory, QtColorEditorFactory, QtCursorEditorFactory, QtDateEditFactory, QtDateTimeEditFactory, QtDoubleSpinBoxFactory, QtEnumEditorFactory, QtFontEditorFactory, QtKeySequenceEditorFactory, QtLineEditFactory, QtScrollBarFactory, QtSliderFactory, QtSpinBoxFactory, QtTimeEditFactory, and QtVariantEditorFactory.

+ +
+ +

Public Functions

+ + + + + + +
QtAbstractEditorFactory ( QObject * parent )
void addPropertyManager ( PropertyManager * manager )
PropertyManager * propertyManager ( QtProperty * property ) const
QSet<PropertyManager *> propertyManagers () const
void removePropertyManager ( PropertyManager * manager )
+
+ +

Reimplemented Public Functions

+ + +
virtual QWidget * createEditor ( QtProperty * property, QWidget * parent )
+ +
+ +

Protected Functions

+ + + + +
virtual void connectPropertyManager ( PropertyManager * manager ) = 0
virtual QWidget * createEditor ( PropertyManager * manager, QtProperty * property, QWidget * parent ) = 0
virtual void disconnectPropertyManager ( PropertyManager * manager ) = 0
+
    +
  • 7 protected functions inherited from QObject
  • +
+

Additional Inherited Members

+
    +
  • 1 property inherited from QObject
  • +
  • 1 public slot inherited from QObject
  • +
  • 1 signal inherited from QObject
  • +
  • 1 public type inherited from QObject
  • +
  • 4 static public members inherited from QObject
  • +
  • 2 protected variables inherited from QObject
  • +
+ +
+

Detailed Description

+

The QtAbstractEditorFactory is the base template class for editor factories.

+

An editor factory is a class that is able to create an editing widget of a specified type (e.g. line edits or comboboxes) for a given QtProperty object, and it is used in conjunction with the QtAbstractPropertyManager and QtAbstractPropertyBrowser classes.

+

Note that the QtAbstractEditorFactory functions are using the PropertyManager template argument class which can be any QtAbstractPropertyManager subclass. For example:

+
 QtSpinBoxFactory *factory;
+ QSet<QtIntPropertyManager *> managers = factory->propertyManagers();
+

Note that QtSpinBoxFactory by definition creates editing widgets only for properties created by QtIntPropertyManager.

+

When using a property browser widget, the properties are created and managed by implementations of the QtAbstractPropertyManager class. To ensure that the properties' values will be displayed using suitable editing widgets, the managers are associated with objects of QtAbstractEditorFactory subclasses. The property browser will use these associations to determine which factories it should use to create the preferred editing widgets.

+

A QtAbstractEditorFactory object is capable of producing editors for several property managers at the same time. To create an association between this factory and a given manager, use the addPropertyManager() function. Use the removePropertyManager() function to make this factory stop producing editors for a given property manager. Use the propertyManagers() function to retrieve the set of managers currently associated with this factory.

+

Several ready-made implementations of the QtAbstractEditorFactory class are available:

+ +

When deriving from the QtAbstractEditorFactory class, several pure virtual functions must be implemented: the connectPropertyManager() function is used by the factory to connect to the given manager's signals, the createEditor() function is supposed to create an editor for the given property controlled by the given manager, and finally the disconnectPropertyManager() function is used by the factory to disconnect from the specified manager's signals.

+

See also QtAbstractEditorFactoryBase and QtAbstractPropertyManager.

+
+

Member Function Documentation

+

QtAbstractEditorFactory::QtAbstractEditorFactory ( QObject * parent )

+

Creates an editor factory with the given parent.

+

See also addPropertyManager().

+

void QtAbstractEditorFactory::addPropertyManager ( PropertyManager * manager )

+

Adds the given manager to this factory's set of managers, making this factory produce editing widgets for properties created by the given manager.

+

The PropertyManager type is a template argument class, and represents the chosen QtAbstractPropertyManager subclass.

+

See also propertyManagers() and removePropertyManager().

+

void QtAbstractEditorFactory::connectPropertyManager ( PropertyManager * manager )   [pure virtual protected]

+

Connects this factory to the given manager's signals. The PropertyManager type is a template argument class, and represents the chosen QtAbstractPropertyManager subclass.

+

This function is used internally by the addPropertyManager() function, and makes it possible to update an editing widget when the associated property's data changes. This is typically done in custom slots responding to the signals emitted by the property's manager, e.g. QtIntPropertyManager::valueChanged() and QtIntPropertyManager::rangeChanged().

+

See also propertyManagers() and disconnectPropertyManager().

+

QWidget * QtAbstractEditorFactory::createEditor ( QtProperty * property, QWidget * parent )   [virtual]

+

Reimplemented from QtAbstractEditorFactoryBase::createEditor().

+

Creates an editing widget (with the given parent) for the given property.

+

QWidget * QtAbstractEditorFactory::createEditor ( PropertyManager * manager, QtProperty * property, QWidget * parent )   [pure virtual protected]

+

Creates an editing widget with the given parent for the specified property created by the given manager. The PropertyManager type is a template argument class, and represents the chosen QtAbstractPropertyManager subclass.

+

This function must be implemented in derived classes: It is recommended to store a pointer to the widget and map it to the given property, since the widget must be updated whenever the associated property's data changes. This is typically done in custom slots responding to the signals emitted by the property's manager, e.g. QtIntPropertyManager::valueChanged() and QtIntPropertyManager::rangeChanged().

+

See also connectPropertyManager().

+

void QtAbstractEditorFactory::disconnectPropertyManager ( PropertyManager * manager )   [pure virtual protected]

+

Disconnects this factory from the given manager's signals. The PropertyManager type is a template argument class, and represents the chosen QtAbstractPropertyManager subclass.

+

This function is used internally by the removePropertyManager() function.

+

See also propertyManagers() and connectPropertyManager().

+

PropertyManager * QtAbstractEditorFactory::propertyManager ( QtProperty * property ) const

+

Returns the property manager for the given property, or 0 if the given property doesn't belong to any of this factory's registered managers.

+

The PropertyManager type is a template argument class, and represents the chosen QtAbstractPropertyManager subclass.

+

See also propertyManagers().

+

QSet<PropertyManager *> QtAbstractEditorFactory::propertyManagers () const

+

Returns the factory's set of associated managers. The PropertyManager type is a template argument class, and represents the chosen QtAbstractPropertyManager subclass.

+

See also addPropertyManager() and removePropertyManager().

+

void QtAbstractEditorFactory::removePropertyManager ( PropertyManager * manager )

+

Removes the given manager from this factory's set of managers. The PropertyManager type is a template argument class, and may be any QtAbstractPropertyManager subclass.

+

See also propertyManagers() and addPropertyManager().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtabstracteditorfactorybase-members.html b/external/QtPropertyBrowser/doc/html/qtabstracteditorfactorybase-members.html new file mode 100644 index 000000000..973a10e28 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtabstracteditorfactorybase-members.html @@ -0,0 +1,76 @@ + + + + + + List of All Members for QtAbstractEditorFactoryBase + + + + + + + +
  Home

List of All Members for QtAbstractEditorFactoryBase

+

This is the complete list of members for QtAbstractEditorFactoryBase, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtabstracteditorfactorybase.html b/external/QtPropertyBrowser/doc/html/qtabstracteditorfactorybase.html new file mode 100644 index 000000000..d44db83dd --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtabstracteditorfactorybase.html @@ -0,0 +1,84 @@ + + + + + + QtAbstractEditorFactoryBase Class Reference + + + + + + + +
  Home

QtAbstractEditorFactoryBase Class Reference

+

The QtAbstractEditorFactoryBase provides an interface for editor factories. More...

+
 #include <QtAbstractEditorFactoryBase>

Inherits QObject.

+

Inherited by QtAbstractEditorFactory.

+ +
+ +

Public Functions

+ + +
virtual QWidget * createEditor ( QtProperty * property, QWidget * parent ) = 0
+
    +
  • 29 public functions inherited from QObject
  • +
+
+ +

Protected Functions

+ + +
QtAbstractEditorFactoryBase ( QObject * parent = 0 )
+
    +
  • 7 protected functions inherited from QObject
  • +
+

Additional Inherited Members

+
    +
  • 1 property inherited from QObject
  • +
  • 1 public slot inherited from QObject
  • +
  • 1 signal inherited from QObject
  • +
  • 1 public type inherited from QObject
  • +
  • 4 static public members inherited from QObject
  • +
  • 2 protected variables inherited from QObject
  • +
+ +
+

Detailed Description

+

The QtAbstractEditorFactoryBase provides an interface for editor factories.

+

An editor factory is a class that is able to create an editing widget of a specified type (e.g. line edits or comboboxes) for a given QtProperty object, and it is used in conjunction with the QtAbstractPropertyManager and QtAbstractPropertyBrowser classes.

+

When using a property browser widget, the properties are created and managed by implementations of the QtAbstractPropertyManager class. To ensure that the properties' values will be displayed using suitable editing widgets, the managers are associated with objects of QtAbstractEditorFactory subclasses. The property browser will use these associations to determine which factories it should use to create the preferred editing widgets.

+

Typically, an editor factory is created by subclassing the QtAbstractEditorFactory template class which inherits QtAbstractEditorFactoryBase. But note that several ready-made implementations are available:

+ +

See also QtAbstractPropertyManager and QtAbstractPropertyBrowser.

+
+

Member Function Documentation

+

QtAbstractEditorFactoryBase::QtAbstractEditorFactoryBase ( QObject * parent = 0 )   [protected]

+

Creates an abstract editor factory with the given parent.

+

QWidget * QtAbstractEditorFactoryBase::createEditor ( QtProperty * property, QWidget * parent )   [pure virtual]

+

Creates an editing widget (with the given parent) for the given property.

+

This function is reimplemented in QtAbstractEditorFactory template class which also provides a pure virtual convenience overload of this function enabling access to the property's manager.

+

See also QtAbstractEditorFactory::createEditor().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtabstractpropertybrowser-members.html b/external/QtPropertyBrowser/doc/html/qtabstractpropertybrowser-members.html new file mode 100644 index 000000000..d3fcbe747 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtabstractpropertybrowser-members.html @@ -0,0 +1,384 @@ + + + + + + List of All Members for QtAbstractPropertyBrowser + + + + + + + +
  Home

List of All Members for QtAbstractPropertyBrowser

+

This is the complete list of members for QtAbstractPropertyBrowser, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtabstractpropertybrowser.html b/external/QtPropertyBrowser/doc/html/qtabstractpropertybrowser.html new file mode 100644 index 000000000..961f57963 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtabstractpropertybrowser.html @@ -0,0 +1,221 @@ + + + + + + QtAbstractPropertyBrowser Class Reference + + + + + + + +
  Home

QtAbstractPropertyBrowser Class Reference

+

QtAbstractPropertyBrowser provides a base class for implementing property browsers. More...

+
 #include <QtAbstractPropertyBrowser>

Inherits QWidget.

+

Inherited by QtButtonPropertyBrowser, QtGroupBoxPropertyBrowser, and QtTreePropertyBrowser.

+ +
+ +

Public Functions

+ + + + + + + + + + + + +
QtAbstractPropertyBrowser ( QWidget * parent = 0 )
~QtAbstractPropertyBrowser ()
void clear ()
QtBrowserItem * currentItem () const
QList<QtBrowserItem *> items ( QtProperty * property ) const
QList<QtProperty *> properties () const
void setCurrentItem ( QtBrowserItem * item )
void setFactoryForManager ( PropertyManager * manager, QtAbstractEditorFactory<PropertyManager> * factory )
QtBrowserItem * topLevelItem ( QtProperty * property ) const
QList<QtBrowserItem *> topLevelItems () const
void unsetFactoryForManager ( QtAbstractPropertyManager * manager )
+
    +
  • 217 public functions inherited from QWidget
  • +
  • 13 public functions inherited from QPaintDevice
  • +
  • 29 public functions inherited from QObject
  • +
+
+ +

Public Slots

+ + + + +
QtBrowserItem * addProperty ( QtProperty * property )
QtBrowserItem * insertProperty ( QtProperty * property, QtProperty * afterProperty )
void removeProperty ( QtProperty * property )
+
    +
  • 19 public slots inherited from QWidget
  • +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + +
void currentItemChanged ( QtBrowserItem * current )
+ +
+ +

Protected Functions

+ + + + + +
virtual QWidget * createEditor ( QtProperty * property, QWidget * parent )
virtual void itemChanged ( QtBrowserItem * item ) = 0
virtual void itemInserted ( QtBrowserItem * insertedItem, QtBrowserItem * precedingItem ) = 0
virtual void itemRemoved ( QtBrowserItem * item ) = 0
+
    +
  • 37 protected functions inherited from QWidget
  • +
  • 1 protected function inherited from QPaintDevice
  • +
  • 7 protected functions inherited from QObject
  • +
+

Additional Inherited Members

+
    +
  • 58 properties inherited from QWidget
  • +
  • 1 property inherited from QObject
  • +
  • 1 public type inherited from QObject
  • +
  • 4 static public members inherited from QWidget
  • +
  • 4 static public members inherited from QObject
  • +
  • 1 protected slot inherited from QWidget
  • +
  • 1 protected type inherited from QPaintDevice
  • +
  • 2 protected variables inherited from QObject
  • +
+ +
+

Detailed Description

+

QtAbstractPropertyBrowser provides a base class for implementing property browsers.

+

A property browser is a widget that enables the user to edit a given set of properties. Each property is represented by a label specifying the property's name, and an editing widget (e.g. a line edit or a combobox) holding its value. A property can have zero or more subproperties.

+

The top level properties can be retrieved using the properties() function. To traverse each property's subproperties, use the QtProperty::subProperties() function. In addition, the set of top level properties can be manipulated using the addProperty(), insertProperty() and removeProperty() functions. Note that the QtProperty class provides a corresponding set of functions making it possible to manipulate the set of subproperties as well.

+

To remove all the properties from the property browser widget, use the clear() function. This function will clear the editor, but it will not delete the properties since they can still be used in other editors.

+

The properties themselves are created and managed by implementations of the QtAbstractPropertyManager class. A manager can handle (i.e. create and manage) properties of a given type. In the property browser the managers are associated with implementations of the QtAbstractEditorFactory: A factory is a class able to create an editing widget of a specified type.

+

When using a property browser widget, managers must be created for each of the required property types before the properties themselves can be created. To ensure that the properties' values will be displayed using suitable editing widgets, the managers must be associated with objects of the preferred factory implementations using the setFactoryForManager() function. The property browser will use these associations to determine which factory it should use to create the preferred editing widget.

+

Note that a factory can be associated with many managers, but a manager can only be associated with one single factory within the context of a single property browser. The associations between managers and factories can at any time be removed using the unsetFactoryForManager() function.

+

Whenever the property data changes or a property is inserted or removed, the itemChanged(), itemInserted() or itemRemoved() functions are called, respectively. These functions must be reimplemented in derived classes in order to update the property browser widget. Be aware that some property instances can appear several times in an abstract tree structure. For example:

+

+ +
 QtProperty *property1, *property2, *property3;
+
+ property2->addSubProperty(property1);
+ property3->addSubProperty(property2);
+
+ QtAbstractPropertyBrowser *editor;
+
+ editor->addProperty(property1);
+ editor->addProperty(property2);
+ editor->addProperty(property3);
+

+

The addProperty() function returns a QtBrowserItem that uniquely identifies the created item.

+

To make a property editable in the property browser, the createEditor() function must be called to provide the property with a suitable editing widget.

+

Note that there are two ready-made property browser implementations:

+ +

See also QtAbstractPropertyManager and QtAbstractEditorFactoryBase.

+
+

Member Function Documentation

+

QtAbstractPropertyBrowser::QtAbstractPropertyBrowser ( QWidget * parent = 0 )

+

Creates an abstract property browser with the given parent.

+

QtAbstractPropertyBrowser::~QtAbstractPropertyBrowser ()

+

Destroys the property browser, and destroys all the items that were created by this property browser.

+

Note that the properties that were displayed in the editor are not deleted since they still can be used in other editors. Neither does the destructor delete the property managers and editor factories that were used by this property browser widget unless this widget was their parent.

+

See also QtAbstractPropertyManager::~QtAbstractPropertyManager().

+

QtBrowserItem * QtAbstractPropertyBrowser::addProperty ( QtProperty * property )   [slot]

+

Appends the given property (and its subproperties) to the property browser's list of top level properties. Returns the item created by property browser which is associated with the property. In order to get all children items created by the property browser in this call, the returned item should be traversed.

+

If the specified property is already added, this function does nothing and returns 0.

+

See also insertProperty(), QtProperty::addSubProperty(), and properties().

+

void QtAbstractPropertyBrowser::clear ()

+

Removes all the properties from the editor, but does not delete them since they can still be used in other editors.

+

See also removeProperty() and QtAbstractPropertyManager::clear().

+

QWidget * QtAbstractPropertyBrowser::createEditor ( QtProperty * property, QWidget * parent )   [virtual protected]

+

Creates an editing widget (with the given parent) for the given property according to the previously established associations between property managers and editor factories.

+

If the property is created by a property manager which was not associated with any of the existing factories in this property editor, the function returns 0.

+

To make a property editable in the property browser, the createEditor() function must be called to provide the property with a suitable editing widget.

+

Reimplement this function to provide additional decoration for the editing widgets created by the installed factories.

+

See also setFactoryForManager().

+

QtBrowserItem * QtAbstractPropertyBrowser::currentItem () const

+

Returns the current item in the property browser.

+

See also setCurrentItem().

+

void QtAbstractPropertyBrowser::currentItemChanged ( QtBrowserItem * current )   [signal]

+

This signal is emitted when the current item changes. The current item is specified by current.

+

See also QtAbstractPropertyBrowser::setCurrentItem().

+

QtBrowserItem * QtAbstractPropertyBrowser::insertProperty ( QtProperty * property, QtProperty * afterProperty )   [slot]

+

Inserts the given property (and its subproperties) after the specified afterProperty in the browser's list of top level properties. Returns item created by property browser which is associated with the property. In order to get all children items created by the property browser in this call returned item should be traversed.

+

If the specified afterProperty is 0, the given property is inserted at the beginning of the list. If property is already inserted, this function does nothing and returns 0.

+

See also addProperty(), QtProperty::insertSubProperty(), and properties().

+

void QtAbstractPropertyBrowser::itemChanged ( QtBrowserItem * item )   [pure virtual protected]

+

This function is called whenever a property's data changes, passing a pointer to the item of property as parameter.

+

This function must be reimplemented in derived classes in order to update the property browser widget whenever a property's name, tool tip, status tip, "what's this" text, value text or value icon changes.

+

Note that if the property browser contains several occurrences of the same property, this method will be called once for each occurrence (with a different item each time).

+

See also QtProperty and items().

+

void QtAbstractPropertyBrowser::itemInserted ( QtBrowserItem * insertedItem, QtBrowserItem * precedingItem )   [pure virtual protected]

+

This function is called to update the widget whenever a property is inserted or added to the property browser, passing pointers to the insertedItem of property and the specified precedingItem as parameters.

+

If precedingItem is 0, the insertedItem was put at the beginning of its parent item's list of subproperties. If the parent of insertedItem is 0, the insertedItem was added as a top level property of this property browser.

+

This function must be reimplemented in derived classes. Note that if the insertedItem's property has subproperties, this method will be called for those properties as soon as the current call is finished.

+

See also insertProperty() and addProperty().

+

void QtAbstractPropertyBrowser::itemRemoved ( QtBrowserItem * item )   [pure virtual protected]

+

This function is called to update the widget whenever a property is removed from the property browser, passing the pointer to the item of the property as parameters. The passed item is deleted just after this call is finished.

+

If the the parent of item is 0, the removed item was a top level property in this editor.

+

This function must be reimplemented in derived classes. Note that if the removed item's property has subproperties, this method will be called for those properties just before the current call is started.

+

See also removeProperty().

+

QList<QtBrowserItem *> QtAbstractPropertyBrowser::items ( QtProperty * property ) const

+

Returns the property browser's list of all items associated with the given property.

+

There is one item per instance of the property in the browser.

+

See also topLevelItem().

+

QList<QtProperty *> QtAbstractPropertyBrowser::properties () const

+

Returns the property browser's list of top level properties.

+

To traverse the subproperties, use the QtProperty::subProperties() function.

+

See also addProperty(), insertProperty(), and removeProperty().

+

void QtAbstractPropertyBrowser::removeProperty ( QtProperty * property )   [slot]

+

Removes the specified property (and its subproperties) from the property browser's list of top level properties. All items that were associated with the given property and its children are deleted.

+

Note that the properties are not deleted since they can still be used in other editors.

+

See also clear(), QtProperty::removeSubProperty(), and properties().

+

void QtAbstractPropertyBrowser::setCurrentItem ( QtBrowserItem * item )

+

Sets the current item in the property browser to item.

+

See also currentItem() and currentItemChanged().

+

void QtAbstractPropertyBrowser::setFactoryForManager ( PropertyManager * manager, QtAbstractEditorFactory<PropertyManager> * factory )

+

Connects the given manager to the given factory, ensuring that properties of the manager's type will be displayed with an editing widget suitable for their value.

+

For example:

+
 QtIntPropertyManager *intManager;
+ QtDoublePropertyManager *doubleManager;
+
+ QtProperty *myInteger = intManager->addProperty();
+ QtProperty *myDouble = doubleManager->addProperty();
+
+ QtSpinBoxFactory  *spinBoxFactory;
+ QtDoubleSpinBoxFactory *doubleSpinBoxFactory;
+
+ QtAbstractPropertyBrowser *editor;
+ editor->setFactoryForManager(intManager, spinBoxFactory);
+ editor->setFactoryForManager(doubleManager, doubleSpinBoxFactory);
+
+ editor->addProperty(myInteger);
+ editor->addProperty(myDouble);
+

In this example the myInteger property's value is displayed with a QSpinBox widget, while the myDouble property's value is displayed with a QDoubleSpinBox widget.

+

Note that a factory can be associated with many managers, but a manager can only be associated with one single factory. If the given manager already is associated with another factory, the old association is broken before the new one established.

+

This function ensures that the given manager and the given factory are compatible, and it automatically calls the QtAbstractEditorFactory::addPropertyManager() function if necessary.

+

See also unsetFactoryForManager().

+

QtBrowserItem * QtAbstractPropertyBrowser::topLevelItem ( QtProperty * property ) const

+

Returns the top-level items associated with the given property.

+

Returns 0 if property wasn't inserted into this property browser or isn't a top-level one.

+

See also topLevelItems() and items().

+

QList<QtBrowserItem *> QtAbstractPropertyBrowser::topLevelItems () const

+

Returns the list of top-level items.

+

See also topLevelItem().

+

void QtAbstractPropertyBrowser::unsetFactoryForManager ( QtAbstractPropertyManager * manager )

+

Removes the association between the given manager and the factory bound to it, automatically calling the QtAbstractEditorFactory::removePropertyManager() function if necessary.

+

See also setFactoryForManager().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtabstractpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtabstractpropertymanager-members.html new file mode 100644 index 000000000..760f91da0 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtabstractpropertymanager-members.html @@ -0,0 +1,89 @@ + + + + + + List of All Members for QtAbstractPropertyManager + + + + + + + +
  Home

List of All Members for QtAbstractPropertyManager

+

This is the complete list of members for QtAbstractPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtabstractpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtabstractpropertymanager.html new file mode 100644 index 000000000..55671fd9c --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtabstractpropertymanager.html @@ -0,0 +1,160 @@ + + + + + + QtAbstractPropertyManager Class Reference + + + + + + + +
  Home

QtAbstractPropertyManager Class Reference

+

The QtAbstractPropertyManager provides an interface for property managers. More...

+
 #include <QtAbstractPropertyManager>

Inherits QObject.

+

Inherited by QtBoolPropertyManager, QtCharPropertyManager, QtColorPropertyManager, QtCursorPropertyManager, QtDatePropertyManager, QtDateTimePropertyManager, QtDoublePropertyManager, QtEnumPropertyManager, QtFlagPropertyManager, QtFontPropertyManager, QtGroupPropertyManager, QtIntPropertyManager, QtKeySequencePropertyManager, QtLocalePropertyManager, QtPointFPropertyManager, QtPointPropertyManager, QtRectFPropertyManager, QtRectPropertyManager, QtSizeFPropertyManager, QtSizePolicyPropertyManager, QtSizePropertyManager, QtStringPropertyManager, QtTimePropertyManager, and QtVariantPropertyManager.

+ +
+ +

Public Functions

+ + + + + + +
QtAbstractPropertyManager ( QObject * parent = 0 )
~QtAbstractPropertyManager ()
QtProperty * addProperty ( const QString & name = QString() )
void clear () const
QSet<QtProperty *> properties () const
+
    +
  • 29 public functions inherited from QObject
  • +
+
+ +

Signals

+ + + + + +
void propertyChanged ( QtProperty * property )
void propertyDestroyed ( QtProperty * property )
void propertyInserted ( QtProperty * newProperty, QtProperty * parentProperty, QtProperty * precedingProperty )
void propertyRemoved ( QtProperty * property, QtProperty * parent )
+
    +
  • 1 signal inherited from QObject
  • +
+
+ +

Protected Functions

+ + + + + + + +
virtual QtProperty * createProperty ()
virtual bool hasValue ( const QtProperty * property ) const
virtual void initializeProperty ( QtProperty * property ) = 0
virtual void uninitializeProperty ( QtProperty * property )
virtual QIcon valueIcon ( const QtProperty * property ) const
virtual QString valueText ( const QtProperty * property ) const
+
    +
  • 7 protected functions inherited from QObject
  • +
+

Additional Inherited Members

+
    +
  • 1 property inherited from QObject
  • +
  • 1 public slot inherited from QObject
  • +
  • 1 public type inherited from QObject
  • +
  • 4 static public members inherited from QObject
  • +
  • 2 protected variables inherited from QObject
  • +
+ +
+

Detailed Description

+

The QtAbstractPropertyManager provides an interface for property managers.

+

A manager can create and manage properties of a given type, and is used in conjunction with the QtAbstractPropertyBrowser class.

+

When using a property browser widget, the properties are created and managed by implementations of the QtAbstractPropertyManager class. To ensure that the properties' values will be displayed using suitable editing widgets, the managers are associated with objects of QtAbstractEditorFactory subclasses. The property browser will use these associations to determine which factories it should use to create the preferred editing widgets.

+

The QtAbstractPropertyManager class provides common functionality like creating a property using the addProperty() function, and retrieving the properties created by the manager using the properties() function. The class also provides signals that are emitted when the manager's properties change: propertyInserted(), propertyRemoved(), propertyChanged() and propertyDestroyed().

+

QtAbstractPropertyManager subclasses are supposed to provide their own type specific API. Note that several ready-made implementations are available:

+ +

See also QtAbstractEditorFactoryBase, QtAbstractPropertyBrowser, and QtProperty.

+
+

Member Function Documentation

+

QtAbstractPropertyManager::QtAbstractPropertyManager ( QObject * parent = 0 )

+

Creates an abstract property manager with the given parent.

+

QtAbstractPropertyManager::~QtAbstractPropertyManager ()

+

Destroys the manager. All properties created by the manager are destroyed.

+

QtProperty * QtAbstractPropertyManager::addProperty ( const QString & name = QString() )

+

Creates a property with the given name which then is owned by this manager.

+

Internally, this function calls the createProperty() and initializeProperty() functions.

+

See also initializeProperty() and properties().

+

void QtAbstractPropertyManager::clear () const

+

Destroys all the properties that this manager has created.

+

See also propertyDestroyed() and uninitializeProperty().

+

QtProperty * QtAbstractPropertyManager::createProperty ()   [virtual protected]

+

Creates a property.

+

The base implementation produce QtProperty instances; Reimplement this function to make this manager produce objects of a QtProperty subclass.

+

See also addProperty() and initializeProperty().

+

bool QtAbstractPropertyManager::hasValue ( const QtProperty * property ) const   [virtual protected]

+

Returns whether the given property has a value.

+

The default implementation of this function returns true.

+

See also QtProperty::hasValue().

+

void QtAbstractPropertyManager::initializeProperty ( QtProperty * property )   [pure virtual protected]

+

This function is called whenever a new valid property pointer has been created, passing the pointer as parameter.

+

The purpose is to let the manager know that the property has been created so that it can provide additional attributes for the new property, e.g. QtIntPropertyManager adds value, minimum and maximum attributes. Since each manager subclass adds type specific attributes, this function is pure virtual and must be reimplemented when deriving from the QtAbstractPropertyManager class.

+

See also addProperty() and createProperty().

+

QSet<QtProperty *> QtAbstractPropertyManager::properties () const

+

Returns the set of properties created by this manager.

+

See also addProperty().

+

void QtAbstractPropertyManager::propertyChanged ( QtProperty * property )   [signal]

+

This signal is emitted whenever a property's data changes, passing a pointer to the property as parameter.

+

Note that signal is only emitted for properties that are created by this manager.

+

See also QtAbstractPropertyBrowser::itemChanged().

+

void QtAbstractPropertyManager::propertyDestroyed ( QtProperty * property )   [signal]

+

This signal is emitted when the specified property is about to be destroyed.

+

Note that signal is only emitted for properties that are created by this manager.

+

See also clear() and uninitializeProperty().

+

void QtAbstractPropertyManager::propertyInserted ( QtProperty * newProperty, QtProperty * parentProperty, QtProperty * precedingProperty )   [signal]

+

This signal is emitted when a new subproperty is inserted into an existing property, passing pointers to the newProperty, parentProperty and precedingProperty as parameters.

+

If precedingProperty is 0, the newProperty was inserted at the beginning of the parentProperty's subproperties list.

+

Note that signal is emitted only if the parentProperty is created by this manager.

+

See also QtAbstractPropertyBrowser::itemInserted().

+

void QtAbstractPropertyManager::propertyRemoved ( QtProperty * property, QtProperty * parent )   [signal]

+

This signal is emitted when a subproperty is removed, passing pointers to the removed property and the parent property as parameters.

+

Note that signal is emitted only when the parent property is created by this manager.

+

See also QtAbstractPropertyBrowser::itemRemoved().

+

void QtAbstractPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

This function is called just before the specified property is destroyed.

+

The purpose is to let the property manager know that the property is being destroyed so that it can remove the property's additional attributes.

+

See also clear() and propertyDestroyed().

+

QIcon QtAbstractPropertyManager::valueIcon ( const QtProperty * property ) const   [virtual protected]

+

Returns an icon representing the current state of the given property.

+

The default implementation of this function returns an invalid icon.

+

See also QtProperty::valueIcon().

+

QString QtAbstractPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Returns a string representing the current state of the given property.

+

The default implementation of this function returns an empty string.

+

See also QtProperty::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtboolpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtboolpropertymanager-members.html new file mode 100644 index 000000000..f32b2e7c5 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtboolpropertymanager-members.html @@ -0,0 +1,92 @@ + + + + + + List of All Members for QtBoolPropertyManager + + + + + + + +
  Home

List of All Members for QtBoolPropertyManager

+

This is the complete list of members for QtBoolPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtboolpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtboolpropertymanager.html new file mode 100644 index 000000000..faebabd21 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtboolpropertymanager.html @@ -0,0 +1,110 @@ + + + + + + QtBoolPropertyManager Class Reference + + + + + + + +
  Home

QtBoolPropertyManager Class Reference

+

The QtBoolPropertyManager class provides and manages boolean properties. More...

+
 #include <QtBoolPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + +
QtBoolPropertyManager ( QObject * parent = 0 )
~QtBoolPropertyManager ()
bool value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + +
void setValue ( QtProperty * property, bool value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + +
void valueChanged ( QtProperty * property, bool value )
+ +
+ +

Reimplemented Protected Functions

+ + + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QIcon valueIcon ( const QtProperty * property ) const
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtBoolPropertyManager class provides and manages boolean properties.

+

The property's value can be retrieved using the value() function, and set using the setValue() slot.

+

In addition, QtBoolPropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes.

+

See also QtAbstractPropertyManager and QtCheckBoxFactory.

+
+

Member Function Documentation

+

QtBoolPropertyManager::QtBoolPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtBoolPropertyManager::~QtBoolPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

void QtBoolPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtBoolPropertyManager::setValue ( QtProperty * property, bool value )   [slot]

+

Sets the value of the given property to value.

+

See also value().

+

void QtBoolPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

bool QtBoolPropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns false.

+

See also setValue().

+

void QtBoolPropertyManager::valueChanged ( QtProperty * property, bool value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

QIcon QtBoolPropertyManager::valueIcon ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueIcon().

+

QString QtBoolPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtbrowseritem-members.html b/external/QtPropertyBrowser/doc/html/qtbrowseritem-members.html new file mode 100644 index 000000000..54893291c --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtbrowseritem-members.html @@ -0,0 +1,29 @@ + + + + + + List of All Members for QtBrowserItem + + + + + + + +
  Home

List of All Members for QtBrowserItem

+

This is the complete list of members for QtBrowserItem, including inherited members.

+
    +
  • browser () const : QtAbstractPropertyBrowser *
  • +
  • children () const : QList<QtBrowserItem *>
  • +
  • parent () const : QtBrowserItem *
  • +
  • property () const : QtProperty *
  • +
+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtbrowseritem.html b/external/QtPropertyBrowser/doc/html/qtbrowseritem.html new file mode 100644 index 000000000..735e426fb --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtbrowseritem.html @@ -0,0 +1,59 @@ + + + + + + QtBrowserItem Class Reference + + + + + + + +
  Home

QtBrowserItem Class Reference

+

The QtBrowserItem class represents a property in a property browser instance. More...

+
 #include <QtBrowserItem>
+
+ +

Public Functions

+ + + + + +
QtAbstractPropertyBrowser * browser () const
QList<QtBrowserItem *> children () const
QtBrowserItem * parent () const
QtProperty * property () const
+ +
+

Detailed Description

+

The QtBrowserItem class represents a property in a property browser instance.

+

Browser items are created whenever a QtProperty is inserted to the property browser. A QtBrowserItem uniquely identifies a browser's item. Thus, if the same QtProperty is inserted multiple times, each occurrence gets its own unique QtBrowserItem. The items are owned by QtAbstractPropertyBrowser and automatically deleted when they are removed from the browser.

+

You can traverse a browser's properties by calling parent() and children(). The property and the browser associated with an item are available as property() and browser().

+

See also QtAbstractPropertyBrowser and QtProperty.

+
+

Member Function Documentation

+

QtAbstractPropertyBrowser * QtBrowserItem::browser () const

+

Returns the property browser which owns this item.

+

QList<QtBrowserItem *> QtBrowserItem::children () const

+

Returns the children items of this item. The properties reproduced from children items are always the same as reproduced from associated property' children, for example:

+
 QtBrowserItem *item;
+ QList<QtBrowserItem *> childrenItems = item->children();
+
+ QList<QtProperty *> childrenProperties = item->property()->subProperties();
+

The childrenItems list represents the same list as childrenProperties.

+

QtBrowserItem * QtBrowserItem::parent () const

+

Returns the parent item of this item. Returns 0 if this item is associated with top-level property in item's property browser.

+

See also children().

+

QtProperty * QtBrowserItem::property () const

+

Returns the property which is accosiated with this item. Note that several items can be associated with the same property instance in the same property browser.

+

See also QtAbstractPropertyBrowser::items().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtbuttonpropertybrowser-members.html b/external/QtPropertyBrowser/doc/html/qtbuttonpropertybrowser-members.html new file mode 100644 index 000000000..2630e2c48 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtbuttonpropertybrowser-members.html @@ -0,0 +1,388 @@ + + + + + + List of All Members for QtButtonPropertyBrowser + + + + + + + +
  Home

List of All Members for QtButtonPropertyBrowser

+

This is the complete list of members for QtButtonPropertyBrowser, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtbuttonpropertybrowser.html b/external/QtPropertyBrowser/doc/html/qtbuttonpropertybrowser.html new file mode 100644 index 000000000..cea7e4d9b --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtbuttonpropertybrowser.html @@ -0,0 +1,120 @@ + + + + + + QtButtonPropertyBrowser Class Reference + + + + + + + +
  Home

QtButtonPropertyBrowser Class Reference

+

The QtButtonPropertyBrowser class provides a drop down QToolButton based property browser. More...

+
 #include <QtButtonPropertyBrowser>

Inherits QtAbstractPropertyBrowser.

+ +
+ +

Public Functions

+ + + + + +
QtButtonPropertyBrowser ( QWidget * parent = 0 )
~QtButtonPropertyBrowser ()
bool isExpanded ( QtBrowserItem * item ) const
void setExpanded ( QtBrowserItem * item, bool expanded )
+ +
+ +

Signals

+ + + +
void collapsed ( QtBrowserItem * item )
void expanded ( QtBrowserItem * item )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void itemChanged ( QtBrowserItem * item )
virtual void itemInserted ( QtBrowserItem * item, QtBrowserItem * afterItem )
virtual void itemRemoved ( QtBrowserItem * item )
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtButtonPropertyBrowser class provides a drop down QToolButton based property browser.

+

A property browser is a widget that enables the user to edit a given set of properties. Each property is represented by a label specifying the property's name, and an editing widget (e.g. a line edit or a combobox) holding its value. A property can have zero or more subproperties.

+

QtButtonPropertyBrowser provides drop down button for all nested properties, i.e. subproperties are enclosed by a container associated with the drop down button. The parent property's name is displayed as button text. For example:

+

Use the QtAbstractPropertyBrowser API to add, insert and remove properties from an instance of the QtButtonPropertyBrowser class. The properties themselves are created and managed by implementations of the QtAbstractPropertyManager class.

+

See also QtTreePropertyBrowser and QtAbstractPropertyBrowser.

+
+

Member Function Documentation

+

QtButtonPropertyBrowser::QtButtonPropertyBrowser ( QWidget * parent = 0 )

+

Creates a property browser with the given parent.

+

QtButtonPropertyBrowser::~QtButtonPropertyBrowser ()

+

Destroys this property browser.

+

Note that the properties that were inserted into this browser are not destroyed since they may still be used in other browsers. The properties are owned by the manager that created them.

+

See also QtProperty and QtAbstractPropertyManager.

+

void QtButtonPropertyBrowser::collapsed ( QtBrowserItem * item )   [signal]

+

This signal is emitted when the item is collapsed.

+

See also expanded() and setExpanded().

+

void QtButtonPropertyBrowser::expanded ( QtBrowserItem * item )   [signal]

+

This signal is emitted when the item is expanded.

+

See also collapsed() and setExpanded().

+

bool QtButtonPropertyBrowser::isExpanded ( QtBrowserItem * item ) const

+

Returns true if the item is expanded; otherwise returns false.

+

See also setExpanded().

+

void QtButtonPropertyBrowser::itemChanged ( QtBrowserItem * item )   [virtual protected]

+

Reimplemented from QtAbstractPropertyBrowser::itemChanged().

+

void QtButtonPropertyBrowser::itemInserted ( QtBrowserItem * item, QtBrowserItem * afterItem )   [virtual protected]

+

Reimplemented from QtAbstractPropertyBrowser::itemInserted().

+

void QtButtonPropertyBrowser::itemRemoved ( QtBrowserItem * item )   [virtual protected]

+

Reimplemented from QtAbstractPropertyBrowser::itemRemoved().

+

void QtButtonPropertyBrowser::setExpanded ( QtBrowserItem * item, bool expanded )

+

Sets the item to either collapse or expanded, depending on the value of expanded.

+

See also isExpanded(), expanded(), and collapsed().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtchareditorfactory-members.html b/external/QtPropertyBrowser/doc/html/qtchareditorfactory-members.html new file mode 100644 index 000000000..2999d6609 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtchareditorfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtCharEditorFactory + + + + + + + +
  Home

List of All Members for QtCharEditorFactory

+

This is the complete list of members for QtCharEditorFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtchareditorfactory.html b/external/QtPropertyBrowser/doc/html/qtchareditorfactory.html new file mode 100644 index 000000000..d6584f3ba --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtchareditorfactory.html @@ -0,0 +1,61 @@ + + + + + + QtCharEditorFactory Class Reference + + + + + + + +
  Home

QtCharEditorFactory Class Reference

+

The QtCharEditorFactory class provides editor widgets for properties created by QtCharPropertyManager objects. More...

+
 #include <QtCharEditorFactory>

Inherits QtAbstractEditorFactory<QtCharPropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtCharEditorFactory ( QObject * parent = 0 )
~QtCharEditorFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtCharEditorFactory class provides editor widgets for properties created by QtCharPropertyManager objects.

+

See also QtAbstractEditorFactory.

+
+

Member Function Documentation

+

QtCharEditorFactory::QtCharEditorFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtCharEditorFactory::~QtCharEditorFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtcharpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtcharpropertymanager-members.html new file mode 100644 index 000000000..6a5c45e69 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtcharpropertymanager-members.html @@ -0,0 +1,92 @@ + + + + + + List of All Members for QtCharPropertyManager + + + + + + + +
  Home

List of All Members for QtCharPropertyManager

+

This is the complete list of members for QtCharPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtcharpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtcharpropertymanager.html new file mode 100644 index 000000000..b7da41e88 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtcharpropertymanager.html @@ -0,0 +1,107 @@ + + + + + + QtCharPropertyManager Class Reference + + + + + + + +
  Home

QtCharPropertyManager Class Reference

+

The QtCharPropertyManager provides and manages QChar properties. More...

+
 #include <QtCharPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + +
QtCharPropertyManager ( QObject * parent = 0 )
~QtCharPropertyManager ()
QChar value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + +
void setValue ( QtProperty * property, const QChar & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + +
void valueChanged ( QtProperty * property, const QChar & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtCharPropertyManager provides and manages QChar properties.

+

A char's value can be retrieved using the value() function, and set using the setValue() slot.

+

In addition, QtCharPropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes.

+

See also QtAbstractPropertyManager.

+
+

Member Function Documentation

+

QtCharPropertyManager::QtCharPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtCharPropertyManager::~QtCharPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

void QtCharPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtCharPropertyManager::setValue ( QtProperty * property, const QChar & value )   [slot]

+

Sets the value of the given property to value.

+

See also value() and valueChanged().

+

void QtCharPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QChar QtCharPropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns an null QChar object.

+

See also setValue().

+

void QtCharPropertyManager::valueChanged ( QtProperty * property, const QChar & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

QString QtCharPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtcheckboxfactory-members.html b/external/QtPropertyBrowser/doc/html/qtcheckboxfactory-members.html new file mode 100644 index 000000000..70b8219db --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtcheckboxfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtCheckBoxFactory + + + + + + + +
  Home

List of All Members for QtCheckBoxFactory

+

This is the complete list of members for QtCheckBoxFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtcheckboxfactory.html b/external/QtPropertyBrowser/doc/html/qtcheckboxfactory.html new file mode 100644 index 000000000..28b3bc6b4 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtcheckboxfactory.html @@ -0,0 +1,61 @@ + + + + + + QtCheckBoxFactory Class Reference + + + + + + + +
  Home

QtCheckBoxFactory Class Reference

+

The QtCheckBoxFactory class provides QCheckBox widgets for properties created by QtBoolPropertyManager objects. More...

+
 #include <QtCheckBoxFactory>

Inherits QtAbstractEditorFactory<QtBoolPropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtCheckBoxFactory ( QObject * parent = 0 )
~QtCheckBoxFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtCheckBoxFactory class provides QCheckBox widgets for properties created by QtBoolPropertyManager objects.

+

See also QtAbstractEditorFactory and QtBoolPropertyManager.

+
+

Member Function Documentation

+

QtCheckBoxFactory::QtCheckBoxFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtCheckBoxFactory::~QtCheckBoxFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtcoloreditorfactory-members.html b/external/QtPropertyBrowser/doc/html/qtcoloreditorfactory-members.html new file mode 100644 index 000000000..5ad22f083 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtcoloreditorfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtColorEditorFactory + + + + + + + +
  Home

List of All Members for QtColorEditorFactory

+

This is the complete list of members for QtColorEditorFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtcoloreditorfactory.html b/external/QtPropertyBrowser/doc/html/qtcoloreditorfactory.html new file mode 100644 index 000000000..78978aa77 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtcoloreditorfactory.html @@ -0,0 +1,61 @@ + + + + + + QtColorEditorFactory Class Reference + + + + + + + +
  Home

QtColorEditorFactory Class Reference

+

The QtColorEditorFactory class provides color editing for properties created by QtColorPropertyManager objects. More...

+
 #include <QtColorEditorFactory>

Inherits QtAbstractEditorFactory<QtColorPropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtColorEditorFactory ( QObject * parent = 0 )
~QtColorEditorFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtColorEditorFactory class provides color editing for properties created by QtColorPropertyManager objects.

+

See also QtAbstractEditorFactory and QtColorPropertyManager.

+
+

Member Function Documentation

+

QtColorEditorFactory::QtColorEditorFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtColorEditorFactory::~QtColorEditorFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtcolorpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtcolorpropertymanager-members.html new file mode 100644 index 000000000..c365c6387 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtcolorpropertymanager-members.html @@ -0,0 +1,93 @@ + + + + + + List of All Members for QtColorPropertyManager + + + + + + + +
  Home

List of All Members for QtColorPropertyManager

+

This is the complete list of members for QtColorPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtcolorpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtcolorpropertymanager.html new file mode 100644 index 000000000..778a86772 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtcolorpropertymanager.html @@ -0,0 +1,117 @@ + + + + + + QtColorPropertyManager Class Reference + + + + + + + +
  Home

QtColorPropertyManager Class Reference

+

The QtColorPropertyManager provides and manages QColor properties. More...

+
 #include <QtColorPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + +
QtColorPropertyManager ( QObject * parent = 0 )
~QtColorPropertyManager ()
QtIntPropertyManager * subIntPropertyManager () const
QColor value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + +
void setValue ( QtProperty * property, const QColor & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + +
void valueChanged ( QtProperty * property, const QColor & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QIcon valueIcon ( const QtProperty * property ) const
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtColorPropertyManager provides and manages QColor properties.

+

A color property has nested red, green and blue subproperties. The top-level property's value can be retrieved using the value() function, and set using the setValue() slot.

+

The subproperties are created by a QtIntPropertyManager object. This manager can be retrieved using the subIntPropertyManager() function. In order to provide editing widgets for the subproperties in a property browser widget, this manager must be associated with an editor factory.

+

In addition, QtColorPropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes.

+

See also QtAbstractPropertyManager, QtAbstractPropertyBrowser, and QtIntPropertyManager.

+
+

Member Function Documentation

+

QtColorPropertyManager::QtColorPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtColorPropertyManager::~QtColorPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

void QtColorPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtColorPropertyManager::setValue ( QtProperty * property, const QColor & value )   [slot]

+

Sets the value of the given property to value. Nested properties are updated automatically.

+

See also value() and valueChanged().

+

QtIntPropertyManager * QtColorPropertyManager::subIntPropertyManager () const

+

Returns the manager that produces the nested red, green and blue subproperties.

+

In order to provide editing widgets for the subproperties in a property browser widget, this manager must be associated with an editor factory.

+

See also QtAbstractPropertyBrowser::setFactoryForManager().

+

void QtColorPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QColor QtColorPropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns an invalid color.

+

See also setValue().

+

void QtColorPropertyManager::valueChanged ( QtProperty * property, const QColor & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QIcon QtColorPropertyManager::valueIcon ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueIcon().

+

QString QtColorPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtcursoreditorfactory-members.html b/external/QtPropertyBrowser/doc/html/qtcursoreditorfactory-members.html new file mode 100644 index 000000000..b8d1a0037 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtcursoreditorfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtCursorEditorFactory + + + + + + + +
  Home

List of All Members for QtCursorEditorFactory

+

This is the complete list of members for QtCursorEditorFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtcursoreditorfactory.html b/external/QtPropertyBrowser/doc/html/qtcursoreditorfactory.html new file mode 100644 index 000000000..204b5ac8f --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtcursoreditorfactory.html @@ -0,0 +1,61 @@ + + + + + + QtCursorEditorFactory Class Reference + + + + + + + +
  Home

QtCursorEditorFactory Class Reference

+

The QtCursorEditorFactory class provides QComboBox widgets for properties created by QtCursorPropertyManager objects. More...

+
 #include <QtCursorEditorFactory>

Inherits QtAbstractEditorFactory<QtCursorPropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtCursorEditorFactory ( QObject * parent = 0 )
~QtCursorEditorFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtCursorEditorFactory class provides QComboBox widgets for properties created by QtCursorPropertyManager objects.

+

See also QtAbstractEditorFactory and QtCursorPropertyManager.

+
+

Member Function Documentation

+

QtCursorEditorFactory::QtCursorEditorFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtCursorEditorFactory::~QtCursorEditorFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtcursorpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtcursorpropertymanager-members.html new file mode 100644 index 000000000..37413fa6a --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtcursorpropertymanager-members.html @@ -0,0 +1,92 @@ + + + + + + List of All Members for QtCursorPropertyManager + + + + + + + +
  Home

List of All Members for QtCursorPropertyManager

+

This is the complete list of members for QtCursorPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtcursorpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtcursorpropertymanager.html new file mode 100644 index 000000000..0b729fca7 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtcursorpropertymanager.html @@ -0,0 +1,110 @@ + + + + + + QtCursorPropertyManager Class Reference + + + + + + + +
  Home

QtCursorPropertyManager Class Reference

+

The QtCursorPropertyManager provides and manages QCursor properties. More...

+
 #include <QtCursorPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + +
QtCursorPropertyManager ( QObject * parent = 0 )
~QtCursorPropertyManager ()
QCursor value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + +
void setValue ( QtProperty * property, const QCursor & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + +
void valueChanged ( QtProperty * property, const QCursor & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QIcon valueIcon ( const QtProperty * property ) const
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtCursorPropertyManager provides and manages QCursor properties.

+

A cursor property has a current value which can be retrieved using the value() function, and set using the setValue() slot. In addition, QtCursorPropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes.

+

See also QtAbstractPropertyManager.

+
+

Member Function Documentation

+

QtCursorPropertyManager::QtCursorPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtCursorPropertyManager::~QtCursorPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

void QtCursorPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtCursorPropertyManager::setValue ( QtProperty * property, const QCursor & value )   [slot]

+

Sets the value of the given property to value.

+

See also value() and valueChanged().

+

void QtCursorPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QCursor QtCursorPropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns a default QCursor object.

+

See also setValue().

+

void QtCursorPropertyManager::valueChanged ( QtProperty * property, const QCursor & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QIcon QtCursorPropertyManager::valueIcon ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueIcon().

+

QString QtCursorPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtdateeditfactory-members.html b/external/QtPropertyBrowser/doc/html/qtdateeditfactory-members.html new file mode 100644 index 000000000..e5398ab24 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtdateeditfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtDateEditFactory + + + + + + + +
  Home

List of All Members for QtDateEditFactory

+

This is the complete list of members for QtDateEditFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtdateeditfactory.html b/external/QtPropertyBrowser/doc/html/qtdateeditfactory.html new file mode 100644 index 000000000..a59b4e734 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtdateeditfactory.html @@ -0,0 +1,61 @@ + + + + + + QtDateEditFactory Class Reference + + + + + + + +
  Home

QtDateEditFactory Class Reference

+

The QtDateEditFactory class provides QDateEdit widgets for properties created by QtDatePropertyManager objects. More...

+
 #include <QtDateEditFactory>

Inherits QtAbstractEditorFactory<QtDatePropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtDateEditFactory ( QObject * parent = 0 )
~QtDateEditFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtDateEditFactory class provides QDateEdit widgets for properties created by QtDatePropertyManager objects.

+

See also QtAbstractEditorFactory and QtDatePropertyManager.

+
+

Member Function Documentation

+

QtDateEditFactory::QtDateEditFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtDateEditFactory::~QtDateEditFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtdatepropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtdatepropertymanager-members.html new file mode 100644 index 000000000..c7aa6ed4d --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtdatepropertymanager-members.html @@ -0,0 +1,98 @@ + + + + + + List of All Members for QtDatePropertyManager + + + + + + + +
  Home

List of All Members for QtDatePropertyManager

+

This is the complete list of members for QtDatePropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtdatepropertymanager.html b/external/QtPropertyBrowser/doc/html/qtdatepropertymanager.html new file mode 100644 index 000000000..96a256fbe --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtdatepropertymanager.html @@ -0,0 +1,138 @@ + + + + + + QtDatePropertyManager Class Reference + + + + + + + +
  Home

QtDatePropertyManager Class Reference

+

The QtDatePropertyManager provides and manages QDate properties. More...

+
 #include <QtDatePropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + + +
QtDatePropertyManager ( QObject * parent = 0 )
~QtDatePropertyManager ()
QDate maximum ( const QtProperty * property ) const
QDate minimum ( const QtProperty * property ) const
QDate value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + + + + +
void setMaximum ( QtProperty * property, const QDate & maxVal )
void setMinimum ( QtProperty * property, const QDate & minVal )
void setRange ( QtProperty * property, const QDate & minimum, const QDate & maximum )
void setValue ( QtProperty * property, const QDate & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + + +
void rangeChanged ( QtProperty * property, const QDate & minimum, const QDate & maximum )
void valueChanged ( QtProperty * property, const QDate & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtDatePropertyManager provides and manages QDate properties.

+

A date property has a current value, and a range specifying the valid dates. The range is defined by a minimum and a maximum value.

+

The property's values can be retrieved using the minimum(), maximum() and value() functions, and can be set using the setMinimum(), setMaximum() and setValue() slots. Alternatively, the range can be defined in one go using the setRange() slot.

+

In addition, QtDatePropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes, and the rangeChanged() signal which is emitted whenever such a property changes its range of valid dates.

+

See also QtAbstractPropertyManager, QtDateEditFactory, and QtDateTimePropertyManager.

+
+

Member Function Documentation

+

QtDatePropertyManager::QtDatePropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtDatePropertyManager::~QtDatePropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

void QtDatePropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

QDate QtDatePropertyManager::maximum ( const QtProperty * property ) const

+

Returns the given property's maximum date.

+

See also setMaximum(), minimum(), and setRange().

+

QDate QtDatePropertyManager::minimum ( const QtProperty * property ) const

+

Returns the given property's minimum date.

+

See also setMinimum(), maximum(), and setRange().

+

void QtDatePropertyManager::rangeChanged ( QtProperty * property, const QDate & minimum, const QDate & maximum )   [signal]

+

This signal is emitted whenever a property created by this manager changes its range of valid dates, passing a pointer to the property and the new minimum and maximum dates.

+

See also setRange().

+

void QtDatePropertyManager::setMaximum ( QtProperty * property, const QDate & maxVal )   [slot]

+

Sets the maximum value for the given property to maxVal.

+

When setting the maximum value, the minimum and current values are adjusted if necessary (ensuring that the range remains valid and that the current value is within in the range).

+

See also maximum() and setRange().

+

void QtDatePropertyManager::setMinimum ( QtProperty * property, const QDate & minVal )   [slot]

+

Sets the minimum value for the given property to minVal.

+

When setting the minimum value, the maximum and current values are adjusted if necessary (ensuring that the range remains valid and that the current value is within in the range).

+

See also minimum() and setRange().

+

void QtDatePropertyManager::setRange ( QtProperty * property, const QDate & minimum, const QDate & maximum )   [slot]

+

Sets the range of valid dates.

+

This is a convenience function defining the range of valid dates in one go; setting the minimum and maximum values for the given property with a single function call.

+

When setting a new date range, the current value is adjusted if necessary (ensuring that the value remains in date range).

+

See also setMinimum(), setMaximum(), and rangeChanged().

+

void QtDatePropertyManager::setValue ( QtProperty * property, const QDate & value )   [slot]

+

Sets the value of the given property to value.

+

If the specified value is not a valid date according to the given property's range, the value is adjusted to the nearest valid value within the range.

+

See also value(), setRange(), and valueChanged().

+

void QtDatePropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QDate QtDatePropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns an invalid date.

+

See also setValue().

+

void QtDatePropertyManager::valueChanged ( QtProperty * property, const QDate & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QString QtDatePropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtdatetimeeditfactory-members.html b/external/QtPropertyBrowser/doc/html/qtdatetimeeditfactory-members.html new file mode 100644 index 000000000..604e8a874 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtdatetimeeditfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtDateTimeEditFactory + + + + + + + +
  Home

List of All Members for QtDateTimeEditFactory

+

This is the complete list of members for QtDateTimeEditFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtdatetimeeditfactory.html b/external/QtPropertyBrowser/doc/html/qtdatetimeeditfactory.html new file mode 100644 index 000000000..ec526cd0e --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtdatetimeeditfactory.html @@ -0,0 +1,61 @@ + + + + + + QtDateTimeEditFactory Class Reference + + + + + + + +
  Home

QtDateTimeEditFactory Class Reference

+

The QtDateTimeEditFactory class provides QDateTimeEdit widgets for properties created by QtDateTimePropertyManager objects. More...

+
 #include <QtDateTimeEditFactory>

Inherits QtAbstractEditorFactory<QtDateTimePropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtDateTimeEditFactory ( QObject * parent = 0 )
~QtDateTimeEditFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtDateTimeEditFactory class provides QDateTimeEdit widgets for properties created by QtDateTimePropertyManager objects.

+

See also QtAbstractEditorFactory and QtDateTimePropertyManager.

+
+

Member Function Documentation

+

QtDateTimeEditFactory::QtDateTimeEditFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtDateTimeEditFactory::~QtDateTimeEditFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtdatetimepropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtdatetimepropertymanager-members.html new file mode 100644 index 000000000..2929cf429 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtdatetimepropertymanager-members.html @@ -0,0 +1,92 @@ + + + + + + List of All Members for QtDateTimePropertyManager + + + + + + + +
  Home

List of All Members for QtDateTimePropertyManager

+

This is the complete list of members for QtDateTimePropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtdatetimepropertymanager.html b/external/QtPropertyBrowser/doc/html/qtdatetimepropertymanager.html new file mode 100644 index 000000000..d68959dad --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtdatetimepropertymanager.html @@ -0,0 +1,106 @@ + + + + + + QtDateTimePropertyManager Class Reference + + + + + + + +
  Home

QtDateTimePropertyManager Class Reference

+

The QtDateTimePropertyManager provides and manages QDateTime properties. More...

+
 #include <QtDateTimePropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + +
QtDateTimePropertyManager ( QObject * parent = 0 )
~QtDateTimePropertyManager ()
QDateTime value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + +
void setValue ( QtProperty * property, const QDateTime & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + +
void valueChanged ( QtProperty * property, const QDateTime & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtDateTimePropertyManager provides and manages QDateTime properties.

+

A date and time property has a current value which can be retrieved using the value() function, and set using the setValue() slot. In addition, QtDateTimePropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes.

+

See also QtAbstractPropertyManager, QtDateTimeEditFactory, and QtDatePropertyManager.

+
+

Member Function Documentation

+

QtDateTimePropertyManager::QtDateTimePropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtDateTimePropertyManager::~QtDateTimePropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

void QtDateTimePropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtDateTimePropertyManager::setValue ( QtProperty * property, const QDateTime & value )   [slot]

+

Sets the value of the given property to value.

+

See also value() and valueChanged().

+

void QtDateTimePropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QDateTime QtDateTimePropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns an invalid QDateTime object.

+

See also setValue().

+

void QtDateTimePropertyManager::valueChanged ( QtProperty * property, const QDateTime & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

QString QtDateTimePropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtdoublepropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtdoublepropertymanager-members.html new file mode 100644 index 000000000..2ea6b0b73 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtdoublepropertymanager-members.html @@ -0,0 +1,104 @@ + + + + + + List of All Members for QtDoublePropertyManager + + + + + + + +
  Home

List of All Members for QtDoublePropertyManager

+

This is the complete list of members for QtDoublePropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtdoublepropertymanager.html b/external/QtPropertyBrowser/doc/html/qtdoublepropertymanager.html new file mode 100644 index 000000000..322c03816 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtdoublepropertymanager.html @@ -0,0 +1,165 @@ + + + + + + QtDoublePropertyManager Class Reference + + + + + + + +
  Home

QtDoublePropertyManager Class Reference

+

The QtDoublePropertyManager provides and manages double properties. More...

+
 #include <QtDoublePropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + + + + +
QtDoublePropertyManager ( QObject * parent = 0 )
~QtDoublePropertyManager ()
int decimals ( const QtProperty * property ) const
double maximum ( const QtProperty * property ) const
double minimum ( const QtProperty * property ) const
double singleStep ( const QtProperty * property ) const
double value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + + + + + + +
void setDecimals ( QtProperty * property, int prec )
void setMaximum ( QtProperty * property, double maxVal )
void setMinimum ( QtProperty * property, double minVal )
void setRange ( QtProperty * property, double minimum, double maximum )
void setSingleStep ( QtProperty * property, double step )
void setValue ( QtProperty * property, double value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + + + + +
void decimalsChanged ( QtProperty * property, int prec )
void rangeChanged ( QtProperty * property, double minimum, double maximum )
void singleStepChanged ( QtProperty * property, double step )
void valueChanged ( QtProperty * property, double value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtDoublePropertyManager provides and manages double properties.

+

A double property has a current value, and a range specifying the valid values. The range is defined by a minimum and a maximum value.

+

The property's value and range can be retrieved using the value(), minimum() and maximum() functions, and can be set using the setValue(), setMinimum() and setMaximum() slots. Alternatively, the range can be defined in one go using the setRange() slot.

+

In addition, QtDoublePropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes, and the rangeChanged() signal which is emitted whenever such a property changes its range of valid values.

+

See also QtAbstractPropertyManager and QtDoubleSpinBoxFactory.

+
+

Member Function Documentation

+

QtDoublePropertyManager::QtDoublePropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtDoublePropertyManager::~QtDoublePropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

int QtDoublePropertyManager::decimals ( const QtProperty * property ) const

+

Returns the given property's precision, in decimals.

+

See also setDecimals().

+

void QtDoublePropertyManager::decimalsChanged ( QtProperty * property, int prec )   [signal]

+

This signal is emitted whenever a property created by this manager changes its precision of value, passing a pointer to the property and the new prec value

+

See also setDecimals().

+

void QtDoublePropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

double QtDoublePropertyManager::maximum ( const QtProperty * property ) const

+

Returns the given property's maximum value.

+

See also setMaximum(), minimum(), and setRange().

+

double QtDoublePropertyManager::minimum ( const QtProperty * property ) const

+

Returns the given property's minimum value.

+

See also setMinimum(), maximum(), and setRange().

+

void QtDoublePropertyManager::rangeChanged ( QtProperty * property, double minimum, double maximum )   [signal]

+

This signal is emitted whenever a property created by this manager changes its range of valid values, passing a pointer to the property and the new minimum and maximum values

+

See also setRange().

+

void QtDoublePropertyManager::setDecimals ( QtProperty * property, int prec )   [slot]

+

Sets the precision of the given property to prec.

+

The valid decimal range is 0-13. The default is 2.

+

See also decimals().

+

void QtDoublePropertyManager::setMaximum ( QtProperty * property, double maxVal )   [slot]

+

Sets the maximum value for the given property to maxVal.

+

When setting the maximum value, the minimum and current values are adjusted if necessary (ensuring that the range remains valid and that the current value is within in the range).

+

See also maximum(), setRange(), and rangeChanged().

+

void QtDoublePropertyManager::setMinimum ( QtProperty * property, double minVal )   [slot]

+

Sets the minimum value for the given property to minVal.

+

When setting the minimum value, the maximum and current values are adjusted if necessary (ensuring that the range remains valid and that the current value is within in the range).

+

See also minimum(), setRange(), and rangeChanged().

+

void QtDoublePropertyManager::setRange ( QtProperty * property, double minimum, double maximum )   [slot]

+

Sets the range of valid values.

+

This is a convenience function defining the range of valid values in one go; setting the minimum and maximum values for the given property with a single function call.

+

When setting a new range, the current value is adjusted if necessary (ensuring that the value remains within range).

+

See also setMinimum(), setMaximum(), and rangeChanged().

+

void QtDoublePropertyManager::setSingleStep ( QtProperty * property, double step )   [slot]

+

Sets the step value for the given property to step.

+

The step is typically used to increment or decrement a property value while pressing an arrow key.

+

See also singleStep().

+

void QtDoublePropertyManager::setValue ( QtProperty * property, double value )   [slot]

+

Sets the value of the given property to value.

+

If the specified value is not valid according to the given property's range, the value is adjusted to the nearest valid value within the range.

+

See also value(), setRange(), and valueChanged().

+

double QtDoublePropertyManager::singleStep ( const QtProperty * property ) const

+

Returns the given property's step value.

+

The step is typically used to increment or decrement a property value while pressing an arrow key.

+

See also setSingleStep().

+

void QtDoublePropertyManager::singleStepChanged ( QtProperty * property, double step )   [signal]

+

This signal is emitted whenever a property created by this manager changes its single step property, passing a pointer to the property and the new step value

+

See also setSingleStep().

+

void QtDoublePropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

double QtDoublePropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns 0.

+

See also setValue().

+

void QtDoublePropertyManager::valueChanged ( QtProperty * property, double value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QString QtDoublePropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtdoublespinboxfactory-members.html b/external/QtPropertyBrowser/doc/html/qtdoublespinboxfactory-members.html new file mode 100644 index 000000000..92ea83a5f --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtdoublespinboxfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtDoubleSpinBoxFactory + + + + + + + +
  Home

List of All Members for QtDoubleSpinBoxFactory

+

This is the complete list of members for QtDoubleSpinBoxFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtdoublespinboxfactory.html b/external/QtPropertyBrowser/doc/html/qtdoublespinboxfactory.html new file mode 100644 index 000000000..fb0724c79 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtdoublespinboxfactory.html @@ -0,0 +1,61 @@ + + + + + + QtDoubleSpinBoxFactory Class Reference + + + + + + + +
  Home

QtDoubleSpinBoxFactory Class Reference

+

The QtDoubleSpinBoxFactory class provides QDoubleSpinBox widgets for properties created by QtDoublePropertyManager objects. More...

+
 #include <QtDoubleSpinBoxFactory>

Inherits QtAbstractEditorFactory<QtDoublePropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtDoubleSpinBoxFactory ( QObject * parent = 0 )
~QtDoubleSpinBoxFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtDoubleSpinBoxFactory class provides QDoubleSpinBox widgets for properties created by QtDoublePropertyManager objects.

+

See also QtAbstractEditorFactory and QtDoublePropertyManager.

+
+

Member Function Documentation

+

QtDoubleSpinBoxFactory::QtDoubleSpinBoxFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtDoubleSpinBoxFactory::~QtDoubleSpinBoxFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtenumeditorfactory-members.html b/external/QtPropertyBrowser/doc/html/qtenumeditorfactory-members.html new file mode 100644 index 000000000..c6615b25c --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtenumeditorfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtEnumEditorFactory + + + + + + + +
  Home

List of All Members for QtEnumEditorFactory

+

This is the complete list of members for QtEnumEditorFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtenumeditorfactory.html b/external/QtPropertyBrowser/doc/html/qtenumeditorfactory.html new file mode 100644 index 000000000..d40586f5f --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtenumeditorfactory.html @@ -0,0 +1,61 @@ + + + + + + QtEnumEditorFactory Class Reference + + + + + + + +
  Home

QtEnumEditorFactory Class Reference

+

The QtEnumEditorFactory class provides QComboBox widgets for properties created by QtEnumPropertyManager objects. More...

+
 #include <QtEnumEditorFactory>

Inherits QtAbstractEditorFactory<QtEnumPropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtEnumEditorFactory ( QObject * parent = 0 )
~QtEnumEditorFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtEnumEditorFactory class provides QComboBox widgets for properties created by QtEnumPropertyManager objects.

+

See also QtAbstractEditorFactory and QtEnumPropertyManager.

+
+

Member Function Documentation

+

QtEnumEditorFactory::QtEnumEditorFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtEnumEditorFactory::~QtEnumEditorFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtenumpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtenumpropertymanager-members.html new file mode 100644 index 000000000..4884a075c --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtenumpropertymanager-members.html @@ -0,0 +1,98 @@ + + + + + + List of All Members for QtEnumPropertyManager + + + + + + + +
  Home

List of All Members for QtEnumPropertyManager

+

This is the complete list of members for QtEnumPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtenumpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtenumpropertymanager.html new file mode 100644 index 000000000..30ba3c865 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtenumpropertymanager.html @@ -0,0 +1,139 @@ + + + + + + QtEnumPropertyManager Class Reference + + + + + + + +
  Home

QtEnumPropertyManager Class Reference

+

The QtEnumPropertyManager provides and manages enum properties. More...

+
 #include <QtEnumPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + + +
QtEnumPropertyManager ( QObject * parent = 0 )
~QtEnumPropertyManager ()
QMap<int, QIcon> enumIcons ( const QtProperty * property ) const
QStringList enumNames ( const QtProperty * property ) const
int value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + + + +
void setEnumIcons ( QtProperty * property, const QMap<int, QIcon> & enumIcons )
void setEnumNames ( QtProperty * property, const QStringList & enumNames )
void setValue ( QtProperty * property, int value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + + + +
void enumIconsChanged ( QtProperty * property, const QMap<int, QIcon> & icons )
void enumNamesChanged ( QtProperty * property, const QStringList & names )
void valueChanged ( QtProperty * property, int value )
+ +
+ +

Reimplemented Protected Functions

+ + + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QIcon valueIcon ( const QtProperty * property ) const
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtEnumPropertyManager provides and manages enum properties.

+

Each enum property has an associated list of enum names which can be retrieved using the enumNames() function, and set using the corresponding setEnumNames() function. An enum property's value is represented by an index in this list, and can be retrieved and set using the value() and setValue() slots respectively.

+

Each enum value can also have an associated icon. The mapping from values to icons can be set using the setEnumIcons() function and queried with the enumIcons() function.

+

In addition, QtEnumPropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes. The enumNamesChanged() or enumIconsChanged() signal is emitted whenever the list of enum names or icons is altered.

+

See also QtAbstractPropertyManager and QtEnumEditorFactory.

+
+

Member Function Documentation

+

QtEnumPropertyManager::QtEnumPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtEnumPropertyManager::~QtEnumPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

QMap<int, QIcon> QtEnumPropertyManager::enumIcons ( const QtProperty * property ) const

+

Returns the given property's map of enum values to their icons.

+

See also value() and setEnumIcons().

+

void QtEnumPropertyManager::enumIconsChanged ( QtProperty * property, const QMap<int, QIcon> & icons )   [signal]

+

This signal is emitted whenever a property created by this manager changes its enum icons, passing a pointer to the property and the new mapping of values to icons as parameters.

+

See also setEnumIcons().

+

QStringList QtEnumPropertyManager::enumNames ( const QtProperty * property ) const

+

Returns the given property's list of enum names.

+

See also value() and setEnumNames().

+

void QtEnumPropertyManager::enumNamesChanged ( QtProperty * property, const QStringList & names )   [signal]

+

This signal is emitted whenever a property created by this manager changes its enum names, passing a pointer to the property and the new names as parameters.

+

See also setEnumNames().

+

void QtEnumPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtEnumPropertyManager::setEnumIcons ( QtProperty * property, const QMap<int, QIcon> & enumIcons )   [slot]

+

Sets the given property's map of enum values to their icons to enumIcons.

+

Each enum value can have associated icon. This association is represented with passed enumIcons map.

+

See also enumIcons(), enumNames(), and enumNamesChanged().

+

void QtEnumPropertyManager::setEnumNames ( QtProperty * property, const QStringList & enumNames )   [slot]

+

Sets the given property's list of enum names to enumNames. The property's current value is reset to 0 indicating the first item of the list.

+

If the specified enumNames list is empty, the property's current value is set to -1.

+

See also enumNames() and enumNamesChanged().

+

void QtEnumPropertyManager::setValue ( QtProperty * property, int value )   [slot]

+

Sets the value of the given property to value.

+

The specified value must be less than the size of the given property's enumNames() list, and larger than (or equal to) 0.

+

See also value() and valueChanged().

+

void QtEnumPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

int QtEnumPropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value which is an index in the list returned by enumNames()

+

If the given property is not managed by this manager, this function returns -1.

+

See also enumNames() and setValue().

+

void QtEnumPropertyManager::valueChanged ( QtProperty * property, int value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QIcon QtEnumPropertyManager::valueIcon ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueIcon().

+

QString QtEnumPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtflagpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtflagpropertymanager-members.html new file mode 100644 index 000000000..3ed3cd250 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtflagpropertymanager-members.html @@ -0,0 +1,96 @@ + + + + + + List of All Members for QtFlagPropertyManager + + + + + + + +
  Home

List of All Members for QtFlagPropertyManager

+

This is the complete list of members for QtFlagPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtflagpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtflagpropertymanager.html new file mode 100644 index 000000000..11894264c --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtflagpropertymanager.html @@ -0,0 +1,128 @@ + + + + + + QtFlagPropertyManager Class Reference + + + + + + + +
  Home

QtFlagPropertyManager Class Reference

+

The QtFlagPropertyManager provides and manages flag properties. More...

+
 #include <QtFlagPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + + +
QtFlagPropertyManager ( QObject * parent = 0 )
~QtFlagPropertyManager ()
QStringList flagNames ( const QtProperty * property ) const
QtBoolPropertyManager * subBoolPropertyManager () const
int value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + + +
void setFlagNames ( QtProperty * property, const QStringList & flagNames )
void setValue ( QtProperty * property, int value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + + +
void flagNamesChanged ( QtProperty * property, const QStringList & names )
void valueChanged ( QtProperty * property, int value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtFlagPropertyManager provides and manages flag properties.

+

Each flag property has an associated list of flag names which can be retrieved using the flagNames() function, and set using the corresponding setFlagNames() function.

+

The flag manager provides properties with nested boolean subproperties representing each flag, i.e. a flag property's value is the binary combination of the subproperties' values. A property's value can be retrieved and set using the value() and setValue() slots respectively. The combination of flags is represented by single int value - that's why it's possible to store up to 32 independent flags in one flag property.

+

The subproperties are created by a QtBoolPropertyManager object. This manager can be retrieved using the subBoolPropertyManager() function. In order to provide editing widgets for the subproperties in a property browser widget, this manager must be associated with an editor factory.

+

In addition, QtFlagPropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes, and the flagNamesChanged() signal which is emitted whenever the list of flag names is altered.

+

See also QtAbstractPropertyManager and QtBoolPropertyManager.

+
+

Member Function Documentation

+

QtFlagPropertyManager::QtFlagPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtFlagPropertyManager::~QtFlagPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

QStringList QtFlagPropertyManager::flagNames ( const QtProperty * property ) const

+

Returns the given property's list of flag names.

+

See also value() and setFlagNames().

+

void QtFlagPropertyManager::flagNamesChanged ( QtProperty * property, const QStringList & names )   [signal]

+

This signal is emitted whenever a property created by this manager changes its flag names, passing a pointer to the property and the new names as parameters.

+

See also setFlagNames().

+

void QtFlagPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtFlagPropertyManager::setFlagNames ( QtProperty * property, const QStringList & flagNames )   [slot]

+

Sets the given property's list of flag names to flagNames. The property's current value is reset to 0 indicating the first item of the list.

+

See also flagNames() and flagNamesChanged().

+

void QtFlagPropertyManager::setValue ( QtProperty * property, int value )   [slot]

+

Sets the value of the given property to value. Nested properties are updated automatically.

+

The specified value must be less than the binary combination of the property's flagNames() list size (i.e. less than 2n, where n is the size of the list) and larger than (or equal to) 0.

+

See also value() and valueChanged().

+

QtBoolPropertyManager * QtFlagPropertyManager::subBoolPropertyManager () const

+

Returns the manager that produces the nested boolean subproperties representing each flag.

+

In order to provide editing widgets for the subproperties in a property browser widget, this manager must be associated with an editor factory.

+

See also QtAbstractPropertyBrowser::setFactoryForManager().

+

void QtFlagPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

int QtFlagPropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns 0.

+

See also flagNames() and setValue().

+

void QtFlagPropertyManager::valueChanged ( QtProperty * property, int value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QString QtFlagPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtfonteditorfactory-members.html b/external/QtPropertyBrowser/doc/html/qtfonteditorfactory-members.html new file mode 100644 index 000000000..849cb2c6c --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtfonteditorfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtFontEditorFactory + + + + + + + +
  Home

List of All Members for QtFontEditorFactory

+

This is the complete list of members for QtFontEditorFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtfonteditorfactory.html b/external/QtPropertyBrowser/doc/html/qtfonteditorfactory.html new file mode 100644 index 000000000..01b88d7e5 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtfonteditorfactory.html @@ -0,0 +1,61 @@ + + + + + + QtFontEditorFactory Class Reference + + + + + + + +
  Home

QtFontEditorFactory Class Reference

+

The QtFontEditorFactory class provides font editing for properties created by QtFontPropertyManager objects. More...

+
 #include <QtFontEditorFactory>

Inherits QtAbstractEditorFactory<QtFontPropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtFontEditorFactory ( QObject * parent = 0 )
~QtFontEditorFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtFontEditorFactory class provides font editing for properties created by QtFontPropertyManager objects.

+

See also QtAbstractEditorFactory and QtFontPropertyManager.

+
+

Member Function Documentation

+

QtFontEditorFactory::QtFontEditorFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtFontEditorFactory::~QtFontEditorFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtfontpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtfontpropertymanager-members.html new file mode 100644 index 000000000..d3b76bcb1 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtfontpropertymanager-members.html @@ -0,0 +1,95 @@ + + + + + + List of All Members for QtFontPropertyManager + + + + + + + +
  Home

List of All Members for QtFontPropertyManager

+

This is the complete list of members for QtFontPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtfontpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtfontpropertymanager.html new file mode 100644 index 000000000..f5946e030 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtfontpropertymanager.html @@ -0,0 +1,127 @@ + + + + + + QtFontPropertyManager Class Reference + + + + + + + +
  Home

QtFontPropertyManager Class Reference

+

The QtFontPropertyManager provides and manages QFont properties. More...

+
 #include <QtFontPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + + + +
QtFontPropertyManager ( QObject * parent = 0 )
~QtFontPropertyManager ()
QtBoolPropertyManager * subBoolPropertyManager () const
QtEnumPropertyManager * subEnumPropertyManager () const
QtIntPropertyManager * subIntPropertyManager () const
QFont value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + +
void setValue ( QtProperty * property, const QFont & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + +
void valueChanged ( QtProperty * property, const QFont & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QIcon valueIcon ( const QtProperty * property ) const
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtFontPropertyManager provides and manages QFont properties.

+

A font property has nested family, pointSize, bold, italic, underline, strikeOut and kerning subproperties. The top-level property's value can be retrieved using the value() function, and set using the setValue() slot.

+

The subproperties are created by QtIntPropertyManager, QtEnumPropertyManager and QtBoolPropertyManager objects. These managers can be retrieved using the corresponding subIntPropertyManager(), subEnumPropertyManager() and subBoolPropertyManager() functions. In order to provide editing widgets for the subproperties in a property browser widget, these managers must be associated with editor factories.

+

In addition, QtFontPropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes.

+

See also QtAbstractPropertyManager, QtEnumPropertyManager, QtIntPropertyManager, and QtBoolPropertyManager.

+
+

Member Function Documentation

+

QtFontPropertyManager::QtFontPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtFontPropertyManager::~QtFontPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

void QtFontPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtFontPropertyManager::setValue ( QtProperty * property, const QFont & value )   [slot]

+

Sets the value of the given property to value. Nested properties are updated automatically.

+

See also value() and valueChanged().

+

QtBoolPropertyManager * QtFontPropertyManager::subBoolPropertyManager () const

+

Returns the manager that creates the bold, italic, underline, strikeOut and kerning subproperties.

+

In order to provide editing widgets for the mentioned properties in a property browser widget, this manager must be associated with an editor factory.

+

See also QtAbstractPropertyBrowser::setFactoryForManager().

+

QtEnumPropertyManager * QtFontPropertyManager::subEnumPropertyManager () const

+

Returns the manager that create the family subproperty.

+

In order to provide editing widgets for the family property in a property browser widget, this manager must be associated with an editor factory.

+

See also QtAbstractPropertyBrowser::setFactoryForManager().

+

QtIntPropertyManager * QtFontPropertyManager::subIntPropertyManager () const

+

Returns the manager that creates the pointSize subproperty.

+

In order to provide editing widgets for the pointSize property in a property browser widget, this manager must be associated with an editor factory.

+

See also QtAbstractPropertyBrowser::setFactoryForManager().

+

void QtFontPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QFont QtFontPropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns a font object that uses the application's default font.

+

See also setValue().

+

void QtFontPropertyManager::valueChanged ( QtProperty * property, const QFont & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QIcon QtFontPropertyManager::valueIcon ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueIcon().

+

QString QtFontPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtgroupboxpropertybrowser-members.html b/external/QtPropertyBrowser/doc/html/qtgroupboxpropertybrowser-members.html new file mode 100644 index 000000000..7ce0783a5 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtgroupboxpropertybrowser-members.html @@ -0,0 +1,384 @@ + + + + + + List of All Members for QtGroupBoxPropertyBrowser + + + + + + + +
  Home

List of All Members for QtGroupBoxPropertyBrowser

+

This is the complete list of members for QtGroupBoxPropertyBrowser, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtgroupboxpropertybrowser.html b/external/QtPropertyBrowser/doc/html/qtgroupboxpropertybrowser.html new file mode 100644 index 000000000..0af7bc0a5 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtgroupboxpropertybrowser.html @@ -0,0 +1,97 @@ + + + + + + QtGroupBoxPropertyBrowser Class Reference + + + + + + + +
  Home

QtGroupBoxPropertyBrowser Class Reference

+

The QtGroupBoxPropertyBrowser class provides a QGroupBox based property browser. More...

+
 #include <QtGroupBoxPropertyBrowser>

Inherits QtAbstractPropertyBrowser.

+ +
+ +

Public Functions

+ + + +
QtGroupBoxPropertyBrowser ( QWidget * parent = 0 )
~QtGroupBoxPropertyBrowser ()
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void itemChanged ( QtBrowserItem * item )
virtual void itemInserted ( QtBrowserItem * item, QtBrowserItem * afterItem )
virtual void itemRemoved ( QtBrowserItem * item )
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtGroupBoxPropertyBrowser class provides a QGroupBox based property browser.

+

A property browser is a widget that enables the user to edit a given set of properties. Each property is represented by a label specifying the property's name, and an editing widget (e.g. a line edit or a combobox) holding its value. A property can have zero or more subproperties.

+

QtGroupBoxPropertyBrowser provides group boxes for all nested properties, i.e. subproperties are enclosed by a group box with the parent property's name as its title. For example:

+

Use the QtAbstractPropertyBrowser API to add, insert and remove properties from an instance of the QtGroupBoxPropertyBrowser class. The properties themselves are created and managed by implementations of the QtAbstractPropertyManager class.

+

See also QtTreePropertyBrowser and QtAbstractPropertyBrowser.

+
+

Member Function Documentation

+

QtGroupBoxPropertyBrowser::QtGroupBoxPropertyBrowser ( QWidget * parent = 0 )

+

Creates a property browser with the given parent.

+

QtGroupBoxPropertyBrowser::~QtGroupBoxPropertyBrowser ()

+

Destroys this property browser.

+

Note that the properties that were inserted into this browser are not destroyed since they may still be used in other browsers. The properties are owned by the manager that created them.

+

See also QtProperty and QtAbstractPropertyManager.

+

void QtGroupBoxPropertyBrowser::itemChanged ( QtBrowserItem * item )   [virtual protected]

+

Reimplemented from QtAbstractPropertyBrowser::itemChanged().

+

void QtGroupBoxPropertyBrowser::itemInserted ( QtBrowserItem * item, QtBrowserItem * afterItem )   [virtual protected]

+

Reimplemented from QtAbstractPropertyBrowser::itemInserted().

+

void QtGroupBoxPropertyBrowser::itemRemoved ( QtBrowserItem * item )   [virtual protected]

+

Reimplemented from QtAbstractPropertyBrowser::itemRemoved().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtgrouppropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtgrouppropertymanager-members.html new file mode 100644 index 000000000..fc17939ec --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtgrouppropertymanager-members.html @@ -0,0 +1,89 @@ + + + + + + List of All Members for QtGroupPropertyManager + + + + + + + +
  Home

List of All Members for QtGroupPropertyManager

+

This is the complete list of members for QtGroupPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtgrouppropertymanager.html b/external/QtPropertyBrowser/doc/html/qtgrouppropertymanager.html new file mode 100644 index 000000000..84e595e4e --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtgrouppropertymanager.html @@ -0,0 +1,80 @@ + + + + + + QtGroupPropertyManager Class Reference + + + + + + + +
  Home

QtGroupPropertyManager Class Reference

+

The QtGroupPropertyManager provides and manages group properties. More...

+
 #include <QtGroupPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + +
QtGroupPropertyManager ( QObject * parent = 0 )
~QtGroupPropertyManager ()
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual bool hasValue ( const QtProperty * property ) const
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtGroupPropertyManager provides and manages group properties.

+

This class is intended to provide a grouping element without any value.

+

See also QtAbstractPropertyManager.

+
+

Member Function Documentation

+

QtGroupPropertyManager::QtGroupPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtGroupPropertyManager::~QtGroupPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

bool QtGroupPropertyManager::hasValue ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::hasValue().

+

void QtGroupPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtGroupPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtintpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtintpropertymanager-members.html new file mode 100644 index 000000000..23411b185 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtintpropertymanager-members.html @@ -0,0 +1,101 @@ + + + + + + List of All Members for QtIntPropertyManager + + + + + + + +
  Home

List of All Members for QtIntPropertyManager

+

This is the complete list of members for QtIntPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtintpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtintpropertymanager.html new file mode 100644 index 000000000..801cc3a82 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtintpropertymanager.html @@ -0,0 +1,152 @@ + + + + + + QtIntPropertyManager Class Reference + + + + + + + +
  Home

QtIntPropertyManager Class Reference

+

The QtIntPropertyManager provides and manages int properties. More...

+
 #include <QtIntPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + + + +
QtIntPropertyManager ( QObject * parent = 0 )
~QtIntPropertyManager ()
int maximum ( const QtProperty * property ) const
int minimum ( const QtProperty * property ) const
int singleStep ( const QtProperty * property ) const
int value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + + + + + +
void setMaximum ( QtProperty * property, int maxVal )
void setMinimum ( QtProperty * property, int minVal )
void setRange ( QtProperty * property, int minimum, int maximum )
void setSingleStep ( QtProperty * property, int step )
void setValue ( QtProperty * property, int value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + + + +
void rangeChanged ( QtProperty * property, int minimum, int maximum )
void singleStepChanged ( QtProperty * property, int step )
void valueChanged ( QtProperty * property, int value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtIntPropertyManager provides and manages int properties.

+

An int property has a current value, and a range specifying the valid values. The range is defined by a minimum and a maximum value.

+

The property's value and range can be retrieved using the value(), minimum() and maximum() functions, and can be set using the setValue(), setMinimum() and setMaximum() slots. Alternatively, the range can be defined in one go using the setRange() slot.

+

In addition, QtIntPropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes, and the rangeChanged() signal which is emitted whenever such a property changes its range of valid values.

+

See also QtAbstractPropertyManager, QtSpinBoxFactory, QtSliderFactory, and QtScrollBarFactory.

+
+

Member Function Documentation

+

QtIntPropertyManager::QtIntPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtIntPropertyManager::~QtIntPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

void QtIntPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

int QtIntPropertyManager::maximum ( const QtProperty * property ) const

+

Returns the given property's maximum value.

+

See also setMaximum(), minimum(), and setRange().

+

int QtIntPropertyManager::minimum ( const QtProperty * property ) const

+

Returns the given property's minimum value.

+

See also setMinimum(), maximum(), and setRange().

+

void QtIntPropertyManager::rangeChanged ( QtProperty * property, int minimum, int maximum )   [signal]

+

This signal is emitted whenever a property created by this manager changes its range of valid values, passing a pointer to the property and the new minimum and maximum values.

+

See also setRange().

+

void QtIntPropertyManager::setMaximum ( QtProperty * property, int maxVal )   [slot]

+

Sets the maximum value for the given property to maxVal.

+

When setting maximum value, the minimum and current values are adjusted if necessary (ensuring that the range remains valid and that the current value is within the range).

+

See also maximum(), setRange(), and rangeChanged().

+

void QtIntPropertyManager::setMinimum ( QtProperty * property, int minVal )   [slot]

+

Sets the minimum value for the given property to minVal.

+

When setting the minimum value, the maximum and current values are adjusted if necessary (ensuring that the range remains valid and that the current value is within the range).

+

See also minimum(), setRange(), and rangeChanged().

+

void QtIntPropertyManager::setRange ( QtProperty * property, int minimum, int maximum )   [slot]

+

Sets the range of valid values.

+

This is a convenience function defining the range of valid values in one go; setting the minimum and maximum values for the given property with a single function call.

+

When setting a new range, the current value is adjusted if necessary (ensuring that the value remains within range).

+

See also setMinimum(), setMaximum(), and rangeChanged().

+

void QtIntPropertyManager::setSingleStep ( QtProperty * property, int step )   [slot]

+

Sets the step value for the given property to step.

+

The step is typically used to increment or decrement a property value while pressing an arrow key.

+

See also singleStep().

+

void QtIntPropertyManager::setValue ( QtProperty * property, int value )   [slot]

+

Sets the value of the given property to value.

+

If the specified value is not valid according to the given property's range, the value is adjusted to the nearest valid value within the range.

+

See also value(), setRange(), and valueChanged().

+

int QtIntPropertyManager::singleStep ( const QtProperty * property ) const

+

Returns the given property's step value.

+

The step is typically used to increment or decrement a property value while pressing an arrow key.

+

See also setSingleStep().

+

void QtIntPropertyManager::singleStepChanged ( QtProperty * property, int step )   [signal]

+

This signal is emitted whenever a property created by this manager changes its single step property, passing a pointer to the property and the new step value

+

See also setSingleStep().

+

void QtIntPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

int QtIntPropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns 0.

+

See also setValue().

+

void QtIntPropertyManager::valueChanged ( QtProperty * property, int value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QString QtIntPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtkeysequenceeditorfactory-members.html b/external/QtPropertyBrowser/doc/html/qtkeysequenceeditorfactory-members.html new file mode 100644 index 000000000..c7422e452 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtkeysequenceeditorfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtKeySequenceEditorFactory + + + + + + + +
  Home

List of All Members for QtKeySequenceEditorFactory

+

This is the complete list of members for QtKeySequenceEditorFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtkeysequenceeditorfactory.html b/external/QtPropertyBrowser/doc/html/qtkeysequenceeditorfactory.html new file mode 100644 index 000000000..80934d40d --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtkeysequenceeditorfactory.html @@ -0,0 +1,61 @@ + + + + + + QtKeySequenceEditorFactory Class Reference + + + + + + + +
  Home

QtKeySequenceEditorFactory Class Reference

+

The QtKeySequenceEditorFactory class provides editor widgets for properties created by QtKeySequencePropertyManager objects. More...

+
 #include <QtKeySequenceEditorFactory>

Inherits QtAbstractEditorFactory<QtKeySequencePropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtKeySequenceEditorFactory ( QObject * parent = 0 )
~QtKeySequenceEditorFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtKeySequenceEditorFactory class provides editor widgets for properties created by QtKeySequencePropertyManager objects.

+

See also QtAbstractEditorFactory.

+
+

Member Function Documentation

+

QtKeySequenceEditorFactory::QtKeySequenceEditorFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtKeySequenceEditorFactory::~QtKeySequenceEditorFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtkeysequencepropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtkeysequencepropertymanager-members.html new file mode 100644 index 000000000..729bd9c75 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtkeysequencepropertymanager-members.html @@ -0,0 +1,92 @@ + + + + + + List of All Members for QtKeySequencePropertyManager + + + + + + + +
  Home

List of All Members for QtKeySequencePropertyManager

+

This is the complete list of members for QtKeySequencePropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtkeysequencepropertymanager.html b/external/QtPropertyBrowser/doc/html/qtkeysequencepropertymanager.html new file mode 100644 index 000000000..c99e73420 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtkeysequencepropertymanager.html @@ -0,0 +1,107 @@ + + + + + + QtKeySequencePropertyManager Class Reference + + + + + + + +
  Home

QtKeySequencePropertyManager Class Reference

+

The QtKeySequencePropertyManager provides and manages QKeySequence properties. More...

+
 #include <QtKeySequencePropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + +
QtKeySequencePropertyManager ( QObject * parent = 0 )
~QtKeySequencePropertyManager ()
QKeySequence value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + +
void setValue ( QtProperty * property, const QKeySequence & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + +
void valueChanged ( QtProperty * property, const QKeySequence & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtKeySequencePropertyManager provides and manages QKeySequence properties.

+

A key sequence's value can be retrieved using the value() function, and set using the setValue() slot.

+

In addition, QtKeySequencePropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes.

+

See also QtAbstractPropertyManager.

+
+

Member Function Documentation

+

QtKeySequencePropertyManager::QtKeySequencePropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtKeySequencePropertyManager::~QtKeySequencePropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

void QtKeySequencePropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtKeySequencePropertyManager::setValue ( QtProperty * property, const QKeySequence & value )   [slot]

+

Sets the value of the given property to value.

+

See also value() and valueChanged().

+

void QtKeySequencePropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QKeySequence QtKeySequencePropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns an empty QKeySequence object.

+

See also setValue().

+

void QtKeySequencePropertyManager::valueChanged ( QtProperty * property, const QKeySequence & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

QString QtKeySequencePropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtlineeditfactory-members.html b/external/QtPropertyBrowser/doc/html/qtlineeditfactory-members.html new file mode 100644 index 000000000..b61d7355c --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtlineeditfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtLineEditFactory + + + + + + + +
  Home

List of All Members for QtLineEditFactory

+

This is the complete list of members for QtLineEditFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtlineeditfactory.html b/external/QtPropertyBrowser/doc/html/qtlineeditfactory.html new file mode 100644 index 000000000..ee158dde7 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtlineeditfactory.html @@ -0,0 +1,61 @@ + + + + + + QtLineEditFactory Class Reference + + + + + + + +
  Home

QtLineEditFactory Class Reference

+

The QtLineEditFactory class provides QLineEdit widgets for properties created by QtStringPropertyManager objects. More...

+
 #include <QtLineEditFactory>

Inherits QtAbstractEditorFactory<QtStringPropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtLineEditFactory ( QObject * parent = 0 )
~QtLineEditFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtLineEditFactory class provides QLineEdit widgets for properties created by QtStringPropertyManager objects.

+

See also QtAbstractEditorFactory and QtStringPropertyManager.

+
+

Member Function Documentation

+

QtLineEditFactory::QtLineEditFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtLineEditFactory::~QtLineEditFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtlocalepropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtlocalepropertymanager-members.html new file mode 100644 index 000000000..63b36c388 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtlocalepropertymanager-members.html @@ -0,0 +1,93 @@ + + + + + + List of All Members for QtLocalePropertyManager + + + + + + + +
  Home

List of All Members for QtLocalePropertyManager

+

This is the complete list of members for QtLocalePropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtlocalepropertymanager.html b/external/QtPropertyBrowser/doc/html/qtlocalepropertymanager.html new file mode 100644 index 000000000..d8ed3e915 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtlocalepropertymanager.html @@ -0,0 +1,114 @@ + + + + + + QtLocalePropertyManager Class Reference + + + + + + + +
  Home

QtLocalePropertyManager Class Reference

+

The QtLocalePropertyManager provides and manages QLocale properties. More...

+
 #include <QtLocalePropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + +
QtLocalePropertyManager ( QObject * parent = 0 )
~QtLocalePropertyManager ()
QtEnumPropertyManager * subEnumPropertyManager () const
QLocale value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + +
void setValue ( QtProperty * property, const QLocale & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + +
void valueChanged ( QtProperty * property, const QLocale & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtLocalePropertyManager provides and manages QLocale properties.

+

A locale property has nested language and country subproperties. The top-level property's value can be retrieved using the value() function, and set using the setValue() slot.

+

The subproperties are created by QtEnumPropertyManager object. These submanager can be retrieved using the subEnumPropertyManager() function. In order to provide editing widgets for the subproperties in a property browser widget, this manager must be associated with editor factory.

+

In addition, QtLocalePropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes.

+

See also QtAbstractPropertyManager and QtEnumPropertyManager.

+
+

Member Function Documentation

+

QtLocalePropertyManager::QtLocalePropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtLocalePropertyManager::~QtLocalePropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

void QtLocalePropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtLocalePropertyManager::setValue ( QtProperty * property, const QLocale & value )   [slot]

+

Sets the value of the given property to value. Nested properties are updated automatically.

+

See also value() and valueChanged().

+

QtEnumPropertyManager * QtLocalePropertyManager::subEnumPropertyManager () const

+

Returns the manager that creates the nested language and country subproperties.

+

In order to provide editing widgets for the mentioned subproperties in a property browser widget, this manager must be associated with an editor factory.

+

See also QtAbstractPropertyBrowser::setFactoryForManager().

+

void QtLocalePropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QLocale QtLocalePropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns the default locale.

+

See also setValue().

+

void QtLocalePropertyManager::valueChanged ( QtProperty * property, const QLocale & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QString QtLocalePropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtpointfpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtpointfpropertymanager-members.html new file mode 100644 index 000000000..d71dc42df --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtpointfpropertymanager-members.html @@ -0,0 +1,96 @@ + + + + + + List of All Members for QtPointFPropertyManager + + + + + + + +
  Home

List of All Members for QtPointFPropertyManager

+

This is the complete list of members for QtPointFPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtpointfpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtpointfpropertymanager.html new file mode 100644 index 000000000..0af61eaf5 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtpointfpropertymanager.html @@ -0,0 +1,127 @@ + + + + + + QtPointFPropertyManager Class Reference + + + + + + + +
  Home

QtPointFPropertyManager Class Reference

+

The QtPointFPropertyManager provides and manages QPointF properties. More...

+
 #include <QtPointFPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + + +
QtPointFPropertyManager ( QObject * parent = 0 )
~QtPointFPropertyManager ()
int decimals ( const QtProperty * property ) const
QtDoublePropertyManager * subDoublePropertyManager () const
QPointF value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + + +
void setDecimals ( QtProperty * property, int prec )
void setValue ( QtProperty * property, const QPointF & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + + +
void decimalsChanged ( QtProperty * property, int prec )
void valueChanged ( QtProperty * property, const QPointF & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtPointFPropertyManager provides and manages QPointF properties.

+

A point property has nested x and y subproperties. The top-level property's value can be retrieved using the value() function, and set using the setValue() slot.

+

The subproperties are created by a QtDoublePropertyManager object. This manager can be retrieved using the subDoublePropertyManager() function. In order to provide editing widgets for the subproperties in a property browser widget, this manager must be associated with an editor factory.

+

In addition, QtPointFPropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes.

+

See also QtAbstractPropertyManager, QtDoublePropertyManager, and QtPointPropertyManager.

+
+

Member Function Documentation

+

QtPointFPropertyManager::QtPointFPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtPointFPropertyManager::~QtPointFPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

int QtPointFPropertyManager::decimals ( const QtProperty * property ) const

+

Returns the given property's precision, in decimals.

+

See also setDecimals().

+

void QtPointFPropertyManager::decimalsChanged ( QtProperty * property, int prec )   [signal]

+

This signal is emitted whenever a property created by this manager changes its precision of value, passing a pointer to the property and the new prec value

+

See also setDecimals().

+

void QtPointFPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtPointFPropertyManager::setDecimals ( QtProperty * property, int prec )   [slot]

+

Sets the precision of the given property to prec.

+

The valid decimal range is 0-13. The default is 2.

+

See also decimals().

+

void QtPointFPropertyManager::setValue ( QtProperty * property, const QPointF & value )   [slot]

+

Sets the value of the given property to value. Nested properties are updated automatically.

+

See also value() and valueChanged().

+

QtDoublePropertyManager * QtPointFPropertyManager::subDoublePropertyManager () const

+

Returns the manager that creates the nested x and y subproperties.

+

In order to provide editing widgets for the subproperties in a property browser widget, this manager must be associated with an editor factory.

+

See also QtAbstractPropertyBrowser::setFactoryForManager().

+

void QtPointFPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QPointF QtPointFPropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns a point with coordinates (0, 0).

+

See also setValue().

+

void QtPointFPropertyManager::valueChanged ( QtProperty * property, const QPointF & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QString QtPointFPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtpointpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtpointpropertymanager-members.html new file mode 100644 index 000000000..109c42784 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtpointpropertymanager-members.html @@ -0,0 +1,93 @@ + + + + + + List of All Members for QtPointPropertyManager + + + + + + + +
  Home

List of All Members for QtPointPropertyManager

+

This is the complete list of members for QtPointPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtpointpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtpointpropertymanager.html new file mode 100644 index 000000000..1ff21ffbd --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtpointpropertymanager.html @@ -0,0 +1,114 @@ + + + + + + QtPointPropertyManager Class Reference + + + + + + + +
  Home

QtPointPropertyManager Class Reference

+

The QtPointPropertyManager provides and manages QPoint properties. More...

+
 #include <QtPointPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + +
QtPointPropertyManager ( QObject * parent = 0 )
~QtPointPropertyManager ()
QtIntPropertyManager * subIntPropertyManager () const
QPoint value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + +
void setValue ( QtProperty * property, const QPoint & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + +
void valueChanged ( QtProperty * property, const QPoint & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtPointPropertyManager provides and manages QPoint properties.

+

A point property has nested x and y subproperties. The top-level property's value can be retrieved using the value() function, and set using the setValue() slot.

+

The subproperties are created by a QtIntPropertyManager object. This manager can be retrieved using the subIntPropertyManager() function. In order to provide editing widgets for the subproperties in a property browser widget, this manager must be associated with an editor factory.

+

In addition, QtPointPropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes.

+

See also QtAbstractPropertyManager, QtIntPropertyManager, and QtPointFPropertyManager.

+
+

Member Function Documentation

+

QtPointPropertyManager::QtPointPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtPointPropertyManager::~QtPointPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

void QtPointPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtPointPropertyManager::setValue ( QtProperty * property, const QPoint & value )   [slot]

+

Sets the value of the given property to value. Nested properties are updated automatically.

+

See also value() and valueChanged().

+

QtIntPropertyManager * QtPointPropertyManager::subIntPropertyManager () const

+

Returns the manager that creates the nested x and y subproperties.

+

In order to provide editing widgets for the subproperties in a property browser widget, this manager must be associated with an editor factory.

+

See also QtAbstractPropertyBrowser::setFactoryForManager().

+

void QtPointPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QPoint QtPointPropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns a point with coordinates (0, 0).

+

See also setValue().

+

void QtPointPropertyManager::valueChanged ( QtProperty * property, const QPoint & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QString QtPointPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtproperty-members.html b/external/QtPropertyBrowser/doc/html/qtproperty-members.html new file mode 100644 index 000000000..a1d5565a5 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtproperty-members.html @@ -0,0 +1,51 @@ + + + + + + List of All Members for QtProperty + + + + + + + +
  Home

List of All Members for QtProperty

+

This is the complete list of members for QtProperty, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtproperty.html b/external/QtPropertyBrowser/doc/html/qtproperty.html new file mode 100644 index 000000000..1ca827957 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtproperty.html @@ -0,0 +1,152 @@ + + + + + + QtProperty Class Reference + + + + + + + +
  Home

QtProperty Class Reference

+

The QtProperty class encapsulates an instance of a property. More...

+
 #include <QtProperty>

Inherited by QtVariantProperty.

+ +
+ +

Public Functions

+ + + + + + + + + + + + + + + + + + + + + + +
virtual ~QtProperty ()
void addSubProperty ( QtProperty * property )
bool hasValue () const
void insertSubProperty ( QtProperty * property, QtProperty * precedingProperty )
bool isEnabled () const
bool isModified () const
QtAbstractPropertyManager * propertyManager () const
QString propertyName () const
void removeSubProperty ( QtProperty * property )
void setEnabled ( bool enable )
void setModified ( bool modified )
void setPropertyName ( const QString & name )
void setStatusTip ( const QString & text )
void setToolTip ( const QString & text )
void setWhatsThis ( const QString & text )
QString statusTip () const
QList<QtProperty *> subProperties () const
QString toolTip () const
QIcon valueIcon () const
QString valueText () const
QString whatsThis () const
+
+ +

Protected Functions

+ + +
QtProperty ( QtAbstractPropertyManager * manager )
+ +
+

Detailed Description

+

The QtProperty class encapsulates an instance of a property.

+

Properties are created by objects of QtAbstractPropertyManager subclasses; a manager can create properties of a given type, and is used in conjunction with the QtAbstractPropertyBrowser class. A property is always owned by the manager that created it, which can be retrieved using the propertyManager() function.

+

QtProperty contains the most common property attributes, and provides functions for retrieving as well as setting their values:

+

+ + + + + + + + + +
GetterSetter
propertyName()setPropertyName()
statusTip()setStatusTip()
toolTip()setToolTip()
whatsThis()setWhatsThis()
isEnabled()setEnabled()
isModified()setModified()
valueText()Nop
valueIcon()Nop

+

It is also possible to nest properties: QtProperty provides the addSubProperty(), insertSubProperty() and removeSubProperty() functions to manipulate the set of subproperties. Use the subProperties() function to retrieve a property's current set of subproperties. Note that nested properties are not owned by the parent property, i.e. each subproperty is owned by the manager that created it.

+

See also QtAbstractPropertyManager and QtBrowserItem.

+
+

Member Function Documentation

+

QtProperty::QtProperty ( QtAbstractPropertyManager * manager )   [protected]

+

Creates a property with the given manager.

+

This constructor is only useful when creating a custom QtProperty subclass (e.g. QtVariantProperty). To create a regular QtProperty object, use the QtAbstractPropertyManager::addProperty() function instead.

+

See also QtAbstractPropertyManager::addProperty().

+

QtProperty::~QtProperty ()   [virtual]

+

Destroys this property.

+

Note that subproperties are detached but not destroyed, i.e. they can still be used in another context.

+

See also QtAbstractPropertyManager::clear().

+

void QtProperty::addSubProperty ( QtProperty * property )

+

Appends the given property to this property's subproperties.

+

If the given property already is added, this function does nothing.

+

See also insertSubProperty() and removeSubProperty().

+

bool QtProperty::hasValue () const

+

Returns whether the property has a value.

+

See also QtAbstractPropertyManager::hasValue().

+

void QtProperty::insertSubProperty ( QtProperty * property, QtProperty * precedingProperty )

+

Inserts the given property after the specified precedingProperty into this property's list of subproperties. If precedingProperty is 0, the specified property is inserted at the beginning of the list.

+

If the given property already is inserted, this function does nothing.

+

See also addSubProperty() and removeSubProperty().

+

bool QtProperty::isEnabled () const

+

Returns whether the property is enabled.

+

See also setEnabled().

+

bool QtProperty::isModified () const

+

Returns whether the property is modified.

+

See also setModified().

+

QtAbstractPropertyManager * QtProperty::propertyManager () const

+

Returns a pointer to the manager that owns this property.

+

QString QtProperty::propertyName () const

+

Returns the property's name.

+

See also setPropertyName().

+

void QtProperty::removeSubProperty ( QtProperty * property )

+

Removes the given property from the list of subproperties without deleting it.

+

See also addSubProperty() and insertSubProperty().

+

void QtProperty::setEnabled ( bool enable )

+

Enables or disables the property according to the passed enable value.

+

See also isEnabled().

+

void QtProperty::setModified ( bool modified )

+

Sets the property's modified state according to the passed modified value.

+

See also isModified().

+

void QtProperty::setPropertyName ( const QString & name )

+

Sets the property's name to the given name.

+

See also propertyName().

+

void QtProperty::setStatusTip ( const QString & text )

+

Sets the property's status tip to the given text.

+

See also statusTip().

+

void QtProperty::setToolTip ( const QString & text )

+

Sets the property's tool tip to the given text.

+

See also toolTip().

+

void QtProperty::setWhatsThis ( const QString & text )

+

Sets the property's "What's This" help text to the given text.

+

See also whatsThis().

+

QString QtProperty::statusTip () const

+

Returns the property's status tip.

+

See also setStatusTip().

+

QList<QtProperty *> QtProperty::subProperties () const

+

Returns the set of subproperties.

+

Note that subproperties are not owned by this property, but by the manager that created them.

+

See also insertSubProperty() and removeSubProperty().

+

QString QtProperty::toolTip () const

+

Returns the property's tool tip.

+

See also setToolTip().

+

QIcon QtProperty::valueIcon () const

+

Returns an icon representing the current state of this property.

+

If the given property type can not generate such an icon, this function returns an invalid icon.

+

See also QtAbstractPropertyManager::valueIcon().

+

QString QtProperty::valueText () const

+

Returns a string representing the current state of this property.

+

If the given property type can not generate such a string, this function returns an empty string.

+

See also QtAbstractPropertyManager::valueText().

+

QString QtProperty::whatsThis () const

+

Returns the property's "What's This" help text.

+

See also setWhatsThis().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-canvas-typed.html b/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-canvas-typed.html new file mode 100644 index 000000000..0d66013d2 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-canvas-typed.html @@ -0,0 +1,49 @@ + + + + + + Type Based Canvas Example + + + + + + + +
  Home

Type Based Canvas Example
+

+

This example demonstrates how to use different QtAbstractPropertyManager subclasses for different property types. Using this approach, the developer interfaces with a type-safe API (since each manager has its own property-type specific API).

+

The example presents a canvas filled up with items of different types, and a tree property browser which displays the currently selected item's properties.

+

All item types has a few common properties like "Position X", "Position Y" or "Position Z", but each type also adds its own type-specific properties (e.g. the text items provide "Text" and "Font" properties, and the line items provide a "Vector" property).

+

The source files can be found in examples/canvas_typed directory of the package.

+ +

Third party copyright notice

+

The canvas class used in this example contains third party code with the following copyright notice:

+
 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                         All Rights Reserved
+
+ Permission to use, copy, modify, and distribute this software and its
+ documentation for any purpose and without fee is hereby granted,
+ provided that the above copyright notice appear in all copies and that
+ both that copyright notice and this permission notice appear in
+ supporting documentation, and that the name of Digital not be
+ used in advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ SOFTWARE.
+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-canvas-variant.html b/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-canvas-variant.html new file mode 100644 index 000000000..b63f9aa8c --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-canvas-variant.html @@ -0,0 +1,49 @@ + + + + + + Variant Based Canvas Example + + + + + + + +
  Home

Variant Based Canvas Example
+

+

This example demonstrates how to use the QtVariantPropertyManager convenience class for all property types. In this approach only one instance of the property manager class is used, and the developer interfaces with a dynamic API based on QVariant.

+

The example presents a canvas filled up with items of different types, and a tree property browser which displays the currently selected item's properties.

+

All item types has a few common properties like "Position X", "Position Y" or "Position Z", but each type also adds its own type-specific properties (e.g. the text items provide "Text" and "Font" properties, and the line items provide a "Vector" property).

+

The source files can be found in examples/canvas_variant directory of the package.

+ +

Third party copyright notice

+

The canvas class used in this example contains third party code with the following copyright notice:

+
 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                         All Rights Reserved
+
+ Permission to use, copy, modify, and distribute this software and its
+ documentation for any purpose and without fee is hereby granted,
+ provided that the above copyright notice appear in all copies and that
+ both that copyright notice and this permission notice appear in
+ supporting documentation, and that the name of Digital not be
+ used in advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ SOFTWARE.
+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-decoration.html b/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-decoration.html new file mode 100644 index 000000000..1657e5d9c --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-decoration.html @@ -0,0 +1,26 @@ + + + + + + Decoration Example + + + + + + + +
  Home

Decoration Example
+

+

This example demonstrates how to decorate the existing QtDoublePropertyManager class with additional responsibilities.

+

It also shows how to write respective editor factory for decorated manager by delegating common responsibilities of undecorated base manager to the aggregated QtDoubleSpinBoxFactory member.

+

The source files can be found in examples/decoration directory of the package.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-demo.html b/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-demo.html new file mode 100644 index 000000000..44a8effda --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-demo.html @@ -0,0 +1,27 @@ + + + + + + Demo Example + + + + + + + +
  Home

Demo Example
+

+

This example shows how to customize a property browser widget's appearance and behavior.

+

The various property browsers presented in this example display the same set of properties, and are implementations of the QtTreePropertyBrowser class and the QtGroupBoxPropertyBrowser class, respectively.

+

The example shows how a property browser's appearance and behavior can be varied using the QtPropertyBrowser framework's property managers and editor factories.

+

The source files can be found in examples/demo directory of the package.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-extension.html b/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-extension.html new file mode 100644 index 000000000..0622df067 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-extension.html @@ -0,0 +1,26 @@ + + + + + + Extension Example + + + + + + + +
  Home

Extension Example
+

+

This example demonstrates how to extend the QtVariantPropertyManager class to handle additional property types.

+

The variant manager is extended to handle the QPointF type.

+

The source files can be found in examples/extension directory of the package.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-object-controller.html b/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-object-controller.html new file mode 100644 index 000000000..d4ab8cb47 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-object-controller.html @@ -0,0 +1,25 @@ + + + + + + The Object Controller Example. + + + + + + + +
  Home

The Object Controller Example.
+

+

This example implements a simple widget component which shows QObject's and its subclasses' properties. The user can modify these properies interacively and the object controller applies the changes to the controlled object. The object controller is similar to the property editor used in QDesigner application. To control the object just instantiate ObjectController, set controlled object (any QObject subclass) by calling ObjectController::setObject() and show the controller.

+

The source files can be found in examples/object_controller directory of the package.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-simple.html b/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-simple.html new file mode 100644 index 000000000..64bf7f0fe --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtpropertybrowser-example-simple.html @@ -0,0 +1,25 @@ + + + + + + Simple Tree Property Browser Example + + + + + + + +
  Home

Simple Tree Property Browser Example
+

+

This example shows how to present various properties using a simple tree property browser, i.e. an implementation of the QtTreePropertyBrowser class.

+

The source files can be found in examples/simple directory of the package.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtpropertybrowser.dcf b/external/QtPropertyBrowser/doc/html/qtpropertybrowser.dcf new file mode 100644 index 000000000..9e2531605 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtpropertybrowser.dcf @@ -0,0 +1,586 @@ + + +
+
+ QtAbstractEditorFactory + addPropertyManager + connectPropertyManager + createEditor + disconnectPropertyManager + propertyManager + propertyManagers + removePropertyManager +
+
+
+ QtAbstractEditorFactoryBase + createEditor +
+
+
+ QtAbstractPropertyBrowser + addProperty + clear + createEditor + currentItem + currentItemChanged + insertProperty + itemChanged + itemInserted + itemRemoved + items + properties + removeProperty + setCurrentItem + setFactoryForManager + topLevelItem + topLevelItems + unsetFactoryForManager +
+
+
+ QtAbstractPropertyManager + addProperty + clear + createProperty + hasValue + initializeProperty + properties + propertyChanged + propertyDestroyed + propertyInserted + propertyRemoved + uninitializeProperty + valueIcon + valueText +
+
+
+ QtBoolPropertyManager + initializeProperty + setValue + uninitializeProperty + value + valueChanged + valueIcon + valueText +
+
+
+ QtBrowserItem + browser + children + parent + property +
+
+
+ QtButtonPropertyBrowser + collapsed + expanded + isExpanded + itemChanged + itemInserted + itemRemoved + setExpanded +
+
+
+ QtCharEditorFactory +
+
+
+ QtCharPropertyManager + initializeProperty + setValue + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtCheckBoxFactory +
+
+
+ QtColorEditorFactory +
+
+
+ QtColorPropertyManager + initializeProperty + setValue + subIntPropertyManager + uninitializeProperty + value + valueChanged + valueIcon + valueText +
+
+
+ QtCursorEditorFactory +
+
+
+ QtCursorPropertyManager + initializeProperty + setValue + uninitializeProperty + value + valueChanged + valueIcon + valueText +
+
+
+ QtDateEditFactory +
+
+
+ QtDatePropertyManager + initializeProperty + maximum + minimum + rangeChanged + setMaximum + setMinimum + setRange + setValue + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtDateTimeEditFactory +
+
+
+ QtDateTimePropertyManager + initializeProperty + setValue + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtDoublePropertyManager + decimals + decimalsChanged + initializeProperty + maximum + minimum + rangeChanged + setDecimals + setMaximum + setMinimum + setRange + setSingleStep + setValue + singleStep + singleStepChanged + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtDoubleSpinBoxFactory +
+
+
+ QtEnumEditorFactory +
+
+
+ QtEnumPropertyManager + enumIcons + enumIconsChanged + enumNames + enumNamesChanged + initializeProperty + setEnumIcons + setEnumNames + setValue + uninitializeProperty + value + valueChanged + valueIcon + valueText +
+
+
+ QtFlagPropertyManager + flagNames + flagNamesChanged + initializeProperty + setFlagNames + setValue + subBoolPropertyManager + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtFontEditorFactory +
+
+
+ QtFontPropertyManager + initializeProperty + setValue + subBoolPropertyManager + subEnumPropertyManager + subIntPropertyManager + uninitializeProperty + value + valueChanged + valueIcon + valueText +
+
+
+ QtGroupBoxPropertyBrowser + itemChanged + itemInserted + itemRemoved +
+
+
+ QtGroupPropertyManager + hasValue + initializeProperty + uninitializeProperty +
+
+
+ QtIntPropertyManager + initializeProperty + maximum + minimum + rangeChanged + setMaximum + setMinimum + setRange + setSingleStep + setValue + singleStep + singleStepChanged + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtKeySequenceEditorFactory +
+
+
+ QtKeySequencePropertyManager + initializeProperty + setValue + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtLineEditFactory +
+
+
+ QtLocalePropertyManager + initializeProperty + setValue + subEnumPropertyManager + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtPointFPropertyManager + decimals + decimalsChanged + initializeProperty + setDecimals + setValue + subDoublePropertyManager + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtPointPropertyManager + initializeProperty + setValue + subIntPropertyManager + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtProperty + addSubProperty + hasValue + insertSubProperty + isEnabled + isModified + propertyManager + propertyName + removeSubProperty + setEnabled + setModified + setPropertyName + setStatusTip + setToolTip + setWhatsThis + statusTip + subProperties + toolTip + valueIcon + valueText + whatsThis +
+
+
+ QtRectFPropertyManager + constraint + constraintChanged + decimals + decimalsChanged + initializeProperty + setConstraint + setDecimals + setValue + subDoublePropertyManager + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtRectPropertyManager + constraint + constraintChanged + initializeProperty + setConstraint + setValue + subIntPropertyManager + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtScrollBarFactory +
+
+
+ QtSizeFPropertyManager + decimals + decimalsChanged + initializeProperty + maximum + minimum + rangeChanged + setDecimals + setMaximum + setMinimum + setRange + setValue + subDoublePropertyManager + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtSizePolicyPropertyManager + initializeProperty + setValue + subEnumPropertyManager + subIntPropertyManager + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtSizePropertyManager + initializeProperty + maximum + minimum + rangeChanged + setMaximum + setMinimum + setRange + setValue + subIntPropertyManager + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtSliderFactory +
+
+
+ QtSpinBoxFactory +
+
+
+ QtStringPropertyManager + initializeProperty + regExp + regExpChanged + setRegExp + setValue + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtTimeEditFactory +
+
+
+ QtTimePropertyManager + initializeProperty + setValue + uninitializeProperty + value + valueChanged + valueText +
+
+
+ QtTreePropertyBrowser + ResizeMode + QtTreePropertyBrowser::ResizeToContents + QtTreePropertyBrowser::Stretch + QtTreePropertyBrowser::Interactive + QtTreePropertyBrowser::Fixed + alternatingRowColors + setAlternatingRowColors + headerVisible + isHeaderVisible + setHeaderVisible + indentation + setIndentation + propertiesWithoutValueMarked + setPropertiesWithoutValueMarked + resizeMode + setResizeMode + rootIsDecorated + setRootIsDecorated + splitterPosition + setSplitterPosition + backgroundColor + calculatedBackgroundColor + collapsed + editItem + expanded + isExpanded + isItemVisible + itemChanged + itemInserted + itemRemoved + setBackgroundColor + setExpanded + setItemVisible +
+
+
+ QtVariantEditorFactory +
+
+
+ QtVariantProperty + attributeValue + propertyType + setAttribute + setValue + value + valueType +
+
+
+ QtVariantPropertyManager + addProperty + attributeChanged + attributeType + attributeValue + attributes + createProperty + enumTypeId + flagTypeId + groupTypeId + hasValue + iconMapTypeId + initializeProperty + isPropertyTypeSupported + propertyType + setAttribute + setValue + uninitializeProperty + value + valueChanged + valueIcon + valueText + valueType + variantProperty +
+
+
+
+
+ Decoration Example +
+
+ Demo Example +
+
+ Extension Example +
+
+ Property Browser +
+
+ Simple Tree Property Browser Example +
+
+ The Object Controller Example. +
+
+ Type Based Canvas Example +
+
+ Variant Based Canvas Example +
+
+
+ diff --git a/external/QtPropertyBrowser/doc/html/qtpropertybrowser.index b/external/QtPropertyBrowser/doc/html/qtpropertybrowser.index new file mode 100644 index 000000000..5fc528445 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtpropertybrowser.index @@ -0,0 +1,1425 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/QtPropertyBrowser/doc/html/qtpropertybrowser.qhp b/external/QtPropertyBrowser/doc/html/qtpropertybrowser.qhp new file mode 100644 index 000000000..b1cd096f0 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtpropertybrowser.qhp @@ -0,0 +1,574 @@ + + + com.nokia.qtsolutions.qtpropertybrowser_head + qdoc + + qt + qtpropertybrowser + solutions + + + qt + qtpropertybrowser + solutions + +
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + images/decoration.png + qtpointfpropertymanager.html + qtpropertybrowser-example-object-controller.html + qtpropertybrowser-example-demo.html + qttimepropertymanager.html + qtspinboxfactory.html + qtvariantpropertymanager.html + qtkeysequenceeditorfactory.html + images/canvas_variant.png + qtabstractpropertybrowser.html + qtrectfpropertymanager.html + qtkeysequencepropertymanager.html + images/qtpropertybrowser-duplicate.png + qtpropertybrowser-example-extension.html + qtvariantproperty.html + qtfonteditorfactory.html + index.html + qtabstractpropertymanager.html + qtstringpropertymanager.html + qtpropertybrowser-example-canvas-variant.html + images/qtbuttonpropertybrowser.png + qtflagpropertymanager.html + images/demo.png + qtscrollbarfactory.html + qtdoublepropertymanager.html + images/qtgroupboxpropertybrowser.png + qttreepropertybrowser.html + qtgrouppropertymanager.html + qtsizepolicypropertymanager.html + qtdatetimeeditfactory.html + qtcharpropertymanager.html + qtdatepropertymanager.html + qtpropertybrowser-example-decoration.html + qtboolpropertymanager.html + qtsliderfactory.html + qtpropertybrowser-example-canvas-typed.html + qtrectpropertymanager.html + qtvarianteditorfactory.html + qtgroupboxpropertybrowser.html + qtsizepropertymanager.html + qtabstracteditorfactory.html + qtcolorpropertymanager.html + qtdoublespinboxfactory.html + qtabstracteditorfactorybase.html + qtpointpropertymanager.html + images/object_controller.png + images/extension.png + qtlineeditfactory.html + qtenumeditorfactory.html + qtcursorpropertymanager.html + qtsizefpropertymanager.html + qtfontpropertymanager.html + qtbrowseritem.html + images/simple.png + qtpropertybrowser-example-simple.html + images/qtpropertybrowser.png + qtproperty.html + qtlocalepropertymanager.html + qtdatetimepropertymanager.html + qtintpropertymanager.html + qtcoloreditorfactory.html + qtdateeditfactory.html + images/qttreepropertybrowser.png + qtbuttonpropertybrowser.html + qtcursoreditorfactory.html + qttimeeditfactory.html + qtcheckboxfactory.html + images/canvas_typed.png + qtchareditorfactory.html + qtenumpropertymanager.html + images/canvas_typed.png + images/demo.png + images/canvas_variant.png + images/simple.png + images/qtpropertybrowser.png + classic.css + images/decoration.png + images/qtpropertybrowser-duplicate.png + images/qt-logo.png + images/qttreepropertybrowser.png + images/qtgroupboxpropertybrowser.png + images/qtbuttonpropertybrowser.png + images/extension.png + images/object_controller.png + + + diff --git a/external/QtPropertyBrowser/doc/html/qtrectfpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtrectfpropertymanager-members.html new file mode 100644 index 000000000..4589e59ef --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtrectfpropertymanager-members.html @@ -0,0 +1,99 @@ + + + + + + List of All Members for QtRectFPropertyManager + + + + + + + +
  Home

List of All Members for QtRectFPropertyManager

+

This is the complete list of members for QtRectFPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtrectfpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtrectfpropertymanager.html new file mode 100644 index 000000000..5d0a47d8a --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtrectfpropertymanager.html @@ -0,0 +1,142 @@ + + + + + + QtRectFPropertyManager Class Reference + + + + + + + +
  Home

QtRectFPropertyManager Class Reference

+

The QtRectFPropertyManager provides and manages QRectF properties. More...

+
 #include <QtRectFPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + + + +
QtRectFPropertyManager ( QObject * parent = 0 )
~QtRectFPropertyManager ()
QRectF constraint ( const QtProperty * property ) const
int decimals ( const QtProperty * property ) const
QtDoublePropertyManager * subDoublePropertyManager () const
QRectF value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + + + +
void setConstraint ( QtProperty * property, const QRectF & constraint )
void setDecimals ( QtProperty * property, int prec )
void setValue ( QtProperty * property, const QRectF & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + + + +
void constraintChanged ( QtProperty * property, const QRectF & constraint )
void decimalsChanged ( QtProperty * property, int prec )
void valueChanged ( QtProperty * property, const QRectF & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtRectFPropertyManager provides and manages QRectF properties.

+

A rectangle property has nested x, y, width and height subproperties. The top-level property's value can be retrieved using the value() function, and set using the setValue() slot.

+

The subproperties are created by a QtDoublePropertyManager object. This manager can be retrieved using the subDoublePropertyManager() function. In order to provide editing widgets for the subproperties in a property browser widget, this manager must be associated with an editor factory.

+

A rectangle property also has a constraint rectangle which can be retrieved using the constraint() function, and set using the setConstraint() slot.

+

In addition, QtRectFPropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes, and the constraintChanged() signal which is emitted whenever such a property changes its constraint rectangle.

+

See also QtAbstractPropertyManager, QtDoublePropertyManager, and QtRectPropertyManager.

+
+

Member Function Documentation

+

QtRectFPropertyManager::QtRectFPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtRectFPropertyManager::~QtRectFPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

QRectF QtRectFPropertyManager::constraint ( const QtProperty * property ) const

+

Returns the given property's constraining rectangle. If returned value is null QRectF it means there is no constraint applied.

+

See also value() and setConstraint().

+

void QtRectFPropertyManager::constraintChanged ( QtProperty * property, const QRectF & constraint )   [signal]

+

This signal is emitted whenever property changes its constraint rectangle, passing a pointer to the property and the new constraint rectangle as parameters.

+

See also setConstraint().

+

int QtRectFPropertyManager::decimals ( const QtProperty * property ) const

+

Returns the given property's precision, in decimals.

+

See also setDecimals().

+

void QtRectFPropertyManager::decimalsChanged ( QtProperty * property, int prec )   [signal]

+

This signal is emitted whenever a property created by this manager changes its precision of value, passing a pointer to the property and the new prec value

+

See also setDecimals().

+

void QtRectFPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtRectFPropertyManager::setConstraint ( QtProperty * property, const QRectF & constraint )   [slot]

+

Sets the given property's constraining rectangle to constraint.

+

When setting the constraint, the current value is adjusted if necessary (ensuring that the current rectangle value is inside the constraint). In order to reset the constraint pass a null QRectF value.

+

See also setValue(), constraint(), and constraintChanged().

+

void QtRectFPropertyManager::setDecimals ( QtProperty * property, int prec )   [slot]

+

Sets the precision of the given property to prec.

+

The valid decimal range is 0-13. The default is 2.

+

See also decimals().

+

void QtRectFPropertyManager::setValue ( QtProperty * property, const QRectF & value )   [slot]

+

Sets the value of the given property to value. Nested properties are updated automatically.

+

If the specified value is not inside the given property's constraining rectangle, the value is adjusted accordingly to fit within the constraint.

+

See also value(), setConstraint(), and valueChanged().

+

QtDoublePropertyManager * QtRectFPropertyManager::subDoublePropertyManager () const

+

Returns the manager that creates the nested x, y, width and height subproperties.

+

In order to provide editing widgets for the mentioned subproperties in a property browser widget, this manager must be associated with an editor factory.

+

See also QtAbstractPropertyBrowser::setFactoryForManager().

+

void QtRectFPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QRectF QtRectFPropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns an invalid rectangle.

+

See also setValue() and constraint().

+

void QtRectFPropertyManager::valueChanged ( QtProperty * property, const QRectF & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QString QtRectFPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtrectpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtrectpropertymanager-members.html new file mode 100644 index 000000000..8018a7630 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtrectpropertymanager-members.html @@ -0,0 +1,96 @@ + + + + + + List of All Members for QtRectPropertyManager + + + + + + + +
  Home

List of All Members for QtRectPropertyManager

+

This is the complete list of members for QtRectPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtrectpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtrectpropertymanager.html new file mode 100644 index 000000000..77d4452dd --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtrectpropertymanager.html @@ -0,0 +1,129 @@ + + + + + + QtRectPropertyManager Class Reference + + + + + + + +
  Home

QtRectPropertyManager Class Reference

+

The QtRectPropertyManager provides and manages QRect properties. More...

+
 #include <QtRectPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + + +
QtRectPropertyManager ( QObject * parent = 0 )
~QtRectPropertyManager ()
QRect constraint ( const QtProperty * property ) const
QtIntPropertyManager * subIntPropertyManager () const
QRect value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + + +
void setConstraint ( QtProperty * property, const QRect & constraint )
void setValue ( QtProperty * property, const QRect & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + + +
void constraintChanged ( QtProperty * property, const QRect & constraint )
void valueChanged ( QtProperty * property, const QRect & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtRectPropertyManager provides and manages QRect properties.

+

A rectangle property has nested x, y, width and height subproperties. The top-level property's value can be retrieved using the value() function, and set using the setValue() slot.

+

The subproperties are created by a QtIntPropertyManager object. This manager can be retrieved using the subIntPropertyManager() function. In order to provide editing widgets for the subproperties in a property browser widget, this manager must be associated with an editor factory.

+

A rectangle property also has a constraint rectangle which can be retrieved using the constraint() function, and set using the setConstraint() slot.

+

In addition, QtRectPropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes, and the constraintChanged() signal which is emitted whenever such a property changes its constraint rectangle.

+

See also QtAbstractPropertyManager, QtIntPropertyManager, and QtRectFPropertyManager.

+
+

Member Function Documentation

+

QtRectPropertyManager::QtRectPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtRectPropertyManager::~QtRectPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

QRect QtRectPropertyManager::constraint ( const QtProperty * property ) const

+

Returns the given property's constraining rectangle. If returned value is null QRect it means there is no constraint applied.

+

See also value() and setConstraint().

+

void QtRectPropertyManager::constraintChanged ( QtProperty * property, const QRect & constraint )   [signal]

+

This signal is emitted whenever property changes its constraint rectangle, passing a pointer to the property and the new constraint rectangle as parameters.

+

See also setConstraint().

+

void QtRectPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtRectPropertyManager::setConstraint ( QtProperty * property, const QRect & constraint )   [slot]

+

Sets the given property's constraining rectangle to constraint.

+

When setting the constraint, the current value is adjusted if necessary (ensuring that the current rectangle value is inside the constraint). In order to reset the constraint pass a null QRect value.

+

See also setValue(), constraint(), and constraintChanged().

+

void QtRectPropertyManager::setValue ( QtProperty * property, const QRect & value )   [slot]

+

Sets the value of the given property to value. Nested properties are updated automatically.

+

If the specified value is not inside the given property's constraining rectangle, the value is adjusted accordingly to fit within the constraint.

+

See also value(), setConstraint(), and valueChanged().

+

QtIntPropertyManager * QtRectPropertyManager::subIntPropertyManager () const

+

Returns the manager that creates the nested x, y, width and height subproperties.

+

In order to provide editing widgets for the mentioned subproperties in a property browser widget, this manager must be associated with an editor factory.

+

See also QtAbstractPropertyBrowser::setFactoryForManager().

+

void QtRectPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QRect QtRectPropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns an invalid rectangle.

+

See also setValue() and constraint().

+

void QtRectPropertyManager::valueChanged ( QtProperty * property, const QRect & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QString QtRectPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtscrollbarfactory-members.html b/external/QtPropertyBrowser/doc/html/qtscrollbarfactory-members.html new file mode 100644 index 000000000..32d9dd2c0 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtscrollbarfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtScrollBarFactory + + + + + + + +
  Home

List of All Members for QtScrollBarFactory

+

This is the complete list of members for QtScrollBarFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtscrollbarfactory.html b/external/QtPropertyBrowser/doc/html/qtscrollbarfactory.html new file mode 100644 index 000000000..207c4e39d --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtscrollbarfactory.html @@ -0,0 +1,61 @@ + + + + + + QtScrollBarFactory Class Reference + + + + + + + +
  Home

QtScrollBarFactory Class Reference

+

The QtScrollBarFactory class provides QScrollBar widgets for properties created by QtIntPropertyManager objects. More...

+
 #include <QtScrollBarFactory>

Inherits QtAbstractEditorFactory<QtIntPropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtScrollBarFactory ( QObject * parent = 0 )
~QtScrollBarFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtScrollBarFactory class provides QScrollBar widgets for properties created by QtIntPropertyManager objects.

+

See also QtAbstractEditorFactory and QtIntPropertyManager.

+
+

Member Function Documentation

+

QtScrollBarFactory::QtScrollBarFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtScrollBarFactory::~QtScrollBarFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtsizefpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtsizefpropertymanager-members.html new file mode 100644 index 000000000..eb7235e28 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtsizefpropertymanager-members.html @@ -0,0 +1,102 @@ + + + + + + List of All Members for QtSizeFPropertyManager + + + + + + + +
  Home

List of All Members for QtSizeFPropertyManager

+

This is the complete list of members for QtSizeFPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtsizefpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtsizefpropertymanager.html new file mode 100644 index 000000000..13c7d81b1 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtsizefpropertymanager.html @@ -0,0 +1,157 @@ + + + + + + QtSizeFPropertyManager Class Reference + + + + + + + +
  Home

QtSizeFPropertyManager Class Reference

+

The QtSizeFPropertyManager provides and manages QSizeF properties. More...

+
 #include <QtSizeFPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + + + + +
QtSizeFPropertyManager ( QObject * parent = 0 )
~QtSizeFPropertyManager ()
int decimals ( const QtProperty * property ) const
QSizeF maximum ( const QtProperty * property ) const
QSizeF minimum ( const QtProperty * property ) const
QtDoublePropertyManager * subDoublePropertyManager () const
QSizeF value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + + + + + +
void setDecimals ( QtProperty * property, int prec )
void setMaximum ( QtProperty * property, const QSizeF & maxVal )
void setMinimum ( QtProperty * property, const QSizeF & minVal )
void setRange ( QtProperty * property, const QSizeF & minimum, const QSizeF & maximum )
void setValue ( QtProperty * property, const QSizeF & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + + + +
void decimalsChanged ( QtProperty * property, int prec )
void rangeChanged ( QtProperty * property, const QSizeF & minimum, const QSizeF & maximum )
void valueChanged ( QtProperty * property, const QSizeF & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtSizeFPropertyManager provides and manages QSizeF properties.

+

A size property has nested width and height subproperties. The top-level property's value can be retrieved using the value() function, and set using the setValue() slot.

+

The subproperties are created by a QtDoublePropertyManager object. This manager can be retrieved using the subDoublePropertyManager() function. In order to provide editing widgets for the subproperties in a property browser widget, this manager must be associated with an editor factory.

+

A size property also has a range of valid values defined by a minimum size and a maximum size. These sizes can be retrieved using the minimum() and the maximum() functions, and set using the setMinimum() and setMaximum() slots. Alternatively, the range can be defined in one go using the setRange() slot.

+

In addition, QtSizeFPropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes, and the rangeChanged() signal which is emitted whenever such a property changes its range of valid sizes.

+

See also QtAbstractPropertyManager, QtDoublePropertyManager, and QtSizePropertyManager.

+
+

Member Function Documentation

+

QtSizeFPropertyManager::QtSizeFPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtSizeFPropertyManager::~QtSizeFPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

int QtSizeFPropertyManager::decimals ( const QtProperty * property ) const

+

Returns the given property's precision, in decimals.

+

See also setDecimals().

+

void QtSizeFPropertyManager::decimalsChanged ( QtProperty * property, int prec )   [signal]

+

This signal is emitted whenever a property created by this manager changes its precision of value, passing a pointer to the property and the new prec value

+

See also setDecimals().

+

void QtSizeFPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

QSizeF QtSizeFPropertyManager::maximum ( const QtProperty * property ) const

+

Returns the given property's maximum size value.

+

See also setMaximum(), minimum(), and setRange().

+

QSizeF QtSizeFPropertyManager::minimum ( const QtProperty * property ) const

+

Returns the given property's minimum size value.

+

See also setMinimum(), maximum(), and setRange().

+

void QtSizeFPropertyManager::rangeChanged ( QtProperty * property, const QSizeF & minimum, const QSizeF & maximum )   [signal]

+

This signal is emitted whenever a property created by this manager changes its range of valid sizes, passing a pointer to the property and the new minimum and maximum sizes.

+

See also setRange().

+

void QtSizeFPropertyManager::setDecimals ( QtProperty * property, int prec )   [slot]

+

Sets the precision of the given property to prec.

+

The valid decimal range is 0-13. The default is 2.

+

See also decimals().

+

void QtSizeFPropertyManager::setMaximum ( QtProperty * property, const QSizeF & maxVal )   [slot]

+

Sets the maximum size value for the given property to maxVal.

+

When setting the maximum size value, the minimum and current values are adjusted if necessary (ensuring that the size range remains valid and that the current value is within the range).

+

See also maximum(), setRange(), and rangeChanged().

+

void QtSizeFPropertyManager::setMinimum ( QtProperty * property, const QSizeF & minVal )   [slot]

+

Sets the minimum size value for the given property to minVal.

+

When setting the minimum size value, the maximum and current values are adjusted if necessary (ensuring that the size range remains valid and that the current value is within the range).

+

See also minimum(), setRange(), and rangeChanged().

+

void QtSizeFPropertyManager::setRange ( QtProperty * property, const QSizeF & minimum, const QSizeF & maximum )   [slot]

+

Sets the range of valid values.

+

This is a convenience function defining the range of valid values in one go; setting the minimum and maximum values for the given property with a single function call.

+

When setting a new range, the current value is adjusted if necessary (ensuring that the value remains within the range).

+

See also setMinimum(), setMaximum(), and rangeChanged().

+

void QtSizeFPropertyManager::setValue ( QtProperty * property, const QSizeF & value )   [slot]

+

Sets the value of the given property to value.

+

If the specified value is not valid according to the given property's size range, the value is adjusted to the nearest valid value within the size range.

+

See also value(), setRange(), and valueChanged().

+

QtDoublePropertyManager * QtSizeFPropertyManager::subDoublePropertyManager () const

+

Returns the manager that creates the nested width and height subproperties.

+

In order to provide editing widgets for the width and height properties in a property browser widget, this manager must be associated with an editor factory.

+

See also QtAbstractPropertyBrowser::setFactoryForManager().

+

void QtSizeFPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QSizeF QtSizeFPropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns an invalid size

+

See also setValue().

+

void QtSizeFPropertyManager::valueChanged ( QtProperty * property, const QSizeF & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QString QtSizeFPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtsizepolicypropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtsizepolicypropertymanager-members.html new file mode 100644 index 000000000..ec47a57ab --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtsizepolicypropertymanager-members.html @@ -0,0 +1,94 @@ + + + + + + List of All Members for QtSizePolicyPropertyManager + + + + + + + +
  Home

List of All Members for QtSizePolicyPropertyManager

+

This is the complete list of members for QtSizePolicyPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtsizepolicypropertymanager.html b/external/QtPropertyBrowser/doc/html/qtsizepolicypropertymanager.html new file mode 100644 index 000000000..92086ebe9 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtsizepolicypropertymanager.html @@ -0,0 +1,119 @@ + + + + + + QtSizePolicyPropertyManager Class Reference + + + + + + + +
  Home

QtSizePolicyPropertyManager Class Reference

+

The QtSizePolicyPropertyManager provides and manages QSizePolicy properties. More...

+
 #include <QtSizePolicyPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + + +
QtSizePolicyPropertyManager ( QObject * parent = 0 )
~QtSizePolicyPropertyManager ()
QtEnumPropertyManager * subEnumPropertyManager () const
QtIntPropertyManager * subIntPropertyManager () const
QSizePolicy value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + +
void setValue ( QtProperty * property, const QSizePolicy & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + +
void valueChanged ( QtProperty * property, const QSizePolicy & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtSizePolicyPropertyManager provides and manages QSizePolicy properties.

+

A size policy property has nested horizontalPolicy, verticalPolicy, horizontalStretch and verticalStretch subproperties. The top-level property's value can be retrieved using the value() function, and set using the setValue() slot.

+

The subproperties are created by QtIntPropertyManager and QtEnumPropertyManager objects. These managers can be retrieved using the subIntPropertyManager() and subEnumPropertyManager() functions respectively. In order to provide editing widgets for the subproperties in a property browser widget, these managers must be associated with editor factories.

+

In addition, QtSizePolicyPropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes.

+

See also QtAbstractPropertyManager, QtIntPropertyManager, and QtEnumPropertyManager.

+
+

Member Function Documentation

+

QtSizePolicyPropertyManager::QtSizePolicyPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtSizePolicyPropertyManager::~QtSizePolicyPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

void QtSizePolicyPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtSizePolicyPropertyManager::setValue ( QtProperty * property, const QSizePolicy & value )   [slot]

+

Sets the value of the given property to value. Nested properties are updated automatically.

+

See also value() and valueChanged().

+

QtEnumPropertyManager * QtSizePolicyPropertyManager::subEnumPropertyManager () const

+

Returns the manager that creates the nested horizontalPolicy and verticalPolicy subproperties.

+

In order to provide editing widgets for the mentioned subproperties in a property browser widget, this manager must be associated with an editor factory.

+

See also QtAbstractPropertyBrowser::setFactoryForManager().

+

QtIntPropertyManager * QtSizePolicyPropertyManager::subIntPropertyManager () const

+

Returns the manager that creates the nested horizontalStretch and verticalStretch subproperties.

+

In order to provide editing widgets for the mentioned subproperties in a property browser widget, this manager must be associated with an editor factory.

+

See also QtAbstractPropertyBrowser::setFactoryForManager().

+

void QtSizePolicyPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QSizePolicy QtSizePolicyPropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns the default size policy.

+

See also setValue().

+

void QtSizePolicyPropertyManager::valueChanged ( QtProperty * property, const QSizePolicy & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QString QtSizePolicyPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtsizepropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtsizepropertymanager-members.html new file mode 100644 index 000000000..35cf20d3e --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtsizepropertymanager-members.html @@ -0,0 +1,99 @@ + + + + + + List of All Members for QtSizePropertyManager + + + + + + + +
  Home

List of All Members for QtSizePropertyManager

+

This is the complete list of members for QtSizePropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtsizepropertymanager.html b/external/QtPropertyBrowser/doc/html/qtsizepropertymanager.html new file mode 100644 index 000000000..2e784bde5 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtsizepropertymanager.html @@ -0,0 +1,144 @@ + + + + + + QtSizePropertyManager Class Reference + + + + + + + +
  Home

QtSizePropertyManager Class Reference

+

The QtSizePropertyManager provides and manages QSize properties. More...

+
 #include <QtSizePropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + + + +
QtSizePropertyManager ( QObject * parent = 0 )
~QtSizePropertyManager ()
QSize maximum ( const QtProperty * property ) const
QSize minimum ( const QtProperty * property ) const
QtIntPropertyManager * subIntPropertyManager () const
QSize value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + + + + +
void setMaximum ( QtProperty * property, const QSize & maxVal )
void setMinimum ( QtProperty * property, const QSize & minVal )
void setRange ( QtProperty * property, const QSize & minimum, const QSize & maximum )
void setValue ( QtProperty * property, const QSize & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + + +
void rangeChanged ( QtProperty * property, const QSize & minimum, const QSize & maximum )
void valueChanged ( QtProperty * property, const QSize & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtSizePropertyManager provides and manages QSize properties.

+

A size property has nested width and height subproperties. The top-level property's value can be retrieved using the value() function, and set using the setValue() slot.

+

The subproperties are created by a QtIntPropertyManager object. This manager can be retrieved using the subIntPropertyManager() function. In order to provide editing widgets for the subproperties in a property browser widget, this manager must be associated with an editor factory.

+

A size property also has a range of valid values defined by a minimum size and a maximum size. These sizes can be retrieved using the minimum() and the maximum() functions, and set using the setMinimum() and setMaximum() slots. Alternatively, the range can be defined in one go using the setRange() slot.

+

In addition, QtSizePropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes, and the rangeChanged() signal which is emitted whenever such a property changes its range of valid sizes.

+

See also QtAbstractPropertyManager, QtIntPropertyManager, and QtSizeFPropertyManager.

+
+

Member Function Documentation

+

QtSizePropertyManager::QtSizePropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtSizePropertyManager::~QtSizePropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

void QtSizePropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

QSize QtSizePropertyManager::maximum ( const QtProperty * property ) const

+

Returns the given property's maximum size value.

+

See also setMaximum(), minimum(), and setRange().

+

QSize QtSizePropertyManager::minimum ( const QtProperty * property ) const

+

Returns the given property's minimum size value.

+

See also setMinimum(), maximum(), and setRange().

+

void QtSizePropertyManager::rangeChanged ( QtProperty * property, const QSize & minimum, const QSize & maximum )   [signal]

+

This signal is emitted whenever a property created by this manager changes its range of valid sizes, passing a pointer to the property and the new minimum and maximum sizes.

+

See also setRange().

+

void QtSizePropertyManager::setMaximum ( QtProperty * property, const QSize & maxVal )   [slot]

+

Sets the maximum size value for the given property to maxVal.

+

When setting the maximum size value, the minimum and current values are adjusted if necessary (ensuring that the size range remains valid and that the current value is within the range).

+

See also maximum(), setRange(), and rangeChanged().

+

void QtSizePropertyManager::setMinimum ( QtProperty * property, const QSize & minVal )   [slot]

+

Sets the minimum size value for the given property to minVal.

+

When setting the minimum size value, the maximum and current values are adjusted if necessary (ensuring that the size range remains valid and that the current value is within the range).

+

See also minimum(), setRange(), and rangeChanged().

+

void QtSizePropertyManager::setRange ( QtProperty * property, const QSize & minimum, const QSize & maximum )   [slot]

+

Sets the range of valid values.

+

This is a convenience function defining the range of valid values in one go; setting the minimum and maximum values for the given property with a single function call.

+

When setting a new range, the current value is adjusted if necessary (ensuring that the value remains within the range).

+

See also setMinimum(), setMaximum(), and rangeChanged().

+

void QtSizePropertyManager::setValue ( QtProperty * property, const QSize & value )   [slot]

+

Sets the value of the given property to value.

+

If the specified value is not valid according to the given property's size range, the value is adjusted to the nearest valid value within the size range.

+

See also value(), setRange(), and valueChanged().

+

QtIntPropertyManager * QtSizePropertyManager::subIntPropertyManager () const

+

Returns the manager that creates the nested width and height subproperties.

+

In order to provide editing widgets for the width and height properties in a property browser widget, this manager must be associated with an editor factory.

+

See also QtAbstractPropertyBrowser::setFactoryForManager().

+

void QtSizePropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QSize QtSizePropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns an invalid size

+

See also setValue().

+

void QtSizePropertyManager::valueChanged ( QtProperty * property, const QSize & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QString QtSizePropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtsliderfactory-members.html b/external/QtPropertyBrowser/doc/html/qtsliderfactory-members.html new file mode 100644 index 000000000..fb2e26a44 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtsliderfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtSliderFactory + + + + + + + +
  Home

List of All Members for QtSliderFactory

+

This is the complete list of members for QtSliderFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtsliderfactory.html b/external/QtPropertyBrowser/doc/html/qtsliderfactory.html new file mode 100644 index 000000000..8f438973a --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtsliderfactory.html @@ -0,0 +1,61 @@ + + + + + + QtSliderFactory Class Reference + + + + + + + +
  Home

QtSliderFactory Class Reference

+

The QtSliderFactory class provides QSlider widgets for properties created by QtIntPropertyManager objects. More...

+
 #include <QtSliderFactory>

Inherits QtAbstractEditorFactory<QtIntPropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtSliderFactory ( QObject * parent = 0 )
~QtSliderFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtSliderFactory class provides QSlider widgets for properties created by QtIntPropertyManager objects.

+

See also QtAbstractEditorFactory and QtIntPropertyManager.

+
+

Member Function Documentation

+

QtSliderFactory::QtSliderFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtSliderFactory::~QtSliderFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtspinboxfactory-members.html b/external/QtPropertyBrowser/doc/html/qtspinboxfactory-members.html new file mode 100644 index 000000000..535a6aeb5 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtspinboxfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtSpinBoxFactory + + + + + + + +
  Home

List of All Members for QtSpinBoxFactory

+

This is the complete list of members for QtSpinBoxFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtspinboxfactory.html b/external/QtPropertyBrowser/doc/html/qtspinboxfactory.html new file mode 100644 index 000000000..11dc7e648 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtspinboxfactory.html @@ -0,0 +1,61 @@ + + + + + + QtSpinBoxFactory Class Reference + + + + + + + +
  Home

QtSpinBoxFactory Class Reference

+

The QtSpinBoxFactory class provides QSpinBox widgets for properties created by QtIntPropertyManager objects. More...

+
 #include <QtSpinBoxFactory>

Inherits QtAbstractEditorFactory<QtIntPropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtSpinBoxFactory ( QObject * parent = 0 )
~QtSpinBoxFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtSpinBoxFactory class provides QSpinBox widgets for properties created by QtIntPropertyManager objects.

+

See also QtAbstractEditorFactory and QtIntPropertyManager.

+
+

Member Function Documentation

+

QtSpinBoxFactory::QtSpinBoxFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtSpinBoxFactory::~QtSpinBoxFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtstringpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtstringpropertymanager-members.html new file mode 100644 index 000000000..eb88f591e --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtstringpropertymanager-members.html @@ -0,0 +1,95 @@ + + + + + + List of All Members for QtStringPropertyManager + + + + + + + +
  Home

List of All Members for QtStringPropertyManager

+

This is the complete list of members for QtStringPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtstringpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtstringpropertymanager.html new file mode 100644 index 000000000..c346d7bbe --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtstringpropertymanager.html @@ -0,0 +1,123 @@ + + + + + + QtStringPropertyManager Class Reference + + + + + + + +
  Home

QtStringPropertyManager Class Reference

+

The QtStringPropertyManager provides and manages QString properties. More...

+
 #include <QtStringPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + +
QtStringPropertyManager ( QObject * parent = 0 )
~QtStringPropertyManager ()
QRegExp regExp ( const QtProperty * property ) const
QString value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + + +
void setRegExp ( QtProperty * property, const QRegExp & regExp )
void setValue ( QtProperty * property, const QString & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + + +
void regExpChanged ( QtProperty * property, const QRegExp & regExp )
void valueChanged ( QtProperty * property, const QString & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtStringPropertyManager provides and manages QString properties.

+

A string property's value can be retrieved using the value() function, and set using the setValue() slot.

+

The current value can be checked against a regular expression. To set the regular expression use the setRegExp() slot, use the regExp() function to retrieve the currently set expression.

+

In addition, QtStringPropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes, and the regExpChanged() signal which is emitted whenever such a property changes its currently set regular expression.

+

See also QtAbstractPropertyManager and QtLineEditFactory.

+
+

Member Function Documentation

+

QtStringPropertyManager::QtStringPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtStringPropertyManager::~QtStringPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

void QtStringPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

QRegExp QtStringPropertyManager::regExp ( const QtProperty * property ) const

+

Returns the given property's currently set regular expression.

+

If the given property is not managed by this manager, this function returns an empty expression.

+

See also setRegExp().

+

void QtStringPropertyManager::regExpChanged ( QtProperty * property, const QRegExp & regExp )   [signal]

+

This signal is emitted whenever a property created by this manager changes its currenlty set regular expression, passing a pointer to the property and the new regExp as parameters.

+

See also setRegExp().

+

void QtStringPropertyManager::setRegExp ( QtProperty * property, const QRegExp & regExp )   [slot]

+

Sets the regular expression of the given property to regExp.

+

See also regExp(), setValue(), and regExpChanged().

+

void QtStringPropertyManager::setValue ( QtProperty * property, const QString & value )   [slot]

+

Sets the value of the given property to value.

+

If the specified value doesn't match the given property's regular expression, this function does nothing.

+

See also value(), setRegExp(), and valueChanged().

+

void QtStringPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QString QtStringPropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns an empty string.

+

See also setValue().

+

void QtStringPropertyManager::valueChanged ( QtProperty * property, const QString & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QString QtStringPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qttimeeditfactory-members.html b/external/QtPropertyBrowser/doc/html/qttimeeditfactory-members.html new file mode 100644 index 000000000..510764da0 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qttimeeditfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtTimeEditFactory + + + + + + + +
  Home

List of All Members for QtTimeEditFactory

+

This is the complete list of members for QtTimeEditFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qttimeeditfactory.html b/external/QtPropertyBrowser/doc/html/qttimeeditfactory.html new file mode 100644 index 000000000..4e68ad2b7 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qttimeeditfactory.html @@ -0,0 +1,61 @@ + + + + + + QtTimeEditFactory Class Reference + + + + + + + +
  Home

QtTimeEditFactory Class Reference

+

The QtTimeEditFactory class provides QTimeEdit widgets for properties created by QtTimePropertyManager objects. More...

+
 #include <QtTimeEditFactory>

Inherits QtAbstractEditorFactory<QtTimePropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtTimeEditFactory ( QObject * parent = 0 )
~QtTimeEditFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtTimeEditFactory class provides QTimeEdit widgets for properties created by QtTimePropertyManager objects.

+

See also QtAbstractEditorFactory and QtTimePropertyManager.

+
+

Member Function Documentation

+

QtTimeEditFactory::QtTimeEditFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtTimeEditFactory::~QtTimeEditFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qttimepropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qttimepropertymanager-members.html new file mode 100644 index 000000000..9b2e0bcbc --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qttimepropertymanager-members.html @@ -0,0 +1,92 @@ + + + + + + List of All Members for QtTimePropertyManager + + + + + + + +
  Home

List of All Members for QtTimePropertyManager

+

This is the complete list of members for QtTimePropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qttimepropertymanager.html b/external/QtPropertyBrowser/doc/html/qttimepropertymanager.html new file mode 100644 index 000000000..af37ed67d --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qttimepropertymanager.html @@ -0,0 +1,108 @@ + + + + + + QtTimePropertyManager Class Reference + + + + + + + +
  Home

QtTimePropertyManager Class Reference

+

The QtTimePropertyManager provides and manages QTime properties. More...

+
 #include <QtTimePropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + +
QtTimePropertyManager ( QObject * parent = 0 )
~QtTimePropertyManager ()
QTime value ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + +
void setValue ( QtProperty * property, const QTime & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + +
void valueChanged ( QtProperty * property, const QTime & value )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtTimePropertyManager provides and manages QTime properties.

+

A time property's value can be retrieved using the value() function, and set using the setValue() slot.

+

In addition, QtTimePropertyManager provides the valueChanged() signal which is emitted whenever a property created by this manager changes.

+

See also QtAbstractPropertyManager and QtTimeEditFactory.

+
+

Member Function Documentation

+

QtTimePropertyManager::QtTimePropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtTimePropertyManager::~QtTimePropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

void QtTimePropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

void QtTimePropertyManager::setValue ( QtProperty * property, const QTime & value )   [slot]

+

Sets the value of the given property to value.

+

See also value() and valueChanged().

+

void QtTimePropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QTime QtTimePropertyManager::value ( const QtProperty * property ) const

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns an invalid time object.

+

See also setValue().

+

void QtTimePropertyManager::valueChanged ( QtProperty * property, const QTime & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QString QtTimePropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qttreepropertybrowser-members.html b/external/QtPropertyBrowser/doc/html/qttreepropertybrowser-members.html new file mode 100644 index 000000000..8d3e67d3f --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qttreepropertybrowser-members.html @@ -0,0 +1,409 @@ + + + + + + List of All Members for QtTreePropertyBrowser + + + + + + + +
  Home

List of All Members for QtTreePropertyBrowser

+

This is the complete list of members for QtTreePropertyBrowser, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qttreepropertybrowser.html b/external/QtPropertyBrowser/doc/html/qttreepropertybrowser.html new file mode 100644 index 000000000..30103e95f --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qttreepropertybrowser.html @@ -0,0 +1,248 @@ + + + + + + QtTreePropertyBrowser Class Reference + + + + + + + +
  Home

QtTreePropertyBrowser Class Reference

+

The QtTreePropertyBrowser class provides QTreeWidget based property browser. More...

+
 #include <QtTreePropertyBrowser>

Inherits QtAbstractPropertyBrowser.

+ +
+ +

Public Types

+ + +
enum ResizeMode { Interactive, Fixed, Stretch, ResizeToContents }
+
+ +

Properties

+

+ +
+

+
    +
  • 58 properties inherited from QWidget
  • +
  • 1 property inherited from QObject
  • +
+
+ +

Public Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + +
QtTreePropertyBrowser ( QWidget * parent = 0 )
~QtTreePropertyBrowser ()
bool alternatingRowColors () const
QColor backgroundColor ( QtBrowserItem * item ) const
QColor calculatedBackgroundColor ( QtBrowserItem * item ) const
void editItem ( QtBrowserItem * item )
int indentation () const
bool isExpanded ( QtBrowserItem * item ) const
bool isHeaderVisible () const
bool isItemVisible ( QtBrowserItem * item ) const
bool propertiesWithoutValueMarked () const
ResizeMode resizeMode () const
bool rootIsDecorated () const
void setAlternatingRowColors ( bool enable )
void setBackgroundColor ( QtBrowserItem * item, const QColor & color )
void setExpanded ( QtBrowserItem * item, bool expanded )
void setHeaderVisible ( bool visible )
void setIndentation ( int i )
void setItemVisible ( QtBrowserItem * item, bool visible )
void setPropertiesWithoutValueMarked ( bool mark )
void setResizeMode ( ResizeMode mode )
void setRootIsDecorated ( bool show )
void setSplitterPosition ( int position )
int splitterPosition () const
+ +
+ +

Signals

+ + + +
void collapsed ( QtBrowserItem * item )
void expanded ( QtBrowserItem * item )
+ +
+ +

Reimplemented Protected Functions

+ + + + +
virtual void itemChanged ( QtBrowserItem * item )
virtual void itemInserted ( QtBrowserItem * item, QtBrowserItem * afterItem )
virtual void itemRemoved ( QtBrowserItem * item )
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtTreePropertyBrowser class provides QTreeWidget based property browser.

+

A property browser is a widget that enables the user to edit a given set of properties. Each property is represented by a label specifying the property's name, and an editing widget (e.g. a line edit or a combobox) holding its value. A property can have zero or more subproperties.

+

QtTreePropertyBrowser provides a tree based view for all nested properties, i.e. properties that have subproperties can be in an expanded (subproperties are visible) or collapsed (subproperties are hidden) state. For example:

+

Use the QtAbstractPropertyBrowser API to add, insert and remove properties from an instance of the QtTreePropertyBrowser class. The properties themselves are created and managed by implementations of the QtAbstractPropertyManager class.

+

See also QtGroupBoxPropertyBrowser and QtAbstractPropertyBrowser.

+
+

Member Type Documentation

+

enum QtTreePropertyBrowser::ResizeMode

+

The resize mode specifies the behavior of the header sections.

+

+ + + + + +
ConstantValueDescription
QtTreePropertyBrowser::Interactive0The user can resize the sections. The sections can also be resized programmatically using setSplitterPosition().
QtTreePropertyBrowser::Fixed2The user cannot resize the section. The section can only be resized programmatically using setSplitterPosition().
QtTreePropertyBrowser::Stretch1QHeaderView will automatically resize the section to fill the available space. The size cannot be changed by the user or programmatically.
QtTreePropertyBrowser::ResizeToContents3QHeaderView will automatically resize the section to its optimal size based on the contents of the entire column. The size cannot be changed by the user or programmatically.

+

See also setResizeMode().

+
+

Property Documentation

+

alternatingRowColors : bool

+

This property holds whether to draw the background using alternating colors. By default this property is set to true.

+

Access functions:

+ + + +
bool alternatingRowColors () const
void setAlternatingRowColors ( bool enable )
+

headerVisible : bool

+

This property holds whether to show the header.

+

Access functions:

+ + + +
bool isHeaderVisible () const
void setHeaderVisible ( bool visible )
+

indentation : int

+

This property holds indentation of the items in the tree view.

+

Access functions:

+ + + +
int indentation () const
void setIndentation ( int i )
+

propertiesWithoutValueMarked : bool

+

This property holds whether to enable or disable marking properties without value.

+

When marking is enabled the item's background is rendered in dark color and item's foreground is rendered with light color.

+

Access functions:

+ + + +
bool propertiesWithoutValueMarked () const
void setPropertiesWithoutValueMarked ( bool mark )
+

See also propertiesWithoutValueMarked().

+

resizeMode : ResizeMode

+

This property holds the resize mode of setions in the header.

+

Access functions:

+ + + +
ResizeMode resizeMode () const
void setResizeMode ( ResizeMode mode )
+

rootIsDecorated : bool

+

This property holds whether to show controls for expanding and collapsing root items.

+

Access functions:

+ + + +
bool rootIsDecorated () const
void setRootIsDecorated ( bool show )
+

splitterPosition : int

+

This property holds the position of the splitter between the colunms.

+

Access functions:

+ + + +
int splitterPosition () const
void setSplitterPosition ( int position )
+
+

Member Function Documentation

+

QtTreePropertyBrowser::QtTreePropertyBrowser ( QWidget * parent = 0 )

+

Creates a property browser with the given parent.

+

QtTreePropertyBrowser::~QtTreePropertyBrowser ()

+

Destroys this property browser.

+

Note that the properties that were inserted into this browser are not destroyed since they may still be used in other browsers. The properties are owned by the manager that created them.

+

See also QtProperty and QtAbstractPropertyManager.

+

QColor QtTreePropertyBrowser::backgroundColor ( QtBrowserItem * item ) const

+

Returns the item's color. If there is no color set for item it returns invalid color.

+

See also calculatedBackgroundColor() and setBackgroundColor().

+

QColor QtTreePropertyBrowser::calculatedBackgroundColor ( QtBrowserItem * item ) const

+

Returns the item's color. If there is no color set for item it returns parent item's color (if there is no color set for parent it returns grandparent's color and so on). In case the color is not set for item and it's top level item it returns invalid color.

+

See also backgroundColor() and setBackgroundColor().

+

void QtTreePropertyBrowser::collapsed ( QtBrowserItem * item )   [signal]

+

This signal is emitted when the item is collapsed.

+

See also expanded() and setExpanded().

+

void QtTreePropertyBrowser::editItem ( QtBrowserItem * item )

+

Sets the current item to item and opens the relevant editor for it.

+

void QtTreePropertyBrowser::expanded ( QtBrowserItem * item )   [signal]

+

This signal is emitted when the item is expanded.

+

See also collapsed() and setExpanded().

+

bool QtTreePropertyBrowser::isExpanded ( QtBrowserItem * item ) const

+

Returns true if the item is expanded; otherwise returns false.

+

See also setExpanded().

+

bool QtTreePropertyBrowser::isItemVisible ( QtBrowserItem * item ) const

+

Returns true if the item is visible; otherwise returns false.

+

This function was introduced in qtpropertybrowser 4.5.

+

See also setItemVisible().

+

void QtTreePropertyBrowser::itemChanged ( QtBrowserItem * item )   [virtual protected]

+

Reimplemented from QtAbstractPropertyBrowser::itemChanged().

+

void QtTreePropertyBrowser::itemInserted ( QtBrowserItem * item, QtBrowserItem * afterItem )   [virtual protected]

+

Reimplemented from QtAbstractPropertyBrowser::itemInserted().

+

void QtTreePropertyBrowser::itemRemoved ( QtBrowserItem * item )   [virtual protected]

+

Reimplemented from QtAbstractPropertyBrowser::itemRemoved().

+

void QtTreePropertyBrowser::setBackgroundColor ( QtBrowserItem * item, const QColor & color )

+

Sets the item's background color to color. Note that while item's background is rendered every second row is being drawn with alternate color (which is a bit lighter than items color)

+

See also backgroundColor() and calculatedBackgroundColor().

+

void QtTreePropertyBrowser::setExpanded ( QtBrowserItem * item, bool expanded )

+

Sets the item to either collapse or expanded, depending on the value of expanded.

+

See also isExpanded(), expanded(), and collapsed().

+

void QtTreePropertyBrowser::setItemVisible ( QtBrowserItem * item, bool visible )

+

Sets the item to be visible, depending on the value of visible.

+

This function was introduced in qtpropertybrowser 4.5.

+

See also isItemVisible().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtvarianteditorfactory-members.html b/external/QtPropertyBrowser/doc/html/qtvarianteditorfactory-members.html new file mode 100644 index 000000000..ab3277989 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtvarianteditorfactory-members.html @@ -0,0 +1,84 @@ + + + + + + List of All Members for QtVariantEditorFactory + + + + + + + +
  Home

List of All Members for QtVariantEditorFactory

+

This is the complete list of members for QtVariantEditorFactory, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtvarianteditorfactory.html b/external/QtPropertyBrowser/doc/html/qtvarianteditorfactory.html new file mode 100644 index 000000000..cc8da6743 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtvarianteditorfactory.html @@ -0,0 +1,77 @@ + + + + + + QtVariantEditorFactory Class Reference + + + + + + + +
  Home

QtVariantEditorFactory Class Reference

+

The QtVariantEditorFactory class provides widgets for properties created by QtVariantPropertyManager objects. More...

+
 #include <QtVariantEditorFactory>

Inherits QtAbstractEditorFactory<QtVariantPropertyManager>.

+ +
+ +

Public Functions

+ + + +
QtVariantEditorFactory ( QObject * parent = 0 )
~QtVariantEditorFactory ()
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtVariantEditorFactory class provides widgets for properties created by QtVariantPropertyManager objects.

+

The variant factory provides the following widgets for the specified property types:

+

+ + + + + + + + + + + + +
Property TypeWidget
intQSpinBox
doubleQDoubleSpinBox
boolQCheckBox
QStringQLineEdit
QDateQDateEdit
QTimeQTimeEdit
QDateTimeQDateTimeEdit
QKeySequencecustomized editor
QCharcustomized editor
enumQComboBox
QCursorQComboBox

+

Note that QtVariantPropertyManager supports several additional property types for which the QtVariantEditorFactory class does not provide editing widgets, e.g. QPoint and QSize. To provide widgets for other types using the variant approach, derive from the QtVariantEditorFactory class.

+

See also QtAbstractEditorFactory and QtVariantPropertyManager.

+
+

Member Function Documentation

+

QtVariantEditorFactory::QtVariantEditorFactory ( QObject * parent = 0 )

+

Creates a factory with the given parent.

+

QtVariantEditorFactory::~QtVariantEditorFactory ()

+

Destroys this factory, and all the widgets it has created.

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtvariantproperty-members.html b/external/QtPropertyBrowser/doc/html/qtvariantproperty-members.html new file mode 100644 index 000000000..d8c5b0c94 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtvariantproperty-members.html @@ -0,0 +1,57 @@ + + + + + + List of All Members for QtVariantProperty + + + + + + + +
  Home

List of All Members for QtVariantProperty

+

This is the complete list of members for QtVariantProperty, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtvariantproperty.html b/external/QtPropertyBrowser/doc/html/qtvariantproperty.html new file mode 100644 index 000000000..9aa3db404 --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtvariantproperty.html @@ -0,0 +1,96 @@ + + + + + + QtVariantProperty Class Reference + + + + + + + +
  Home

QtVariantProperty Class Reference

+

The QtVariantProperty class is a convenience class handling QVariant based properties. More...

+
 #include <QtVariantProperty>

Inherits QtProperty.

+ +
+ +

Public Functions

+ + + + + + + + +
~QtVariantProperty ()
QVariant attributeValue ( const QString & attribute ) const
int propertyType () const
void setAttribute ( const QString & attribute, const QVariant & value )
void setValue ( const QVariant & value )
QVariant value () const
int valueType () const
+ +
+ +

Protected Functions

+ + +
QtVariantProperty ( QtVariantPropertyManager * manager )
+ +
+

Detailed Description

+

The QtVariantProperty class is a convenience class handling QVariant based properties.

+

QtVariantProperty provides additional API: A property's type, value type, attribute values and current value can easily be retrieved using the propertyType(), valueType(), attributeValue() and value() functions respectively. In addition, the attribute values and the current value can be set using the corresponding setValue() and setAttribute() functions.

+

For example, instead of writing:

+
 QtVariantPropertyManager *variantPropertyManager;
+ QtProperty *property;
+
+ variantPropertyManager->setValue(property, 10);
+

you can write:

+
 QtVariantPropertyManager *variantPropertyManager;
+ QtVariantProperty *property;
+
+ property->setValue(10);
+

QtVariantProperty instances can only be created by the QtVariantPropertyManager class.

+

See also QtProperty, QtVariantPropertyManager, and QtVariantEditorFactory.

+
+

Member Function Documentation

+

QtVariantProperty::QtVariantProperty ( QtVariantPropertyManager * manager )   [protected]

+

Creates a variant property using the given manager.

+

Do not use this constructor to create variant property instances; use the QtVariantPropertyManager::addProperty() function instead. This constructor is used internally by the QtVariantPropertyManager::createProperty() function.

+

See also QtVariantPropertyManager.

+

QtVariantProperty::~QtVariantProperty ()

+

Destroys this property.

+

See also QtProperty::~QtProperty().

+

QVariant QtVariantProperty::attributeValue ( const QString & attribute ) const

+

Returns this property's value for the specified attribute.

+

QtVariantPropertyManager provides a couple of related functions: attributes() and attributeType().

+

See also setAttribute().

+

int QtVariantProperty::propertyType () const

+

Returns this property's type.

+

QtVariantPropertyManager provides several related functions: enumTypeId(), flagTypeId() and groupTypeId().

+

See also valueType().

+

void QtVariantProperty::setAttribute ( const QString & attribute, const QVariant & value )

+

Sets the attribute of property to value.

+

QtVariantPropertyManager provides the related setAttribute() function.

+

See also attributeValue().

+

void QtVariantProperty::setValue ( const QVariant & value )

+

Sets the value of this property to value.

+

The specified value must be of the type returned by valueType(), or of a type that can be converted to valueType() using the QVariant::canConvert() function; otherwise this function does nothing.

+

See also value().

+

QVariant QtVariantProperty::value () const

+

Returns the property's current value.

+

See also valueType() and setValue().

+

int QtVariantProperty::valueType () const

+

Returns the type of this property's value.

+

See also propertyType().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtvariantpropertymanager-members.html b/external/QtPropertyBrowser/doc/html/qtvariantpropertymanager-members.html new file mode 100644 index 000000000..9e1ce208d --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtvariantpropertymanager-members.html @@ -0,0 +1,106 @@ + + + + + + List of All Members for QtVariantPropertyManager + + + + + + + +
  Home

List of All Members for QtVariantPropertyManager

+

This is the complete list of members for QtVariantPropertyManager, including inherited members.

+

+ +
+

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/html/qtvariantpropertymanager.html b/external/QtPropertyBrowser/doc/html/qtvariantpropertymanager.html new file mode 100644 index 000000000..ba563926e --- /dev/null +++ b/external/QtPropertyBrowser/doc/html/qtvariantpropertymanager.html @@ -0,0 +1,251 @@ + + + + + + QtVariantPropertyManager Class Reference + + + + + + + +
  Home

QtVariantPropertyManager Class Reference

+

The QtVariantPropertyManager class provides and manages QVariant based properties. More...

+
 #include <QtVariantPropertyManager>

Inherits QtAbstractPropertyManager.

+ +
+ +

Public Functions

+ + + + + + + + + + + + + +
QtVariantPropertyManager ( QObject * parent = 0 )
~QtVariantPropertyManager ()
virtual QtVariantProperty * addProperty ( int propertyType, const QString & name = QString() )
virtual int attributeType ( int propertyType, const QString & attribute ) const
virtual QVariant attributeValue ( const QtProperty * property, const QString & attribute ) const
virtual QStringList attributes ( int propertyType ) const
virtual bool isPropertyTypeSupported ( int propertyType ) const
int propertyType ( const QtProperty * property ) const
virtual QVariant value ( const QtProperty * property ) const
int valueType ( const QtProperty * property ) const
virtual int valueType ( int propertyType ) const
QtVariantProperty * variantProperty ( const QtProperty * property ) const
+ +
+ +

Public Slots

+ + + +
virtual void setAttribute ( QtProperty * property, const QString & attribute, const QVariant & value )
virtual void setValue ( QtProperty * property, const QVariant & value )
+
    +
  • 1 public slot inherited from QObject
  • +
+
+ +

Signals

+ + + +
void attributeChanged ( QtProperty * property, const QString & attribute, const QVariant & value )
void valueChanged ( QtProperty * property, const QVariant & value )
+ +
+ +

Static Public Members

+ + + + + +
int enumTypeId ()
int flagTypeId ()
int groupTypeId ()
int iconMapTypeId ()
+
    +
  • 4 static public members inherited from QObject
  • +
+
+ +

Reimplemented Protected Functions

+ + + + + + + +
virtual QtProperty * createProperty ()
virtual bool hasValue ( const QtProperty * property ) const
virtual void initializeProperty ( QtProperty * property )
virtual void uninitializeProperty ( QtProperty * property )
virtual QIcon valueIcon ( const QtProperty * property ) const
virtual QString valueText ( const QtProperty * property ) const
+ +

Additional Inherited Members

+ + +
+

Detailed Description

+

The QtVariantPropertyManager class provides and manages QVariant based properties.

+

QtVariantPropertyManager provides the addProperty() function which creates QtVariantProperty objects. The QtVariantProperty class is a convenience class handling QVariant based properties inheriting QtProperty. A QtProperty object created by a QtVariantPropertyManager instance can be converted into a QtVariantProperty object using the variantProperty() function.

+

The property's value can be retrieved using the value(), and set using the setValue() slot. In addition the property's type, and the type of its value, can be retrieved using the propertyType() and valueType() functions respectively.

+

A property's type is a QVariant::Type enumerator value, and usually a property's type is the same as its value type. But for some properties the types differ, for example for enums, flags and group types in which case QtVariantPropertyManager provides the enumTypeId(), flagTypeId() and groupTypeId() functions, respectively, to identify their property type (the value types are QVariant::Int for the enum and flag types, and QVariant::Invalid for the group type).

+

Use the isPropertyTypeSupported() function to check if a particular property type is supported. The currently supported property types are:

+

+ + + + + + + + + + + + + + + + + + + + + + + + +
Property TypeProperty Type Id
intQVariant::Int
doubleQVariant::Double
boolQVariant::Bool
QStringQVariant::String
QDateQVariant::Date
QTimeQVariant::Time
QDateTimeQVariant::DateTime
QKeySequenceQVariant::KeySequence
QCharQVariant::Char
QLocaleQVariant::Locale
QPointQVariant::Point
QPointFQVariant::PointF
QSizeQVariant::Size
QSizeFQVariant::SizeF
QRectQVariant::Rect
QRectFQVariant::RectF
QColorQVariant::Color
QSizePolicyQVariant::SizePolicy
QFontQVariant::Font
QCursorQVariant::Cursor
enumenumTypeId()
flagflagTypeId()
groupgroupTypeId()

+

Each property type can provide additional attributes, e.g. QVariant::Int and QVariant::Double provides minimum and maximum values. The currently supported attributes are:

+

+ + + + + + + + + + + + + + + + + + + + + + + +
Property TypeAttribute NameAttribute Type
intminimumQVariant::Int
maximumQVariant::Int
singleStepQVariant::Int
doubleminimumQVariant::Double
maximumQVariant::Double
singleStepQVariant::Double
decimalsQVariant::Int
QStringregExpQVariant::RegExp
QDateminimumQVariant::Date
maximumQVariant::Date
QPointFdecimalsQVariant::Int
QSizeminimumQVariant::Size
maximumQVariant::Size
QSizeFminimumQVariant::SizeF
maximumQVariant::SizeF
decimalsQVariant::Int
QRectconstraintQVariant::Rect
QRectFconstraintQVariant::RectF
decimalsQVariant::Int
enumenumNamesQVariant::StringList
enumIconsiconMapTypeId()
flagflagNamesQVariant::StringList

+

The attributes for a given property type can be retrieved using the attributes() function. Each attribute has a value type which can be retrieved using the attributeType() function, and a value accessible through the attributeValue() function. In addition, the value can be set using the setAttribute() slot.

+

QtVariantManager also provides the valueChanged() signal which is emitted whenever a property created by this manager change, and the attributeChanged() signal which is emitted whenever an attribute of such a property changes.

+

See also QtVariantProperty and QtVariantEditorFactory.

+
+

Member Function Documentation

+

QtVariantPropertyManager::QtVariantPropertyManager ( QObject * parent = 0 )

+

Creates a manager with the given parent.

+

QtVariantPropertyManager::~QtVariantPropertyManager ()

+

Destroys this manager, and all the properties it has created.

+

QtVariantProperty * QtVariantPropertyManager::addProperty ( int propertyType, const QString & name = QString() )   [virtual]

+

Creates and returns a variant property of the given propertyType with the given name.

+

If the specified propertyType is not supported by this variant manager, this function returns 0.

+

Do not use the inherited QtAbstractPropertyManager::addProperty() function to create a variant property (that function will always return 0 since it will not be clear what type the property should have).

+

See also isPropertyTypeSupported().

+

void QtVariantPropertyManager::attributeChanged ( QtProperty * property, const QString & attribute, const QVariant & value )   [signal]

+

This signal is emitted whenever an attribute of a property created by this manager changes its value, passing a pointer to the property, the attribute and the new value as parameters.

+

See also setAttribute().

+

int QtVariantPropertyManager::attributeType ( int propertyType, const QString & attribute ) const   [virtual]

+

Returns the type of the specified attribute of the given propertyType.

+

If the given propertyType is not supported by this manager, or if the given propertyType does not possess the specified attribute, this function returns QVariant::Invalid.

+

See also attributes() and valueType().

+

QVariant QtVariantPropertyManager::attributeValue ( const QtProperty * property, const QString & attribute ) const   [virtual]

+

Returns the given property's value for the specified attribute

+

If the given property was not created by this manager, or if the specified attribute does not exist, this function returns an invalid variant.

+

See also attributes(), attributeType(), and setAttribute().

+

QStringList QtVariantPropertyManager::attributes ( int propertyType ) const   [virtual]

+

Returns a list of the given propertyType 's attributes.

+

See also attributeValue() and attributeType().

+

QtProperty * QtVariantPropertyManager::createProperty ()   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::createProperty().

+

int QtVariantPropertyManager::enumTypeId ()   [static]

+

Returns the type id for an enum property.

+

Note that the property's value type can be retrieved using the valueType() function (which is QVariant::Int for the enum property type).

+

See also propertyType() and valueType().

+

int QtVariantPropertyManager::flagTypeId ()   [static]

+

Returns the type id for a flag property.

+

Note that the property's value type can be retrieved using the valueType() function (which is QVariant::Int for the flag property type).

+

See also propertyType() and valueType().

+

int QtVariantPropertyManager::groupTypeId ()   [static]

+

Returns the type id for a group property.

+

Note that the property's value type can be retrieved using the valueType() function (which is QVariant::Invalid for the group property type, since it doesn't provide any value).

+

See also propertyType() and valueType().

+

bool QtVariantPropertyManager::hasValue ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::hasValue().

+

int QtVariantPropertyManager::iconMapTypeId ()   [static]

+

Returns the type id for a icon map attribute.

+

Note that the property's attribute type can be retrieved using the attributeType() function.

+

See also attributeType() and QtEnumPropertyManager::enumIcons().

+

void QtVariantPropertyManager::initializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::initializeProperty().

+

bool QtVariantPropertyManager::isPropertyTypeSupported ( int propertyType ) const   [virtual]

+

Returns true if the given propertyType is supported by this variant manager; otherwise false.

+

See also propertyType().

+

int QtVariantPropertyManager::propertyType ( const QtProperty * property ) const

+

Returns the given property's type.

+

See also valueType().

+

void QtVariantPropertyManager::setAttribute ( QtProperty * property, const QString & attribute, const QVariant & value )   [virtual slot]

+

Sets the value of the specified attribute of the given property, to value.

+

The new value's type must be of the type returned by attributeType(), or of a type that can be converted to attributeType() using the QVariant::canConvert() function, otherwise this function does nothing.

+

See also attributeValue(), QtVariantProperty::setAttribute(), and attributeChanged().

+

void QtVariantPropertyManager::setValue ( QtProperty * property, const QVariant & value )   [virtual slot]

+

Sets the value of the given property to value.

+

The specified value must be of a type returned by valueType(), or of type that can be converted to valueType() using the QVariant::canConvert() function, otherwise this function does nothing.

+

See also value(), QtVariantProperty::setValue(), and valueChanged().

+

void QtVariantPropertyManager::uninitializeProperty ( QtProperty * property )   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::uninitializeProperty().

+

QVariant QtVariantPropertyManager::value ( const QtProperty * property ) const   [virtual]

+

Returns the given property's value.

+

If the given property is not managed by this manager, this function returns an invalid variant.

+

See also setValue().

+

void QtVariantPropertyManager::valueChanged ( QtProperty * property, const QVariant & value )   [signal]

+

This signal is emitted whenever a property created by this manager changes its value, passing a pointer to the property and the new value as parameters.

+

See also setValue().

+

QIcon QtVariantPropertyManager::valueIcon ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueIcon().

+

QString QtVariantPropertyManager::valueText ( const QtProperty * property ) const   [virtual protected]

+

Reimplemented from QtAbstractPropertyManager::valueText().

+

int QtVariantPropertyManager::valueType ( const QtProperty * property ) const

+

Returns the given property's value type.

+

See also propertyType().

+

int QtVariantPropertyManager::valueType ( int propertyType ) const   [virtual]

+

This is an overloaded function.

+

Returns the value type associated with the given propertyType.

+

QtVariantProperty * QtVariantPropertyManager::variantProperty ( const QtProperty * property ) const

+

Returns the given property converted into a QtVariantProperty.

+

If the property was not created by this variant manager, the function returns 0.

+

See also createProperty().

+


+ + + + +
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt Solutions
+ diff --git a/external/QtPropertyBrowser/doc/images/canvas_typed.png b/external/QtPropertyBrowser/doc/images/canvas_typed.png new file mode 100644 index 0000000000000000000000000000000000000000..888cb6a0e1e2c3081b3c5dd82bbc1ab3ca0c7eb0 GIT binary patch literal 16376 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 literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/images/decoration.png b/external/QtPropertyBrowser/doc/images/decoration.png new file mode 100644 index 0000000000000000000000000000000000000000..92db0fc60f85e9a9e2862c50367d8788ac7145b5 GIT binary patch literal 6620 zcmaJ`cQjnzw-+T!B3kt5A$sqGU=S^$hA=wOTMVN_3DIkU(W3-2+Ni~n6^%NMG|M07-0SXjhr&jGqvSa;+wavT9R zrp$5Q)q>mpT~ENq<_?RI{IxKA(M@;@5)a zB_}5zQRDipwE+4Q76wrIsEy3C^mzREG2O=i)N6s3=Zg8RjpP1HpIbQKyHer}k=Sg4 zc%kgpHD3~>mceo$K5Xl-Bc|f0_|UulaYt3hX_I!Z!<1KiEnQ81pC{}HjTbat(@exa ze$4*Z<;~u6Wf8e)E*8q zXUBUAGP}iPmFbn;ytFHAbTU>xG#)wi#CJ71?bMh=ByzNo;UX{OpG;}LTd(Pu=<@kB zobJl@t`&68S#pB_^g}w z$#vJ*g68X`1;M`}sa*`(j*Kp}DKq}0@q7vk}s ziA_>Vv%o)=bB3CTkI)OYdwuI9YUh&??jNDMG=3Wja0s#?VDDfkcDG6?^rkW!fru1# zw#3!!$o;4Vf#oet;lvRTanAE@S^w%ihF#5U7U;s(s+vNO7v9-TKB#G!T5+oZP-2Fr z6$X+Y>wWjGG$x!5Uz=gshqIqVsy**t?AMF59@QKvuHWs_D>|9?WXO~X zFRq^wh5(jJg;v9$kD0$`7iyK^*;((&ZZ&Wk;=AZi*_D`s%etDg&uYF>>HLY%%Yk2; z=AoaMWQABcb8V(hti#DTR76#FHuUO;`|V-Pdz3)S=NHu3`1Ov+A`pFy^zPm3#f6&m z)5z%2ZF44C_NEvWTlAhu!vw@d-ricCSynbnkJ>o)^)^Y?wop507jgQ0%+x1Wb7?DK z4osZsKl;6raZRLsKq{b*>2m`w+V_f>6S5=iDrNEfBDMVa*b+Dq$Zsdk%9`)C-0HhG zMKnm;(taq2b zz}5AvA6ow?RorR0X&{JC>7#pV@gB?R#f#OHgrq7vT zHvNf34=73#;uO(myNkqGIEf%JE{4pmaN?_qWvB%5T>oV5JZ?(#;u&Xlc6OU*hM9jS z*_VA}(|J#BW0rouBT8_Kc&rV)Yc4%f_KV7FVw==+YH~6|>LMy~5CG+>OzjB8Uk_eB zy5Sk?qL*HHFzH8cuq7U-c%gj$Q?+nSBFGlCuF0-Y;YFSHUV%Ncmzb{JVNEE;k*v^m zC}xKm031`=UmSB;m^ms)ed<2t^_Ah`MH?R6pK*p3R5MW%fSw*4B)ZSL@ec6(V_9?A zhF_kPRQ6F?dv#fPIZwhI*BeI(k(BIg8D+~@wueJm6 zbZ1Xq=eWFfXo=$nUCz4=6$)7fY1j^S);VZbC*w9w0xgK{rZ@|SUI_5?x@3Td)m8bO zjAvRW9vt^WOGbINNAdMxSi)d`b5} zWthcG$E*Atd13v;wS|}GhQ(3^8e=-&f=PQ05zeN9Bwo9zZfiqnPxc|*tLW*TXXoX4 zCiKP#iA_o9`=KJw3K=?(cXg$`(?qKt8_#}pmv?@!D|DMFU1kQ^?E6*>{;q9Ti*#v^ zG4m~c?bZ1{T*_~G(K-P{9DmIwp0XP#c=fqd;#5t1QYqp=N@2xT-DWs~QaYCL_Uc0w z{is@x+o3l*3E_XH{CizSN{=%puHPT}eC@1t_Dy=Hj52gzUhMZ!d8+}bXP_!r%-X)r zo(-6tf(6~)c*lp*OO5gEx0*{#mv6qcS^xY-SXdY!GR!;cbJ^-NTVZQwTl{oj$z!h- z+1#?c=wDUlF?813)5EfDr;gapn1g2*L6|^~ZA`p$b#-6F-x&?K>6M=-cj2V@Kx91a ztK?zuBw&h9?J}@^l zO8uxsk&r%b+4V+vq?mQTe<*gY62!cSNF7Pi6HNZL4bf8q_{<2WSnj1 zW!1Np+y~QUw;XJFc4&@GH5uw_=&c-Vr;sHi9EFbefkQQ@M%?<5A(Yj6uvY~vDMIKt zOzWgnW>Hd{PBh{is%*z12AuV(q>p`3UAr`vje{^*yeHOKyH)p`=UaZV)AnxT5%{*T ziMQC5GryhS5Au&BO@)4(WTYp1__EpoE!0Io!A8e+_7irMvuL-tO0lA}|m;|XK z<@6YESa$=F3*ENf?@ZdHTYA&k=kWdzZ3u?R$^I}oN9!Y27M&Q$GOnqG0z3F2mG#Z+ zM!n15##5aBW=aZ>nkYw3ga(Nb5Ha*)Qr_>OfrU-G<3C-nqFUF;lob{8Sq6$-xz0H; zg$i+08e(8z06ZZd^NbmKpP6G5_8i!|n2n3AU~92s@P&VUw*uHyL|&T!^v&JQO(<#( zxD?(r#scYxK7IN$G}ks4&$v`i4^_aWRmkrRRvZ_$vbLrL!MIK*lI>oe3n>hd>Ov~Q zA7o74N6E3;(<-7Szl|&CWhfvcaQT#;0}*u6_Ua;q)VDc*3VXEjGRA;?z*383@n!NlauGGf~ItZi2n8 zL#6P%GOFtC2JFP}l$JQLe{n7G7WCek`y7Z?gDN~m3R(9ud!SDo0LQ8krOxx!E(^7d zURxhGD@d0ZJGBbWz7Y)QU+Ty&;4{MUr2qiGcoj18lnWb;$g* zmLXHaGLLzytRyW1!^o+SkWe!X`ju(|qpd@72ZsP=U_z;Koq;2w(MYl0H#mC1_3fH?L z-&0f8#Z-obWvcI%Ql@DkuTVI2T@Rn4>o3HxQtvjYL-gum z>H2fk!3{0ML7%4aO?~uEhPSIloB5l01UROH4m$98Cs zXBvRZ!=|++=@8z#bflz}?yHLTT^q@FDIYzGWfWtCMCJ`;hCX>VktyL;E!qn(h5r*i zeWr1mqD`Tyi3*@hmLQ@D91-S0CSYf2N%jeU^RNp~GeL((eBwi|B&t0G2TaN0^i{V| z9Rsgaj;+^ci$z+QH#b-N+|7oHC=N&B215DU-*07U>s=OmQ{39F&n62sCJcI^#hCeM z27%Xx1lk^nIX+bBWajQ4JN+k+{wSR7Ln>&WGp;O4rlksYW;0EoWAKRR!rYwuQ?#8u zFg8-q7FlVjbl=o=#Of=~RHow3XiA<+YBcCCyGv8d84_+wU(_h_>@JUf);Z0FJ1GnJ z^~TaRvw*SN+~%M6hO$Z#Q zN$kvl+2JQ`xsD+fP)=DQ!iVs6`22KBflM%>$DT+e^#D=w)R+adPg;Aw2IimnXZdTq zQo`4AxC^2ncpaXI@DlSH{{taZ{}V!%9{)Flr~{jiW7+L#?G;pjj_U733)Q9zS6UuM zq~{Ju4r`}`kc{Mzi@wLKq$%ZbEj_9f1a3aR!l&tX9cI+#a`r#hN)BE|Apl6Lrp%F+ zHgh5-qE|39YzT)kGCHrPD!0V6(bFhns#u#TptbA7sP6dse3>mnGlkm#Q&|Za=j$hR zSlG{37mj3rOmRVO2)U<6DSmd+I73H@Eoelj{2B_Z2Y=e<|{36@5kcO=xHXHtI!ErV6n0^pD+14TT)NG zdGqG#;-WIr{p;7S4P$9?A|g{=T{znp+^;HrZ^PS!*#nF46m*vcaj?lOKfQ{k=w1^D z2#nR@UD%r`H|dF{Ts0y!jrOI7!C#iV-g+sf3S=R5VtS=i(l^k_H?;S@Zl&Ri5w_O! zwJI1$RYhEy?*V64XEU@DZh=6kvDqx@aOIG=*S8i)ml{;DQak)wgYRDIYXx?JKHb zog}LGsZ!KT<@o4eEV6HCGMDHPgT`!`F+~rcj+vaOQx3DX?}+;rUX*DLEVjc38Ncd& zQ;#SCqFB+|NCfCojZn3mpoe2p1fZ-e<}?#4q~}QMcTzll*jr+k|2egpf6eFTj~@i| zLlo;FR~^!*~%iEvdwo#GqhW z86TH~tMXOG2QxwhV}s!&?|qNUw^{?ja=Cr(;hX12E&SH-$sm>$NEkoa1JW0hk|3RD zGbxs$ANWg8ERvfm#t9xMebwD*@;i0Z?6P>Dto%Kd&+dyO5)3rOH)Zb*&=vk*`C*5q zAsKg4c(cS}GGw!u9lpK0i_BBP*C*T$yCpak_dBs)pYGvz#)?WRamSLf9en8gp8LQJ zJZ#-RcoHcUR>cp+yUVKiNYBcBu~38B6}Mx?mZwL6#^Np|gzD{&e~xp|QOr<$*!nw1H=W?pTyLBs6e$ zp^jIbKKy*=++4GGFGI|Uv^`E4jI+C18x{Ea2!TuK2gLRTV(UPjnL(aSvnS57lY*iU zKQI?A=50QI9st&q_NUO{(5bg>mm+5%I7SQ=>?6us6!XbFNWL@LJUH8#w+^2b^OUeC z(?}jC1<|^h#J?`)=Bl93U-V69eZW%80goFMr;Tm-0U9BdMR`2~_L|hieUGk+6OGtv zTASd!_${u59T3l9u%=;Bd9Lga^e&s13jY#ed?iry0Qgo}>G5L}6<)9WJp&d{%nd_n z6cr8VkkaMoc*Q&~`oySNM|PU88@cRo)7YxPkGt1)&HR)eUu&8jMP&R$`j;c9QL!KTF+4Cr!~l9XPOS;LG%r zd6KCbYKDf9WF&Rg@}bXBLF}Xcv$juF1H1SP4e!ns?BZGKStD$zEpI*S9?)HE*5Q|Z zD51vgi`(ZuH^uEykq3Cj|$hmf}ybW6KFoDCR zZ9+zJ#?x|mvdd@eiLBwj&PN`u?d`epgUA*XE<)kD2d02ye+M&&#&QpJyIQIl73jP> zF5)`X44@G#xcX*K7lkIm$`<(&)%=&yxX*r&gV~~ZUC3hiG1y>WUX^A4K9yj^?qc9wz#G+R9JOgspow^ zYjH^N-dRdg(&B!q{IE`BzX5L&LUU)~gdn;@�tNNt{hvpw4vjnQ^nGmzSua%t*RO z1Xq>){g_F2U3v*u0G-oxB30nkc&)=!e}8}R;OdMGET+zwKl}h%7NW=kKAe0L1}eFo<1l)m+DdI z4K!xO->8Zp9@ykf?8I`(7js%m^RmjI&*;m*i8@*1aNIPz20aB##$z#V>M#MIF8O0T z)aM{ErO-7G$F}Oo($W&l{UIXaEqiM6+TlY?rDM-68+RI8hQ&{3=u=Zzrv8_+r9NGv z-90_9&TUWWkgm<2iuc2t4+m;Kjt8%@%Dl{n@ceA+Z|y^uzHxi%_c5JGH)8Q2rHF1_ zCDpYK_4d}Au^i&1XjkL;NY=kyGO$Oj^}7|?97Mp}&A2Z;Zj=mdzH)|CzhunD(}9w5 zuJ#&#R!p-aQ=Z>898aN6C9dbt00L|;7e$#L06hGFg|~R|AQH1trfsX>X#P?!2zCp< zCk39_t6KQ&DENMaG+vg{=SvtiC{DlJ4IWd${63=nJYOSfkEw0dW*y9>{DV97IS@~m z8i&a%-sXweL^aLP3N2rus}8np-fs+d$L8{=<5HU;T^qU?5r>Q3DL*!D?G+fRbQHL&ey*gIO%WEtcucU~oCMLN` z8)$z;g+~12S1&APLm+3gE7@Gd zLYhs_wag^>nK5VVamgzVQPDbF z)4stTv9~gikz(Btus<-(a2OCyTcZaS3iiQL@Dv%A$@y$aWw=p)DvdDOBw2nja(@oe z{D5jOvL8z2>+G+iDX1RMjMcdu6fBH1{iT8u zuJ3B*+)wFPNr5Q)X-X?b74v<^`o*l>v*C|iBTDWWT=#*>U!Um3Mrh@^0sy$^4Ruqo z7r=RKVH+Li&o+tn5CrB3rSn}Bqkx_9#Urjg!Qt&nT02ddLrJs0)1(jpWV4~_5Z>Qq z$f(83fmexv__}M1N^` zk(j!m7fg?>Kz+xRGnzUiSDX|?h+&+NXUr&ag1>}mc2WWW5IY1zOr(FzVuwIAm@yLW z-vZ|IKg7lSf9PR)_*d~S;s4S5)5E_8{|Nt&9)=YEWAHEGf9w76{a=@%r2yo?fxC@4 z2PpwJP9&ipx2}YgRC*Q07?kMmLj%lVf);@eBrFW7p{RKD9)@Z2r7nZah5 literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/images/demo.png b/external/QtPropertyBrowser/doc/images/demo.png new file mode 100644 index 0000000000000000000000000000000000000000..767e77f66cf09217830b556d211a9029395abd79 GIT binary patch literal 76351 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�YJiQ*E#{%7dHn@ z{kVmVHlV|yoQ%xvTI9&EJsx)$II{K^5WwS`!8<{?d-2nw{4zmi15()sZ}erQc?LCr z)3R#wZ93-L$8Y0=i9+?eWienA#90o5-0>G)dQ)vGk_ zE|QZZeoDKX0D2h*%!mZ0a&M0Sw2w5bK08xJdJlsQF;9D2)>EH2o#bjUPIXj=YvwFaW8H81kA8x)8Xt z2^rQH=po{ev+*`Je+PJniwaR`buJh!DQ#^L&VlM@&y3cVSV+|cc?tO6lEaa4_Q3jG zcB@S1RP>xyU*w{~!G(d;Z$1_86x)m8daQ5-o&>83G;DBR!9KGoXinpN8-kCJqX&w% za^uKfJ5q?vZc2ZPMEJMMl-DXfF+v@PFLxmS@kH!a-;b?N7KwN5y9`Ct~q1{*Sb{xCg*%sjs0{ zTem=3Wp|GD0b& z7~ed1?ejL_kK}|h3mI<NQ)s@zZf#kz`!}wRve6y8buf|!Q0>U&g=`=H76DJ(5tG8tP%y97LkHbXbY*gzSPB-(bj{ znF+uZwzjs`Fc$iUEx4U|6E)(0(a1_n{($Q0A68fW057kh-JT`got-Mkw8w`Yc1O@Z zu>%2DL~_sdSFS2c+1U}&h{n+acmw)Nr}UZ4k5V=6amfVT4o2@r^g_eIBJQ=bN+H>< zkNTFwJ(@nW{UG-W#625r+lGCUcKY@1U18qx)%f?nuF-M~McOFb6Q5YJyStGQQ9kx6|mfKo7`Ny(6kgxlS0RKOB)A z94w<%2%?OpO*(BMBe21vwOGK|3aMOZU)Ybee)}KB@;aeuC+M#NexM+0!vv09n9eF? z5__$I%nt@^ol&Yk5LcMBGu~h=(cZFFAsCSVWIh9<*|pFCjslp0L&C;w`0MVA6=f};G1enfa`>^~%TRijn#V?S_dVMahZk=$I~{od)6vY7HdwK*5W^j-dJJHgzp^b#)b$ zcQrMk_1#QMmJGXB1f~!lgd;p;rAlP@f1|*afr(`%wwCX2bG^7PKo?BScyV%5Ep#Kf zrBg-$mjL+hpWDdiwd@XuUnwK$k=4K6ITOpQ63_PUkVL501MBLf7Vga_;|r0aZM-)M?^o}7_jDH5D`rEA2QWh(+nBcf7V2I(uk2r`|VYBXuig_guKV&R&>;C^H1UeE5JUU^vFmX}2^tzy0wWxXDs!WSPvNE5=QQ z7lOuoeb>jv<_ZZR)+0sjU=lC^bo%BLm(TyB|k53>y8~gt8XBE8a#<#9Glr{bc%_I-7r$SyCcDO z1}m_H+WtvQ)3)pJzp;$J-@G|(#c9=-P-rW8B$lbZvgjI!aC>1O58VuaFGQAt1Um*K z50Ak4xr@JPUmuww`33dZ)E(6Hi1!6*Z(0Cs*pMMnc40^a4E z4;mc#W!b2j*v|#s3&x2~n3^h>r-rx_6X1scA(4cK3Vt&vbL*$? z*S2r7TDS%p3mRCYeEcUstN519n0>p?@#CmUsL0zds&uD%mUgUs*zjL~ZNwgYKkqIa z`rh3gN~0my59xG3tF9oN`fs5Xjyw%K!XVU;Ul#DEkBHlR#9BbAB^s2(f^@(AQ&8BcX-=`4b^Lgtnb4QBz9l83vYc!gTKYYY$o*Xop-? zB1@JzAJILmnDHy|(V-8*v_O4{1WKnJN8VPg>5A;4$& z#iVQyE2s0~MG0OZUe>XUe{^0DUoUVfIT@KJr=}lgW`0M{I>C)42#|?Gf(7_!7-3<> z4n(3DzJwD%J5ff4?wR??KLp`2rTdmJ$UvAD4!9j84X0JcqTr82ieNryhWFR%<>{$7 zm-N!T1-YvCAsP~nUasfk<6~y_76Zb1fOe?FLV&8Ero{IMfjc%2ws-l^|J9~V0r`in z-b{uUx*v#%gxdbIS>xGpTnom>Z4n1>xK;g&g6_(g+3im`df>rVGvbneR&jnMsI-dMX>{-kj!se0D1+Ti_xS0@e%0E zBO}uQ%;Nw2j{)wTBluc~?yJzm;A>VVvZ3Mr5emd|-B`lAjvxU1A4p!U(0pw3f3|8= zYXF?sAi$dW`t|F1L?yvV!307a8So~I_(+l(YW}L%u}p#Zb^`YL);+fd@ng8)+ciEOV`m zLz)B2`Y?D*{ING3wg<4i?an7N9_*CLk?VWk_4XVj=Gd$W>{QrYdh_+SxKVT_*$fsO z`vmTqboDASzBWrDkb4&A&T!X5OoBU|qV*Pq_Jdb2EFzWQHF;4&h`^njwMDeboiVs$%`{7RT3rJgN$u(WwJbc}B8`nC=fZ1K%I?|}9Ja&4 zO*ouB<++Fe?LxW*Jh!ckn6~gk0k9(+o!bFGau^&7E3^ZP6Zl3KfM4itK{67lde*sN z&uM=HAEHdHr@n`Vp|i%+$Rd4|ak0;=&Oiy{KxhO}*#jaC&Jn(;WoF-osy&AfohZZ3 zCb+e^!eNY42k#E!)bpP$7uM&Z*@n`wI@v@B4j-iKkd1$06z87qskNFMoqd|JbCo&A zH32%EuXr}bMn_jYUSa7@Xi0OS9q$3!PJFup>y}{$q;#wyJPBY^P`)c1ha|~}5`t6# z2Ob^@Oo7D-586^gXD zc;(BN+h!aNfUSpJg+AC;S3ca#edw%pEzj!RvrR`D98BFQ%B!}VgF}{b`4CkCba68@ zA-FrasIXIk7NyopAXYRiU1tR&gxcVLAo#t))(4LPVT~e*GU1Ma;1&7FSnZ-NFK<$O zhuMjfRF|1G-Bb(x8(9qb>5{p(R94SBb+$OfDqU;og1acK5vRp6cBsO7kAgkn9RIOre$QCj{M-z}R!YU_FH9O=v1wi* z@L`gZzyH=S(qm8|x{ewW(KPs1(;aOJL_aMN?QPVpqq>@ZSK2aTLpV;l z&JQdbliyvRY~ZbDUvhS)ch!0vt{IWAwPJX!e*WV2l{1mdv#YBdCbR3ZzK7xF_xMDT z+BkDXy>5>tplo(VepG+52`ixs%WoGfo0ob4F8Je-{uiP`h#9~TtdGQW+92}Dt4Ep9e| zOZ!zXMMrNtablwxeJHhK&Dn{!=y>ah;r#QZ3P;NMPFY@~|FRgq-!{gU*5zPlSK?xj z)xG=p@7s2om&0Nu&gaScj`SN`Yzw`zX*~YT{&_>k4iXp4^RRnDl#O=>>5=@PB}0|# zzcY^hq1z*gE|u$$+x30$e4KRHCPvcxizrB7fq^fT&VOtz4Bu=yFdy_%n4kY}Rq!6Q zYJSDYtt>aB{H1fwM=sy!-(?zp*QAu&o|`LXyH0wF^zVrrgKp!~&)L`J^jm!IPS@(& zs`TfUd#31#C+t<*6ueWN0)y^;-g~Lz!QPY#&9#FctE%$%4m|pJrNq5#-2UpHT|e`m z7GcHXTNmsmiGzY1zzy{Uav~r%Lr7p(XJ;H{f8ca!Y1_!Pb#)kAu3}`sDpx#}`eej| z^d9mHLijooxv?DFHpd>vJ1#q5m#+vO{0$b}=;k{tTYFwp1DR37XW@2RS*UpS3q&eh z>DDti=5x%7Wr7G=?`McQ>&a7qpF)_k=nZ z9IY~7E!x;3aN4|_5+=s3$4FD6X-E`J*Uot;Dh{H|hE0A|^7(r06Ym)FHjsWW%o`b< zwQq}Gsjq{c4G+Ql2GgB8tK4;HWu?K;Oku^lFGVTRSn%crcl^`>mHc;?b_+WAPeudx zK(5U$*A}iMZBn`c9OwvM+g^Ya_>&Fay1Q!*V;AMy7oxw-R#C|Np6*c?9PqM(ZYk9t zVwk%@DHQ6jK?1CmnA7Z zZOhwEjjz0-OKfxEf3w8#H&x!z|5oYVD~PsTD|tMp{{GKzd%t`t@txJ4pF9rTh37>{ z?yY6A-^mXdg4OUDEbZ;L6I-WVO3ni#0gHn#;X4rnpt{2-Z9e_E!7(JnoWHwBrCTcnnR_9)z#HvdSMz< zz1P99UEFy5K-uKCZ{Of==jP(-KuFZ*gSk*}UC4x>=p52T?4pr%m=8VCGo=J_m0UrRY$? zo72M*tXQ@6BvX6in5Fwvgw?;l0LC5tAoDt(czkW|9$&WdSFa93G4XIdnSxb~2J1ih zp8jBb+9?HW04Q>!Y$0^O4Gktap8`RwV1!>f9lNIP)hh*n1c(UBrsN#mwVO9p>)OMt zroIoEePbNrH@N0#G|Ic2{y#Dqrr-_m%DVW%eK+(xScGuAk$Fz@W#>Tos`|D)*OK$g z#0U1C2wtl0sHuZvN;IO%<6Iaor=FxB*U<}4*_j&q_rBD)kDGnDLqM#H`^MHf=W{{j zRqJjn!zA;nzUb|T53OInzT9}?hWTp$$_VL0hQQ~R7Kc-REF<;BV-4+34m^SzdrT+CyZ0Hk2CoIL7i$PdP1(_& z?U%C5Z*%kT;LF3{H~0IN_9M79#@rw&JB8FvSTL!EnA-I9X~-WbDVbgSS_86Vm$Q9+ zCjK0xH$m9Ep|Wtf6Nzckd8#{~8B$iS;d_r z(qcX-S6k`efH~hUA}sX#V3zC4>-(}?$F7^-zL62P|0gZX$SS+ZBg=KJVHEs|$Dub_ z^(j4^5ET?U*PP`T5(I?)Wi3t)mnUdU3i#@YH)J}rD=@IbKx6=6j?=Wc?yi3Hmzhar zKb$LUTK5I5z0#wYT#wk&)Yw=qXp``3xb$OVE6!&l&j%Z{X7EH3BqYFCJU^wzkd6mV z@7+?B_qP^cpa26M<|uz;>Ry^aC0e$8IZkq2C>5HUB_$+&`%Iv7#rDS~pGSy*93T)| zuN#0{^Z`1PnRPGlwMzNwN}h1*zEIq~WSS^PzH*@2QIno1T z>A|u=NcOtB2@}u`t;rjM??C+lc)^$e2`Auyea?pu|H2>B_V}cPh8BkivSIHQRJENP z)b!EnKvXe6EWpHed-h;nwK4cf;@Vf!wyPmU(eF*%jh7l*7(RchVpVbXnB1A`?m2%vqe^~%5NA=2`R!i&!aZ|Hn`;~Z zycx*M7c|zq7f&Y}2M0!nO~-mE+px5p3}79#8AE_x5IO zPm3pRQ{n4VQbM9V@l^W%6Q_yj2L(aji$#}ey|CAfE5 zSeNZp?&PD(sw#d@ciKiSqUvsLvnSE0^u(QP@K}21$Dy}pPxCq_s7$_*{m{~iJLhn~ z^qRp~%T)oXK7)1`Q=aX;dTP6G1>0HJ7hxP}lXbTfl;Y+%K_Rg%<@W~{nZGaGYyOJH z9&(kl%d{fa)8d8$v3cOp)XVj4dmgy5Y(sW14mCJ34ng>i)K>SogaqD;CR?UYG=FFS zF--u0K|%8f)!2XqVR%YruRO(aO9}4CnoiWggOB4?ucwVaewo(#%K7YSded4T5ea;cJ4!OF6kN^jS=l;pJrK7nN6_qphIPJDsaH-3J~OLyV+m~aC$JD1lTvh{ox zBy!OH(#b>R&dee1GcFYoy5;A3CdbjYKSdyiiIgDLt{{K=)8-Ty5s!ngh}2gBsDv{; ze-buxr02r-`5Xff(p1BxVD1WpuK_2ekCzuz)3#5%#FBSny-W$5hagL#bH9X~*T_5B zZTbAeXG!m!?E8XsNTNxCast<9Pu_s;X5Bi3oBQIxI`;KZ+s0!z`kyh21SsKbT;aF* zrui&v3fMM%iu_pWy?mM!hwQkm+ zv!lx4k9z;rUK1h5oj1&Xw9SnbAYKnZ6~cRLpWUUinIokre(xLo81U=&lS7`KWza^h z^IBdHW+4#A&X|jbhx}K+;hN>gKdQL#Z}APd{;Tkz@EOd{E_>s-sjYtBmY#3B`0bCk zMiiYjqaPb?NRlJz6#J=L8F6Zls+eB9KlnszX=20bqpyMuZY~+Z8HZB{%{~?(oP^v! z^EucfC>g1!P?;J0t);LU`jq)a!7r+!JCE8jN1-6hGJ z#UDlqGu%@SEOjG-_rdIgzXWjb028Bn>|33!>N{$WxQy6QA zq@H89>ml*cgp&JicNvJ>6%IboeLr-?hUKSe`pjC2yhUk(TIQdcnqQF<=vOQW5u>N_ zQ-$Nc&bkIYPEPhkY*E$B;fA}1%{*9l_uvG_d~dRKYe&b+Dh|tZ&|$Ei9&pdPecNem z`3Q5cwxY_~$1~BJ;sr>?^nKV|vSewZ#?kL4*-sCwIDXOPJ4nFMHGLyG#9vr`XJ~wU zP?=Nkbt1*w(sJ|OCUe1*0fxBx?vj=FV03d_i`50xqkMb^#(1dJ&UxmyRihpspXe`~ zoK!0+2oNl?cRgq=?HFNd$WLdMU3+2gi|G2Q>(|5~1ysw9qM(<9>ZoP8PC;{}$cbLD zrvp7bh}!o%xbEO7<-$F$TGzmc8l2}xA_>!9)h4+Ulg%5pwX8(Z)5KdG!fC6hcx&}z zAVI0da|n|(y;^29g;{dLSR{yveOD4T&c8e(Y*5X}#FTmK7O2ZjEe@6}eT?i}tmG=n zqf1J(;-N}50A)bAY%}%(LxH1!fu6qi`2%7VkK#H#fB#8rsQWb4ajW@@%OPar0?Ywb zd~o2*;=Mt_t$|(9lmd@z5wtG;}?bspfF=s=VzoB+k1}=JbBPPOVT8yrQt7% z(biRd@_vh(+s(rpt^P2SKb4<{xbk9WwxI+!PohU=`Z}h`N6&j4mg2yZ*AvAoCMAx! z1cl*()>Ia(YV$L%=YI>DDQaoii&FIU^>JA)pc{XANljH#Ow0*-4iK~l9-Tmjis}*E z%t#s9cj!>l+0o?7my4k+#a>EN26b>0DuL=5!4x_!^Q&bsSxx#f6KV=!zs%sYYC$vz zJ`Fx)AG`RzCfk0_O#QI&M=6(%8(ll{sw5()VF zc$(I}0b|CqMV|N^q7+hjyUX6a1@LA)+C`98A!`q|=Zt1eBo@@fo) z`ZTdbSdy3Z`0`Mv{58;kpqYRAu1^*M`-Mf@q11E?)N;; zIp1@h^UNRjq^n_OKFj<4+TJQS+RDhwvwh8 zT$6c|9+~=j8iA~H8f6ZY+qI|36P3tOdHdIdbg~_lE`gIBR{X)#V^rE&2E7~Ub*gjL z&;^dHzG{V{H>4yQGSBrTocHl&)oUSd6< z_mmIat<6@_AVnl2*-qUyc3wjOved>@_3hU}GUw^TO&M?HYqp#ei$nGKB#O5@qo1YR zRBGJJ?d%uDi(@KF3u=A^m%S+L%vzMN!3V4i3MQL|Y3Pk__HLU(O>^}qF>lSC0|>iN z$B}r1JrlGp>}0=A#gR>_-O5hY;jllHnz>@k3_hxJK0Y0VPJ5B|XpzIi&Ao{1J0`*q z+axyA5PT%(2u@>s7nE|B#-0yC4~MxVA+{zvo|FxpD7rm0Y@_Zed#l`)(z!_>5?Est zZRfKHt#m!inO*Urm8Smwz^TJeS}wINpw0T2Rqr+yeDrr+^tkru6$cOaj&XNwTd8KN z$ozCdSWYdkG1GE7nn1=5LG)xT9g?aI;XIvl5!@}K={gHg&zK7d!uUK^;`B(Nm_tDV zRXk!SO;a@E`F$`j0SSYUWP@jbv|R&IBGinygfT4;-k?5nrs7EB;^scO4T<@=2|FAPM*Pvd>~8Lh(eci3 z>fl*7$+%#fL9PovQS~*bVVs*7yTqKFar34MEIJvKSerZr=1j7MkwPOz?+CG8ZYE>QDPe zHgE7RrbzqHq4Xo$+-}DP&%>64akzx16|G{+bHjPb5D|jXJTnj704Uwn`pB^}nMGqQ z3!kx+PO7sTrf6Ncas?Dx_zhgt4^jiT5-Q3I?R_DY>@qlPi>+vPF%d8F@Zp>1Dxw;d z(6pnMMj45CKNxB-V9Gc468NcF=)Ic=ksu==dDRS<8bU8-u-+UPYke^;9Na`w*kq7= zrEBD@J#1%}H-a1I!=wCs=6M6TAv1wBKK{)ZbEXG+8b6%iV5pFH+95c7*wS*w)ADgK zCGXybq=y+m&DmGrh2| zn#((W;QBx>8AIT=1HrzCr8>)Ua0K&Ry5_65jA^aBE6YFe-I zz!~8`+jS9i%DXXiKFEh(eftNFYA9TZ4BI$07>VB`CJhE}lErXj)^+ z4czkkcTFHjW;#pYA9Z+%#Ke6Y!*3+o2e^T4!_|jGJ{$otV~4BXzRiMv+LJ<|6c3{h zg&i*+dnGqFYLn%|`PauA4_~$3E;&d0 zYmb0-VE(H!jbrjND>AQNlUaYYZB^vDz3%LNwJLq@7(G>btHGEJGAnHo_TE3p|&@RKJvWieEjgf}YNp46yZ=XO4qXxp_V*G4qx zLcPHieWy;RlSx-TS%*Olt4w0NTB5*ZG6^e*?@Jgisnx)(u3x_{2b=@CDLfuNZ2J#T z{7~pea|}++R3aoOMu#+BVMw zhWzgp<7iOlQ0&n+HuiB0T~9=V6roZXVh=PKcomvo()b@EA_Xu5A1E`NGeAxo_n<-> z94V*(qQOlhQh0<`Lmdj67F^^YH!1dk9=NQSFVv4ISk&Q9(@89zjjO+=O;-CXEmMO# zd!?ps)+O{V?NF3@uWs)w}6235>4hK2O# z)APkWD}C3dH>4TmE)18Pc%G7C2Z#dx<)vpQ-f+FBx++2WbI(UbbQ*XhTWWwm#!+U| zScegpI|pY9nRV9&WYcS8W^~XAcci^0&epRpr()?2cA6yDl!4Iet zy&5AffO8*2&=@~=6%6BX*KvLwqo9B^=6HvFz|AIWTp574H)1C*kcEoH*| zQI!x=V9A~)#@OVgDmqo;R!L4y2B!?a^4~|c!PAPdCaifZ-4;2w)?xaEd8P&I&wzA* z5%fPFOhwIe7u?NBtFJJfC#R;4_4e-N{O8>}#GGej+At(iWG1%Qr~nVzp`b8uS_m1+ z>>M14w{Cea!!OrR6tspEidcnL`EmT!d(Ih5p-j7MI-rEEeCM z5L&~jC|>8Vqadr57NJ9zfh-P^0PHyT+&9?W+l5~j7CABt&0V{9r)m2A`PK=p#J^Ec zVVVw>0w7+*Uwvt9ErG)aHU&7_e71U^@j;Ee9U#fMbD(_onVQyr{8&25RTeP4Z6pYg zbUF0ohW49-7$F($(5JlHbRM7uphO^h2%(u>p4yTTWc#|j61LC+%1#0OsrNj+QledR zl#wjuv2}Bf4cfO0WasGhJfXUduCB5Ik*X;|m#K=6KIn;t@G^f}o*Vy1&C+am`~O|B zy#FT8Om+gmS}Km{g?0;ha!lf>pBY*Kd(TQo2~~G(%yJF@3xKy~dclk+HK$*SuD)X)E=-yp~3B7e7h?8>d#aBlfoVfp2y}FLvFBMCcJE_$pm{0e~%9fe{d4HH#ctbk$FFNLFmbEfz^~1cD|Edm+3^+Q?!uEcER`K%cKCJOL^f`|WXsXnexZ)2qp|5^^($m~E%lati})g+ z%^Slx5-j<;vnQ1dzW~I<4|eQR2=zFf&S%=Imxyn?^Q{S9`Im_2{3?4&1Jh_DABqi? z?uy=WgXJ-@onJ6kq?|V9bo25Oi8Pp*nZb#CX)xuYFL5m>Hr&9L`N!Ma+OjofFiiqC zuqOaQjIP6a?qs5zT`%PqA4J8(;FHky{u*MFchJ~4pg-PfJ54#>_#~#*CML7SP8e}$ zP3oZk^lqm;`@O9&&#<{C>Vt8OPPRj-nmMCzG;Zj_z3cDP* z<&hr$yQsA)pfH{a4ZqD(|K`dl|7bHVlt)0_a z?d9@`{ zc1qPr`AIV}Sqd2*Vsw2u^EKSy-^X{(l-4yinm?U)*m0QX-7_F=jN*9AAQU5`)Sp6D@tFm&(Sqz zjE2U}xVx*G-#%AnNe~V4vo3E~9ubP28j$Ds>^KkN&!Ct)9d}l(x1+};a2WfuM zv%>2O-3w_NiWydfz?a(ux$^G(05jNi_R#|=sg}^WL{@iOn6Mgy*PBew&jv>C=@3U_ zlvS)dVZ-7$(ONYzxV~p{oO*D>##4`7d*m{-Nhe$CZfX^IAH#uT2<~+Eindoa+GJDI z#>NpG{^k?&vx^x8woea&H+%jZ($D+5UkjSLXmhg>^3>LF+wrBWPpo@Mj@^{wj4>s^ zO3=OeX6ww8=yh{*{#|=d)9dgWU{{0ixOiBVaS}6TEON?_cDLK;?d9>CV`H9I^zYr> zcV2AN$BKBHC75LlTRZK?=4N)h(<>h|Zu%a{@{o0sULW~9v`JSgqCf4H0L%WQ-J`=r z`Bb~J1|>t~b;tG~2XSVLtlEPC^HH_v%g*;J)vktKVvvfl0GWFFDA3kX^?U^KpeAlI$uy%a5*^0F-JUThPC{{w7O{qT~ zK8eJ}o;c1APa9i1I^M4w_#1{IzKNU@!IN|&o+7g(m8n*8=Y21C7MYhBF2mH$SJc*} z4#9$Srx>-UuRew&pPi3Jdl=WVmRwybmRidanL0E-wITn6?ST8SNrZ=$T>R-vXc}$& zi%ypNJ}$RPW`0o6+|0j{HeS?T`_r$rSBqS~WmgubyR)c7Jp(C9aFsKOGbajDvq;ko?d=NI4D*|1POBWi`3s^lfL8h=-5zH%zxjls`MZ z{Gd#n{Ql*+2lvjm3!23YE;&!!h)bP0w^+xxbuq&vlTqhl*4@n!?0KPLOR$~obk=>3 zXLmU}hKkxLHN5g^WQ-sj7>OXstR;otW$_+;iovP4Z8R_gbjcswUCt3rbl+fwUV&0X za0wphC|V_2+trbW;t35rq#U4cQ7!@x(jiYVwVvVOpMD?$6o1s`{KISgGBmv zIu-9XNPSnN*4j`%CA0pVC*IJTTXD5@RXA(qSFM!OMv~Db8s3|dPP$_-_L*dr&(ju$ zaxyL-H{=@ypV=7xsLjfF_JV+4RfW(ca>BXoKZcEtQyB}M9ws6(8^@2=$B6t9^a zpgoZ39-`>|s&-Vu9glwvRNC#L+z#kUF<|QS$n!q5`e^DOww{S0kpWf3|KoBfLI|L# zvAlIm7aPhN+@g>tcP>YShkI|Q8aU`u&$h^^$V=eR9~HC1$ghEZ% z%V|g(?93S#9hS)oTjwJAjka*`^j?un3*56g1^NEnRR`)9@#=vt41TzC7+9KRZW?Lk zm}cJ&Wn~}epMXom?b`^Eif`2e>K;yacL1d|CzR$%9A#iuQBP%Kv@-Y|2r8Q6`0#p= zE>CvbcEw%>M(mU!O%Y;^w){dXUmD-_zCU0?h9wP`VfNiAKlqqk?fu$L zoeJx5m)bJnfj3#?^Ce22FJ>bi^w9?Lo$~MNtR%M6N$ffW3vCUv_hkcIg1+dnZ4CH} zBV~Z_0d+*%cTwcn3g9KK-#=P31MzZts! z)(#-ibz`m36Y9InJr0=q`_G~GgBCQKn9ToIV&d#)TQ96)^xbDWp18e;80{z-0SYG& z>4GL3mzirbW|ipxlSE_zum%G|LwT@QX^C_MA)DP%K8aXoeA5<2B^IZ=;V&%3wt4J{9!)#2scC-lD zXRCzeZr(V1z;x`6*uMJ?b!kgm66;=-m9=@)+dXoR61^HhROG=GJ8t>@Hi}))Q*E(c zWj|NiTKV?k`eBady(^=pmLR_kg1%a(6=nL;{4Vf$y1Mo<)Y*kM^Apnf2+|S+f6m#q ze!m6U+=KA^O4R+m#2G+haqNdJ z9F1;K?kQvvB@G2TTh%Li1|70yoO->6aWI?>=)!|&-(e+juin*s+LZCn?7J>zw~pbS zJ5IyAb!O~121E2~C+$JB`83ZX-rqkZm@6X5NrLpa?f!7Qaw&PUcs~m=>ErejgtAOlT#Gnwrel4-;uG zBSzwu#QrItSz|Z(-dfHzb@xR+o!4JO9!ef4oKR*mv}Hmu<(bERRI{Kk4(EUI;b!?4 zOYXBX>S}6Y7b<=Z?sU4=uY-7Lt-_U|1?Kf(`lkkDHk7lb^Eo;t?>cwcvF9YgQJ+xh z+%uH0Ss)TFAQ@XbD968i`NI39^q?wPLxP`-XcV$XBiLtWN>sJdRgeIHFQ>u=@kbhtY?Rv|0kg(EJ8b9%P$91OKR(IE) zgtx+m3sY4#dHrV28yjakBFeYyx36aG4eMtt)go7OIUy@Q*^+e(v9h|n*NI{z>;tfeXa0TjRkCd z9%2xb-3Guq(BwOPu{5Dh(w}#F(JwLoS>;12MxitLXTt3g?9Wi9nY7D{R=dax43Q7fKa(f0FJ{7;gK*jU00Y~ z^skLbK;tdvH+5CFZ|UjBO=e9*UU8#)D_KA=|9WuiE_~#D5z5INWBTh6vWXRoI8mbUUqz_d@6EF+`5`&C{76@o4 zf(Q|jE+7F!q>Ug=nsjOMgN|$d`s=^7?mOq*b?&>T?0wIB_v~yed3gXlEG#U%P{{d< zEG)mtGW8;^Bh33LQ>g)_;JyWMMY6CQ3uW3E{^ssZO=eDV-iE@=Io}`Q0j(5}W&u-XFa_+00=)@0FkCsxXMCS;*@pHi; zeL>cpnWG-xvg}z!s^{+#b~4vFNZBFA7r~)ii0sQ|fZdNKt}jc===6in?dcn-I`To` zseL}Xi8`r4>R-z*452LOCz42ESC9t`Gw_XqOR0`_5~gnN$E52Wbhn(((q0r67S`1n z^>~nazqh{Qh-cSPtMZ$lIlCjTCy_+j{-m&*Sub+ir(*+>Nc4erMx&DF!~9;9`1ulu zL@@vWXEk53#YZ7VRz(1G10PkDjw%W#kqi)hD^nU6L+z<>a@-dI#>oXSt<@1)3xjcy zKJMY-lI2ow$-R@KPYaB?y7@%s=;jsO_C(nUv4g=T-k|*F(E@8GK~|kBluS!zthFaD zI){!fmh=-RCQjf=(0*}3rzyFH36+VvNtj0!GZQ1?F)d^UL)$_3rQtz#g*C<3VQtUV zNF(c13uPee@rQSrz2O$7sr^Scbo}6{m6D^OU#2Hj_*0qgg{X{>u7u66?*`USeiyK% zr%uG3!1uQ|vB1 zJz@~%-O3-WC0p#vsn(~W=J4jG)FBY)F&{>hVl$)8jz9Xm&F_WB|M};cN?NB@^JK&C zl+P^<+dYr2=@tK8-Nj2&?t0t@Pi6mp?E#3`xM=`mu32w>s$*?CI+S zg{#BCor~Ni)+_(+Qa!tU4Oyr@P9RJZ=Twx`)ys;CAZ26T*%RI>>B|kPPOD~B#$Rq< zh8}oUSNiKr)93#O+6$YE*@Ma zOdWj|X$}wHxAxcc3$?s_`EpcL6i}eeoj#~ISm9FydHhfeQaTSO4eg=Ex{>~3=IB$~ zh!S~{7>H8b&M3Xe8lHb1Mi=_)_S&U=b=T^x8sxAI#}#^qq2JfRksL;?*6e@6R)v*!(yk;&Z zbUIycW~nr#dJl^fa&$rnQYr2+XS7F)^0k7~-*0}T7JJP(7mKRdEj@VoN0=wfLr>Zk zl6MKEqBpwBsd$j>AT}m~K0NdexxXC|2M}J~i}FNTH>R{&<oBvEl}i z-@X3hCXD!gcz`4W5Zezq|`z?C@Wbh=KvJw`)&S?PYr07uHrjJP-*sAGCS zv8%VV0uospr4&)(ue02_%UN`FSBa3`eW6yen3-YFeyjhf5jT9|z+r^VwYrH^BD zinoWinPph6n!?w(c-z&Q*=Ewr#rGTXpE=tqGOK&F>Xkc()PmA8;3<8ykGPYH_UYEV ziZU*1-Cp!w3M1!A279wrFpL>1C1W&?IvoXz&8wK~pA5np{W_+V`7kZS`>2?#zEztq zJ7$Lf@J^?_t?sw{kPCrz!eRJ=QmBXgV(r`&)F-S1?|&`DH|X;;Nd|9!x4r+-HfV1{ zr>;QtpY*{SKs-%j&$N0M3A8hCa4;7FYm&m+^t9Ft;=Zyf!tAe_koar01#)t70w< zJ<)f-(!6(HHLqk^eH`$MNtzAH*#|NfVBPM3cD3$N zDFmO~BB9V9q(1_#CQkfbckbi6wi>U#n)%G3+;)n0S$rG;7V;J+Pe*sMdVwBT#H&VM zI&)nZA|~FTJhUL1#OwR(UVXnkJqDoCf&=ZI<{tkf-*MWS z;J$k``T=Ot^X%$GYqKmWu`<`oR+42N81dfgc3zyV;%Wp3qw>c!7d2QPV+H|u<=ld#T zcYW=*FURpgfUrc6_z~e&kK>4MG;rj&Y{RlW2SN|%Y|g)~$+g5ojs${P z*%)D=*Qltj<>{DcP!Dp~dEC!c=)phHsFu&s6=S&e@Y#aRsXnf_bW4-2)IMK{LY#aJvM0(NWOrjZKTf=nUDez4oUB(+0T}*rq z8aJ!!!w!dnAQktY-MO^NZvG%`Q^FPt)iyNB?y*lVY1Q1V8m^0v`;_i8zi?x#W2gv{ zwFo8zFdFtZhcSOWNd_YD!Yf$leMfp+y?c(cIgbS%)Y-u|R%l@KFl0C$G)&$nD%8z@ z+Q~zthU#$P5jnZza*WsXcA2mL3j5vV3#f; zW~Ti#LI!>QLfN>CIbqUB1|KBR^f*9#U6*VY1ioI6ZkRif`W@nrO zurZj#XG%!?p?;1KQ2~Qzt-&3n_rk zw__`d(tOr;-K8Ay8;fcs_a4dgPvFWW!2n1)n9%D@?Dfu|s>%wPcl$5llB_M$PJY@# z$opsQ(NaYjs&%aXKsBw3u05xOUiftoBt2$Bks-|VR12bgM1Fz{ZIHbl-NJzYs<}Da z#cgSV2JzKP$qD?CZ=l)+o|92be`O*q*?vaH1P~KMM-V^9cpwYdVP}}v7q!u-?zY{M zvt`1&6ul1;FBo2!U7za%t={H3=k_wK;HuM5B|l#uDF0xke3^~Kc^&v3C*EEbjxs;mTB)U z`JRVyN@c1sBUvhVGK#=1wgZ)dGoIYdu0Rq-OWx?m!lb*(Cbk~=Kml7vw8|h&19{s6 zdDOduK-jFh3`B6RWHZ>DFkPGdaB@G2&<4+M&o78Kk{LS%i%HFi7##ER8yTC@3(qPD zBPS^g-U;C~pAI8@e+a1KW-?U~*VE_t_UjoYYb$5Z+U9{<)<9{S`-MJ|G2a!%3j&O7 zn+kotLhbZVnsBG^KR5e^VihHS+L25_G8xV+7!zdxw*OU`o#)r=FZE|X`Z4=|)SvC^ zhwU%*M^nqql3V=n%#-;E!zv&&F2j?YsE8|g_5Kj~!EYa>bAZ#-e(eqX=?##11TmfZ zZ^3*cbMjrkEVX!E$1Rrm4=Udv50UMS(L83^bAIT6MWrj-4@vR5!u+phftuT#FEhOw F_a8dJpCkYP literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/images/object_controller.png b/external/QtPropertyBrowser/doc/images/object_controller.png new file mode 100644 index 0000000000000000000000000000000000000000..e490e6d5371adf0afd0928ce3ff97601f7048024 GIT binary patch literal 39658 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 Yu8XGlt*q6I_7=Rfj_RpDRI?8GKW8Fbv;Y7A literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/images/qt-logo.png b/external/QtPropertyBrowser/doc/images/qt-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..794162f5af58e7b38beebf472842fc9703ede19b GIT binary patch literal 4075 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 literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/images/qtbuttonpropertybrowser.png b/external/QtPropertyBrowser/doc/images/qtbuttonpropertybrowser.png new file mode 100644 index 0000000000000000000000000000000000000000..7890fdb04d942505e8198a02b913e76fd75800e8 GIT binary patch literal 7181 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 NQIJ)YDU&ks|1T1HXA1xT literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/images/qtgroupboxpropertybrowser.png b/external/QtPropertyBrowser/doc/images/qtgroupboxpropertybrowser.png new file mode 100644 index 0000000000000000000000000000000000000000..203c50f06dcdbc38cd4231b4df74879eed1a2fdf GIT binary patch literal 5819 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 literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/images/qtpropertybrowser-duplicate.png b/external/QtPropertyBrowser/doc/images/qtpropertybrowser-duplicate.png new file mode 100644 index 0000000000000000000000000000000000000000..0a939fc3066d2891fc14f6dc6286c12c29cf84c1 GIT binary patch literal 1620 zcmZvcdoZd$rYM4t#Kcw`KiXuugn8u_~=&>e}OpQT_VP?6#=0{Adq|{Y6 zGG2)uq?E_?N-8QN@@5{)FinhiXvF=w-F5%EXPtHSUVDGnI^Xp^tN`; z74x`bm|}WSB&I3;)2@J8`s*u|gv6BNBkqUop8Qam6wJ8>=I<%8=+a<_N8YupfaMAw zSJv$icD!gVHbrZ_ctoq3wL=fc5aZ#qp<6+x8av>))E~`_VSyFz>man|FuJ=?Ewc{S z{k9G&zNS-pBjg_B5K^N{x15AQJ;3^z{I;sKx-rleRDGuNUDDHN3fUp-WuaC@29 z?^Ria#tmcOa8OaWRh>>}PB0vC(&NWTq#dVg_M$8OG}25C;w*3fvf3QS0_Px)#nrSI zW)<48E{9{BG4QgN1oa@s^61R(8q<3E0PZuxai`ba*QDCPD=e^~L)Ek(mvT9Td*70V zPIruh00qj(Bd^YZxKRTuM15UKgAd<$#8rgVn+I+oyb(F}{HCp6f zQnmB@O$~U(4h)?6*x_TmCTxPF{C`2DNq&K_um1(&d}0z2(ia%9E!IX6to|Z}u%Voq zy*B6L36 z++E2DROgj%eG4A|(shCoR}ic5Czv)_qtNLM1<93n#EIMDDVwCFr()xL?Q|M{2S_{+ zOWXn$G&3+(8F0|_o&|F}@D%37qBUg`mieg-fQv8{!&0v8a%erVZP?xu_l3wE)@o$zeJmyDjAaov&~K-EoyHV%|& zQbeEn>O_7ob2jh1U>p4AgLEO$=Rhg@i0=25R$A2u$&Am6<^Z6?Aop8nTIlKR&Yyg} zpF5Hgeb$we-2vntY!o5cEga+h3(Huk+Y0oA!wD+~p*$+6KjpE)V>R>}|D^|cXHKJk zAzd1lwtWY>SffT-TXm;Zc&dn+UFOzo_u6u|5aOQ(x3Z!&6wMQd8u^ipEwkB#oN9?v zqTK$|7Tt;GhI)ES@J1V8M6eO`VW@cyD=y!{5%ZK*qmJkNYz8B4246JO9klNm>kiOV zG`BfG*5xh#y&rSN6Zct%V~lwA?NWFoc*S(nOpSTe9GrQmC3qxe-Bz=70`MZs)~PBi zZ43i`=LP^5DdFvyVnuU{$%so{<^#L?%3IdDx8kcTavMx!EsGEAj-zf@t<0)-*xYMR z^U50(H(KN-82c8x9o-|(*o_UKY>PNG9`QK&`G=r7b&-Ql`^Q{c}xH(bzV-*AB^y922IX$#+J(es2-X6*{NNL2ozlw^=R8 zc1(2AG2p4`oP+AFb3n`W!#lI_QphWR{{RBv+@W4!-c;&z18f literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/images/qtpropertybrowser.png b/external/QtPropertyBrowser/doc/images/qtpropertybrowser.png new file mode 100644 index 0000000000000000000000000000000000000000..1f0403af24777f12af953f7da6383420625f0c46 GIT binary patch literal 9677 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 I%yZxW0Z@#nLjV8( literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/images/simple.png b/external/QtPropertyBrowser/doc/images/simple.png new file mode 100644 index 0000000000000000000000000000000000000000..56048d5dfd2f447805f1fbf7cb8e3e7a764e90e3 GIT binary patch literal 9548 zcmaia2Rv2(|G#ykW9JyzBOEJ|LPpoMbK@FCHp$3N_8!+rMaYP_H!>S~=hkO@zrX+g@&7$MIOp-c@Ao;c@q9gBQ9H#~@ls6634mxxVF3Zvmg^1GT>RmlfQXiiFr-He|7NJMmINmE71 zz-MITsee4?n*k=p65l`RmZ0mdtN%3#Pnj>P}mrS(_So5InvYwZbyfVT_z2 zJsW-8RkdDecX>GWTv3%y)n;h8Dcy1XmfLZ=+(qmABCCUJLBSM2_Udr-xr()(^yB#m zN5kjkMx6z$BtuI0*{%mHGi5Z-+*>;`%V?~7AF)AZ0Ur8gfF49^~HZ{<~*Nqo(npYb?%wob>mY%zn}e_3?UGbi%N z60XP3+i;Ap$l}6Mla}EtqxE;Bv}mUq`;X4YCJpae`^3%V=Qn%>gO&_?2MDK+x?Xq$ z_usTDDdM}peuo8^sUPCs(o9is``p4TZd_)6bhy`?`-#nar*-62vaI(fi`P?C9b*VuPp-?W35;KhQ@biRSiy%+f=ctV2D`pL8oKP;s9Xoz`ikRj$M+jqvWKbN?Ca&1 zxPtCO(yy#`TfBqzDb=avf*lG~(6Og<&lVCCLmviJHsy^Sj`bwFXRF6Cnaa3)OmcVj z5PW*Ux&PVZi=iej&e8S5*N8Z-;00ja5It|=OATaQ_I*1{R`~R@n6$j-=LYABQX@m- zW<&MvO9%eqs(@+?{6;08T}0*a_reK1xhZPG*SA zy0bj&pr5Dxs}<2%{?f9Xw%>8LsZFPPcF)Zhb1JAHmGOq5v4>BnI2B5%PS9xS++^Tl zLYB+#H-=LjdDQRd<*a2WK`euAJ>=DHOL+}G{g)ruGX%GkL7F2`Fl^jfY2OZT`c6FH zQ!i&9m-OsN5;||!#UAuoaz$9?L;0GVZR@9|$<$I5I<|qY*jHZCFo|6v(I{{%K{<7I z!@=<00G~(mV@fEx$yn1zha~1I`AbV|+r)1F^UI@7FuKYj`Px2S+R04e#XeI>VjIMi za)-6kzqi;@>^CLHo)50loF2qB(0S9e>10YfHQm=t6u6opyo1!+u?B0Kh-3>MOZuBcR7QIr2F{lq6OpDGmK`>heJ zgpN(f36$CNYQm%jOy-`^sa=T^D`e1Sk(=GDv0&R7pNwNUUw;e3XQGo;wS24Pp3H|{ ztzVicg-+Gm>uY1pu$Tp$fJItQ=BDHux3!J3Q5s#O=-8=eYBqaSVF($c+i?vG3!TT= z-CfpZ4%El;wu8(577xLDr*vJ6!reMm$qzs^GoSQSrhok-F?)1XFU#}Ch<={Mn54_s z-SkYVE85j_DK~W-7(ayVM%+34xGl8f$zK?oDDU^^Fn8)(wTPgo0@xZwn|}7nn_6&G z()6fQy)wWPRRhUxFVmdknY(wgB#T|NT&HetK_qB`d3#9Eg7MdsWzRGDH#sm?VdN}m z1qC0`TF{szMc-*=ZT(oS6)@OyXMLso)HyNOa%BX@k=Q!oEamC$J0GQ@NA&f_p!(7kwrg4RXz->HWbv!TN{n`V8)F97A}s- zgqit&N&ERyh$DUCtYNuSTm_Tf3@7V812YmH|hsAhbVD zaP@q{&!1RI=7);Mxehz7K#ERXv12Qv^jVAg!-sOKRY#FOGJ~3L_71owsM0ps0=-KJZeLI03k zS>g8>pN`&R^D6uGh0@~8{qXYj>co_W-jd~mIK}<%%Cri1#~aS31+-DF-*QWsk){a_ z-n5@C&g%Q@H;#vX^}eo{Hhfj)f4V?E)xY%(GjAshw(_v2)0PE+`w4a`yTdnLEol%4 zkLSo_sjuj*YZD^2tLm4I=H=GRTAKm>*dJ*Zj<-**aLkMb+pl}9cKD5boxERVJ-a@C zH@cxw#ZotDjzc`U!Fpe-c{D7+K)jh-=C)o91O{VUuB&`%%x&%@5Zl~|SVRr@>Y53W zNWffScff(+uYXcd>Yk;z%M-!Ly|241I`?Zg8lSXi>9VA;fw_J+!kaE1c7D$m{M2_n zv+VLCgj+)Q+pV;{hQ-QKqoF^!PxkU+3%?sRa4hr8+29~tN+VlgX2MW#a(g*Uy&|XF zNb4^Jtp?-#-A~F-M+$0Zc*b&v?TX|�$toe<)*el)a`rbqO*$=46wbE%2_BS&tM{ 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 literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/doc/index.qdoc b/external/QtPropertyBrowser/doc/index.qdoc new file mode 100644 index 000000000..7a2585eaa --- /dev/null +++ b/external/QtPropertyBrowser/doc/index.qdoc @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page index.html + \title Property Browser + + \section1 Description + + A property browser framework enabling the user to edit a + set of properties. + + + + The framework provides a browser widget that displays the + given properties with labels and corresponding editing + widgets (e.g. line edits or comboboxes). The various types + of editing widgets are provided by the framework's editor + factories: For each property type, the framework provides + a property manager (e.g. QtIntPropertyManager and + QtStringPropertyManager) which can be associated with the + preferred editor factory (e.g. QtSpinBoxFactory and + QtLineEditFactory). The framework also provides a variant + based property type with corresponding variant manager and + factory. Finally, the framework provides three ready-made + implementations of the browser widget: + QtTreePropertyBrowser, QtButtonPropertyBrowser and QtGroupBoxPropertyBrowser. + + + + \section1 Classes + \list + \i QtProperty \i QtVariantProperty \i QtAbstractPropertyManager \i QtBoolPropertyManager \i QtColorPropertyManager \i QtCursorPropertyManager \i QtDatePropertyManager \i QtDateTimePropertyManager \i QtDoublePropertyManager \i QtEnumPropertyManager \i QtFlagPropertyManager \i QtFontPropertyManager \i QtGroupPropertyManager \i QtIntPropertyManager \i QtKeySequencePropertyManager \i QtCharPropertyManager \i QtLocalePropertyManager \i QtPointPropertyManager \i QtPointFPropertyManager \i QtRectPropertyManager \i QtRectFPropertyManager \i QtSizePropertyManager \i QtSizeFPropertyManager \i QtSizePolicyPropertyManager \i QtStringPropertyManager \i QtTimePropertyManager \i QtVariantPropertyManager \i QtAbstractEditorFactoryBase \i QtAbstractEditorFactory \i QtCheckBoxFactory \i QtDateEditFactory \i QtDateTimeEditFactory \i QtDoubleSpinBoxFactory \i QtEnumEditorFactory \i QtLineEditFactory \i QtScrollBarFactory \i QtSliderFactory \i QtSpinBoxFactory \i QtTimeEditFactory \i QtColorEditorFactory \i QtFontEditorFactory \i QtVariantEditorFactory \i QtBrowserItem \i QtAbstractPropertyBrowser \i QtButtonPropertyBrowser \i QtGroupBoxPropertyBrowser \i QtTreePropertyBrowser\endlist + + \section1 Examples + \list + \i \link qtpropertybrowser-example-simple.html Simple \endlink \i \link qtpropertybrowser-example-demo.html Demo \endlink \i \link qtpropertybrowser-example-canvas_typed.html Canvas Typed \endlink \i \link qtpropertybrowser-example-canvas_variant.html Canvas Variant \endlink \i \link qtpropertybrowser-example-extension.html Extension \endlink \i \link qtpropertybrowser-example-decoration.html Decoration \endlink \i \link qtpropertybrowser-example-object_controller.html Object Controller \endlink \endlist + + + + + + + \section1 Tested platforms + \list + \i Qt 4.4, 4.5 / Windows XP / MSVC.NET 2008 + \i Qt 4.4, 4.5 / Linux / gcc + \i Qt 4.4, 4.5 / MacOS X 10.5 / gcc + \endlist + + + + + \section1 Screenshots + + \img qttreepropertybrowser.png + \img qtbuttonpropertybrowser.png + \img qtgroupboxpropertybrowser.png + +*/ diff --git a/external/QtPropertyBrowser/src/QtAbstractEditorFactoryBase b/external/QtPropertyBrowser/src/QtAbstractEditorFactoryBase new file mode 100644 index 000000000..ab4e7104a --- /dev/null +++ b/external/QtPropertyBrowser/src/QtAbstractEditorFactoryBase @@ -0,0 +1 @@ +#include "qtpropertybrowser.h" diff --git a/external/QtPropertyBrowser/src/QtAbstractPropertyBrowser b/external/QtPropertyBrowser/src/QtAbstractPropertyBrowser new file mode 100644 index 000000000..ab4e7104a --- /dev/null +++ b/external/QtPropertyBrowser/src/QtAbstractPropertyBrowser @@ -0,0 +1 @@ +#include "qtpropertybrowser.h" diff --git a/external/QtPropertyBrowser/src/QtAbstractPropertyManager b/external/QtPropertyBrowser/src/QtAbstractPropertyManager new file mode 100644 index 000000000..ab4e7104a --- /dev/null +++ b/external/QtPropertyBrowser/src/QtAbstractPropertyManager @@ -0,0 +1 @@ +#include "qtpropertybrowser.h" diff --git a/external/QtPropertyBrowser/src/QtBoolPropertyManager b/external/QtPropertyBrowser/src/QtBoolPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtBoolPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtBrowserItem b/external/QtPropertyBrowser/src/QtBrowserItem new file mode 100644 index 000000000..ab4e7104a --- /dev/null +++ b/external/QtPropertyBrowser/src/QtBrowserItem @@ -0,0 +1 @@ +#include "qtpropertybrowser.h" diff --git a/external/QtPropertyBrowser/src/QtButtonPropertyBrowser b/external/QtPropertyBrowser/src/QtButtonPropertyBrowser new file mode 100644 index 000000000..56e089704 --- /dev/null +++ b/external/QtPropertyBrowser/src/QtButtonPropertyBrowser @@ -0,0 +1 @@ +#include "qtbuttonpropertybrowser.h" diff --git a/external/QtPropertyBrowser/src/QtCharEditorFactory b/external/QtPropertyBrowser/src/QtCharEditorFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/external/QtPropertyBrowser/src/QtCharEditorFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/external/QtPropertyBrowser/src/QtCharPropertyManager b/external/QtPropertyBrowser/src/QtCharPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtCharPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtCheckBoxFactory b/external/QtPropertyBrowser/src/QtCheckBoxFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/external/QtPropertyBrowser/src/QtCheckBoxFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/external/QtPropertyBrowser/src/QtColorEditorFactory b/external/QtPropertyBrowser/src/QtColorEditorFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/external/QtPropertyBrowser/src/QtColorEditorFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/external/QtPropertyBrowser/src/QtColorPropertyManager b/external/QtPropertyBrowser/src/QtColorPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtColorPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtCursorEditorFactory b/external/QtPropertyBrowser/src/QtCursorEditorFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/external/QtPropertyBrowser/src/QtCursorEditorFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/external/QtPropertyBrowser/src/QtCursorPropertyManager b/external/QtPropertyBrowser/src/QtCursorPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtCursorPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtDateEditFactory b/external/QtPropertyBrowser/src/QtDateEditFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/external/QtPropertyBrowser/src/QtDateEditFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/external/QtPropertyBrowser/src/QtDatePropertyManager b/external/QtPropertyBrowser/src/QtDatePropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtDatePropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtDateTimeEditFactory b/external/QtPropertyBrowser/src/QtDateTimeEditFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/external/QtPropertyBrowser/src/QtDateTimeEditFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/external/QtPropertyBrowser/src/QtDateTimePropertyManager b/external/QtPropertyBrowser/src/QtDateTimePropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtDateTimePropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtDoublePropertyManager b/external/QtPropertyBrowser/src/QtDoublePropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtDoublePropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtDoubleSpinBoxFactory b/external/QtPropertyBrowser/src/QtDoubleSpinBoxFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/external/QtPropertyBrowser/src/QtDoubleSpinBoxFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/external/QtPropertyBrowser/src/QtEnumEditorFactory b/external/QtPropertyBrowser/src/QtEnumEditorFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/external/QtPropertyBrowser/src/QtEnumEditorFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/external/QtPropertyBrowser/src/QtEnumPropertyManager b/external/QtPropertyBrowser/src/QtEnumPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtEnumPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtFlagPropertyManager b/external/QtPropertyBrowser/src/QtFlagPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtFlagPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtFontEditorFactory b/external/QtPropertyBrowser/src/QtFontEditorFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/external/QtPropertyBrowser/src/QtFontEditorFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/external/QtPropertyBrowser/src/QtFontPropertyManager b/external/QtPropertyBrowser/src/QtFontPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtFontPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtGroupBoxPropertyBrowser b/external/QtPropertyBrowser/src/QtGroupBoxPropertyBrowser new file mode 100644 index 000000000..27964c080 --- /dev/null +++ b/external/QtPropertyBrowser/src/QtGroupBoxPropertyBrowser @@ -0,0 +1 @@ +#include "qtgroupboxpropertybrowser.h" diff --git a/external/QtPropertyBrowser/src/QtGroupPropertyManager b/external/QtPropertyBrowser/src/QtGroupPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtGroupPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtIntPropertyManager b/external/QtPropertyBrowser/src/QtIntPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtIntPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtKeySequenceEditorFactory b/external/QtPropertyBrowser/src/QtKeySequenceEditorFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/external/QtPropertyBrowser/src/QtKeySequenceEditorFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/external/QtPropertyBrowser/src/QtKeySequencePropertyManager b/external/QtPropertyBrowser/src/QtKeySequencePropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtKeySequencePropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtLineEditFactory b/external/QtPropertyBrowser/src/QtLineEditFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/external/QtPropertyBrowser/src/QtLineEditFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/external/QtPropertyBrowser/src/QtLocalePropertyManager b/external/QtPropertyBrowser/src/QtLocalePropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtLocalePropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtPointFPropertyManager b/external/QtPropertyBrowser/src/QtPointFPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtPointFPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtPointPropertyManager b/external/QtPropertyBrowser/src/QtPointPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtPointPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtProperty b/external/QtPropertyBrowser/src/QtProperty new file mode 100644 index 000000000..ab4e7104a --- /dev/null +++ b/external/QtPropertyBrowser/src/QtProperty @@ -0,0 +1 @@ +#include "qtpropertybrowser.h" diff --git a/external/QtPropertyBrowser/src/QtRectFPropertyManager b/external/QtPropertyBrowser/src/QtRectFPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtRectFPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtRectPropertyManager b/external/QtPropertyBrowser/src/QtRectPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtRectPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtScrollBarFactory b/external/QtPropertyBrowser/src/QtScrollBarFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/external/QtPropertyBrowser/src/QtScrollBarFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/external/QtPropertyBrowser/src/QtSizeFPropertyManager b/external/QtPropertyBrowser/src/QtSizeFPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtSizeFPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtSizePolicyPropertyManager b/external/QtPropertyBrowser/src/QtSizePolicyPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtSizePolicyPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtSizePropertyManager b/external/QtPropertyBrowser/src/QtSizePropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtSizePropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtSliderFactory b/external/QtPropertyBrowser/src/QtSliderFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/external/QtPropertyBrowser/src/QtSliderFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/external/QtPropertyBrowser/src/QtSpinBoxFactory b/external/QtPropertyBrowser/src/QtSpinBoxFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/external/QtPropertyBrowser/src/QtSpinBoxFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/external/QtPropertyBrowser/src/QtStringPropertyManager b/external/QtPropertyBrowser/src/QtStringPropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtStringPropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtTimeEditFactory b/external/QtPropertyBrowser/src/QtTimeEditFactory new file mode 100644 index 000000000..75f35adab --- /dev/null +++ b/external/QtPropertyBrowser/src/QtTimeEditFactory @@ -0,0 +1 @@ +#include "qteditorfactory.h" diff --git a/external/QtPropertyBrowser/src/QtTimePropertyManager b/external/QtPropertyBrowser/src/QtTimePropertyManager new file mode 100644 index 000000000..1842e431d --- /dev/null +++ b/external/QtPropertyBrowser/src/QtTimePropertyManager @@ -0,0 +1 @@ +#include "qtpropertymanager.h" diff --git a/external/QtPropertyBrowser/src/QtTreePropertyBrowser b/external/QtPropertyBrowser/src/QtTreePropertyBrowser new file mode 100644 index 000000000..aab106c75 --- /dev/null +++ b/external/QtPropertyBrowser/src/QtTreePropertyBrowser @@ -0,0 +1 @@ +#include "qttreepropertybrowser.h" diff --git a/external/QtPropertyBrowser/src/QtVariantEditorFactory b/external/QtPropertyBrowser/src/QtVariantEditorFactory new file mode 100644 index 000000000..8118190d5 --- /dev/null +++ b/external/QtPropertyBrowser/src/QtVariantEditorFactory @@ -0,0 +1 @@ +#include "qtvariantproperty.h" diff --git a/external/QtPropertyBrowser/src/QtVariantProperty b/external/QtPropertyBrowser/src/QtVariantProperty new file mode 100644 index 000000000..8118190d5 --- /dev/null +++ b/external/QtPropertyBrowser/src/QtVariantProperty @@ -0,0 +1 @@ +#include "qtvariantproperty.h" diff --git a/external/QtPropertyBrowser/src/QtVariantPropertyManager b/external/QtPropertyBrowser/src/QtVariantPropertyManager new file mode 100644 index 000000000..8118190d5 --- /dev/null +++ b/external/QtPropertyBrowser/src/QtVariantPropertyManager @@ -0,0 +1 @@ +#include "qtvariantproperty.h" diff --git a/external/QtPropertyBrowser/src/images/button-reset.ico b/external/QtPropertyBrowser/src/images/button-reset.ico new file mode 100644 index 0000000000000000000000000000000000000000..f94794fb0be7d9f54c38e0bd9386725f61fd4de3 GIT binary patch literal 9622 zcmeI0ziSjh6vv+!4gP=xOdulSi6G(+)D(h0;1t9k*ol=kqWA-U5D19n9oPgd=cU>T4?8im4AVV2(cBEE3Y_i{Jfn#Ig&Gbv$;K#n}H9rGrRBmX5a44%v+H)G9u&S zLS2&EBO+%+WMaa%->(;0pl@o*x92v9+}tEmD*5&+?0#|W9&9*7!S_?eGVloKY41{< zh?c|Lo2`C>ttn{qTJ#n+Kj8-)O6k#FXSv?SyOe6L-m$&jVQ>DqhtOj2O2&}GHq_Vf zUhjCyOKHuEGW@qyZ(@j#_d=*QKK=%mfM!sj8)2vqb1iV>!if-|? z`kHz-oC4lZ{SdCEtfYDl9>aGy0XyL;@P>yLJ&)ZBXwSbFIJP>DkqK5KPmaC-cZN(w4j;Npf;ML^pAD9KGm>wiw|G;Fq3`uFvm9DdyK&9Bap1gw!X6+)LrS^ zZR>ow58B(&u{GZGroq}zz}B1jKIk7qXC~FVNZro4p8LMM9&|tUmWzGyI>~r%aNN$x zUi$t#`g#=G`|#Fl{MjG8q5Uky;#13`j@>LQfNA`Vcbu!{(>E*K3!S;5`MC=Rz@EV> z*Zt&OJdDm$Xy3y%j%|O({zTX1AA6^z9zp8?n2#$k*?Be|#|Zqd5pX2=D^jb7t9n{e zk!DIuoEYxW%J#MoE5S*K{|^X4EHMHx0x<$H0)2`=k$Fkh5R*Kmz`P~Xe?fUorr!ed zo=o2b=S7+R2aq>qj-lYZD$~FH0~kQwl{t=>mt}=0o{tfT5r`4^$0NW$h_KQeb*_=J QNL@==9COZSl!Nqs1A=Q9=>Px# literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/src/images/cursor-arrow.png b/external/QtPropertyBrowser/src/images/cursor-arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..a69ef4eb6158503c7c67c916aea86e65fdc81f72 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~)3?z59=Y9ZEoB=)|uK&RR$m{!Z_zjR^ED7=p zW^j0RBMrz2@N{tusfe>Zw~@EOfQR+sk_Oou&-fjcEVpj<&$!X3+c~E>J1*JV{%`IM zZgwlFFx}G*?uS>UO1?P#t>x;u4TbmfTg6u$kN3O$qTon=;uum9xAyEt-c|zv=78lpdFvQ2-{H`#GwYbpmwD+D`;ru|4Sly6 z!u|DfH10id;EhPQ?!aC0$4imznq|kzoDQ|k!q4v~%5Ey$Ds|~#XU>6Rfw7|8GuZ2t ub|G literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/src/images/cursor-closedhand.png b/external/QtPropertyBrowser/src/images/cursor-closedhand.png new file mode 100644 index 0000000000000000000000000000000000000000..b78dd1dac5a827fa698f1993718f22c282019505 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6I14-?iy0WWJ3*My{N(AiKtWee z7sn8d^J_1j=3-FbaJl&N|NMQrDg{-+lDl3uEOL6iyxxIhJsV5IbqBU04WsP|EmPEI sG+%tqc!TF=!@MiLH_pW!e7ccq3Qxekuk)up2O7xW>FVdQ&MBb@057mJumAu6 literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/src/images/cursor-cross.png b/external/QtPropertyBrowser/src/images/cursor-cross.png new file mode 100644 index 0000000000000000000000000000000000000000..fe38e744805f61abefcc555e07d399725c3fd7e6 GIT binary patch literal 130 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~)3?z59=Y9ZEoB=)|uK&RR$m{!Z_zjR^ED7=p zW^j0RBMrz=_jGX#;h346aDZ1vLF6&ZrWY3kt_3XM>{%UFuy$6%gUPvacWfgV8N9#n V_FPj?S`E~~;OXk;vd$@?2>`R9Dxv@Y literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/src/images/cursor-forbidden.png b/external/QtPropertyBrowser/src/images/cursor-forbidden.png new file mode 100644 index 0000000000000000000000000000000000000000..2b08c4e2a3cafc992459a8f484e6c8e6c3e74857 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~)3?z59=Y9ZEoB=)|uK&RR$m{!Z_zjR^ED7=p zW^j0RBMr#O@pN$vsfa5*w~^P`kb@;)w}Ny_&ztDY@kvlRIOU`3qAsV; zTo+`Y{*UQrTXjS>sKxPHd$OYcrG25=M&E9}?0tT1Yy7oqDMB$hU$uYoMqOpDnka4~ qygb6(Z%*F(qx}EZO#W7L6_Nk?#pi+cGI+ZBxvX&}>iqs75rOW+zd6_S+ yS|~6}xHpZ9x7T5rLt)D22WQ%mvv4FO#t=)GwlEX literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/src/images/cursor-ibeam.png b/external/QtPropertyBrowser/src/images/cursor-ibeam.png new file mode 100644 index 0000000000000000000000000000000000000000..097fc5fa7287da71ffd907b3a11adbda4516aca6 GIT binary patch literal 124 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~)3?z59=Y9ZEoB=)|uK)l42QqgTe~DWM4f DkdQT7 literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/src/images/cursor-sizeall.png b/external/QtPropertyBrowser/src/images/cursor-sizeall.png new file mode 100644 index 0000000000000000000000000000000000000000..69f13eb347a6c299e06844729a14f657b282fe8f GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~)3?z59=Y9ZEoB=)|uK)l42Qq(Z!J(8lD*)YR5__{zaA2hTRnmr4+Dcjj*u+}&-pB%i42~uelF{r5}E+x CJu-a& literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/src/images/cursor-sizef.png b/external/QtPropertyBrowser/src/images/cursor-sizef.png new file mode 100644 index 0000000000000000000000000000000000000000..3b127a05d34b48a2f4f9b9cc77b681c6b43afcdd GIT binary patch literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~)3?z59=Y9ZEoB=)|uK)l42QqD?iBlbDB7>)^pUXO@geCxo C3NS_h literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/src/images/cursor-sizeh.png b/external/QtPropertyBrowser/src/images/cursor-sizeh.png new file mode 100644 index 0000000000000000000000000000000000000000..a9f40cbc3d77c566c11c32c0631b4f94f44dd441 GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~)3?z59=Y9ZEoB=)|uK)l42Qq&V7RQzr9bPir8&?922WQ%mvv4FO#sHOC(Zx> literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/src/images/cursor-sizev.png b/external/QtPropertyBrowser/src/images/cursor-sizev.png new file mode 100644 index 0000000000000000000000000000000000000000..1edbab27a5b05555aaf515931f69ad6bf7e417f0 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~)3?z59=Y9ZEoB=)|uK)l42QqM`U1 literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/src/images/cursor-wait.png b/external/QtPropertyBrowser/src/images/cursor-wait.png new file mode 100644 index 0000000000000000000000000000000000000000..69056c479e9b2f009e366dfd71999a7c74f97620 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~)3?z59=Y9ZEoB=)|uK&RR$m{!Z_zjR^ED7=p zW^j0RBMrz2^mK6y;h346;J_ZVI&3Y=<%J7po~YS&;ev>WRgqc?pLgqp;N^OZ7kj)9 zt2OYRn)8&w&_Fn;AZ-e>OWiG&j$ap41wJoZG>h5TTvwNMesusN!}2q-U)D!*O8^aL N@O1TaS?83{1OR$JJ0<`C literal 0 HcmV?d00001 diff --git a/external/QtPropertyBrowser/src/images/cursor-whatsthis.png b/external/QtPropertyBrowser/src/images/cursor-whatsthis.png new file mode 100644 index 0000000000000000000000000000000000000000..b47601c3780eec780fdae43bab7481bbfebdddae GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@&H$ef*Z*JuL59RLGuTpf8VsdEq+OT~Tw87C;38om{D5bL fNHFu^21W*zFY +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QtButtonPropertyBrowserPrivate +{ + QtButtonPropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtButtonPropertyBrowser) +public: + + void init(QWidget *parent); + + void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex); + void propertyRemoved(QtBrowserItem *index); + void propertyChanged(QtBrowserItem *index); + QWidget *createEditor(QtProperty *property, QWidget *parent) const + { return q_ptr->createEditor(property, parent); } + + void slotEditorDestroyed(); + void slotUpdate(); + void slotToggled(bool checked); + + struct WidgetItem + { + QWidget *widget{nullptr}; // can be null + QLabel *label{nullptr}; // main label with property name + QLabel *widgetLabel{nullptr}; // label substitute showing the current value if there is no widget + QToolButton *button{nullptr}; // expandable button for items with children + QWidget *container{nullptr}; // container which is expanded when the button is clicked + QGridLayout *layout{nullptr}; // layout in container + WidgetItem *parent{nullptr}; + QList children; + bool expanded{false}; + }; +private: + void updateLater(); + void updateItem(WidgetItem *item); + void insertRow(QGridLayout *layout, int row) const; + void removeRow(QGridLayout *layout, int row) const; + int gridRow(WidgetItem *item) const; + int gridSpan(WidgetItem *item) const; + void setExpanded(WidgetItem *item, bool expanded); + QToolButton *createButton(QWidget *panret = 0) const; + + QMap m_indexToItem; + QMap m_itemToIndex; + QMap m_widgetToItem; + QMap m_buttonToItem; + QGridLayout *m_mainLayout; + QList m_children; + QList m_recreateQueue; +}; + +QToolButton *QtButtonPropertyBrowserPrivate::createButton(QWidget *parent) const +{ + QToolButton *button = new QToolButton(parent); + button->setCheckable(true); + button->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed)); + button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + button->setArrowType(Qt::DownArrow); + button->setIconSize(QSize(3, 16)); + /* + QIcon icon; + icon.addPixmap(q_ptr->style()->standardPixmap(QStyle::SP_ArrowDown), QIcon::Normal, QIcon::Off); + icon.addPixmap(q_ptr->style()->standardPixmap(QStyle::SP_ArrowUp), QIcon::Normal, QIcon::On); + button->setIcon(icon); + */ + return button; +} + +int QtButtonPropertyBrowserPrivate::gridRow(WidgetItem *item) const +{ + QList siblings; + if (item->parent) + siblings = item->parent->children; + else + siblings = m_children; + + int row = 0; + for (WidgetItem *sibling : qAsConst(siblings)) { + if (sibling == item) + return row; + row += gridSpan(sibling); + } + return -1; +} + +int QtButtonPropertyBrowserPrivate::gridSpan(WidgetItem *item) const +{ + if (item->container && item->expanded) + return 2; + return 1; +} + +void QtButtonPropertyBrowserPrivate::init(QWidget *parent) +{ + m_mainLayout = new QGridLayout(); + parent->setLayout(m_mainLayout); + QLayoutItem *item = new QSpacerItem(0, 0, + QSizePolicy::Fixed, QSizePolicy::Expanding); + m_mainLayout->addItem(item, 0, 0); +} + +void QtButtonPropertyBrowserPrivate::slotEditorDestroyed() +{ + QWidget *editor = qobject_cast(q_ptr->sender()); + if (!editor) + return; + if (!m_widgetToItem.contains(editor)) + return; + m_widgetToItem[editor]->widget = 0; + m_widgetToItem.remove(editor); +} + +void QtButtonPropertyBrowserPrivate::slotUpdate() +{ + for (WidgetItem *item : qAsConst(m_recreateQueue)) { + WidgetItem *parent = item->parent; + QWidget *w = 0; + QGridLayout *l = 0; + const int oldRow = gridRow(item); + if (parent) { + w = parent->container; + l = parent->layout; + } else { + w = q_ptr; + l = m_mainLayout; + } + + int span = 1; + if (!item->widget && !item->widgetLabel) + span = 2; + item->label = new QLabel(w); + item->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + l->addWidget(item->label, oldRow, 0, 1, span); + + updateItem(item); + } + m_recreateQueue.clear(); +} + +void QtButtonPropertyBrowserPrivate::setExpanded(WidgetItem *item, bool expanded) +{ + if (item->expanded == expanded) + return; + + if (!item->container) + return; + + item->expanded = expanded; + const int row = gridRow(item); + WidgetItem *parent = item->parent; + QGridLayout *l = 0; + if (parent) + l = parent->layout; + else + l = m_mainLayout; + + if (expanded) { + insertRow(l, row + 1); + l->addWidget(item->container, row + 1, 0, 1, 2); + item->container->show(); + } else { + l->removeWidget(item->container); + item->container->hide(); + removeRow(l, row + 1); + } + + item->button->setChecked(expanded); + item->button->setArrowType(expanded ? Qt::UpArrow : Qt::DownArrow); +} + +void QtButtonPropertyBrowserPrivate::slotToggled(bool checked) +{ + WidgetItem *item = m_buttonToItem.value(q_ptr->sender()); + if (!item) + return; + + setExpanded(item, checked); + + if (checked) + emit q_ptr->expanded(m_itemToIndex.value(item)); + else + emit q_ptr->collapsed(m_itemToIndex.value(item)); +} + +void QtButtonPropertyBrowserPrivate::updateLater() +{ + QTimer::singleShot(0, q_ptr, SLOT(slotUpdate())); +} + +void QtButtonPropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex) +{ + WidgetItem *afterItem = m_indexToItem.value(afterIndex); + WidgetItem *parentItem = m_indexToItem.value(index->parent()); + + WidgetItem *newItem = new WidgetItem(); + newItem->parent = parentItem; + + QGridLayout *layout = 0; + QWidget *parentWidget = 0; + int row = -1; + if (!afterItem) { + row = 0; + if (parentItem) + parentItem->children.insert(0, newItem); + else + m_children.insert(0, newItem); + } else { + row = gridRow(afterItem) + gridSpan(afterItem); + if (parentItem) + parentItem->children.insert(parentItem->children.indexOf(afterItem) + 1, newItem); + else + m_children.insert(m_children.indexOf(afterItem) + 1, newItem); + } + + if (!parentItem) { + layout = m_mainLayout; + parentWidget = q_ptr; + } else { + if (!parentItem->container) { + m_recreateQueue.removeAll(parentItem); + WidgetItem *grandParent = parentItem->parent; + QGridLayout *l = 0; + const int oldRow = gridRow(parentItem); + if (grandParent) { + l = grandParent->layout; + } else { + l = m_mainLayout; + } + QFrame *container = new QFrame(); + container->setFrameShape(QFrame::Panel); + container->setFrameShadow(QFrame::Raised); + parentItem->container = container; + parentItem->button = createButton(); + m_buttonToItem[parentItem->button] = parentItem; + q_ptr->connect(parentItem->button, SIGNAL(toggled(bool)), q_ptr, SLOT(slotToggled(bool))); + parentItem->layout = new QGridLayout(); + container->setLayout(parentItem->layout); + if (parentItem->label) { + l->removeWidget(parentItem->label); + delete parentItem->label; + parentItem->label = 0; + } + int span = 1; + if (!parentItem->widget && !parentItem->widgetLabel) + span = 2; + l->addWidget(parentItem->button, oldRow, 0, 1, span); + updateItem(parentItem); + } + layout = parentItem->layout; + parentWidget = parentItem->container; + } + + newItem->label = new QLabel(parentWidget); + newItem->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + newItem->widget = createEditor(index->property(), parentWidget); + if (newItem->widget) { + QObject::connect(newItem->widget, SIGNAL(destroyed()), q_ptr, SLOT(slotEditorDestroyed())); + m_widgetToItem[newItem->widget] = newItem; + } else if (index->property()->hasValue()) { + newItem->widgetLabel = new QLabel(parentWidget); + newItem->widgetLabel->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed)); + } + + insertRow(layout, row); + int span = 1; + if (newItem->widget) + layout->addWidget(newItem->widget, row, 1); + else if (newItem->widgetLabel) + layout->addWidget(newItem->widgetLabel, row, 1); + else + span = 2; + layout->addWidget(newItem->label, row, 0, span, 1); + + m_itemToIndex[newItem] = index; + m_indexToItem[index] = newItem; + + updateItem(newItem); +} + +void QtButtonPropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index) +{ + WidgetItem *item = m_indexToItem.value(index); + + m_indexToItem.remove(index); + m_itemToIndex.remove(item); + + WidgetItem *parentItem = item->parent; + + const int row = gridRow(item); + + if (parentItem) + parentItem->children.removeAt(parentItem->children.indexOf(item)); + else + m_children.removeAt(m_children.indexOf(item)); + + const int colSpan = gridSpan(item); + + m_buttonToItem.remove(item->button); + + if (item->widget) + delete item->widget; + if (item->label) + delete item->label; + if (item->widgetLabel) + delete item->widgetLabel; + if (item->button) + delete item->button; + if (item->container) + delete item->container; + + if (!parentItem) { + removeRow(m_mainLayout, row); + if (colSpan > 1) + removeRow(m_mainLayout, row); + } else if (parentItem->children.count() != 0) { + removeRow(parentItem->layout, row); + if (colSpan > 1) + removeRow(parentItem->layout, row); + } else { + const WidgetItem *grandParent = parentItem->parent; + QGridLayout *l = 0; + if (grandParent) { + l = grandParent->layout; + } else { + l = m_mainLayout; + } + + const int parentRow = gridRow(parentItem); + const int parentSpan = gridSpan(parentItem); + + l->removeWidget(parentItem->button); + l->removeWidget(parentItem->container); + delete parentItem->button; + delete parentItem->container; + parentItem->button = 0; + parentItem->container = 0; + parentItem->layout = 0; + if (!m_recreateQueue.contains(parentItem)) + m_recreateQueue.append(parentItem); + if (parentSpan > 1) + removeRow(l, parentRow + 1); + + updateLater(); + } + m_recreateQueue.removeAll(item); + + delete item; +} + +void QtButtonPropertyBrowserPrivate::insertRow(QGridLayout *layout, int row) const +{ + QMap itemToPos; + int idx = 0; + while (idx < layout->count()) { + int r, c, rs, cs; + layout->getItemPosition(idx, &r, &c, &rs, &cs); + if (r >= row) { + itemToPos[layout->takeAt(idx)] = QRect(r + 1, c, rs, cs); + } else { + idx++; + } + } + + for (auto it = itemToPos.constBegin(), icend = itemToPos.constEnd(); it != icend; ++it) { + const QRect r = it.value(); + layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height()); + } +} + +void QtButtonPropertyBrowserPrivate::removeRow(QGridLayout *layout, int row) const +{ + QMap itemToPos; + int idx = 0; + while (idx < layout->count()) { + int r, c, rs, cs; + layout->getItemPosition(idx, &r, &c, &rs, &cs); + if (r > row) { + itemToPos[layout->takeAt(idx)] = QRect(r - 1, c, rs, cs); + } else { + idx++; + } + } + + for (auto it = itemToPos.constBegin(), icend = itemToPos.constEnd(); it != icend; ++it) { + const QRect r = it.value(); + layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height()); + } +} + +void QtButtonPropertyBrowserPrivate::propertyChanged(QtBrowserItem *index) +{ + WidgetItem *item = m_indexToItem.value(index); + + updateItem(item); +} + +void QtButtonPropertyBrowserPrivate::updateItem(WidgetItem *item) +{ + QtProperty *property = m_itemToIndex[item]->property(); + if (item->button) { + QFont font = item->button->font(); + font.setUnderline(property->isModified()); + item->button->setFont(font); + item->button->setText(property->propertyName()); + item->button->setToolTip(property->descriptionToolTip()); + item->button->setStatusTip(property->statusTip()); + item->button->setWhatsThis(property->whatsThis()); + item->button->setEnabled(property->isEnabled()); + } + if (item->label) { + QFont font = item->label->font(); + font.setUnderline(property->isModified()); + item->label->setFont(font); + item->label->setText(property->propertyName()); + item->label->setToolTip(property->descriptionToolTip()); + item->label->setStatusTip(property->statusTip()); + item->label->setWhatsThis(property->whatsThis()); + item->label->setEnabled(property->isEnabled()); + } + if (item->widgetLabel) { + QFont font = item->widgetLabel->font(); + font.setUnderline(false); + item->widgetLabel->setFont(font); + item->widgetLabel->setText(property->valueText()); + item->widgetLabel->setToolTip(property->valueText()); + item->widgetLabel->setEnabled(property->isEnabled()); + } + if (item->widget) { + QFont font = item->widget->font(); + font.setUnderline(false); + item->widget->setFont(font); + item->widget->setEnabled(property->isEnabled()); + const QString valueToolTip = property->valueToolTip(); + item->widget->setToolTip(valueToolTip.isEmpty() ? property->valueText() : valueToolTip); + } +} + + + +/*! + \class QtButtonPropertyBrowser + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtButtonPropertyBrowser class provides a drop down QToolButton + based property browser. + + A property browser is a widget that enables the user to edit a + given set of properties. Each property is represented by a label + specifying the property's name, and an editing widget (e.g. a line + edit or a combobox) holding its value. A property can have zero or + more subproperties. + + QtButtonPropertyBrowser provides drop down button for all nested + properties, i.e. subproperties are enclosed by a container associated with + the drop down button. The parent property's name is displayed as button text. For example: + + \image qtbuttonpropertybrowser.png + + Use the QtAbstractPropertyBrowser API to add, insert and remove + properties from an instance of the QtButtonPropertyBrowser + class. The properties themselves are created and managed by + implementations of the QtAbstractPropertyManager class. + + \sa QtTreePropertyBrowser, QtAbstractPropertyBrowser +*/ + +/*! + \fn void QtButtonPropertyBrowser::collapsed(QtBrowserItem *item) + + This signal is emitted when the \a item is collapsed. + + \sa expanded(), setExpanded() +*/ + +/*! + \fn void QtButtonPropertyBrowser::expanded(QtBrowserItem *item) + + This signal is emitted when the \a item is expanded. + + \sa collapsed(), setExpanded() +*/ + +/*! + Creates a property browser with the given \a parent. +*/ +QtButtonPropertyBrowser::QtButtonPropertyBrowser(QWidget *parent) + : QtAbstractPropertyBrowser(parent), d_ptr(new QtButtonPropertyBrowserPrivate) +{ + d_ptr->q_ptr = this; + + d_ptr->init(this); +} + +/*! + Destroys this property browser. + + Note that the properties that were inserted into this browser are + \e not destroyed since they may still be used in other + browsers. The properties are owned by the manager that created + them. + + \sa QtProperty, QtAbstractPropertyManager +*/ +QtButtonPropertyBrowser::~QtButtonPropertyBrowser() +{ + const QMap::ConstIterator icend = d_ptr->m_itemToIndex.constEnd(); + for (QMap::ConstIterator it = d_ptr->m_itemToIndex.constBegin(); it != icend; ++it) + delete it.key(); +} + +/*! + \reimp +*/ +void QtButtonPropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) +{ + d_ptr->propertyInserted(item, afterItem); +} + +/*! + \reimp +*/ +void QtButtonPropertyBrowser::itemRemoved(QtBrowserItem *item) +{ + d_ptr->propertyRemoved(item); +} + +/*! + \reimp +*/ +void QtButtonPropertyBrowser::itemChanged(QtBrowserItem *item) +{ + d_ptr->propertyChanged(item); +} + +/*! + Sets the \a item to either collapse or expanded, depending on the value of \a expanded. + + \sa isExpanded(), expanded(), collapsed() +*/ + +void QtButtonPropertyBrowser::setExpanded(QtBrowserItem *item, bool expanded) +{ + QtButtonPropertyBrowserPrivate::WidgetItem *itm = d_ptr->m_indexToItem.value(item); + if (itm) + d_ptr->setExpanded(itm, expanded); +} + +/*! + Returns true if the \a item is expanded; otherwise returns false. + + \sa setExpanded() +*/ + +bool QtButtonPropertyBrowser::isExpanded(QtBrowserItem *item) const +{ + QtButtonPropertyBrowserPrivate::WidgetItem *itm = d_ptr->m_indexToItem.value(item); + if (itm) + return itm->expanded; + return false; +} + +QT_END_NAMESPACE + +#include "moc_qtbuttonpropertybrowser.cpp" diff --git a/external/QtPropertyBrowser/src/qtbuttonpropertybrowser.h b/external/QtPropertyBrowser/src/qtbuttonpropertybrowser.h new file mode 100644 index 000000000..5e0799cbe --- /dev/null +++ b/external/QtPropertyBrowser/src/qtbuttonpropertybrowser.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTBUTTONPROPERTYBROWSER_H +#define QTBUTTONPROPERTYBROWSER_H + +#include "qtpropertybrowser.h" + +QT_BEGIN_NAMESPACE + +class QtButtonPropertyBrowserPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtButtonPropertyBrowser : public QtAbstractPropertyBrowser +{ + Q_OBJECT +public: + + QtButtonPropertyBrowser(QWidget *parent = 0); + ~QtButtonPropertyBrowser(); + + void setExpanded(QtBrowserItem *item, bool expanded); + bool isExpanded(QtBrowserItem *item) const; + +Q_SIGNALS: + + void collapsed(QtBrowserItem *item); + void expanded(QtBrowserItem *item); + +protected: + void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) override; + void itemRemoved(QtBrowserItem *item) override; + void itemChanged(QtBrowserItem *item) override; + +private: + + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtButtonPropertyBrowser) + Q_DISABLE_COPY_MOVE(QtButtonPropertyBrowser) + Q_PRIVATE_SLOT(d_func(), void slotUpdate()) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed()) + Q_PRIVATE_SLOT(d_func(), void slotToggled(bool)) + +}; + +QT_END_NAMESPACE + +#endif diff --git a/external/QtPropertyBrowser/src/qteditorfactory.cpp b/external/QtPropertyBrowser/src/qteditorfactory.cpp new file mode 100644 index 000000000..6945f488f --- /dev/null +++ b/external/QtPropertyBrowser/src/qteditorfactory.cpp @@ -0,0 +1,2592 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qteditorfactory.h" +#include "qtpropertybrowserutils_p.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(Q_CC_MSVC) +# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ +#endif + +QT_BEGIN_NAMESPACE + +// Set a hard coded left margin to account for the indentation +// of the tree view icon when switching to an editor + +static inline void setupTreeViewEditorMargin(QLayout* lt) +{ + enum { DecorationMargin = 4 }; + if (QApplication::layoutDirection() == Qt::LeftToRight) + lt->setContentsMargins(DecorationMargin, 0, 0, 0); + else + lt->setContentsMargins(0, 0, DecorationMargin, 0); +} + +// ---------- EditorFactoryPrivate : +// Base class for editor factory private classes. Manages mapping of properties to editors and vice versa. + +template +class EditorFactoryPrivate +{ +public: + + typedef QList EditorList; + typedef QMap PropertyToEditorListMap; + typedef QMap EditorToPropertyMap; + + Editor* createEditor(QtProperty* property, QWidget* parent); + void initializeEditor(QtProperty* property, Editor* e); + void slotEditorDestroyed(QObject* object); + + PropertyToEditorListMap m_createdEditors; + EditorToPropertyMap m_editorToProperty; +}; + +template +Editor* EditorFactoryPrivate::createEditor(QtProperty* property, QWidget* parent) +{ + Editor* editor = new Editor(parent); + initializeEditor(property, editor); + return editor; +} + +template +void EditorFactoryPrivate::initializeEditor(QtProperty* property, Editor* editor) +{ + typename PropertyToEditorListMap::iterator it = m_createdEditors.find(property); + if (it == m_createdEditors.end()) + it = m_createdEditors.insert(property, EditorList()); + it.value().append(editor); + m_editorToProperty.insert(editor, property); +} + +template +void EditorFactoryPrivate::slotEditorDestroyed(QObject* object) +{ + const typename EditorToPropertyMap::iterator ecend = m_editorToProperty.end(); + for (typename EditorToPropertyMap::iterator itEditor = m_editorToProperty.begin(); itEditor != ecend; ++itEditor) { + if (itEditor.key() == object) { + Editor* editor = itEditor.key(); + QtProperty* property = itEditor.value(); + const typename PropertyToEditorListMap::iterator pit = m_createdEditors.find(property); + if (pit != m_createdEditors.end()) { + pit.value().removeAll(editor); + if (pit.value().isEmpty()) + m_createdEditors.erase(pit); + } + m_editorToProperty.erase(itEditor); + return; + } + } +} + +// ------------ QtSpinBoxFactory +#pragma region QtSpinBoxFactory + +class QtSpinBoxFactoryPrivate : public EditorFactoryPrivate +{ + QtSpinBoxFactory* q_ptr; + Q_DECLARE_PUBLIC(QtSpinBoxFactory) +public: + + void slotPropertyChanged(QtProperty* property, int value); + void slotRangeChanged(QtProperty* property, int min, int max); + void slotSingleStepChanged(QtProperty* property, int step); + void slotSetValue(int value); +}; + +void QtSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty* property, int value) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.cend()) + return; + for (QtIntEdit* editor : it.value()) { + if (editor->value() != value) { + editor->blockSignals(true); + editor->setValue(value); + editor->blockSignals(false); + } + } +} + +void QtSpinBoxFactoryPrivate::slotRangeChanged(QtProperty* property, int min, int max) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.cend()) + return; + + QtIntPropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + + for (QtIntEdit* editor : it.value()) { + editor->blockSignals(true); + editor->setRange(min, max); + editor->setValue(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty* property, int step) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.cend()) + return; + for (QtIntEdit* editor : it.value()) { + editor->blockSignals(true); + editor->setSingleStep(step); + editor->blockSignals(false); + } +} + +void QtSpinBoxFactoryPrivate::slotSetValue(int value) +{ + QObject* object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) { + if (itEditor.key() == object) { + QtProperty* property = itEditor.value(); + QtIntPropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } + } +} + +/*! + \class QtSpinBoxFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtSpinBoxFactory class provides QSpinBox widgets for + properties created by QtIntPropertyManager objects. + + \sa QtAbstractEditorFactory, QtIntPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtSpinBoxFactory::QtSpinBoxFactory(QObject* parent) + : QtAbstractEditorFactory(parent), d_ptr(new QtSpinBoxFactoryPrivate()) +{ + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtSpinBoxFactory::~QtSpinBoxFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtSpinBoxFactory::connectPropertyManager(QtIntPropertyManager* manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotPropertyChanged(QtProperty*, int))); + connect(manager, SIGNAL(rangeChanged(QtProperty*, int, int)), + this, SLOT(slotRangeChanged(QtProperty*, int, int))); + connect(manager, SIGNAL(singleStepChanged(QtProperty*, int)), + this, SLOT(slotSingleStepChanged(QtProperty*, int))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget* QtSpinBoxFactory::createEditor(QtIntPropertyManager* manager, QtProperty* property, + QWidget* parent) +{ + QtIntEdit* editor = d_ptr->createEditor(property, parent); + editor->setSingleStep(manager->singleStep(property)); + editor->setRange(manager->minimum(property), manager->maximum(property)); + editor->setValue(manager->value(property)); + editor->setInitialValue(manager->initialValue(property)); + editor->setKeyboardTracking(false); + + connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int))); + connect(editor, SIGNAL(destroyed(QObject*)), + this, SLOT(slotEditorDestroyed(QObject*))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtSpinBoxFactory::disconnectPropertyManager(QtIntPropertyManager* manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotPropertyChanged(QtProperty*, int))); + disconnect(manager, SIGNAL(rangeChanged(QtProperty*, int, int)), + this, SLOT(slotRangeChanged(QtProperty*, int, int))); + disconnect(manager, SIGNAL(singleStepChanged(QtProperty*, int)), + this, SLOT(slotSingleStepChanged(QtProperty*, int))); +} + +#pragma endregion + +// QtSliderFactory +#pragma region QtSliderFactory + +class QtSliderFactoryPrivate : public EditorFactoryPrivate +{ + QtSliderFactory* q_ptr; + Q_DECLARE_PUBLIC(QtSliderFactory) +public: + void slotPropertyChanged(QtProperty* property, int value); + void slotRangeChanged(QtProperty* property, int min, int max); + void slotSingleStepChanged(QtProperty* property, int step); + void slotSetValue(int value); +}; + +void QtSliderFactoryPrivate::slotPropertyChanged(QtProperty* property, int value) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.cend()) + return; + for (QSlider* editor : it.value()) { + editor->blockSignals(true); + editor->setValue(value); + editor->blockSignals(false); + } +} + +void QtSliderFactoryPrivate::slotRangeChanged(QtProperty* property, int min, int max) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.cend()) + return; + + QtIntPropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + + for (QSlider* editor : it.value()) { + editor->blockSignals(true); + editor->setRange(min, max); + editor->setValue(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtSliderFactoryPrivate::slotSingleStepChanged(QtProperty* property, int step) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.cend()) + return; + for (QSlider* editor : it.value()) { + editor->blockSignals(true); + editor->setSingleStep(step); + editor->blockSignals(false); + } +} + +void QtSliderFactoryPrivate::slotSetValue(int value) +{ + QObject* object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) { + if (itEditor.key() == object) { + QtProperty* property = itEditor.value(); + QtIntPropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } + } +} + +/*! + \class QtSliderFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtSliderFactory class provides QSlider widgets for + properties created by QtIntPropertyManager objects. + + \sa QtAbstractEditorFactory, QtIntPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtSliderFactory::QtSliderFactory(QObject* parent) + : QtAbstractEditorFactory(parent), d_ptr(new QtSliderFactoryPrivate()) +{ + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtSliderFactory::~QtSliderFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtSliderFactory::connectPropertyManager(QtIntPropertyManager* manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotPropertyChanged(QtProperty*, int))); + connect(manager, SIGNAL(rangeChanged(QtProperty*, int, int)), + this, SLOT(slotRangeChanged(QtProperty*, int, int))); + connect(manager, SIGNAL(singleStepChanged(QtProperty*, int)), + this, SLOT(slotSingleStepChanged(QtProperty*, int))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget* QtSliderFactory::createEditor(QtIntPropertyManager* manager, QtProperty* property, + QWidget* parent) +{ + QSlider* editor = new QSlider(Qt::Horizontal, parent); + d_ptr->initializeEditor(property, editor); + editor->setSingleStep(manager->singleStep(property)); + editor->setRange(manager->minimum(property), manager->maximum(property)); + editor->setValue(manager->value(property)); + + connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int))); + connect(editor, SIGNAL(destroyed(QObject*)), + this, SLOT(slotEditorDestroyed(QObject*))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtSliderFactory::disconnectPropertyManager(QtIntPropertyManager* manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotPropertyChanged(QtProperty*, int))); + disconnect(manager, SIGNAL(rangeChanged(QtProperty*, int, int)), + this, SLOT(slotRangeChanged(QtProperty*, int, int))); + disconnect(manager, SIGNAL(singleStepChanged(QtProperty*, int)), + this, SLOT(slotSingleStepChanged(QtProperty*, int))); +} + +#pragma endregion + +// QtScrollBarFactory +#pragma region QtScrollBarFactory + +class QtScrollBarFactoryPrivate : public EditorFactoryPrivate +{ + QtScrollBarFactory* q_ptr; + Q_DECLARE_PUBLIC(QtScrollBarFactory) +public: + void slotPropertyChanged(QtProperty* property, int value); + void slotRangeChanged(QtProperty* property, int min, int max); + void slotSingleStepChanged(QtProperty* property, int step); + void slotSetValue(int value); +}; + +void QtScrollBarFactoryPrivate::slotPropertyChanged(QtProperty* property, int value) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.cend()) + return; + + for (QScrollBar* editor : it.value()) { + editor->blockSignals(true); + editor->setValue(value); + editor->blockSignals(false); + } +} + +void QtScrollBarFactoryPrivate::slotRangeChanged(QtProperty* property, int min, int max) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.cend()) + return; + + QtIntPropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + + for (QScrollBar* editor : it.value()) { + editor->blockSignals(true); + editor->setRange(min, max); + editor->setValue(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtScrollBarFactoryPrivate::slotSingleStepChanged(QtProperty* property, int step) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.cend()) + return; + for (QScrollBar* editor : it.value()) { + editor->blockSignals(true); + editor->setSingleStep(step); + editor->blockSignals(false); + } +} + +void QtScrollBarFactoryPrivate::slotSetValue(int value) +{ + QObject* object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty* property = itEditor.value(); + QtIntPropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtScrollBarFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtScrollBarFactory class provides QScrollBar widgets for + properties created by QtIntPropertyManager objects. + + \sa QtAbstractEditorFactory, QtIntPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtScrollBarFactory::QtScrollBarFactory(QObject* parent) + : QtAbstractEditorFactory(parent), d_ptr(new QtScrollBarFactoryPrivate()) +{ + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtScrollBarFactory::~QtScrollBarFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtScrollBarFactory::connectPropertyManager(QtIntPropertyManager* manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotPropertyChanged(QtProperty*, int))); + connect(manager, SIGNAL(rangeChanged(QtProperty*, int, int)), + this, SLOT(slotRangeChanged(QtProperty*, int, int))); + connect(manager, SIGNAL(singleStepChanged(QtProperty*, int)), + this, SLOT(slotSingleStepChanged(QtProperty*, int))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget* QtScrollBarFactory::createEditor(QtIntPropertyManager* manager, QtProperty* property, + QWidget* parent) +{ + QScrollBar* editor = new QScrollBar(Qt::Horizontal, parent); + d_ptr->initializeEditor(property, editor); + editor->setSingleStep(manager->singleStep(property)); + editor->setRange(manager->minimum(property), manager->maximum(property)); + editor->setValue(manager->value(property)); + connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int))); + connect(editor, SIGNAL(destroyed(QObject*)), + this, SLOT(slotEditorDestroyed(QObject*))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtScrollBarFactory::disconnectPropertyManager(QtIntPropertyManager* manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotPropertyChanged(QtProperty*, int))); + disconnect(manager, SIGNAL(rangeChanged(QtProperty*, int, int)), + this, SLOT(slotRangeChanged(QtProperty*, int, int))); + disconnect(manager, SIGNAL(singleStepChanged(QtProperty*, int)), + this, SLOT(slotSingleStepChanged(QtProperty*, int))); +} + +#pragma endregion + +// QtCheckBoxFactory +#pragma region QtCheckBoxFactory + +class QtCheckBoxFactoryPrivate : public EditorFactoryPrivate +{ + QtCheckBoxFactory* q_ptr; + Q_DECLARE_PUBLIC(QtCheckBoxFactory) +public: + void slotPropertyChanged(QtProperty* property, bool value); + void slotSetValue(bool value); +}; + +void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty* property, bool value) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.cend()) + return; + + for (QtBoolEdit* editor : it.value()) { + editor->blockCheckBoxSignals(true); + editor->setChecked(value); + editor->blockCheckBoxSignals(false); + } +} + +void QtCheckBoxFactoryPrivate::slotSetValue(bool value) +{ + QObject* object = q_ptr->sender(); + + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty* property = itEditor.value(); + QtBoolPropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtCheckBoxFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtCheckBoxFactory class provides QCheckBox widgets for + properties created by QtBoolPropertyManager objects. + + \sa QtAbstractEditorFactory, QtBoolPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtCheckBoxFactory::QtCheckBoxFactory(QObject* parent) + : QtAbstractEditorFactory(parent), d_ptr(new QtCheckBoxFactoryPrivate()) +{ + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtCheckBoxFactory::~QtCheckBoxFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCheckBoxFactory::connectPropertyManager(QtBoolPropertyManager* manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*, bool)), + this, SLOT(slotPropertyChanged(QtProperty*, bool))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget* QtCheckBoxFactory::createEditor(QtBoolPropertyManager* manager, QtProperty* property, + QWidget* parent) +{ + QtBoolEdit* editor = d_ptr->createEditor(property, parent); + editor->setChecked(manager->value(property)); + editor->setInitialChecked(manager->initialValue(property)); + + connect(editor, SIGNAL(toggled(bool)), this, SLOT(slotSetValue(bool))); + connect(editor, SIGNAL(destroyed(QObject*)), + this, SLOT(slotEditorDestroyed(QObject*))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCheckBoxFactory::disconnectPropertyManager(QtBoolPropertyManager* manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*, bool)), + this, SLOT(slotPropertyChanged(QtProperty*, bool))); +} + +#pragma endregion + +// QtDoubleSpinBoxFactory +#pragma region QtDoubleSpinBoxFactory + +class QtDoubleSpinBoxFactoryPrivate : public EditorFactoryPrivate +{ + QtDoubleSpinBoxFactory* q_ptr; + Q_DECLARE_PUBLIC(QtDoubleSpinBoxFactory) +public: + + void slotPropertyChanged(QtProperty* property, double value); + void slotRangeChanged(QtProperty* property, double min, double max); + void slotSingleStepChanged(QtProperty* property, double step); + void slotDecimalsChanged(QtProperty* property, int prec); + void slotSetValue(double value); +}; + +void QtDoubleSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty* property, double value) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.cend()) + return; + for (QtDoubleEdit* editor : it.value()) { + if (editor->value() != value) { + editor->blockSignals(true); + editor->setValue(value); + editor->blockSignals(false); + } + } +} + +void QtDoubleSpinBoxFactoryPrivate::slotRangeChanged(QtProperty* property, + double min, double max) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.cend()) + return; + + QtDoublePropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + + for (QtDoubleEdit* editor : it.value()) { + editor->blockSignals(true); + editor->setRange(min, max); + editor->setValue(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtDoubleSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty* property, double step) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.cend()) + return; + + QtDoublePropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + + for (QtDoubleEdit* editor : it.value()) { + editor->blockSignals(true); + editor->setSingleStep(step); + editor->blockSignals(false); + } +} + +void QtDoubleSpinBoxFactoryPrivate::slotDecimalsChanged(QtProperty* property, int prec) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.constEnd()) + return; + + QtDoublePropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + + for (QtDoubleEdit* editor : it.value()) { + editor->blockSignals(true); + editor->setDecimals(prec); + editor->setValue(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtDoubleSpinBoxFactoryPrivate::slotSetValue(double value) +{ + QObject* object = q_ptr->sender(); + const QMap::ConstIterator itcend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != itcend; ++itEditor) { + if (itEditor.key() == object) { + QtProperty* property = itEditor.value(); + QtDoublePropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } + } +} + +/*! \class QtDoubleSpinBoxFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtDoubleSpinBoxFactory class provides QDoubleSpinBox + widgets for properties created by QtDoublePropertyManager objects. + + \sa QtAbstractEditorFactory, QtDoublePropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtDoubleSpinBoxFactory::QtDoubleSpinBoxFactory(QObject* parent) + : QtAbstractEditorFactory(parent), d_ptr(new QtDoubleSpinBoxFactoryPrivate()) +{ + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtDoubleSpinBoxFactory::~QtDoubleSpinBoxFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDoubleSpinBoxFactory::connectPropertyManager(QtDoublePropertyManager* manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*, double)), + this, SLOT(slotPropertyChanged(QtProperty*, double))); + connect(manager, SIGNAL(rangeChanged(QtProperty*, double, double)), + this, SLOT(slotRangeChanged(QtProperty*, double, double))); + connect(manager, SIGNAL(singleStepChanged(QtProperty*, double)), + this, SLOT(slotSingleStepChanged(QtProperty*, double))); + connect(manager, SIGNAL(decimalsChanged(QtProperty*, int)), + this, SLOT(slotDecimalsChanged(QtProperty*, int))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget* QtDoubleSpinBoxFactory::createEditor(QtDoublePropertyManager* manager, + QtProperty* property, QWidget* parent) +{ + QtDoubleEdit* editor = d_ptr->createEditor(property, parent); + editor->setSingleStep(manager->singleStep(property)); + editor->setDecimals(manager->decimals(property)); + editor->setRange(manager->minimum(property), manager->maximum(property)); + editor->setValue(manager->value(property)); + editor->setInitialValue(manager->initialValue(property)); + editor->setKeyboardTracking(false); + + connect(editor, SIGNAL(valueChanged(double)), this, SLOT(slotSetValue(double))); + connect(editor, SIGNAL(destroyed(QObject*)), + this, SLOT(slotEditorDestroyed(QObject*))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDoubleSpinBoxFactory::disconnectPropertyManager(QtDoublePropertyManager* manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*, double)), + this, SLOT(slotPropertyChanged(QtProperty*, double))); + disconnect(manager, SIGNAL(rangeChanged(QtProperty*, double, double)), + this, SLOT(slotRangeChanged(QtProperty*, double, double))); + disconnect(manager, SIGNAL(singleStepChanged(QtProperty*, double)), + this, SLOT(slotSingleStepChanged(QtProperty*, double))); + disconnect(manager, SIGNAL(decimalsChanged(QtProperty*, int)), + this, SLOT(slotDecimalsChanged(QtProperty*, int))); +} + +#pragma endregion + +// QtLineEditFactory +#pragma region QtLineEditFactory + +class QtLineEditFactoryPrivate : public EditorFactoryPrivate +{ + QtLineEditFactory* q_ptr; + Q_DECLARE_PUBLIC(QtLineEditFactory) +public: + + void slotPropertyChanged(QtProperty* property, const QString& value); + void slotRegExpChanged(QtProperty* property, const QRegularExpression& regExp); + void slotSetValue(const QString& value); +}; + +void QtLineEditFactoryPrivate::slotPropertyChanged(QtProperty* property, + const QString& value) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.constEnd()) + return; + + for (QtStringEdit* editor : it.value()) { + if (editor->text() != value) + editor->setText(value); + } +} + +void QtLineEditFactoryPrivate::slotRegExpChanged(QtProperty* property, + const QRegularExpression& regExp) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.constEnd()) + return; + + QtStringPropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + + for (QtStringEdit* editor : it.value()) { + editor->blockSignals(true); + const QValidator* oldValidator = editor->validator(); + QValidator* newValidator = 0; + if (regExp.isValid()) { + newValidator = new QRegularExpressionValidator(regExp, editor); + } + editor->setValidator(newValidator); + if (oldValidator) + delete oldValidator; + editor->blockSignals(false); + } +} + +void QtLineEditFactoryPrivate::slotSetValue(const QString& value) +{ + QObject* object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty* property = itEditor.value(); + QtStringPropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtLineEditFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtLineEditFactory class provides QLineEdit widgets for + properties created by QtStringPropertyManager objects. + + \sa QtAbstractEditorFactory, QtStringPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtLineEditFactory::QtLineEditFactory(QObject* parent) + : QtAbstractEditorFactory(parent), d_ptr(new QtLineEditFactoryPrivate()) +{ + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtLineEditFactory::~QtLineEditFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtLineEditFactory::connectPropertyManager(QtStringPropertyManager* manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*, QString)), + this, SLOT(slotPropertyChanged(QtProperty*, QString))); + connect(manager, SIGNAL(regExpChanged(QtProperty*, QRegularExpression)), + this, SLOT(slotRegExpChanged(QtProperty*, QRegularExpression))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget* QtLineEditFactory::createEditor(QtStringPropertyManager* manager, + QtProperty* property, QWidget* parent) +{ + QtStringEdit* editor = d_ptr->createEditor(property, parent); + QRegularExpression regExp = manager->regExp(property); + if (regExp.isValid() && !regExp.pattern().isEmpty()) { + QValidator* validator = new QRegularExpressionValidator(regExp, editor); + editor->setValidator(validator); + } + editor->setText(manager->value(property)); + editor->setInitialText(manager->initialValue(property)); + + connect(editor, SIGNAL(textEdited(QString)), + this, SLOT(slotSetValue(QString))); + connect(editor, SIGNAL(textChanged(QString)), + this, SLOT(slotSetValue(QString))); + connect(editor, SIGNAL(destroyed(QObject*)), + this, SLOT(slotEditorDestroyed(QObject*))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtLineEditFactory::disconnectPropertyManager(QtStringPropertyManager* manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*, QString)), + this, SLOT(slotPropertyChanged(QtProperty*, QString))); + disconnect(manager, SIGNAL(regExpChanged(QtProperty*, QRegularExpression)), + this, SLOT(slotRegExpChanged(QtProperty*, QRegularExpression))); +} + +#pragma endregion + +// QtDateEditFactory +#pragma region QtDateEditFactory + +class QtDateEditFactoryPrivate : public EditorFactoryPrivate +{ + QtDateEditFactory* q_ptr; + Q_DECLARE_PUBLIC(QtDateEditFactory) +public: + + void slotPropertyChanged(QtProperty* property, QDate value); + void slotRangeChanged(QtProperty* property, QDate min, QDate max); + void slotSetValue(QDate value); +}; + +void QtDateEditFactoryPrivate::slotPropertyChanged(QtProperty* property, QDate value) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.constEnd()) + return; + for (QtDateEdit* editor : it.value()) { + editor->blockSignals(true); + editor->setDate(value); + editor->blockSignals(false); + } +} + +void QtDateEditFactoryPrivate::slotRangeChanged(QtProperty* property, QDate min, QDate max) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.constEnd()) + return; + + QtDatePropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + + for (QtDateEdit* editor : it.value()) { + editor->blockSignals(true); + editor->setDateRange(min, max); + editor->setDate(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtDateEditFactoryPrivate::slotSetValue(QDate value) +{ + QObject* object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty* property = itEditor.value(); + QtDatePropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtDateEditFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtDateEditFactory class provides QDateEdit widgets for + properties created by QtDatePropertyManager objects. + + \sa QtAbstractEditorFactory, QtDatePropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtDateEditFactory::QtDateEditFactory(QObject* parent) + : QtAbstractEditorFactory(parent), d_ptr(new QtDateEditFactoryPrivate()) +{ + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtDateEditFactory::~QtDateEditFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDateEditFactory::connectPropertyManager(QtDatePropertyManager* manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*, QDate)), + this, SLOT(slotPropertyChanged(QtProperty*, QDate))); + connect(manager, SIGNAL(rangeChanged(QtProperty*, QDate, QDate)), + this, SLOT(slotRangeChanged(QtProperty*, QDate, QDate))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget* QtDateEditFactory::createEditor(QtDatePropertyManager* manager, QtProperty* property, + QWidget* parent) +{ + QtDateEdit* editor = d_ptr->createEditor(property, parent); + editor->setDisplayFormat(QtPropertyBrowserUtils::dateFormat()); + editor->setCalendarPopup(true); + editor->setDateRange(manager->minimum(property), manager->maximum(property)); + editor->setDate(manager->value(property)); + editor->setInitialDate(manager->initialValue(property)); + + connect(editor, SIGNAL(dateChanged(QDate)), + this, SLOT(slotSetValue(QDate))); + connect(editor, SIGNAL(destroyed(QObject*)), + this, SLOT(slotEditorDestroyed(QObject*))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDateEditFactory::disconnectPropertyManager(QtDatePropertyManager* manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*, QDate)), + this, SLOT(slotPropertyChanged(QtProperty*, QDate))); + disconnect(manager, SIGNAL(rangeChanged(QtProperty*, QDate, QDate)), + this, SLOT(slotRangeChanged(QtProperty*, QDate, QDate))); +} + +#pragma endregion + +// QtTimeEditFactory +#pragma region QtTimeEditFactory + +class QtTimeEditFactoryPrivate : public EditorFactoryPrivate +{ + QtTimeEditFactory* q_ptr; + Q_DECLARE_PUBLIC(QtTimeEditFactory) +public: + + void slotPropertyChanged(QtProperty* property, QTime value); + void slotSetValue(QTime value); +}; + +void QtTimeEditFactoryPrivate::slotPropertyChanged(QtProperty* property, QTime value) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.constEnd()) + return; + for (QtTimeEdit* editor : it.value()) { + editor->blockSignals(true); + editor->setTime(value); + editor->blockSignals(false); + } +} + +void QtTimeEditFactoryPrivate::slotSetValue(QTime value) +{ + QObject* object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty* property = itEditor.value(); + QtTimePropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtTimeEditFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtTimeEditFactory class provides QTimeEdit widgets for + properties created by QtTimePropertyManager objects. + + \sa QtAbstractEditorFactory, QtTimePropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtTimeEditFactory::QtTimeEditFactory(QObject* parent) + : QtAbstractEditorFactory(parent), d_ptr(new QtTimeEditFactoryPrivate()) +{ + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtTimeEditFactory::~QtTimeEditFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtTimeEditFactory::connectPropertyManager(QtTimePropertyManager* manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*, QTime)), + this, SLOT(slotPropertyChanged(QtProperty*, QTime))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget* QtTimeEditFactory::createEditor(QtTimePropertyManager* manager, QtProperty* property, + QWidget* parent) +{ + QtTimeEdit* editor = d_ptr->createEditor(property, parent); + editor->setDisplayFormat(QtPropertyBrowserUtils::timeFormat()); + editor->setTime(manager->value(property)); + editor->setInitialTime(manager->initialValue(property)); + + connect(editor, SIGNAL(timeChanged(QTime)), + this, SLOT(slotSetValue(QTime))); + connect(editor, SIGNAL(destroyed(QObject*)), + this, SLOT(slotEditorDestroyed(QObject*))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtTimeEditFactory::disconnectPropertyManager(QtTimePropertyManager* manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*, QTime)), + this, SLOT(slotPropertyChanged(QtProperty*, QTime))); +} + +#pragma endregion + +// QtDateTimeEditFactory +#pragma region QtDateTimeEditFactory + +class QtDateTimeEditFactoryPrivate : public EditorFactoryPrivate +{ + QtDateTimeEditFactory* q_ptr; + Q_DECLARE_PUBLIC(QtDateTimeEditFactory) +public: + + void slotPropertyChanged(QtProperty* property, const QDateTime& value); + void slotSetValue(const QDateTime& value); + +}; + +void QtDateTimeEditFactoryPrivate::slotPropertyChanged(QtProperty* property, + const QDateTime& value) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.constEnd()) + return; + + for (QtDateTimeEdit* editor : it.value()) { + editor->blockSignals(true); + editor->setDateTime(value); + editor->blockSignals(false); + } +} + +void QtDateTimeEditFactoryPrivate::slotSetValue(const QDateTime& value) +{ + QObject* object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty* property = itEditor.value(); + QtDateTimePropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtDateTimeEditFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtDateTimeEditFactory class provides QDateTimeEdit + widgets for properties created by QtDateTimePropertyManager objects. + + \sa QtAbstractEditorFactory, QtDateTimePropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtDateTimeEditFactory::QtDateTimeEditFactory(QObject* parent) + : QtAbstractEditorFactory(parent), d_ptr(new QtDateTimeEditFactoryPrivate()) +{ + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtDateTimeEditFactory::~QtDateTimeEditFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDateTimeEditFactory::connectPropertyManager(QtDateTimePropertyManager* manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*, QDateTime)), + this, SLOT(slotPropertyChanged(QtProperty*, QDateTime))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget* QtDateTimeEditFactory::createEditor(QtDateTimePropertyManager* manager, + QtProperty* property, QWidget* parent) +{ + QtDateTimeEdit* editor = d_ptr->createEditor(property, parent); + editor->setDisplayFormat(QtPropertyBrowserUtils::dateTimeFormat()); + editor->setDateTime(manager->value(property)); + editor->setInitialDateTime(manager->initialValue(property)); + + connect(editor, SIGNAL(dateTimeChanged(QDateTime)), + this, SLOT(slotSetValue(QDateTime))); + connect(editor, SIGNAL(destroyed(QObject*)), + this, SLOT(slotEditorDestroyed(QObject*))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtDateTimeEditFactory::disconnectPropertyManager(QtDateTimePropertyManager* manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*, QDateTime)), + this, SLOT(slotPropertyChanged(QtProperty*, QDateTime))); +} + +#pragma endregion + +// QtKeySequenceEditorFactory +#pragma region QtKeySequenceEditorFactory + +class QtKeySequenceEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtKeySequenceEditorFactory* q_ptr; + Q_DECLARE_PUBLIC(QtKeySequenceEditorFactory) +public: + + void slotPropertyChanged(QtProperty* property, const QKeySequence& value); + void slotSetValue(const QKeySequence& value); +}; + +void QtKeySequenceEditorFactoryPrivate::slotPropertyChanged(QtProperty* property, + const QKeySequence& value) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.constEnd()) + return; + + for (QKeySequenceEdit* editor : it.value()) { + editor->blockSignals(true); + editor->setKeySequence(value); + editor->blockSignals(false); + } +} + +void QtKeySequenceEditorFactoryPrivate::slotSetValue(const QKeySequence& value) +{ + QObject* object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty* property = itEditor.value(); + QtKeySequencePropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtKeySequenceEditorFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtKeySequenceEditorFactory class provides editor + widgets for properties created by QtKeySequencePropertyManager objects. + + \sa QtAbstractEditorFactory +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtKeySequenceEditorFactory::QtKeySequenceEditorFactory(QObject* parent) + : QtAbstractEditorFactory(parent), d_ptr(new QtKeySequenceEditorFactoryPrivate()) +{ + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtKeySequenceEditorFactory::~QtKeySequenceEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtKeySequenceEditorFactory::connectPropertyManager(QtKeySequencePropertyManager* manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*, QKeySequence)), + this, SLOT(slotPropertyChanged(QtProperty*, QKeySequence))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget* QtKeySequenceEditorFactory::createEditor(QtKeySequencePropertyManager* manager, + QtProperty* property, QWidget* parent) +{ + QKeySequenceEdit* editor = d_ptr->createEditor(property, parent); + editor->setKeySequence(manager->value(property)); + + connect(editor, SIGNAL(keySequenceChanged(QKeySequence)), + this, SLOT(slotSetValue(QKeySequence))); + connect(editor, SIGNAL(destroyed(QObject*)), + this, SLOT(slotEditorDestroyed(QObject*))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtKeySequenceEditorFactory::disconnectPropertyManager(QtKeySequencePropertyManager* manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*, QKeySequence)), + this, SLOT(slotPropertyChanged(QtProperty*, QKeySequence))); +} + +#pragma endregion + +// QtCharEdit +#pragma region QtCharEdit + +class QtCharEdit : public QWidget +{ + Q_OBJECT +public: + QtCharEdit(QWidget* parent = 0); + + QChar value() const; + bool eventFilter(QObject* o, QEvent* e) override; +public Q_SLOTS: + void setValue(const QChar& value); +Q_SIGNALS: + void valueChanged(const QChar& value); +protected: + void focusInEvent(QFocusEvent* e) override; + void focusOutEvent(QFocusEvent* e) override; + void keyPressEvent(QKeyEvent* e) override; + void keyReleaseEvent(QKeyEvent* e) override; + bool event(QEvent* e) override; +private slots: + void slotClearChar(); +private: + void handleKeyEvent(QKeyEvent* e); + + QChar m_value; + QLineEdit* m_lineEdit; +}; + +QtCharEdit::QtCharEdit(QWidget* parent) + : QWidget(parent), m_lineEdit(new QLineEdit(this)) +{ + QHBoxLayout* layout = new QHBoxLayout(this); + layout->addWidget(m_lineEdit); + layout->setContentsMargins(QMargins()); + m_lineEdit->installEventFilter(this); + m_lineEdit->setReadOnly(true); + m_lineEdit->setFocusProxy(this); + setFocusPolicy(m_lineEdit->focusPolicy()); + setAttribute(Qt::WA_InputMethodEnabled); +} + +bool QtCharEdit::eventFilter(QObject* o, QEvent* e) +{ + if (o == m_lineEdit && e->type() == QEvent::ContextMenu) { + QContextMenuEvent* c = static_cast(e); + QMenu* menu = m_lineEdit->createStandardContextMenu(); + const auto actions = menu->actions(); + for (QAction* action : actions) { + action->setShortcut(QKeySequence()); + QString actionString = action->text(); + const int pos = actionString.lastIndexOf(QLatin1Char('\t')); + if (pos > 0) + actionString = actionString.remove(pos, actionString.length() - pos); + action->setText(actionString); + } + QAction* actionBefore = 0; + if (actions.count() > 0) + actionBefore = actions[0]; + QAction* clearAction = new QAction(tr("Clear Char"), menu); + menu->insertAction(actionBefore, clearAction); + menu->insertSeparator(actionBefore); + clearAction->setEnabled(!m_value.isNull()); + connect(clearAction, SIGNAL(triggered()), this, SLOT(slotClearChar())); + menu->exec(c->globalPos()); + delete menu; + e->accept(); + return true; + } + + return QWidget::eventFilter(o, e); +} + +void QtCharEdit::slotClearChar() +{ + if (m_value.isNull()) + return; + setValue(QChar()); + emit valueChanged(m_value); +} + +void QtCharEdit::handleKeyEvent(QKeyEvent* e) +{ + const int key = e->key(); + switch (key) { + case Qt::Key_Control: + case Qt::Key_Shift: + case Qt::Key_Meta: + case Qt::Key_Alt: + case Qt::Key_Super_L: + case Qt::Key_Return: + return; + default: + break; + } + + const QString text = e->text(); + if (text.count() != 1) + return; + + const QChar c = text.at(0); + if (!c.isPrint()) + return; + + if (m_value == c) + return; + + m_value = c; + const QString str = m_value.isNull() ? QString() : QString(m_value); + m_lineEdit->setText(str); + e->accept(); + emit valueChanged(m_value); +} + +void QtCharEdit::setValue(const QChar& value) +{ + if (value == m_value) + return; + + m_value = value; + QString str = value.isNull() ? QString() : QString(value); + m_lineEdit->setText(str); +} + +QChar QtCharEdit::value() const +{ + return m_value; +} + +void QtCharEdit::focusInEvent(QFocusEvent* e) +{ + m_lineEdit->event(e); + m_lineEdit->selectAll(); + QWidget::focusInEvent(e); +} + +void QtCharEdit::focusOutEvent(QFocusEvent* e) +{ + m_lineEdit->event(e); + QWidget::focusOutEvent(e); +} + +void QtCharEdit::keyPressEvent(QKeyEvent* e) +{ + handleKeyEvent(e); + e->accept(); +} + +void QtCharEdit::keyReleaseEvent(QKeyEvent* e) +{ + m_lineEdit->event(e); +} + +bool QtCharEdit::event(QEvent* e) +{ + switch (e->type()) { + case QEvent::Shortcut: + case QEvent::ShortcutOverride: + case QEvent::KeyRelease: + e->accept(); + return true; + default: + break; + } + return QWidget::event(e); +} + +#pragma endregion + +// QtCharEditorFactory +#pragma region QtCharEditorFactory + +class QtCharEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtCharEditorFactory* q_ptr; + Q_DECLARE_PUBLIC(QtCharEditorFactory) +public: + + void slotPropertyChanged(QtProperty* property, const QChar& value); + void slotSetValue(const QChar& value); + +}; + +void QtCharEditorFactoryPrivate::slotPropertyChanged(QtProperty* property, + const QChar& value) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.constEnd()) + return; + + for (QtCharEdit* editor : it.value()) { + editor->blockSignals(true); + editor->setValue(value); + editor->blockSignals(false); + } +} + +void QtCharEditorFactoryPrivate::slotSetValue(const QChar& value) +{ + QObject* object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty* property = itEditor.value(); + QtCharPropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtCharEditorFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtCharEditorFactory class provides editor + widgets for properties created by QtCharPropertyManager objects. + + \sa QtAbstractEditorFactory +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtCharEditorFactory::QtCharEditorFactory(QObject* parent) + : QtAbstractEditorFactory(parent), d_ptr(new QtCharEditorFactoryPrivate()) +{ + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtCharEditorFactory::~QtCharEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCharEditorFactory::connectPropertyManager(QtCharPropertyManager* manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*, QChar)), + this, SLOT(slotPropertyChanged(QtProperty*, QChar))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget* QtCharEditorFactory::createEditor(QtCharPropertyManager* manager, + QtProperty* property, QWidget* parent) +{ + QtCharEdit* editor = d_ptr->createEditor(property, parent); + editor->setValue(manager->value(property)); + + connect(editor, SIGNAL(valueChanged(QChar)), + this, SLOT(slotSetValue(QChar))); + connect(editor, SIGNAL(destroyed(QObject*)), + this, SLOT(slotEditorDestroyed(QObject*))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCharEditorFactory::disconnectPropertyManager(QtCharPropertyManager* manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*, QChar)), + this, SLOT(slotPropertyChanged(QtProperty*, QChar))); +} + +#pragma endregion + +// QtEnumEditorFactory +#pragma region QtEnumEditorFactory + +class QtEnumEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtEnumEditorFactory* q_ptr; + Q_DECLARE_PUBLIC(QtEnumEditorFactory) +public: + + void slotPropertyChanged(QtProperty* property, int value); + void slotEnumNamesChanged(QtProperty* property, const QStringList&); + void slotEnumIconsChanged(QtProperty* property, const QMap&); + void slotSetValue(int value); +}; + +void QtEnumEditorFactoryPrivate::slotPropertyChanged(QtProperty* property, int value) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.constEnd()) + return; + + for (QComboBox* editor : it.value()) { + editor->blockSignals(true); + editor->setCurrentIndex(value); + editor->blockSignals(false); + } +} + +void QtEnumEditorFactoryPrivate::slotEnumNamesChanged(QtProperty* property, + const QStringList& enumNames) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.constEnd()) + return; + + QtEnumPropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + + QMap enumIcons = manager->enumIcons(property); + + for (QComboBox* editor : it.value()) { + editor->blockSignals(true); + editor->clear(); + editor->addItems(enumNames); + const int nameCount = enumNames.count(); + for (int i = 0; i < nameCount; i++) + editor->setItemIcon(i, enumIcons.value(i)); + editor->setCurrentIndex(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtEnumEditorFactoryPrivate::slotEnumIconsChanged(QtProperty* property, + const QMap& enumIcons) +{ + const auto it = m_createdEditors.constFind(property); + if (it == m_createdEditors.constEnd()) + return; + + QtEnumPropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + + const QStringList enumNames = manager->enumNames(property); + for (QComboBox* editor : it.value()) { + editor->blockSignals(true); + const int nameCount = enumNames.count(); + for (int i = 0; i < nameCount; i++) + editor->setItemIcon(i, enumIcons.value(i)); + editor->setCurrentIndex(manager->value(property)); + editor->blockSignals(false); + } +} + +void QtEnumEditorFactoryPrivate::slotSetValue(int value) +{ + QObject* object = q_ptr->sender(); + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty* property = itEditor.value(); + QtEnumPropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtEnumEditorFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtEnumEditorFactory class provides QComboBox widgets for + properties created by QtEnumPropertyManager objects. + + \sa QtAbstractEditorFactory, QtEnumPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtEnumEditorFactory::QtEnumEditorFactory(QObject* parent) + : QtAbstractEditorFactory(parent), d_ptr(new QtEnumEditorFactoryPrivate()) +{ + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtEnumEditorFactory::~QtEnumEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtEnumEditorFactory::connectPropertyManager(QtEnumPropertyManager* manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotPropertyChanged(QtProperty*, int))); + connect(manager, SIGNAL(enumNamesChanged(QtProperty*, QStringList)), + this, SLOT(slotEnumNamesChanged(QtProperty*, QStringList))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget* QtEnumEditorFactory::createEditor(QtEnumPropertyManager* manager, QtProperty* property, + QWidget* parent) +{ + QComboBox* editor = d_ptr->createEditor(property, parent); + editor->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + editor->view()->setTextElideMode(Qt::ElideRight); + QStringList enumNames = manager->enumNames(property); + editor->addItems(enumNames); + QMap enumIcons = manager->enumIcons(property); + const int enumNamesCount = enumNames.count(); + for (int i = 0; i < enumNamesCount; i++) + editor->setItemIcon(i, enumIcons.value(i)); + editor->setCurrentIndex(manager->value(property)); + + connect(editor, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetValue(int))); + connect(editor, SIGNAL(destroyed(QObject*)), + this, SLOT(slotEditorDestroyed(QObject*))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtEnumEditorFactory::disconnectPropertyManager(QtEnumPropertyManager* manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotPropertyChanged(QtProperty*, int))); + disconnect(manager, SIGNAL(enumNamesChanged(QtProperty*, QStringList)), + this, SLOT(slotEnumNamesChanged(QtProperty*, QStringList))); +} + +#pragma endregion + +// QtCursorEditorFactory +#pragma region QtCursorEditorFactory + +Q_GLOBAL_STATIC(QtCursorDatabase, cursorDatabase) + +class QtCursorEditorFactoryPrivate +{ + QtCursorEditorFactory* q_ptr; + Q_DECLARE_PUBLIC(QtCursorEditorFactory) +public: + QtCursorEditorFactoryPrivate(); + + void slotPropertyChanged(QtProperty* property, const QCursor& cursor); + void slotEnumChanged(QtProperty* property, int value); + void slotEditorDestroyed(QObject* object); + + QtEnumEditorFactory* m_enumEditorFactory; + QtEnumPropertyManager* m_enumPropertyManager; + + QMap m_propertyToEnum; + QMap m_enumToProperty; + QMap m_enumToEditors; + QMap m_editorToEnum; + bool m_updatingEnum; +}; + +QtCursorEditorFactoryPrivate::QtCursorEditorFactoryPrivate() + : m_updatingEnum(false) +{ + +} + +void QtCursorEditorFactoryPrivate::slotPropertyChanged(QtProperty* property, const QCursor& cursor) +{ + // update enum property + QtProperty* enumProp = m_propertyToEnum.value(property); + if (!enumProp) + return; + + m_updatingEnum = true; + m_enumPropertyManager->setValue(enumProp, cursorDatabase()->cursorToValue(cursor)); + m_updatingEnum = false; +} + +void QtCursorEditorFactoryPrivate::slotEnumChanged(QtProperty* property, int value) +{ + if (m_updatingEnum) + return; + // update cursor property + QtProperty* prop = m_enumToProperty.value(property); + if (!prop) + return; + QtCursorPropertyManager* cursorManager = q_ptr->propertyManager(prop); + if (!cursorManager) + return; +#ifndef QT_NO_CURSOR + cursorManager->setValue(prop, QCursor(cursorDatabase()->valueToCursor(value))); +#endif +} + +void QtCursorEditorFactoryPrivate::slotEditorDestroyed(QObject* object) +{ + // remove from m_editorToEnum map; + // remove from m_enumToEditors map; + // if m_enumToEditors doesn't contains more editors delete enum property; + const QMap::ConstIterator ecend = m_editorToEnum.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToEnum.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QWidget* editor = itEditor.key(); + QtProperty* enumProp = itEditor.value(); + m_editorToEnum.remove(editor); + m_enumToEditors[enumProp].removeAll(editor); + if (m_enumToEditors[enumProp].isEmpty()) { + m_enumToEditors.remove(enumProp); + QtProperty* property = m_enumToProperty.value(enumProp); + m_enumToProperty.remove(enumProp); + m_propertyToEnum.remove(property); + delete enumProp; + } + return; + } +} + +/*! + \class QtCursorEditorFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtCursorEditorFactory class provides QComboBox widgets for + properties created by QtCursorPropertyManager objects. + + \sa QtAbstractEditorFactory, QtCursorPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtCursorEditorFactory::QtCursorEditorFactory(QObject* parent) + : QtAbstractEditorFactory(parent), d_ptr(new QtCursorEditorFactoryPrivate()) +{ + d_ptr->q_ptr = this; + + d_ptr->m_enumEditorFactory = new QtEnumEditorFactory(this); + d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this); + connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotEnumChanged(QtProperty*, int))); + d_ptr->m_enumEditorFactory->addPropertyManager(d_ptr->m_enumPropertyManager); +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtCursorEditorFactory::~QtCursorEditorFactory() +{ +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCursorEditorFactory::connectPropertyManager(QtCursorPropertyManager* manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*, QCursor)), + this, SLOT(slotPropertyChanged(QtProperty*, QCursor))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget* QtCursorEditorFactory::createEditor(QtCursorPropertyManager* manager, QtProperty* property, + QWidget* parent) +{ + QtProperty* enumProp = 0; + if (d_ptr->m_propertyToEnum.contains(property)) { + enumProp = d_ptr->m_propertyToEnum[property]; + } + else { + enumProp = d_ptr->m_enumPropertyManager->addProperty(property->propertyName()); + d_ptr->m_enumPropertyManager->setEnumNames(enumProp, cursorDatabase()->cursorShapeNames()); + d_ptr->m_enumPropertyManager->setEnumIcons(enumProp, cursorDatabase()->cursorShapeIcons()); +#ifndef QT_NO_CURSOR + d_ptr->m_enumPropertyManager->setValue(enumProp, cursorDatabase()->cursorToValue(manager->value(property))); +#endif + d_ptr->m_propertyToEnum[property] = enumProp; + d_ptr->m_enumToProperty[enumProp] = property; + } + QtAbstractEditorFactoryBase* af = d_ptr->m_enumEditorFactory; + QWidget* editor = af->createEditor(enumProp, parent); + d_ptr->m_enumToEditors[enumProp].append(editor); + d_ptr->m_editorToEnum[editor] = enumProp; + connect(editor, SIGNAL(destroyed(QObject*)), + this, SLOT(slotEditorDestroyed(QObject*))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtCursorEditorFactory::disconnectPropertyManager(QtCursorPropertyManager* manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*, QCursor)), + this, SLOT(slotPropertyChanged(QtProperty*, QCursor))); +} + +#pragma endregion + +// QtColorEditWidget +#pragma region QtColorEditWidget + +class QtColorEditWidget : public QWidget { + Q_OBJECT + +public: + QtColorEditWidget(QWidget* parent); + + bool eventFilter(QObject* obj, QEvent* ev) override; + +public Q_SLOTS: + void setValue(const QColor& value); + +private Q_SLOTS: + void buttonClicked(); + +Q_SIGNALS: + void valueChanged(const QColor& value); + +private: + QColor m_color; + QLabel* m_pixmapLabel; + QLabel* m_label; + QToolButton* m_button; +}; + +QtColorEditWidget::QtColorEditWidget(QWidget* parent) : + QWidget(parent), + m_pixmapLabel(new QLabel), + m_label(new QLabel), + m_button(new QToolButton) +{ + QHBoxLayout* lt = new QHBoxLayout(this); + setupTreeViewEditorMargin(lt); + lt->setSpacing(0); + lt->addWidget(m_pixmapLabel); + lt->addWidget(m_label); + lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); + + m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored); + m_button->setFixedWidth(20); + setFocusProxy(m_button); + setFocusPolicy(m_button->focusPolicy()); + m_button->setText(tr("...")); + m_button->installEventFilter(this); + connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked())); + lt->addWidget(m_button); + m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::brushValuePixmap(QBrush(m_color))); + m_label->setText(QtPropertyBrowserUtils::colorValueText(m_color)); +} + +void QtColorEditWidget::setValue(const QColor& c) +{ + if (m_color != c) { + m_color = c; + m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::brushValuePixmap(QBrush(c))); + m_label->setText(QtPropertyBrowserUtils::colorValueText(c)); + } +} + +void QtColorEditWidget::buttonClicked() +{ + const QColor newColor = QColorDialog::getColor(m_color, this, QString(), QColorDialog::ShowAlphaChannel); + if (newColor.isValid() && newColor != m_color) { + setValue(newColor); + emit valueChanged(m_color); + } +} + +bool QtColorEditWidget::eventFilter(QObject* obj, QEvent* ev) +{ + if (obj == m_button) { + switch (ev->type()) { + case QEvent::KeyPress: + case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate + switch (static_cast(ev)->key()) { + case Qt::Key_Escape: + case Qt::Key_Enter: + case Qt::Key_Return: + ev->ignore(); + return true; + default: + break; + } + } + break; + default: + break; + } + } + return QWidget::eventFilter(obj, ev); +} + +#pragma endregion + +// QtColorEditorFactoryPrivate +#pragma region QtColorEditorFactoryPrivate + +class QtColorEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtColorEditorFactory* q_ptr; + Q_DECLARE_PUBLIC(QtColorEditorFactory) +public: + + void slotPropertyChanged(QtProperty* property, const QColor& value); + void slotSetValue(const QColor& value); +}; + +void QtColorEditorFactoryPrivate::slotPropertyChanged(QtProperty* property, + const QColor& value) +{ + const PropertyToEditorListMap::const_iterator it = m_createdEditors.constFind(property); + if (it == m_createdEditors.constEnd()) + return; + + for (QtColorEditWidget* e : it.value()) + e->setValue(value); +} + +void QtColorEditorFactoryPrivate::slotSetValue(const QColor& value) +{ + QObject* object = q_ptr->sender(); + const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty* property = itEditor.value(); + QtColorPropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtColorEditorFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtColorEditorFactory class provides color editing for + properties created by QtColorPropertyManager objects. + + \sa QtAbstractEditorFactory, QtColorPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtColorEditorFactory::QtColorEditorFactory(QObject* parent) : + QtAbstractEditorFactory(parent), + d_ptr(new QtColorEditorFactoryPrivate()) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtColorEditorFactory::~QtColorEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtColorEditorFactory::connectPropertyManager(QtColorPropertyManager* manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*, QColor)), + this, SLOT(slotPropertyChanged(QtProperty*, QColor))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget* QtColorEditorFactory::createEditor(QtColorPropertyManager* manager, + QtProperty* property, QWidget* parent) +{ + QtColorEditWidget* editor = d_ptr->createEditor(property, parent); + editor->setValue(manager->value(property)); + connect(editor, SIGNAL(valueChanged(QColor)), this, SLOT(slotSetValue(QColor))); + connect(editor, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtColorEditorFactory::disconnectPropertyManager(QtColorPropertyManager* manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*, QColor)), this, SLOT(slotPropertyChanged(QtProperty*, QColor))); +} + +#pragma endregion + +// QtFontEditWidget +#pragma region QtFontEditWidget + +class QtFontEditWidget : public QWidget { + Q_OBJECT + +public: + QtFontEditWidget(QWidget* parent); + + bool eventFilter(QObject* obj, QEvent* ev) override; + +public Q_SLOTS: + void setValue(const QFont& value); + +private Q_SLOTS: + void buttonClicked(); + +Q_SIGNALS: + void valueChanged(const QFont& value); + +private: + QFont m_font; + QLabel* m_pixmapLabel; + QLabel* m_label; + QToolButton* m_button; +}; + +QtFontEditWidget::QtFontEditWidget(QWidget* parent) : + QWidget(parent), + m_pixmapLabel(new QLabel), + m_label(new QLabel), + m_button(new QToolButton) +{ + QHBoxLayout* lt = new QHBoxLayout(this); + setupTreeViewEditorMargin(lt); + lt->setSpacing(0); + lt->addWidget(m_pixmapLabel); + lt->addWidget(m_label); + lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); + + m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored); + m_button->setFixedWidth(20); + setFocusProxy(m_button); + setFocusPolicy(m_button->focusPolicy()); + m_button->setText(tr("...")); + m_button->installEventFilter(this); + connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked())); + lt->addWidget(m_button); + m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::fontValuePixmap(m_font)); + m_label->setText(QtPropertyBrowserUtils::fontValueText(m_font)); +} + +void QtFontEditWidget::setValue(const QFont& f) +{ + if (m_font != f) { + m_font = f; + m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::fontValuePixmap(f)); + m_label->setText(QtPropertyBrowserUtils::fontValueText(f)); + } +} + +void QtFontEditWidget::buttonClicked() +{ + bool ok = false; + QFont newFont = QFontDialog::getFont(&ok, m_font, this, tr("Select Font")); + if (ok && newFont != m_font) { + QFont f = m_font; + // prevent mask for unchanged attributes, don't change other attributes (like kerning, etc...) + if (m_font.family() != newFont.family()) + f.setFamily(newFont.family()); + if (m_font.pointSize() != newFont.pointSize()) + f.setPointSize(newFont.pointSize()); + if (m_font.bold() != newFont.bold()) + f.setBold(newFont.bold()); + if (m_font.italic() != newFont.italic()) + f.setItalic(newFont.italic()); + if (m_font.underline() != newFont.underline()) + f.setUnderline(newFont.underline()); + if (m_font.strikeOut() != newFont.strikeOut()) + f.setStrikeOut(newFont.strikeOut()); + setValue(f); + emit valueChanged(m_font); + } +} + +bool QtFontEditWidget::eventFilter(QObject* obj, QEvent* ev) +{ + if (obj == m_button) { + switch (ev->type()) { + case QEvent::KeyPress: + case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate + switch (static_cast(ev)->key()) { + case Qt::Key_Escape: + case Qt::Key_Enter: + case Qt::Key_Return: + ev->ignore(); + return true; + default: + break; + } + } + break; + default: + break; + } + } + return QWidget::eventFilter(obj, ev); +} + +#pragma endregion + +// QtFontEditorFactoryPrivate +#pragma region QtFontEditorFactoryPrivate + +class QtFontEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtFontEditorFactory* q_ptr; + Q_DECLARE_PUBLIC(QtFontEditorFactory) +public: + + void slotPropertyChanged(QtProperty* property, const QFont& value); + void slotSetValue(const QFont& value); +}; + +void QtFontEditorFactoryPrivate::slotPropertyChanged(QtProperty* property, + const QFont& value) +{ + const PropertyToEditorListMap::const_iterator it = m_createdEditors.constFind(property); + if (it == m_createdEditors.constEnd()) + return; + + for (QtFontEditWidget* e : it.value()) + e->setValue(value); +} + +void QtFontEditorFactoryPrivate::slotSetValue(const QFont& value) +{ + QObject* object = q_ptr->sender(); + const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty* property = itEditor.value(); + QtFontPropertyManager* manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} + +/*! + \class QtFontEditorFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtFontEditorFactory class provides font editing for + properties created by QtFontPropertyManager objects. + + \sa QtAbstractEditorFactory, QtFontPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtFontEditorFactory::QtFontEditorFactory(QObject* parent) : + QtAbstractEditorFactory(parent), + d_ptr(new QtFontEditorFactoryPrivate()) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtFontEditorFactory::~QtFontEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtFontEditorFactory::connectPropertyManager(QtFontPropertyManager* manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty*, QFont)), + this, SLOT(slotPropertyChanged(QtProperty*, QFont))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget* QtFontEditorFactory::createEditor(QtFontPropertyManager* manager, + QtProperty* property, QWidget* parent) +{ + QtFontEditWidget* editor = d_ptr->createEditor(property, parent); + editor->setValue(manager->value(property)); + connect(editor, SIGNAL(valueChanged(QFont)), this, SLOT(slotSetValue(QFont))); + connect(editor, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtFontEditorFactory::disconnectPropertyManager(QtFontPropertyManager* manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty*, QFont)), this, SLOT(slotPropertyChanged(QtProperty*, QFont))); +} + +#pragma endregion + +QT_END_NAMESPACE + +#include "moc_qteditorfactory.cpp" +#include "qteditorfactory.moc" diff --git a/external/QtPropertyBrowser/src/qteditorfactory.h b/external/QtPropertyBrowser/src/qteditorfactory.h new file mode 100644 index 000000000..61b8f4738 --- /dev/null +++ b/external/QtPropertyBrowser/src/qteditorfactory.h @@ -0,0 +1,396 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTEDITORFACTORY_H +#define QTEDITORFACTORY_H + +#include "qtpropertymanager.h" + +QT_BEGIN_NAMESPACE + +class QRegularExpression; + +class QtSpinBoxFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtSpinBoxFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtSpinBoxFactory(QObject *parent = 0); + ~QtSpinBoxFactory(); +protected: + void connectPropertyManager(QtIntPropertyManager *manager) override; + QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtIntPropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtSpinBoxFactory) + Q_DISABLE_COPY_MOVE(QtSpinBoxFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(int)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtSliderFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtSliderFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtSliderFactory(QObject *parent = 0); + ~QtSliderFactory(); +protected: + void connectPropertyManager(QtIntPropertyManager *manager) override; + QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtIntPropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtSliderFactory) + Q_DISABLE_COPY_MOVE(QtSliderFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(int)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtScrollBarFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtScrollBarFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtScrollBarFactory(QObject *parent = 0); + ~QtScrollBarFactory(); +protected: + void connectPropertyManager(QtIntPropertyManager *manager) override; + QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtIntPropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtScrollBarFactory) + Q_DISABLE_COPY_MOVE(QtScrollBarFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(int)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtCheckBoxFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtCheckBoxFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtCheckBoxFactory(QObject *parent = 0); + ~QtCheckBoxFactory(); +protected: + void connectPropertyManager(QtBoolPropertyManager *manager) override; + QWidget *createEditor(QtBoolPropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtBoolPropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtCheckBoxFactory) + Q_DISABLE_COPY_MOVE(QtCheckBoxFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, bool)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(bool)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtDoubleSpinBoxFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDoubleSpinBoxFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtDoubleSpinBoxFactory(QObject *parent = 0); + ~QtDoubleSpinBoxFactory(); +protected: + void connectPropertyManager(QtDoublePropertyManager *manager) override; + QWidget *createEditor(QtDoublePropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtDoublePropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtDoubleSpinBoxFactory) + Q_DISABLE_COPY_MOVE(QtDoubleSpinBoxFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, double, double)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotDecimalsChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(double)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtLineEditFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtLineEditFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtLineEditFactory(QObject *parent = 0); + ~QtLineEditFactory(); +protected: + void connectPropertyManager(QtStringPropertyManager *manager) override; + QWidget *createEditor(QtStringPropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtStringPropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtLineEditFactory) + Q_DISABLE_COPY_MOVE(QtLineEditFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QString &)) + Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty *, const QRegularExpression &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QString &)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtDateEditFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDateEditFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtDateEditFactory(QObject *parent = 0); + ~QtDateEditFactory(); +protected: + void connectPropertyManager(QtDatePropertyManager *manager) override; + QWidget *createEditor(QtDatePropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtDatePropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtDateEditFactory) + Q_DISABLE_COPY_MOVE(QtDateEditFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, QDate)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, QDate, QDate)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(QDate)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtTimeEditFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtTimeEditFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtTimeEditFactory(QObject *parent = 0); + ~QtTimeEditFactory(); +protected: + void connectPropertyManager(QtTimePropertyManager *manager) override; + QWidget *createEditor(QtTimePropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtTimePropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtTimeEditFactory) + Q_DISABLE_COPY_MOVE(QtTimeEditFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, QTime)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(QTime)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtDateTimeEditFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDateTimeEditFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtDateTimeEditFactory(QObject *parent = 0); + ~QtDateTimeEditFactory(); +protected: + void connectPropertyManager(QtDateTimePropertyManager *manager) override; + QWidget *createEditor(QtDateTimePropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtDateTimePropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtDateTimeEditFactory) + Q_DISABLE_COPY_MOVE(QtDateTimeEditFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QDateTime &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QDateTime &)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtKeySequenceEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtKeySequenceEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtKeySequenceEditorFactory(QObject *parent = 0); + ~QtKeySequenceEditorFactory(); +protected: + void connectPropertyManager(QtKeySequencePropertyManager *manager) override; + QWidget *createEditor(QtKeySequencePropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtKeySequencePropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtKeySequenceEditorFactory) + Q_DISABLE_COPY_MOVE(QtKeySequenceEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QKeySequence &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QKeySequence &)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtCharEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtCharEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtCharEditorFactory(QObject *parent = 0); + ~QtCharEditorFactory(); +protected: + void connectPropertyManager(QtCharPropertyManager *manager) override; + QWidget *createEditor(QtCharPropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtCharPropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtCharEditorFactory) + Q_DISABLE_COPY_MOVE(QtCharEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QChar &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QChar &)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtEnumEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtEnumEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtEnumEditorFactory(QObject *parent = 0); + ~QtEnumEditorFactory(); +protected: + void connectPropertyManager(QtEnumPropertyManager *manager) override; + QWidget *createEditor(QtEnumPropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtEnumPropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtEnumEditorFactory) + Q_DISABLE_COPY_MOVE(QtEnumEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotEnumNamesChanged(QtProperty *, + const QStringList &)) + Q_PRIVATE_SLOT(d_func(), void slotEnumIconsChanged(QtProperty *, + const QMap &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(int)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtCursorEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtCursorEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtCursorEditorFactory(QObject *parent = 0); + ~QtCursorEditorFactory(); +protected: + void connectPropertyManager(QtCursorPropertyManager *manager) override; + QWidget *createEditor(QtCursorPropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtCursorPropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtCursorEditorFactory) + Q_DISABLE_COPY_MOVE(QtCursorEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QCursor &)) + Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + +class QtColorEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtColorEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtColorEditorFactory(QObject *parent = 0); + ~QtColorEditorFactory(); +protected: + void connectPropertyManager(QtColorPropertyManager *manager) override; + QWidget *createEditor(QtColorPropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtColorPropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtColorEditorFactory) + Q_DISABLE_COPY_MOVE(QtColorEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QColor &)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QColor &)) +}; + +class QtFontEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtFontEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtFontEditorFactory(QObject *parent = 0); + ~QtFontEditorFactory(); +protected: + void connectPropertyManager(QtFontPropertyManager *manager) override; + QWidget *createEditor(QtFontPropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtFontPropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtFontEditorFactory) + Q_DISABLE_COPY_MOVE(QtFontEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QFont &)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QFont &)) +}; + +QT_END_NAMESPACE + +#endif diff --git a/external/QtPropertyBrowser/src/qtgroupboxpropertybrowser.cpp b/external/QtPropertyBrowser/src/qtgroupboxpropertybrowser.cpp new file mode 100644 index 000000000..b7534e25b --- /dev/null +++ b/external/QtPropertyBrowser/src/qtgroupboxpropertybrowser.cpp @@ -0,0 +1,520 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtgroupboxpropertybrowser.h" +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QtGroupBoxPropertyBrowserPrivate +{ + QtGroupBoxPropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtGroupBoxPropertyBrowser) +public: + + void init(QWidget *parent); + + void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex); + void propertyRemoved(QtBrowserItem *index); + void propertyChanged(QtBrowserItem *index); + QWidget *createEditor(QtProperty *property, QWidget *parent) const + { return q_ptr->createEditor(property, parent); } + + void slotEditorDestroyed(); + void slotUpdate(); + + struct WidgetItem + { + QWidget *widget{nullptr}; // can be null + QLabel *label{nullptr}; + QLabel *widgetLabel{nullptr}; + QGroupBox *groupBox{nullptr}; + QGridLayout *layout{nullptr}; + QFrame *line{nullptr}; + WidgetItem *parent{nullptr}; + QList children; + }; +private: + void updateLater(); + void updateItem(WidgetItem *item); + void insertRow(QGridLayout *layout, int row) const; + void removeRow(QGridLayout *layout, int row) const; + + bool hasHeader(WidgetItem *item) const; + + QMap m_indexToItem; + QMap m_itemToIndex; + QMap m_widgetToItem; + QGridLayout *m_mainLayout; + QList m_children; + QList m_recreateQueue; +}; + +void QtGroupBoxPropertyBrowserPrivate::init(QWidget *parent) +{ + m_mainLayout = new QGridLayout(); + parent->setLayout(m_mainLayout); + QLayoutItem *item = new QSpacerItem(0, 0, + QSizePolicy::Fixed, QSizePolicy::Expanding); + m_mainLayout->addItem(item, 0, 0); +} + +void QtGroupBoxPropertyBrowserPrivate::slotEditorDestroyed() +{ + QWidget *editor = qobject_cast(q_ptr->sender()); + if (!editor) + return; + if (!m_widgetToItem.contains(editor)) + return; + m_widgetToItem[editor]->widget = 0; + m_widgetToItem.remove(editor); +} + +void QtGroupBoxPropertyBrowserPrivate::slotUpdate() +{ + for (WidgetItem *item : qAsConst(m_recreateQueue)) { + WidgetItem *par = item->parent; + QWidget *w = 0; + QGridLayout *l = 0; + int oldRow = -1; + if (!par) { + w = q_ptr; + l = m_mainLayout; + oldRow = m_children.indexOf(item); + } else { + w = par->groupBox; + l = par->layout; + oldRow = par->children.indexOf(item); + if (hasHeader(par)) + oldRow += 2; + } + + if (item->widget) { + item->widget->setParent(w); + } else if (item->widgetLabel) { + item->widgetLabel->setParent(w); + } else { + item->widgetLabel = new QLabel(w); + } + int span = 1; + if (item->widget) + l->addWidget(item->widget, oldRow, 1, 1, 1); + else if (item->widgetLabel) + l->addWidget(item->widgetLabel, oldRow, 1, 1, 1); + else + span = 2; + item->label = new QLabel(w); + item->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + l->addWidget(item->label, oldRow, 0, 1, span); + + updateItem(item); + } + m_recreateQueue.clear(); +} + +void QtGroupBoxPropertyBrowserPrivate::updateLater() +{ + QTimer::singleShot(0, q_ptr, SLOT(slotUpdate())); +} + +void QtGroupBoxPropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex) +{ + WidgetItem *afterItem = m_indexToItem.value(afterIndex); + WidgetItem *parentItem = m_indexToItem.value(index->parent()); + + WidgetItem *newItem = new WidgetItem(); + newItem->parent = parentItem; + + QGridLayout *layout = 0; + QWidget *parentWidget = 0; + int row = -1; + if (!afterItem) { + row = 0; + if (parentItem) + parentItem->children.insert(0, newItem); + else + m_children.insert(0, newItem); + } else { + if (parentItem) { + row = parentItem->children.indexOf(afterItem) + 1; + parentItem->children.insert(row, newItem); + } else { + row = m_children.indexOf(afterItem) + 1; + m_children.insert(row, newItem); + } + } + if (parentItem && hasHeader(parentItem)) + row += 2; + + if (!parentItem) { + layout = m_mainLayout; + parentWidget = q_ptr;; + } else { + if (!parentItem->groupBox) { + m_recreateQueue.removeAll(parentItem); + WidgetItem *par = parentItem->parent; + QWidget *w = 0; + QGridLayout *l = 0; + int oldRow = -1; + if (!par) { + w = q_ptr; + l = m_mainLayout; + oldRow = m_children.indexOf(parentItem); + } else { + w = par->groupBox; + l = par->layout; + oldRow = par->children.indexOf(parentItem); + if (hasHeader(par)) + oldRow += 2; + } + parentItem->groupBox = new QGroupBox(w); + parentItem->layout = new QGridLayout(); + parentItem->groupBox->setLayout(parentItem->layout); + if (parentItem->label) { + l->removeWidget(parentItem->label); + delete parentItem->label; + parentItem->label = 0; + } + if (parentItem->widget) { + l->removeWidget(parentItem->widget); + parentItem->widget->setParent(parentItem->groupBox); + parentItem->layout->addWidget(parentItem->widget, 0, 0, 1, 2); + parentItem->line = new QFrame(parentItem->groupBox); + } else if (parentItem->widgetLabel) { + l->removeWidget(parentItem->widgetLabel); + delete parentItem->widgetLabel; + parentItem->widgetLabel = 0; + } + if (parentItem->line) { + parentItem->line->setFrameShape(QFrame::HLine); + parentItem->line->setFrameShadow(QFrame::Sunken); + parentItem->layout->addWidget(parentItem->line, 1, 0, 1, 2); + } + l->addWidget(parentItem->groupBox, oldRow, 0, 1, 2); + updateItem(parentItem); + } + layout = parentItem->layout; + parentWidget = parentItem->groupBox; + } + + newItem->label = new QLabel(parentWidget); + newItem->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + newItem->widget = createEditor(index->property(), parentWidget); + if (!newItem->widget) { + newItem->widgetLabel = new QLabel(parentWidget); + } else { + QObject::connect(newItem->widget, SIGNAL(destroyed()), q_ptr, SLOT(slotEditorDestroyed())); + m_widgetToItem[newItem->widget] = newItem; + } + + insertRow(layout, row); + int span = 1; + if (newItem->widget) + layout->addWidget(newItem->widget, row, 1); + else if (newItem->widgetLabel) + layout->addWidget(newItem->widgetLabel, row, 1); + else + span = 2; + layout->addWidget(newItem->label, row, 0, 1, span); + + m_itemToIndex[newItem] = index; + m_indexToItem[index] = newItem; + + updateItem(newItem); +} + +void QtGroupBoxPropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index) +{ + WidgetItem *item = m_indexToItem.value(index); + + m_indexToItem.remove(index); + m_itemToIndex.remove(item); + + WidgetItem *parentItem = item->parent; + + int row = -1; + + if (parentItem) { + row = parentItem->children.indexOf(item); + parentItem->children.removeAt(row); + if (hasHeader(parentItem)) + row += 2; + } else { + row = m_children.indexOf(item); + m_children.removeAt(row); + } + + if (item->widget) + delete item->widget; + if (item->label) + delete item->label; + if (item->widgetLabel) + delete item->widgetLabel; + if (item->groupBox) + delete item->groupBox; + + if (!parentItem) { + removeRow(m_mainLayout, row); + } else if (parentItem->children.count() != 0) { + removeRow(parentItem->layout, row); + } else { + WidgetItem *par = parentItem->parent; + QGridLayout *l = 0; + int oldRow = -1; + if (!par) { + l = m_mainLayout; + oldRow = m_children.indexOf(parentItem); + } else { + l = par->layout; + oldRow = par->children.indexOf(parentItem); + if (hasHeader(par)) + oldRow += 2; + } + + if (parentItem->widget) { + parentItem->widget->hide(); + parentItem->widget->setParent(0); + } else if (parentItem->widgetLabel) { + parentItem->widgetLabel->hide(); + parentItem->widgetLabel->setParent(0); + } else { + //parentItem->widgetLabel = new QLabel(w); + } + l->removeWidget(parentItem->groupBox); + delete parentItem->groupBox; + parentItem->groupBox = 0; + parentItem->line = 0; + parentItem->layout = 0; + if (!m_recreateQueue.contains(parentItem)) + m_recreateQueue.append(parentItem); + updateLater(); + } + m_recreateQueue.removeAll(item); + + delete item; +} + +void QtGroupBoxPropertyBrowserPrivate::insertRow(QGridLayout *layout, int row) const +{ + QMap itemToPos; + int idx = 0; + while (idx < layout->count()) { + int r, c, rs, cs; + layout->getItemPosition(idx, &r, &c, &rs, &cs); + if (r >= row) { + itemToPos[layout->takeAt(idx)] = QRect(r + 1, c, rs, cs); + } else { + idx++; + } + } + + const QMap::ConstIterator icend = itemToPos.constEnd(); + for (QMap::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) { + const QRect r = it.value(); + layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height()); + } +} + +void QtGroupBoxPropertyBrowserPrivate::removeRow(QGridLayout *layout, int row) const +{ + QMap itemToPos; + int idx = 0; + while (idx < layout->count()) { + int r, c, rs, cs; + layout->getItemPosition(idx, &r, &c, &rs, &cs); + if (r > row) { + itemToPos[layout->takeAt(idx)] = QRect(r - 1, c, rs, cs); + } else { + idx++; + } + } + + const QMap::ConstIterator icend = itemToPos.constEnd(); + for (QMap::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) { + const QRect r = it.value(); + layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height()); + } +} + +bool QtGroupBoxPropertyBrowserPrivate::hasHeader(WidgetItem *item) const +{ + if (item->widget) + return true; + return false; +} + +void QtGroupBoxPropertyBrowserPrivate::propertyChanged(QtBrowserItem *index) +{ + WidgetItem *item = m_indexToItem.value(index); + + updateItem(item); +} + +void QtGroupBoxPropertyBrowserPrivate::updateItem(WidgetItem *item) +{ + QtProperty *property = m_itemToIndex[item]->property(); + if (item->groupBox) { + QFont font = item->groupBox->font(); + font.setUnderline(property->isModified()); + item->groupBox->setFont(font); + item->groupBox->setTitle(property->propertyName()); + item->groupBox->setToolTip(property->descriptionToolTip()); + item->groupBox->setStatusTip(property->statusTip()); + item->groupBox->setWhatsThis(property->whatsThis()); + item->groupBox->setEnabled(property->isEnabled()); + } + if (item->label) { + QFont font = item->label->font(); + font.setUnderline(property->isModified()); + item->label->setFont(font); + item->label->setText(property->propertyName()); + item->label->setToolTip(property->descriptionToolTip()); + item->label->setStatusTip(property->statusTip()); + item->label->setWhatsThis(property->whatsThis()); + item->label->setEnabled(property->isEnabled()); + } + if (item->widgetLabel) { + QFont font = item->widgetLabel->font(); + font.setUnderline(false); + item->widgetLabel->setFont(font); + item->widgetLabel->setText(property->valueText()); + item->widgetLabel->setEnabled(property->isEnabled()); + } + if (item->widget) { + QFont font = item->widget->font(); + font.setUnderline(false); + item->widget->setFont(font); + item->widget->setEnabled(property->isEnabled()); + const QString valueToolTip = property->valueToolTip(); + item->widget->setToolTip(valueToolTip.isEmpty() ? property->valueText() : valueToolTip); + } + //item->setIcon(1, property->valueIcon()); +} + + + +/*! + \class QtGroupBoxPropertyBrowser + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtGroupBoxPropertyBrowser class provides a QGroupBox + based property browser. + + A property browser is a widget that enables the user to edit a + given set of properties. Each property is represented by a label + specifying the property's name, and an editing widget (e.g. a line + edit or a combobox) holding its value. A property can have zero or + more subproperties. + + QtGroupBoxPropertyBrowser provides group boxes for all nested + properties, i.e. subproperties are enclosed by a group box with + the parent property's name as its title. For example: + + \image qtgroupboxpropertybrowser.png + + Use the QtAbstractPropertyBrowser API to add, insert and remove + properties from an instance of the QtGroupBoxPropertyBrowser + class. The properties themselves are created and managed by + implementations of the QtAbstractPropertyManager class. + + \sa QtTreePropertyBrowser, QtAbstractPropertyBrowser +*/ + +/*! + Creates a property browser with the given \a parent. +*/ +QtGroupBoxPropertyBrowser::QtGroupBoxPropertyBrowser(QWidget *parent) + : QtAbstractPropertyBrowser(parent), d_ptr(new QtGroupBoxPropertyBrowserPrivate) +{ + d_ptr->q_ptr = this; + + d_ptr->init(this); +} + +/*! + Destroys this property browser. + + Note that the properties that were inserted into this browser are + \e not destroyed since they may still be used in other + browsers. The properties are owned by the manager that created + them. + + \sa QtProperty, QtAbstractPropertyManager +*/ +QtGroupBoxPropertyBrowser::~QtGroupBoxPropertyBrowser() +{ + const QMap::ConstIterator icend = d_ptr->m_itemToIndex.constEnd(); + for (QMap::ConstIterator it = d_ptr->m_itemToIndex.constBegin(); it != icend; ++it) + delete it.key(); +} + +/*! + \reimp +*/ +void QtGroupBoxPropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) +{ + d_ptr->propertyInserted(item, afterItem); +} + +/*! + \reimp +*/ +void QtGroupBoxPropertyBrowser::itemRemoved(QtBrowserItem *item) +{ + d_ptr->propertyRemoved(item); +} + +/*! + \reimp +*/ +void QtGroupBoxPropertyBrowser::itemChanged(QtBrowserItem *item) +{ + d_ptr->propertyChanged(item); +} + +QT_END_NAMESPACE + +#include "moc_qtgroupboxpropertybrowser.cpp" diff --git a/external/QtPropertyBrowser/src/qtgroupboxpropertybrowser.h b/external/QtPropertyBrowser/src/qtgroupboxpropertybrowser.h new file mode 100644 index 000000000..bb1b247c6 --- /dev/null +++ b/external/QtPropertyBrowser/src/qtgroupboxpropertybrowser.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTGROUPBOXPROPERTYBROWSER_H +#define QTGROUPBOXPROPERTYBROWSER_H + +#include "qtpropertybrowser.h" + +QT_BEGIN_NAMESPACE + +class QtGroupBoxPropertyBrowserPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtGroupBoxPropertyBrowser : public QtAbstractPropertyBrowser +{ + Q_OBJECT +public: + + QtGroupBoxPropertyBrowser(QWidget *parent = 0); + ~QtGroupBoxPropertyBrowser(); + +protected: + void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) override; + void itemRemoved(QtBrowserItem *item) override; + void itemChanged(QtBrowserItem *item) override; + +private: + + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtGroupBoxPropertyBrowser) + Q_DISABLE_COPY_MOVE(QtGroupBoxPropertyBrowser) + Q_PRIVATE_SLOT(d_func(), void slotUpdate()) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed()) + +}; + +QT_END_NAMESPACE + +#endif diff --git a/external/QtPropertyBrowser/src/qtpropertybrowser.cmake b/external/QtPropertyBrowser/src/qtpropertybrowser.cmake new file mode 100644 index 000000000..3dfb8e062 --- /dev/null +++ b/external/QtPropertyBrowser/src/qtpropertybrowser.cmake @@ -0,0 +1,66 @@ +# qtpropertybrowser.cmake - Include file for QtPropertyBrowser + +# Include common settings +include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake) + +# Current directory +set(QTPROPERTYBROWSER_DIR ${CMAKE_CURRENT_LIST_DIR}) + +# Determine if we should use the library or compile sources +if(QTPROPERTYBROWSER_USELIB AND NOT QTPROPERTYBROWSER_BUILDLIB) + # Use pre-built library + link_directories(${QTPROPERTYBROWSER_LIBDIR}) + set(QTPROPERTYBROWSER_LIBRARIES ${QTPROPERTYBROWSER_LIBNAME}) +else() + # Compile sources directly + add_compile_definitions(QT_DISABLE_DEPRECATED_BEFORE=0) + + # Define source files + set(QTPROPERTYBROWSER_SOURCES + ${QTPROPERTYBROWSER_DIR}/qtpropertybrowser.cpp + ${QTPROPERTYBROWSER_DIR}/qtpropertymanager.cpp + ${QTPROPERTYBROWSER_DIR}/qteditorfactory.cpp + ${QTPROPERTYBROWSER_DIR}/qtvariantproperty.cpp + ${QTPROPERTYBROWSER_DIR}/qttreepropertybrowser.cpp + ${QTPROPERTYBROWSER_DIR}/qtbuttonpropertybrowser.cpp + ${QTPROPERTYBROWSER_DIR}/qtgroupboxpropertybrowser.cpp + ${QTPROPERTYBROWSER_DIR}/qtpropertybrowserutils.cpp + ) + + # Define header files + set(QTPROPERTYBROWSER_HEADERS + ${QTPROPERTYBROWSER_DIR}/qtpropertybrowser.h + ${QTPROPERTYBROWSER_DIR}/qtpropertymanager.h + ${QTPROPERTYBROWSER_DIR}/qteditorfactory.h + ${QTPROPERTYBROWSER_DIR}/qtvariantproperty.h + ${QTPROPERTYBROWSER_DIR}/qttreepropertybrowser.h + ${QTPROPERTYBROWSER_DIR}/qtbuttonpropertybrowser.h + ${QTPROPERTYBROWSER_DIR}/qtgroupboxpropertybrowser.h + ${QTPROPERTYBROWSER_DIR}/qtpropertybrowserutils_p.h + ) + + # Define resource files + set(QTPROPERTYBROWSER_RESOURCES + ${QTPROPERTYBROWSER_DIR}/qtpropertybrowser.qrc + ) +endif() + +# Windows-specific definitions +if(WIN32) + # Check if we're building a shared library + get_target_property(target_type ${PROJECT_NAME} TYPE) + if(target_type STREQUAL "SHARED_LIBRARY") + add_compile_definitions(QT_QTPROPERTYBROWSER_EXPORT) + elseif(QTPROPERTYBROWSER_USELIB) + add_compile_definitions(QT_QTPROPERTYBROWSER_IMPORT) + endif() +endif() + +# Export variables to parent scope +if(NOT QTPROPERTYBROWSER_USELIB OR QTPROPERTYBROWSER_BUILDLIB) + set(QTPROPERTYBROWSER_SOURCES ${QTPROPERTYBROWSER_SOURCES} PARENT_SCOPE) + set(QTPROPERTYBROWSER_HEADERS ${QTPROPERTYBROWSER_HEADERS} PARENT_SCOPE) + set(QTPROPERTYBROWSER_RESOURCES ${QTPROPERTYBROWSER_RESOURCES} PARENT_SCOPE) +endif() +set(QTPROPERTYBROWSER_LIBRARIES ${QTPROPERTYBROWSER_LIBRARIES} PARENT_SCOPE) +set(QTPROPERTYBROWSER_DIR ${QTPROPERTYBROWSER_DIR} PARENT_SCOPE) \ No newline at end of file diff --git a/external/QtPropertyBrowser/src/qtpropertybrowser.cpp b/external/QtPropertyBrowser/src/qtpropertybrowser.cpp new file mode 100644 index 000000000..601fb854a --- /dev/null +++ b/external/QtPropertyBrowser/src/qtpropertybrowser.cpp @@ -0,0 +1,1951 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtpropertybrowser.h" +#include +#include +#include + +#if defined(Q_CC_MSVC) +# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ +#endif + +QT_BEGIN_NAMESPACE + +class QtPropertyPrivate +{ +public: + QtPropertyPrivate(QtAbstractPropertyManager *manager) : m_enabled(true), m_modified(false), m_manager(manager) {} + QtProperty *q_ptr; + + QSet m_parentItems; + QList m_subItems; + + QString m_valueToolTip; + QString m_descriptionToolTip; + QString m_statusTip; + QString m_whatsThis; + QString m_name; + bool m_enabled; + bool m_modified; + + QtAbstractPropertyManager * const m_manager; +}; + +class QtAbstractPropertyManagerPrivate +{ + QtAbstractPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtAbstractPropertyManager) +public: + void propertyDestroyed(QtProperty *property); + void propertyChanged(QtProperty *property) const; + void propertyRemoved(QtProperty *property, + QtProperty *parentProperty) const; + void propertyInserted(QtProperty *property, QtProperty *parentProperty, + QtProperty *afterProperty) const; + + QSet m_properties; +}; + +/*! + \class QtProperty + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtProperty class encapsulates an instance of a property. + + Properties are created by objects of QtAbstractPropertyManager + subclasses; a manager can create properties of a given type, and + is used in conjunction with the QtAbstractPropertyBrowser class. A + property is always owned by the manager that created it, which can + be retrieved using the propertyManager() function. + + QtProperty contains the most common property attributes, and + provides functions for retrieving as well as setting their values: + + \table + \header \li Getter \li Setter + \row + \li propertyName() \li setPropertyName() + \row + \li statusTip() \li setStatusTip() + \row + \li descriptionToolTip() \li setDescriptionToolTip() + \row + \li valueToolTip() \li setValueToolTip() + \row + \li toolTip() \deprecated in 5.6 \li setToolTip() \deprecated in 5.6 + \row + \li whatsThis() \li setWhatsThis() + \row + \li isEnabled() \li setEnabled() + \row + \li isModified() \li setModified() + \row + \li valueText() \li Nop + \row + \li valueIcon() \li Nop + \endtable + + It is also possible to nest properties: QtProperty provides the + addSubProperty(), insertSubProperty() and removeSubProperty() functions to + manipulate the set of subproperties. Use the subProperties() + function to retrieve a property's current set of subproperties. + Note that nested properties are not owned by the parent property, + i.e. each subproperty is owned by the manager that created it. + + \sa QtAbstractPropertyManager, QtBrowserItem +*/ + +/*! + Creates a property with the given \a manager. + + This constructor is only useful when creating a custom QtProperty + subclass (e.g. QtVariantProperty). To create a regular QtProperty + object, use the QtAbstractPropertyManager::addProperty() + function instead. + + \sa QtAbstractPropertyManager::addProperty() +*/ +QtProperty::QtProperty(QtAbstractPropertyManager *manager) + : d_ptr(new QtPropertyPrivate(manager)) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this property. + + Note that subproperties are detached but not destroyed, i.e. they + can still be used in another context. + + \sa QtAbstractPropertyManager::clear() + +*/ +QtProperty::~QtProperty() +{ + for (QtProperty *property : qAsConst(d_ptr->m_parentItems)) + property->d_ptr->m_manager->d_ptr->propertyRemoved(this, property); + + d_ptr->m_manager->d_ptr->propertyDestroyed(this); + + for (QtProperty *property : qAsConst(d_ptr->m_subItems)) + property->d_ptr->m_parentItems.remove(this); + + for (QtProperty *property : qAsConst(d_ptr->m_parentItems)) + property->d_ptr->m_subItems.removeAll(this); +} + +/*! + Returns the set of subproperties. + + Note that subproperties are not owned by \e this property, but by + the manager that created them. + + \sa insertSubProperty(), removeSubProperty() +*/ +QList QtProperty::subProperties() const +{ + return d_ptr->m_subItems; +} + +/*! + Returns a pointer to the manager that owns this property. +*/ +QtAbstractPropertyManager *QtProperty::propertyManager() const +{ + return d_ptr->m_manager; +} + +/* Note: As of 17.7.2015 for Qt 5.6, the existing 'toolTip' of the Property + * Browser solution was split into valueToolTip() and descriptionToolTip() + * to be able to implement custom tool tip for QTBUG-45442. This could + * be back-ported to the solution. */ + +/*! + Returns the property value's tool tip. + + This is suitable for tool tips over the value (item delegate). + + \since 5.6 + \sa setValueToolTip() +*/ +QString QtProperty::valueToolTip() const +{ + return d_ptr->m_valueToolTip; +} + +/*! + Returns the property description's tool tip. + + This is suitable for tool tips over the description (label). + + \since 5.6 + \sa setDescriptionToolTip() +*/ +QString QtProperty::descriptionToolTip() const +{ + return d_ptr->m_descriptionToolTip; +} + +/*! + Returns the property's status tip. + + \sa setStatusTip() +*/ +QString QtProperty::statusTip() const +{ + return d_ptr->m_statusTip; +} + +/*! + Returns the property's "What's This" help text. + + \sa setWhatsThis() +*/ +QString QtProperty::whatsThis() const +{ + return d_ptr->m_whatsThis; +} + +/*! + Returns the property's name. + + \sa setPropertyName() +*/ +QString QtProperty::propertyName() const +{ + return d_ptr->m_name; +} + +/*! + Returns whether the property is enabled. + + \sa setEnabled() +*/ +bool QtProperty::isEnabled() const +{ + return d_ptr->m_enabled; +} + +/*! + Returns whether the property is modified. + + \sa setModified() +*/ +bool QtProperty::isModified() const +{ + return d_ptr->m_modified; +} + +/*! + Returns whether the property has a value. + + \sa QtAbstractPropertyManager::hasValue() +*/ +bool QtProperty::hasValue() const +{ + return d_ptr->m_manager->hasValue(this); +} + +/*! + Returns an icon representing the current state of this property. + + If the given property type can not generate such an icon, this + function returns an invalid icon. + + \sa QtAbstractPropertyManager::valueIcon() +*/ +QIcon QtProperty::valueIcon() const +{ + return d_ptr->m_manager->valueIcon(this); +} + +/*! + Returns a string representing the current state of this property. + + If the given property type can not generate such a string, this + function returns an empty string. + + \sa QtAbstractPropertyManager::valueText() +*/ +QString QtProperty::valueText() const +{ + return d_ptr->m_manager->valueText(this); +} + +/*! + Sets the property value's tool tip to the given \a text. + + \since 5.6 + \sa valueToolTip() +*/ +void QtProperty::setValueToolTip(const QString &text) +{ + if (d_ptr->m_valueToolTip == text) + return; + + d_ptr->m_valueToolTip = text; + propertyChanged(); +} + +/*! + Sets the property description's tool tip to the given \a text. + + \since 5.6 + \sa descriptionToolTip() +*/ +void QtProperty::setDescriptionToolTip(const QString &text) +{ + if (d_ptr->m_descriptionToolTip == text) + return; + + d_ptr->m_descriptionToolTip = text; + propertyChanged(); +} + +/*! + Sets the property's status tip to the given \a text. + + \sa statusTip() +*/ +void QtProperty::setStatusTip(const QString &text) +{ + if (d_ptr->m_statusTip == text) + return; + + d_ptr->m_statusTip = text; + propertyChanged(); +} + +/*! + Sets the property's "What's This" help text to the given \a text. + + \sa whatsThis() +*/ +void QtProperty::setWhatsThis(const QString &text) +{ + if (d_ptr->m_whatsThis == text) + return; + + d_ptr->m_whatsThis = text; + propertyChanged(); +} + +/*! + \fn void QtProperty::setPropertyName(const QString &name) + + Sets the property's name to the given \a name. + + \sa propertyName() +*/ +void QtProperty::setPropertyName(const QString &text) +{ + if (d_ptr->m_name == text) + return; + + d_ptr->m_name = text; + propertyChanged(); +} + +/*! + Enables or disables the property according to the passed \a enable value. + + \sa isEnabled() +*/ +void QtProperty::setEnabled(bool enable) +{ + if (d_ptr->m_enabled == enable) + return; + + d_ptr->m_enabled = enable; + propertyChanged(); +} + +/*! + Sets the property's modified state according to the passed \a modified value. + + \sa isModified() +*/ +void QtProperty::setModified(bool modified) +{ + if (d_ptr->m_modified == modified) + return; + + d_ptr->m_modified = modified; + propertyChanged(); +} + +/*! + Appends the given \a property to this property's subproperties. + + If the given \a property already is added, this function does + nothing. + + \sa insertSubProperty(), removeSubProperty() +*/ +void QtProperty::addSubProperty(QtProperty *property) +{ + QtProperty *after = 0; + if (d_ptr->m_subItems.count() > 0) + after = d_ptr->m_subItems.last(); + insertSubProperty(property, after); +} + +/*! + \fn void QtProperty::insertSubProperty(QtProperty *property, QtProperty *precedingProperty) + + Inserts the given \a property after the specified \a + precedingProperty into this property's list of subproperties. If + \a precedingProperty is 0, the specified \a property is inserted + at the beginning of the list. + + If the given \a property already is inserted, this function does + nothing. + + \sa addSubProperty(), removeSubProperty() +*/ +void QtProperty::insertSubProperty(QtProperty *property, + QtProperty *afterProperty) +{ + if (!property) + return; + + if (property == this) + return; + + // traverse all children of item. if this item is a child of item then cannot add. + auto pendingList = property->subProperties(); + QMap visited; + while (!pendingList.isEmpty()) { + QtProperty *i = pendingList.first(); + if (i == this) + return; + pendingList.removeFirst(); + if (visited.contains(i)) + continue; + visited[i] = true; + pendingList += i->subProperties(); + } + + pendingList = subProperties(); + int pos = 0; + int newPos = 0; + QtProperty *properAfterProperty = 0; + while (pos < pendingList.count()) { + QtProperty *i = pendingList.at(pos); + if (i == property) + return; // if item is already inserted in this item then cannot add. + if (i == afterProperty) { + newPos = pos + 1; + properAfterProperty = afterProperty; + } + pos++; + } + + d_ptr->m_subItems.insert(newPos, property); + property->d_ptr->m_parentItems.insert(this); + + d_ptr->m_manager->d_ptr->propertyInserted(property, this, properAfterProperty); +} + +/*! + Removes the given \a property from the list of subproperties + without deleting it. + + \sa addSubProperty(), insertSubProperty() +*/ +void QtProperty::removeSubProperty(QtProperty *property) +{ + if (!property) + return; + + d_ptr->m_manager->d_ptr->propertyRemoved(property, this); + + auto pendingList = subProperties(); + int pos = 0; + while (pos < pendingList.count()) { + if (pendingList.at(pos) == property) { + d_ptr->m_subItems.removeAt(pos); + property->d_ptr->m_parentItems.remove(this); + + return; + } + pos++; + } +} + +/*! + \internal +*/ +void QtProperty::propertyChanged() +{ + d_ptr->m_manager->d_ptr->propertyChanged(this); +} + +//////////////////////////////// + +void QtAbstractPropertyManagerPrivate::propertyDestroyed(QtProperty *property) +{ + if (m_properties.contains(property)) { + emit q_ptr->propertyDestroyed(property); + q_ptr->uninitializeProperty(property); + m_properties.remove(property); + } +} + +void QtAbstractPropertyManagerPrivate::propertyChanged(QtProperty *property) const +{ + emit q_ptr->propertyChanged(property); +} + +void QtAbstractPropertyManagerPrivate::propertyRemoved(QtProperty *property, + QtProperty *parentProperty) const +{ + emit q_ptr->propertyRemoved(property, parentProperty); +} + +void QtAbstractPropertyManagerPrivate::propertyInserted(QtProperty *property, + QtProperty *parentProperty, QtProperty *afterProperty) const +{ + emit q_ptr->propertyInserted(property, parentProperty, afterProperty); +} + +/*! + \class QtAbstractPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtAbstractPropertyManager provides an interface for + property managers. + + A manager can create and manage properties of a given type, and is + used in conjunction with the QtAbstractPropertyBrowser class. + + When using a property browser widget, the properties are created + and managed by implementations of the QtAbstractPropertyManager + class. To ensure that the properties' values will be displayed + using suitable editing widgets, the managers are associated with + objects of QtAbstractEditorFactory subclasses. The property browser + will use these associations to determine which factories it should + use to create the preferred editing widgets. + + The QtAbstractPropertyManager class provides common functionality + like creating a property using the addProperty() function, and + retrieving the properties created by the manager using the + properties() function. The class also provides signals that are + emitted when the manager's properties change: propertyInserted(), + propertyRemoved(), propertyChanged() and propertyDestroyed(). + + QtAbstractPropertyManager subclasses are supposed to provide their + own type specific API. Note that several ready-made + implementations are available: + + \list + \li QtBoolPropertyManager + \li QtColorPropertyManager + \li QtDatePropertyManager + \li QtDateTimePropertyManager + \li QtDoublePropertyManager + \li QtEnumPropertyManager + \li QtFlagPropertyManager + \li QtFontPropertyManager + \li QtGroupPropertyManager + \li QtIntPropertyManager + \li QtPointPropertyManager + \li QtRectPropertyManager + \li QtSizePropertyManager + \li QtSizePolicyPropertyManager + \li QtStringPropertyManager + \li QtTimePropertyManager + \li QtVariantPropertyManager + \endlist + + \sa QtAbstractEditorFactoryBase, QtAbstractPropertyBrowser, QtProperty +*/ + +/*! + \fn void QtAbstractPropertyManager::propertyInserted(QtProperty *newProperty, + QtProperty *parentProperty, QtProperty *precedingProperty) + + This signal is emitted when a new subproperty is inserted into an + existing property, passing pointers to the \a newProperty, \a + parentProperty and \a precedingProperty as parameters. + + If \a precedingProperty is 0, the \a newProperty was inserted at + the beginning of the \a parentProperty's subproperties list. + + Note that signal is emitted only if the \a parentProperty is created + by this manager. + + \sa QtAbstractPropertyBrowser::itemInserted() +*/ + +/*! + \fn void QtAbstractPropertyManager::propertyChanged(QtProperty *property) + + This signal is emitted whenever a property's data changes, passing + a pointer to the \a property as parameter. + + Note that signal is only emitted for properties that are created by + this manager. + + \sa QtAbstractPropertyBrowser::itemChanged() +*/ + +/*! + \fn void QtAbstractPropertyManager::propertyRemoved(QtProperty *property, QtProperty *parent) + + This signal is emitted when a subproperty is removed, passing + pointers to the removed \a property and the \a parent property as + parameters. + + Note that signal is emitted only when the \a parent property is + created by this manager. + + \sa QtAbstractPropertyBrowser::itemRemoved() +*/ + +/*! + \fn void QtAbstractPropertyManager::propertyDestroyed(QtProperty *property) + + This signal is emitted when the specified \a property is about to + be destroyed. + + Note that signal is only emitted for properties that are created + by this manager. + + \sa clear(), uninitializeProperty() +*/ + +/*! + \fn void QtAbstractPropertyBrowser::currentItemChanged(QtBrowserItem *current) + + This signal is emitted when the current item changes. The current item is specified by \a current. + + \sa QtAbstractPropertyBrowser::setCurrentItem() +*/ + +/*! + Creates an abstract property manager with the given \a parent. +*/ +QtAbstractPropertyManager::QtAbstractPropertyManager(QObject *parent) + : QObject(parent), d_ptr(new QtAbstractPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; + +} + +/*! + Destroys the manager. All properties created by the manager are + destroyed. +*/ +QtAbstractPropertyManager::~QtAbstractPropertyManager() +{ + clear(); +} + +/*! + Destroys all the properties that this manager has created. + + \sa propertyDestroyed(), uninitializeProperty() +*/ +void QtAbstractPropertyManager::clear() const +{ + while (!d_ptr->m_properties.isEmpty()) + delete *d_ptr->m_properties.cbegin(); +} + +/*! + Returns the set of properties created by this manager. + + \sa addProperty() +*/ +QSet QtAbstractPropertyManager::properties() const +{ + return d_ptr->m_properties; +} + +/*! + Returns whether the given \a property has a value. + + The default implementation of this function returns true. + + \sa QtProperty::hasValue() +*/ +bool QtAbstractPropertyManager::hasValue(const QtProperty *property) const +{ + Q_UNUSED(property); + return true; +} + +/*! + Returns an icon representing the current state of the given \a + property. + + The default implementation of this function returns an invalid + icon. + + \sa QtProperty::valueIcon() +*/ +QIcon QtAbstractPropertyManager::valueIcon(const QtProperty *property) const +{ + Q_UNUSED(property); + return QIcon(); +} + +/*! + Returns a string representing the current state of the given \a + property. + + The default implementation of this function returns an empty + string. + + \sa QtProperty::valueText() +*/ +QString QtAbstractPropertyManager::valueText(const QtProperty *property) const +{ + Q_UNUSED(property); + return QString(); +} + +/*! + Creates a property with the given \a name which then is owned by this manager. + + Internally, this function calls the createProperty() and + initializeProperty() functions. + + \sa initializeProperty(), properties() +*/ +QtProperty *QtAbstractPropertyManager::addProperty(const QString &name) +{ + QtProperty *property = createProperty(); + if (property) { + property->setPropertyName(name); + d_ptr->m_properties.insert(property); + initializeProperty(property); + } + return property; +} + +/*! + Creates a property. + + The base implementation produce QtProperty instances; Reimplement + this function to make this manager produce objects of a QtProperty + subclass. + + \sa addProperty(), initializeProperty() +*/ +QtProperty *QtAbstractPropertyManager::createProperty() +{ + return new QtProperty(this); +} + +/*! + \fn void QtAbstractPropertyManager::initializeProperty(QtProperty *property) = 0 + + This function is called whenever a new valid property pointer has + been created, passing the pointer as parameter. + + The purpose is to let the manager know that the \a property has + been created so that it can provide additional attributes for the + new property, e.g. QtIntPropertyManager adds \l + {QtIntPropertyManager::value()}{value}, \l + {QtIntPropertyManager::minimum()}{minimum} and \l + {QtIntPropertyManager::maximum()}{maximum} attributes. Since each manager + subclass adds type specific attributes, this function is pure + virtual and must be reimplemented when deriving from the + QtAbstractPropertyManager class. + + \sa addProperty(), createProperty() +*/ + +/*! + This function is called just before the specified \a property is destroyed. + + The purpose is to let the property manager know that the \a + property is being destroyed so that it can remove the property's + additional attributes. + + \sa clear(), propertyDestroyed() +*/ +void QtAbstractPropertyManager::uninitializeProperty(QtProperty *property) +{ + Q_UNUSED(property); +} + +//////////////////////////////////// + +/*! + \class QtAbstractEditorFactoryBase + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtAbstractEditorFactoryBase provides an interface for + editor factories. + + An editor factory is a class that is able to create an editing + widget of a specified type (e.g. line edits or comboboxes) for a + given QtProperty object, and it is used in conjunction with the + QtAbstractPropertyManager and QtAbstractPropertyBrowser classes. + + When using a property browser widget, the properties are created + and managed by implementations of the QtAbstractPropertyManager + class. To ensure that the properties' values will be displayed + using suitable editing widgets, the managers are associated with + objects of QtAbstractEditorFactory subclasses. The property browser + will use these associations to determine which factories it should + use to create the preferred editing widgets. + + Typically, an editor factory is created by subclassing the + QtAbstractEditorFactory template class which inherits + QtAbstractEditorFactoryBase. But note that several ready-made + implementations are available: + + \list + \li QtCheckBoxFactory + \li QtDateEditFactory + \li QtDateTimeEditFactory + \li QtDoubleSpinBoxFactory + \li QtEnumEditorFactory + \li QtLineEditFactory + \li QtScrollBarFactory + \li QtSliderFactory + \li QtSpinBoxFactory + \li QtTimeEditFactory + \li QtVariantEditorFactory + \endlist + + \sa QtAbstractPropertyManager, QtAbstractPropertyBrowser +*/ + +/*! + \fn virtual QWidget *QtAbstractEditorFactoryBase::createEditor(QtProperty *property, + QWidget *parent) = 0 + + Creates an editing widget (with the given \a parent) for the given + \a property. + + This function is reimplemented in QtAbstractEditorFactory template class + which also provides a pure virtual convenience overload of this + function enabling access to the property's manager. + + \sa QtAbstractEditorFactory::createEditor() +*/ + +/*! + \fn QtAbstractEditorFactoryBase::QtAbstractEditorFactoryBase(QObject *parent = 0) + + Creates an abstract editor factory with the given \a parent. +*/ + +/*! + \fn virtual void QtAbstractEditorFactoryBase::breakConnection(QtAbstractPropertyManager *manager) = 0 + + \internal + + Detaches property manager from factory. + This method is reimplemented in QtAbstractEditorFactory template subclass. + You don't need to reimplement it in your subclasses. Instead implement more convenient + QtAbstractEditorFactory::disconnectPropertyManager() which gives you access to particular manager subclass. +*/ + +/*! + \fn virtual void QtAbstractEditorFactoryBase::managerDestroyed(QObject *manager) = 0 + + \internal + + This method is called when property manager is being destroyed. + Basically it notifies factory not to produce editors for properties owned by \a manager. + You don't need to reimplement it in your subclass. This method is implemented in + QtAbstractEditorFactory template subclass. +*/ + +/*! + \class QtAbstractEditorFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtAbstractEditorFactory is the base template class for editor + factories. + + An editor factory is a class that is able to create an editing + widget of a specified type (e.g. line edits or comboboxes) for a + given QtProperty object, and it is used in conjunction with the + QtAbstractPropertyManager and QtAbstractPropertyBrowser classes. + + Note that the QtAbstractEditorFactory functions are using the + PropertyManager template argument class which can be any + QtAbstractPropertyManager subclass. For example: + + \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 0 + + Note that QtSpinBoxFactory by definition creates editing widgets + \e only for properties created by QtIntPropertyManager. + + When using a property browser widget, the properties are created + and managed by implementations of the QtAbstractPropertyManager + class. To ensure that the properties' values will be displayed + using suitable editing widgets, the managers are associated with + objects of QtAbstractEditorFactory subclasses. The property browser will + use these associations to determine which factories it should use + to create the preferred editing widgets. + + A QtAbstractEditorFactory object is capable of producing editors for + several property managers at the same time. To create an + association between this factory and a given manager, use the + addPropertyManager() function. Use the removePropertyManager() function to make + this factory stop producing editors for a given property + manager. Use the propertyManagers() function to retrieve the set of + managers currently associated with this factory. + + Several ready-made implementations of the QtAbstractEditorFactory class + are available: + + \list + \li QtCheckBoxFactory + \li QtDateEditFactory + \li QtDateTimeEditFactory + \li QtDoubleSpinBoxFactory + \li QtEnumEditorFactory + \li QtLineEditFactory + \li QtScrollBarFactory + \li QtSliderFactory + \li QtSpinBoxFactory + \li QtTimeEditFactory + \li QtVariantEditorFactory + \endlist + + When deriving from the QtAbstractEditorFactory class, several pure virtual + functions must be implemented: the connectPropertyManager() function is + used by the factory to connect to the given manager's signals, the + createEditor() function is supposed to create an editor for the + given property controlled by the given manager, and finally the + disconnectPropertyManager() function is used by the factory to disconnect + from the specified manager's signals. + + \sa QtAbstractEditorFactoryBase, QtAbstractPropertyManager +*/ + +/*! + \fn QtAbstractEditorFactory::QtAbstractEditorFactory(QObject *parent = 0) + + Creates an editor factory with the given \a parent. + + \sa addPropertyManager() +*/ + +/*! + \fn QWidget *QtAbstractEditorFactory::createEditor(QtProperty *property, QWidget *parent) + + Creates an editing widget (with the given \a parent) for the given + \a property. +*/ + +/*! + \fn void QtAbstractEditorFactory::addPropertyManager(PropertyManager *manager) + + Adds the given \a manager to this factory's set of managers, + making this factory produce editing widgets for properties created + by the given manager. + + The PropertyManager type is a template argument class, and represents the chosen + QtAbstractPropertyManager subclass. + + \sa propertyManagers(), removePropertyManager() +*/ + +/*! + \fn void QtAbstractEditorFactory::removePropertyManager(PropertyManager *manager) + + Removes the given \a manager from this factory's set of + managers. The PropertyManager type is a template argument class, and may be + any QtAbstractPropertyManager subclass. + + \sa propertyManagers(), addPropertyManager() +*/ + +/*! + \fn virtual void QtAbstractEditorFactory::connectPropertyManager(PropertyManager *manager) = 0 + + Connects this factory to the given \a manager's signals. The + PropertyManager type is a template argument class, and represents + the chosen QtAbstractPropertyManager subclass. + + This function is used internally by the addPropertyManager() function, and + makes it possible to update an editing widget when the associated + property's data changes. This is typically done in custom slots + responding to the signals emitted by the property's manager, + e.g. QtIntPropertyManager::valueChanged() and + QtIntPropertyManager::rangeChanged(). + + \sa propertyManagers(), disconnectPropertyManager() +*/ + +/*! + \fn virtual QWidget *QtAbstractEditorFactory::createEditor(PropertyManager *manager, QtProperty *property, + QWidget *parent) = 0 + + Creates an editing widget with the given \a parent for the + specified \a property created by the given \a manager. The + PropertyManager type is a template argument class, and represents + the chosen QtAbstractPropertyManager subclass. + + This function must be implemented in derived classes: It is + recommended to store a pointer to the widget and map it to the + given \a property, since the widget must be updated whenever the + associated property's data changes. This is typically done in + custom slots responding to the signals emitted by the property's + manager, e.g. QtIntPropertyManager::valueChanged() and + QtIntPropertyManager::rangeChanged(). + + \sa connectPropertyManager() +*/ + +/*! + \fn virtual void QtAbstractEditorFactory::disconnectPropertyManager(PropertyManager *manager) = 0 + + Disconnects this factory from the given \a manager's signals. The + PropertyManager type is a template argument class, and represents + the chosen QtAbstractPropertyManager subclass. + + This function is used internally by the removePropertyManager() function. + + \sa propertyManagers(), connectPropertyManager() +*/ + +/*! + \fn QSet QtAbstractEditorFactory::propertyManagers() const + + Returns the factory's set of associated managers. The + PropertyManager type is a template argument class, and represents + the chosen QtAbstractPropertyManager subclass. + + \sa addPropertyManager(), removePropertyManager() +*/ + +/*! + \fn PropertyManager *QtAbstractEditorFactory::propertyManager(QtProperty *property) const + + Returns the property manager for the given \a property, or 0 if + the given \a property doesn't belong to any of this factory's + registered managers. + + The PropertyManager type is a template argument class, and represents the chosen + QtAbstractPropertyManager subclass. + + \sa propertyManagers() +*/ + +/*! + \fn virtual void QtAbstractEditorFactory::managerDestroyed(QObject *manager) + + \internal +*/ + +//////////////////////////////////// +class QtBrowserItemPrivate +{ +public: + QtBrowserItemPrivate(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent) + : m_browser(browser), m_property(property), m_parent(parent), q_ptr(0) {} + + void addChild(QtBrowserItem *index, QtBrowserItem *after); + void removeChild(QtBrowserItem *index); + + QtAbstractPropertyBrowser * const m_browser; + QtProperty *m_property; + QtBrowserItem *m_parent; + + QtBrowserItem *q_ptr; + + QList m_children; + +}; + +void QtBrowserItemPrivate::addChild(QtBrowserItem *index, QtBrowserItem *after) +{ + if (m_children.contains(index)) + return; + int idx = m_children.indexOf(after) + 1; // we insert after returned idx, if it was -1 then we set idx to 0; + m_children.insert(idx, index); +} + +void QtBrowserItemPrivate::removeChild(QtBrowserItem *index) +{ + m_children.removeAll(index); +} + + +/*! + \class QtBrowserItem + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtBrowserItem class represents a property in + a property browser instance. + + Browser items are created whenever a QtProperty is inserted to the + property browser. A QtBrowserItem uniquely identifies a + browser's item. Thus, if the same QtProperty is inserted multiple + times, each occurrence gets its own unique QtBrowserItem. The + items are owned by QtAbstractPropertyBrowser and automatically + deleted when they are removed from the browser. + + You can traverse a browser's properties by calling parent() and + children(). The property and the browser associated with an item + are available as property() and browser(). + + \sa QtAbstractPropertyBrowser, QtProperty +*/ + +/*! + Returns the property which is accosiated with this item. Note that + several items can be associated with the same property instance in + the same property browser. + + \sa QtAbstractPropertyBrowser::items() +*/ + +QtProperty *QtBrowserItem::property() const +{ + return d_ptr->m_property; +} + +/*! + Returns the parent item of \e this item. Returns 0 if \e this item + is associated with top-level property in item's property browser. + + \sa children() +*/ + +QtBrowserItem *QtBrowserItem::parent() const +{ + return d_ptr->m_parent; +} + +/*! + Returns the children items of \e this item. The properties + reproduced from children items are always the same as + reproduced from associated property' children, for example: + + \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 1 + + The \e childrenItems list represents the same list as \e childrenProperties. +*/ + +QList QtBrowserItem::children() const +{ + return d_ptr->m_children; +} + +/*! + Returns the property browser which owns \e this item. +*/ + +QtAbstractPropertyBrowser *QtBrowserItem::browser() const +{ + return d_ptr->m_browser; +} + +QtBrowserItem::QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent) + : d_ptr(new QtBrowserItemPrivate(browser, property, parent)) +{ + d_ptr->q_ptr = this; +} + +QtBrowserItem::~QtBrowserItem() +{ +} + + +//////////////////////////////////// + +typedef QMap > Map1; +typedef QMap > > Map2; +Q_GLOBAL_STATIC(Map1, m_viewToManagerToFactory) +Q_GLOBAL_STATIC(Map2, m_managerToFactoryToViews) + +class QtAbstractPropertyBrowserPrivate +{ + QtAbstractPropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtAbstractPropertyBrowser) +public: + QtAbstractPropertyBrowserPrivate(); + + void insertSubTree(QtProperty *property, + QtProperty *parentProperty); + void removeSubTree(QtProperty *property, + QtProperty *parentProperty); + void createBrowserIndexes(QtProperty *property, QtProperty *parentProperty, QtProperty *afterProperty); + void removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty); + QtBrowserItem *createBrowserIndex(QtProperty *property, QtBrowserItem *parentIndex, QtBrowserItem *afterIndex); + void removeBrowserIndex(QtBrowserItem *index); + void clearIndex(QtBrowserItem *index); + + void slotPropertyInserted(QtProperty *property, + QtProperty *parentProperty, QtProperty *afterProperty); + void slotPropertyRemoved(QtProperty *property, QtProperty *parentProperty); + void slotPropertyDestroyed(QtProperty *property); + void slotPropertyDataChanged(QtProperty *property); + + QList m_subItems; + QMap > m_managerToProperties; + QMap > m_propertyToParents; + + QMap m_topLevelPropertyToIndex; + QList m_topLevelIndexes; + QMap > m_propertyToIndexes; + + QtBrowserItem *m_currentItem; +}; + +QtAbstractPropertyBrowserPrivate::QtAbstractPropertyBrowserPrivate() : + m_currentItem(0) +{ +} + +void QtAbstractPropertyBrowserPrivate::insertSubTree(QtProperty *property, + QtProperty *parentProperty) +{ + if (m_propertyToParents.contains(property)) { + // property was already inserted, so its manager is connected + // and all its children are inserted and theirs managers are connected + // we just register new parent (parent has to be new). + m_propertyToParents[property].append(parentProperty); + // don't need to update m_managerToProperties map since + // m_managerToProperties[manager] already contains property. + return; + } + QtAbstractPropertyManager *manager = property->propertyManager(); + if (m_managerToProperties[manager].isEmpty()) { + // connect manager's signals + q_ptr->connect(manager, SIGNAL(propertyInserted(QtProperty *, + QtProperty *, QtProperty *)), + q_ptr, SLOT(slotPropertyInserted(QtProperty *, + QtProperty *, QtProperty *))); + q_ptr->connect(manager, SIGNAL(propertyRemoved(QtProperty *, + QtProperty *)), + q_ptr, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*))); + q_ptr->connect(manager, SIGNAL(propertyDestroyed(QtProperty*)), + q_ptr, SLOT(slotPropertyDestroyed(QtProperty*))); + q_ptr->connect(manager, SIGNAL(propertyChanged(QtProperty*)), + q_ptr, SLOT(slotPropertyDataChanged(QtProperty*))); + } + m_managerToProperties[manager].append(property); + m_propertyToParents[property].append(parentProperty); + + const auto subList = property->subProperties(); + for (QtProperty *subProperty : subList) + insertSubTree(subProperty, property); +} + +void QtAbstractPropertyBrowserPrivate::removeSubTree(QtProperty *property, + QtProperty *parentProperty) +{ + if (!m_propertyToParents.contains(property)) { + // ASSERT + return; + } + + m_propertyToParents[property].removeAll(parentProperty); + if (!m_propertyToParents[property].isEmpty()) + return; + + m_propertyToParents.remove(property); + QtAbstractPropertyManager *manager = property->propertyManager(); + m_managerToProperties[manager].removeAll(property); + if (m_managerToProperties[manager].isEmpty()) { + // disconnect manager's signals + q_ptr->disconnect(manager, SIGNAL(propertyInserted(QtProperty *, + QtProperty *, QtProperty *)), + q_ptr, SLOT(slotPropertyInserted(QtProperty *, + QtProperty *, QtProperty *))); + q_ptr->disconnect(manager, SIGNAL(propertyRemoved(QtProperty *, + QtProperty *)), + q_ptr, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*))); + q_ptr->disconnect(manager, SIGNAL(propertyDestroyed(QtProperty*)), + q_ptr, SLOT(slotPropertyDestroyed(QtProperty*))); + q_ptr->disconnect(manager, SIGNAL(propertyChanged(QtProperty*)), + q_ptr, SLOT(slotPropertyDataChanged(QtProperty*))); + + m_managerToProperties.remove(manager); + } + + const auto subList = property->subProperties(); + for (QtProperty *subProperty : subList) + removeSubTree(subProperty, property); +} + +void QtAbstractPropertyBrowserPrivate::createBrowserIndexes(QtProperty *property, QtProperty *parentProperty, QtProperty *afterProperty) +{ + QMap parentToAfter; + if (afterProperty) { + const auto it = m_propertyToIndexes.constFind(afterProperty); + if (it == m_propertyToIndexes.constEnd()) + return; + + for (QtBrowserItem *idx : it.value()) { + QtBrowserItem *parentIdx = idx->parent(); + if ((parentProperty && parentIdx && parentIdx->property() == parentProperty) || (!parentProperty && !parentIdx)) + parentToAfter[idx->parent()] = idx; + } + } else if (parentProperty) { + const auto it = m_propertyToIndexes.find(parentProperty); + if (it == m_propertyToIndexes.constEnd()) + return; + + for (QtBrowserItem *idx : it.value()) + parentToAfter[idx] = 0; + } else { + parentToAfter[0] = 0; + } + + const QMap::ConstIterator pcend = parentToAfter.constEnd(); + for (QMap::ConstIterator it = parentToAfter.constBegin(); it != pcend; ++it) + createBrowserIndex(property, it.key(), it.value()); +} + +QtBrowserItem *QtAbstractPropertyBrowserPrivate::createBrowserIndex(QtProperty *property, + QtBrowserItem *parentIndex, QtBrowserItem *afterIndex) +{ + QtBrowserItem *newIndex = new QtBrowserItem(q_ptr, property, parentIndex); + if (parentIndex) { + parentIndex->d_ptr->addChild(newIndex, afterIndex); + } else { + m_topLevelPropertyToIndex[property] = newIndex; + m_topLevelIndexes.insert(m_topLevelIndexes.indexOf(afterIndex) + 1, newIndex); + } + m_propertyToIndexes[property].append(newIndex); + + q_ptr->itemInserted(newIndex, afterIndex); + + const auto subItems = property->subProperties(); + QtBrowserItem *afterChild = 0; + for (QtProperty *child : subItems) + afterChild = createBrowserIndex(child, newIndex, afterChild); + return newIndex; +} + +void QtAbstractPropertyBrowserPrivate::removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty) +{ + QList toRemove; + const auto it = m_propertyToIndexes.constFind(property); + if (it == m_propertyToIndexes.constEnd()) + return; + + for (QtBrowserItem *idx : it.value()) { + QtBrowserItem *parentIdx = idx->parent(); + if ((parentProperty && parentIdx && parentIdx->property() == parentProperty) || (!parentProperty && !parentIdx)) + toRemove.append(idx); + } + + for (QtBrowserItem *index : qAsConst(toRemove)) + removeBrowserIndex(index); +} + +void QtAbstractPropertyBrowserPrivate::removeBrowserIndex(QtBrowserItem *index) +{ + const auto children = index->children(); + for (int i = children.count(); i > 0; i--) { + removeBrowserIndex(children.at(i - 1)); + } + + q_ptr->itemRemoved(index); + + if (index->parent()) { + index->parent()->d_ptr->removeChild(index); + } else { + m_topLevelPropertyToIndex.remove(index->property()); + m_topLevelIndexes.removeAll(index); + } + + QtProperty *property = index->property(); + + m_propertyToIndexes[property].removeAll(index); + if (m_propertyToIndexes[property].isEmpty()) + m_propertyToIndexes.remove(property); + + delete index; +} + +void QtAbstractPropertyBrowserPrivate::clearIndex(QtBrowserItem *index) +{ + const auto children = index->children(); + for (QtBrowserItem *item : children) + clearIndex(item); + delete index; +} + +void QtAbstractPropertyBrowserPrivate::slotPropertyInserted(QtProperty *property, + QtProperty *parentProperty, QtProperty *afterProperty) +{ + if (!m_propertyToParents.contains(parentProperty)) + return; + createBrowserIndexes(property, parentProperty, afterProperty); + insertSubTree(property, parentProperty); + //q_ptr->propertyInserted(property, parentProperty, afterProperty); +} + +void QtAbstractPropertyBrowserPrivate::slotPropertyRemoved(QtProperty *property, + QtProperty *parentProperty) +{ + if (!m_propertyToParents.contains(parentProperty)) + return; + removeSubTree(property, parentProperty); // this line should be probably moved down after propertyRemoved call + //q_ptr->propertyRemoved(property, parentProperty); + removeBrowserIndexes(property, parentProperty); +} + +void QtAbstractPropertyBrowserPrivate::slotPropertyDestroyed(QtProperty *property) +{ + if (!m_subItems.contains(property)) + return; + q_ptr->removeProperty(property); +} + +void QtAbstractPropertyBrowserPrivate::slotPropertyDataChanged(QtProperty *property) +{ + if (!m_propertyToParents.contains(property)) + return; + + const auto it = m_propertyToIndexes.constFind(property); + if (it == m_propertyToIndexes.constEnd()) + return; + + const auto indexes = it.value(); + for (QtBrowserItem *idx : indexes) + q_ptr->itemChanged(idx); + //q_ptr->propertyChanged(property); +} + +/*! + \class QtAbstractPropertyBrowser + \internal + \inmodule QtDesigner + \since 4.4 + + \brief QtAbstractPropertyBrowser provides a base class for + implementing property browsers. + + A property browser is a widget that enables the user to edit a + given set of properties. Each property is represented by a label + specifying the property's name, and an editing widget (e.g. a line + edit or a combobox) holding its value. A property can have zero or + more subproperties. + + \image qtpropertybrowser.png + + The top level properties can be retrieved using the + properties() function. To traverse each property's + subproperties, use the QtProperty::subProperties() function. In + addition, the set of top level properties can be manipulated using + the addProperty(), insertProperty() and removeProperty() + functions. Note that the QtProperty class provides a corresponding + set of functions making it possible to manipulate the set of + subproperties as well. + + To remove all the properties from the property browser widget, use + the clear() function. This function will clear the editor, but it + will not delete the properties since they can still be used in + other editors. + + The properties themselves are created and managed by + implementations of the QtAbstractPropertyManager class. A manager + can handle (i.e. create and manage) properties of a given type. In + the property browser the managers are associated with + implementations of the QtAbstractEditorFactory: A factory is a + class able to create an editing widget of a specified type. + + When using a property browser widget, managers must be created for + each of the required property types before the properties + themselves can be created. To ensure that the properties' values + will be displayed using suitable editing widgets, the managers + must be associated with objects of the preferred factory + implementations using the setFactoryForManager() function. The + property browser will use these associations to determine which + factory it should use to create the preferred editing widget. + + Note that a factory can be associated with many managers, but a + manager can only be associated with one single factory within the + context of a single property browser. The associations between + managers and factories can at any time be removed using the + unsetFactoryForManager() function. + + Whenever the property data changes or a property is inserted or + removed, the itemChanged(), itemInserted() or + itemRemoved() functions are called, respectively. These + functions must be reimplemented in derived classes in order to + update the property browser widget. Be aware that some property + instances can appear several times in an abstract tree + structure. For example: + + \table 100% + \row + \li + \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 2 + \li \image qtpropertybrowser-duplicate.png + \endtable + + The addProperty() function returns a QtBrowserItem that uniquely + identifies the created item. + + To make a property editable in the property browser, the + createEditor() function must be called to provide the + property with a suitable editing widget. + + Note that there are two ready-made property browser + implementations: + + \list + \li QtGroupBoxPropertyBrowser + \li QtTreePropertyBrowser + \endlist + + \sa QtAbstractPropertyManager, QtAbstractEditorFactoryBase +*/ + +/*! + \fn void QtAbstractPropertyBrowser::setFactoryForManager(PropertyManager *manager, + QtAbstractEditorFactory *factory) + + Connects the given \a manager to the given \a factory, ensuring + that properties of the \a manager's type will be displayed with an + editing widget suitable for their value. + + For example: + + \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 3 + + In this example the \c myInteger property's value is displayed + with a QSpinBox widget, while the \c myDouble property's value is + displayed with a QDoubleSpinBox widget. + + Note that a factory can be associated with many managers, but a + manager can only be associated with one single factory. If the + given \a manager already is associated with another factory, the + old association is broken before the new one established. + + This function ensures that the given \a manager and the given \a + factory are compatible, and it automatically calls the + QtAbstractEditorFactory::addPropertyManager() function if necessary. + + \sa unsetFactoryForManager() +*/ + +/*! + \fn virtual void QtAbstractPropertyBrowser::itemInserted(QtBrowserItem *insertedItem, + QtBrowserItem *precedingItem) = 0 + + This function is called to update the widget whenever a property + is inserted or added to the property browser, passing pointers to + the \a insertedItem of property and the specified + \a precedingItem as parameters. + + If \a precedingItem is 0, the \a insertedItem was put at + the beginning of its parent item's list of subproperties. If + the parent of \a insertedItem is 0, the \a insertedItem was added as a top + level property of \e this property browser. + + This function must be reimplemented in derived classes. Note that + if the \a insertedItem's property has subproperties, this + method will be called for those properties as soon as the current call is finished. + + \sa insertProperty(), addProperty() +*/ + +/*! + \fn virtual void QtAbstractPropertyBrowser::itemRemoved(QtBrowserItem *item) = 0 + + This function is called to update the widget whenever a property + is removed from the property browser, passing the pointer to the + \a item of the property as parameters. The passed \a item is + deleted just after this call is finished. + + If the the parent of \a item is 0, the removed \a item was a + top level property in this editor. + + This function must be reimplemented in derived classes. Note that + if the removed \a item's property has subproperties, this + method will be called for those properties just before the current call is started. + + \sa removeProperty() +*/ + +/*! + \fn virtual void QtAbstractPropertyBrowser::itemChanged(QtBrowserItem *item) = 0 + + This function is called whenever a property's data changes, + passing a pointer to the \a item of property as parameter. + + This function must be reimplemented in derived classes in order to + update the property browser widget whenever a property's name, + tool tip, status tip, "what's this" text, value text or value icon + changes. + + Note that if the property browser contains several occurrences of + the same property, this method will be called once for each + occurrence (with a different item each time). + + \sa QtProperty, items() +*/ + +/*! + Creates an abstract property browser with the given \a parent. +*/ +QtAbstractPropertyBrowser::QtAbstractPropertyBrowser(QWidget *parent) + : QWidget(parent), d_ptr(new QtAbstractPropertyBrowserPrivate) +{ + d_ptr->q_ptr = this; + +} + +/*! + Destroys the property browser, and destroys all the items that were + created by this property browser. + + Note that the properties that were displayed in the editor are not + deleted since they still can be used in other editors. Neither + does the destructor delete the property managers and editor + factories that were used by this property browser widget unless + this widget was their parent. + + \sa QtAbstractPropertyManager::~QtAbstractPropertyManager() +*/ +QtAbstractPropertyBrowser::~QtAbstractPropertyBrowser() +{ + const auto indexes = topLevelItems(); + for (QtBrowserItem *item : indexes) + d_ptr->clearIndex(item); +} + +/*! + Returns the property browser's list of top level properties. + + To traverse the subproperties, use the QtProperty::subProperties() + function. + + \sa addProperty(), insertProperty(), removeProperty() +*/ +QList QtAbstractPropertyBrowser::properties() const +{ + return d_ptr->m_subItems; +} + +/*! + Returns the property browser's list of all items associated + with the given \a property. + + There is one item per instance of the property in the browser. + + \sa topLevelItem() +*/ + +QList QtAbstractPropertyBrowser::items(QtProperty *property) const +{ + return d_ptr->m_propertyToIndexes.value(property); +} + +/*! + Returns the top-level items associated with the given \a property. + + Returns 0 if \a property wasn't inserted into this property + browser or isn't a top-level one. + + \sa topLevelItems(), items() +*/ + +QtBrowserItem *QtAbstractPropertyBrowser::topLevelItem(QtProperty *property) const +{ + return d_ptr->m_topLevelPropertyToIndex.value(property); +} + +/*! + Returns the list of top-level items. + + \sa topLevelItem() +*/ + +QList QtAbstractPropertyBrowser::topLevelItems() const +{ + return d_ptr->m_topLevelIndexes; +} + +/*! + Removes all the properties from the editor, but does not delete + them since they can still be used in other editors. + + \sa removeProperty(), QtAbstractPropertyManager::clear() +*/ +void QtAbstractPropertyBrowser::clear() +{ + const auto subList = properties(); + for (auto rit = subList.crbegin(), rend = subList.crend(); rit != rend; ++rit) + removeProperty(*rit); +} + +/*! + Appends the given \a property (and its subproperties) to the + property browser's list of top level properties. Returns the item + created by property browser which is associated with the \a property. + In order to get all children items created by the property + browser in this call, the returned item should be traversed. + + If the specified \a property is already added, this function does + nothing and returns 0. + + \sa insertProperty(), QtProperty::addSubProperty(), properties() +*/ +QtBrowserItem *QtAbstractPropertyBrowser::addProperty(QtProperty *property) +{ + QtProperty *afterProperty = 0; + if (d_ptr->m_subItems.count() > 0) + afterProperty = d_ptr->m_subItems.last(); + return insertProperty(property, afterProperty); +} + +/*! + \fn QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property, + QtProperty *afterProperty) + + Inserts the given \a property (and its subproperties) after + the specified \a afterProperty in the browser's list of top + level properties. Returns item created by property browser which + is associated with the \a property. In order to get all children items + created by the property browser in this call returned item should be traversed. + + If the specified \a afterProperty is 0, the given \a property is + inserted at the beginning of the list. If \a property is + already inserted, this function does nothing and returns 0. + + \sa addProperty(), QtProperty::insertSubProperty(), properties() +*/ +QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property, + QtProperty *afterProperty) +{ + if (!property) + return 0; + + // if item is already inserted in this item then cannot add. + auto pendingList = properties(); + int pos = 0; + int newPos = 0; + while (pos < pendingList.count()) { + QtProperty *prop = pendingList.at(pos); + if (prop == property) + return 0; + if (prop == afterProperty) { + newPos = pos + 1; + } + pos++; + } + d_ptr->createBrowserIndexes(property, 0, afterProperty); + + // traverse inserted subtree and connect to manager's signals + d_ptr->insertSubTree(property, 0); + + d_ptr->m_subItems.insert(newPos, property); + //propertyInserted(property, 0, properAfterProperty); + return topLevelItem(property); +} + +/*! + Removes the specified \a property (and its subproperties) from the + property browser's list of top level properties. All items + that were associated with the given \a property and its children + are deleted. + + Note that the properties are \e not deleted since they can still + be used in other editors. + + \sa clear(), QtProperty::removeSubProperty(), properties() +*/ +void QtAbstractPropertyBrowser::removeProperty(QtProperty *property) +{ + if (!property) + return; + + auto pendingList = properties(); + int pos = 0; + while (pos < pendingList.count()) { + if (pendingList.at(pos) == property) { + d_ptr->m_subItems.removeAt(pos); //perhaps this two lines + d_ptr->removeSubTree(property, 0); //should be moved down after propertyRemoved call. + //propertyRemoved(property, 0); + + d_ptr->removeBrowserIndexes(property, 0); + + // when item is deleted, item will call removeItem for top level items, + // and itemRemoved for nested items. + + return; + } + pos++; + } +} + +/*! + Creates an editing widget (with the given \a parent) for the given + \a property according to the previously established associations + between property managers and editor factories. + + If the property is created by a property manager which was not + associated with any of the existing factories in \e this property + editor, the function returns 0. + + To make a property editable in the property browser, the + createEditor() function must be called to provide the + property with a suitable editing widget. + + Reimplement this function to provide additional decoration for the + editing widgets created by the installed factories. + + \sa setFactoryForManager() +*/ +QWidget *QtAbstractPropertyBrowser::createEditor(QtProperty *property, + QWidget *parent) +{ + QtAbstractEditorFactoryBase *factory = 0; + QtAbstractPropertyManager *manager = property->propertyManager(); + + if (m_viewToManagerToFactory()->contains(this) && + (*m_viewToManagerToFactory())[this].contains(manager)) { + factory = (*m_viewToManagerToFactory())[this][manager]; + } + + if (!factory) + return 0; + QWidget *w = factory->createEditor(property, parent); + // Since some editors can be QComboBoxes, and we changed their focus policy in Qt 5 + // to make them feel more native on Mac, we need to relax the focus policy to something + // more permissive to keep the combo box from losing focus, allowing it to stay alive, + // when the user clicks on it to show the popup. + if (w) + w->setFocusPolicy(Qt::WheelFocus); + return w; +} + +bool QtAbstractPropertyBrowser::addFactory(QtAbstractPropertyManager *abstractManager, + QtAbstractEditorFactoryBase *abstractFactory) +{ + bool connectNeeded = false; + if (!m_managerToFactoryToViews()->contains(abstractManager) || + !(*m_managerToFactoryToViews())[abstractManager].contains(abstractFactory)) { + connectNeeded = true; + } else if ((*m_managerToFactoryToViews())[abstractManager][abstractFactory] + .contains(this)) { + return connectNeeded; + } + + if (m_viewToManagerToFactory()->contains(this) && + (*m_viewToManagerToFactory())[this].contains(abstractManager)) { + unsetFactoryForManager(abstractManager); + } + + (*m_managerToFactoryToViews())[abstractManager][abstractFactory].append(this); + (*m_viewToManagerToFactory())[this][abstractManager] = abstractFactory; + + return connectNeeded; +} + +/*! + Removes the association between the given \a manager and the + factory bound to it, automatically calling the + QtAbstractEditorFactory::removePropertyManager() function if necessary. + + \sa setFactoryForManager() +*/ +void QtAbstractPropertyBrowser::unsetFactoryForManager(QtAbstractPropertyManager *manager) +{ + if (!m_viewToManagerToFactory()->contains(this) || + !(*m_viewToManagerToFactory())[this].contains(manager)) { + return; + } + + QtAbstractEditorFactoryBase *abstractFactory = + (*m_viewToManagerToFactory())[this][manager]; + (*m_viewToManagerToFactory())[this].remove(manager); + if ((*m_viewToManagerToFactory())[this].isEmpty()) { + (*m_viewToManagerToFactory()).remove(this); + } + + (*m_managerToFactoryToViews())[manager][abstractFactory].removeAll(this); + if ((*m_managerToFactoryToViews())[manager][abstractFactory].isEmpty()) { + (*m_managerToFactoryToViews())[manager].remove(abstractFactory); + abstractFactory->breakConnection(manager); + if ((*m_managerToFactoryToViews())[manager].isEmpty()) { + (*m_managerToFactoryToViews()).remove(manager); + } + } +} + +/*! + Returns the current item in the property browser. + + \sa setCurrentItem() +*/ +QtBrowserItem *QtAbstractPropertyBrowser::currentItem() const +{ + return d_ptr->m_currentItem; +} + +/*! + Sets the current item in the property browser to \a item. + + \sa currentItem(), currentItemChanged() +*/ +void QtAbstractPropertyBrowser::setCurrentItem(QtBrowserItem *item) +{ + QtBrowserItem *oldItem = d_ptr->m_currentItem; + d_ptr->m_currentItem = item; + if (oldItem != item) + emit currentItemChanged(item); +} + +QT_END_NAMESPACE + +#include "moc_qtpropertybrowser.cpp" diff --git a/external/QtPropertyBrowser/src/qtpropertybrowser.h b/external/QtPropertyBrowser/src/qtpropertybrowser.h new file mode 100644 index 000000000..7547f8546 --- /dev/null +++ b/external/QtPropertyBrowser/src/qtpropertybrowser.h @@ -0,0 +1,319 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTPROPERTYBROWSER_H +#define QTPROPERTYBROWSER_H + +#include +#include + +QT_BEGIN_NAMESPACE + +#if defined(Q_OS_WIN) +# if !defined(QT_QTPROPERTYBROWSER_EXPORT) && !defined(QT_QTPROPERTYBROWSER_IMPORT) +# define QT_QTPROPERTYBROWSER_EXPORT +# elif defined(QT_QTPROPERTYBROWSER_IMPORT) +# if defined(QT_QTPROPERTYBROWSER_EXPORT) +# undef QT_QTPROPERTYBROWSER_EXPORT +# endif +# define QT_QTPROPERTYBROWSER_EXPORT __declspec(dllimport) +# elif defined(QT_QTPROPERTYBROWSER_EXPORT) +# undef QT_QTPROPERTYBROWSER_EXPORT +# define QT_QTPROPERTYBROWSER_EXPORT __declspec(dllexport) +# endif +#else +# define QT_QTPROPERTYBROWSER_EXPORT +#endif + +class QtAbstractPropertyManager; +class QtPropertyPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtProperty +{ +public: + virtual ~QtProperty(); + + QList subProperties() const; + + QtAbstractPropertyManager *propertyManager() const; + + QString toolTip() const { return valueToolTip(); } // Compatibility + QString valueToolTip() const; + QString descriptionToolTip() const; + QString statusTip() const; + QString whatsThis() const; + QString propertyName() const; + bool isEnabled() const; + bool isModified() const; + + bool hasValue() const; + QIcon valueIcon() const; + QString valueText() const; + + void setToolTip(const QString &text) { setValueToolTip(text); } // Compatibility + void setValueToolTip(const QString &text); + void setDescriptionToolTip(const QString &text); + void setStatusTip(const QString &text); + void setWhatsThis(const QString &text); + void setPropertyName(const QString &text); + void setEnabled(bool enable); + void setModified(bool modified); + + void addSubProperty(QtProperty *property); + void insertSubProperty(QtProperty *property, QtProperty *afterProperty); + void removeSubProperty(QtProperty *property); +protected: + explicit QtProperty(QtAbstractPropertyManager *manager); + void propertyChanged(); +private: + friend class QtAbstractPropertyManager; + QScopedPointer d_ptr; +}; + +class QtAbstractPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtAbstractPropertyManager : public QObject +{ + Q_OBJECT +public: + + explicit QtAbstractPropertyManager(QObject *parent = 0); + ~QtAbstractPropertyManager(); + + QSet properties() const; + void clear() const; + + QtProperty *addProperty(const QString &name = QString()); +Q_SIGNALS: + + void propertyInserted(QtProperty *property, + QtProperty *parent, QtProperty *after); + void propertyChanged(QtProperty *property); + void propertyRemoved(QtProperty *property, QtProperty *parent); + void propertyDestroyed(QtProperty *property); +protected: + virtual bool hasValue(const QtProperty *property) const; + virtual QIcon valueIcon(const QtProperty *property) const; + virtual QString valueText(const QtProperty *property) const; + virtual void initializeProperty(QtProperty *property) = 0; + virtual void uninitializeProperty(QtProperty *property); + virtual QtProperty *createProperty(); +private: + friend class QtProperty; + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtAbstractPropertyManager) + Q_DISABLE_COPY_MOVE(QtAbstractPropertyManager) +}; + +class QT_QTPROPERTYBROWSER_EXPORT QtAbstractEditorFactoryBase : public QObject +{ + Q_OBJECT +public: + virtual QWidget *createEditor(QtProperty *property, QWidget *parent) = 0; +protected: + explicit QtAbstractEditorFactoryBase(QObject *parent = 0) + : QObject(parent) {} + + virtual void breakConnection(QtAbstractPropertyManager *manager) = 0; +protected Q_SLOTS: + virtual void managerDestroyed(QObject *manager) = 0; + + friend class QtAbstractPropertyBrowser; +}; + +template +class QtAbstractEditorFactory : public QtAbstractEditorFactoryBase +{ +public: + explicit QtAbstractEditorFactory(QObject *parent) : QtAbstractEditorFactoryBase(parent) {} + QWidget *createEditor(QtProperty *property, QWidget *parent) override + { + for (PropertyManager *manager : qAsConst(m_managers)) { + if (manager == property->propertyManager()) { + return createEditor(manager, property, parent); + } + } + return 0; + } + void addPropertyManager(PropertyManager *manager) + { + if (m_managers.contains(manager)) + return; + m_managers.insert(manager); + connectPropertyManager(manager); + connect(manager, SIGNAL(destroyed(QObject *)), + this, SLOT(managerDestroyed(QObject *))); + } + void removePropertyManager(PropertyManager *manager) + { + if (!m_managers.contains(manager)) + return; + disconnect(manager, SIGNAL(destroyed(QObject *)), + this, SLOT(managerDestroyed(QObject *))); + disconnectPropertyManager(manager); + m_managers.remove(manager); + } + QSet propertyManagers() const + { + return m_managers; + } + PropertyManager *propertyManager(QtProperty *property) const + { + QtAbstractPropertyManager *manager = property->propertyManager(); + for (PropertyManager *m : qAsConst(m_managers)) { + if (m == manager) { + return m; + } + } + return 0; + } +protected: + virtual void connectPropertyManager(PropertyManager *manager) = 0; + virtual QWidget *createEditor(PropertyManager *manager, QtProperty *property, + QWidget *parent) = 0; + virtual void disconnectPropertyManager(PropertyManager *manager) = 0; + void managerDestroyed(QObject *manager) override + { + for (PropertyManager *m : qAsConst(m_managers)) { + if (m == manager) { + m_managers.remove(m); + return; + } + } + } +private: + void breakConnection(QtAbstractPropertyManager *manager) override + { + for (PropertyManager *m : qAsConst(m_managers)) { + if (m == manager) { + removePropertyManager(m); + return; + } + } + } +private: + QSet m_managers; + friend class QtAbstractPropertyEditor; +}; + +class QtAbstractPropertyBrowser; +class QtBrowserItemPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtBrowserItem +{ +public: + QtProperty *property() const; + QtBrowserItem *parent() const; + QList children() const; + QtAbstractPropertyBrowser *browser() const; +private: + explicit QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent); + ~QtBrowserItem(); + QScopedPointer d_ptr; + friend class QtAbstractPropertyBrowserPrivate; +}; + +class QtAbstractPropertyBrowserPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtAbstractPropertyBrowser : public QWidget +{ + Q_OBJECT +public: + + explicit QtAbstractPropertyBrowser(QWidget *parent = 0); + ~QtAbstractPropertyBrowser(); + + QList properties() const; + QList items(QtProperty *property) const; + QtBrowserItem *topLevelItem(QtProperty *property) const; + QList topLevelItems() const; + void clear(); + + template + void setFactoryForManager(PropertyManager *manager, + QtAbstractEditorFactory *factory) { + QtAbstractPropertyManager *abstractManager = manager; + QtAbstractEditorFactoryBase *abstractFactory = factory; + + if (addFactory(abstractManager, abstractFactory)) + factory->addPropertyManager(manager); + } + + void unsetFactoryForManager(QtAbstractPropertyManager *manager); + + QtBrowserItem *currentItem() const; + void setCurrentItem(QtBrowserItem *); + +Q_SIGNALS: + void currentItemChanged(QtBrowserItem *); + +public Q_SLOTS: + + QtBrowserItem *addProperty(QtProperty *property); + QtBrowserItem *insertProperty(QtProperty *property, QtProperty *afterProperty); + void removeProperty(QtProperty *property); + +protected: + + virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) = 0; + virtual void itemRemoved(QtBrowserItem *item) = 0; + // can be tooltip, statustip, whatsthis, name, icon, text. + virtual void itemChanged(QtBrowserItem *item) = 0; + + virtual QWidget *createEditor(QtProperty *property, QWidget *parent); +private: + + bool addFactory(QtAbstractPropertyManager *abstractManager, + QtAbstractEditorFactoryBase *abstractFactory); + + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtAbstractPropertyBrowser) + Q_DISABLE_COPY_MOVE(QtAbstractPropertyBrowser) + Q_PRIVATE_SLOT(d_func(), void slotPropertyInserted(QtProperty *, + QtProperty *, QtProperty *)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyRemoved(QtProperty *, + QtProperty *)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDataChanged(QtProperty *)) + +}; + +QT_END_NAMESPACE + +#endif // QTPROPERTYBROWSER_H diff --git a/external/QtPropertyBrowser/src/qtpropertybrowser.pri b/external/QtPropertyBrowser/src/qtpropertybrowser.pri new file mode 100644 index 000000000..279782787 --- /dev/null +++ b/external/QtPropertyBrowser/src/qtpropertybrowser.pri @@ -0,0 +1,32 @@ +include(../common.pri) +greaterThan(QT_MAJOR_VERSION, 4): QT *= widgets +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +qtpropertybrowser-uselib:!qtpropertybrowser-buildlib { + LIBS += -L$$QTPROPERTYBROWSER_LIBDIR -l$$QTPROPERTYBROWSER_LIBNAME +} else { + DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + SOURCES += $$PWD/qtpropertybrowser.cpp \ + $$PWD/qtpropertymanager.cpp \ + $$PWD/qteditorfactory.cpp \ + $$PWD/qtvariantproperty.cpp \ + $$PWD/qttreepropertybrowser.cpp \ + $$PWD/qtbuttonpropertybrowser.cpp \ + $$PWD/qtgroupboxpropertybrowser.cpp \ + $$PWD/qtpropertybrowserutils.cpp + HEADERS += $$PWD/qtpropertybrowser.h \ + $$PWD/qtpropertymanager.h \ + $$PWD/qteditorfactory.h \ + $$PWD/qtvariantproperty.h \ + $$PWD/qttreepropertybrowser.h \ + $$PWD/qtbuttonpropertybrowser.h \ + $$PWD/qtgroupboxpropertybrowser.h \ + $$PWD/qtpropertybrowserutils_p.h + RESOURCES += $$PWD/qtpropertybrowser.qrc +} + +win32 { + contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTPROPERTYBROWSER_EXPORT + else:qtpropertybrowser-uselib:DEFINES += QT_QTPROPERTYBROWSER_IMPORT +} diff --git a/external/QtPropertyBrowser/src/qtpropertybrowser.qrc b/external/QtPropertyBrowser/src/qtpropertybrowser.qrc new file mode 100644 index 000000000..d680bf40f --- /dev/null +++ b/external/QtPropertyBrowser/src/qtpropertybrowser.qrc @@ -0,0 +1,24 @@ + + + images/button-reset.ico + images/cursor-arrow.png + images/cursor-busy.png + images/cursor-closedhand.png + images/cursor-cross.png + images/cursor-forbidden.png + images/cursor-hand.png + images/cursor-hsplit.png + images/cursor-ibeam.png + images/cursor-openhand.png + images/cursor-sizeall.png + images/cursor-sizeb.png + images/cursor-sizef.png + images/cursor-sizeh.png + images/cursor-sizev.png + images/cursor-uparrow.png + images/cursor-vsplit.png + images/cursor-wait.png + images/cursor-whatsthis.png + + + diff --git a/external/QtPropertyBrowser/src/qtpropertybrowserutils.cpp b/external/QtPropertyBrowser/src/qtpropertybrowserutils.cpp new file mode 100644 index 000000000..38b147caa --- /dev/null +++ b/external/QtPropertyBrowser/src/qtpropertybrowserutils.cpp @@ -0,0 +1,686 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtpropertybrowserutils_p.h" +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QtCursorDatabase::QtCursorDatabase() +{ + appendCursor(Qt::ArrowCursor, QCoreApplication::translate("QtCursorDatabase", "Arrow"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-arrow.png"))); + appendCursor(Qt::UpArrowCursor, QCoreApplication::translate("QtCursorDatabase", "Up Arrow"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-uparrow.png"))); + appendCursor(Qt::CrossCursor, QCoreApplication::translate("QtCursorDatabase", "Cross"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-cross.png"))); + appendCursor(Qt::WaitCursor, QCoreApplication::translate("QtCursorDatabase", "Wait"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-wait.png"))); + appendCursor(Qt::IBeamCursor, QCoreApplication::translate("QtCursorDatabase", "IBeam"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-ibeam.png"))); + appendCursor(Qt::SizeVerCursor, QCoreApplication::translate("QtCursorDatabase", "Size Vertical"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-sizev.png"))); + appendCursor(Qt::SizeHorCursor, QCoreApplication::translate("QtCursorDatabase", "Size Horizontal"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-sizeh.png"))); + appendCursor(Qt::SizeFDiagCursor, QCoreApplication::translate("QtCursorDatabase", "Size Backslash"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-sizef.png"))); + appendCursor(Qt::SizeBDiagCursor, QCoreApplication::translate("QtCursorDatabase", "Size Slash"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-sizeb.png"))); + appendCursor(Qt::SizeAllCursor, QCoreApplication::translate("QtCursorDatabase", "Size All"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-sizeall.png"))); + appendCursor(Qt::BlankCursor, QCoreApplication::translate("QtCursorDatabase", "Blank"), + QIcon()); + appendCursor(Qt::SplitVCursor, QCoreApplication::translate("QtCursorDatabase", "Split Vertical"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-vsplit.png"))); + appendCursor(Qt::SplitHCursor, QCoreApplication::translate("QtCursorDatabase", "Split Horizontal"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-hsplit.png"))); + appendCursor(Qt::PointingHandCursor, QCoreApplication::translate("QtCursorDatabase", "Pointing Hand"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-hand.png"))); + appendCursor(Qt::ForbiddenCursor, QCoreApplication::translate("QtCursorDatabase", "Forbidden"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-forbidden.png"))); + appendCursor(Qt::OpenHandCursor, QCoreApplication::translate("QtCursorDatabase", "Open Hand"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-openhand.png"))); + appendCursor(Qt::ClosedHandCursor, QCoreApplication::translate("QtCursorDatabase", "Closed Hand"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-closedhand.png"))); + appendCursor(Qt::WhatsThisCursor, QCoreApplication::translate("QtCursorDatabase", "What's This"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-whatsthis.png"))); + appendCursor(Qt::BusyCursor, QCoreApplication::translate("QtCursorDatabase", "Busy"), + QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-busy.png"))); +} + +void QtCursorDatabase::clear() +{ + m_cursorNames.clear(); + m_cursorIcons.clear(); + m_valueToCursorShape.clear(); + m_cursorShapeToValue.clear(); +} + +void QtCursorDatabase::appendCursor(Qt::CursorShape shape, const QString& name, const QIcon& icon) +{ + if (m_cursorShapeToValue.contains(shape)) + return; + const int value = m_cursorNames.count(); + m_cursorNames.append(name); + m_cursorIcons.insert(value, icon); + m_valueToCursorShape.insert(value, shape); + m_cursorShapeToValue.insert(shape, value); +} + +QStringList QtCursorDatabase::cursorShapeNames() const +{ + return m_cursorNames; +} + +QMap QtCursorDatabase::cursorShapeIcons() const +{ + return m_cursorIcons; +} + +QString QtCursorDatabase::cursorToShapeName(const QCursor& cursor) const +{ + int val = cursorToValue(cursor); + if (val >= 0) + return m_cursorNames.at(val); + return QString(); +} + +QIcon QtCursorDatabase::cursorToShapeIcon(const QCursor& cursor) const +{ + int val = cursorToValue(cursor); + return m_cursorIcons.value(val); +} + +int QtCursorDatabase::cursorToValue(const QCursor& cursor) const +{ +#ifndef QT_NO_CURSOR + Qt::CursorShape shape = cursor.shape(); + if (m_cursorShapeToValue.contains(shape)) + return m_cursorShapeToValue[shape]; +#endif + return -1; +} + +#ifndef QT_NO_CURSOR +QCursor QtCursorDatabase::valueToCursor(int value) const +{ + if (m_valueToCursorShape.contains(value)) + return QCursor(m_valueToCursorShape[value]); + return QCursor(); +} +#endif + +QPixmap QtPropertyBrowserUtils::brushValuePixmap(const QBrush& b) +{ + QImage img(16, 16, QImage::Format_ARGB32_Premultiplied); + img.fill(0); + + QPainter painter(&img); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.fillRect(0, 0, img.width(), img.height(), b); + QColor color = b.color(); + if (color.alpha() != 255) { // indicate alpha by an inset + QBrush opaqueBrush = b; + color.setAlpha(255); + opaqueBrush.setColor(color); + painter.fillRect(img.width() / 4, img.height() / 4, + img.width() / 2, img.height() / 2, opaqueBrush); + } + painter.end(); + return QPixmap::fromImage(img); +} + +QIcon QtPropertyBrowserUtils::brushValueIcon(const QBrush& b) +{ + return QIcon(brushValuePixmap(b)); +} + +QString QtPropertyBrowserUtils::colorValueText(const QColor& c) +{ + return QCoreApplication::translate("QtPropertyBrowserUtils", "[%1, %2, %3] (%4)") + .arg(c.red()).arg(c.green()).arg(c.blue()).arg(c.alpha()); +} + +QPixmap QtPropertyBrowserUtils::fontValuePixmap(const QFont& font) +{ + QFont f = font; + QImage img(16, 16, QImage::Format_ARGB32_Premultiplied); + img.fill(0); + QPainter p(&img); + p.setRenderHint(QPainter::TextAntialiasing, true); + p.setRenderHint(QPainter::Antialiasing, true); + f.setPointSize(13); + p.setFont(f); + QTextOption t; + t.setAlignment(Qt::AlignCenter); + p.drawText(QRect(0, 0, 16, 16), QString(QLatin1Char('A')), t); + return QPixmap::fromImage(img); +} + +QIcon QtPropertyBrowserUtils::fontValueIcon(const QFont& f) +{ + return QIcon(fontValuePixmap(f)); +} + +QString QtPropertyBrowserUtils::fontValueText(const QFont& f) +{ + return QCoreApplication::translate("QtPropertyBrowserUtils", "[%1, %2]") + .arg(f.family()).arg(f.pointSize()); +} + +QString QtPropertyBrowserUtils::dateFormat() +{ + QLocale loc; + QString format = loc.dateFormat(QLocale::ShortFormat); + // Change dd.MM.yy, MM/dd/yy to 4 digit years + if (format.count(QLatin1Char('y')) == 2) + format.insert(format.indexOf(QLatin1Char('y')), QLatin1String("yy")); + return format; +} + +QString QtPropertyBrowserUtils::timeFormat() +{ + QLocale loc; + // ShortFormat is missing seconds on UNIX. + return loc.timeFormat(QLocale::LongFormat); +} + +QString QtPropertyBrowserUtils::dateTimeFormat() +{ + QString format = dateFormat(); + format += QLatin1Char(' '); + format += timeFormat(); + return format; +} + +#pragma region QtBoolEdit + +QtBoolEdit::QtBoolEdit(QWidget* parent) : + QWidget(parent), + m_checkBox(new QCheckBox(this)), + m_button(new QPushButton(this)), + m_textVisible(true) +{ + m_button->setIcon(QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/button-reset.ico"))); + m_button->setMaximumWidth(15); + + QHBoxLayout* lt = new QHBoxLayout; + if (QApplication::layoutDirection() == Qt::LeftToRight) + lt->setContentsMargins(4, 0, 0, 0); + else + lt->setContentsMargins(0, 0, 4, 0); + lt->setSpacing(1); + lt->addWidget(m_checkBox); + lt->addWidget(m_button); + lt->setStretch(0, 1); + lt->setStretch(1, 0); + setLayout(lt); + connect(m_checkBox, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool))); + connect(m_checkBox, &QCheckBox::toggled, this, [&] { m_button->setEnabled(m_initialChecked != m_checkBox->isChecked()); }); + connect(m_button, &QPushButton::clicked, this, [&] { this->setChecked(m_initialChecked); }); + setFocusProxy(m_checkBox); + m_checkBox->setText(tr("True")); +} + +void QtBoolEdit::setTextVisible(bool textVisible) +{ + if (m_textVisible == textVisible) + return; + + m_textVisible = textVisible; + if (m_textVisible) + m_checkBox->setText(isChecked() ? tr("True") : tr("False")); + else + m_checkBox->setText(QString()); +} + +Qt::CheckState QtBoolEdit::checkState() const +{ + return m_checkBox->checkState(); +} + +void QtBoolEdit::setCheckState(Qt::CheckState state) +{ + m_checkBox->setCheckState(state); +} + +bool QtBoolEdit::isChecked() const +{ + return m_checkBox->isChecked(); +} + +void QtBoolEdit::setChecked(bool c) +{ + m_checkBox->setChecked(c); + if (!m_textVisible) + return; + m_checkBox->setText(isChecked() ? tr("True") : tr("False")); +} + +void QtBoolEdit::setInitialChecked(bool c) +{ + m_initialChecked = c; + m_button->setEnabled(m_initialChecked != m_checkBox->isChecked()); +} + +bool QtBoolEdit::blockCheckBoxSignals(bool block) +{ + return m_checkBox->blockSignals(block); +} + +void QtBoolEdit::mousePressEvent(QMouseEvent* event) +{ + if (event->buttons() == Qt::LeftButton) { + m_checkBox->click(); + event->accept(); + } + else { + QWidget::mousePressEvent(event); + } +} + +#pragma endregion + +#pragma region QtIntEdit + +QtIntEdit::QtIntEdit(QWidget* parent) : + QWidget(parent), + m_spinbox(new QSpinBox(this)), + m_button(new QPushButton(this)) +{ + m_button->setIcon(QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/button-reset.ico"))); + m_button->setMaximumWidth(15); + + QHBoxLayout* lt = new QHBoxLayout; + lt->setContentsMargins(0, 0, 0, 0); + lt->setSpacing(1); + lt->addWidget(m_spinbox); + lt->addWidget(m_button); + lt->setStretch(0, 1); + lt->setStretch(1, 0); + setLayout(lt); + + m_initialvalue = m_spinbox->value(); + connect(m_spinbox, &QSpinBox::valueChanged, this, &QtIntEdit::valueChanged); + connect(m_spinbox, &QSpinBox::valueChanged, this, [&] { m_button->setEnabled(m_initialvalue != m_spinbox->value()); }); + connect(m_button, &QPushButton::clicked, this, [&] { m_spinbox->setValue(m_initialvalue); }); + setFocusProxy(m_spinbox); +} + +int QtIntEdit::value() +{ + return m_spinbox->value(); +} + +void QtIntEdit::setValue(int val) +{ + m_spinbox->setValue(val); +} + +void QtIntEdit::setInitialValue(int val) +{ + m_initialvalue = val; + m_button->setEnabled(val != m_spinbox->value()); +} + +void QtIntEdit::setSingleStep(int step) +{ + m_spinbox->setSingleStep(step); +} + +void QtIntEdit::setRange(int min, int max) +{ + m_spinbox->setRange(min, max); +} + +void QtIntEdit::setKeyboardTracking(bool kt) +{ + m_spinbox->setKeyboardTracking(kt); +} + +#pragma endregion + +#pragma region QtDoubleEdit + +QtDoubleEdit::QtDoubleEdit(QWidget* parent) : + QWidget(parent), + m_doublespinbox(new QDoubleSpinBox(this)), + m_button(new QPushButton(this)) +{ + m_button->setIcon(QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/button-reset.ico"))); + m_button->setMaximumWidth(15); + + QHBoxLayout* lt = new QHBoxLayout; + lt->setContentsMargins(0, 0, 0, 0); + lt->setSpacing(1); + lt->addWidget(m_doublespinbox); + lt->addWidget(m_button); + lt->setStretch(0, 1); + lt->setStretch(1, 0); + setLayout(lt); + + m_initialvalue = m_doublespinbox->value(); + connect(m_doublespinbox, &QDoubleSpinBox::valueChanged, this, &QtDoubleEdit::valueChanged); + connect(m_doublespinbox, &QDoubleSpinBox::valueChanged, this, [&] { + int e10 = pow(10, m_doublespinbox->decimals()); + m_button->setEnabled(int(m_initialvalue + 0.5) * e10 != int(m_doublespinbox->value() + 0.5) * e10); }); + connect(m_button, &QPushButton::clicked, this, [&] { m_doublespinbox->setValue(m_initialvalue); }); + setFocusProxy(m_doublespinbox); +} + +int QtDoubleEdit::value() +{ + return m_doublespinbox->value(); +} + +void QtDoubleEdit::setValue(double val) +{ + m_doublespinbox->setValue(val); +} + +void QtDoubleEdit::setInitialValue(double val) +{ + int e10 = pow(10, m_doublespinbox->decimals()); + m_initialvalue = val; + m_button->setEnabled(int(val + 0.5) * e10 != int(m_doublespinbox->value() + 0.5) * e10); +} + +void QtDoubleEdit::setDecimals(double val) +{ + m_doublespinbox->setDecimals(val); +} + +void QtDoubleEdit::setSingleStep(double step) +{ + m_doublespinbox->setSingleStep(step); +} + +void QtDoubleEdit::setRange(double min, double max) +{ + m_doublespinbox->setRange(min, max); +} + +void QtDoubleEdit::setKeyboardTracking(bool kt) +{ + m_doublespinbox->setKeyboardTracking(kt); +} + +#pragma endregion + +#pragma region QtStringEdit + +QtStringEdit::QtStringEdit(QWidget* parent) : + QWidget(parent), + m_lineedit(new QLineEdit(this)), + m_button(new QPushButton(this)) +{ + m_button->setIcon(QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/button-reset.ico"))); + m_button->setMaximumWidth(15); + + QHBoxLayout* lt = new QHBoxLayout; + lt->setContentsMargins(0, 0, 0, 0); + lt->setSpacing(1); + lt->addWidget(m_lineedit); + lt->addWidget(m_button); + lt->setStretch(0, 1); + lt->setStretch(1, 0); + setLayout(lt); + + m_initialvalue = m_lineedit->text(); + connect(m_lineedit, &QLineEdit::textChanged, this, &QtStringEdit::textChanged); + connect(m_lineedit, &QLineEdit::textEdited, this, &QtStringEdit::textEdited); + connect(m_lineedit, &QLineEdit::textChanged, this, [&] { m_button->setEnabled(m_initialvalue != m_lineedit->text()); }); + connect(m_lineedit, &QLineEdit::textEdited, this, [&] { m_button->setEnabled(m_initialvalue != m_lineedit->text()); }); + connect(m_button, &QPushButton::clicked, this, [&] { m_lineedit->setText(m_initialvalue); }); + setFocusProxy(m_lineedit); +} + +QString QtStringEdit::text() +{ + return m_lineedit->text(); +} + +void QtStringEdit::setText(QString val) +{ + m_lineedit->setText(val); +} + +const QValidator* QtStringEdit::validator() +{ + return m_lineedit->validator(); +} + +void QtStringEdit::setValidator(QValidator* val) +{ + m_lineedit->setValidator(val); +} + +void QtStringEdit::setInitialText(QString val) +{ + m_initialvalue = val; + m_button->setEnabled(val != m_lineedit->text()); +} + +#pragma endregion + +#pragma region QtDateEdit + +QtDateEdit::QtDateEdit(QWidget* parent) : + QWidget(parent), + m_dateedit(new QDateEdit(this)), + m_button(new QPushButton(this)) +{ + m_button->setIcon(QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/button-reset.ico"))); + m_button->setMaximumWidth(15); + + QHBoxLayout* lt = new QHBoxLayout; + lt->setContentsMargins(0, 0, 0, 0); + lt->setSpacing(1); + lt->addWidget(m_dateedit); + lt->addWidget(m_button); + lt->setStretch(0, 1); + lt->setStretch(1, 0); + setLayout(lt); + + m_initialvalue = m_dateedit->date(); + connect(m_dateedit, &QDateEdit::dateChanged, this, &QtDateEdit::dateChanged); + connect(m_dateedit, &QDateEdit::dateChanged, this, [&] { m_button->setEnabled(m_initialvalue != m_dateedit->date()); }); + connect(m_button, &QPushButton::clicked, this, [&] { m_dateedit->setDate(m_initialvalue); }); + setFocusProxy(m_dateedit); +} + +QDate QtDateEdit::date() +{ + return m_dateedit->date(); +} + +void QtDateEdit::setDate(QDate val) +{ + m_dateedit->setDate(val); +} + +void QtDateEdit::setInitialDate(QDate val) +{ + m_initialvalue = val; + m_button->setEnabled(val != m_dateedit->date()); +} + +void QtDateEdit::setDateRange(QDate min, QDate max) +{ + m_dateedit->setDateRange(min, max); +} + +void QtDateEdit::setDisplayFormat(QString format) +{ + m_dateedit->setDisplayFormat(format); +} + +void QtDateEdit::setCalendarPopup(bool popup) +{ + m_dateedit->setCalendarPopup(popup); +} + +#pragma endregion + +#pragma region QtTimeEdit + +QtTimeEdit::QtTimeEdit(QWidget* parent) : + QWidget(parent), + m_timeedit(new QTimeEdit(this)), + m_button(new QPushButton(this)) +{ + m_button->setIcon(QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/button-reset.ico"))); + m_button->setMaximumWidth(15); + + QHBoxLayout* lt = new QHBoxLayout; + lt->setContentsMargins(0, 0, 0, 0); + lt->setSpacing(1); + lt->addWidget(m_timeedit); + lt->addWidget(m_button); + lt->setStretch(0, 1); + lt->setStretch(1, 0); + setLayout(lt); + + m_initialvalue = m_timeedit->time(); + connect(m_timeedit, &QTimeEdit::timeChanged, this, &QtTimeEdit::timeChanged); + connect(m_timeedit, &QTimeEdit::timeChanged, this, [&] { m_button->setEnabled(m_initialvalue != m_timeedit->time()); }); + connect(m_button, &QPushButton::clicked, this, [&] { m_timeedit->setTime(m_initialvalue); }); + setFocusProxy(m_timeedit); +} + +QTime QtTimeEdit::time() +{ + return m_timeedit->time(); +} + +void QtTimeEdit::setTime(QTime val) +{ + m_timeedit->setTime(val); +} + +void QtTimeEdit::setInitialTime(QTime val) +{ + m_initialvalue = val; + m_button->setEnabled(val != m_timeedit->time()); +} + +void QtTimeEdit::setTimeRange(QTime min, QTime max) +{ + m_timeedit->setTimeRange(min, max); +} + +void QtTimeEdit::setDisplayFormat(QString format) +{ + m_timeedit->setDisplayFormat(format); +} + +void QtTimeEdit::setCalendarPopup(bool popup) +{ + m_timeedit->setCalendarPopup(popup); +} + +#pragma endregion + +#pragma region QtDateTimeEdit + +QtDateTimeEdit::QtDateTimeEdit(QWidget* parent) : + QWidget(parent), + m_timeedit(new QDateTimeEdit(this)), + m_button(new QPushButton(this)) +{ + m_button->setIcon(QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/button-reset.ico"))); + m_button->setMaximumWidth(15); + + QHBoxLayout* lt = new QHBoxLayout; + lt->setContentsMargins(0, 0, 0, 0); + lt->setSpacing(1); + lt->addWidget(m_timeedit); + lt->addWidget(m_button); + lt->setStretch(0, 1); + lt->setStretch(1, 0); + setLayout(lt); + + m_initialvalue = m_timeedit->dateTime(); + connect(m_timeedit, &QTimeEdit::dateTimeChanged, this, &QtDateTimeEdit::dateTimeChanged); + connect(m_timeedit, &QTimeEdit::dateTimeChanged, this, [&] { m_button->setEnabled(m_initialvalue != m_timeedit->dateTime()); }); + connect(m_button, &QPushButton::clicked, this, [&] { m_timeedit->setDateTime(m_initialvalue); }); + setFocusProxy(m_timeedit); +} + +QDateTime QtDateTimeEdit::dateTime() +{ + return m_timeedit->dateTime(); +} + +void QtDateTimeEdit::setDateTime(const QDateTime& val) +{ + m_timeedit->setDateTime(val); +} + +void QtDateTimeEdit::setInitialDateTime(const QDateTime& val) +{ + m_initialvalue = val; + m_button->setEnabled(val != m_timeedit->dateTime()); +} + +void QtDateTimeEdit::setDateTimeRange(const QDateTime& min, const QDateTime& max) +{ + m_timeedit->setDateTimeRange(min, max); +} + +void QtDateTimeEdit::setDisplayFormat(const QString& format) +{ + m_timeedit->setDisplayFormat(format); +} + +void QtDateTimeEdit::setCalendarPopup(bool popup) +{ + m_timeedit->setCalendarPopup(popup); +} + +#pragma endregion + +QT_END_NAMESPACE diff --git a/external/QtPropertyBrowser/src/qtpropertybrowserutils_p.h b/external/QtPropertyBrowser/src/qtpropertybrowserutils_p.h new file mode 100644 index 000000000..37e16d8b3 --- /dev/null +++ b/external/QtPropertyBrowser/src/qtpropertybrowserutils_p.h @@ -0,0 +1,292 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of Qt Designer. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#ifndef QTPROPERTYBROWSERUTILS_H +#define QTPROPERTYBROWSERUTILS_H + +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QMouseEvent; +class QCheckBox; +class QLineEdit; + +class QtCursorDatabase +{ +public: + QtCursorDatabase(); + void clear(); + + QStringList cursorShapeNames() const; + QMap cursorShapeIcons() const; + QString cursorToShapeName(const QCursor& cursor) const; + QIcon cursorToShapeIcon(const QCursor& cursor) const; + int cursorToValue(const QCursor& cursor) const; +#ifndef QT_NO_CURSOR + QCursor valueToCursor(int value) const; +#endif +private: + void appendCursor(Qt::CursorShape shape, const QString& name, const QIcon& icon); + QStringList m_cursorNames; + QMap m_cursorIcons; + QMap m_valueToCursorShape; + QMap m_cursorShapeToValue; +}; + +class QtPropertyBrowserUtils +{ +public: + static QPixmap brushValuePixmap(const QBrush& b); + static QIcon brushValueIcon(const QBrush& b); + static QString colorValueText(const QColor& c); + static QPixmap fontValuePixmap(const QFont& f); + static QIcon fontValueIcon(const QFont& f); + static QString fontValueText(const QFont& f); + static QString dateFormat(); + static QString timeFormat(); + static QString dateTimeFormat(); +}; + +#pragma region QtBoolEdit + +class QtBoolEdit : public QWidget { + Q_OBJECT +public: + QtBoolEdit(QWidget* parent = 0); + + bool textVisible() const { return m_textVisible; } + void setTextVisible(bool textVisible); + + Qt::CheckState checkState() const; + void setCheckState(Qt::CheckState state); + + bool isChecked() const; + void setChecked(bool c); + void setInitialChecked(bool c); + + bool blockCheckBoxSignals(bool block); + +Q_SIGNALS: + void toggled(bool); + +protected: + void mousePressEvent(QMouseEvent* event) override; + +private: + QCheckBox* m_checkBox; + QPushButton* m_button; + bool m_textVisible; + bool m_initialChecked; +}; +#pragma endregion + +#pragma region QtIntEdit + +class QtIntEdit : public QWidget { + Q_OBJECT +public: + QtIntEdit(QWidget* parent = Q_NULLPTR); + + int value(); + void setValue(int); + void setInitialValue(int); + void setSingleStep(int); + void setRange(int, int); + void setKeyboardTracking(bool); + +Q_SIGNALS: + void valueChanged(int); + +private: + QSpinBox* m_spinbox; + QPushButton* m_button; + int m_initialvalue; +}; + +#pragma endregion + +#pragma region QtDoubleEdit + +class QtDoubleEdit : public QWidget { + Q_OBJECT +public: + QtDoubleEdit(QWidget* parent = Q_NULLPTR); + + int value(); + void setValue(double); + void setInitialValue(double); + void setDecimals(double); + void setSingleStep(double); + void setRange(double, double); + void setKeyboardTracking(bool); + +Q_SIGNALS: + void valueChanged(double); + +private: + QDoubleSpinBox* m_doublespinbox; + QPushButton* m_button; + double m_initialvalue; +}; + +#pragma endregion + +#pragma region QtStringEdit + +class QtStringEdit : public QWidget { + Q_OBJECT +public: + QtStringEdit(QWidget* parent = Q_NULLPTR); + + QString text(); + void setText(QString); + void setInitialText(QString); + const QValidator* validator(); + void setValidator(QValidator*); + +Q_SIGNALS: + void textChanged(QString); + void textEdited(QString); + +private: + QLineEdit* m_lineedit; + QPushButton* m_button; + QString m_initialvalue; +}; + +#pragma endregion + +#pragma region QtDateEdit + +class QtDateEdit : public QWidget { + Q_OBJECT +public: + QtDateEdit(QWidget* parent = Q_NULLPTR); + + QDate date(); + void setDate(QDate); + void setInitialDate(QDate); + void setDateRange(QDate, QDate); + void setDisplayFormat(QString); + void setCalendarPopup(bool); + +Q_SIGNALS: + void dateChanged(QDate); + +private: + QDateEdit* m_dateedit; + QPushButton* m_button; + QDate m_initialvalue; +}; + +#pragma endregion + +#pragma region QtTimeEdit + +class QtTimeEdit : public QWidget { + Q_OBJECT +public: + QtTimeEdit(QWidget* parent = Q_NULLPTR); + + QTime time(); + void setTime(QTime); + void setInitialTime(QTime); + void setTimeRange(QTime, QTime); + void setDisplayFormat(QString); + void setCalendarPopup(bool); + +Q_SIGNALS: + void timeChanged(QTime); + +private: + QTimeEdit* m_timeedit; + QPushButton* m_button; + QTime m_initialvalue; +}; + +#pragma endregion + +#pragma region QDateTimeEdit + +class QtDateTimeEdit : public QWidget { + Q_OBJECT +public: + QtDateTimeEdit(QWidget* parent = Q_NULLPTR); + + QDateTime dateTime(); + void setDateTime(const QDateTime&); + void setInitialDateTime(const QDateTime&); + void setDateTimeRange(const QDateTime&, const QDateTime&); + void setDisplayFormat(const QString&); + void setCalendarPopup(bool); + +Q_SIGNALS: + void dateTimeChanged(const QDateTime&); + +private: + QDateTimeEdit* m_timeedit; + QPushButton* m_button; + QDateTime m_initialvalue; +}; + +#pragma endregion + + +QT_END_NAMESPACE + +#endif diff --git a/external/QtPropertyBrowser/src/qtpropertymanager.cpp b/external/QtPropertyBrowser/src/qtpropertymanager.cpp new file mode 100644 index 000000000..0d0c98458 --- /dev/null +++ b/external/QtPropertyBrowser/src/qtpropertymanager.cpp @@ -0,0 +1,6864 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtpropertymanager.h" +#include "qtpropertybrowserutils_p.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if defined(Q_CC_MSVC) +# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ +#endif + +QT_BEGIN_NAMESPACE + +template +static void setSimpleMinimumData(PrivateData* data, const Value& minVal) +{ + data->minVal = minVal; + if (data->maxVal < data->minVal) + data->maxVal = data->minVal; + + if (data->val < data->minVal) + data->val = data->minVal; +} + +template +static void setSimpleMaximumData(PrivateData* data, const Value& maxVal) +{ + data->maxVal = maxVal; + if (data->minVal > data->maxVal) + data->minVal = data->maxVal; + + if (data->val > data->maxVal) + data->val = data->maxVal; +} + +template +static void setSizeMinimumData(PrivateData* data, const Value& newMinVal) +{ + data->minVal = newMinVal; + if (data->maxVal.width() < data->minVal.width()) + data->maxVal.setWidth(data->minVal.width()); + if (data->maxVal.height() < data->minVal.height()) + data->maxVal.setHeight(data->minVal.height()); + + if (data->val.width() < data->minVal.width()) + data->val.setWidth(data->minVal.width()); + if (data->val.height() < data->minVal.height()) + data->val.setHeight(data->minVal.height()); +} + +template +static void setSizeMaximumData(PrivateData* data, const Value& newMaxVal) +{ + data->maxVal = newMaxVal; + if (data->minVal.width() > data->maxVal.width()) + data->minVal.setWidth(data->maxVal.width()); + if (data->minVal.height() > data->maxVal.height()) + data->minVal.setHeight(data->maxVal.height()); + + if (data->val.width() > data->maxVal.width()) + data->val.setWidth(data->maxVal.width()); + if (data->val.height() > data->maxVal.height()) + data->val.setHeight(data->maxVal.height()); +} + +template +static SizeValue qBoundSize(const SizeValue& minVal, const SizeValue& val, const SizeValue& maxVal) +{ + SizeValue croppedVal = val; + if (minVal.width() > val.width()) + croppedVal.setWidth(minVal.width()); + else if (maxVal.width() < val.width()) + croppedVal.setWidth(maxVal.width()); + + if (minVal.height() > val.height()) + croppedVal.setHeight(minVal.height()); + else if (maxVal.height() < val.height()) + croppedVal.setHeight(maxVal.height()); + + return croppedVal; +} + +// Match the exact signature of qBound for VS 6. +QSize qBound(QSize minVal, QSize val, QSize maxVal) +{ + return qBoundSize(minVal, val, maxVal); +} + +QSizeF qBound(QSizeF minVal, QSizeF val, QSizeF maxVal) +{ + return qBoundSize(minVal, val, maxVal); +} + +namespace { + + namespace { + template + void orderBorders(Value& minVal, Value& maxVal) + { + if (minVal > maxVal) + qSwap(minVal, maxVal); + } + + template + static void orderSizeBorders(Value& minVal, Value& maxVal) + { + Value fromSize = minVal; + Value toSize = maxVal; + if (fromSize.width() > toSize.width()) { + fromSize.setWidth(maxVal.width()); + toSize.setWidth(minVal.width()); + } + if (fromSize.height() > toSize.height()) { + fromSize.setHeight(maxVal.height()); + toSize.setHeight(minVal.height()); + } + minVal = fromSize; + maxVal = toSize; + } + + void orderBorders(QSize& minVal, QSize& maxVal) + { + orderSizeBorders(minVal, maxVal); + } + + void orderBorders(QSizeF& minVal, QSizeF& maxVal) + { + orderSizeBorders(minVal, maxVal); + } + + } +} +//////// + +template +static Value getData(const QMap& propertyMap, + Value PrivateData::* data, + const QtProperty* property, const Value& defaultValue = Value()) +{ + const auto it = propertyMap.constFind(property); + if (it == propertyMap.constEnd()) + return defaultValue; + return it.value().*data; +} + +template +static Value getValue(const QMap& propertyMap, + const QtProperty* property, const Value& defaultValue = Value()) +{ + return getData(propertyMap, &PrivateData::val, property, defaultValue); +} + +template +static Value getMinimum(const QMap& propertyMap, + const QtProperty* property, const Value& defaultValue = Value()) +{ + return getData(propertyMap, &PrivateData::minVal, property, defaultValue); +} + +template +static Value getMaximum(const QMap& propertyMap, + const QtProperty* property, const Value& defaultValue = Value()) +{ + return getData(propertyMap, &PrivateData::maxVal, property, defaultValue); +} + +template +static void setSimpleValue(QMap& propertyMap, + PropertyManager* manager, + void (PropertyManager::* propertyChangedSignal)(QtProperty*), + void (PropertyManager::* valueChangedSignal)(QtProperty*, ValueChangeParameter), + QtProperty* property, const Value& val) +{ + const auto it = propertyMap.find(property); + if (it == propertyMap.end()) + return; + + if (it.value() == val) + return; + + it.value() = val; + + emit(manager->*propertyChangedSignal)(property); + emit(manager->*valueChangedSignal)(property, val); +} + +template +static void setSimpleValue(PropertyManager* manager, PropertyManagerPrivate* managerPrivate, + void (PropertyManager::* propertyChangedSignal)(QtProperty*), + void (PropertyManager::* valueChangedSignal)(QtProperty*, ValueChangeParameter), + QtProperty* property, const Value& val, + void (PropertyManagerPrivate::* setSubPropertyValue)(QtProperty*, ValueChangeParameter)) +{ + const auto it = managerPrivate->m_values.find(property); + if (it == managerPrivate->m_values.end()) + return; + + auto& data = it.value(); + + if (data.val == val) + return; + + data.val = val; + + if (setSubPropertyValue) + (managerPrivate->*setSubPropertyValue)(property, data.val); + + emit(manager->*propertyChangedSignal)(property); + emit(manager->*valueChangedSignal)(property, data.val); +} + +template +static void setValueInRange(PropertyManager* manager, PropertyManagerPrivate* managerPrivate, + void (PropertyManager::* propertyChangedSignal)(QtProperty*), + void (PropertyManager::* valueChangedSignal)(QtProperty*, ValueChangeParameter), + QtProperty* property, const Value& val, + void (PropertyManagerPrivate::* setSubPropertyValue)(QtProperty*, ValueChangeParameter)) +{ + const auto it = managerPrivate->m_values.find(property); + if (it == managerPrivate->m_values.end()) + return; + + auto& data = it.value(); + + if (data.val == val) + return; + + const Value oldVal = data.val; + + data.val = qBound(data.minVal, val, data.maxVal); + + if (data.val == oldVal) + return; + + if (setSubPropertyValue) + (managerPrivate->*setSubPropertyValue)(property, data.val); + + emit(manager->*propertyChangedSignal)(property); + emit(manager->*valueChangedSignal)(property, data.val); +} + +template +static void setBorderValues(PropertyManager* manager, PropertyManagerPrivate* managerPrivate, + void (PropertyManager::* propertyChangedSignal)(QtProperty*), + void (PropertyManager::* valueChangedSignal)(QtProperty*, ValueChangeParameter), + void (PropertyManager::* rangeChangedSignal)(QtProperty*, ValueChangeParameter, ValueChangeParameter), + QtProperty* property, ValueChangeParameter minVal, ValueChangeParameter maxVal, + void (PropertyManagerPrivate::* setSubPropertyRange)(QtProperty*, + ValueChangeParameter, ValueChangeParameter, ValueChangeParameter)) +{ + const auto it = managerPrivate->m_values.find(property); + if (it == managerPrivate->m_values.end()) + return; + + Value fromVal = minVal; + Value toVal = maxVal; + orderBorders(fromVal, toVal); + + auto& data = it.value(); + + if (data.minVal == fromVal && data.maxVal == toVal) + return; + + const Value oldVal = data.val; + + data.setMinimumValue(fromVal); + data.setMaximumValue(toVal); + + emit(manager->*rangeChangedSignal)(property, data.minVal, data.maxVal); + + if (setSubPropertyRange) + (managerPrivate->*setSubPropertyRange)(property, data.minVal, data.maxVal, data.val); + + if (data.val == oldVal) + return; + + emit(manager->*propertyChangedSignal)(property); + emit(manager->*valueChangedSignal)(property, data.val); +} + +template +static void setBorderValue(PropertyManager* manager, PropertyManagerPrivate* managerPrivate, + void (PropertyManager::* propertyChangedSignal)(QtProperty*), + void (PropertyManager::* valueChangedSignal)(QtProperty*, ValueChangeParameter), + void (PropertyManager::* rangeChangedSignal)(QtProperty*, ValueChangeParameter, ValueChangeParameter), + QtProperty* property, + Value(PrivateData::* getRangeVal)() const, + void (PrivateData::* setRangeVal)(ValueChangeParameter), const Value& borderVal, + void (PropertyManagerPrivate::* setSubPropertyRange)(QtProperty*, + ValueChangeParameter, ValueChangeParameter, ValueChangeParameter)) +{ + const auto it = managerPrivate->m_values.find(property); + if (it == managerPrivate->m_values.end()) + return; + + PrivateData& data = it.value(); + + if ((data.*getRangeVal)() == borderVal) + return; + + const Value oldVal = data.val; + + (data.*setRangeVal)(borderVal); + + emit(manager->*rangeChangedSignal)(property, data.minVal, data.maxVal); + + if (setSubPropertyRange) + (managerPrivate->*setSubPropertyRange)(property, data.minVal, data.maxVal, data.val); + + if (data.val == oldVal) + return; + + emit(manager->*propertyChangedSignal)(property); + emit(manager->*valueChangedSignal)(property, data.val); +} + +template +static void setMinimumValue(PropertyManager* manager, PropertyManagerPrivate* managerPrivate, + void (PropertyManager::* propertyChangedSignal)(QtProperty*), + void (PropertyManager::* valueChangedSignal)(QtProperty*, ValueChangeParameter), + void (PropertyManager::* rangeChangedSignal)(QtProperty*, ValueChangeParameter, ValueChangeParameter), + QtProperty* property, const Value& minVal) +{ + void (PropertyManagerPrivate:: * setSubPropertyRange)(QtProperty*, + ValueChangeParameter, ValueChangeParameter, ValueChangeParameter) = 0; + setBorderValue(manager, managerPrivate, + propertyChangedSignal, valueChangedSignal, rangeChangedSignal, + property, &PropertyManagerPrivate::Data::minimumValue, &PropertyManagerPrivate::Data::setMinimumValue, minVal, setSubPropertyRange); +} + +template +static void setMaximumValue(PropertyManager* manager, PropertyManagerPrivate* managerPrivate, + void (PropertyManager::* propertyChangedSignal)(QtProperty*), + void (PropertyManager::* valueChangedSignal)(QtProperty*, ValueChangeParameter), + void (PropertyManager::* rangeChangedSignal)(QtProperty*, ValueChangeParameter, ValueChangeParameter), + QtProperty* property, const Value& maxVal) +{ + void (PropertyManagerPrivate:: * setSubPropertyRange)(QtProperty*, + ValueChangeParameter, ValueChangeParameter, ValueChangeParameter) = 0; + setBorderValue(manager, managerPrivate, + propertyChangedSignal, valueChangedSignal, rangeChangedSignal, + property, &PropertyManagerPrivate::Data::maximumValue, &PropertyManagerPrivate::Data::setMaximumValue, maxVal, setSubPropertyRange); +} + +class QtMetaEnumWrapper : public QObject +{ + Q_OBJECT + Q_PROPERTY(QSizePolicy::Policy policy READ policy) +public: + QSizePolicy::Policy policy() const { return QSizePolicy::Ignored; } +private: + QtMetaEnumWrapper(QObject* parent) : QObject(parent) {} +}; + +class QtMetaEnumProvider +{ +public: + QtMetaEnumProvider(); + + QStringList policyEnumNames() const { return m_policyEnumNames; } + QStringList languageEnumNames() const { return m_languageEnumNames; } + QStringList countryEnumNames(QLocale::Language language) const { return m_countryEnumNames.value(language); } + + QSizePolicy::Policy indexToSizePolicy(int index) const; + int sizePolicyToIndex(QSizePolicy::Policy policy) const; + + void indexToLocale(int languageIndex, int countryIndex, QLocale::Language* language, QLocale::Country* country) const; + void localeToIndex(QLocale::Language language, QLocale::Country country, int* languageIndex, int* countryIndex) const; + +private: + void initLocale(); + + QStringList m_policyEnumNames; + QStringList m_languageEnumNames; + QMap m_countryEnumNames; + QMap m_indexToLanguage; + QMap m_languageToIndex; + QMap > m_indexToCountry; + QMap > m_countryToIndex; + QMetaEnum m_policyEnum; +}; + +static QList sortCountries(const QList& countries) +{ + QMultiMap nameToCountry; + for (QLocale::Country country : countries) + nameToCountry.insert(QLocale::countryToString(country), country); + return nameToCountry.values(); +} + +void QtMetaEnumProvider::initLocale() +{ + QMultiMap nameToLanguage; + for (int l = QLocale::C, last = QLocale::LastLanguage; l <= last; ++l) { + const QLocale::Language language = static_cast(l); + QLocale locale(language); + if (locale.language() == language) + nameToLanguage.insert(QLocale::languageToString(language), language); + } + + const QLocale system = QLocale::system(); + if (!nameToLanguage.contains(QLocale::languageToString(system.language()))) + nameToLanguage.insert(QLocale::languageToString(system.language()), system.language()); + + const auto languages = nameToLanguage.values(); + for (QLocale::Language language : languages) { + QList countries; + countries = QLocale::countriesForLanguage(language); + if (countries.isEmpty() && language == system.language()) + countries << system.country(); + + if (!countries.isEmpty() && !m_languageToIndex.contains(language)) { + countries = sortCountries(countries); + int langIdx = m_languageEnumNames.count(); + m_indexToLanguage[langIdx] = language; + m_languageToIndex[language] = langIdx; + QStringList countryNames; + int countryIdx = 0; + for (QLocale::Country country : qAsConst(countries)) { + countryNames << QLocale::countryToString(country); + m_indexToCountry[langIdx][countryIdx] = country; + m_countryToIndex[language][country] = countryIdx; + ++countryIdx; + } + m_languageEnumNames << QLocale::languageToString(language); + m_countryEnumNames[language] = countryNames; + } + } +} + +QtMetaEnumProvider::QtMetaEnumProvider() +{ + QMetaProperty p; + + p = QtMetaEnumWrapper::staticMetaObject.property( + QtMetaEnumWrapper::staticMetaObject.propertyOffset() + 0); + m_policyEnum = p.enumerator(); + const int keyCount = m_policyEnum.keyCount(); + for (int i = 0; i < keyCount; i++) + m_policyEnumNames << QLatin1String(m_policyEnum.key(i)); + + initLocale(); +} + +QSizePolicy::Policy QtMetaEnumProvider::indexToSizePolicy(int index) const +{ + return static_cast(m_policyEnum.value(index)); +} + +int QtMetaEnumProvider::sizePolicyToIndex(QSizePolicy::Policy policy) const +{ + const int keyCount = m_policyEnum.keyCount(); + for (int i = 0; i < keyCount; i++) + if (indexToSizePolicy(i) == policy) + return i; + return -1; +} + +void QtMetaEnumProvider::indexToLocale(int languageIndex, int countryIndex, QLocale::Language* language, QLocale::Country* country) const +{ + QLocale::Language l = QLocale::C; + QLocale::Country c = QLocale::AnyCountry; + if (m_indexToLanguage.contains(languageIndex)) { + l = m_indexToLanguage[languageIndex]; + if (m_indexToCountry.contains(languageIndex) && m_indexToCountry[languageIndex].contains(countryIndex)) + c = m_indexToCountry[languageIndex][countryIndex]; + } + if (language) + *language = l; + if (country) + *country = c; +} + +void QtMetaEnumProvider::localeToIndex(QLocale::Language language, QLocale::Country country, int* languageIndex, int* countryIndex) const +{ + int l = -1; + int c = -1; + if (m_languageToIndex.contains(language)) { + l = m_languageToIndex[language]; + if (m_countryToIndex.contains(language) && m_countryToIndex[language].contains(country)) + c = m_countryToIndex[language][country]; + } + + if (languageIndex) + *languageIndex = l; + if (countryIndex) + *countryIndex = c; +} + +Q_GLOBAL_STATIC(QtMetaEnumProvider, metaEnumProvider) + +// QtGroupPropertyManager +#pragma region QtGroupPropertyManager + +/*! + \class QtGroupPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtGroupPropertyManager provides and manages group properties. + + This class is intended to provide a grouping element without any value. + + \sa QtAbstractPropertyManager +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtGroupPropertyManager::QtGroupPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent) +{ + +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtGroupPropertyManager::~QtGroupPropertyManager() +{ + +} + +/*! + \reimp +*/ +bool QtGroupPropertyManager::hasValue(const QtProperty* property) const +{ + Q_UNUSED(property); + return false; +} + +/*! + \reimp +*/ +void QtGroupPropertyManager::initializeProperty(QtProperty* property) +{ + Q_UNUSED(property); +} + +/*! + \reimp +*/ +void QtGroupPropertyManager::uninitializeProperty(QtProperty* property) +{ + Q_UNUSED(property); +} + +#pragma endregion + +// QtIntPropertyManager +#pragma region QtIntPropertyManager + +class QtIntPropertyManagerPrivate +{ + QtIntPropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtIntPropertyManager) +public: + + struct Data + { + int val{ 0 }; + int initVal{ 0 }; + int minVal{ -INT_MAX }; + int maxVal{ INT_MAX }; + int singleStep{ 1 }; + bool isInitialed{ false }; + int minimumValue() const { return minVal; } + int maximumValue() const { return maxVal; } + void setMinimumValue(int newMinVal) { setSimpleMinimumData(this, newMinVal); } + void setMaximumValue(int newMaxVal) { setSimpleMaximumData(this, newMaxVal); } + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! + \class QtIntPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtIntPropertyManager provides and manages int properties. + + An int property has a current value, and a range specifying the + valid values. The range is defined by a minimum and a maximum + value. + + The property's value and range can be retrieved using the value(), + minimum() and maximum() functions, and can be set using the + setValue(), setMinimum() and setMaximum() slots. Alternatively, + the range can be defined in one go using the setRange() slot. + + In addition, QtIntPropertyManager provides the valueChanged() signal which + is emitted whenever a property created by this manager changes, + and the rangeChanged() signal which is emitted whenever such a + property changes its range of valid values. + + \sa QtAbstractPropertyManager, QtSpinBoxFactory, QtSliderFactory, QtScrollBarFactory +*/ + +/*! + \fn void QtIntPropertyManager::valueChanged(QtProperty *property, int value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtIntPropertyManager::rangeChanged(QtProperty *property, int minimum, int maximum) + + This signal is emitted whenever a property created by this manager + changes its range of valid values, passing a pointer to the + \a property and the new \a minimum and \a maximum values. + + \sa setRange() +*/ + +/*! + \fn void QtIntPropertyManager::singleStepChanged(QtProperty *property, int step) + + This signal is emitted whenever a property created by this manager + changes its single step property, passing a pointer to the + \a property and the new \a step value + + \sa setSingleStep() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtIntPropertyManager::QtIntPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtIntPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtIntPropertyManager::~QtIntPropertyManager() +{ + clear(); +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns 0. + + \sa setValue() +*/ +int QtIntPropertyManager::value(const QtProperty* property) const +{ + return getValue(d_ptr->m_values, property, 0); +} + +int QtIntPropertyManager::initialValue(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtIntPropertyManagerPrivate::Data::initVal, property, 0); +} + +/*! + Returns the given \a property's minimum value. + + \sa setMinimum(), maximum(), setRange() +*/ +int QtIntPropertyManager::minimum(const QtProperty* property) const +{ + return getMinimum(d_ptr->m_values, property, 0); +} + +/*! + Returns the given \a property's maximum value. + + \sa setMaximum(), minimum(), setRange() +*/ +int QtIntPropertyManager::maximum(const QtProperty* property) const +{ + return getMaximum(d_ptr->m_values, property, 0); +} + +/*! + Returns the given \a property's step value. + + The step is typically used to increment or decrement a property value while pressing an arrow key. + + \sa setSingleStep() +*/ +int QtIntPropertyManager::singleStep(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtIntPropertyManagerPrivate::Data::singleStep, property, 0); +} + +/*! + \reimp +*/ +QString QtIntPropertyManager::valueText(const QtProperty* property) const +{ + const QtIntPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return QString::number(it.value().val); +} + +/*! + \fn void QtIntPropertyManager::setValue(QtProperty *property, int value) + + Sets the value of the given \a property to \a value. + + If the specified \a value is not valid according to the given \a + property's range, the \a value is adjusted to the nearest valid + value within the range. + + \sa value(), setRange(), valueChanged() +*/ +void QtIntPropertyManager::setValue(QtProperty* property, int val) +{ + const QtIntPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtIntPropertyManagerPrivate::Data& data = it.value(); + + if (!data.isInitialed) + { + data.initVal = val; + data.isInitialed = true; + } + + void (QtIntPropertyManagerPrivate:: * setSubPropertyValue)(QtProperty*, int) = 0; + setValueInRange(this, d_ptr.data(), + &QtIntPropertyManager::propertyChanged, + &QtIntPropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +void QtIntPropertyManager::setValueOnly(QtProperty* property, int val) +{ + const QtIntPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtIntPropertyManagerPrivate::Data& data = it.value(); + + if (data.initVal != val) + { + data.initVal = val; + } + + void (QtIntPropertyManagerPrivate:: * setSubPropertyValue)(QtProperty*, int) = 0; + setValueInRange(this, d_ptr.data(), + &QtIntPropertyManager::propertyChanged, + &QtIntPropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +/*! + Sets the minimum value for the given \a property to \a minVal. + + When setting the minimum value, the maximum and current values are + adjusted if necessary (ensuring that the range remains valid and + that the current value is within the range). + + \sa minimum(), setRange(), rangeChanged() +*/ +void QtIntPropertyManager::setMinimum(QtProperty* property, int minVal) +{ + setMinimumValue(this, d_ptr.data(), + &QtIntPropertyManager::propertyChanged, + &QtIntPropertyManager::valueChanged, + &QtIntPropertyManager::rangeChanged, + property, minVal); +} + +/*! + Sets the maximum value for the given \a property to \a maxVal. + + When setting maximum value, the minimum and current values are + adjusted if necessary (ensuring that the range remains valid and + that the current value is within the range). + + \sa maximum(), setRange(), rangeChanged() +*/ +void QtIntPropertyManager::setMaximum(QtProperty* property, int maxVal) +{ + setMaximumValue(this, d_ptr.data(), + &QtIntPropertyManager::propertyChanged, + &QtIntPropertyManager::valueChanged, + &QtIntPropertyManager::rangeChanged, + property, maxVal); +} + +/*! + \fn void QtIntPropertyManager::setRange(QtProperty *property, int minimum, int maximum) + + Sets the range of valid values. + + This is a convenience function defining the range of valid values + in one go; setting the \a minimum and \a maximum values for the + given \a property with a single function call. + + When setting a new range, the current value is adjusted if + necessary (ensuring that the value remains within range). + + \sa setMinimum(), setMaximum(), rangeChanged() +*/ +void QtIntPropertyManager::setRange(QtProperty* property, int minVal, int maxVal) +{ + void (QtIntPropertyManagerPrivate:: * setSubPropertyRange)(QtProperty*, int, int, int) = 0; + setBorderValues(this, d_ptr.data(), + &QtIntPropertyManager::propertyChanged, + &QtIntPropertyManager::valueChanged, + &QtIntPropertyManager::rangeChanged, + property, minVal, maxVal, setSubPropertyRange); +} + +/*! + Sets the step value for the given \a property to \a step. + + The step is typically used to increment or decrement a property value while pressing an arrow key. + + \sa singleStep() +*/ +void QtIntPropertyManager::setSingleStep(QtProperty* property, int step) +{ + const QtIntPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtIntPropertyManagerPrivate::Data data = it.value(); + + if (step < 0) + step = 0; + + if (data.singleStep == step) + return; + + data.singleStep = step; + + it.value() = data; + + emit singleStepChanged(property, data.singleStep); +} + +/*! + \reimp +*/ +void QtIntPropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QtIntPropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtIntPropertyManager::uninitializeProperty(QtProperty* property) +{ + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtDoublePropertyManager +#pragma region QtDoublePropertyManager + +class QtDoublePropertyManagerPrivate +{ + QtDoublePropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtDoublePropertyManager) +public: + + struct Data + { + double val{ 0 }; + double initVal{ 0 }; + double minVal{ -DBL_MAX }; + double maxVal{ DBL_MAX }; + double singleStep{ 1 }; + int decimals{ 2 }; + bool isInitialed{ false }; + double minimumValue() const { return minVal; } + double maximumValue() const { return maxVal; } + void setMinimumValue(double newMinVal) { setSimpleMinimumData(this, newMinVal); } + void setMaximumValue(double newMaxVal) { setSimpleMaximumData(this, newMaxVal); } + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! + \class QtDoublePropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtDoublePropertyManager provides and manages double properties. + + A double property has a current value, and a range specifying the + valid values. The range is defined by a minimum and a maximum + value. + + The property's value and range can be retrieved using the value(), + minimum() and maximum() functions, and can be set using the + setValue(), setMinimum() and setMaximum() slots. + Alternatively, the range can be defined in one go using the + setRange() slot. + + In addition, QtDoublePropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the rangeChanged() signal which is emitted whenever + such a property changes its range of valid values. + + \sa QtAbstractPropertyManager, QtDoubleSpinBoxFactory +*/ + +/*! + \fn void QtDoublePropertyManager::valueChanged(QtProperty *property, double value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtDoublePropertyManager::rangeChanged(QtProperty *property, double minimum, double maximum) + + This signal is emitted whenever a property created by this manager + changes its range of valid values, passing a pointer to the + \a property and the new \a minimum and \a maximum values + + \sa setRange() +*/ + +/*! + \fn void QtDoublePropertyManager::decimalsChanged(QtProperty *property, int prec) + + This signal is emitted whenever a property created by this manager + changes its precision of value, passing a pointer to the + \a property and the new \a prec value + + \sa setDecimals() +*/ + +/*! + \fn void QtDoublePropertyManager::singleStepChanged(QtProperty *property, double step) + + This signal is emitted whenever a property created by this manager + changes its single step property, passing a pointer to the + \a property and the new \a step value + + \sa setSingleStep() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtDoublePropertyManager::QtDoublePropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtDoublePropertyManagerPrivate) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtDoublePropertyManager::~QtDoublePropertyManager() +{ + clear(); +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns 0. + + \sa setValue() +*/ +double QtDoublePropertyManager::value(const QtProperty* property) const +{ + return getValue(d_ptr->m_values, property, 0.0); +} + +double QtDoublePropertyManager::initialValue(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtDoublePropertyManagerPrivate::Data::initVal, property, 0); +} + +/*! + Returns the given \a property's minimum value. + + \sa maximum(), setRange() +*/ +double QtDoublePropertyManager::minimum(const QtProperty* property) const +{ + return getMinimum(d_ptr->m_values, property, 0.0); +} + +/*! + Returns the given \a property's maximum value. + + \sa minimum(), setRange() +*/ +double QtDoublePropertyManager::maximum(const QtProperty* property) const +{ + return getMaximum(d_ptr->m_values, property, 0.0); +} + +/*! + Returns the given \a property's step value. + + The step is typically used to increment or decrement a property value while pressing an arrow key. + + \sa setSingleStep() +*/ +double QtDoublePropertyManager::singleStep(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtDoublePropertyManagerPrivate::Data::singleStep, property, 0); +} + +/*! + Returns the given \a property's precision, in decimals. + + \sa setDecimals() +*/ +int QtDoublePropertyManager::decimals(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtDoublePropertyManagerPrivate::Data::decimals, property, 0); +} + +/*! + \reimp +*/ +QString QtDoublePropertyManager::valueText(const QtProperty* property) const +{ + const QtDoublePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return QString::number(it.value().val, 'f', it.value().decimals); +} + +/*! + \fn void QtDoublePropertyManager::setValue(QtProperty *property, double value) + + Sets the value of the given \a property to \a value. + + If the specified \a value is not valid according to the given + \a property's range, the \a value is adjusted to the nearest valid value + within the range. + + \sa value(), setRange(), valueChanged() +*/ +void QtDoublePropertyManager::setValue(QtProperty* property, double val) +{ + const QtDoublePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtDoublePropertyManagerPrivate::Data& data = it.value(); + + if (!data.isInitialed) + { + data.initVal = val; + data.isInitialed = true; + } + + void (QtDoublePropertyManagerPrivate:: * setSubPropertyValue)(QtProperty*, double) = 0; + setValueInRange(this, d_ptr.data(), + &QtDoublePropertyManager::propertyChanged, + &QtDoublePropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +void QtDoublePropertyManager::setValueOnly(QtProperty* property, double val) +{ + const QtDoublePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtDoublePropertyManagerPrivate::Data& data = it.value(); + + if (data.initVal != val) + { + data.initVal = val; + } + + void (QtDoublePropertyManagerPrivate:: * setSubPropertyValue)(QtProperty*, double) = 0; + setValueInRange(this, d_ptr.data(), + &QtDoublePropertyManager::propertyChanged, + &QtDoublePropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +/*! + Sets the step value for the given \a property to \a step. + + The step is typically used to increment or decrement a property value while pressing an arrow key. + + \sa singleStep() +*/ +void QtDoublePropertyManager::setSingleStep(QtProperty* property, double step) +{ + const QtDoublePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtDoublePropertyManagerPrivate::Data data = it.value(); + + if (step < 0) + step = 0; + + if (data.singleStep == step) + return; + + data.singleStep = step; + + it.value() = data; + + emit singleStepChanged(property, data.singleStep); +} + +/*! + \fn void QtDoublePropertyManager::setDecimals(QtProperty *property, int prec) + + Sets the precision of the given \a property to \a prec. + + The valid decimal range is 0-13. The default is 2. + + \sa decimals() +*/ +void QtDoublePropertyManager::setDecimals(QtProperty* property, int prec) +{ + const QtDoublePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtDoublePropertyManagerPrivate::Data data = it.value(); + + if (prec > 13) + prec = 13; + else if (prec < 0) + prec = 0; + + if (data.decimals == prec) + return; + + data.decimals = prec; + + it.value() = data; + + emit decimalsChanged(property, data.decimals); +} + +/*! + Sets the minimum value for the given \a property to \a minVal. + + When setting the minimum value, the maximum and current values are + adjusted if necessary (ensuring that the range remains valid and + that the current value is within in the range). + + \sa minimum(), setRange(), rangeChanged() +*/ +void QtDoublePropertyManager::setMinimum(QtProperty* property, double minVal) +{ + setMinimumValue(this, d_ptr.data(), + &QtDoublePropertyManager::propertyChanged, + &QtDoublePropertyManager::valueChanged, + &QtDoublePropertyManager::rangeChanged, + property, minVal); +} + +/*! + Sets the maximum value for the given \a property to \a maxVal. + + When setting the maximum value, the minimum and current values are + adjusted if necessary (ensuring that the range remains valid and + that the current value is within in the range). + + \sa maximum(), setRange(), rangeChanged() +*/ +void QtDoublePropertyManager::setMaximum(QtProperty* property, double maxVal) +{ + setMaximumValue(this, d_ptr.data(), + &QtDoublePropertyManager::propertyChanged, + &QtDoublePropertyManager::valueChanged, + &QtDoublePropertyManager::rangeChanged, + property, maxVal); +} + +/*! + \fn void QtDoublePropertyManager::setRange(QtProperty *property, double minimum, double maximum) + + Sets the range of valid values. + + This is a convenience function defining the range of valid values + in one go; setting the \a minimum and \a maximum values for the + given \a property with a single function call. + + When setting a new range, the current value is adjusted if + necessary (ensuring that the value remains within range). + + \sa setMinimum(), setMaximum(), rangeChanged() +*/ +void QtDoublePropertyManager::setRange(QtProperty* property, double minVal, double maxVal) +{ + void (QtDoublePropertyManagerPrivate:: * setSubPropertyRange)(QtProperty*, double, double, double) = 0; + setBorderValues(this, d_ptr.data(), + &QtDoublePropertyManager::propertyChanged, + &QtDoublePropertyManager::valueChanged, + &QtDoublePropertyManager::rangeChanged, + property, minVal, maxVal, setSubPropertyRange); +} + +/*! + \reimp +*/ +void QtDoublePropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QtDoublePropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtDoublePropertyManager::uninitializeProperty(QtProperty* property) +{ + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtStringPropertyManager +#pragma region QtStringPropertyManager + +class QtStringPropertyManagerPrivate +{ + QtStringPropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtStringPropertyManager) +public: + + struct Data + { + QString val; + QString initVal; + bool isInitialed; + QRegularExpression regExp; + }; + + typedef QMap PropertyValueMap; + QMap m_values; +}; + +/*! + \class QtStringPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtStringPropertyManager provides and manages QString properties. + + A string property's value can be retrieved using the value() + function, and set using the setValue() slot. + + The current value can be checked against a regular expression. To + set the regular expression use the setRegExp() slot, use the + regExp() function to retrieve the currently set expression. + + In addition, QtStringPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the regExpChanged() signal which is emitted whenever + such a property changes its currently set regular expression. + + \sa QtAbstractPropertyManager, QtLineEditFactory +*/ + +/*! + \fn void QtStringPropertyManager::valueChanged(QtProperty *property, const QString &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtStringPropertyManager::regExpChanged(QtProperty *property, const QRegularExpression ®Exp) + + This signal is emitted whenever a property created by this manager + changes its currenlty set regular expression, passing a pointer to + the \a property and the new \a regExp as parameters. + + \sa setRegExp() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtStringPropertyManager::QtStringPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtStringPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtStringPropertyManager::~QtStringPropertyManager() +{ + clear(); +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns an empty string. + + \sa setValue() +*/ +QString QtStringPropertyManager::value(const QtProperty* property) const +{ + return getValue(d_ptr->m_values, property); +} + +QString QtStringPropertyManager::initialValue(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtStringPropertyManagerPrivate::Data::initVal, property, QString()); +} + +/*! + Returns the given \a property's currently set regular expression. + + If the given \a property is not managed by this manager, this + function returns an empty expression. + + \sa setRegExp() +*/ +QRegularExpression QtStringPropertyManager::regExp(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtStringPropertyManagerPrivate::Data::regExp, property, QRegularExpression()); +} + +/*! + \reimp +*/ +QString QtStringPropertyManager::valueText(const QtProperty* property) const +{ + const QtStringPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return it.value().val; +} + +/*! + \fn void QtStringPropertyManager::setValue(QtProperty *property, const QString &value) + + Sets the value of the given \a property to \a value. + + If the specified \a value doesn't match the given \a property's + regular expression, this function does nothing. + + \sa value(), setRegExp(), valueChanged() +*/ +void QtStringPropertyManager::setValue(QtProperty* property, const QString& val) +{ + const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtStringPropertyManagerPrivate::Data data = it.value(); + + if (data.val == val) + return; + + if (data.regExp.isValid() && !data.regExp.pattern().isEmpty() + && !data.regExp.match(val).hasMatch()) { + return; + } + + if (!data.isInitialed) + { + data.initVal = val; + data.isInitialed = true; + } + + data.val = val; + + it.value() = data; + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +void QtStringPropertyManager::setValueOnly(QtProperty* property, const QString& val) +{ + const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtStringPropertyManagerPrivate::Data data = it.value(); + + if (data.val == val) + return; + + if (data.regExp.isValid() && !data.regExp.pattern().isEmpty() + && !data.regExp.match(val).hasMatch()) { + return; + } + + data.val = val; + data.initVal = val; + + it.value() = data; + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the regular expression of the given \a property to \a regExp. + + \sa regExp(), setValue(), regExpChanged() +*/ +void QtStringPropertyManager::setRegExp(QtProperty* property, const QRegularExpression& regExp) +{ + const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtStringPropertyManagerPrivate::Data data = it.value(); + + if (data.regExp == regExp) + return; + + data.regExp = regExp; + + it.value() = data; + + emit regExpChanged(property, data.regExp); +} + +/*! + \reimp +*/ +void QtStringPropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QtStringPropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtStringPropertyManager::uninitializeProperty(QtProperty* property) +{ + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtBoolPropertyManager +#pragma region QtBoolPropertyManager + +// Return an icon containing a check box indicator +static QIcon drawCheckBox(bool value) +{ + QStyleOptionButton opt; + opt.state |= value ? QStyle::State_On : QStyle::State_Off; + opt.state |= QStyle::State_Enabled; + const QStyle* style = QApplication::style(); + // Figure out size of an indicator and make sure it is not scaled down in a list view item + // by making the pixmap as big as a list view icon and centering the indicator in it. + // (if it is smaller, it can't be helped) + const int indicatorWidth = style->pixelMetric(QStyle::PM_IndicatorWidth, &opt); + const int indicatorHeight = style->pixelMetric(QStyle::PM_IndicatorHeight, &opt); + const int listViewIconSize = indicatorWidth; + const int pixmapWidth = indicatorWidth; + const int pixmapHeight = qMax(indicatorHeight, listViewIconSize); + + opt.rect = QRect(0, 0, indicatorWidth, indicatorHeight); + QPixmap pixmap = QPixmap(pixmapWidth, pixmapHeight); + pixmap.fill(Qt::transparent); + { + // Center? + const int xoff = (pixmapWidth > indicatorWidth) ? (pixmapWidth - indicatorWidth) / 2 : 0; + const int yoff = (pixmapHeight > indicatorHeight) ? (pixmapHeight - indicatorHeight) / 2 : 0; + QPainter painter(&pixmap); + painter.translate(xoff, yoff); + style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt, &painter); + } + return QIcon(pixmap); +} + +class QtBoolPropertyManagerPrivate +{ + QtBoolPropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtBoolPropertyManager) +public: + QtBoolPropertyManagerPrivate(); + + struct Data + { + bool val; + bool initVal; + bool isInitialed; + }; + + typedef QMap PropertyValueMap; + QMap m_values; + const QIcon m_checkedIcon; + const QIcon m_uncheckedIcon; +}; + +QtBoolPropertyManagerPrivate::QtBoolPropertyManagerPrivate() : + m_checkedIcon(drawCheckBox(true)), + m_uncheckedIcon(drawCheckBox(false)) +{ +} + +/*! + \class QtBoolPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtBoolPropertyManager class provides and manages boolean properties. + + The property's value can be retrieved using the value() function, + and set using the setValue() slot. + + In addition, QtBoolPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager, QtCheckBoxFactory +*/ + +/*! + \fn void QtBoolPropertyManager::valueChanged(QtProperty *property, bool value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtBoolPropertyManager::QtBoolPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtBoolPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtBoolPropertyManager::~QtBoolPropertyManager() +{ + clear(); +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by \e this manager, this + function returns false. + + \sa setValue() +*/ +bool QtBoolPropertyManager::value(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtBoolPropertyManagerPrivate::Data::val, property, false); +} + +bool QtBoolPropertyManager::initialValue(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtBoolPropertyManagerPrivate::Data::initVal, property, false); +} + +/*! + \reimp +*/ +QString QtBoolPropertyManager::valueText(const QtProperty* property) const +{ + const QMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + static const QString trueText = tr("True"); + static const QString falseText = tr("False"); + return it.value().val ? trueText : falseText; +} + +/*! + \reimp +*/ +QIcon QtBoolPropertyManager::valueIcon(const QtProperty* property) const +{ + const QMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QIcon(); + + return it.value().val ? d_ptr->m_checkedIcon : d_ptr->m_uncheckedIcon; +} + +/*! + \fn void QtBoolPropertyManager::setValue(QtProperty *property, bool value) + + Sets the value of the given \a property to \a value. + + \sa value() +*/ +void QtBoolPropertyManager::setValue(QtProperty* property, bool val) +{ + const QtBoolPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtBoolPropertyManagerPrivate::Data& data = it.value(); + + if (!data.isInitialed) + { + data.initVal = val; + data.isInitialed = true; + } + + void (QtBoolPropertyManagerPrivate:: * setSubPropertyValue)(QtProperty*, bool) = 0; + setSimpleValue(this, d_ptr.data(), + &QtBoolPropertyManager::propertyChanged, + &QtBoolPropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +void QtBoolPropertyManager::setValueOnly(QtProperty* property, bool val) +{ + const QtBoolPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtBoolPropertyManagerPrivate::Data& data = it.value(); + + if (data.initVal != val) + { + data.initVal = val; + } + + void (QtBoolPropertyManagerPrivate:: * setSubPropertyValue)(QtProperty*, bool) = 0; + setSimpleValue(this, d_ptr.data(), + &QtBoolPropertyManager::propertyChanged, + &QtBoolPropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +/*! + \reimp +*/ +void QtBoolPropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QtBoolPropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtBoolPropertyManager::uninitializeProperty(QtProperty* property) +{ + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtDatePropertyManager +#pragma region QtDatePropertyManager + +class QtDatePropertyManagerPrivate +{ + QtDatePropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtDatePropertyManager) +public: + explicit QtDatePropertyManagerPrivate(QtDatePropertyManager* q); + + struct Data + { + QDate val{ QDate::currentDate() }; + QDate minVal{ QDate(1752, 9, 14) }; + QDate maxVal{ QDate(9999, 12, 31) }; + QDate initVal{ QDate::currentDate() }; + bool isInitialed; + QDate minimumValue() const { return minVal; } + QDate maximumValue() const { return maxVal; } + void setMinimumValue(QDate newMinVal) { setSimpleMinimumData(this, newMinVal); } + void setMaximumValue(QDate newMaxVal) { setSimpleMaximumData(this, newMaxVal); } + }; + + QString m_format; + + typedef QMap PropertyValueMap; + QMap m_values; +}; + +QtDatePropertyManagerPrivate::QtDatePropertyManagerPrivate(QtDatePropertyManager* q) : + q_ptr(q), + m_format(QtPropertyBrowserUtils::dateFormat()) +{ +} + +/*! + \class QtDatePropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtDatePropertyManager provides and manages QDate properties. + + A date property has a current value, and a range specifying the + valid dates. The range is defined by a minimum and a maximum + value. + + The property's values can be retrieved using the minimum(), + maximum() and value() functions, and can be set using the + setMinimum(), setMaximum() and setValue() slots. Alternatively, + the range can be defined in one go using the setRange() slot. + + In addition, QtDatePropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the rangeChanged() signal which is emitted whenever + such a property changes its range of valid dates. + + \sa QtAbstractPropertyManager, QtDateEditFactory, QtDateTimePropertyManager +*/ + +/*! + \fn void QtDatePropertyManager::valueChanged(QtProperty *property, QDate value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtDatePropertyManager::rangeChanged(QtProperty *property, QDate minimum, QDate maximum) + + This signal is emitted whenever a property created by this manager + changes its range of valid dates, passing a pointer to the \a + property and the new \a minimum and \a maximum dates. + + \sa setRange() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtDatePropertyManager::QtDatePropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtDatePropertyManagerPrivate(this)) +{ +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtDatePropertyManager::~QtDatePropertyManager() +{ + clear(); +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by \e this manager, this + function returns an invalid date. + + \sa setValue() +*/ +QDate QtDatePropertyManager::value(const QtProperty* property) const +{ + return getValue(d_ptr->m_values, property); +} + +QDate QtDatePropertyManager::initialValue(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtDatePropertyManagerPrivate::Data::initVal, property, QDate::currentDate()); +} + +/*! + Returns the given \a property's minimum date. + + \sa maximum(), setRange() +*/ +QDate QtDatePropertyManager::minimum(const QtProperty* property) const +{ + return getMinimum(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's maximum date. + + \sa minimum(), setRange() +*/ +QDate QtDatePropertyManager::maximum(const QtProperty* property) const +{ + return getMaximum(d_ptr->m_values, property); +} + +/*! + \reimp +*/ +QString QtDatePropertyManager::valueText(const QtProperty* property) const +{ + const QtDatePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return it.value().val.toString(d_ptr->m_format); +} + +/*! + \fn void QtDatePropertyManager::setValue(QtProperty *property, QDate value) + + Sets the value of the given \a property to \a value. + + If the specified \a value is not a valid date according to the + given \a property's range, the value is adjusted to the nearest + valid value within the range. + + \sa value(), setRange(), valueChanged() +*/ +void QtDatePropertyManager::setValue(QtProperty* property, QDate val) +{ + const QtDatePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtDatePropertyManagerPrivate::Data& data = it.value(); + + if (!data.isInitialed) + { + data.initVal = val; + data.isInitialed = true; + } + + void (QtDatePropertyManagerPrivate:: * setSubPropertyValue)(QtProperty*, QDate) = 0; + setValueInRange(this, d_ptr.data(), + &QtDatePropertyManager::propertyChanged, + &QtDatePropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +void QtDatePropertyManager::setValueOnly(QtProperty* property, QDate val) +{ + const QtDatePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtDatePropertyManagerPrivate::Data& data = it.value(); + + if (data.initVal != val) + { + data.initVal = val; + } + + void (QtDatePropertyManagerPrivate:: * setSubPropertyValue)(QtProperty*, QDate) = 0; + setValueInRange(this, d_ptr.data(), + &QtDatePropertyManager::propertyChanged, + &QtDatePropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +/*! + Sets the minimum value for the given \a property to \a minVal. + + When setting the minimum value, the maximum and current values are + adjusted if necessary (ensuring that the range remains valid and + that the current value is within in the range). + + \sa minimum(), setRange() +*/ +void QtDatePropertyManager::setMinimum(QtProperty* property, QDate minVal) +{ + setMinimumValue(this, d_ptr.data(), + &QtDatePropertyManager::propertyChanged, + &QtDatePropertyManager::valueChanged, + &QtDatePropertyManager::rangeChanged, + property, minVal); +} + +/*! + Sets the maximum value for the given \a property to \a maxVal. + + When setting the maximum value, the minimum and current + values are adjusted if necessary (ensuring that the range remains + valid and that the current value is within in the range). + + \sa maximum(), setRange() +*/ +void QtDatePropertyManager::setMaximum(QtProperty* property, QDate maxVal) +{ + setMaximumValue(this, d_ptr.data(), + &QtDatePropertyManager::propertyChanged, + &QtDatePropertyManager::valueChanged, + &QtDatePropertyManager::rangeChanged, + property, maxVal); +} + +/*! + \fn void QtDatePropertyManager::setRange(QtProperty *property, QDate minimum, QDate maximum) + + Sets the range of valid dates. + + This is a convenience function defining the range of valid dates + in one go; setting the \a minimum and \a maximum values for the + given \a property with a single function call. + + When setting a new date range, the current value is adjusted if + necessary (ensuring that the value remains in date range). + + \sa setMinimum(), setMaximum(), rangeChanged() +*/ +void QtDatePropertyManager::setRange(QtProperty* property, QDate minVal, QDate maxVal) +{ + void (QtDatePropertyManagerPrivate:: * setSubPropertyRange)(QtProperty*, QDate, QDate, QDate) = 0; + setBorderValues(this, d_ptr.data(), + &QtDatePropertyManager::propertyChanged, + &QtDatePropertyManager::valueChanged, + &QtDatePropertyManager::rangeChanged, + property, minVal, maxVal, setSubPropertyRange); +} + +/*! + \reimp +*/ +void QtDatePropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QtDatePropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtDatePropertyManager::uninitializeProperty(QtProperty* property) +{ + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtTimePropertyManager +#pragma region QtTimePropertyManager + +class QtTimePropertyManagerPrivate +{ + QtTimePropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtTimePropertyManager) +public: + explicit QtTimePropertyManagerPrivate(QtTimePropertyManager* q); + + const QString m_format; + + struct Data + { + QTime val{ QTime() }; + QTime initVal{ QTime() }; + bool isInitialed{ false }; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +QtTimePropertyManagerPrivate::QtTimePropertyManagerPrivate(QtTimePropertyManager* q) : + q_ptr(q), + m_format(QtPropertyBrowserUtils::timeFormat()) +{ +} + +/*! + \class QtTimePropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtTimePropertyManager provides and manages QTime properties. + + A time property's value can be retrieved using the value() + function, and set using the setValue() slot. + + In addition, QtTimePropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager, QtTimeEditFactory +*/ + +/*! + \fn void QtTimePropertyManager::valueChanged(QtProperty *property, QTime value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtTimePropertyManager::QtTimePropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtTimePropertyManagerPrivate(this)) +{ +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtTimePropertyManager::~QtTimePropertyManager() +{ + clear(); +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns an invalid time object. + + \sa setValue() +*/ +QTime QtTimePropertyManager::value(const QtProperty* property) const +{ + return getValue(d_ptr->m_values, property, QTime()); +} + +QTime QtTimePropertyManager::initialValue(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtTimePropertyManagerPrivate::Data::initVal, property, QTime()); +} + +/*! + \reimp +*/ +QString QtTimePropertyManager::valueText(const QtProperty* property) const +{ + const QtTimePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return it.value().val.toString(d_ptr->m_format); +} + +/*! + \fn void QtTimePropertyManager::setValue(QtProperty *property, QTime value) + + Sets the value of the given \a property to \a value. + + \sa value(), valueChanged() +*/ +void QtTimePropertyManager::setValue(QtProperty* property, QTime val) +{ + const QtTimePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtTimePropertyManagerPrivate::Data& data = it.value(); + + if (!data.isInitialed) + { + data.initVal = val; + data.isInitialed = true; + } + + void (QtTimePropertyManagerPrivate:: * setSubPropertyValue)(QtProperty*, QTime) = 0; + setSimpleValue(this, d_ptr.data(), + &QtTimePropertyManager::propertyChanged, + &QtTimePropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +void QtTimePropertyManager::setValueOnly(QtProperty* property, QTime val) +{ + const QtTimePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtTimePropertyManagerPrivate::Data& data = it.value(); + + if (data.initVal != val) + { + data.initVal = val; + } + + void (QtTimePropertyManagerPrivate:: * setSubPropertyValue)(QtProperty*, QTime) = 0; + setSimpleValue(this, d_ptr.data(), + &QtTimePropertyManager::propertyChanged, + &QtTimePropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +/*! + \reimp +*/ +void QtTimePropertyManager::initializeProperty(QtProperty* property) +{ + + d_ptr->m_values[property] = QtTimePropertyManagerPrivate::Data(); + QTime time = QTime::currentTime(); + d_ptr->m_values[property].val = time; + d_ptr->m_values[property].initVal = time; +} + +/*! + \reimp +*/ +void QtTimePropertyManager::uninitializeProperty(QtProperty* property) +{ + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtDateTimePropertyManager +#pragma region QtDateTimePropertyManager + +class QtDateTimePropertyManagerPrivate +{ + QtDateTimePropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtDateTimePropertyManager) +public: + explicit QtDateTimePropertyManagerPrivate(QtDateTimePropertyManager* q); + + const QString m_format; + + struct Data + { + QDateTime val{ QDateTime() }; + QDateTime initVal{ QDateTime() }; + bool isInitialed{ false }; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +QtDateTimePropertyManagerPrivate::QtDateTimePropertyManagerPrivate(QtDateTimePropertyManager* q) : + q_ptr(q), + m_format(QtPropertyBrowserUtils::dateTimeFormat()) +{ +} + +/*! \class QtDateTimePropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtDateTimePropertyManager provides and manages QDateTime properties. + + A date and time property has a current value which can be + retrieved using the value() function, and set using the setValue() + slot. In addition, QtDateTimePropertyManager provides the + valueChanged() signal which is emitted whenever a property created + by this manager changes. + + \sa QtAbstractPropertyManager, QtDateTimeEditFactory, QtDatePropertyManager +*/ + +/*! + \fn void QtDateTimePropertyManager::valueChanged(QtProperty *property, const QDateTime &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtDateTimePropertyManager::QtDateTimePropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtDateTimePropertyManagerPrivate(this)) +{ +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtDateTimePropertyManager::~QtDateTimePropertyManager() +{ + clear(); +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid QDateTime object. + + \sa setValue() +*/ +QDateTime QtDateTimePropertyManager::value(const QtProperty* property) const +{ + return getValue(d_ptr->m_values, property, QDateTime()); +} + +QDateTime QtDateTimePropertyManager::initialValue(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtDateTimePropertyManagerPrivate::Data::initVal, property, QDateTime()); +} + +/*! + \reimp +*/ +QString QtDateTimePropertyManager::valueText(const QtProperty* property) const +{ + const QtDateTimePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return it.value().val.toString(d_ptr->m_format); +} + +/*! + \fn void QtDateTimePropertyManager::setValue(QtProperty *property, const QDateTime &value) + + Sets the value of the given \a property to \a value. + + \sa value(), valueChanged() +*/ +void QtDateTimePropertyManager::setValue(QtProperty* property, const QDateTime& val) +{ + const QtDateTimePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtDateTimePropertyManagerPrivate::Data& data = it.value(); + + if (!data.isInitialed) + { + data.initVal = val; + data.isInitialed = true; + } + + void (QtDateTimePropertyManagerPrivate:: * setSubPropertyValue)(QtProperty*, const QDateTime&) = 0; + setSimpleValue(this, d_ptr.data(), + &QtDateTimePropertyManager::propertyChanged, + &QtDateTimePropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +void QtDateTimePropertyManager::setValueOnly(QtProperty* property, const QDateTime& val) +{ + const QtDateTimePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtDateTimePropertyManagerPrivate::Data& data = it.value(); + + if (data.initVal != val) + { + data.initVal = val; + } + + void (QtDateTimePropertyManagerPrivate:: * setSubPropertyValue)(QtProperty*, const QDateTime&) = 0; + setSimpleValue(this, d_ptr.data(), + &QtDateTimePropertyManager::propertyChanged, + &QtDateTimePropertyManager::valueChanged, + property, val, setSubPropertyValue); +} + +/*! + \reimp +*/ +void QtDateTimePropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QtDateTimePropertyManagerPrivate::Data(); + QDateTime dt = QDateTime::currentDateTime(); + d_ptr->m_values[property].val = dt; + d_ptr->m_values[property].initVal = dt; +} + +/*! + \reimp +*/ +void QtDateTimePropertyManager::uninitializeProperty(QtProperty* property) +{ + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtKeySequencePropertyManager +#pragma region QtKeySequencePropertyManager + +class QtKeySequencePropertyManagerPrivate +{ + QtKeySequencePropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtKeySequencePropertyManager) +public: + + QString m_format; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! \class QtKeySequencePropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtKeySequencePropertyManager provides and manages QKeySequence properties. + + A key sequence's value can be retrieved using the value() + function, and set using the setValue() slot. + + In addition, QtKeySequencePropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager +*/ + +/*! + \fn void QtKeySequencePropertyManager::valueChanged(QtProperty *property, const QKeySequence &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtKeySequencePropertyManager::QtKeySequencePropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtKeySequencePropertyManagerPrivate) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtKeySequencePropertyManager::~QtKeySequencePropertyManager() +{ + clear(); +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an empty QKeySequence object. + + \sa setValue() +*/ +QKeySequence QtKeySequencePropertyManager::value(const QtProperty* property) const +{ + return d_ptr->m_values.value(property, QKeySequence()); +} + +/*! + \reimp +*/ +QString QtKeySequencePropertyManager::valueText(const QtProperty* property) const +{ + const QtKeySequencePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + return it.value().toString(QKeySequence::NativeText); +} + +/*! + \fn void QtKeySequencePropertyManager::setValue(QtProperty *property, const QKeySequence &value) + + Sets the value of the given \a property to \a value. + + \sa value(), valueChanged() +*/ +void QtKeySequencePropertyManager::setValue(QtProperty* property, const QKeySequence& val) +{ + setSimpleValue(d_ptr->m_values, this, + &QtKeySequencePropertyManager::propertyChanged, + &QtKeySequencePropertyManager::valueChanged, + property, val); +} + +/*! + \reimp +*/ +void QtKeySequencePropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QKeySequence(); +} + +/*! + \reimp +*/ +void QtKeySequencePropertyManager::uninitializeProperty(QtProperty* property) +{ + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtCharPropertyManager +#pragma region QtCharPropertyManager + +class QtCharPropertyManagerPrivate +{ + QtCharPropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtCharPropertyManager) +public: + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! \class QtCharPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtCharPropertyManager provides and manages QChar properties. + + A char's value can be retrieved using the value() + function, and set using the setValue() slot. + + In addition, QtCharPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager +*/ + +/*! + \fn void QtCharPropertyManager::valueChanged(QtProperty *property, const QChar &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtCharPropertyManager::QtCharPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtCharPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtCharPropertyManager::~QtCharPropertyManager() +{ + clear(); +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an null QChar object. + + \sa setValue() +*/ +QChar QtCharPropertyManager::value(const QtProperty* property) const +{ + return d_ptr->m_values.value(property, QChar()); +} + +/*! + \reimp +*/ +QString QtCharPropertyManager::valueText(const QtProperty* property) const +{ + const QtCharPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QChar c = it.value(); + return c.isNull() ? QString() : QString(c); +} + +/*! + \fn void QtCharPropertyManager::setValue(QtProperty *property, const QChar &value) + + Sets the value of the given \a property to \a value. + + \sa value(), valueChanged() +*/ +void QtCharPropertyManager::setValue(QtProperty* property, const QChar& val) +{ + setSimpleValue(d_ptr->m_values, this, + &QtCharPropertyManager::propertyChanged, + &QtCharPropertyManager::valueChanged, + property, val); +} + +/*! + \reimp +*/ +void QtCharPropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QChar(); +} + +/*! + \reimp +*/ +void QtCharPropertyManager::uninitializeProperty(QtProperty* property) +{ + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtLocalePropertyManager +#pragma region QtLocalePropertyManager + +class QtLocalePropertyManagerPrivate +{ + QtLocalePropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtLocalePropertyManager) +public: + + QtLocalePropertyManagerPrivate(); + + void slotEnumChanged(QtProperty* property, int value); + void slotPropertyDestroyed(QtProperty* property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtEnumPropertyManager* m_enumPropertyManager; + + QMap m_propertyToLanguage; + QMap m_propertyToCountry; + + QMap m_languageToProperty; + QMap m_countryToProperty; +}; + +QtLocalePropertyManagerPrivate::QtLocalePropertyManagerPrivate() +{ +} + +void QtLocalePropertyManagerPrivate::slotEnumChanged(QtProperty* property, int value) +{ + if (QtProperty* prop = m_languageToProperty.value(property, 0)) { + const QLocale loc = m_values[prop]; + QLocale::Language newLanguage = loc.language(); + QLocale::Country newCountry = loc.country(); + metaEnumProvider()->indexToLocale(value, 0, &newLanguage, 0); + QLocale newLoc(newLanguage, newCountry); + q_ptr->setValue(prop, newLoc); + } + else if (QtProperty* prop = m_countryToProperty.value(property, 0)) { + const QLocale loc = m_values[prop]; + QLocale::Language newLanguage = loc.language(); + QLocale::Country newCountry = loc.country(); + metaEnumProvider()->indexToLocale(m_enumPropertyManager->value(m_propertyToLanguage.value(prop)), value, &newLanguage, &newCountry); + QLocale newLoc(newLanguage, newCountry); + q_ptr->setValue(prop, newLoc); + } +} + +void QtLocalePropertyManagerPrivate::slotPropertyDestroyed(QtProperty* property) +{ + if (QtProperty* subProp = m_languageToProperty.value(property, 0)) { + m_propertyToLanguage[subProp] = 0; + m_languageToProperty.remove(property); + } + else if (QtProperty* subProp = m_countryToProperty.value(property, 0)) { + m_propertyToCountry[subProp] = 0; + m_countryToProperty.remove(property); + } +} + +/*! + \class QtLocalePropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtLocalePropertyManager provides and manages QLocale properties. + + A locale property has nested \e language and \e country + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by QtEnumPropertyManager object. + These submanager can be retrieved using the subEnumPropertyManager() + function. In order to provide editing widgets for the subproperties + in a property browser widget, this manager must be associated with editor factory. + + In addition, QtLocalePropertyManager provides the valueChanged() + signal which is emitted whenever a property created by this + manager changes. + + \sa QtAbstractPropertyManager, QtEnumPropertyManager +*/ + +/*! + \fn void QtLocalePropertyManager::valueChanged(QtProperty *property, const QLocale &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtLocalePropertyManager::QtLocalePropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtLocalePropertyManagerPrivate) +{ + d_ptr->q_ptr = this; + + d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this); + connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotEnumChanged(QtProperty*, int))); + + connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)), + this, SLOT(slotPropertyDestroyed(QtProperty*))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtLocalePropertyManager::~QtLocalePropertyManager() +{ + clear(); +} + +/*! + Returns the manager that creates the nested \e language + and \e country subproperties. + + In order to provide editing widgets for the mentioned subproperties + in a property browser widget, this manager must be associated with + an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtEnumPropertyManager* QtLocalePropertyManager::subEnumPropertyManager() const +{ + return d_ptr->m_enumPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns the default locale. + + \sa setValue() +*/ +QLocale QtLocalePropertyManager::value(const QtProperty* property) const +{ + return d_ptr->m_values.value(property, QLocale()); +} + +/*! + \reimp +*/ +QString QtLocalePropertyManager::valueText(const QtProperty* property) const +{ + const QtLocalePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + const QLocale loc = it.value(); + + int langIdx = 0; + int countryIdx = 0; + const QtMetaEnumProvider* me = metaEnumProvider(); + me->localeToIndex(loc.language(), loc.country(), &langIdx, &countryIdx); + if (langIdx < 0) { + qWarning("QtLocalePropertyManager::valueText: Unknown language %d", loc.language()); + return tr(""); + } + const QString languageName = me->languageEnumNames().at(langIdx); + if (countryIdx < 0) { + qWarning("QtLocalePropertyManager::valueText: Unknown country %d for %s", loc.country(), qPrintable(languageName)); + return languageName; + } + const QString countryName = me->countryEnumNames(loc.language()).at(countryIdx); + return tr("%1, %2").arg(languageName, countryName); +} + +/*! + \fn void QtLocalePropertyManager::setValue(QtProperty *property, const QLocale &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtLocalePropertyManager::setValue(QtProperty* property, const QLocale& val) +{ + const QtLocalePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + const QLocale loc = it.value(); + if (loc == val) + return; + + it.value() = val; + + int langIdx = 0; + int countryIdx = 0; + metaEnumProvider()->localeToIndex(val.language(), val.country(), &langIdx, &countryIdx); + if (loc.language() != val.language()) { + d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToLanguage.value(property), langIdx); + d_ptr->m_enumPropertyManager->setEnumNames(d_ptr->m_propertyToCountry.value(property), + metaEnumProvider()->countryEnumNames(val.language())); + } + d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToCountry.value(property), countryIdx); + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \reimp +*/ +void QtLocalePropertyManager::initializeProperty(QtProperty* property) +{ + QLocale val; + d_ptr->m_values[property] = val; + + int langIdx = 0; + int countryIdx = 0; + metaEnumProvider()->localeToIndex(val.language(), val.country(), &langIdx, &countryIdx); + + QtProperty* languageProp = d_ptr->m_enumPropertyManager->addProperty(); + languageProp->setPropertyName(tr("Language")); + d_ptr->m_enumPropertyManager->setEnumNames(languageProp, metaEnumProvider()->languageEnumNames()); + d_ptr->m_enumPropertyManager->setValue(languageProp, langIdx); + d_ptr->m_propertyToLanguage[property] = languageProp; + d_ptr->m_languageToProperty[languageProp] = property; + property->addSubProperty(languageProp); + + QtProperty* countryProp = d_ptr->m_enumPropertyManager->addProperty(); + countryProp->setPropertyName(tr("Country")); + d_ptr->m_enumPropertyManager->setEnumNames(countryProp, metaEnumProvider()->countryEnumNames(val.language())); + d_ptr->m_enumPropertyManager->setValue(countryProp, countryIdx); + d_ptr->m_propertyToCountry[property] = countryProp; + d_ptr->m_countryToProperty[countryProp] = property; + property->addSubProperty(countryProp); +} + +/*! + \reimp +*/ +void QtLocalePropertyManager::uninitializeProperty(QtProperty* property) +{ + QtProperty* languageProp = d_ptr->m_propertyToLanguage[property]; + if (languageProp) { + d_ptr->m_languageToProperty.remove(languageProp); + delete languageProp; + } + d_ptr->m_propertyToLanguage.remove(property); + + QtProperty* countryProp = d_ptr->m_propertyToCountry[property]; + if (countryProp) { + d_ptr->m_countryToProperty.remove(countryProp); + delete countryProp; + } + d_ptr->m_propertyToCountry.remove(property); + + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtPointPropertyManager +#pragma region QtPointPropertyManager + +class QtPointPropertyManagerPrivate +{ + QtPointPropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtPointPropertyManager) +public: + + void slotIntChanged(QtProperty* property, int value); + void slotPropertyDestroyed(QtProperty* property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager* m_intPropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + + QMap m_xToProperty; + QMap m_yToProperty; +}; + +void QtPointPropertyManagerPrivate::slotIntChanged(QtProperty* property, int value) +{ + if (QtProperty* xprop = m_xToProperty.value(property, 0)) { + QPoint p = m_values[xprop]; + p.setX(value); + q_ptr->setValue(xprop, p); + } + else if (QtProperty* yprop = m_yToProperty.value(property, 0)) { + QPoint p = m_values[yprop]; + p.setY(value); + q_ptr->setValue(yprop, p); + } +} + +void QtPointPropertyManagerPrivate::slotPropertyDestroyed(QtProperty* property) +{ + if (QtProperty* pointProp = m_xToProperty.value(property, 0)) { + m_propertyToX[pointProp] = 0; + m_xToProperty.remove(property); + } + else if (QtProperty* pointProp = m_yToProperty.value(property, 0)) { + m_propertyToY[pointProp] = 0; + m_yToProperty.remove(property); + } +} + +/*! \class QtPointPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtPointPropertyManager provides and manages QPoint properties. + + A point property has nested \e x and \e y subproperties. The + top-level property's value can be retrieved using the value() + function, and set using the setValue() slot. + + The subproperties are created by a QtIntPropertyManager object. This + manager can be retrieved using the subIntPropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + In addition, QtPointPropertyManager provides the valueChanged() signal which + is emitted whenever a property created by this manager changes. + + \sa QtAbstractPropertyManager, QtIntPropertyManager, QtPointFPropertyManager +*/ + +/*! + \fn void QtPointPropertyManager::valueChanged(QtProperty *property, const QPoint &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtPointPropertyManager::QtPointPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtPointPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotIntChanged(QtProperty*, int))); + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)), + this, SLOT(slotPropertyDestroyed(QtProperty*))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtPointPropertyManager::~QtPointPropertyManager() +{ + clear(); +} + +/*! + Returns the manager that creates the nested \e x and \e y + subproperties. + + In order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager* QtPointPropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns a point with coordinates (0, 0). + + \sa setValue() +*/ +QPoint QtPointPropertyManager::value(const QtProperty* property) const +{ + return d_ptr->m_values.value(property, QPoint()); +} + +/*! + \reimp +*/ +QString QtPointPropertyManager::valueText(const QtProperty* property) const +{ + const QtPointPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QPoint v = it.value(); + return tr("(%1, %2)").arg(QString::number(v.x())) + .arg(QString::number(v.y())); +} + +/*! + \fn void QtPointPropertyManager::setValue(QtProperty *property, const QPoint &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtPointPropertyManager::setValue(QtProperty* property, const QPoint& val) +{ + const QtPointPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + if (it.value() == val) + return; + + it.value() = val; + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToX[property], val.x()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToY[property], val.y()); + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \reimp +*/ +void QtPointPropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QPoint(0, 0); + + QtProperty* xProp = d_ptr->m_intPropertyManager->addProperty(); + xProp->setPropertyName(tr("X")); + d_ptr->m_intPropertyManager->setValueOnly(xProp, 0); + d_ptr->m_propertyToX[property] = xProp; + d_ptr->m_xToProperty[xProp] = property; + property->addSubProperty(xProp); + + QtProperty* yProp = d_ptr->m_intPropertyManager->addProperty(); + yProp->setPropertyName(tr("Y")); + d_ptr->m_intPropertyManager->setValueOnly(yProp, 0); + d_ptr->m_propertyToY[property] = yProp; + d_ptr->m_yToProperty[yProp] = property; + property->addSubProperty(yProp); +} + +/*! + \reimp +*/ +void QtPointPropertyManager::uninitializeProperty(QtProperty* property) +{ + QtProperty* xProp = d_ptr->m_propertyToX[property]; + if (xProp) { + d_ptr->m_xToProperty.remove(xProp); + delete xProp; + } + d_ptr->m_propertyToX.remove(property); + + QtProperty* yProp = d_ptr->m_propertyToY[property]; + if (yProp) { + d_ptr->m_yToProperty.remove(yProp); + delete yProp; + } + d_ptr->m_propertyToY.remove(property); + + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtPointFPropertyManager +#pragma region QtPointFPropertyManager + +class QtPointFPropertyManagerPrivate +{ + QtPointFPropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtPointFPropertyManager) +public: + + struct Data + { + QPointF val; + int decimals{ 2 }; + }; + + void slotDoubleChanged(QtProperty* property, double value); + void slotPropertyDestroyed(QtProperty* property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtDoublePropertyManager* m_doublePropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + + QMap m_xToProperty; + QMap m_yToProperty; +}; + +void QtPointFPropertyManagerPrivate::slotDoubleChanged(QtProperty* property, double value) +{ + if (QtProperty* prop = m_xToProperty.value(property, 0)) { + QPointF p = m_values[prop].val; + p.setX(value); + q_ptr->setValue(prop, p); + } + else if (QtProperty* prop = m_yToProperty.value(property, 0)) { + QPointF p = m_values[prop].val; + p.setY(value); + q_ptr->setValue(prop, p); + } +} + +void QtPointFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty* property) +{ + if (QtProperty* pointProp = m_xToProperty.value(property, 0)) { + m_propertyToX[pointProp] = 0; + m_xToProperty.remove(property); + } + else if (QtProperty* pointProp = m_yToProperty.value(property, 0)) { + m_propertyToY[pointProp] = 0; + m_yToProperty.remove(property); + } +} + +/*! \class QtPointFPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtPointFPropertyManager provides and manages QPointF properties. + + A point property has nested \e x and \e y subproperties. The + top-level property's value can be retrieved using the value() + function, and set using the setValue() slot. + + The subproperties are created by a QtDoublePropertyManager object. This + manager can be retrieved using the subDoublePropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + In addition, QtPointFPropertyManager provides the valueChanged() signal which + is emitted whenever a property created by this manager changes. + + \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtPointPropertyManager +*/ + +/*! + \fn void QtPointFPropertyManager::valueChanged(QtProperty *property, const QPointF &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtPointFPropertyManager::decimalsChanged(QtProperty *property, int prec) + + This signal is emitted whenever a property created by this manager + changes its precision of value, passing a pointer to the + \a property and the new \a prec value + + \sa setDecimals() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtPointFPropertyManager::QtPointFPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtPointFPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; + + d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this); + connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty*, double)), + this, SLOT(slotDoubleChanged(QtProperty*, double))); + connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty*)), + this, SLOT(slotPropertyDestroyed(QtProperty*))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtPointFPropertyManager::~QtPointFPropertyManager() +{ + clear(); +} + +/*! + Returns the manager that creates the nested \e x and \e y + subproperties. + + In order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtDoublePropertyManager* QtPointFPropertyManager::subDoublePropertyManager() const +{ + return d_ptr->m_doublePropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns a point with coordinates (0, 0). + + \sa setValue() +*/ +QPointF QtPointFPropertyManager::value(const QtProperty* property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's precision, in decimals. + + \sa setDecimals() +*/ +int QtPointFPropertyManager::decimals(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtPointFPropertyManagerPrivate::Data::decimals, property, 0); +} + +/*! + \reimp +*/ +QString QtPointFPropertyManager::valueText(const QtProperty* property) const +{ + const QtPointFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QPointF v = it.value().val; + const int dec = it.value().decimals; + return tr("(%1, %2)").arg(QString::number(v.x(), 'f', dec)) + .arg(QString::number(v.y(), 'f', dec)); +} + +/*! + \fn void QtPointFPropertyManager::setValue(QtProperty *property, const QPointF &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtPointFPropertyManager::setValue(QtProperty* property, const QPointF& val) +{ + const QtPointFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + if (it.value().val == val) + return; + + it.value().val = val; + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToX[property], val.x()); + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToY[property], val.y()); + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \fn void QtPointFPropertyManager::setDecimals(QtProperty *property, int prec) + + Sets the precision of the given \a property to \a prec. + + The valid decimal range is 0-13. The default is 2. + + \sa decimals() +*/ +void QtPointFPropertyManager::setDecimals(QtProperty* property, int prec) +{ + const QtPointFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtPointFPropertyManagerPrivate::Data data = it.value(); + + if (prec > 13) + prec = 13; + else if (prec < 0) + prec = 0; + + if (data.decimals == prec) + return; + + data.decimals = prec; + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToX[property], prec); + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToY[property], prec); + + it.value() = data; + + emit decimalsChanged(property, data.decimals); +} + +/*! + \reimp +*/ +void QtPointFPropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QtPointFPropertyManagerPrivate::Data(); + + QtProperty* xProp = d_ptr->m_doublePropertyManager->addProperty(); + xProp->setPropertyName(tr("X")); + d_ptr->m_doublePropertyManager->setDecimals(xProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValueOnly(xProp, 0); + d_ptr->m_propertyToX[property] = xProp; + d_ptr->m_xToProperty[xProp] = property; + property->addSubProperty(xProp); + + QtProperty* yProp = d_ptr->m_doublePropertyManager->addProperty(); + yProp->setPropertyName(tr("Y")); + d_ptr->m_doublePropertyManager->setDecimals(yProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValueOnly(yProp, 0); + d_ptr->m_propertyToY[property] = yProp; + d_ptr->m_yToProperty[yProp] = property; + property->addSubProperty(yProp); +} + +/*! + \reimp +*/ +void QtPointFPropertyManager::uninitializeProperty(QtProperty* property) +{ + QtProperty* xProp = d_ptr->m_propertyToX[property]; + if (xProp) { + d_ptr->m_xToProperty.remove(xProp); + delete xProp; + } + d_ptr->m_propertyToX.remove(property); + + QtProperty* yProp = d_ptr->m_propertyToY[property]; + if (yProp) { + d_ptr->m_yToProperty.remove(yProp); + delete yProp; + } + d_ptr->m_propertyToY.remove(property); + + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtSizePropertyManager +#pragma region QtSizePropertyManager + +class QtSizePropertyManagerPrivate +{ + QtSizePropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtSizePropertyManager) +public: + + void slotIntChanged(QtProperty* property, int value); + void slotPropertyDestroyed(QtProperty* property); + void setValue(QtProperty* property, const QSize& val); + void setRange(QtProperty* property, + const QSize& minVal, const QSize& maxVal, const QSize& val); + + struct Data + { + QSize val{ 0, 0 }; + QSize minVal{ 0, 0 }; + QSize maxVal{ INT_MAX, INT_MAX }; + QSize minimumValue() const { return minVal; } + QSize maximumValue() const { return maxVal; } + void setMinimumValue(const QSize& newMinVal) { setSizeMinimumData(this, newMinVal); } + void setMaximumValue(const QSize& newMaxVal) { setSizeMaximumData(this, newMaxVal); } + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager* m_intPropertyManager; + + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_wToProperty; + QMap m_hToProperty; +}; + +void QtSizePropertyManagerPrivate::slotIntChanged(QtProperty* property, int value) +{ + if (QtProperty* prop = m_wToProperty.value(property, 0)) { + QSize s = m_values[prop].val; + s.setWidth(value); + q_ptr->setValue(prop, s); + } + else if (QtProperty* prop = m_hToProperty.value(property, 0)) { + QSize s = m_values[prop].val; + s.setHeight(value); + q_ptr->setValue(prop, s); + } +} + +void QtSizePropertyManagerPrivate::slotPropertyDestroyed(QtProperty* property) +{ + if (QtProperty* pointProp = m_wToProperty.value(property, 0)) { + m_propertyToW[pointProp] = 0; + m_wToProperty.remove(property); + } + else if (QtProperty* pointProp = m_hToProperty.value(property, 0)) { + m_propertyToH[pointProp] = 0; + m_hToProperty.remove(property); + } +} + +void QtSizePropertyManagerPrivate::setValue(QtProperty* property, const QSize& val) +{ + m_intPropertyManager->setValue(m_propertyToW.value(property), val.width()); + m_intPropertyManager->setValue(m_propertyToH.value(property), val.height()); +} + +void QtSizePropertyManagerPrivate::setRange(QtProperty* property, + const QSize& minVal, const QSize& maxVal, const QSize& val) +{ + QtProperty* wProperty = m_propertyToW.value(property); + QtProperty* hProperty = m_propertyToH.value(property); + m_intPropertyManager->setRange(wProperty, minVal.width(), maxVal.width()); + m_intPropertyManager->setValue(wProperty, val.width()); + m_intPropertyManager->setRange(hProperty, minVal.height(), maxVal.height()); + m_intPropertyManager->setValue(hProperty, val.height()); +} + +/*! + \class QtSizePropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtSizePropertyManager provides and manages QSize properties. + + A size property has nested \e width and \e height + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by a QtIntPropertyManager object. This + manager can be retrieved using the subIntPropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + A size property also has a range of valid values defined by a + minimum size and a maximum size. These sizes can be retrieved + using the minimum() and the maximum() functions, and set using the + setMinimum() and setMaximum() slots. Alternatively, the range can + be defined in one go using the setRange() slot. + + In addition, QtSizePropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the rangeChanged() signal which is emitted whenever + such a property changes its range of valid sizes. + + \sa QtAbstractPropertyManager, QtIntPropertyManager, QtSizeFPropertyManager +*/ + +/*! + \fn void QtSizePropertyManager::valueChanged(QtProperty *property, const QSize &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtSizePropertyManager::rangeChanged(QtProperty *property, const QSize &minimum, const QSize &maximum) + + This signal is emitted whenever a property created by this manager + changes its range of valid sizes, passing a pointer to the \a + property and the new \a minimum and \a maximum sizes. + + \sa setRange() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtSizePropertyManager::QtSizePropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtSizePropertyManagerPrivate) +{ + d_ptr->q_ptr = this; + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotIntChanged(QtProperty*, int))); + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)), + this, SLOT(slotPropertyDestroyed(QtProperty*))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtSizePropertyManager::~QtSizePropertyManager() +{ + clear(); +} + +/*! + Returns the manager that creates the nested \e width and \e height + subproperties. + + In order to provide editing widgets for the \e width and \e height + properties in a property browser widget, this manager must be + associated with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager* QtSizePropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid size + + \sa setValue() +*/ +QSize QtSizePropertyManager::value(const QtProperty* property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's minimum size value. + + \sa setMinimum(), maximum(), setRange() +*/ +QSize QtSizePropertyManager::minimum(const QtProperty* property) const +{ + return getMinimum(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's maximum size value. + + \sa setMaximum(), minimum(), setRange() +*/ +QSize QtSizePropertyManager::maximum(const QtProperty* property) const +{ + return getMaximum(d_ptr->m_values, property); +} + +/*! + \reimp +*/ +QString QtSizePropertyManager::valueText(const QtProperty* property) const +{ + const QtSizePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QSize v = it.value().val; + return tr("%1 x %2").arg(QString::number(v.width())) + .arg(QString::number(v.height())); +} + +/*! + \fn void QtSizePropertyManager::setValue(QtProperty *property, const QSize &value) + + Sets the value of the given \a property to \a value. + + If the specified \a value is not valid according to the given \a + property's size range, the \a value is adjusted to the nearest + valid value within the size range. + + \sa value(), setRange(), valueChanged() +*/ +void QtSizePropertyManager::setValue(QtProperty* property, const QSize& val) +{ + setValueInRange(this, d_ptr.data(), + &QtSizePropertyManager::propertyChanged, + &QtSizePropertyManager::valueChanged, + property, val, &QtSizePropertyManagerPrivate::setValue); +} + +/*! + Sets the minimum size value for the given \a property to \a minVal. + + When setting the minimum size value, the maximum and current + values are adjusted if necessary (ensuring that the size range + remains valid and that the current value is within the range). + + \sa minimum(), setRange(), rangeChanged() +*/ +void QtSizePropertyManager::setMinimum(QtProperty* property, const QSize& minVal) +{ + setBorderValue(this, d_ptr.data(), + &QtSizePropertyManager::propertyChanged, + &QtSizePropertyManager::valueChanged, + &QtSizePropertyManager::rangeChanged, + property, + &QtSizePropertyManagerPrivate::Data::minimumValue, + &QtSizePropertyManagerPrivate::Data::setMinimumValue, + minVal, &QtSizePropertyManagerPrivate::setRange); +} + +/*! + Sets the maximum size value for the given \a property to \a maxVal. + + When setting the maximum size value, the minimum and current + values are adjusted if necessary (ensuring that the size range + remains valid and that the current value is within the range). + + \sa maximum(), setRange(), rangeChanged() +*/ +void QtSizePropertyManager::setMaximum(QtProperty* property, const QSize& maxVal) +{ + setBorderValue(this, d_ptr.data(), + &QtSizePropertyManager::propertyChanged, + &QtSizePropertyManager::valueChanged, + &QtSizePropertyManager::rangeChanged, + property, + &QtSizePropertyManagerPrivate::Data::maximumValue, + &QtSizePropertyManagerPrivate::Data::setMaximumValue, + maxVal, &QtSizePropertyManagerPrivate::setRange); +} + +/*! + \fn void QtSizePropertyManager::setRange(QtProperty *property, const QSize &minimum, const QSize &maximum) + + Sets the range of valid values. + + This is a convenience function defining the range of valid values + in one go; setting the \a minimum and \a maximum values for the + given \a property with a single function call. + + When setting a new range, the current value is adjusted if + necessary (ensuring that the value remains within the range). + + \sa setMinimum(), setMaximum(), rangeChanged() +*/ +void QtSizePropertyManager::setRange(QtProperty* property, const QSize& minVal, const QSize& maxVal) +{ + setBorderValues(this, d_ptr.data(), + &QtSizePropertyManager::propertyChanged, + &QtSizePropertyManager::valueChanged, + &QtSizePropertyManager::rangeChanged, + property, minVal, maxVal, &QtSizePropertyManagerPrivate::setRange); +} + +/*! + \reimp +*/ +void QtSizePropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QtSizePropertyManagerPrivate::Data(); + + QtProperty* wProp = d_ptr->m_intPropertyManager->addProperty(); + wProp->setPropertyName(tr("Width")); + d_ptr->m_intPropertyManager->setValueOnly(wProp, 0); + d_ptr->m_intPropertyManager->setMinimum(wProp, 0); + d_ptr->m_propertyToW[property] = wProp; + d_ptr->m_wToProperty[wProp] = property; + property->addSubProperty(wProp); + + QtProperty* hProp = d_ptr->m_intPropertyManager->addProperty(); + hProp->setPropertyName(tr("Height")); + d_ptr->m_intPropertyManager->setValueOnly(hProp, 0); + d_ptr->m_intPropertyManager->setMinimum(hProp, 0); + d_ptr->m_propertyToH[property] = hProp; + d_ptr->m_hToProperty[hProp] = property; + property->addSubProperty(hProp); +} + +/*! + \reimp +*/ +void QtSizePropertyManager::uninitializeProperty(QtProperty* property) +{ + QtProperty* wProp = d_ptr->m_propertyToW[property]; + if (wProp) { + d_ptr->m_wToProperty.remove(wProp); + delete wProp; + } + d_ptr->m_propertyToW.remove(property); + + QtProperty* hProp = d_ptr->m_propertyToH[property]; + if (hProp) { + d_ptr->m_hToProperty.remove(hProp); + delete hProp; + } + d_ptr->m_propertyToH.remove(property); + + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtSizeFPropertyManager +#pragma region QtSizeFPropertyManager + +class QtSizeFPropertyManagerPrivate +{ + QtSizeFPropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtSizeFPropertyManager) +public: + + void slotDoubleChanged(QtProperty* property, double value); + void slotPropertyDestroyed(QtProperty* property); + void setValue(QtProperty* property, const QSizeF& val); + void setRange(QtProperty* property, + const QSizeF& minVal, const QSizeF& maxVal, const QSizeF& val); + + struct Data + { + QSizeF val{ 0, 0 }; + QSizeF minVal{ 0, 0 }; + QSizeF maxVal{ std::numeric_limits::max(), std::numeric_limits::max() }; + int decimals{ 2 }; + QSizeF minimumValue() const { return minVal; } + QSizeF maximumValue() const { return maxVal; } + void setMinimumValue(const QSizeF& newMinVal) { setSizeMinimumData(this, newMinVal); } + void setMaximumValue(const QSizeF& newMaxVal) { setSizeMaximumData(this, newMaxVal); } + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtDoublePropertyManager* m_doublePropertyManager; + + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_wToProperty; + QMap m_hToProperty; +}; + +void QtSizeFPropertyManagerPrivate::slotDoubleChanged(QtProperty* property, double value) +{ + if (QtProperty* prop = m_wToProperty.value(property, 0)) { + QSizeF s = m_values[prop].val; + s.setWidth(value); + q_ptr->setValue(prop, s); + } + else if (QtProperty* prop = m_hToProperty.value(property, 0)) { + QSizeF s = m_values[prop].val; + s.setHeight(value); + q_ptr->setValue(prop, s); + } +} + +void QtSizeFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty* property) +{ + if (QtProperty* pointProp = m_wToProperty.value(property, 0)) { + m_propertyToW[pointProp] = 0; + m_wToProperty.remove(property); + } + else if (QtProperty* pointProp = m_hToProperty.value(property, 0)) { + m_propertyToH[pointProp] = 0; + m_hToProperty.remove(property); + } +} + +void QtSizeFPropertyManagerPrivate::setValue(QtProperty* property, const QSizeF& val) +{ + m_doublePropertyManager->setValue(m_propertyToW.value(property), val.width()); + m_doublePropertyManager->setValue(m_propertyToH.value(property), val.height()); +} + +void QtSizeFPropertyManagerPrivate::setRange(QtProperty* property, + const QSizeF& minVal, const QSizeF& maxVal, const QSizeF& val) +{ + m_doublePropertyManager->setRange(m_propertyToW[property], minVal.width(), maxVal.width()); + m_doublePropertyManager->setValue(m_propertyToW[property], val.width()); + m_doublePropertyManager->setRange(m_propertyToH[property], minVal.height(), maxVal.height()); + m_doublePropertyManager->setValue(m_propertyToH[property], val.height()); +} + +/*! + \class QtSizeFPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtSizeFPropertyManager provides and manages QSizeF properties. + + A size property has nested \e width and \e height + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by a QtDoublePropertyManager object. This + manager can be retrieved using the subDoublePropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + A size property also has a range of valid values defined by a + minimum size and a maximum size. These sizes can be retrieved + using the minimum() and the maximum() functions, and set using the + setMinimum() and setMaximum() slots. Alternatively, the range can + be defined in one go using the setRange() slot. + + In addition, QtSizeFPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the rangeChanged() signal which is emitted whenever + such a property changes its range of valid sizes. + + \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtSizePropertyManager +*/ + +/*! + \fn void QtSizeFPropertyManager::valueChanged(QtProperty *property, const QSizeF &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtSizeFPropertyManager::rangeChanged(QtProperty *property, const QSizeF &minimum, const QSizeF &maximum) + + This signal is emitted whenever a property created by this manager + changes its range of valid sizes, passing a pointer to the \a + property and the new \a minimum and \a maximum sizes. + + \sa setRange() +*/ + +/*! + \fn void QtSizeFPropertyManager::decimalsChanged(QtProperty *property, int prec) + + This signal is emitted whenever a property created by this manager + changes its precision of value, passing a pointer to the + \a property and the new \a prec value + + \sa setDecimals() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtSizeFPropertyManager::QtSizeFPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtSizeFPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; + + d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this); + connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty*, double)), + this, SLOT(slotDoubleChanged(QtProperty*, double))); + connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty*)), + this, SLOT(slotPropertyDestroyed(QtProperty*))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtSizeFPropertyManager::~QtSizeFPropertyManager() +{ + clear(); +} + +/*! + Returns the manager that creates the nested \e width and \e height + subproperties. + + In order to provide editing widgets for the \e width and \e height + properties in a property browser widget, this manager must be + associated with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtDoublePropertyManager* QtSizeFPropertyManager::subDoublePropertyManager() const +{ + return d_ptr->m_doublePropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid size + + \sa setValue() +*/ +QSizeF QtSizeFPropertyManager::value(const QtProperty* property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's precision, in decimals. + + \sa setDecimals() +*/ +int QtSizeFPropertyManager::decimals(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtSizeFPropertyManagerPrivate::Data::decimals, property, 0); +} + +/*! + Returns the given \a property's minimum size value. + + \sa setMinimum(), maximum(), setRange() +*/ +QSizeF QtSizeFPropertyManager::minimum(const QtProperty* property) const +{ + return getMinimum(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's maximum size value. + + \sa setMaximum(), minimum(), setRange() +*/ +QSizeF QtSizeFPropertyManager::maximum(const QtProperty* property) const +{ + return getMaximum(d_ptr->m_values, property); +} + +/*! + \reimp +*/ +QString QtSizeFPropertyManager::valueText(const QtProperty* property) const +{ + const QtSizeFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QSizeF v = it.value().val; + const int dec = it.value().decimals; + return tr("%1 x %2").arg(QString::number(v.width(), 'f', dec)) + .arg(QString::number(v.height(), 'f', dec)); +} + +/*! + \fn void QtSizeFPropertyManager::setValue(QtProperty *property, const QSizeF &value) + + Sets the value of the given \a property to \a value. + + If the specified \a value is not valid according to the given \a + property's size range, the \a value is adjusted to the nearest + valid value within the size range. + + \sa value(), setRange(), valueChanged() +*/ +void QtSizeFPropertyManager::setValue(QtProperty* property, const QSizeF& val) +{ + setValueInRange(this, d_ptr.data(), + &QtSizeFPropertyManager::propertyChanged, + &QtSizeFPropertyManager::valueChanged, + property, val, &QtSizeFPropertyManagerPrivate::setValue); +} + +/*! + \fn void QtSizeFPropertyManager::setDecimals(QtProperty *property, int prec) + + Sets the precision of the given \a property to \a prec. + + The valid decimal range is 0-13. The default is 2. + + \sa decimals() +*/ +void QtSizeFPropertyManager::setDecimals(QtProperty* property, int prec) +{ + const QtSizeFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtSizeFPropertyManagerPrivate::Data data = it.value(); + + if (prec > 13) + prec = 13; + else if (prec < 0) + prec = 0; + + if (data.decimals == prec) + return; + + data.decimals = prec; + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToW[property], prec); + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToH[property], prec); + + it.value() = data; + + emit decimalsChanged(property, data.decimals); +} + +/*! + Sets the minimum size value for the given \a property to \a minVal. + + When setting the minimum size value, the maximum and current + values are adjusted if necessary (ensuring that the size range + remains valid and that the current value is within the range). + + \sa minimum(), setRange(), rangeChanged() +*/ +void QtSizeFPropertyManager::setMinimum(QtProperty* property, const QSizeF& minVal) +{ + setBorderValue(this, d_ptr.data(), + &QtSizeFPropertyManager::propertyChanged, + &QtSizeFPropertyManager::valueChanged, + &QtSizeFPropertyManager::rangeChanged, + property, + &QtSizeFPropertyManagerPrivate::Data::minimumValue, + &QtSizeFPropertyManagerPrivate::Data::setMinimumValue, + minVal, &QtSizeFPropertyManagerPrivate::setRange); +} + +/*! + Sets the maximum size value for the given \a property to \a maxVal. + + When setting the maximum size value, the minimum and current + values are adjusted if necessary (ensuring that the size range + remains valid and that the current value is within the range). + + \sa maximum(), setRange(), rangeChanged() +*/ +void QtSizeFPropertyManager::setMaximum(QtProperty* property, const QSizeF& maxVal) +{ + setBorderValue(this, d_ptr.data(), + &QtSizeFPropertyManager::propertyChanged, + &QtSizeFPropertyManager::valueChanged, + &QtSizeFPropertyManager::rangeChanged, + property, + &QtSizeFPropertyManagerPrivate::Data::maximumValue, + &QtSizeFPropertyManagerPrivate::Data::setMaximumValue, + maxVal, &QtSizeFPropertyManagerPrivate::setRange); +} + +/*! + \fn void QtSizeFPropertyManager::setRange(QtProperty *property, const QSizeF &minimum, const QSizeF &maximum) + + Sets the range of valid values. + + This is a convenience function defining the range of valid values + in one go; setting the \a minimum and \a maximum values for the + given \a property with a single function call. + + When setting a new range, the current value is adjusted if + necessary (ensuring that the value remains within the range). + + \sa setMinimum(), setMaximum(), rangeChanged() +*/ +void QtSizeFPropertyManager::setRange(QtProperty* property, const QSizeF& minVal, const QSizeF& maxVal) +{ + setBorderValues(this, d_ptr.data(), + &QtSizeFPropertyManager::propertyChanged, + &QtSizeFPropertyManager::valueChanged, + &QtSizeFPropertyManager::rangeChanged, + property, minVal, maxVal, &QtSizeFPropertyManagerPrivate::setRange); +} + +/*! + \reimp +*/ +void QtSizeFPropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QtSizeFPropertyManagerPrivate::Data(); + + QtProperty* wProp = d_ptr->m_doublePropertyManager->addProperty(); + wProp->setPropertyName(tr("Width")); + d_ptr->m_doublePropertyManager->setDecimals(wProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValueOnly(wProp, 0); + d_ptr->m_doublePropertyManager->setMinimum(wProp, 0); + d_ptr->m_propertyToW[property] = wProp; + d_ptr->m_wToProperty[wProp] = property; + property->addSubProperty(wProp); + + QtProperty* hProp = d_ptr->m_doublePropertyManager->addProperty(); + hProp->setPropertyName(tr("Height")); + d_ptr->m_doublePropertyManager->setDecimals(hProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValueOnly(hProp, 0); + d_ptr->m_doublePropertyManager->setMinimum(hProp, 0); + d_ptr->m_propertyToH[property] = hProp; + d_ptr->m_hToProperty[hProp] = property; + property->addSubProperty(hProp); +} + +/*! + \reimp +*/ +void QtSizeFPropertyManager::uninitializeProperty(QtProperty* property) +{ + QtProperty* wProp = d_ptr->m_propertyToW[property]; + if (wProp) { + d_ptr->m_wToProperty.remove(wProp); + delete wProp; + } + d_ptr->m_propertyToW.remove(property); + + QtProperty* hProp = d_ptr->m_propertyToH[property]; + if (hProp) { + d_ptr->m_hToProperty.remove(hProp); + delete hProp; + } + d_ptr->m_propertyToH.remove(property); + + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtRectPropertyManager +#pragma region QtRectPropertyManager + +class QtRectPropertyManagerPrivate +{ + QtRectPropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtRectPropertyManager) +public: + + void slotIntChanged(QtProperty* property, int value); + void slotPropertyDestroyed(QtProperty* property); + void setConstraint(QtProperty* property, const QRect& constraint, const QRect& val); + + struct Data + { + QRect val{ 0, 0, 0, 0 }; + QRect constraint; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager* m_intPropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_xToProperty; + QMap m_yToProperty; + QMap m_wToProperty; + QMap m_hToProperty; +}; + +void QtRectPropertyManagerPrivate::slotIntChanged(QtProperty* property, int value) +{ + if (QtProperty* prop = m_xToProperty.value(property, 0)) { + QRect r = m_values[prop].val; + r.moveLeft(value); + q_ptr->setValue(prop, r); + } + else if (QtProperty* prop = m_yToProperty.value(property)) { + QRect r = m_values[prop].val; + r.moveTop(value); + q_ptr->setValue(prop, r); + } + else if (QtProperty* prop = m_wToProperty.value(property, 0)) { + Data data = m_values[prop]; + QRect r = data.val; + r.setWidth(value); + if (!data.constraint.isNull() && data.constraint.x() + data.constraint.width() < r.x() + r.width()) { + r.moveLeft(data.constraint.left() + data.constraint.width() - r.width()); + } + q_ptr->setValue(prop, r); + } + else if (QtProperty* prop = m_hToProperty.value(property, 0)) { + Data data = m_values[prop]; + QRect r = data.val; + r.setHeight(value); + if (!data.constraint.isNull() && data.constraint.y() + data.constraint.height() < r.y() + r.height()) { + r.moveTop(data.constraint.top() + data.constraint.height() - r.height()); + } + q_ptr->setValue(prop, r); + } +} + +void QtRectPropertyManagerPrivate::slotPropertyDestroyed(QtProperty* property) +{ + if (QtProperty* pointProp = m_xToProperty.value(property, 0)) { + m_propertyToX[pointProp] = 0; + m_xToProperty.remove(property); + } + else if (QtProperty* pointProp = m_yToProperty.value(property, 0)) { + m_propertyToY[pointProp] = 0; + m_yToProperty.remove(property); + } + else if (QtProperty* pointProp = m_wToProperty.value(property, 0)) { + m_propertyToW[pointProp] = 0; + m_wToProperty.remove(property); + } + else if (QtProperty* pointProp = m_hToProperty.value(property, 0)) { + m_propertyToH[pointProp] = 0; + m_hToProperty.remove(property); + } +} + +void QtRectPropertyManagerPrivate::setConstraint(QtProperty* property, + const QRect& constraint, const QRect& val) +{ + const bool isNull = constraint.isNull(); + const int left = isNull ? INT_MIN : constraint.left(); + const int right = isNull ? INT_MAX : constraint.left() + constraint.width(); + const int top = isNull ? INT_MIN : constraint.top(); + const int bottom = isNull ? INT_MAX : constraint.top() + constraint.height(); + const int width = isNull ? INT_MAX : constraint.width(); + const int height = isNull ? INT_MAX : constraint.height(); + + m_intPropertyManager->setRange(m_propertyToX[property], left, right); + m_intPropertyManager->setRange(m_propertyToY[property], top, bottom); + m_intPropertyManager->setRange(m_propertyToW[property], 0, width); + m_intPropertyManager->setRange(m_propertyToH[property], 0, height); + + m_intPropertyManager->setValue(m_propertyToX[property], val.x()); + m_intPropertyManager->setValue(m_propertyToY[property], val.y()); + m_intPropertyManager->setValue(m_propertyToW[property], val.width()); + m_intPropertyManager->setValue(m_propertyToH[property], val.height()); +} + +/*! + \class QtRectPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtRectPropertyManager provides and manages QRect properties. + + A rectangle property has nested \e x, \e y, \e width and \e height + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by a QtIntPropertyManager object. This + manager can be retrieved using the subIntPropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + A rectangle property also has a constraint rectangle which can be + retrieved using the constraint() function, and set using the + setConstraint() slot. + + In addition, QtRectPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the constraintChanged() signal which is emitted + whenever such a property changes its constraint rectangle. + + \sa QtAbstractPropertyManager, QtIntPropertyManager, QtRectFPropertyManager +*/ + +/*! + \fn void QtRectPropertyManager::valueChanged(QtProperty *property, const QRect &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtRectPropertyManager::constraintChanged(QtProperty *property, const QRect &constraint) + + This signal is emitted whenever property changes its constraint + rectangle, passing a pointer to the \a property and the new \a + constraint rectangle as parameters. + + \sa setConstraint() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtRectPropertyManager::QtRectPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtRectPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotIntChanged(QtProperty*, int))); + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)), + this, SLOT(slotPropertyDestroyed(QtProperty*))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtRectPropertyManager::~QtRectPropertyManager() +{ + clear(); +} + +/*! + Returns the manager that creates the nested \e x, \e y, \e width + and \e height subproperties. + + In order to provide editing widgets for the mentioned + subproperties in a property browser widget, this manager must be + associated with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager* QtRectPropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid rectangle. + + \sa setValue(), constraint() +*/ +QRect QtRectPropertyManager::value(const QtProperty* property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's constraining rectangle. If returned value is null QRect it means there is no constraint applied. + + \sa value(), setConstraint() +*/ +QRect QtRectPropertyManager::constraint(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtRectPropertyManagerPrivate::Data::constraint, property, QRect()); +} + +/*! + \reimp +*/ +QString QtRectPropertyManager::valueText(const QtProperty* property) const +{ + const QtRectPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QRect v = it.value().val; + return tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x())) + .arg(QString::number(v.y())) + .arg(QString::number(v.width())) + .arg(QString::number(v.height())); +} + +/*! + \fn void QtRectPropertyManager::setValue(QtProperty *property, const QRect &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + If the specified \a value is not inside the given \a property's + constraining rectangle, the value is adjusted accordingly to fit + within the constraint. + + \sa value(), setConstraint(), valueChanged() +*/ +void QtRectPropertyManager::setValue(QtProperty* property, const QRect& val) +{ + const QtRectPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtRectPropertyManagerPrivate::Data data = it.value(); + + QRect newRect = val.normalized(); + if (!data.constraint.isNull() && !data.constraint.contains(newRect)) { + const QRect r1 = data.constraint; + const QRect r2 = newRect; + newRect.setLeft(qMax(r1.left(), r2.left())); + newRect.setRight(qMin(r1.right(), r2.right())); + newRect.setTop(qMax(r1.top(), r2.top())); + newRect.setBottom(qMin(r1.bottom(), r2.bottom())); + if (newRect.width() < 0 || newRect.height() < 0) + return; + } + + if (data.val == newRect) + return; + + data.val = newRect; + + it.value() = data; + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToX[property], newRect.x()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToY[property], newRect.y()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToW[property], newRect.width()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToH[property], newRect.height()); + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the given \a property's constraining rectangle to \a + constraint. + + When setting the constraint, the current value is adjusted if + necessary (ensuring that the current rectangle value is inside the + constraint). In order to reset the constraint pass a null QRect value. + + \sa setValue(), constraint(), constraintChanged() +*/ +void QtRectPropertyManager::setConstraint(QtProperty* property, const QRect& constraint) +{ + const QtRectPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtRectPropertyManagerPrivate::Data data = it.value(); + + QRect newConstraint = constraint.normalized(); + if (data.constraint == newConstraint) + return; + + const QRect oldVal = data.val; + + data.constraint = newConstraint; + + if (!data.constraint.isNull() && !data.constraint.contains(oldVal)) { + QRect r1 = data.constraint; + QRect r2 = data.val; + + if (r2.width() > r1.width()) + r2.setWidth(r1.width()); + if (r2.height() > r1.height()) + r2.setHeight(r1.height()); + if (r2.left() < r1.left()) + r2.moveLeft(r1.left()); + else if (r2.right() > r1.right()) + r2.moveRight(r1.right()); + if (r2.top() < r1.top()) + r2.moveTop(r1.top()); + else if (r2.bottom() > r1.bottom()) + r2.moveBottom(r1.bottom()); + + data.val = r2; + } + + it.value() = data; + + emit constraintChanged(property, data.constraint); + + d_ptr->setConstraint(property, data.constraint, data.val); + + if (data.val == oldVal) + return; + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + \reimp +*/ +void QtRectPropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QtRectPropertyManagerPrivate::Data(); + + QtProperty* xProp = d_ptr->m_intPropertyManager->addProperty(); + xProp->setPropertyName(tr("X")); + d_ptr->m_intPropertyManager->setValueOnly(xProp, 0); + d_ptr->m_propertyToX[property] = xProp; + d_ptr->m_xToProperty[xProp] = property; + property->addSubProperty(xProp); + + QtProperty* yProp = d_ptr->m_intPropertyManager->addProperty(); + yProp->setPropertyName(tr("Y")); + d_ptr->m_intPropertyManager->setValueOnly(yProp, 0); + d_ptr->m_propertyToY[property] = yProp; + d_ptr->m_yToProperty[yProp] = property; + property->addSubProperty(yProp); + + QtProperty* wProp = d_ptr->m_intPropertyManager->addProperty(); + wProp->setPropertyName(tr("Width")); + d_ptr->m_intPropertyManager->setValueOnly(wProp, 0); + d_ptr->m_intPropertyManager->setMinimum(wProp, 0); + d_ptr->m_propertyToW[property] = wProp; + d_ptr->m_wToProperty[wProp] = property; + property->addSubProperty(wProp); + + QtProperty* hProp = d_ptr->m_intPropertyManager->addProperty(); + hProp->setPropertyName(tr("Height")); + d_ptr->m_intPropertyManager->setValueOnly(hProp, 0); + d_ptr->m_intPropertyManager->setMinimum(hProp, 0); + d_ptr->m_propertyToH[property] = hProp; + d_ptr->m_hToProperty[hProp] = property; + property->addSubProperty(hProp); +} + +/*! + \reimp +*/ +void QtRectPropertyManager::uninitializeProperty(QtProperty* property) +{ + QtProperty* xProp = d_ptr->m_propertyToX[property]; + if (xProp) { + d_ptr->m_xToProperty.remove(xProp); + delete xProp; + } + d_ptr->m_propertyToX.remove(property); + + QtProperty* yProp = d_ptr->m_propertyToY[property]; + if (yProp) { + d_ptr->m_yToProperty.remove(yProp); + delete yProp; + } + d_ptr->m_propertyToY.remove(property); + + QtProperty* wProp = d_ptr->m_propertyToW[property]; + if (wProp) { + d_ptr->m_wToProperty.remove(wProp); + delete wProp; + } + d_ptr->m_propertyToW.remove(property); + + QtProperty* hProp = d_ptr->m_propertyToH[property]; + if (hProp) { + d_ptr->m_hToProperty.remove(hProp); + delete hProp; + } + d_ptr->m_propertyToH.remove(property); + + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtRectFPropertyManager +#pragma region QtRectFPropertyManager + +class QtRectFPropertyManagerPrivate +{ + QtRectFPropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtRectFPropertyManager) +public: + + void slotDoubleChanged(QtProperty* property, double value); + void slotPropertyDestroyed(QtProperty* property); + void setConstraint(QtProperty* property, const QRectF& constraint, const QRectF& val); + + struct Data + { + QRectF val{ 0, 0, 0, 0 }; + QRectF constraint; + int decimals{ 2 }; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtDoublePropertyManager* m_doublePropertyManager; + + QMap m_propertyToX; + QMap m_propertyToY; + QMap m_propertyToW; + QMap m_propertyToH; + + QMap m_xToProperty; + QMap m_yToProperty; + QMap m_wToProperty; + QMap m_hToProperty; +}; + +void QtRectFPropertyManagerPrivate::slotDoubleChanged(QtProperty* property, double value) +{ + if (QtProperty* prop = m_xToProperty.value(property, 0)) { + QRectF r = m_values[prop].val; + r.moveLeft(value); + q_ptr->setValue(prop, r); + } + else if (QtProperty* prop = m_yToProperty.value(property, 0)) { + QRectF r = m_values[prop].val; + r.moveTop(value); + q_ptr->setValue(prop, r); + } + else if (QtProperty* prop = m_wToProperty.value(property, 0)) { + Data data = m_values[prop]; + QRectF r = data.val; + r.setWidth(value); + if (!data.constraint.isNull() && data.constraint.x() + data.constraint.width() < r.x() + r.width()) { + r.moveLeft(data.constraint.left() + data.constraint.width() - r.width()); + } + q_ptr->setValue(prop, r); + } + else if (QtProperty* prop = m_hToProperty.value(property, 0)) { + Data data = m_values[prop]; + QRectF r = data.val; + r.setHeight(value); + if (!data.constraint.isNull() && data.constraint.y() + data.constraint.height() < r.y() + r.height()) { + r.moveTop(data.constraint.top() + data.constraint.height() - r.height()); + } + q_ptr->setValue(prop, r); + } +} + +void QtRectFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty* property) +{ + if (QtProperty* pointProp = m_xToProperty.value(property, 0)) { + m_propertyToX[pointProp] = 0; + m_xToProperty.remove(property); + } + else if (QtProperty* pointProp = m_yToProperty.value(property, 0)) { + m_propertyToY[pointProp] = 0; + m_yToProperty.remove(property); + } + else if (QtProperty* pointProp = m_wToProperty.value(property, 0)) { + m_propertyToW[pointProp] = 0; + m_wToProperty.remove(property); + } + else if (QtProperty* pointProp = m_hToProperty.value(property, 0)) { + m_propertyToH[pointProp] = 0; + m_hToProperty.remove(property); + } +} + +void QtRectFPropertyManagerPrivate::setConstraint(QtProperty* property, + const QRectF& constraint, const QRectF& val) +{ + const bool isNull = constraint.isNull(); + const float left = isNull ? FLT_MIN : constraint.left(); + const float right = isNull ? FLT_MAX : constraint.left() + constraint.width(); + const float top = isNull ? FLT_MIN : constraint.top(); + const float bottom = isNull ? FLT_MAX : constraint.top() + constraint.height(); + const float width = isNull ? FLT_MAX : constraint.width(); + const float height = isNull ? FLT_MAX : constraint.height(); + + m_doublePropertyManager->setRange(m_propertyToX[property], left, right); + m_doublePropertyManager->setRange(m_propertyToY[property], top, bottom); + m_doublePropertyManager->setRange(m_propertyToW[property], 0, width); + m_doublePropertyManager->setRange(m_propertyToH[property], 0, height); + + m_doublePropertyManager->setValue(m_propertyToX[property], val.x()); + m_doublePropertyManager->setValue(m_propertyToY[property], val.y()); + m_doublePropertyManager->setValue(m_propertyToW[property], val.width()); + m_doublePropertyManager->setValue(m_propertyToH[property], val.height()); +} + +/*! + \class QtRectFPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtRectFPropertyManager provides and manages QRectF properties. + + A rectangle property has nested \e x, \e y, \e width and \e height + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by a QtDoublePropertyManager object. This + manager can be retrieved using the subDoublePropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + A rectangle property also has a constraint rectangle which can be + retrieved using the constraint() function, and set using the + setConstraint() slot. + + In addition, QtRectFPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the constraintChanged() signal which is emitted + whenever such a property changes its constraint rectangle. + + \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtRectPropertyManager +*/ + +/*! + \fn void QtRectFPropertyManager::valueChanged(QtProperty *property, const QRectF &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtRectFPropertyManager::constraintChanged(QtProperty *property, const QRectF &constraint) + + This signal is emitted whenever property changes its constraint + rectangle, passing a pointer to the \a property and the new \a + constraint rectangle as parameters. + + \sa setConstraint() +*/ + +/*! + \fn void QtRectFPropertyManager::decimalsChanged(QtProperty *property, int prec) + + This signal is emitted whenever a property created by this manager + changes its precision of value, passing a pointer to the + \a property and the new \a prec value + + \sa setDecimals() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtRectFPropertyManager::QtRectFPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtRectFPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; + + d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this); + connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty*, double)), + this, SLOT(slotDoubleChanged(QtProperty*, double))); + connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty*)), + this, SLOT(slotPropertyDestroyed(QtProperty*))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtRectFPropertyManager::~QtRectFPropertyManager() +{ + clear(); +} + +/*! + Returns the manager that creates the nested \e x, \e y, \e width + and \e height subproperties. + + In order to provide editing widgets for the mentioned + subproperties in a property browser widget, this manager must be + associated with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtDoublePropertyManager* QtRectFPropertyManager::subDoublePropertyManager() const +{ + return d_ptr->m_doublePropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid rectangle. + + \sa setValue(), constraint() +*/ +QRectF QtRectFPropertyManager::value(const QtProperty* property) const +{ + return getValue(d_ptr->m_values, property); +} + +/*! + Returns the given \a property's precision, in decimals. + + \sa setDecimals() +*/ +int QtRectFPropertyManager::decimals(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtRectFPropertyManagerPrivate::Data::decimals, property, 0); +} + +/*! + Returns the given \a property's constraining rectangle. If returned value is null QRectF it means there is no constraint applied. + + \sa value(), setConstraint() +*/ +QRectF QtRectFPropertyManager::constraint(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtRectFPropertyManagerPrivate::Data::constraint, property, QRect()); +} + +/*! + \reimp +*/ +QString QtRectFPropertyManager::valueText(const QtProperty* property) const +{ + const QtRectFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + const QRectF v = it.value().val; + const int dec = it.value().decimals; + return QString(tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x(), 'f', dec)) + .arg(QString::number(v.y(), 'f', dec)) + .arg(QString::number(v.width(), 'f', dec)) + .arg(QString::number(v.height(), 'f', dec))); +} + +/*! + \fn void QtRectFPropertyManager::setValue(QtProperty *property, const QRectF &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + If the specified \a value is not inside the given \a property's + constraining rectangle, the value is adjusted accordingly to fit + within the constraint. + + \sa value(), setConstraint(), valueChanged() +*/ +void QtRectFPropertyManager::setValue(QtProperty* property, const QRectF& val) +{ + const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtRectFPropertyManagerPrivate::Data data = it.value(); + + QRectF newRect = val.normalized(); + if (!data.constraint.isNull() && !data.constraint.contains(newRect)) { + const QRectF r1 = data.constraint; + const QRectF r2 = newRect; + newRect.setLeft(qMax(r1.left(), r2.left())); + newRect.setRight(qMin(r1.right(), r2.right())); + newRect.setTop(qMax(r1.top(), r2.top())); + newRect.setBottom(qMin(r1.bottom(), r2.bottom())); + if (newRect.width() < 0 || newRect.height() < 0) + return; + } + + if (data.val == newRect) + return; + + data.val = newRect; + + it.value() = data; + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToX[property], newRect.x()); + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToY[property], newRect.y()); + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToW[property], newRect.width()); + d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToH[property], newRect.height()); + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the given \a property's constraining rectangle to \a + constraint. + + When setting the constraint, the current value is adjusted if + necessary (ensuring that the current rectangle value is inside the + constraint). In order to reset the constraint pass a null QRectF value. + + \sa setValue(), constraint(), constraintChanged() +*/ +void QtRectFPropertyManager::setConstraint(QtProperty* property, const QRectF& constraint) +{ + const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtRectFPropertyManagerPrivate::Data data = it.value(); + + QRectF newConstraint = constraint.normalized(); + if (data.constraint == newConstraint) + return; + + const QRectF oldVal = data.val; + + data.constraint = newConstraint; + + if (!data.constraint.isNull() && !data.constraint.contains(oldVal)) { + QRectF r1 = data.constraint; + QRectF r2 = data.val; + + if (r2.width() > r1.width()) + r2.setWidth(r1.width()); + if (r2.height() > r1.height()) + r2.setHeight(r1.height()); + if (r2.left() < r1.left()) + r2.moveLeft(r1.left()); + else if (r2.right() > r1.right()) + r2.moveRight(r1.right()); + if (r2.top() < r1.top()) + r2.moveTop(r1.top()); + else if (r2.bottom() > r1.bottom()) + r2.moveBottom(r1.bottom()); + + data.val = r2; + } + + it.value() = data; + + emit constraintChanged(property, data.constraint); + + d_ptr->setConstraint(property, data.constraint, data.val); + + if (data.val == oldVal) + return; + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + \fn void QtRectFPropertyManager::setDecimals(QtProperty *property, int prec) + + Sets the precision of the given \a property to \a prec. + + The valid decimal range is 0-13. The default is 2. + + \sa decimals() +*/ +void QtRectFPropertyManager::setDecimals(QtProperty* property, int prec) +{ + const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtRectFPropertyManagerPrivate::Data data = it.value(); + + if (prec > 13) + prec = 13; + else if (prec < 0) + prec = 0; + + if (data.decimals == prec) + return; + + data.decimals = prec; + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToX[property], prec); + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToY[property], prec); + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToW[property], prec); + d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToH[property], prec); + + it.value() = data; + + emit decimalsChanged(property, data.decimals); +} + +/*! + \reimp +*/ +void QtRectFPropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QtRectFPropertyManagerPrivate::Data(); + + QtProperty* xProp = d_ptr->m_doublePropertyManager->addProperty(); + xProp->setPropertyName(tr("X")); + d_ptr->m_doublePropertyManager->setDecimals(xProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValueOnly(xProp, 0); + d_ptr->m_propertyToX[property] = xProp; + d_ptr->m_xToProperty[xProp] = property; + property->addSubProperty(xProp); + + QtProperty* yProp = d_ptr->m_doublePropertyManager->addProperty(); + yProp->setPropertyName(tr("Y")); + d_ptr->m_doublePropertyManager->setDecimals(yProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValueOnly(yProp, 0); + d_ptr->m_propertyToY[property] = yProp; + d_ptr->m_yToProperty[yProp] = property; + property->addSubProperty(yProp); + + QtProperty* wProp = d_ptr->m_doublePropertyManager->addProperty(); + wProp->setPropertyName(tr("Width")); + d_ptr->m_doublePropertyManager->setDecimals(wProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValueOnly(wProp, 0); + d_ptr->m_doublePropertyManager->setMinimum(wProp, 0); + d_ptr->m_propertyToW[property] = wProp; + d_ptr->m_wToProperty[wProp] = property; + property->addSubProperty(wProp); + + QtProperty* hProp = d_ptr->m_doublePropertyManager->addProperty(); + hProp->setPropertyName(tr("Height")); + d_ptr->m_doublePropertyManager->setDecimals(hProp, decimals(property)); + d_ptr->m_doublePropertyManager->setValueOnly(hProp, 0); + d_ptr->m_doublePropertyManager->setMinimum(hProp, 0); + d_ptr->m_propertyToH[property] = hProp; + d_ptr->m_hToProperty[hProp] = property; + property->addSubProperty(hProp); +} + +/*! + \reimp +*/ +void QtRectFPropertyManager::uninitializeProperty(QtProperty* property) +{ + QtProperty* xProp = d_ptr->m_propertyToX[property]; + if (xProp) { + d_ptr->m_xToProperty.remove(xProp); + delete xProp; + } + d_ptr->m_propertyToX.remove(property); + + QtProperty* yProp = d_ptr->m_propertyToY[property]; + if (yProp) { + d_ptr->m_yToProperty.remove(yProp); + delete yProp; + } + d_ptr->m_propertyToY.remove(property); + + QtProperty* wProp = d_ptr->m_propertyToW[property]; + if (wProp) { + d_ptr->m_wToProperty.remove(wProp); + delete wProp; + } + d_ptr->m_propertyToW.remove(property); + + QtProperty* hProp = d_ptr->m_propertyToH[property]; + if (hProp) { + d_ptr->m_hToProperty.remove(hProp); + delete hProp; + } + d_ptr->m_propertyToH.remove(property); + + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtEnumPropertyManager +#pragma region QtEnumPropertyManager + +class QtEnumPropertyManagerPrivate +{ + QtEnumPropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtEnumPropertyManager) +public: + + struct Data + { + int val{ -1 }; + QStringList enumNames; + QMap enumIcons; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! + \class QtEnumPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtEnumPropertyManager provides and manages enum properties. + + Each enum property has an associated list of enum names which can + be retrieved using the enumNames() function, and set using the + corresponding setEnumNames() function. An enum property's value is + represented by an index in this list, and can be retrieved and set + using the value() and setValue() slots respectively. + + Each enum value can also have an associated icon. The mapping from + values to icons can be set using the setEnumIcons() function and + queried with the enumIcons() function. + + In addition, QtEnumPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. The enumNamesChanged() or enumIconsChanged() signal is emitted + whenever the list of enum names or icons is altered. + + \sa QtAbstractPropertyManager, QtEnumEditorFactory +*/ + +/*! + \fn void QtEnumPropertyManager::valueChanged(QtProperty *property, int value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtEnumPropertyManager::enumNamesChanged(QtProperty *property, const QStringList &names) + + This signal is emitted whenever a property created by this manager + changes its enum names, passing a pointer to the \a property and + the new \a names as parameters. + + \sa setEnumNames() +*/ + +/*! + \fn void QtEnumPropertyManager::enumIconsChanged(QtProperty *property, const QMap &icons) + + This signal is emitted whenever a property created by this manager + changes its enum icons, passing a pointer to the \a property and + the new mapping of values to \a icons as parameters. + + \sa setEnumIcons() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtEnumPropertyManager::QtEnumPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtEnumPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtEnumPropertyManager::~QtEnumPropertyManager() +{ + clear(); +} + +/*! + Returns the given \a property's value which is an index in the + list returned by enumNames() + + If the given property is not managed by this manager, this + function returns -1. + + \sa enumNames(), setValue() +*/ +int QtEnumPropertyManager::value(const QtProperty* property) const +{ + return getValue(d_ptr->m_values, property, -1); +} + +/*! + Returns the given \a property's list of enum names. + + \sa value(), setEnumNames() +*/ +QStringList QtEnumPropertyManager::enumNames(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtEnumPropertyManagerPrivate::Data::enumNames, property, QStringList()); +} + +/*! + Returns the given \a property's map of enum values to their icons. + + \sa value(), setEnumIcons() +*/ +QMap QtEnumPropertyManager::enumIcons(const QtProperty* property) const +{ + return getData >(d_ptr->m_values, &QtEnumPropertyManagerPrivate::Data::enumIcons, property, QMap()); +} + +/*! + \reimp +*/ +QString QtEnumPropertyManager::valueText(const QtProperty* property) const +{ + const QtEnumPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + const QtEnumPropertyManagerPrivate::Data& data = it.value(); + + const int v = data.val; + if (v >= 0 && v < data.enumNames.count()) + return data.enumNames.at(v); + return QString(); +} + +/*! + \reimp +*/ +QIcon QtEnumPropertyManager::valueIcon(const QtProperty* property) const +{ + const QtEnumPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QIcon(); + + const QtEnumPropertyManagerPrivate::Data& data = it.value(); + + const int v = data.val; + return data.enumIcons.value(v); +} + +/*! + \fn void QtEnumPropertyManager::setValue(QtProperty *property, int value) + + Sets the value of the given \a property to \a value. + + The specified \a value must be less than the size of the given \a + property's enumNames() list, and larger than (or equal to) 0. + + \sa value(), valueChanged() +*/ +void QtEnumPropertyManager::setValue(QtProperty* property, int val) +{ + const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtEnumPropertyManagerPrivate::Data data = it.value(); + + if (val >= data.enumNames.count()) + return; + + if (val < 0 && data.enumNames.count() > 0) + return; + + if (val < 0) + val = -1; + + if (data.val == val) + return; + + data.val = val; + + it.value() = data; + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the given \a property's list of enum names to \a + enumNames. The \a property's current value is reset to 0 + indicating the first item of the list. + + If the specified \a enumNames list is empty, the \a property's + current value is set to -1. + + \sa enumNames(), enumNamesChanged() +*/ +void QtEnumPropertyManager::setEnumNames(QtProperty* property, const QStringList& enumNames) +{ + const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtEnumPropertyManagerPrivate::Data data = it.value(); + + if (data.enumNames == enumNames) + return; + + data.enumNames = enumNames; + + data.val = -1; + + if (enumNames.count() > 0) + data.val = 0; + + it.value() = data; + + emit enumNamesChanged(property, data.enumNames); + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the given \a property's map of enum values to their icons to \a + enumIcons. + + Each enum value can have associated icon. This association is represented with passed \a enumIcons map. + + \sa enumNames(), enumNamesChanged() +*/ +void QtEnumPropertyManager::setEnumIcons(QtProperty* property, const QMap& enumIcons) +{ + const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + it.value().enumIcons = enumIcons; + + emit enumIconsChanged(property, it.value().enumIcons); + + emit propertyChanged(property); +} + +/*! + \reimp +*/ +void QtEnumPropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QtEnumPropertyManagerPrivate::Data(); +} + +/*! + \reimp +*/ +void QtEnumPropertyManager::uninitializeProperty(QtProperty* property) +{ + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtFlagPropertyManager +#pragma region QtFlagPropertyManager + +class QtFlagPropertyManagerPrivate +{ + QtFlagPropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtFlagPropertyManager) +public: + + void slotBoolChanged(QtProperty* property, bool value); + void slotPropertyDestroyed(QtProperty* property); + + struct Data + { + int val{ -1 }; + QStringList flagNames; + }; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtBoolPropertyManager* m_boolPropertyManager; + + QMap > m_propertyToFlags; + + QMap m_flagToProperty; +}; + +void QtFlagPropertyManagerPrivate::slotBoolChanged(QtProperty* property, bool value) +{ + QtProperty* prop = m_flagToProperty.value(property, 0); + if (prop == 0) + return; + + const auto pfit = m_propertyToFlags.constFind(prop); + if (pfit == m_propertyToFlags.constEnd()) + return; + int level = 0; + for (QtProperty* p : pfit.value()) { + if (p == property) { + int v = m_values[prop].val; + if (value) { + v |= (1 << level); + } + else { + v &= ~(1 << level); + } + q_ptr->setValue(prop, v); + return; + } + level++; + } +} + +void QtFlagPropertyManagerPrivate::slotPropertyDestroyed(QtProperty* property) +{ + QtProperty* flagProperty = m_flagToProperty.value(property, 0); + if (flagProperty == 0) + return; + + m_propertyToFlags[flagProperty].replace(m_propertyToFlags[flagProperty].indexOf(property), 0); + m_flagToProperty.remove(property); +} + +/*! + \class QtFlagPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtFlagPropertyManager provides and manages flag properties. + + Each flag property has an associated list of flag names which can + be retrieved using the flagNames() function, and set using the + corresponding setFlagNames() function. + + The flag manager provides properties with nested boolean + subproperties representing each flag, i.e. a flag property's value + is the binary combination of the subproperties' values. A + property's value can be retrieved and set using the value() and + setValue() slots respectively. The combination of flags is represented + by single int value - that's why it's possible to store up to + 32 independent flags in one flag property. + + The subproperties are created by a QtBoolPropertyManager object. This + manager can be retrieved using the subBoolPropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + In addition, QtFlagPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes, and the flagNamesChanged() signal which is emitted + whenever the list of flag names is altered. + + \sa QtAbstractPropertyManager, QtBoolPropertyManager +*/ + +/*! + \fn void QtFlagPropertyManager::valueChanged(QtProperty *property, int value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtFlagPropertyManager::flagNamesChanged(QtProperty *property, const QStringList &names) + + This signal is emitted whenever a property created by this manager + changes its flag names, passing a pointer to the \a property and the + new \a names as parameters. + + \sa setFlagNames() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtFlagPropertyManager::QtFlagPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtFlagPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; + + d_ptr->m_boolPropertyManager = new QtBoolPropertyManager(this); + connect(d_ptr->m_boolPropertyManager, SIGNAL(valueChanged(QtProperty*, bool)), + this, SLOT(slotBoolChanged(QtProperty*, bool))); + connect(d_ptr->m_boolPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)), + this, SLOT(slotPropertyDestroyed(QtProperty*))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtFlagPropertyManager::~QtFlagPropertyManager() +{ + clear(); +} + +/*! + Returns the manager that produces the nested boolean subproperties + representing each flag. + + In order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtBoolPropertyManager* QtFlagPropertyManager::subBoolPropertyManager() const +{ + return d_ptr->m_boolPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns 0. + + \sa flagNames(), setValue() +*/ +int QtFlagPropertyManager::value(const QtProperty* property) const +{ + return getValue(d_ptr->m_values, property, 0); +} + +/*! + Returns the given \a property's list of flag names. + + \sa value(), setFlagNames() +*/ +QStringList QtFlagPropertyManager::flagNames(const QtProperty* property) const +{ + return getData(d_ptr->m_values, &QtFlagPropertyManagerPrivate::Data::flagNames, property, QStringList()); +} + +/*! + \reimp +*/ +QString QtFlagPropertyManager::valueText(const QtProperty* property) const +{ + const QtFlagPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + const QtFlagPropertyManagerPrivate::Data& data = it.value(); + + QString str; + int level = 0; + const QChar bar = QLatin1Char('|'); + const QStringList::const_iterator fncend = data.flagNames.constEnd(); + for (QStringList::const_iterator it = data.flagNames.constBegin(); it != fncend; ++it) { + if (data.val & (1 << level)) { + if (!str.isEmpty()) + str += bar; + str += *it; + } + + level++; + } + return str; +} + +/*! + \fn void QtFlagPropertyManager::setValue(QtProperty *property, int value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + The specified \a value must be less than the binary combination of + the property's flagNames() list size (i.e. less than 2\sup n, + where \c n is the size of the list) and larger than (or equal to) + 0. + + \sa value(), valueChanged() +*/ +void QtFlagPropertyManager::setValue(QtProperty* property, int val) +{ + const QtFlagPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtFlagPropertyManagerPrivate::Data data = it.value(); + + if (data.val == val) + return; + + if (val > (1 << data.flagNames.count()) - 1) + return; + + if (val < 0) + return; + + data.val = val; + + it.value() = data; + + const auto pfit = d_ptr->m_propertyToFlags.constFind(property); + int level = 0; + if (pfit != d_ptr->m_propertyToFlags.constEnd()) { + for (QtProperty* prop : pfit.value()) { + if (prop) + d_ptr->m_boolPropertyManager->setValue(prop, val & (1 << level)); + level++; + } + } + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + Sets the given \a property's list of flag names to \a flagNames. The + property's current value is reset to 0 indicating the first item + of the list. + + \sa flagNames(), flagNamesChanged() +*/ +void QtFlagPropertyManager::setFlagNames(QtProperty* property, const QStringList& flagNames) +{ + const QtFlagPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + QtFlagPropertyManagerPrivate::Data data = it.value(); + + if (data.flagNames == flagNames) + return; + + data.flagNames = flagNames; + data.val = 0; + + it.value() = data; + + const auto pfit = d_ptr->m_propertyToFlags.find(property); + if (pfit != d_ptr->m_propertyToFlags.end()) { + for (QtProperty* prop : qAsConst(pfit.value())) { + if (prop) { + delete prop; + d_ptr->m_flagToProperty.remove(prop); + } + } + pfit.value().clear(); + } + + for (const QString& flagName : flagNames) { + QtProperty* prop = d_ptr->m_boolPropertyManager->addProperty(); + prop->setPropertyName(flagName); + property->addSubProperty(prop); + d_ptr->m_propertyToFlags[property].append(prop); + d_ptr->m_flagToProperty[prop] = property; + } + + emit flagNamesChanged(property, data.flagNames); + + emit propertyChanged(property); + emit valueChanged(property, data.val); +} + +/*! + \reimp +*/ +void QtFlagPropertyManager::initializeProperty(QtProperty* property) +{ + d_ptr->m_values[property] = QtFlagPropertyManagerPrivate::Data(); + + d_ptr->m_propertyToFlags[property] = QList(); +} + +/*! + \reimp +*/ +void QtFlagPropertyManager::uninitializeProperty(QtProperty* property) +{ + const auto it = d_ptr->m_propertyToFlags.find(property); + if (it != d_ptr->m_propertyToFlags.end()) { + for (QtProperty* prop : qAsConst(it.value())) { + if (prop) { + d_ptr->m_flagToProperty.remove(prop); + delete prop; + } + } + } + d_ptr->m_propertyToFlags.erase(it); + + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtSizePolicyPropertyManager +#pragma region QtSizePolicyPropertyManager + +class QtSizePolicyPropertyManagerPrivate +{ + QtSizePolicyPropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtSizePolicyPropertyManager) +public: + + QtSizePolicyPropertyManagerPrivate(); + + void slotIntChanged(QtProperty* property, int value); + void slotEnumChanged(QtProperty* property, int value); + void slotPropertyDestroyed(QtProperty* property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager* m_intPropertyManager; + QtEnumPropertyManager* m_enumPropertyManager; + + QMap m_propertyToHPolicy; + QMap m_propertyToVPolicy; + QMap m_propertyToHStretch; + QMap m_propertyToVStretch; + + QMap m_hPolicyToProperty; + QMap m_vPolicyToProperty; + QMap m_hStretchToProperty; + QMap m_vStretchToProperty; +}; + +QtSizePolicyPropertyManagerPrivate::QtSizePolicyPropertyManagerPrivate() +{ +} + +void QtSizePolicyPropertyManagerPrivate::slotIntChanged(QtProperty* property, int value) +{ + if (QtProperty* prop = m_hStretchToProperty.value(property, 0)) { + QSizePolicy sp = m_values[prop]; + sp.setHorizontalStretch(value); + q_ptr->setValue(prop, sp); + } + else if (QtProperty* prop = m_vStretchToProperty.value(property, 0)) { + QSizePolicy sp = m_values[prop]; + sp.setVerticalStretch(value); + q_ptr->setValue(prop, sp); + } +} + +void QtSizePolicyPropertyManagerPrivate::slotEnumChanged(QtProperty* property, int value) +{ + if (QtProperty* prop = m_hPolicyToProperty.value(property, 0)) { + QSizePolicy sp = m_values[prop]; + sp.setHorizontalPolicy(metaEnumProvider()->indexToSizePolicy(value)); + q_ptr->setValue(prop, sp); + } + else if (QtProperty* prop = m_vPolicyToProperty.value(property, 0)) { + QSizePolicy sp = m_values[prop]; + sp.setVerticalPolicy(metaEnumProvider()->indexToSizePolicy(value)); + q_ptr->setValue(prop, sp); + } +} + +void QtSizePolicyPropertyManagerPrivate::slotPropertyDestroyed(QtProperty* property) +{ + if (QtProperty* pointProp = m_hStretchToProperty.value(property, 0)) { + m_propertyToHStretch[pointProp] = 0; + m_hStretchToProperty.remove(property); + } + else if (QtProperty* pointProp = m_vStretchToProperty.value(property, 0)) { + m_propertyToVStretch[pointProp] = 0; + m_vStretchToProperty.remove(property); + } + else if (QtProperty* pointProp = m_hPolicyToProperty.value(property, 0)) { + m_propertyToHPolicy[pointProp] = 0; + m_hPolicyToProperty.remove(property); + } + else if (QtProperty* pointProp = m_vPolicyToProperty.value(property, 0)) { + m_propertyToVPolicy[pointProp] = 0; + m_vPolicyToProperty.remove(property); + } +} + +/*! + \class QtSizePolicyPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtSizePolicyPropertyManager provides and manages QSizePolicy properties. + + A size policy property has nested \e horizontalPolicy, \e + verticalPolicy, \e horizontalStretch and \e verticalStretch + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by QtIntPropertyManager and QtEnumPropertyManager + objects. These managers can be retrieved using the subIntPropertyManager() + and subEnumPropertyManager() functions respectively. In order to provide + editing widgets for the subproperties in a property browser widget, + these managers must be associated with editor factories. + + In addition, QtSizePolicyPropertyManager provides the valueChanged() + signal which is emitted whenever a property created by this + manager changes. + + \sa QtAbstractPropertyManager, QtIntPropertyManager, QtEnumPropertyManager +*/ + +/*! + \fn void QtSizePolicyPropertyManager::valueChanged(QtProperty *property, const QSizePolicy &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtSizePolicyPropertyManager::QtSizePolicyPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtSizePolicyPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotIntChanged(QtProperty*, int))); + d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this); + connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotEnumChanged(QtProperty*, int))); + + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)), + this, SLOT(slotPropertyDestroyed(QtProperty*))); + connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)), + this, SLOT(slotPropertyDestroyed(QtProperty*))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtSizePolicyPropertyManager::~QtSizePolicyPropertyManager() +{ + clear(); +} + +/*! + Returns the manager that creates the nested \e horizontalStretch + and \e verticalStretch subproperties. + + In order to provide editing widgets for the mentioned subproperties + in a property browser widget, this manager must be associated with + an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager* QtSizePolicyPropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the manager that creates the nested \e horizontalPolicy + and \e verticalPolicy subproperties. + + In order to provide editing widgets for the mentioned subproperties + in a property browser widget, this manager must be associated with + an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtEnumPropertyManager* QtSizePolicyPropertyManager::subEnumPropertyManager() const +{ + return d_ptr->m_enumPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns the default size policy. + + \sa setValue() +*/ +QSizePolicy QtSizePolicyPropertyManager::value(const QtProperty* property) const +{ + return d_ptr->m_values.value(property, QSizePolicy()); +} + +/*! + \reimp +*/ +QString QtSizePolicyPropertyManager::valueText(const QtProperty* property) const +{ + const QtSizePolicyPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + const QSizePolicy sp = it.value(); + const QtMetaEnumProvider* mep = metaEnumProvider(); + const int hIndex = mep->sizePolicyToIndex(sp.horizontalPolicy()); + const int vIndex = mep->sizePolicyToIndex(sp.verticalPolicy()); + //! Unknown size policy on reading invalid uic3 files + const QString hPolicy = hIndex != -1 ? mep->policyEnumNames().at(hIndex) : tr(""); + const QString vPolicy = vIndex != -1 ? mep->policyEnumNames().at(vIndex) : tr(""); + const QString str = tr("[%1, %2, %3, %4]").arg(hPolicy, vPolicy).arg(sp.horizontalStretch()).arg(sp.verticalStretch()); + return str; +} + +/*! + \fn void QtSizePolicyPropertyManager::setValue(QtProperty *property, const QSizePolicy &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtSizePolicyPropertyManager::setValue(QtProperty* property, const QSizePolicy& val) +{ + const QtSizePolicyPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + if (it.value() == val) + return; + + it.value() = val; + + d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToHPolicy[property], + metaEnumProvider()->sizePolicyToIndex(val.horizontalPolicy())); + d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToVPolicy[property], + metaEnumProvider()->sizePolicyToIndex(val.verticalPolicy())); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToHStretch[property], + val.horizontalStretch()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToVStretch[property], + val.verticalStretch()); + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \reimp +*/ +void QtSizePolicyPropertyManager::initializeProperty(QtProperty* property) +{ + QSizePolicy val; + d_ptr->m_values[property] = val; + + QtProperty* hPolicyProp = d_ptr->m_enumPropertyManager->addProperty(); + hPolicyProp->setPropertyName(tr("Horizontal Policy")); + d_ptr->m_enumPropertyManager->setEnumNames(hPolicyProp, metaEnumProvider()->policyEnumNames()); + d_ptr->m_enumPropertyManager->setValue(hPolicyProp, + metaEnumProvider()->sizePolicyToIndex(val.horizontalPolicy())); + d_ptr->m_propertyToHPolicy[property] = hPolicyProp; + d_ptr->m_hPolicyToProperty[hPolicyProp] = property; + property->addSubProperty(hPolicyProp); + + QtProperty* vPolicyProp = d_ptr->m_enumPropertyManager->addProperty(); + vPolicyProp->setPropertyName(tr("Vertical Policy")); + d_ptr->m_enumPropertyManager->setEnumNames(vPolicyProp, metaEnumProvider()->policyEnumNames()); + d_ptr->m_enumPropertyManager->setValue(vPolicyProp, + metaEnumProvider()->sizePolicyToIndex(val.verticalPolicy())); + d_ptr->m_propertyToVPolicy[property] = vPolicyProp; + d_ptr->m_vPolicyToProperty[vPolicyProp] = property; + property->addSubProperty(vPolicyProp); + + QtProperty* hStretchProp = d_ptr->m_intPropertyManager->addProperty(); + hStretchProp->setPropertyName(tr("Horizontal Stretch")); + d_ptr->m_intPropertyManager->setValueOnly(hStretchProp, val.horizontalStretch()); + d_ptr->m_intPropertyManager->setRange(hStretchProp, 0, 0xff); + d_ptr->m_propertyToHStretch[property] = hStretchProp; + d_ptr->m_hStretchToProperty[hStretchProp] = property; + property->addSubProperty(hStretchProp); + + QtProperty* vStretchProp = d_ptr->m_intPropertyManager->addProperty(); + vStretchProp->setPropertyName(tr("Vertical Stretch")); + d_ptr->m_intPropertyManager->setValueOnly(vStretchProp, val.verticalStretch()); + d_ptr->m_intPropertyManager->setRange(vStretchProp, 0, 0xff); + d_ptr->m_propertyToVStretch[property] = vStretchProp; + d_ptr->m_vStretchToProperty[vStretchProp] = property; + property->addSubProperty(vStretchProp); + +} + +/*! + \reimp +*/ +void QtSizePolicyPropertyManager::uninitializeProperty(QtProperty* property) +{ + QtProperty* hPolicyProp = d_ptr->m_propertyToHPolicy[property]; + if (hPolicyProp) { + d_ptr->m_hPolicyToProperty.remove(hPolicyProp); + delete hPolicyProp; + } + d_ptr->m_propertyToHPolicy.remove(property); + + QtProperty* vPolicyProp = d_ptr->m_propertyToVPolicy[property]; + if (vPolicyProp) { + d_ptr->m_vPolicyToProperty.remove(vPolicyProp); + delete vPolicyProp; + } + d_ptr->m_propertyToVPolicy.remove(property); + + QtProperty* hStretchProp = d_ptr->m_propertyToHStretch[property]; + if (hStretchProp) { + d_ptr->m_hStretchToProperty.remove(hStretchProp); + delete hStretchProp; + } + d_ptr->m_propertyToHStretch.remove(property); + + QtProperty* vStretchProp = d_ptr->m_propertyToVStretch[property]; + if (vStretchProp) { + d_ptr->m_vStretchToProperty.remove(vStretchProp); + delete vStretchProp; + } + d_ptr->m_propertyToVStretch.remove(property); + + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtFontPropertyManager: +// QtFontPropertyManagerPrivate has a mechanism for reacting +// to QApplication::fontDatabaseChanged() [4.5], which is emitted +// when someone loads an application font. The signals are compressed +// using a timer with interval 0, which then causes the family +// enumeration manager to re-set its strings and index values +// for each property. +#pragma region QtFontPropertyManager + +class QtFontPropertyManagerPrivate +{ + QtFontPropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtFontPropertyManager) +public: + + QtFontPropertyManagerPrivate(); + + void slotIntChanged(QtProperty* property, int value); + void slotEnumChanged(QtProperty* property, int value); + void slotBoolChanged(QtProperty* property, bool value); + void slotPropertyDestroyed(QtProperty* property); + void slotFontDatabaseChanged(); + void slotFontDatabaseDelayedChange(); + + QStringList m_familyNames; + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager* m_intPropertyManager; + QtEnumPropertyManager* m_enumPropertyManager; + QtBoolPropertyManager* m_boolPropertyManager; + + QMap m_propertyToFamily; + QMap m_propertyToPointSize; + QMap m_propertyToBold; + QMap m_propertyToItalic; + QMap m_propertyToUnderline; + QMap m_propertyToStrikeOut; + QMap m_propertyToKerning; + + QMap m_familyToProperty; + QMap m_pointSizeToProperty; + QMap m_boldToProperty; + QMap m_italicToProperty; + QMap m_underlineToProperty; + QMap m_strikeOutToProperty; + QMap m_kerningToProperty; + + bool m_settingValue; + QTimer* m_fontDatabaseChangeTimer; +}; + +QtFontPropertyManagerPrivate::QtFontPropertyManagerPrivate() : + m_settingValue(false), + m_fontDatabaseChangeTimer(0) +{ +} + +void QtFontPropertyManagerPrivate::slotIntChanged(QtProperty* property, int value) +{ + if (m_settingValue) + return; + if (QtProperty* prop = m_pointSizeToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setPointSize(value); + q_ptr->setValue(prop, f); + } +} + +void QtFontPropertyManagerPrivate::slotEnumChanged(QtProperty* property, int value) +{ + if (m_settingValue) + return; + if (QtProperty* prop = m_familyToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setFamily(m_familyNames.at(value)); + q_ptr->setValue(prop, f); + } +} + +void QtFontPropertyManagerPrivate::slotBoolChanged(QtProperty* property, bool value) +{ + if (m_settingValue) + return; + if (QtProperty* prop = m_boldToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setBold(value); + q_ptr->setValue(prop, f); + } + else if (QtProperty* prop = m_italicToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setItalic(value); + q_ptr->setValue(prop, f); + } + else if (QtProperty* prop = m_underlineToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setUnderline(value); + q_ptr->setValue(prop, f); + } + else if (QtProperty* prop = m_strikeOutToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setStrikeOut(value); + q_ptr->setValue(prop, f); + } + else if (QtProperty* prop = m_kerningToProperty.value(property, 0)) { + QFont f = m_values[prop]; + f.setKerning(value); + q_ptr->setValue(prop, f); + } +} + +void QtFontPropertyManagerPrivate::slotPropertyDestroyed(QtProperty* property) +{ + if (QtProperty* pointProp = m_pointSizeToProperty.value(property, 0)) { + m_propertyToPointSize[pointProp] = 0; + m_pointSizeToProperty.remove(property); + } + else if (QtProperty* pointProp = m_familyToProperty.value(property, 0)) { + m_propertyToFamily[pointProp] = 0; + m_familyToProperty.remove(property); + } + else if (QtProperty* pointProp = m_boldToProperty.value(property, 0)) { + m_propertyToBold[pointProp] = 0; + m_boldToProperty.remove(property); + } + else if (QtProperty* pointProp = m_italicToProperty.value(property, 0)) { + m_propertyToItalic[pointProp] = 0; + m_italicToProperty.remove(property); + } + else if (QtProperty* pointProp = m_underlineToProperty.value(property, 0)) { + m_propertyToUnderline[pointProp] = 0; + m_underlineToProperty.remove(property); + } + else if (QtProperty* pointProp = m_strikeOutToProperty.value(property, 0)) { + m_propertyToStrikeOut[pointProp] = 0; + m_strikeOutToProperty.remove(property); + } + else if (QtProperty* pointProp = m_kerningToProperty.value(property, 0)) { + m_propertyToKerning[pointProp] = 0; + m_kerningToProperty.remove(property); + } +} + +void QtFontPropertyManagerPrivate::slotFontDatabaseChanged() +{ + if (!m_fontDatabaseChangeTimer) { + m_fontDatabaseChangeTimer = new QTimer(q_ptr); + m_fontDatabaseChangeTimer->setInterval(0); + m_fontDatabaseChangeTimer->setSingleShot(true); + QObject::connect(m_fontDatabaseChangeTimer, SIGNAL(timeout()), q_ptr, SLOT(slotFontDatabaseDelayedChange())); + } + if (!m_fontDatabaseChangeTimer->isActive()) + m_fontDatabaseChangeTimer->start(); +} + +void QtFontPropertyManagerPrivate::slotFontDatabaseDelayedChange() +{ + typedef QMap PropertyPropertyMap; + // rescan available font names + const QStringList oldFamilies = m_familyNames; + m_familyNames = QFontDatabase::families(); + + // Adapt all existing properties + if (!m_propertyToFamily.isEmpty()) { + PropertyPropertyMap::const_iterator cend = m_propertyToFamily.constEnd(); + for (PropertyPropertyMap::const_iterator it = m_propertyToFamily.constBegin(); it != cend; ++it) { + QtProperty* familyProp = it.value(); + const int oldIdx = m_enumPropertyManager->value(familyProp); + int newIdx = m_familyNames.indexOf(oldFamilies.at(oldIdx)); + if (newIdx < 0) + newIdx = 0; + m_enumPropertyManager->setEnumNames(familyProp, m_familyNames); + m_enumPropertyManager->setValue(familyProp, newIdx); + } + } +} + +/*! + \class QtFontPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtFontPropertyManager provides and manages QFont properties. + + A font property has nested \e family, \e pointSize, \e bold, \e + italic, \e underline, \e strikeOut and \e kerning subproperties. The top-level + property's value can be retrieved using the value() function, and + set using the setValue() slot. + + The subproperties are created by QtIntPropertyManager, QtEnumPropertyManager and + QtBoolPropertyManager objects. These managers can be retrieved using the + corresponding subIntPropertyManager(), subEnumPropertyManager() and + subBoolPropertyManager() functions. In order to provide editing widgets + for the subproperties in a property browser widget, these managers + must be associated with editor factories. + + In addition, QtFontPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager, QtEnumPropertyManager, QtIntPropertyManager, QtBoolPropertyManager +*/ + +/*! + \fn void QtFontPropertyManager::valueChanged(QtProperty *property, const QFont &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtFontPropertyManager::QtFontPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtFontPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; + QObject::connect(qApp, SIGNAL(fontDatabaseChanged()), this, SLOT(slotFontDatabaseChanged())); + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotIntChanged(QtProperty*, int))); + d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this); + connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotEnumChanged(QtProperty*, int))); + d_ptr->m_boolPropertyManager = new QtBoolPropertyManager(this); + connect(d_ptr->m_boolPropertyManager, SIGNAL(valueChanged(QtProperty*, bool)), + this, SLOT(slotBoolChanged(QtProperty*, bool))); + + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)), + this, SLOT(slotPropertyDestroyed(QtProperty*))); + connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)), + this, SLOT(slotPropertyDestroyed(QtProperty*))); + connect(d_ptr->m_boolPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)), + this, SLOT(slotPropertyDestroyed(QtProperty*))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtFontPropertyManager::~QtFontPropertyManager() +{ + clear(); +} + +/*! + Returns the manager that creates the \e pointSize subproperty. + + In order to provide editing widgets for the \e pointSize property + in a property browser widget, this manager must be associated + with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager* QtFontPropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the manager that create the \e family subproperty. + + In order to provide editing widgets for the \e family property + in a property browser widget, this manager must be associated + with an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtEnumPropertyManager* QtFontPropertyManager::subEnumPropertyManager() const +{ + return d_ptr->m_enumPropertyManager; +} + +/*! + Returns the manager that creates the \e bold, \e italic, \e underline, + \e strikeOut and \e kerning subproperties. + + In order to provide editing widgets for the mentioned properties + in a property browser widget, this manager must be associated with + an editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtBoolPropertyManager* QtFontPropertyManager::subBoolPropertyManager() const +{ + return d_ptr->m_boolPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given property is not managed by this manager, this + function returns a font object that uses the application's default + font. + + \sa setValue() +*/ +QFont QtFontPropertyManager::value(const QtProperty* property) const +{ + return d_ptr->m_values.value(property, QFont()); +} + +/*! + \reimp +*/ +QString QtFontPropertyManager::valueText(const QtProperty* property) const +{ + const QtFontPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + return QtPropertyBrowserUtils::fontValueText(it.value()); +} + +/*! + \reimp +*/ +QIcon QtFontPropertyManager::valueIcon(const QtProperty* property) const +{ + const QtFontPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QIcon(); + + return QtPropertyBrowserUtils::fontValueIcon(it.value()); +} + +/*! + \fn void QtFontPropertyManager::setValue(QtProperty *property, const QFont &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtFontPropertyManager::setValue(QtProperty* property, const QFont& val) +{ + const QtFontPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + const QFont oldVal = it.value(); + if (oldVal == val && oldVal.resolveMask() == val.resolveMask()) + return; + + it.value() = val; + + int idx = d_ptr->m_familyNames.indexOf(val.family()); + if (idx == -1) + idx = 0; + bool settingValue = d_ptr->m_settingValue; + d_ptr->m_settingValue = true; + d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToFamily[property], idx); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToPointSize[property], val.pointSize()); + d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToBold[property], val.bold()); + d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToItalic[property], val.italic()); + d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToUnderline[property], val.underline()); + d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToStrikeOut[property], val.strikeOut()); + d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToKerning[property], val.kerning()); + d_ptr->m_settingValue = settingValue; + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \reimp +*/ +void QtFontPropertyManager::initializeProperty(QtProperty* property) +{ + QFont val; + d_ptr->m_values[property] = val; + + QtProperty* familyProp = d_ptr->m_enumPropertyManager->addProperty(); + familyProp->setPropertyName(tr("Family")); + if (d_ptr->m_familyNames.isEmpty()) + d_ptr->m_familyNames = QFontDatabase::families(); + d_ptr->m_enumPropertyManager->setEnumNames(familyProp, d_ptr->m_familyNames); + int idx = d_ptr->m_familyNames.indexOf(val.family()); + if (idx == -1) + idx = 0; + d_ptr->m_enumPropertyManager->setValue(familyProp, idx); + d_ptr->m_propertyToFamily[property] = familyProp; + d_ptr->m_familyToProperty[familyProp] = property; + property->addSubProperty(familyProp); + + QtProperty* pointSizeProp = d_ptr->m_intPropertyManager->addProperty(); + pointSizeProp->setPropertyName(tr("Point Size")); + d_ptr->m_intPropertyManager->setValueOnly(pointSizeProp, val.pointSize()); + d_ptr->m_intPropertyManager->setMinimum(pointSizeProp, 1); + d_ptr->m_propertyToPointSize[property] = pointSizeProp; + d_ptr->m_pointSizeToProperty[pointSizeProp] = property; + property->addSubProperty(pointSizeProp); + + QtProperty* boldProp = d_ptr->m_boolPropertyManager->addProperty(); + boldProp->setPropertyName(tr("Bold")); + d_ptr->m_boolPropertyManager->setValueOnly(boldProp, val.bold()); + d_ptr->m_propertyToBold[property] = boldProp; + d_ptr->m_boldToProperty[boldProp] = property; + property->addSubProperty(boldProp); + + QtProperty* italicProp = d_ptr->m_boolPropertyManager->addProperty(); + italicProp->setPropertyName(tr("Italic")); + d_ptr->m_boolPropertyManager->setValueOnly(italicProp, val.italic()); + d_ptr->m_propertyToItalic[property] = italicProp; + d_ptr->m_italicToProperty[italicProp] = property; + property->addSubProperty(italicProp); + + QtProperty* underlineProp = d_ptr->m_boolPropertyManager->addProperty(); + underlineProp->setPropertyName(tr("Underline")); + d_ptr->m_boolPropertyManager->setValueOnly(underlineProp, val.underline()); + d_ptr->m_propertyToUnderline[property] = underlineProp; + d_ptr->m_underlineToProperty[underlineProp] = property; + property->addSubProperty(underlineProp); + + QtProperty* strikeOutProp = d_ptr->m_boolPropertyManager->addProperty(); + strikeOutProp->setPropertyName(tr("Strikeout")); + d_ptr->m_boolPropertyManager->setValueOnly(strikeOutProp, val.strikeOut()); + d_ptr->m_propertyToStrikeOut[property] = strikeOutProp; + d_ptr->m_strikeOutToProperty[strikeOutProp] = property; + property->addSubProperty(strikeOutProp); + + QtProperty* kerningProp = d_ptr->m_boolPropertyManager->addProperty(); + kerningProp->setPropertyName(tr("Kerning")); + d_ptr->m_boolPropertyManager->setValueOnly(kerningProp, val.kerning()); + d_ptr->m_propertyToKerning[property] = kerningProp; + d_ptr->m_kerningToProperty[kerningProp] = property; + property->addSubProperty(kerningProp); +} + +/*! + \reimp +*/ +void QtFontPropertyManager::uninitializeProperty(QtProperty* property) +{ + QtProperty* familyProp = d_ptr->m_propertyToFamily[property]; + if (familyProp) { + d_ptr->m_familyToProperty.remove(familyProp); + delete familyProp; + } + d_ptr->m_propertyToFamily.remove(property); + + QtProperty* pointSizeProp = d_ptr->m_propertyToPointSize[property]; + if (pointSizeProp) { + d_ptr->m_pointSizeToProperty.remove(pointSizeProp); + delete pointSizeProp; + } + d_ptr->m_propertyToPointSize.remove(property); + + QtProperty* boldProp = d_ptr->m_propertyToBold[property]; + if (boldProp) { + d_ptr->m_boldToProperty.remove(boldProp); + delete boldProp; + } + d_ptr->m_propertyToBold.remove(property); + + QtProperty* italicProp = d_ptr->m_propertyToItalic[property]; + if (italicProp) { + d_ptr->m_italicToProperty.remove(italicProp); + delete italicProp; + } + d_ptr->m_propertyToItalic.remove(property); + + QtProperty* underlineProp = d_ptr->m_propertyToUnderline[property]; + if (underlineProp) { + d_ptr->m_underlineToProperty.remove(underlineProp); + delete underlineProp; + } + d_ptr->m_propertyToUnderline.remove(property); + + QtProperty* strikeOutProp = d_ptr->m_propertyToStrikeOut[property]; + if (strikeOutProp) { + d_ptr->m_strikeOutToProperty.remove(strikeOutProp); + delete strikeOutProp; + } + d_ptr->m_propertyToStrikeOut.remove(property); + + QtProperty* kerningProp = d_ptr->m_propertyToKerning[property]; + if (kerningProp) { + d_ptr->m_kerningToProperty.remove(kerningProp); + delete kerningProp; + } + d_ptr->m_propertyToKerning.remove(property); + + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtColorPropertyManager +#pragma region QtColorPropertyManager + +class QtColorPropertyManagerPrivate +{ + QtColorPropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtColorPropertyManager) +public: + + void slotIntChanged(QtProperty* property, int value); + void slotPropertyDestroyed(QtProperty* property); + + typedef QMap PropertyValueMap; + PropertyValueMap m_values; + + QtIntPropertyManager* m_intPropertyManager; + + QMap m_propertyToR; + QMap m_propertyToG; + QMap m_propertyToB; + QMap m_propertyToA; + + QMap m_rToProperty; + QMap m_gToProperty; + QMap m_bToProperty; + QMap m_aToProperty; +}; + +void QtColorPropertyManagerPrivate::slotIntChanged(QtProperty* property, int value) +{ + if (QtProperty* prop = m_rToProperty.value(property, 0)) { + QColor c = m_values[prop]; + c.setRed(value); + q_ptr->setValue(prop, c); + } + else if (QtProperty* prop = m_gToProperty.value(property, 0)) { + QColor c = m_values[prop]; + c.setGreen(value); + q_ptr->setValue(prop, c); + } + else if (QtProperty* prop = m_bToProperty.value(property, 0)) { + QColor c = m_values[prop]; + c.setBlue(value); + q_ptr->setValue(prop, c); + } + else if (QtProperty* prop = m_aToProperty.value(property, 0)) { + QColor c = m_values[prop]; + c.setAlpha(value); + q_ptr->setValue(prop, c); + } +} + +void QtColorPropertyManagerPrivate::slotPropertyDestroyed(QtProperty* property) +{ + if (QtProperty* pointProp = m_rToProperty.value(property, 0)) { + m_propertyToR[pointProp] = 0; + m_rToProperty.remove(property); + } + else if (QtProperty* pointProp = m_gToProperty.value(property, 0)) { + m_propertyToG[pointProp] = 0; + m_gToProperty.remove(property); + } + else if (QtProperty* pointProp = m_bToProperty.value(property, 0)) { + m_propertyToB[pointProp] = 0; + m_bToProperty.remove(property); + } + else if (QtProperty* pointProp = m_aToProperty.value(property, 0)) { + m_propertyToA[pointProp] = 0; + m_aToProperty.remove(property); + } +} + +/*! + \class QtColorPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtColorPropertyManager provides and manages QColor properties. + + A color property has nested \e red, \e green and \e blue + subproperties. The top-level property's value can be retrieved + using the value() function, and set using the setValue() slot. + + The subproperties are created by a QtIntPropertyManager object. This + manager can be retrieved using the subIntPropertyManager() function. In + order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + In addition, QtColorPropertyManager provides the valueChanged() signal + which is emitted whenever a property created by this manager + changes. + + \sa QtAbstractPropertyManager, QtAbstractPropertyBrowser, QtIntPropertyManager +*/ + +/*! + \fn void QtColorPropertyManager::valueChanged(QtProperty *property, const QColor &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtColorPropertyManager::QtColorPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtColorPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; + + d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); + connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*, int)), + this, SLOT(slotIntChanged(QtProperty*, int))); + + connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)), + this, SLOT(slotPropertyDestroyed(QtProperty*))); +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtColorPropertyManager::~QtColorPropertyManager() +{ + clear(); +} + +/*! + Returns the manager that produces the nested \e red, \e green and + \e blue subproperties. + + In order to provide editing widgets for the subproperties in a + property browser widget, this manager must be associated with an + editor factory. + + \sa QtAbstractPropertyBrowser::setFactoryForManager() +*/ +QtIntPropertyManager* QtColorPropertyManager::subIntPropertyManager() const +{ + return d_ptr->m_intPropertyManager; +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by \e this manager, this + function returns an invalid color. + + \sa setValue() +*/ +QColor QtColorPropertyManager::value(const QtProperty* property) const +{ + return d_ptr->m_values.value(property, QColor()); +} + +/*! + \reimp +*/ + +QString QtColorPropertyManager::valueText(const QtProperty* property) const +{ + const QtColorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + return QtPropertyBrowserUtils::colorValueText(it.value()); +} + +/*! + \reimp +*/ + +QIcon QtColorPropertyManager::valueIcon(const QtProperty* property) const +{ + const QtColorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QIcon(); + return QtPropertyBrowserUtils::brushValueIcon(QBrush(it.value())); +} + +/*! + \fn void QtColorPropertyManager::setValue(QtProperty *property, const QColor &value) + + Sets the value of the given \a property to \a value. Nested + properties are updated automatically. + + \sa value(), valueChanged() +*/ +void QtColorPropertyManager::setValue(QtProperty* property, const QColor& val) +{ + const QtColorPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + if (it.value() == val) + return; + + it.value() = val; + + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToR[property], val.red()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToG[property], val.green()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToB[property], val.blue()); + d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToA[property], val.alpha()); + + emit propertyChanged(property); + emit valueChanged(property, val); +} + +/*! + \reimp +*/ +void QtColorPropertyManager::initializeProperty(QtProperty* property) +{ + QColor val; + d_ptr->m_values[property] = val; + + QtProperty* rProp = d_ptr->m_intPropertyManager->addProperty(); + rProp->setPropertyName(tr("Red")); + d_ptr->m_intPropertyManager->setValueOnly(rProp, val.red()); + d_ptr->m_intPropertyManager->setRange(rProp, 0, 0xFF); + d_ptr->m_propertyToR[property] = rProp; + d_ptr->m_rToProperty[rProp] = property; + property->addSubProperty(rProp); + + QtProperty* gProp = d_ptr->m_intPropertyManager->addProperty(); + gProp->setPropertyName(tr("Green")); + d_ptr->m_intPropertyManager->setValueOnly(gProp, val.green()); + d_ptr->m_intPropertyManager->setRange(gProp, 0, 0xFF); + d_ptr->m_propertyToG[property] = gProp; + d_ptr->m_gToProperty[gProp] = property; + property->addSubProperty(gProp); + + QtProperty* bProp = d_ptr->m_intPropertyManager->addProperty(); + bProp->setPropertyName(tr("Blue")); + d_ptr->m_intPropertyManager->setValueOnly(bProp, val.blue()); + d_ptr->m_intPropertyManager->setRange(bProp, 0, 0xFF); + d_ptr->m_propertyToB[property] = bProp; + d_ptr->m_bToProperty[bProp] = property; + property->addSubProperty(bProp); + + QtProperty* aProp = d_ptr->m_intPropertyManager->addProperty(); + aProp->setPropertyName(tr("Alpha")); + d_ptr->m_intPropertyManager->setValueOnly(aProp, val.alpha()); + d_ptr->m_intPropertyManager->setRange(aProp, 0, 0xFF); + d_ptr->m_propertyToA[property] = aProp; + d_ptr->m_aToProperty[aProp] = property; + property->addSubProperty(aProp); +} + +/*! + \reimp +*/ +void QtColorPropertyManager::uninitializeProperty(QtProperty* property) +{ + QtProperty* rProp = d_ptr->m_propertyToR[property]; + if (rProp) { + d_ptr->m_rToProperty.remove(rProp); + delete rProp; + } + d_ptr->m_propertyToR.remove(property); + + QtProperty* gProp = d_ptr->m_propertyToG[property]; + if (gProp) { + d_ptr->m_gToProperty.remove(gProp); + delete gProp; + } + d_ptr->m_propertyToG.remove(property); + + QtProperty* bProp = d_ptr->m_propertyToB[property]; + if (bProp) { + d_ptr->m_bToProperty.remove(bProp); + delete bProp; + } + d_ptr->m_propertyToB.remove(property); + + QtProperty* aProp = d_ptr->m_propertyToA[property]; + if (aProp) { + d_ptr->m_aToProperty.remove(aProp); + delete aProp; + } + d_ptr->m_propertyToA.remove(property); + + d_ptr->m_values.remove(property); +} + +#pragma endregion + +// QtCursorPropertyManager +#pragma region QtCursorPropertyManager + +// Make sure icons are removed as soon as QApplication is destroyed, otherwise, +// handles are leaked on X11. +static void clearCursorDatabase(); +namespace { + struct CursorDatabase : public QtCursorDatabase + { + CursorDatabase() + { + qAddPostRoutine(clearCursorDatabase); + } + }; +} +Q_GLOBAL_STATIC(QtCursorDatabase, cursorDatabase) + +static void clearCursorDatabase() +{ + cursorDatabase()->clear(); +} + +class QtCursorPropertyManagerPrivate +{ + QtCursorPropertyManager* q_ptr; + Q_DECLARE_PUBLIC(QtCursorPropertyManager) +public: + typedef QMap PropertyValueMap; + PropertyValueMap m_values; +}; + +/*! + \class QtCursorPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtCursorPropertyManager provides and manages QCursor properties. + + A cursor property has a current value which can be + retrieved using the value() function, and set using the setValue() + slot. In addition, QtCursorPropertyManager provides the + valueChanged() signal which is emitted whenever a property created + by this manager changes. + + \sa QtAbstractPropertyManager +*/ + +/*! + \fn void QtCursorPropertyManager::valueChanged(QtProperty *property, const QCursor &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the new + \a value as parameters. + + \sa setValue() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtCursorPropertyManager::QtCursorPropertyManager(QObject* parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtCursorPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtCursorPropertyManager::~QtCursorPropertyManager() +{ + clear(); +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns a default QCursor object. + + \sa setValue() +*/ +#ifndef QT_NO_CURSOR +QCursor QtCursorPropertyManager::value(const QtProperty* property) const +{ + return d_ptr->m_values.value(property, QCursor()); +} +#endif + +/*! + \reimp +*/ +QString QtCursorPropertyManager::valueText(const QtProperty* property) const +{ + const QtCursorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QString(); + + return cursorDatabase()->cursorToShapeName(it.value()); +} + +/*! + \reimp +*/ +QIcon QtCursorPropertyManager::valueIcon(const QtProperty* property) const +{ + const QtCursorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property); + if (it == d_ptr->m_values.constEnd()) + return QIcon(); + + return cursorDatabase()->cursorToShapeIcon(it.value()); +} + +/*! + \fn void QtCursorPropertyManager::setValue(QtProperty *property, const QCursor &value) + + Sets the value of the given \a property to \a value. + + \sa value(), valueChanged() +*/ +void QtCursorPropertyManager::setValue(QtProperty* property, const QCursor& value) +{ +#ifndef QT_NO_CURSOR + const QtCursorPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); + if (it == d_ptr->m_values.end()) + return; + + if (it.value().shape() == value.shape() && value.shape() != Qt::BitmapCursor) + return; + + it.value() = value; + + emit propertyChanged(property); + emit valueChanged(property, value); +#endif +} + +/*! + \reimp +*/ +void QtCursorPropertyManager::initializeProperty(QtProperty* property) +{ +#ifndef QT_NO_CURSOR + d_ptr->m_values[property] = QCursor(); +#endif +} + +/*! + \reimp +*/ +void QtCursorPropertyManager::uninitializeProperty(QtProperty* property) +{ + d_ptr->m_values.remove(property); +} + +#pragma endregion + +QT_END_NAMESPACE + +#include "moc_qtpropertymanager.cpp" +#include "qtpropertymanager.moc" diff --git a/external/QtPropertyBrowser/src/qtpropertymanager.h b/external/QtPropertyBrowser/src/qtpropertymanager.h new file mode 100644 index 000000000..78fed96ba --- /dev/null +++ b/external/QtPropertyBrowser/src/qtpropertymanager.h @@ -0,0 +1,850 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTPROPERTYMANAGER_H +#define QTPROPERTYMANAGER_H + +#include "qtpropertybrowser.h" + +QT_BEGIN_NAMESPACE + +class QDate; +class QTime; +class QDateTime; +class QLocale; +class QRegularExpression; + +#pragma region QtGroupPropertyManager + +class QT_QTPROPERTYBROWSER_EXPORT QtGroupPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtGroupPropertyManager(QObject* parent = 0); + ~QtGroupPropertyManager(); + +protected: + bool hasValue(const QtProperty* property) const override; + + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +}; + +#pragma endregion + +#pragma region QtIntPropertyManager + +class QtIntPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtIntPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtIntPropertyManager(QObject* parent = 0); + ~QtIntPropertyManager(); + + int value(const QtProperty* property) const; + int initialValue(const QtProperty* property) const; + int minimum(const QtProperty* property) const; + int maximum(const QtProperty* property) const; + int singleStep(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, int val); + void setValueOnly(QtProperty* property, int val); + void setMinimum(QtProperty* property, int minVal); + void setMaximum(QtProperty* property, int maxVal); + void setRange(QtProperty* property, int minVal, int maxVal); + void setSingleStep(QtProperty* property, int step); +Q_SIGNALS: + void valueChanged(QtProperty* property, int val); + void rangeChanged(QtProperty* property, int minVal, int maxVal); + void singleStepChanged(QtProperty* property, int step); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtIntPropertyManager) + Q_DISABLE_COPY_MOVE(QtIntPropertyManager) +}; +#pragma endregion + +#pragma region QtBoolPropertyManager + +class QtBoolPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtBoolPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtBoolPropertyManager(QObject* parent = 0); + ~QtBoolPropertyManager(); + + bool value(const QtProperty* property) const; + bool initialValue(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, bool val); + void setValueOnly(QtProperty* property, bool val); +Q_SIGNALS: + void valueChanged(QtProperty* property, bool val); +protected: + QString valueText(const QtProperty* property) const override; + QIcon valueIcon(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtBoolPropertyManager) + Q_DISABLE_COPY_MOVE(QtBoolPropertyManager) +}; + +#pragma endregion + +#pragma region QtDoublePropertyManager + +class QtDoublePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDoublePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtDoublePropertyManager(QObject* parent = 0); + ~QtDoublePropertyManager(); + + double value(const QtProperty* property) const; + double initialValue(const QtProperty* property) const; + double minimum(const QtProperty* property) const; + double maximum(const QtProperty* property) const; + double singleStep(const QtProperty* property) const; + int decimals(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, double val); + void setValueOnly(QtProperty* property, double val); + void setMinimum(QtProperty* property, double minVal); + void setMaximum(QtProperty* property, double maxVal); + void setRange(QtProperty* property, double minVal, double maxVal); + void setSingleStep(QtProperty* property, double step); + void setDecimals(QtProperty* property, int prec); +Q_SIGNALS: + void valueChanged(QtProperty* property, double val); + void rangeChanged(QtProperty* property, double minVal, double maxVal); + void singleStepChanged(QtProperty* property, double step); + void decimalsChanged(QtProperty* property, int prec); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtDoublePropertyManager) + Q_DISABLE_COPY_MOVE(QtDoublePropertyManager) +}; + +#pragma endregion + +#pragma region QtStringPropertyManager + +class QtStringPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtStringPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtStringPropertyManager(QObject* parent = 0); + ~QtStringPropertyManager(); + + QString value(const QtProperty* property) const; + QString initialValue(const QtProperty* property) const; + QRegularExpression regExp(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, const QString& val); + void setValueOnly(QtProperty* property, const QString& val); + void setRegExp(QtProperty* property, const QRegularExpression& regExp); +Q_SIGNALS: + void valueChanged(QtProperty* property, const QString& val); + void regExpChanged(QtProperty* property, const QRegularExpression& regExp); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtStringPropertyManager) + Q_DISABLE_COPY_MOVE(QtStringPropertyManager) +}; + +#pragma endregion + +#pragma region QtDatePropertyManager + +class QtDatePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDatePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtDatePropertyManager(QObject* parent = 0); + ~QtDatePropertyManager(); + + QDate value(const QtProperty* property) const; + QDate initialValue(const QtProperty* property) const; + QDate minimum(const QtProperty* property) const; + QDate maximum(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, QDate val); + void setValueOnly(QtProperty* property, QDate val); + void setMinimum(QtProperty* property, QDate minVal); + void setMaximum(QtProperty* property, QDate maxVal); + void setRange(QtProperty* property, QDate minVal, QDate maxVal); +Q_SIGNALS: + void valueChanged(QtProperty* property, QDate val); + void rangeChanged(QtProperty* property, QDate minVal, QDate maxVal); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtDatePropertyManager) + Q_DISABLE_COPY_MOVE(QtDatePropertyManager) +}; + +#pragma endregion + +#pragma region QtTimePropertyManager + +class QtTimePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtTimePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtTimePropertyManager(QObject* parent = 0); + ~QtTimePropertyManager(); + + QTime value(const QtProperty* property) const; + QTime initialValue(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, QTime val); + void setValueOnly(QtProperty* property, QTime val); +Q_SIGNALS: + void valueChanged(QtProperty* property, QTime val); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtTimePropertyManager) + Q_DISABLE_COPY_MOVE(QtTimePropertyManager) +}; + +#pragma endregion + +#pragma region QtDateTimePropertyManager + +class QtDateTimePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtDateTimePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtDateTimePropertyManager(QObject* parent = 0); + ~QtDateTimePropertyManager(); + + QDateTime value(const QtProperty* property) const; + QDateTime initialValue(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, const QDateTime& val); + void setValueOnly(QtProperty* property, const QDateTime& val); +Q_SIGNALS: + void valueChanged(QtProperty* property, const QDateTime& val); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtDateTimePropertyManager) + Q_DISABLE_COPY_MOVE(QtDateTimePropertyManager) +}; + +#pragma endregion + +#pragma region QtKeySequencePropertyManager + +class QtKeySequencePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtKeySequencePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtKeySequencePropertyManager(QObject* parent = 0); + ~QtKeySequencePropertyManager(); + + QKeySequence value(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, const QKeySequence& val); +Q_SIGNALS: + void valueChanged(QtProperty* property, const QKeySequence& val); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtKeySequencePropertyManager) + Q_DISABLE_COPY_MOVE(QtKeySequencePropertyManager) +}; + +#pragma endregion + +#pragma region QtCharPropertyManager + +class QtCharPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtCharPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtCharPropertyManager(QObject* parent = 0); + ~QtCharPropertyManager(); + + QChar value(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, const QChar& val); +Q_SIGNALS: + void valueChanged(QtProperty* property, const QChar& val); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtCharPropertyManager) + Q_DISABLE_COPY_MOVE(QtCharPropertyManager) +}; + +#pragma endregion + +#pragma region QtLocalePropertyManager + +class QtEnumPropertyManager; +class QtLocalePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtLocalePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtLocalePropertyManager(QObject* parent = 0); + ~QtLocalePropertyManager(); + + QtEnumPropertyManager* subEnumPropertyManager() const; + + QLocale value(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, const QLocale& val); +Q_SIGNALS: + void valueChanged(QtProperty* property, const QLocale& val); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtLocalePropertyManager) + Q_DISABLE_COPY_MOVE(QtLocalePropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty*, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty*)) +}; + +#pragma endregion + +#pragma region QtPointPropertyManager + +class QtPointPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtPointPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtPointPropertyManager(QObject* parent = 0); + ~QtPointPropertyManager(); + + QtIntPropertyManager* subIntPropertyManager() const; + + QPoint value(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, const QPoint& val); +Q_SIGNALS: + void valueChanged(QtProperty* property, const QPoint& val); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtPointPropertyManager) + Q_DISABLE_COPY_MOVE(QtPointPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty*, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty*)) +}; + +#pragma endregion + +#pragma region QtPointFPropertyManager + +class QtPointFPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtPointFPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtPointFPropertyManager(QObject* parent = 0); + ~QtPointFPropertyManager(); + + QtDoublePropertyManager* subDoublePropertyManager() const; + + QPointF value(const QtProperty* property) const; + int decimals(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, const QPointF& val); + void setDecimals(QtProperty* property, int prec); +Q_SIGNALS: + void valueChanged(QtProperty* property, const QPointF& val); + void decimalsChanged(QtProperty* property, int prec); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtPointFPropertyManager) + Q_DISABLE_COPY_MOVE(QtPointFPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty*, double)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty*)) +}; + +#pragma endregion + +#pragma region QtSizePropertyManager + +class QtSizePropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtSizePropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtSizePropertyManager(QObject* parent = 0); + ~QtSizePropertyManager(); + + QtIntPropertyManager* subIntPropertyManager() const; + + QSize value(const QtProperty* property) const; + QSize minimum(const QtProperty* property) const; + QSize maximum(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, const QSize& val); + void setMinimum(QtProperty* property, const QSize& minVal); + void setMaximum(QtProperty* property, const QSize& maxVal); + void setRange(QtProperty* property, const QSize& minVal, const QSize& maxVal); +Q_SIGNALS: + void valueChanged(QtProperty* property, const QSize& val); + void rangeChanged(QtProperty* property, const QSize& minVal, const QSize& maxVal); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtSizePropertyManager) + Q_DISABLE_COPY_MOVE(QtSizePropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty*, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty*)) +}; + +#pragma endregion + +#pragma region QtSizeFPropertyManager + +class QtSizeFPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtSizeFPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtSizeFPropertyManager(QObject* parent = 0); + ~QtSizeFPropertyManager(); + + QtDoublePropertyManager* subDoublePropertyManager() const; + + QSizeF value(const QtProperty* property) const; + QSizeF minimum(const QtProperty* property) const; + QSizeF maximum(const QtProperty* property) const; + int decimals(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, const QSizeF& val); + void setMinimum(QtProperty* property, const QSizeF& minVal); + void setMaximum(QtProperty* property, const QSizeF& maxVal); + void setRange(QtProperty* property, const QSizeF& minVal, const QSizeF& maxVal); + void setDecimals(QtProperty* property, int prec); +Q_SIGNALS: + void valueChanged(QtProperty* property, const QSizeF& val); + void rangeChanged(QtProperty* property, const QSizeF& minVal, const QSizeF& maxVal); + void decimalsChanged(QtProperty* property, int prec); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtSizeFPropertyManager) + Q_DISABLE_COPY_MOVE(QtSizeFPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty*, double)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty*)) +}; + +#pragma endregion + +#pragma region QtRectPropertyManager + +class QtRectPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtRectPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtRectPropertyManager(QObject* parent = 0); + ~QtRectPropertyManager(); + + QtIntPropertyManager* subIntPropertyManager() const; + + QRect value(const QtProperty* property) const; + QRect constraint(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, const QRect& val); + void setConstraint(QtProperty* property, const QRect& constraint); +Q_SIGNALS: + void valueChanged(QtProperty* property, const QRect& val); + void constraintChanged(QtProperty* property, const QRect& constraint); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtRectPropertyManager) + Q_DISABLE_COPY_MOVE(QtRectPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty*, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty*)) +}; + +#pragma endregion + +#pragma region QtRectFPropertyManager + +class QtRectFPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtRectFPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtRectFPropertyManager(QObject* parent = 0); + ~QtRectFPropertyManager(); + + QtDoublePropertyManager* subDoublePropertyManager() const; + + QRectF value(const QtProperty* property) const; + QRectF constraint(const QtProperty* property) const; + int decimals(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, const QRectF& val); + void setConstraint(QtProperty* property, const QRectF& constraint); + void setDecimals(QtProperty* property, int prec); +Q_SIGNALS: + void valueChanged(QtProperty* property, const QRectF& val); + void constraintChanged(QtProperty* property, const QRectF& constraint); + void decimalsChanged(QtProperty* property, int prec); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtRectFPropertyManager) + Q_DISABLE_COPY_MOVE(QtRectFPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty*, double)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty*)) +}; + +#pragma endregion + +#pragma region QtEnumPropertyManager + +class QtEnumPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtEnumPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtEnumPropertyManager(QObject* parent = 0); + ~QtEnumPropertyManager(); + + int value(const QtProperty* property) const; + QStringList enumNames(const QtProperty* property) const; + QMap enumIcons(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, int val); + void setEnumNames(QtProperty* property, const QStringList& names); + void setEnumIcons(QtProperty* property, const QMap& icons); +Q_SIGNALS: + void valueChanged(QtProperty* property, int val); + void enumNamesChanged(QtProperty* property, const QStringList& names); + void enumIconsChanged(QtProperty* property, const QMap& icons); +protected: + QString valueText(const QtProperty* property) const override; + QIcon valueIcon(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtEnumPropertyManager) + Q_DISABLE_COPY_MOVE(QtEnumPropertyManager) +}; + +#pragma endregion + +#pragma region QtFlagPropertyManager + +class QtFlagPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtFlagPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtFlagPropertyManager(QObject* parent = 0); + ~QtFlagPropertyManager(); + + QtBoolPropertyManager* subBoolPropertyManager() const; + + int value(const QtProperty* property) const; + QStringList flagNames(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, int val); + void setFlagNames(QtProperty* property, const QStringList& names); +Q_SIGNALS: + void valueChanged(QtProperty* property, int val); + void flagNamesChanged(QtProperty* property, const QStringList& names); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtFlagPropertyManager) + Q_DISABLE_COPY_MOVE(QtFlagPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotBoolChanged(QtProperty*, bool)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty*)) +}; + +#pragma endregion + +#pragma region QtSizePolicyPropertyManager + +class QtSizePolicyPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtSizePolicyPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtSizePolicyPropertyManager(QObject* parent = 0); + ~QtSizePolicyPropertyManager(); + + QtIntPropertyManager* subIntPropertyManager() const; + QtEnumPropertyManager* subEnumPropertyManager() const; + + QSizePolicy value(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, const QSizePolicy& val); +Q_SIGNALS: + void valueChanged(QtProperty* property, const QSizePolicy& val); +protected: + QString valueText(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtSizePolicyPropertyManager) + Q_DISABLE_COPY_MOVE(QtSizePolicyPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty*, int)) + Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty*, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty*)) +}; + +#pragma endregion + +#pragma region QtFontPropertyManager + +class QtFontPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtFontPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtFontPropertyManager(QObject* parent = 0); + ~QtFontPropertyManager(); + + QtIntPropertyManager* subIntPropertyManager() const; + QtEnumPropertyManager* subEnumPropertyManager() const; + QtBoolPropertyManager* subBoolPropertyManager() const; + + QFont value(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, const QFont& val); +Q_SIGNALS: + void valueChanged(QtProperty* property, const QFont& val); +protected: + QString valueText(const QtProperty* property) const override; + QIcon valueIcon(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtFontPropertyManager) + Q_DISABLE_COPY_MOVE(QtFontPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty*, int)) + Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty*, int)) + Q_PRIVATE_SLOT(d_func(), void slotBoolChanged(QtProperty*, bool)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty*)) + Q_PRIVATE_SLOT(d_func(), void slotFontDatabaseChanged()) + Q_PRIVATE_SLOT(d_func(), void slotFontDatabaseDelayedChange()) +}; + +#pragma endregion + +#pragma region QtColorPropertyManager + +class QtColorPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtColorPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtColorPropertyManager(QObject* parent = 0); + ~QtColorPropertyManager(); + + QtIntPropertyManager* subIntPropertyManager() const; + + QColor value(const QtProperty* property) const; + +public Q_SLOTS: + void setValue(QtProperty* property, const QColor& val); +Q_SIGNALS: + void valueChanged(QtProperty* property, const QColor& val); +protected: + QString valueText(const QtProperty* property) const override; + QIcon valueIcon(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtColorPropertyManager) + Q_DISABLE_COPY_MOVE(QtColorPropertyManager) + Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty*, int)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty*)) +}; + +#pragma endregion + +#pragma region QtCursorPropertyManager + +class QtCursorPropertyManagerPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtCursorPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtCursorPropertyManager(QObject* parent = 0); + ~QtCursorPropertyManager(); + +#ifndef QT_NO_CURSOR + QCursor value(const QtProperty* property) const; +#endif + +public Q_SLOTS: + void setValue(QtProperty* property, const QCursor& val); +Q_SIGNALS: + void valueChanged(QtProperty* property, const QCursor& val); +protected: + QString valueText(const QtProperty* property) const override; + QIcon valueIcon(const QtProperty* property) const override; + void initializeProperty(QtProperty* property) override; + void uninitializeProperty(QtProperty* property) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtCursorPropertyManager) + Q_DISABLE_COPY_MOVE(QtCursorPropertyManager) +}; + +#pragma endregion + +QT_END_NAMESPACE + +#endif diff --git a/external/QtPropertyBrowser/src/qttreepropertybrowser.cpp b/external/QtPropertyBrowser/src/qttreepropertybrowser.cpp new file mode 100644 index 000000000..fb77ee6eb --- /dev/null +++ b/external/QtPropertyBrowser/src/qttreepropertybrowser.cpp @@ -0,0 +1,1037 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qttreepropertybrowser.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QtPropertyEditorView; + +class QtTreePropertyBrowserPrivate +{ + QtTreePropertyBrowser *q_ptr; + Q_DECLARE_PUBLIC(QtTreePropertyBrowser) + +public: + QtTreePropertyBrowserPrivate(); + void init(QWidget *parent); + + void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex); + void propertyRemoved(QtBrowserItem *index); + void propertyChanged(QtBrowserItem *index); + QWidget *createEditor(QtProperty *property, QWidget *parent) const + { return q_ptr->createEditor(property, parent); } + QtProperty *indexToProperty(const QModelIndex &index) const; + QTreeWidgetItem *indexToItem(const QModelIndex &index) const; + QtBrowserItem *indexToBrowserItem(const QModelIndex &index) const; + bool lastColumn(int column) const; + void disableItem(QTreeWidgetItem *item) const; + void enableItem(QTreeWidgetItem *item) const; + bool hasValue(QTreeWidgetItem *item) const; + + void slotCollapsed(const QModelIndex &index); + void slotExpanded(const QModelIndex &index); + + QColor calculatedBackgroundColor(QtBrowserItem *item) const; + + QtPropertyEditorView *treeWidget() const { return m_treeWidget; } + bool markPropertiesWithoutValue() const { return m_markPropertiesWithoutValue; } + + QtBrowserItem *currentItem() const; + void setCurrentItem(QtBrowserItem *browserItem, bool block); + void editItem(QtBrowserItem *browserItem); + + void slotCurrentBrowserItemChanged(QtBrowserItem *item); + void slotCurrentTreeItemChanged(QTreeWidgetItem *newItem, QTreeWidgetItem *); + + QTreeWidgetItem *editedItem() const; + +private: + void updateItem(QTreeWidgetItem *item); + + QMap m_indexToItem; + QMap m_itemToIndex; + + QMap m_indexToBackgroundColor; + + QtPropertyEditorView *m_treeWidget; + + bool m_headerVisible; + QtTreePropertyBrowser::ResizeMode m_resizeMode; + class QtPropertyEditorDelegate *m_delegate; + bool m_markPropertiesWithoutValue; + bool m_browserChangedBlocked; + QIcon m_expandIcon; +}; + +// ------------ QtPropertyEditorView +class QtPropertyEditorView : public QTreeWidget +{ + Q_OBJECT +public: + QtPropertyEditorView(QWidget *parent = 0); + + void setEditorPrivate(QtTreePropertyBrowserPrivate *editorPrivate) + { m_editorPrivate = editorPrivate; } + + QTreeWidgetItem *indexToItem(const QModelIndex &index) const + { return itemFromIndex(index); } + +protected: + void keyPressEvent(QKeyEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + +private: + QtTreePropertyBrowserPrivate *m_editorPrivate; +}; + +QtPropertyEditorView::QtPropertyEditorView(QWidget *parent) : + QTreeWidget(parent), + m_editorPrivate(0) +{ + connect(header(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(resizeColumnToContents(int))); +} + +void QtPropertyEditorView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyleOptionViewItem opt = option; + bool hasValue = true; + if (m_editorPrivate) { + QtProperty *property = m_editorPrivate->indexToProperty(index); + if (property) + hasValue = property->hasValue(); + } + if (!hasValue && m_editorPrivate->markPropertiesWithoutValue()) { + const QColor c = option.palette.color(QPalette::Dark); + painter->fillRect(option.rect, c); + opt.palette.setColor(QPalette::AlternateBase, c); + } else { + const QColor c = m_editorPrivate->calculatedBackgroundColor(m_editorPrivate->indexToBrowserItem(index)); + if (c.isValid()) { + painter->fillRect(option.rect, c); + opt.palette.setColor(QPalette::AlternateBase, c.lighter(112)); + } + } + QTreeWidget::drawRow(painter, opt, index); + QColor color = static_cast(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt)); + painter->save(); + painter->setPen(QPen(color)); + painter->drawLine(opt.rect.x(), opt.rect.bottom(), opt.rect.right(), opt.rect.bottom()); + painter->restore(); +} + +void QtPropertyEditorView::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Return: + case Qt::Key_Enter: + case Qt::Key_Space: // Trigger Edit + if (!m_editorPrivate->editedItem()) + if (const QTreeWidgetItem *item = currentItem()) + if (item->columnCount() >= 2 && ((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled))) { + event->accept(); + // If the current position is at column 0, move to 1. + QModelIndex index = currentIndex(); + if (index.column() == 0) { + index = index.sibling(index.row(), 1); + setCurrentIndex(index); + } + edit(index); + return; + } + break; + default: + break; + } + QTreeWidget::keyPressEvent(event); +} + +void QtPropertyEditorView::mousePressEvent(QMouseEvent *event) +{ + QTreeWidget::mousePressEvent(event); + QTreeWidgetItem *item = itemAt(event->position().toPoint()); + + if (item) { + if ((item != m_editorPrivate->editedItem()) && (event->button() == Qt::LeftButton) + && (header()->logicalIndexAt(event->position().toPoint().x()) == 1) + && ((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled))) { + editItem(item, 1); + } else if (!m_editorPrivate->hasValue(item) && m_editorPrivate->markPropertiesWithoutValue() && !rootIsDecorated()) { + if (event->position().toPoint().x() + header()->offset() < 20) + item->setExpanded(!item->isExpanded()); + } + } +} + +// ------------ QtPropertyEditorDelegate +class QtPropertyEditorDelegate : public QItemDelegate +{ + Q_OBJECT +public: + QtPropertyEditorDelegate(QObject *parent = 0) + : QItemDelegate(parent), m_editorPrivate(0), m_editedItem(0), m_editedWidget(0) + {} + + void setEditorPrivate(QtTreePropertyBrowserPrivate *editorPrivate) + { m_editorPrivate = editorPrivate; } + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; + + void setModelData(QWidget *, QAbstractItemModel *, + const QModelIndex &) const override {} + + void setEditorData(QWidget *, const QModelIndex &) const override {} + + bool eventFilter(QObject *object, QEvent *event) override; + void closeEditor(QtProperty *property); + + QTreeWidgetItem *editedItem() const { return m_editedItem; } + +private slots: + void slotEditorDestroyed(QObject *object); + +private: + int indentation(const QModelIndex &index) const; + + typedef QMap EditorToPropertyMap; + mutable EditorToPropertyMap m_editorToProperty; + + typedef QMap PropertyToEditorMap; + mutable PropertyToEditorMap m_propertyToEditor; + QtTreePropertyBrowserPrivate *m_editorPrivate; + mutable QTreeWidgetItem *m_editedItem; + mutable QWidget *m_editedWidget; +}; + +int QtPropertyEditorDelegate::indentation(const QModelIndex &index) const +{ + if (!m_editorPrivate) + return 0; + + QTreeWidgetItem *item = m_editorPrivate->indexToItem(index); + int indent = 0; + while (item->parent()) { + item = item->parent(); + ++indent; + } + if (m_editorPrivate->treeWidget()->rootIsDecorated()) + ++indent; + return indent * m_editorPrivate->treeWidget()->indentation(); +} + +void QtPropertyEditorDelegate::slotEditorDestroyed(QObject *object) +{ + if (QWidget *w = qobject_cast(object)) { + const EditorToPropertyMap::iterator it = m_editorToProperty.find(w); + if (it != m_editorToProperty.end()) { + m_propertyToEditor.remove(it.value()); + m_editorToProperty.erase(it); + } + if (m_editedWidget == w) { + m_editedWidget = 0; + m_editedItem = 0; + } + } +} + +void QtPropertyEditorDelegate::closeEditor(QtProperty *property) +{ + if (QWidget *w = m_propertyToEditor.value(property, 0)) + w->deleteLater(); +} + +QWidget *QtPropertyEditorDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem &, const QModelIndex &index) const +{ + if (index.column() == 1 && m_editorPrivate) { + QtProperty *property = m_editorPrivate->indexToProperty(index); + QTreeWidgetItem *item = m_editorPrivate->indexToItem(index); + if (property && item && (item->flags() & Qt::ItemIsEnabled)) { + QWidget *editor = m_editorPrivate->createEditor(property, parent); + if (editor) { + editor->setAutoFillBackground(true); + editor->installEventFilter(const_cast(this)); + connect(editor, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*))); + m_propertyToEditor[property] = editor; + m_editorToProperty[editor] = property; + m_editedItem = item; + m_editedWidget = editor; + } + return editor; + } + } + return 0; +} + +void QtPropertyEditorDelegate::updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index); + editor->setGeometry(option.rect.adjusted(0, 0, 0, -1)); +} + +void QtPropertyEditorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + bool hasValue = true; + if (m_editorPrivate) { + QtProperty *property = m_editorPrivate->indexToProperty(index); + if (property) + hasValue = property->hasValue(); + } + QStyleOptionViewItem opt = option; + if ((m_editorPrivate && index.column() == 0) || !hasValue) { + QtProperty *property = m_editorPrivate->indexToProperty(index); + if (property && property->isModified()) { + opt.font.setBold(true); + opt.fontMetrics = QFontMetrics(opt.font); + } + } + QColor c; + if (!hasValue && m_editorPrivate->markPropertiesWithoutValue()) { + c = opt.palette.color(QPalette::Dark); + opt.palette.setColor(QPalette::Text, opt.palette.color(QPalette::BrightText)); + } else { + c = m_editorPrivate->calculatedBackgroundColor(m_editorPrivate->indexToBrowserItem(index)); + if (c.isValid() && (opt.features & QStyleOptionViewItem::Alternate)) + c = c.lighter(112); + } + if (c.isValid()) + painter->fillRect(option.rect, c); + opt.state &= ~QStyle::State_HasFocus; + QItemDelegate::paint(painter, opt, index); + + opt.palette.setCurrentColorGroup(QPalette::Active); + QColor color = static_cast(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt)); + painter->save(); + painter->setPen(QPen(color)); + if (!m_editorPrivate || (!m_editorPrivate->lastColumn(index.column()) && hasValue)) { + int right = (option.direction == Qt::LeftToRight) ? option.rect.right() : option.rect.left(); + painter->drawLine(right, option.rect.y(), right, option.rect.bottom()); + } + painter->restore(); +} + +QSize QtPropertyEditorDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + return QItemDelegate::sizeHint(option, index) + QSize(3, 4); +} + +bool QtPropertyEditorDelegate::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::FocusOut) { + QFocusEvent *fe = static_cast(event); + if (fe->reason() == Qt::ActiveWindowFocusReason) + return false; + } + return QItemDelegate::eventFilter(object, event); +} + +// -------- QtTreePropertyBrowserPrivate implementation +QtTreePropertyBrowserPrivate::QtTreePropertyBrowserPrivate() : + m_treeWidget(0), + m_headerVisible(true), + m_resizeMode(QtTreePropertyBrowser::Stretch), + m_delegate(0), + m_markPropertiesWithoutValue(false), + m_browserChangedBlocked(false) +{ +} + +// Draw an icon indicating opened/closing branches +static QIcon drawIndicatorIcon(const QPalette &palette, QStyle *style) +{ + QPixmap pix(14, 14); + pix.fill(Qt::transparent); + QStyleOption branchOption; + branchOption.rect = QRect(2, 2, 9, 9); // ### hardcoded in qcommonstyle.cpp + branchOption.palette = palette; + branchOption.state = QStyle::State_Children; + + QPainter p; + // Draw closed state + p.begin(&pix); + style->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, &p); + p.end(); + QIcon rc = pix; + rc.addPixmap(pix, QIcon::Selected, QIcon::Off); + // Draw opened state + branchOption.state |= QStyle::State_Open; + pix.fill(Qt::transparent); + p.begin(&pix); + style->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, &p); + p.end(); + + rc.addPixmap(pix, QIcon::Normal, QIcon::On); + rc.addPixmap(pix, QIcon::Selected, QIcon::On); + return rc; +} + +void QtTreePropertyBrowserPrivate::init(QWidget *parent) +{ + QHBoxLayout *layout = new QHBoxLayout(parent); + layout->setContentsMargins(QMargins()); + m_treeWidget = new QtPropertyEditorView(parent); + m_treeWidget->setEditorPrivate(this); + m_treeWidget->setIconSize(QSize(18, 18)); + layout->addWidget(m_treeWidget); + + m_treeWidget->setColumnCount(2); + QStringList labels; + labels.append(QCoreApplication::translate("QtTreePropertyBrowser", "Property")); + labels.append(QCoreApplication::translate("QtTreePropertyBrowser", "Value")); + m_treeWidget->setHeaderLabels(labels); + m_treeWidget->setAlternatingRowColors(true); + m_treeWidget->setEditTriggers(QAbstractItemView::EditKeyPressed); + m_delegate = new QtPropertyEditorDelegate(parent); + m_delegate->setEditorPrivate(this); + m_treeWidget->setItemDelegate(m_delegate); + m_treeWidget->header()->setSectionsMovable(false); + m_treeWidget->header()->setSectionResizeMode(QHeaderView::Stretch); + + m_expandIcon = drawIndicatorIcon(q_ptr->palette(), q_ptr->style()); + + QObject::connect(m_treeWidget, SIGNAL(collapsed(QModelIndex)), q_ptr, SLOT(slotCollapsed(QModelIndex))); + QObject::connect(m_treeWidget, SIGNAL(expanded(QModelIndex)), q_ptr, SLOT(slotExpanded(QModelIndex))); + QObject::connect(m_treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), q_ptr, SLOT(slotCurrentTreeItemChanged(QTreeWidgetItem*,QTreeWidgetItem*))); +} + +QtBrowserItem *QtTreePropertyBrowserPrivate::currentItem() const +{ + if (QTreeWidgetItem *treeItem = m_treeWidget->currentItem()) + return m_itemToIndex.value(treeItem); + return 0; +} + +void QtTreePropertyBrowserPrivate::setCurrentItem(QtBrowserItem *browserItem, bool block) +{ + const bool blocked = block ? m_treeWidget->blockSignals(true) : false; + if (browserItem == 0) + m_treeWidget->setCurrentItem(0); + else + m_treeWidget->setCurrentItem(m_indexToItem.value(browserItem)); + if (block) + m_treeWidget->blockSignals(blocked); +} + +QtProperty *QtTreePropertyBrowserPrivate::indexToProperty(const QModelIndex &index) const +{ + QTreeWidgetItem *item = m_treeWidget->indexToItem(index); + QtBrowserItem *idx = m_itemToIndex.value(item); + if (idx) + return idx->property(); + return 0; +} + +QtBrowserItem *QtTreePropertyBrowserPrivate::indexToBrowserItem(const QModelIndex &index) const +{ + QTreeWidgetItem *item = m_treeWidget->indexToItem(index); + return m_itemToIndex.value(item); +} + +QTreeWidgetItem *QtTreePropertyBrowserPrivate::indexToItem(const QModelIndex &index) const +{ + return m_treeWidget->indexToItem(index); +} + +bool QtTreePropertyBrowserPrivate::lastColumn(int column) const +{ + return m_treeWidget->header()->visualIndex(column) == m_treeWidget->columnCount() - 1; +} + +void QtTreePropertyBrowserPrivate::disableItem(QTreeWidgetItem *item) const +{ + Qt::ItemFlags flags = item->flags(); + if (flags & Qt::ItemIsEnabled) { + flags &= ~Qt::ItemIsEnabled; + item->setFlags(flags); + m_delegate->closeEditor(m_itemToIndex[item]->property()); + const int childCount = item->childCount(); + for (int i = 0; i < childCount; i++) { + QTreeWidgetItem *child = item->child(i); + disableItem(child); + } + } +} + +void QtTreePropertyBrowserPrivate::enableItem(QTreeWidgetItem *item) const +{ + Qt::ItemFlags flags = item->flags(); + flags |= Qt::ItemIsEnabled; + item->setFlags(flags); + const int childCount = item->childCount(); + for (int i = 0; i < childCount; i++) { + QTreeWidgetItem *child = item->child(i); + QtProperty *property = m_itemToIndex[child]->property(); + if (property->isEnabled()) { + enableItem(child); + } + } +} + +bool QtTreePropertyBrowserPrivate::hasValue(QTreeWidgetItem *item) const +{ + QtBrowserItem *browserItem = m_itemToIndex.value(item); + if (browserItem) + return browserItem->property()->hasValue(); + return false; +} + +void QtTreePropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex) +{ + QTreeWidgetItem *afterItem = m_indexToItem.value(afterIndex); + QTreeWidgetItem *parentItem = m_indexToItem.value(index->parent()); + + QTreeWidgetItem *newItem = 0; + if (parentItem) { + newItem = new QTreeWidgetItem(parentItem, afterItem); + } else { + newItem = new QTreeWidgetItem(m_treeWidget, afterItem); + } + m_itemToIndex[newItem] = index; + m_indexToItem[index] = newItem; + + newItem->setFlags(newItem->flags() | Qt::ItemIsEditable); + newItem->setExpanded(true); + + updateItem(newItem); +} + +void QtTreePropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index) +{ + QTreeWidgetItem *item = m_indexToItem.value(index); + + if (m_treeWidget->currentItem() == item) { + m_treeWidget->setCurrentItem(0); + } + + delete item; + + m_indexToItem.remove(index); + m_itemToIndex.remove(item); + m_indexToBackgroundColor.remove(index); +} + +void QtTreePropertyBrowserPrivate::propertyChanged(QtBrowserItem *index) +{ + QTreeWidgetItem *item = m_indexToItem.value(index); + + updateItem(item); +} + +void QtTreePropertyBrowserPrivate::updateItem(QTreeWidgetItem *item) +{ + QtProperty *property = m_itemToIndex[item]->property(); + QIcon expandIcon; + if (property->hasValue()) { + const QString valueToolTip = property->valueToolTip(); + const QString valueText = property->valueText(); + item->setToolTip(1, valueToolTip.isEmpty() ? valueText : valueToolTip); + item->setIcon(1, property->valueIcon()); + item->setText(1, valueText); + } else if (markPropertiesWithoutValue() && !m_treeWidget->rootIsDecorated()) { + expandIcon = m_expandIcon; + } + item->setIcon(0, expandIcon); + item->setFirstColumnSpanned(!property->hasValue()); + const QString descriptionToolTip = property->descriptionToolTip(); + const QString propertyName = property->propertyName(); + item->setToolTip(0, descriptionToolTip.isEmpty() ? propertyName : descriptionToolTip); + item->setStatusTip(0, property->statusTip()); + item->setWhatsThis(0, property->whatsThis()); + item->setText(0, propertyName); + bool wasEnabled = item->flags() & Qt::ItemIsEnabled; + bool isEnabled = wasEnabled; + if (property->isEnabled()) { + QTreeWidgetItem *parent = item->parent(); + if (!parent || (parent->flags() & Qt::ItemIsEnabled)) + isEnabled = true; + else + isEnabled = false; + } else { + isEnabled = false; + } + if (wasEnabled != isEnabled) { + if (isEnabled) + enableItem(item); + else + disableItem(item); + } + m_treeWidget->viewport()->update(); +} + +QColor QtTreePropertyBrowserPrivate::calculatedBackgroundColor(QtBrowserItem *item) const +{ + QtBrowserItem *i = item; + const QMap::const_iterator itEnd = m_indexToBackgroundColor.constEnd(); + while (i) { + QMap::const_iterator it = m_indexToBackgroundColor.constFind(i); + if (it != itEnd) + return it.value(); + i = i->parent(); + } + return QColor(); +} + +void QtTreePropertyBrowserPrivate::slotCollapsed(const QModelIndex &index) +{ + QTreeWidgetItem *item = indexToItem(index); + QtBrowserItem *idx = m_itemToIndex.value(item); + if (item) + emit q_ptr->collapsed(idx); +} + +void QtTreePropertyBrowserPrivate::slotExpanded(const QModelIndex &index) +{ + QTreeWidgetItem *item = indexToItem(index); + QtBrowserItem *idx = m_itemToIndex.value(item); + if (item) + emit q_ptr->expanded(idx); +} + +void QtTreePropertyBrowserPrivate::slotCurrentBrowserItemChanged(QtBrowserItem *item) +{ + if (!m_browserChangedBlocked && item != currentItem()) + setCurrentItem(item, true); +} + +void QtTreePropertyBrowserPrivate::slotCurrentTreeItemChanged(QTreeWidgetItem *newItem, QTreeWidgetItem *) +{ + QtBrowserItem *browserItem = newItem ? m_itemToIndex.value(newItem) : 0; + m_browserChangedBlocked = true; + q_ptr->setCurrentItem(browserItem); + m_browserChangedBlocked = false; +} + +QTreeWidgetItem *QtTreePropertyBrowserPrivate::editedItem() const +{ + return m_delegate->editedItem(); +} + +void QtTreePropertyBrowserPrivate::editItem(QtBrowserItem *browserItem) +{ + if (QTreeWidgetItem *treeItem = m_indexToItem.value(browserItem, 0)) { + m_treeWidget->setCurrentItem (treeItem, 1); + m_treeWidget->editItem(treeItem, 1); + } +} + +/*! + \class QtTreePropertyBrowser + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtTreePropertyBrowser class provides QTreeWidget based + property browser. + + A property browser is a widget that enables the user to edit a + given set of properties. Each property is represented by a label + specifying the property's name, and an editing widget (e.g. a line + edit or a combobox) holding its value. A property can have zero or + more subproperties. + + QtTreePropertyBrowser provides a tree based view for all nested + properties, i.e. properties that have subproperties can be in an + expanded (subproperties are visible) or collapsed (subproperties + are hidden) state. For example: + + \image qttreepropertybrowser.png + + Use the QtAbstractPropertyBrowser API to add, insert and remove + properties from an instance of the QtTreePropertyBrowser class. + The properties themselves are created and managed by + implementations of the QtAbstractPropertyManager class. + + \sa QtGroupBoxPropertyBrowser, QtAbstractPropertyBrowser +*/ + +/*! + \fn void QtTreePropertyBrowser::collapsed(QtBrowserItem *item) + + This signal is emitted when the \a item is collapsed. + + \sa expanded(), setExpanded() +*/ + +/*! + \fn void QtTreePropertyBrowser::expanded(QtBrowserItem *item) + + This signal is emitted when the \a item is expanded. + + \sa collapsed(), setExpanded() +*/ + +/*! + Creates a property browser with the given \a parent. +*/ +QtTreePropertyBrowser::QtTreePropertyBrowser(QWidget *parent) + : QtAbstractPropertyBrowser(parent), d_ptr(new QtTreePropertyBrowserPrivate) +{ + d_ptr->q_ptr = this; + + d_ptr->init(this); + connect(this, SIGNAL(currentItemChanged(QtBrowserItem*)), this, SLOT(slotCurrentBrowserItemChanged(QtBrowserItem*))); +} + +/*! + Destroys this property browser. + + Note that the properties that were inserted into this browser are + \e not destroyed since they may still be used in other + browsers. The properties are owned by the manager that created + them. + + \sa QtProperty, QtAbstractPropertyManager +*/ +QtTreePropertyBrowser::~QtTreePropertyBrowser() +{ +} + +/*! + \property QtTreePropertyBrowser::indentation + \brief indentation of the items in the tree view. +*/ +int QtTreePropertyBrowser::indentation() const +{ + return d_ptr->m_treeWidget->indentation(); +} + +void QtTreePropertyBrowser::setIndentation(int i) +{ + d_ptr->m_treeWidget->setIndentation(i); +} + +/*! + \property QtTreePropertyBrowser::rootIsDecorated + \brief whether to show controls for expanding and collapsing root items. +*/ +bool QtTreePropertyBrowser::rootIsDecorated() const +{ + return d_ptr->m_treeWidget->rootIsDecorated(); +} + +void QtTreePropertyBrowser::setRootIsDecorated(bool show) +{ + d_ptr->m_treeWidget->setRootIsDecorated(show); + for (auto it = d_ptr->m_itemToIndex.cbegin(), end = d_ptr->m_itemToIndex.cend(); it != end; ++it) { + QtProperty *property = it.value()->property(); + if (!property->hasValue()) + d_ptr->updateItem(it.key()); + } +} + +/*! + \property QtTreePropertyBrowser::alternatingRowColors + \brief whether to draw the background using alternating colors. + By default this property is set to true. +*/ +bool QtTreePropertyBrowser::alternatingRowColors() const +{ + return d_ptr->m_treeWidget->alternatingRowColors(); +} + +void QtTreePropertyBrowser::setAlternatingRowColors(bool enable) +{ + d_ptr->m_treeWidget->setAlternatingRowColors(enable); +} + +/*! + \property QtTreePropertyBrowser::headerVisible + \brief whether to show the header. +*/ +bool QtTreePropertyBrowser::isHeaderVisible() const +{ + return d_ptr->m_headerVisible; +} + +void QtTreePropertyBrowser::setHeaderVisible(bool visible) +{ + if (d_ptr->m_headerVisible == visible) + return; + + d_ptr->m_headerVisible = visible; + d_ptr->m_treeWidget->header()->setVisible(visible); +} + +/*! + \enum QtTreePropertyBrowser::ResizeMode + + The resize mode specifies the behavior of the header sections. + + \value Interactive The user can resize the sections. + The sections can also be resized programmatically using setSplitterPosition(). + + \value Fixed The user cannot resize the section. + The section can only be resized programmatically using setSplitterPosition(). + + \value Stretch QHeaderView will automatically resize the section to fill the available space. + The size cannot be changed by the user or programmatically. + + \value ResizeToContents QHeaderView will automatically resize the section to its optimal + size based on the contents of the entire column. + The size cannot be changed by the user or programmatically. + + \sa setResizeMode() +*/ + +/*! + \property QtTreePropertyBrowser::resizeMode + \brief the resize mode of setions in the header. +*/ + +QtTreePropertyBrowser::ResizeMode QtTreePropertyBrowser::resizeMode() const +{ + return d_ptr->m_resizeMode; +} + +void QtTreePropertyBrowser::setResizeMode(QtTreePropertyBrowser::ResizeMode mode) +{ + if (d_ptr->m_resizeMode == mode) + return; + + d_ptr->m_resizeMode = mode; + QHeaderView::ResizeMode m = QHeaderView::Stretch; + switch (mode) { + case QtTreePropertyBrowser::Interactive: m = QHeaderView::Interactive; break; + case QtTreePropertyBrowser::Fixed: m = QHeaderView::Fixed; break; + case QtTreePropertyBrowser::ResizeToContents: m = QHeaderView::ResizeToContents; break; + case QtTreePropertyBrowser::Stretch: + default: m = QHeaderView::Stretch; break; + } + d_ptr->m_treeWidget->header()->setSectionResizeMode(m); +} + +/*! + \property QtTreePropertyBrowser::splitterPosition + \brief the position of the splitter between the colunms. +*/ + +int QtTreePropertyBrowser::splitterPosition() const +{ + return d_ptr->m_treeWidget->header()->sectionSize(0); +} + +void QtTreePropertyBrowser::setSplitterPosition(int position) +{ + d_ptr->m_treeWidget->header()->resizeSection(0, position); +} + +/*! + Sets the \a item to either collapse or expanded, depending on the value of \a expanded. + + \sa isExpanded(), expanded(), collapsed() +*/ + +void QtTreePropertyBrowser::setExpanded(QtBrowserItem *item, bool expanded) +{ + QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item); + if (treeItem) + treeItem->setExpanded(expanded); +} + +/*! + Returns true if the \a item is expanded; otherwise returns false. + + \sa setExpanded() +*/ + +bool QtTreePropertyBrowser::isExpanded(QtBrowserItem *item) const +{ + QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item); + if (treeItem) + return treeItem->isExpanded(); + return false; +} + +/*! + Returns true if the \a item is visible; otherwise returns false. + + \sa setItemVisible() + \since 4.5 +*/ + +bool QtTreePropertyBrowser::isItemVisible(QtBrowserItem *item) const +{ + if (const QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item)) + return !treeItem->isHidden(); + return false; +} + +/*! + Sets the \a item to be visible, depending on the value of \a visible. + + \sa isItemVisible() + \since 4.5 +*/ + +void QtTreePropertyBrowser::setItemVisible(QtBrowserItem *item, bool visible) +{ + if (QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item)) + treeItem->setHidden(!visible); +} + +/*! + Sets the \a item's background color to \a color. Note that while item's background + is rendered every second row is being drawn with alternate color (which is a bit lighter than items \a color) + + \sa backgroundColor(), calculatedBackgroundColor() +*/ + +void QtTreePropertyBrowser::setBackgroundColor(QtBrowserItem *item, const QColor &color) +{ + if (!d_ptr->m_indexToItem.contains(item)) + return; + if (color.isValid()) + d_ptr->m_indexToBackgroundColor[item] = color; + else + d_ptr->m_indexToBackgroundColor.remove(item); + d_ptr->m_treeWidget->viewport()->update(); +} + +/*! + Returns the \a item's color. If there is no color set for item it returns invalid color. + + \sa calculatedBackgroundColor(), setBackgroundColor() +*/ + +QColor QtTreePropertyBrowser::backgroundColor(QtBrowserItem *item) const +{ + return d_ptr->m_indexToBackgroundColor.value(item); +} + +/*! + Returns the \a item's color. If there is no color set for item it returns parent \a item's + color (if there is no color set for parent it returns grandparent's color and so on). In case + the color is not set for \a item and it's top level item it returns invalid color. + + \sa backgroundColor(), setBackgroundColor() +*/ + +QColor QtTreePropertyBrowser::calculatedBackgroundColor(QtBrowserItem *item) const +{ + return d_ptr->calculatedBackgroundColor(item); +} + +/*! + \property QtTreePropertyBrowser::propertiesWithoutValueMarked + \brief whether to enable or disable marking properties without value. + + When marking is enabled the item's background is rendered in dark color and item's + foreground is rendered with light color. + + \sa propertiesWithoutValueMarked() +*/ +void QtTreePropertyBrowser::setPropertiesWithoutValueMarked(bool mark) +{ + if (d_ptr->m_markPropertiesWithoutValue == mark) + return; + + d_ptr->m_markPropertiesWithoutValue = mark; + for (auto it = d_ptr->m_itemToIndex.cbegin(), end = d_ptr->m_itemToIndex.cend(); it != end; ++it) { + QtProperty *property = it.value()->property(); + if (!property->hasValue()) + d_ptr->updateItem(it.key()); + } + d_ptr->m_treeWidget->viewport()->update(); +} + +bool QtTreePropertyBrowser::propertiesWithoutValueMarked() const +{ + return d_ptr->m_markPropertiesWithoutValue; +} + +/*! + \reimp +*/ +void QtTreePropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) +{ + d_ptr->propertyInserted(item, afterItem); +} + +/*! + \reimp +*/ +void QtTreePropertyBrowser::itemRemoved(QtBrowserItem *item) +{ + d_ptr->propertyRemoved(item); +} + +/*! + \reimp +*/ +void QtTreePropertyBrowser::itemChanged(QtBrowserItem *item) +{ + d_ptr->propertyChanged(item); +} + +/*! + Sets the current item to \a item and opens the relevant editor for it. +*/ +void QtTreePropertyBrowser::editItem(QtBrowserItem *item) +{ + d_ptr->editItem(item); +} + +QT_END_NAMESPACE + +#include "moc_qttreepropertybrowser.cpp" +#include "qttreepropertybrowser.moc" diff --git a/external/QtPropertyBrowser/src/qttreepropertybrowser.h b/external/QtPropertyBrowser/src/qttreepropertybrowser.h new file mode 100644 index 000000000..a1c87aef4 --- /dev/null +++ b/external/QtPropertyBrowser/src/qttreepropertybrowser.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTTREEPROPERTYBROWSER_H +#define QTTREEPROPERTYBROWSER_H + +#include "qtpropertybrowser.h" + +QT_BEGIN_NAMESPACE + +class QTreeWidgetItem; +class QtTreePropertyBrowserPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtTreePropertyBrowser : public QtAbstractPropertyBrowser +{ + Q_OBJECT + Q_PROPERTY(int indentation READ indentation WRITE setIndentation) + Q_PROPERTY(bool rootIsDecorated READ rootIsDecorated WRITE setRootIsDecorated) + Q_PROPERTY(bool alternatingRowColors READ alternatingRowColors WRITE setAlternatingRowColors) + Q_PROPERTY(bool headerVisible READ isHeaderVisible WRITE setHeaderVisible) + Q_PROPERTY(ResizeMode resizeMode READ resizeMode WRITE setResizeMode) + Q_PROPERTY(int splitterPosition READ splitterPosition WRITE setSplitterPosition) + Q_PROPERTY(bool propertiesWithoutValueMarked READ propertiesWithoutValueMarked WRITE setPropertiesWithoutValueMarked) +public: + + enum ResizeMode + { + Interactive, + Stretch, + Fixed, + ResizeToContents + }; + Q_ENUM(ResizeMode) + + QtTreePropertyBrowser(QWidget *parent = 0); + ~QtTreePropertyBrowser(); + + int indentation() const; + void setIndentation(int i); + + bool rootIsDecorated() const; + void setRootIsDecorated(bool show); + + bool alternatingRowColors() const; + void setAlternatingRowColors(bool enable); + + bool isHeaderVisible() const; + void setHeaderVisible(bool visible); + + ResizeMode resizeMode() const; + void setResizeMode(ResizeMode mode); + + int splitterPosition() const; + void setSplitterPosition(int position); + + void setExpanded(QtBrowserItem *item, bool expanded); + bool isExpanded(QtBrowserItem *item) const; + + bool isItemVisible(QtBrowserItem *item) const; + void setItemVisible(QtBrowserItem *item, bool visible); + + void setBackgroundColor(QtBrowserItem *item, const QColor &color); + QColor backgroundColor(QtBrowserItem *item) const; + QColor calculatedBackgroundColor(QtBrowserItem *item) const; + + void setPropertiesWithoutValueMarked(bool mark); + bool propertiesWithoutValueMarked() const; + + void editItem(QtBrowserItem *item); + +Q_SIGNALS: + + void collapsed(QtBrowserItem *item); + void expanded(QtBrowserItem *item); + +protected: + void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) override; + void itemRemoved(QtBrowserItem *item) override; + void itemChanged(QtBrowserItem *item) override; + +private: + + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtTreePropertyBrowser) + Q_DISABLE_COPY_MOVE(QtTreePropertyBrowser) + + Q_PRIVATE_SLOT(d_func(), void slotCollapsed(const QModelIndex &)) + Q_PRIVATE_SLOT(d_func(), void slotExpanded(const QModelIndex &)) + Q_PRIVATE_SLOT(d_func(), void slotCurrentBrowserItemChanged(QtBrowserItem *)) + Q_PRIVATE_SLOT(d_func(), void slotCurrentTreeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)) + +}; + +QT_END_NAMESPACE + +#endif diff --git a/external/QtPropertyBrowser/src/qtvariantproperty.cpp b/external/QtPropertyBrowser/src/qtvariantproperty.cpp new file mode 100644 index 000000000..2c36d887b --- /dev/null +++ b/external/QtPropertyBrowser/src/qtvariantproperty.cpp @@ -0,0 +1,2215 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtvariantproperty.h" +#include "qtpropertymanager.h" +#include "qteditorfactory.h" +#include +#include +#include +#include +#include + +#if defined(Q_CC_MSVC) +# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ +#endif + +QT_BEGIN_NAMESPACE + +class QtEnumPropertyType +{ +}; + + +class QtFlagPropertyType +{ +}; + + +class QtGroupPropertyType +{ +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QtEnumPropertyType) +Q_DECLARE_METATYPE(QtFlagPropertyType) +Q_DECLARE_METATYPE(QtGroupPropertyType) + +QT_BEGIN_NAMESPACE + +/*! + Returns the type id for an enum property. + + Note that the property's value type can be retrieved using the + valueType() function (which is QMetaType::Int for the enum property + type). + + \sa propertyType(), valueType() +*/ +int QtVariantPropertyManager::enumTypeId() +{ + return qMetaTypeId(); +} + +/*! + Returns the type id for a flag property. + + Note that the property's value type can be retrieved using the + valueType() function (which is QMetaType::Int for the flag property + type). + + \sa propertyType(), valueType() +*/ +int QtVariantPropertyManager::flagTypeId() +{ + return qMetaTypeId(); +} + +/*! + Returns the type id for a group property. + + Note that the property's value type can be retrieved using the + valueType() function (which is QMetaType::UnknownType for the group + property type, since it doesn't provide any value). + + \sa propertyType(), valueType() +*/ +int QtVariantPropertyManager::groupTypeId() +{ + return qMetaTypeId(); +} + +/*! + Returns the type id for a icon map attribute. + + Note that the property's attribute type can be retrieved using the + attributeType() function. + + \sa attributeType(), QtEnumPropertyManager::enumIcons() +*/ +int QtVariantPropertyManager::iconMapTypeId() +{ + return qMetaTypeId(); +} + +typedef QMap PropertyMap; +Q_GLOBAL_STATIC(PropertyMap, propertyToWrappedProperty) + +static QtProperty *wrappedProperty(QtProperty *property) +{ + return propertyToWrappedProperty()->value(property, 0); +} + +class QtVariantPropertyPrivate +{ +public: + QtVariantPropertyPrivate(QtVariantPropertyManager *m) : manager(m) {} + + QtVariantPropertyManager *manager; +}; + +/*! + \class QtVariantProperty + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtVariantProperty class is a convenience class handling + QVariant based properties. + + QtVariantProperty provides additional API: A property's type, + value type, attribute values and current value can easily be + retrieved using the propertyType(), valueType(), attributeValue() + and value() functions respectively. In addition, the attribute + values and the current value can be set using the corresponding + setValue() and setAttribute() functions. + + For example, instead of writing: + + \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtvariantproperty.cpp 0 + + you can write: + + \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtvariantproperty.cpp 1 + + QtVariantProperty instances can only be created by the + QtVariantPropertyManager class. + + \sa QtProperty, QtVariantPropertyManager, QtVariantEditorFactory +*/ + +/*! + Creates a variant property using the given \a manager. + + Do not use this constructor to create variant property instances; + use the QtVariantPropertyManager::addProperty() function + instead. This constructor is used internally by the + QtVariantPropertyManager::createProperty() function. + + \sa QtVariantPropertyManager +*/ +QtVariantProperty::QtVariantProperty(QtVariantPropertyManager *manager) + : QtProperty(manager), d_ptr(new QtVariantPropertyPrivate(manager)) +{ +} + +/*! + Destroys this property. + + \sa QtProperty::~QtProperty() +*/ +QtVariantProperty::~QtVariantProperty() +{ +} + +/*! + Returns the property's current value. + + \sa valueType(), setValue() +*/ +QVariant QtVariantProperty::value() const +{ + return d_ptr->manager->value(this); +} + +/*! + Returns this property's value for the specified \a attribute. + + QtVariantPropertyManager provides a couple of related functions: + \l{QtVariantPropertyManager::attributes()}{attributes()} and + \l{QtVariantPropertyManager::attributeType()}{attributeType()}. + + \sa setAttribute() +*/ +QVariant QtVariantProperty::attributeValue(const QString &attribute) const +{ + return d_ptr->manager->attributeValue(this, attribute); +} + +/*! + Returns the type of this property's value. + + \sa propertyType() +*/ +int QtVariantProperty::valueType() const +{ + return d_ptr->manager->valueType(this); +} + +/*! + Returns this property's type. + + QtVariantPropertyManager provides several related functions: + \l{QtVariantPropertyManager::enumTypeId()}{enumTypeId()}, + \l{QtVariantPropertyManager::flagTypeId()}{flagTypeId()} and + \l{QtVariantPropertyManager::groupTypeId()}{groupTypeId()}. + + \sa valueType() +*/ +int QtVariantProperty::propertyType() const +{ + return d_ptr->manager->propertyType(this); +} + +/*! + Sets the value of this property to \a value. + + The specified \a value must be of the type returned by + valueType(), or of a type that can be converted to valueType() + using the QVariant::canConvert() function; otherwise this function + does nothing. + + \sa value() +*/ +void QtVariantProperty::setValue(const QVariant &value) +{ + d_ptr->manager->setValue(this, value); +} + +/*! + Sets the \a attribute of property to \a value. + + QtVariantPropertyManager provides the related + \l{QtVariantPropertyManager::setAttribute()}{setAttribute()} + function. + + \sa attributeValue() +*/ +void QtVariantProperty::setAttribute(const QString &attribute, const QVariant &value) +{ + d_ptr->manager->setAttribute(this, attribute, value); +} + +class QtVariantPropertyManagerPrivate +{ + QtVariantPropertyManager *q_ptr; + Q_DECLARE_PUBLIC(QtVariantPropertyManager) +public: + QtVariantPropertyManagerPrivate(); + + bool m_creatingProperty; + bool m_creatingSubProperties; + bool m_destroyingSubProperties; + int m_propertyType; + + void slotValueChanged(QtProperty *property, int val); + void slotRangeChanged(QtProperty *property, int min, int max); + void slotSingleStepChanged(QtProperty *property, int step); + void slotValueChanged(QtProperty *property, double val); + void slotRangeChanged(QtProperty *property, double min, double max); + void slotSingleStepChanged(QtProperty *property, double step); + void slotDecimalsChanged(QtProperty *property, int prec); + void slotValueChanged(QtProperty *property, bool val); + void slotValueChanged(QtProperty *property, const QString &val); + void slotRegExpChanged(QtProperty *property, const QRegularExpression ®Exp); + void slotValueChanged(QtProperty *property, QDate val); + void slotRangeChanged(QtProperty *property, QDate min, QDate max); + void slotValueChanged(QtProperty *property, QTime val); + void slotValueChanged(QtProperty *property, const QDateTime &val); + void slotValueChanged(QtProperty *property, const QKeySequence &val); + void slotValueChanged(QtProperty *property, const QChar &val); + void slotValueChanged(QtProperty *property, const QLocale &val); + void slotValueChanged(QtProperty *property, const QPoint &val); + void slotValueChanged(QtProperty *property, const QPointF &val); + void slotValueChanged(QtProperty *property, const QSize &val); + void slotRangeChanged(QtProperty *property, const QSize &min, const QSize &max); + void slotValueChanged(QtProperty *property, const QSizeF &val); + void slotRangeChanged(QtProperty *property, const QSizeF &min, const QSizeF &max); + void slotValueChanged(QtProperty *property, const QRect &val); + void slotConstraintChanged(QtProperty *property, const QRect &val); + void slotValueChanged(QtProperty *property, const QRectF &val); + void slotConstraintChanged(QtProperty *property, const QRectF &val); + void slotValueChanged(QtProperty *property, const QColor &val); + void slotEnumChanged(QtProperty *property, int val); + void slotEnumNamesChanged(QtProperty *property, const QStringList &enumNames); + void slotEnumIconsChanged(QtProperty *property, const QMap &enumIcons); + void slotValueChanged(QtProperty *property, const QSizePolicy &val); + void slotValueChanged(QtProperty *property, const QFont &val); + void slotValueChanged(QtProperty *property, const QCursor &val); + void slotFlagChanged(QtProperty *property, int val); + void slotFlagNamesChanged(QtProperty *property, const QStringList &flagNames); + void slotPropertyInserted(QtProperty *property, QtProperty *parent, QtProperty *after); + void slotPropertyRemoved(QtProperty *property, QtProperty *parent); + + void valueChanged(QtProperty *property, const QVariant &val); + + int internalPropertyToType(QtProperty *property) const; + QtVariantProperty *createSubProperty(QtVariantProperty *parent, QtVariantProperty *after, + QtProperty *internal); + void removeSubProperty(QtVariantProperty *property); + + QMap m_typeToPropertyManager; + QMap > m_typeToAttributeToAttributeType; + + QMap > m_propertyToType; + + QMap m_typeToValueType; + + + QMap m_internalToProperty; + + const QString m_constraintAttribute; + const QString m_singleStepAttribute; + const QString m_decimalsAttribute; + const QString m_enumIconsAttribute; + const QString m_enumNamesAttribute; + const QString m_flagNamesAttribute; + const QString m_maximumAttribute; + const QString m_minimumAttribute; + const QString m_regExpAttribute; +}; + +QtVariantPropertyManagerPrivate::QtVariantPropertyManagerPrivate() : + m_constraintAttribute(QLatin1String("constraint")), + m_singleStepAttribute(QLatin1String("singleStep")), + m_decimalsAttribute(QLatin1String("decimals")), + m_enumIconsAttribute(QLatin1String("enumIcons")), + m_enumNamesAttribute(QLatin1String("enumNames")), + m_flagNamesAttribute(QLatin1String("flagNames")), + m_maximumAttribute(QLatin1String("maximum")), + m_minimumAttribute(QLatin1String("minimum")), + m_regExpAttribute(QLatin1String("regExp")) +{ +} + +int QtVariantPropertyManagerPrivate::internalPropertyToType(QtProperty *property) const +{ + int type = 0; + QtAbstractPropertyManager *internPropertyManager = property->propertyManager(); + if (qobject_cast(internPropertyManager)) + type = QMetaType::Int; + else if (qobject_cast(internPropertyManager)) + type = QtVariantPropertyManager::enumTypeId(); + else if (qobject_cast(internPropertyManager)) + type = QMetaType::Bool; + else if (qobject_cast(internPropertyManager)) + type = QMetaType::Double; + return type; +} + +QtVariantProperty *QtVariantPropertyManagerPrivate::createSubProperty(QtVariantProperty *parent, + QtVariantProperty *after, QtProperty *internal) +{ + int type = internalPropertyToType(internal); + if (!type) + return 0; + + bool wasCreatingSubProperties = m_creatingSubProperties; + m_creatingSubProperties = true; + + QtVariantProperty *varChild = q_ptr->addProperty(type, internal->propertyName()); + + m_creatingSubProperties = wasCreatingSubProperties; + + varChild->setPropertyName(internal->propertyName()); + varChild->setToolTip(internal->toolTip()); + varChild->setStatusTip(internal->statusTip()); + varChild->setWhatsThis(internal->whatsThis()); + + parent->insertSubProperty(varChild, after); + + m_internalToProperty[internal] = varChild; + propertyToWrappedProperty()->insert(varChild, internal); + return varChild; +} + +void QtVariantPropertyManagerPrivate::removeSubProperty(QtVariantProperty *property) +{ + QtProperty *internChild = wrappedProperty(property); + bool wasDestroyingSubProperties = m_destroyingSubProperties; + m_destroyingSubProperties = true; + delete property; + m_destroyingSubProperties = wasDestroyingSubProperties; + m_internalToProperty.remove(internChild); + propertyToWrappedProperty()->remove(property); +} + +void QtVariantPropertyManagerPrivate::slotPropertyInserted(QtProperty *property, + QtProperty *parent, QtProperty *after) +{ + if (m_creatingProperty) + return; + + QtVariantProperty *varParent = m_internalToProperty.value(parent, 0); + if (!varParent) + return; + + QtVariantProperty *varAfter = 0; + if (after) { + varAfter = m_internalToProperty.value(after, 0); + if (!varAfter) + return; + } + + createSubProperty(varParent, varAfter, property); +} + +void QtVariantPropertyManagerPrivate::slotPropertyRemoved(QtProperty *property, QtProperty *parent) +{ + Q_UNUSED(parent); + + QtVariantProperty *varProperty = m_internalToProperty.value(property, 0); + if (!varProperty) + return; + + removeSubProperty(varProperty); +} + +void QtVariantPropertyManagerPrivate::valueChanged(QtProperty *property, const QVariant &val) +{ + QtVariantProperty *varProp = m_internalToProperty.value(property, 0); + if (!varProp) + return; + emit q_ptr->valueChanged(varProp, val); + emit q_ptr->propertyChanged(varProp); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, int val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, int min, int max) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min)); + emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max)); + } +} + +void QtVariantPropertyManagerPrivate::slotSingleStepChanged(QtProperty *property, int step) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_singleStepAttribute, QVariant(step)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, double val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, double min, double max) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min)); + emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max)); + } +} + +void QtVariantPropertyManagerPrivate::slotSingleStepChanged(QtProperty *property, double step) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_singleStepAttribute, QVariant(step)); +} + +void QtVariantPropertyManagerPrivate::slotDecimalsChanged(QtProperty *property, int prec) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_decimalsAttribute, QVariant(prec)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, bool val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QString &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRegExpChanged(QtProperty *property, const QRegularExpression ®Exp) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_regExpAttribute, QVariant(regExp)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, QDate val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, QDate min, QDate max) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min)); + emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max)); + } +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, QTime val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QDateTime &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QKeySequence &val) +{ + QVariant v; + v.setValue(val); + valueChanged(property, v); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QChar &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QLocale &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QPoint &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QPointF &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QSize &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, const QSize &min, const QSize &max) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min)); + emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max)); + } +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QSizeF &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, const QSizeF &min, const QSizeF &max) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min)); + emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max)); + } +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QRect &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotConstraintChanged(QtProperty *property, const QRect &constraint) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_constraintAttribute, QVariant(constraint)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QRectF &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotConstraintChanged(QtProperty *property, const QRectF &constraint) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_constraintAttribute, QVariant(constraint)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QColor &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotEnumNamesChanged(QtProperty *property, const QStringList &enumNames) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_enumNamesAttribute, QVariant(enumNames)); +} + +void QtVariantPropertyManagerPrivate::slotEnumIconsChanged(QtProperty *property, const QMap &enumIcons) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { + QVariant v; + v.setValue(enumIcons); + emit q_ptr->attributeChanged(varProp, m_enumIconsAttribute, v); + } +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QSizePolicy &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QFont &val) +{ + valueChanged(property, QVariant(val)); +} + +void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QCursor &val) +{ +#ifndef QT_NO_CURSOR + valueChanged(property, QVariant(val)); +#endif +} + +void QtVariantPropertyManagerPrivate::slotFlagNamesChanged(QtProperty *property, const QStringList &flagNames) +{ + if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) + emit q_ptr->attributeChanged(varProp, m_flagNamesAttribute, QVariant(flagNames)); +} + +/*! + \class QtVariantPropertyManager + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtVariantPropertyManager class provides and manages QVariant based properties. + + QtVariantPropertyManager provides the addProperty() function which + creates QtVariantProperty objects. The QtVariantProperty class is + a convenience class handling QVariant based properties inheriting + QtProperty. A QtProperty object created by a + QtVariantPropertyManager instance can be converted into a + QtVariantProperty object using the variantProperty() function. + + The property's value can be retrieved using the value(), and set + using the setValue() slot. In addition the property's type, and + the type of its value, can be retrieved using the propertyType() + and valueType() functions respectively. + + A property's type is a QMetaType::QType enumerator value, and + usually a property's type is the same as its value type. But for + some properties the types differ, for example for enums, flags and + group types in which case QtVariantPropertyManager provides the + enumTypeId(), flagTypeId() and groupTypeId() functions, + respectively, to identify their property type (the value types are + QMetaType::Int for the enum and flag types, and QMetaType::UnknownType + for the group type). + + Use the isPropertyTypeSupported() function to check if a particular + property type is supported. The currently supported property types + are: + + \table + \header + \li Property Type + \li Property Type Id + \row + \li int + \li QMetaType::Int + \row + \li double + \li QMetaType::Double + \row + \li bool + \li QMetaType::Bool + \row + \li QString + \li QMetaType::QString + \row + \li QDate + \li QMetaType::QDate + \row + \li QTime + \li QMetaType::QTime + \row + \li QDateTime + \li QMetaType::QDateTime + \row + \li QKeySequence + \li QMetaType::QKeySequence + \row + \li QChar + \li QMetaType::QChar + \row + \li QLocale + \li QMetaType::QLocale + \row + \li QPoint + \li QMetaType::QPoint + \row + \li QPointF + \li QMetaType::QPointF + \row + \li QSize + \li QMetaType::QSize + \row + \li QSizeF + \li QMetaType::QSizeF + \row + \li QRect + \li QMetaType::QRect + \row + \li QRectF + \li QMetaType::QRectF + \row + \li QColor + \li QMetaType::QColor + \row + \li QSizePolicy + \li QMetaType::QSizePolicy + \row + \li QFont + \li QMetaType::QFont + \row + \li QCursor + \li QMetaType::QCursor + \row + \li enum + \li enumTypeId() + \row + \li flag + \li flagTypeId() + \row + \li group + \li groupTypeId() + \endtable + + Each property type can provide additional attributes, + e.g. QMetaType::Int and QMetaType::Double provides minimum and + maximum values. The currently supported attributes are: + + \table + \header + \li Property Type + \li Attribute Name + \li Attribute Type + \row + \li \c int + \li minimum + \li QMetaType::Int + \row + \li + \li maximum + \li QMetaType::Int + \row + \li + \li singleStep + \li QMetaType::Int + \row + \li \c double + \li minimum + \li QMetaType::Double + \row + \li + \li maximum + \li QMetaType::Double + \row + \li + \li singleStep + \li QMetaType::Double + \row + \li + \li decimals + \li QMetaType::Int + \row + \li QString + \li regExp + \li QMetaType::QRegExp + \row + \li QDate + \li minimum + \li QMetaType::QDate + \row + \li + \li maximum + \li QMetaType::QDate + \row + \li QPointF + \li decimals + \li QMetaType::Int + \row + \li QSize + \li minimum + \li QMetaType::QSize + \row + \li + \li maximum + \li QMetaType::QSize + \row + \li QSizeF + \li minimum + \li QMetaType::QSizeF + \row + \li + \li maximum + \li QMetaType::QSizeF + \row + \li + \li decimals + \li QMetaType::Int + \row + \li QRect + \li constraint + \li QMetaType::QRect + \row + \li QRectF + \li constraint + \li QMetaType::QRectF + \row + \li + \li decimals + \li QMetaType::Int + \row + \li \c enum + \li enumNames + \li QMetaType::QStringList + \row + \li + \li enumIcons + \li iconMapTypeId() + \row + \li \c flag + \li flagNames + \li QMetaType::QStringList + \endtable + + The attributes for a given property type can be retrieved using + the attributes() function. Each attribute has a value type which + can be retrieved using the attributeType() function, and a value + accessible through the attributeValue() function. In addition, the + value can be set using the setAttribute() slot. + + QtVariantManager also provides the valueChanged() signal which is + emitted whenever a property created by this manager change, and + the attributeChanged() signal which is emitted whenever an + attribute of such a property changes. + + \sa QtVariantProperty, QtVariantEditorFactory +*/ + +/*! + \fn void QtVariantPropertyManager::valueChanged(QtProperty *property, const QVariant &value) + + This signal is emitted whenever a property created by this manager + changes its value, passing a pointer to the \a property and the + new \a value as parameters. + + \sa setValue() +*/ + +/*! + \fn void QtVariantPropertyManager::attributeChanged(QtProperty *property, + const QString &attribute, const QVariant &value) + + This signal is emitted whenever an attribute of a property created + by this manager changes its value, passing a pointer to the \a + property, the \a attribute and the new \a value as parameters. + + \sa setAttribute() +*/ + +/*! + Creates a manager with the given \a parent. +*/ +QtVariantPropertyManager::QtVariantPropertyManager(QObject *parent) + : QtAbstractPropertyManager(parent), d_ptr(new QtVariantPropertyManagerPrivate) +{ + d_ptr->q_ptr = this; + + d_ptr->m_creatingProperty = false; + d_ptr->m_creatingSubProperties = false; + d_ptr->m_destroyingSubProperties = false; + d_ptr->m_propertyType = 0; + + // IntPropertyManager + QtIntPropertyManager *intPropertyManager = new QtIntPropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::Int] = intPropertyManager; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::Int][d_ptr->m_minimumAttribute] = QMetaType::Int; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::Int][d_ptr->m_maximumAttribute] = QMetaType::Int; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::Int][d_ptr->m_singleStepAttribute] = QMetaType::Int; + d_ptr->m_typeToValueType[QMetaType::Int] = QMetaType::Int; + connect(intPropertyManager, SIGNAL(valueChanged(QtProperty*,int)), + this, SLOT(slotValueChanged(QtProperty*,int))); + connect(intPropertyManager, SIGNAL(rangeChanged(QtProperty*,int,int)), + this, SLOT(slotRangeChanged(QtProperty*,int,int))); + connect(intPropertyManager, SIGNAL(singleStepChanged(QtProperty*,int)), + this, SLOT(slotSingleStepChanged(QtProperty*,int))); + // DoublePropertyManager + QtDoublePropertyManager *doublePropertyManager = new QtDoublePropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::Double] = doublePropertyManager; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::Double][d_ptr->m_minimumAttribute] = + QMetaType::Double; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::Double][d_ptr->m_maximumAttribute] = + QMetaType::Double; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::Double][d_ptr->m_singleStepAttribute] = + QMetaType::Double; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::Double][d_ptr->m_decimalsAttribute] = + QMetaType::Int; + d_ptr->m_typeToValueType[QMetaType::Double] = QMetaType::Double; + connect(doublePropertyManager, SIGNAL(valueChanged(QtProperty*,double)), + this, SLOT(slotValueChanged(QtProperty*,double))); + connect(doublePropertyManager, SIGNAL(rangeChanged(QtProperty*,double,double)), + this, SLOT(slotRangeChanged(QtProperty*,double,double))); + connect(doublePropertyManager, SIGNAL(singleStepChanged(QtProperty*,double)), + this, SLOT(slotSingleStepChanged(QtProperty*,double))); + connect(doublePropertyManager, SIGNAL(decimalsChanged(QtProperty*,int)), + this, SLOT(slotDecimalsChanged(QtProperty*,int))); + // BoolPropertyManager + QtBoolPropertyManager *boolPropertyManager = new QtBoolPropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::Bool] = boolPropertyManager; + d_ptr->m_typeToValueType[QMetaType::Bool] = QMetaType::Bool; + connect(boolPropertyManager, SIGNAL(valueChanged(QtProperty*,bool)), + this, SLOT(slotValueChanged(QtProperty*,bool))); + // StringPropertyManager + QtStringPropertyManager *stringPropertyManager = new QtStringPropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QString] = stringPropertyManager; + d_ptr->m_typeToValueType[QMetaType::QString] = QMetaType::QString; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::QString][d_ptr->m_regExpAttribute] = + QMetaType::QRegularExpression; + connect(stringPropertyManager, SIGNAL(valueChanged(QtProperty*,QString)), + this, SLOT(slotValueChanged(QtProperty*,QString))); + connect(stringPropertyManager, SIGNAL(regExpChanged(QtProperty*,QRegularExpression)), + this, SLOT(slotRegExpChanged(QtProperty*,QRegularExpression))); + // DatePropertyManager + QtDatePropertyManager *datePropertyManager = new QtDatePropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QDate] = datePropertyManager; + d_ptr->m_typeToValueType[QMetaType::QDate] = QMetaType::QDate; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::QDate][d_ptr->m_minimumAttribute] = + QMetaType::QDate; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::QDate][d_ptr->m_maximumAttribute] = + QMetaType::QDate; + connect(datePropertyManager, SIGNAL(valueChanged(QtProperty*,QDate)), + this, SLOT(slotValueChanged(QtProperty*,QDate))); + connect(datePropertyManager, SIGNAL(rangeChanged(QtProperty*,QDate,QDate)), + this, SLOT(slotRangeChanged(QtProperty*,QDate,QDate))); + // TimePropertyManager + QtTimePropertyManager *timePropertyManager = new QtTimePropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QTime] = timePropertyManager; + d_ptr->m_typeToValueType[QMetaType::QTime] = QMetaType::QTime; + connect(timePropertyManager, SIGNAL(valueChanged(QtProperty*,QTime)), + this, SLOT(slotValueChanged(QtProperty*,QTime))); + // DateTimePropertyManager + QtDateTimePropertyManager *dateTimePropertyManager = new QtDateTimePropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QDateTime] = dateTimePropertyManager; + d_ptr->m_typeToValueType[QMetaType::QDateTime] = QMetaType::QDateTime; + connect(dateTimePropertyManager, SIGNAL(valueChanged(QtProperty*,QDateTime)), + this, SLOT(slotValueChanged(QtProperty*,QDateTime))); + // KeySequencePropertyManager + QtKeySequencePropertyManager *keySequencePropertyManager = new QtKeySequencePropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QKeySequence] = keySequencePropertyManager; + d_ptr->m_typeToValueType[QMetaType::QKeySequence] = QMetaType::QKeySequence; + connect(keySequencePropertyManager, SIGNAL(valueChanged(QtProperty*,QKeySequence)), + this, SLOT(slotValueChanged(QtProperty*,QKeySequence))); + // CharPropertyManager + QtCharPropertyManager *charPropertyManager = new QtCharPropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QChar] = charPropertyManager; + d_ptr->m_typeToValueType[QMetaType::QChar] = QMetaType::QChar; + connect(charPropertyManager, SIGNAL(valueChanged(QtProperty*,QChar)), + this, SLOT(slotValueChanged(QtProperty*,QChar))); + // LocalePropertyManager + QtLocalePropertyManager *localePropertyManager = new QtLocalePropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QLocale] = localePropertyManager; + d_ptr->m_typeToValueType[QMetaType::QLocale] = QMetaType::QLocale; + connect(localePropertyManager, SIGNAL(valueChanged(QtProperty*,QLocale)), + this, SLOT(slotValueChanged(QtProperty*,QLocale))); + connect(localePropertyManager->subEnumPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)), + this, SLOT(slotValueChanged(QtProperty*,int))); + connect(localePropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)), + this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*))); + connect(localePropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)), + this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*))); + // PointPropertyManager + QtPointPropertyManager *pointPropertyManager = new QtPointPropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QPoint] = pointPropertyManager; + d_ptr->m_typeToValueType[QMetaType::QPoint] = QMetaType::QPoint; + connect(pointPropertyManager, SIGNAL(valueChanged(QtProperty*,QPoint)), + this, SLOT(slotValueChanged(QtProperty*,QPoint))); + connect(pointPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)), + this, SLOT(slotValueChanged(QtProperty*,int))); + connect(pointPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)), + this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*))); + connect(pointPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)), + this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*))); + // PointFPropertyManager + QtPointFPropertyManager *pointFPropertyManager = new QtPointFPropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QPointF] = pointFPropertyManager; + d_ptr->m_typeToValueType[QMetaType::QPointF] = QMetaType::QPointF; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::QPointF][d_ptr->m_decimalsAttribute] = + QMetaType::Int; + connect(pointFPropertyManager, SIGNAL(valueChanged(QtProperty*,QPointF)), + this, SLOT(slotValueChanged(QtProperty*,QPointF))); + connect(pointFPropertyManager, SIGNAL(decimalsChanged(QtProperty*,int)), + this, SLOT(slotDecimalsChanged(QtProperty*,int))); + connect(pointFPropertyManager->subDoublePropertyManager(), SIGNAL(valueChanged(QtProperty*,double)), + this, SLOT(slotValueChanged(QtProperty*,double))); + connect(pointFPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)), + this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*))); + connect(pointFPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)), + this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*))); + // SizePropertyManager + QtSizePropertyManager *sizePropertyManager = new QtSizePropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QSize] = sizePropertyManager; + d_ptr->m_typeToValueType[QMetaType::QSize] = QMetaType::QSize; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::QSize][d_ptr->m_minimumAttribute] = + QMetaType::QSize; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::QSize][d_ptr->m_maximumAttribute] = + QMetaType::QSize; + connect(sizePropertyManager, SIGNAL(valueChanged(QtProperty*,QSize)), + this, SLOT(slotValueChanged(QtProperty*,QSize))); + connect(sizePropertyManager, SIGNAL(rangeChanged(QtProperty*,QSize,QSize)), + this, SLOT(slotRangeChanged(QtProperty*,QSize,QSize))); + connect(sizePropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)), + this, SLOT(slotValueChanged(QtProperty*,int))); + connect(sizePropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty*,int,int)), + this, SLOT(slotRangeChanged(QtProperty*,int,int))); + connect(sizePropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)), + this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*))); + connect(sizePropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)), + this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*))); + // SizeFPropertyManager + QtSizeFPropertyManager *sizeFPropertyManager = new QtSizeFPropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QSizeF] = sizeFPropertyManager; + d_ptr->m_typeToValueType[QMetaType::QSizeF] = QMetaType::QSizeF; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::QSizeF][d_ptr->m_minimumAttribute] = + QMetaType::QSizeF; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::QSizeF][d_ptr->m_maximumAttribute] = + QMetaType::QSizeF; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::QSizeF][d_ptr->m_decimalsAttribute] = + QMetaType::Int; + connect(sizeFPropertyManager, SIGNAL(valueChanged(QtProperty*,QSizeF)), + this, SLOT(slotValueChanged(QtProperty*,QSizeF))); + connect(sizeFPropertyManager, SIGNAL(rangeChanged(QtProperty*,QSizeF,QSizeF)), + this, SLOT(slotRangeChanged(QtProperty*,QSizeF,QSizeF))); + connect(sizeFPropertyManager, SIGNAL(decimalsChanged(QtProperty*,int)), + this, SLOT(slotDecimalsChanged(QtProperty*,int))); + connect(sizeFPropertyManager->subDoublePropertyManager(), SIGNAL(valueChanged(QtProperty*,double)), + this, SLOT(slotValueChanged(QtProperty*,double))); + connect(sizeFPropertyManager->subDoublePropertyManager(), SIGNAL(rangeChanged(QtProperty*,double,double)), + this, SLOT(slotRangeChanged(QtProperty*,double,double))); + connect(sizeFPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)), + this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*))); + connect(sizeFPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)), + this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*))); + // RectPropertyManager + QtRectPropertyManager *rectPropertyManager = new QtRectPropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QRect] = rectPropertyManager; + d_ptr->m_typeToValueType[QMetaType::QRect] = QMetaType::QRect; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::QRect][d_ptr->m_constraintAttribute] = + QMetaType::QRect; + connect(rectPropertyManager, SIGNAL(valueChanged(QtProperty*,QRect)), + this, SLOT(slotValueChanged(QtProperty*,QRect))); + connect(rectPropertyManager, SIGNAL(constraintChanged(QtProperty*,QRect)), + this, SLOT(slotConstraintChanged(QtProperty*,QRect))); + connect(rectPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)), + this, SLOT(slotValueChanged(QtProperty*,int))); + connect(rectPropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty*,int,int)), + this, SLOT(slotRangeChanged(QtProperty*,int,int))); + connect(rectPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)), + this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*))); + connect(rectPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)), + this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*))); + // RectFPropertyManager + QtRectFPropertyManager *rectFPropertyManager = new QtRectFPropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QRectF] = rectFPropertyManager; + d_ptr->m_typeToValueType[QMetaType::QRectF] = QMetaType::QRectF; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::QRectF][d_ptr->m_constraintAttribute] = + QMetaType::QRectF; + d_ptr->m_typeToAttributeToAttributeType[QMetaType::QRectF][d_ptr->m_decimalsAttribute] = + QMetaType::Int; + connect(rectFPropertyManager, SIGNAL(valueChanged(QtProperty*,QRectF)), + this, SLOT(slotValueChanged(QtProperty*,QRectF))); + connect(rectFPropertyManager, SIGNAL(constraintChanged(QtProperty*,QRectF)), + this, SLOT(slotConstraintChanged(QtProperty*,QRectF))); + connect(rectFPropertyManager, SIGNAL(decimalsChanged(QtProperty*,int)), + this, SLOT(slotDecimalsChanged(QtProperty*,int))); + connect(rectFPropertyManager->subDoublePropertyManager(), SIGNAL(valueChanged(QtProperty*,double)), + this, SLOT(slotValueChanged(QtProperty*,double))); + connect(rectFPropertyManager->subDoublePropertyManager(), SIGNAL(rangeChanged(QtProperty*,double,double)), + this, SLOT(slotRangeChanged(QtProperty*,double,double))); + connect(rectFPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)), + this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*))); + connect(rectFPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)), + this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*))); + // ColorPropertyManager + QtColorPropertyManager *colorPropertyManager = new QtColorPropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QColor] = colorPropertyManager; + d_ptr->m_typeToValueType[QMetaType::QColor] = QMetaType::QColor; + connect(colorPropertyManager, SIGNAL(valueChanged(QtProperty*,QColor)), + this, SLOT(slotValueChanged(QtProperty*,QColor))); + connect(colorPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)), + this, SLOT(slotValueChanged(QtProperty*,int))); + connect(colorPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)), + this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*))); + connect(colorPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)), + this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*))); + // EnumPropertyManager + int enumId = enumTypeId(); + QtEnumPropertyManager *enumPropertyManager = new QtEnumPropertyManager(this); + d_ptr->m_typeToPropertyManager[enumId] = enumPropertyManager; + d_ptr->m_typeToValueType[enumId] = QMetaType::Int; + d_ptr->m_typeToAttributeToAttributeType[enumId][d_ptr->m_enumNamesAttribute] = + QMetaType::QStringList; + d_ptr->m_typeToAttributeToAttributeType[enumId][d_ptr->m_enumIconsAttribute] = + iconMapTypeId(); + connect(enumPropertyManager, SIGNAL(valueChanged(QtProperty*,int)), + this, SLOT(slotValueChanged(QtProperty*,int))); + connect(enumPropertyManager, SIGNAL(enumNamesChanged(QtProperty*,QStringList)), + this, SLOT(slotEnumNamesChanged(QtProperty*,QStringList))); + connect(enumPropertyManager, SIGNAL(enumIconsChanged(QtProperty*,QMap)), + this, SLOT(slotEnumIconsChanged(QtProperty*,QMap))); + // SizePolicyPropertyManager + QtSizePolicyPropertyManager *sizePolicyPropertyManager = new QtSizePolicyPropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QSizePolicy] = sizePolicyPropertyManager; + d_ptr->m_typeToValueType[QMetaType::QSizePolicy] = QMetaType::QSizePolicy; + connect(sizePolicyPropertyManager, SIGNAL(valueChanged(QtProperty*,QSizePolicy)), + this, SLOT(slotValueChanged(QtProperty*,QSizePolicy))); + connect(sizePolicyPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)), + this, SLOT(slotValueChanged(QtProperty*,int))); + connect(sizePolicyPropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty*,int,int)), + this, SLOT(slotRangeChanged(QtProperty*,int,int))); + connect(sizePolicyPropertyManager->subEnumPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)), + this, SLOT(slotValueChanged(QtProperty*,int))); + connect(sizePolicyPropertyManager->subEnumPropertyManager(), + SIGNAL(enumNamesChanged(QtProperty*,QStringList)), + this, SLOT(slotEnumNamesChanged(QtProperty*,QStringList))); + connect(sizePolicyPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)), + this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*))); + connect(sizePolicyPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)), + this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*))); + // FontPropertyManager + QtFontPropertyManager *fontPropertyManager = new QtFontPropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QFont] = fontPropertyManager; + d_ptr->m_typeToValueType[QMetaType::QFont] = QMetaType::QFont; + connect(fontPropertyManager, SIGNAL(valueChanged(QtProperty*,QFont)), + this, SLOT(slotValueChanged(QtProperty*,QFont))); + connect(fontPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)), + this, SLOT(slotValueChanged(QtProperty*,int))); + connect(fontPropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty*,int,int)), + this, SLOT(slotRangeChanged(QtProperty*,int,int))); + connect(fontPropertyManager->subEnumPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)), + this, SLOT(slotValueChanged(QtProperty*,int))); + connect(fontPropertyManager->subEnumPropertyManager(), + SIGNAL(enumNamesChanged(QtProperty*,QStringList)), + this, SLOT(slotEnumNamesChanged(QtProperty*,QStringList))); + connect(fontPropertyManager->subBoolPropertyManager(), SIGNAL(valueChanged(QtProperty*,bool)), + this, SLOT(slotValueChanged(QtProperty*,bool))); + connect(fontPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)), + this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*))); + connect(fontPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)), + this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*))); + // CursorPropertyManager + QtCursorPropertyManager *cursorPropertyManager = new QtCursorPropertyManager(this); + d_ptr->m_typeToPropertyManager[QMetaType::QCursor] = cursorPropertyManager; + d_ptr->m_typeToValueType[QMetaType::QCursor] = QMetaType::QCursor; + connect(cursorPropertyManager, SIGNAL(valueChanged(QtProperty*,QCursor)), + this, SLOT(slotValueChanged(QtProperty*,QCursor))); + // FlagPropertyManager + int flagId = flagTypeId(); + QtFlagPropertyManager *flagPropertyManager = new QtFlagPropertyManager(this); + d_ptr->m_typeToPropertyManager[flagId] = flagPropertyManager; + d_ptr->m_typeToValueType[flagId] = QMetaType::Int; + d_ptr->m_typeToAttributeToAttributeType[flagId][d_ptr->m_flagNamesAttribute] = + QMetaType::QStringList; + connect(flagPropertyManager, SIGNAL(valueChanged(QtProperty*,int)), + this, SLOT(slotValueChanged(QtProperty*,int))); + connect(flagPropertyManager, SIGNAL(flagNamesChanged(QtProperty*,QStringList)), + this, SLOT(slotFlagNamesChanged(QtProperty*,QStringList))); + connect(flagPropertyManager->subBoolPropertyManager(), SIGNAL(valueChanged(QtProperty*,bool)), + this, SLOT(slotValueChanged(QtProperty*,bool))); + connect(flagPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)), + this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*))); + connect(flagPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)), + this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*))); + // FlagPropertyManager + int groupId = groupTypeId(); + QtGroupPropertyManager *groupPropertyManager = new QtGroupPropertyManager(this); + d_ptr->m_typeToPropertyManager[groupId] = groupPropertyManager; + d_ptr->m_typeToValueType[groupId] = QMetaType::UnknownType; +} + +/*! + Destroys this manager, and all the properties it has created. +*/ +QtVariantPropertyManager::~QtVariantPropertyManager() +{ + clear(); +} + +/*! + Returns the given \a property converted into a QtVariantProperty. + + If the \a property was not created by this variant manager, the + function returns 0. + + \sa createProperty() +*/ +QtVariantProperty *QtVariantPropertyManager::variantProperty(const QtProperty *property) const +{ + const QMap >::const_iterator it = d_ptr->m_propertyToType.constFind(property); + if (it == d_ptr->m_propertyToType.constEnd()) + return 0; + return it.value().first; +} + +/*! + Returns true if the given \a propertyType is supported by this + variant manager; otherwise false. + + \sa propertyType() +*/ +bool QtVariantPropertyManager::isPropertyTypeSupported(int propertyType) const +{ + if (d_ptr->m_typeToValueType.contains(propertyType)) + return true; + return false; +} + +/*! + Creates and returns a variant property of the given \a propertyType + with the given \a name. + + If the specified \a propertyType is not supported by this variant + manager, this function returns 0. + + Do not use the inherited + QtAbstractPropertyManager::addProperty() function to create a + variant property (that function will always return 0 since it will + not be clear what type the property should have). + + \sa isPropertyTypeSupported() +*/ +QtVariantProperty *QtVariantPropertyManager::addProperty(int propertyType, const QString &name) +{ + if (!isPropertyTypeSupported(propertyType)) + return 0; + + bool wasCreating = d_ptr->m_creatingProperty; + d_ptr->m_creatingProperty = true; + d_ptr->m_propertyType = propertyType; + QtProperty *property = QtAbstractPropertyManager::addProperty(name); + d_ptr->m_creatingProperty = wasCreating; + d_ptr->m_propertyType = 0; + + if (!property) + return 0; + + return variantProperty(property); +} + +/*! + Returns the given \a property's value. + + If the given \a property is not managed by this manager, this + function returns an invalid variant. + + \sa setValue() +*/ +QVariant QtVariantPropertyManager::value(const QtProperty *property) const +{ + QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + if (internProp == 0) + return QVariant(); + + QtAbstractPropertyManager *manager = internProp->propertyManager(); + if (QtIntPropertyManager *intManager = qobject_cast(manager)) { + return intManager->value(internProp); + } else if (QtDoublePropertyManager *doubleManager = qobject_cast(manager)) { + return doubleManager->value(internProp); + } else if (QtBoolPropertyManager *boolManager = qobject_cast(manager)) { + return boolManager->value(internProp); + } else if (QtStringPropertyManager *stringManager = qobject_cast(manager)) { + return stringManager->value(internProp); + } else if (QtDatePropertyManager *dateManager = qobject_cast(manager)) { + return dateManager->value(internProp); + } else if (QtTimePropertyManager *timeManager = qobject_cast(manager)) { + return timeManager->value(internProp); + } else if (QtDateTimePropertyManager *dateTimeManager = qobject_cast(manager)) { + return dateTimeManager->value(internProp); + } else if (QtKeySequencePropertyManager *keySequenceManager = qobject_cast(manager)) { + return QVariant::fromValue(keySequenceManager->value(internProp)); + } else if (QtCharPropertyManager *charManager = qobject_cast(manager)) { + return charManager->value(internProp); + } else if (QtLocalePropertyManager *localeManager = qobject_cast(manager)) { + return localeManager->value(internProp); + } else if (QtPointPropertyManager *pointManager = qobject_cast(manager)) { + return pointManager->value(internProp); + } else if (QtPointFPropertyManager *pointFManager = qobject_cast(manager)) { + return pointFManager->value(internProp); + } else if (QtSizePropertyManager *sizeManager = qobject_cast(manager)) { + return sizeManager->value(internProp); + } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast(manager)) { + return sizeFManager->value(internProp); + } else if (QtRectPropertyManager *rectManager = qobject_cast(manager)) { + return rectManager->value(internProp); + } else if (QtRectFPropertyManager *rectFManager = qobject_cast(manager)) { + return rectFManager->value(internProp); + } else if (QtColorPropertyManager *colorManager = qobject_cast(manager)) { + return colorManager->value(internProp); + } else if (QtEnumPropertyManager *enumManager = qobject_cast(manager)) { + return enumManager->value(internProp); + } else if (QtSizePolicyPropertyManager *sizePolicyManager = + qobject_cast(manager)) { + return sizePolicyManager->value(internProp); + } else if (QtFontPropertyManager *fontManager = qobject_cast(manager)) { + return fontManager->value(internProp); +#ifndef QT_NO_CURSOR + } else if (QtCursorPropertyManager *cursorManager = qobject_cast(manager)) { + return cursorManager->value(internProp); +#endif + } else if (QtFlagPropertyManager *flagManager = qobject_cast(manager)) { + return flagManager->value(internProp); + } + return QVariant(); +} + +/*! + Returns the given \a property's value type. + + \sa propertyType() +*/ +int QtVariantPropertyManager::valueType(const QtProperty *property) const +{ + int propType = propertyType(property); + return valueType(propType); +} + +/*! + \overload + + Returns the value type associated with the given \a propertyType. +*/ +int QtVariantPropertyManager::valueType(int propertyType) const +{ + if (d_ptr->m_typeToValueType.contains(propertyType)) + return d_ptr->m_typeToValueType[propertyType]; + return 0; +} + +/*! + Returns the given \a property's type. + + \sa valueType() +*/ +int QtVariantPropertyManager::propertyType(const QtProperty *property) const +{ + const QMap >::const_iterator it = d_ptr->m_propertyToType.constFind(property); + if (it == d_ptr->m_propertyToType.constEnd()) + return 0; + return it.value().second; +} + +/*! + Returns the given \a property's value for the specified \a + attribute + + If the given \a property was not created by \e this manager, or if + the specified \a attribute does not exist, this function returns + an invalid variant. + + \sa attributes(), attributeType(), setAttribute() +*/ +QVariant QtVariantPropertyManager::attributeValue(const QtProperty *property, const QString &attribute) const +{ + int propType = propertyType(property); + if (!propType) + return QVariant(); + + QMap >::ConstIterator it = + d_ptr->m_typeToAttributeToAttributeType.find(propType); + if (it == d_ptr->m_typeToAttributeToAttributeType.constEnd()) + return QVariant(); + + QMap attributes = it.value(); + QMap::ConstIterator itAttr = attributes.find(attribute); + if (itAttr == attributes.constEnd()) + return QVariant(); + + QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + if (internProp == 0) + return QVariant(); + + QtAbstractPropertyManager *manager = internProp->propertyManager(); + if (QtIntPropertyManager *intManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + return intManager->maximum(internProp); + if (attribute == d_ptr->m_minimumAttribute) + return intManager->minimum(internProp); + if (attribute == d_ptr->m_singleStepAttribute) + return intManager->singleStep(internProp); + return QVariant(); + } else if (QtDoublePropertyManager *doubleManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + return doubleManager->maximum(internProp); + if (attribute == d_ptr->m_minimumAttribute) + return doubleManager->minimum(internProp); + if (attribute == d_ptr->m_singleStepAttribute) + return doubleManager->singleStep(internProp); + if (attribute == d_ptr->m_decimalsAttribute) + return doubleManager->decimals(internProp); + return QVariant(); + } else if (QtStringPropertyManager *stringManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_regExpAttribute) + return stringManager->regExp(internProp); + return QVariant(); + } else if (QtDatePropertyManager *dateManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + return dateManager->maximum(internProp); + if (attribute == d_ptr->m_minimumAttribute) + return dateManager->minimum(internProp); + return QVariant(); + } else if (QtPointFPropertyManager *pointFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_decimalsAttribute) + return pointFManager->decimals(internProp); + return QVariant(); + } else if (QtSizePropertyManager *sizeManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + return sizeManager->maximum(internProp); + if (attribute == d_ptr->m_minimumAttribute) + return sizeManager->minimum(internProp); + return QVariant(); + } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + return sizeFManager->maximum(internProp); + if (attribute == d_ptr->m_minimumAttribute) + return sizeFManager->minimum(internProp); + if (attribute == d_ptr->m_decimalsAttribute) + return sizeFManager->decimals(internProp); + return QVariant(); + } else if (QtRectPropertyManager *rectManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_constraintAttribute) + return rectManager->constraint(internProp); + return QVariant(); + } else if (QtRectFPropertyManager *rectFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_constraintAttribute) + return rectFManager->constraint(internProp); + if (attribute == d_ptr->m_decimalsAttribute) + return rectFManager->decimals(internProp); + return QVariant(); + } else if (QtEnumPropertyManager *enumManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_enumNamesAttribute) + return enumManager->enumNames(internProp); + if (attribute == d_ptr->m_enumIconsAttribute) { + QVariant v; + v.setValue(enumManager->enumIcons(internProp)); + return v; + } + return QVariant(); + } else if (QtFlagPropertyManager *flagManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_flagNamesAttribute) + return flagManager->flagNames(internProp); + return QVariant(); + } + return QVariant(); +} + +/*! + Returns a list of the given \a propertyType 's attributes. + + \sa attributeValue(), attributeType() +*/ +QStringList QtVariantPropertyManager::attributes(int propertyType) const +{ + QMap >::ConstIterator it = + d_ptr->m_typeToAttributeToAttributeType.find(propertyType); + if (it == d_ptr->m_typeToAttributeToAttributeType.constEnd()) + return QStringList(); + return it.value().keys(); +} + +/*! + Returns the type of the specified \a attribute of the given \a + propertyType. + + If the given \a propertyType is not supported by \e this manager, + or if the given \a propertyType does not possess the specified \a + attribute, this function returns QMetaType::UnknownType. + + \sa attributes(), valueType() +*/ +int QtVariantPropertyManager::attributeType(int propertyType, const QString &attribute) const +{ + QMap >::ConstIterator it = + d_ptr->m_typeToAttributeToAttributeType.find(propertyType); + if (it == d_ptr->m_typeToAttributeToAttributeType.constEnd()) + return 0; + + QMap attributes = it.value(); + QMap::ConstIterator itAttr = attributes.find(attribute); + if (itAttr == attributes.constEnd()) + return 0; + return itAttr.value(); +} + +/*! + \fn void QtVariantPropertyManager::setValue(QtProperty *property, const QVariant &value) + + Sets the value of the given \a property to \a value. + + The specified \a value must be of a type returned by valueType(), + or of type that can be converted to valueType() using the + QVariant::canConvert() function, otherwise this function does + nothing. + + \sa value(), QtVariantProperty::setValue(), valueChanged() +*/ +void QtVariantPropertyManager::setValue(QtProperty *property, const QVariant &val) +{ + int propType = val.userType(); + if (!propType) + return; + + int valType = valueType(property); + + if (propType != valType && !val.canConvert(QMetaType(valType))) + return; + + QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + if (internProp == 0) + return; + + + QtAbstractPropertyManager *manager = internProp->propertyManager(); + if (QtIntPropertyManager *intManager = qobject_cast(manager)) { + intManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtDoublePropertyManager *doubleManager = qobject_cast(manager)) { + doubleManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtBoolPropertyManager *boolManager = qobject_cast(manager)) { + boolManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtStringPropertyManager *stringManager = qobject_cast(manager)) { + stringManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtDatePropertyManager *dateManager = qobject_cast(manager)) { + dateManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtTimePropertyManager *timeManager = qobject_cast(manager)) { + timeManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtDateTimePropertyManager *dateTimeManager = qobject_cast(manager)) { + dateTimeManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtKeySequencePropertyManager *keySequenceManager = qobject_cast(manager)) { + keySequenceManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtCharPropertyManager *charManager = qobject_cast(manager)) { + charManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtLocalePropertyManager *localeManager = qobject_cast(manager)) { + localeManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtPointPropertyManager *pointManager = qobject_cast(manager)) { + pointManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtPointFPropertyManager *pointFManager = qobject_cast(manager)) { + pointFManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtSizePropertyManager *sizeManager = qobject_cast(manager)) { + sizeManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast(manager)) { + sizeFManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtRectPropertyManager *rectManager = qobject_cast(manager)) { + rectManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtRectFPropertyManager *rectFManager = qobject_cast(manager)) { + rectFManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtColorPropertyManager *colorManager = qobject_cast(manager)) { + colorManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtEnumPropertyManager *enumManager = qobject_cast(manager)) { + enumManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtSizePolicyPropertyManager *sizePolicyManager = + qobject_cast(manager)) { + sizePolicyManager->setValue(internProp, qvariant_cast(val)); + return; + } else if (QtFontPropertyManager *fontManager = qobject_cast(manager)) { + fontManager->setValue(internProp, qvariant_cast(val)); + return; +#ifndef QT_NO_CURSOR + } else if (QtCursorPropertyManager *cursorManager = qobject_cast(manager)) { + cursorManager->setValue(internProp, qvariant_cast(val)); + return; +#endif + } else if (QtFlagPropertyManager *flagManager = qobject_cast(manager)) { + flagManager->setValue(internProp, qvariant_cast(val)); + return; + } +} + +/*! + Sets the value of the specified \a attribute of the given \a + property, to \a value. + + The new \a value's type must be of the type returned by + attributeType(), or of a type that can be converted to + attributeType() using the QVariant::canConvert() function, + otherwise this function does nothing. + + \sa attributeValue(), QtVariantProperty::setAttribute(), attributeChanged() +*/ +void QtVariantPropertyManager::setAttribute(QtProperty *property, + const QString &attribute, const QVariant &value) +{ + QVariant oldAttr = attributeValue(property, attribute); + if (!oldAttr.isValid()) + return; + + int attrType = value.userType(); + if (!attrType) + return; + + if (attrType != attributeType(propertyType(property), attribute) && + !value.canConvert(QMetaType(attrType))) + return; + + QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + if (internProp == 0) + return; + + QtAbstractPropertyManager *manager = internProp->propertyManager(); + if (QtIntPropertyManager *intManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + intManager->setMaximum(internProp, qvariant_cast(value)); + else if (attribute == d_ptr->m_minimumAttribute) + intManager->setMinimum(internProp, qvariant_cast(value)); + else if (attribute == d_ptr->m_singleStepAttribute) + intManager->setSingleStep(internProp, qvariant_cast(value)); + return; + } else if (QtDoublePropertyManager *doubleManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + doubleManager->setMaximum(internProp, qvariant_cast(value)); + if (attribute == d_ptr->m_minimumAttribute) + doubleManager->setMinimum(internProp, qvariant_cast(value)); + if (attribute == d_ptr->m_singleStepAttribute) + doubleManager->setSingleStep(internProp, qvariant_cast(value)); + if (attribute == d_ptr->m_decimalsAttribute) + doubleManager->setDecimals(internProp, qvariant_cast(value)); + return; + } else if (QtStringPropertyManager *stringManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_regExpAttribute) + stringManager->setRegExp(internProp, qvariant_cast(value)); + return; + } else if (QtDatePropertyManager *dateManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + dateManager->setMaximum(internProp, qvariant_cast(value)); + if (attribute == d_ptr->m_minimumAttribute) + dateManager->setMinimum(internProp, qvariant_cast(value)); + return; + } else if (QtPointFPropertyManager *pointFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_decimalsAttribute) + pointFManager->setDecimals(internProp, qvariant_cast(value)); + return; + } else if (QtSizePropertyManager *sizeManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + sizeManager->setMaximum(internProp, qvariant_cast(value)); + if (attribute == d_ptr->m_minimumAttribute) + sizeManager->setMinimum(internProp, qvariant_cast(value)); + return; + } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_maximumAttribute) + sizeFManager->setMaximum(internProp, qvariant_cast(value)); + if (attribute == d_ptr->m_minimumAttribute) + sizeFManager->setMinimum(internProp, qvariant_cast(value)); + if (attribute == d_ptr->m_decimalsAttribute) + sizeFManager->setDecimals(internProp, qvariant_cast(value)); + return; + } else if (QtRectPropertyManager *rectManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_constraintAttribute) + rectManager->setConstraint(internProp, qvariant_cast(value)); + return; + } else if (QtRectFPropertyManager *rectFManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_constraintAttribute) + rectFManager->setConstraint(internProp, qvariant_cast(value)); + if (attribute == d_ptr->m_decimalsAttribute) + rectFManager->setDecimals(internProp, qvariant_cast(value)); + return; + } else if (QtEnumPropertyManager *enumManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_enumNamesAttribute) + enumManager->setEnumNames(internProp, qvariant_cast(value)); + if (attribute == d_ptr->m_enumIconsAttribute) + enumManager->setEnumIcons(internProp, qvariant_cast(value)); + return; + } else if (QtFlagPropertyManager *flagManager = qobject_cast(manager)) { + if (attribute == d_ptr->m_flagNamesAttribute) + flagManager->setFlagNames(internProp, qvariant_cast(value)); + return; + } +} + +/*! + \internal +*/ +bool QtVariantPropertyManager::hasValue(const QtProperty *property) const +{ + if (propertyType(property) == groupTypeId()) + return false; + return true; +} + +/*! + \internal +*/ +QString QtVariantPropertyManager::valueText(const QtProperty *property) const +{ + const QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + return internProp ? internProp->valueText() : QString(); +} + +/*! + \internal +*/ +QIcon QtVariantPropertyManager::valueIcon(const QtProperty *property) const +{ + const QtProperty *internProp = propertyToWrappedProperty()->value(property, 0); + return internProp ? internProp->valueIcon() : QIcon(); +} + +/*! + \internal +*/ +void QtVariantPropertyManager::initializeProperty(QtProperty *property) +{ + QtVariantProperty *varProp = variantProperty(property); + if (!varProp) + return; + + QMap::ConstIterator it = + d_ptr->m_typeToPropertyManager.find(d_ptr->m_propertyType); + if (it != d_ptr->m_typeToPropertyManager.constEnd()) { + QtProperty *internProp = 0; + if (!d_ptr->m_creatingSubProperties) { + QtAbstractPropertyManager *manager = it.value(); + internProp = manager->addProperty(); + d_ptr->m_internalToProperty[internProp] = varProp; + } + propertyToWrappedProperty()->insert(varProp, internProp); + if (internProp) { + const auto children = internProp->subProperties(); + QtVariantProperty *lastProperty = 0; + for (QtProperty *child : children) { + QtVariantProperty *prop = d_ptr->createSubProperty(varProp, lastProperty, child); + lastProperty = prop ? prop : lastProperty; + } + } + } +} + +/*! + \internal +*/ +void QtVariantPropertyManager::uninitializeProperty(QtProperty *property) +{ + const QMap >::iterator type_it = d_ptr->m_propertyToType.find(property); + if (type_it == d_ptr->m_propertyToType.end()) + return; + + PropertyMap::iterator it = propertyToWrappedProperty()->find(property); + if (it != propertyToWrappedProperty()->end()) { + QtProperty *internProp = it.value(); + if (internProp) { + d_ptr->m_internalToProperty.remove(internProp); + if (!d_ptr->m_destroyingSubProperties) { + delete internProp; + } + } + propertyToWrappedProperty()->erase(it); + } + d_ptr->m_propertyToType.erase(type_it); +} + +/*! + \internal +*/ +QtProperty *QtVariantPropertyManager::createProperty() +{ + if (!d_ptr->m_creatingProperty) + return 0; + + QtVariantProperty *property = new QtVariantProperty(this); + d_ptr->m_propertyToType.insert(property, qMakePair(property, d_ptr->m_propertyType)); + + return property; +} + +///////////////////////////// + +class QtVariantEditorFactoryPrivate +{ + QtVariantEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtVariantEditorFactory) +public: + + QtSpinBoxFactory *m_spinBoxFactory; + QtDoubleSpinBoxFactory *m_doubleSpinBoxFactory; + QtCheckBoxFactory *m_checkBoxFactory; + QtLineEditFactory *m_lineEditFactory; + QtDateEditFactory *m_dateEditFactory; + QtTimeEditFactory *m_timeEditFactory; + QtDateTimeEditFactory *m_dateTimeEditFactory; + QtKeySequenceEditorFactory *m_keySequenceEditorFactory; + QtCharEditorFactory *m_charEditorFactory; + QtEnumEditorFactory *m_comboBoxFactory; + QtCursorEditorFactory *m_cursorEditorFactory; + QtColorEditorFactory *m_colorEditorFactory; + QtFontEditorFactory *m_fontEditorFactory; + + QMap m_factoryToType; + QMap m_typeToFactory; +}; + +/*! + \class QtVariantEditorFactory + \internal + \inmodule QtDesigner + \since 4.4 + + \brief The QtVariantEditorFactory class provides widgets for properties + created by QtVariantPropertyManager objects. + + The variant factory provides the following widgets for the + specified property types: + + \table + \header + \li Property Type + \li Widget + \row + \li \c int + \li QSpinBox + \row + \li \c double + \li QDoubleSpinBox + \row + \li \c bool + \li QCheckBox + \row + \li QString + \li QLineEdit + \row + \li QDate + \li QDateEdit + \row + \li QTime + \li QTimeEdit + \row + \li QDateTime + \li QDateTimeEdit + \row + \li QKeySequence + \li customized editor + \row + \li QChar + \li customized editor + \row + \li \c enum + \li QComboBox + \row + \li QCursor + \li QComboBox + \endtable + + Note that QtVariantPropertyManager supports several additional property + types for which the QtVariantEditorFactory class does not provide + editing widgets, e.g. QPoint and QSize. To provide widgets for other + types using the variant approach, derive from the QtVariantEditorFactory + class. + + \sa QtAbstractEditorFactory, QtVariantPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtVariantEditorFactory::QtVariantEditorFactory(QObject *parent) + : QtAbstractEditorFactory(parent), d_ptr(new QtVariantEditorFactoryPrivate()) +{ + d_ptr->q_ptr = this; + + d_ptr->m_spinBoxFactory = new QtSpinBoxFactory(this); + d_ptr->m_factoryToType[d_ptr->m_spinBoxFactory] = QMetaType::Int; + d_ptr->m_typeToFactory[QMetaType::Int] = d_ptr->m_spinBoxFactory; + + d_ptr->m_doubleSpinBoxFactory = new QtDoubleSpinBoxFactory(this); + d_ptr->m_factoryToType[d_ptr->m_doubleSpinBoxFactory] = QMetaType::Double; + d_ptr->m_typeToFactory[QMetaType::Double] = d_ptr->m_doubleSpinBoxFactory; + + d_ptr->m_checkBoxFactory = new QtCheckBoxFactory(this); + d_ptr->m_factoryToType[d_ptr->m_checkBoxFactory] = QMetaType::Bool; + d_ptr->m_typeToFactory[QMetaType::Bool] = d_ptr->m_checkBoxFactory; + + d_ptr->m_lineEditFactory = new QtLineEditFactory(this); + d_ptr->m_factoryToType[d_ptr->m_lineEditFactory] = QMetaType::QString; + d_ptr->m_typeToFactory[QMetaType::QString] = d_ptr->m_lineEditFactory; + + d_ptr->m_dateEditFactory = new QtDateEditFactory(this); + d_ptr->m_factoryToType[d_ptr->m_dateEditFactory] = QMetaType::QDate; + d_ptr->m_typeToFactory[QMetaType::QDate] = d_ptr->m_dateEditFactory; + + d_ptr->m_timeEditFactory = new QtTimeEditFactory(this); + d_ptr->m_factoryToType[d_ptr->m_timeEditFactory] = QMetaType::QTime; + d_ptr->m_typeToFactory[QMetaType::QTime] = d_ptr->m_timeEditFactory; + + d_ptr->m_dateTimeEditFactory = new QtDateTimeEditFactory(this); + d_ptr->m_factoryToType[d_ptr->m_dateTimeEditFactory] = QMetaType::QDateTime; + d_ptr->m_typeToFactory[QMetaType::QDateTime] = d_ptr->m_dateTimeEditFactory; + + d_ptr->m_keySequenceEditorFactory = new QtKeySequenceEditorFactory(this); + d_ptr->m_factoryToType[d_ptr->m_keySequenceEditorFactory] = QMetaType::QKeySequence; + d_ptr->m_typeToFactory[QMetaType::QKeySequence] = d_ptr->m_keySequenceEditorFactory; + + d_ptr->m_charEditorFactory = new QtCharEditorFactory(this); + d_ptr->m_factoryToType[d_ptr->m_charEditorFactory] = QMetaType::QChar; + d_ptr->m_typeToFactory[QMetaType::QChar] = d_ptr->m_charEditorFactory; + + d_ptr->m_cursorEditorFactory = new QtCursorEditorFactory(this); + d_ptr->m_factoryToType[d_ptr->m_cursorEditorFactory] = QMetaType::QCursor; + d_ptr->m_typeToFactory[QMetaType::QCursor] = d_ptr->m_cursorEditorFactory; + + d_ptr->m_colorEditorFactory = new QtColorEditorFactory(this); + d_ptr->m_factoryToType[d_ptr->m_colorEditorFactory] = QMetaType::QColor; + d_ptr->m_typeToFactory[QMetaType::QColor] = d_ptr->m_colorEditorFactory; + + d_ptr->m_fontEditorFactory = new QtFontEditorFactory(this); + d_ptr->m_factoryToType[d_ptr->m_fontEditorFactory] = QMetaType::QFont; + d_ptr->m_typeToFactory[QMetaType::QFont] = d_ptr->m_fontEditorFactory; + + d_ptr->m_comboBoxFactory = new QtEnumEditorFactory(this); + const int enumId = QtVariantPropertyManager::enumTypeId(); + d_ptr->m_factoryToType[d_ptr->m_comboBoxFactory] = enumId; + d_ptr->m_typeToFactory[enumId] = d_ptr->m_comboBoxFactory; +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtVariantEditorFactory::~QtVariantEditorFactory() +{ +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtVariantEditorFactory::connectPropertyManager(QtVariantPropertyManager *manager) +{ + const auto intPropertyManagers = manager->findChildren(); + for (QtIntPropertyManager *manager : intPropertyManagers) + d_ptr->m_spinBoxFactory->addPropertyManager(manager); + + const auto doublePropertyManagers = manager->findChildren(); + for (QtDoublePropertyManager *manager : doublePropertyManagers) + d_ptr->m_doubleSpinBoxFactory->addPropertyManager(manager); + + const auto boolPropertyManagers = manager->findChildren(); + for (QtBoolPropertyManager *manager : boolPropertyManagers) + d_ptr->m_checkBoxFactory->addPropertyManager(manager); + + const auto stringPropertyManagers = manager->findChildren(); + for (QtStringPropertyManager *manager : stringPropertyManagers) + d_ptr->m_lineEditFactory->addPropertyManager(manager); + + const auto datePropertyManagers = manager->findChildren(); + for (QtDatePropertyManager *manager : datePropertyManagers) + d_ptr->m_dateEditFactory->addPropertyManager(manager); + + const auto timePropertyManagers = manager->findChildren(); + for (QtTimePropertyManager *manager : timePropertyManagers) + d_ptr->m_timeEditFactory->addPropertyManager(manager); + + const auto dateTimePropertyManagers = manager->findChildren(); + for (QtDateTimePropertyManager *manager : dateTimePropertyManagers) + d_ptr->m_dateTimeEditFactory->addPropertyManager(manager); + + const auto keySequencePropertyManagers = manager->findChildren(); + for (QtKeySequencePropertyManager *manager : keySequencePropertyManagers) + d_ptr->m_keySequenceEditorFactory->addPropertyManager(manager); + + const auto charPropertyManagers = manager->findChildren(); + for (QtCharPropertyManager *manager : charPropertyManagers) + d_ptr->m_charEditorFactory->addPropertyManager(manager); + + const auto localePropertyManagers = manager->findChildren(); + for (QtLocalePropertyManager *manager : localePropertyManagers) + d_ptr->m_comboBoxFactory->addPropertyManager(manager->subEnumPropertyManager()); + + const auto pointPropertyManagers = manager->findChildren(); + for (QtPointPropertyManager *manager : pointPropertyManagers) + d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager()); + + const auto pointFPropertyManagers = manager->findChildren(); + for (QtPointFPropertyManager *manager : pointFPropertyManagers) + d_ptr->m_doubleSpinBoxFactory->addPropertyManager(manager->subDoublePropertyManager()); + + const auto sizePropertyManagers = manager->findChildren(); + for (QtSizePropertyManager *manager : sizePropertyManagers) + d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager()); + + const auto sizeFPropertyManagers = manager->findChildren(); + for (QtSizeFPropertyManager *manager : sizeFPropertyManagers) + d_ptr->m_doubleSpinBoxFactory->addPropertyManager(manager->subDoublePropertyManager()); + + const auto rectPropertyManagers = manager->findChildren(); + for (QtRectPropertyManager *manager : rectPropertyManagers) + d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager()); + + const auto rectFPropertyManagers = manager->findChildren(); + for (QtRectFPropertyManager *manager : rectFPropertyManagers) + d_ptr->m_doubleSpinBoxFactory->addPropertyManager(manager->subDoublePropertyManager()); + + const auto colorPropertyManagers = manager->findChildren(); + for (QtColorPropertyManager *manager : colorPropertyManagers) { + d_ptr->m_colorEditorFactory->addPropertyManager(manager); + d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager()); + } + + const auto enumPropertyManagers = manager->findChildren(); + for (QtEnumPropertyManager *manager : enumPropertyManagers) + d_ptr->m_comboBoxFactory->addPropertyManager(manager); + + const auto sizePolicyPropertyManagers = manager->findChildren(); + for (QtSizePolicyPropertyManager *manager : sizePolicyPropertyManagers) { + d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager()); + d_ptr->m_comboBoxFactory->addPropertyManager(manager->subEnumPropertyManager()); + } + + const auto fontPropertyManagers = manager->findChildren(); + for (QtFontPropertyManager *manager : fontPropertyManagers) { + d_ptr->m_fontEditorFactory->addPropertyManager(manager); + d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager()); + d_ptr->m_comboBoxFactory->addPropertyManager(manager->subEnumPropertyManager()); + d_ptr->m_checkBoxFactory->addPropertyManager(manager->subBoolPropertyManager()); + } + + const auto cursorPropertyManagers = manager->findChildren(); + for (QtCursorPropertyManager *manager : cursorPropertyManagers) + d_ptr->m_cursorEditorFactory->addPropertyManager(manager); + + const auto flagPropertyManagers = manager->findChildren(); + for (QtFlagPropertyManager *manager : flagPropertyManagers) + d_ptr->m_checkBoxFactory->addPropertyManager(manager->subBoolPropertyManager()); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtVariantEditorFactory::createEditor(QtVariantPropertyManager *manager, QtProperty *property, + QWidget *parent) +{ + const int propType = manager->propertyType(property); + QtAbstractEditorFactoryBase *factory = d_ptr->m_typeToFactory.value(propType, 0); + if (!factory) + return 0; + return factory->createEditor(wrappedProperty(property), parent); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtVariantEditorFactory::disconnectPropertyManager(QtVariantPropertyManager *manager) +{ + const auto intPropertyManagers = manager->findChildren(); + for (QtIntPropertyManager *manager : intPropertyManagers) + d_ptr->m_spinBoxFactory->removePropertyManager(manager); + + const auto doublePropertyManagers = manager->findChildren(); + for (QtDoublePropertyManager *manager : doublePropertyManagers) + d_ptr->m_doubleSpinBoxFactory->removePropertyManager(manager); + + const auto boolPropertyManagers = manager->findChildren(); + for (QtBoolPropertyManager *manager : boolPropertyManagers) + d_ptr->m_checkBoxFactory->removePropertyManager(manager); + + const auto stringPropertyManagers = manager->findChildren(); + for (QtStringPropertyManager *manager : stringPropertyManagers) + d_ptr->m_lineEditFactory->removePropertyManager(manager); + + const auto datePropertyManagers = manager->findChildren(); + for (QtDatePropertyManager *manager : datePropertyManagers) + d_ptr->m_dateEditFactory->removePropertyManager(manager); + + const auto timePropertyManagers = manager->findChildren(); + for (QtTimePropertyManager *manager : timePropertyManagers) + d_ptr->m_timeEditFactory->removePropertyManager(manager); + + const auto dateTimePropertyManagers = manager->findChildren(); + for (QtDateTimePropertyManager *manager : dateTimePropertyManagers) + d_ptr->m_dateTimeEditFactory->removePropertyManager(manager); + + const auto keySequencePropertyManagers = manager->findChildren(); + for (QtKeySequencePropertyManager *manager : keySequencePropertyManagers) + d_ptr->m_keySequenceEditorFactory->removePropertyManager(manager); + + const auto charPropertyManagers = manager->findChildren(); + for (QtCharPropertyManager *manager : charPropertyManagers) + d_ptr->m_charEditorFactory->removePropertyManager(manager); + + const auto localePropertyManagers = manager->findChildren(); + for (QtLocalePropertyManager *manager : localePropertyManagers) + d_ptr->m_comboBoxFactory->removePropertyManager(manager->subEnumPropertyManager()); + + const auto pointPropertyManagers = manager->findChildren(); + for (QtPointPropertyManager *manager : pointPropertyManagers) + d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager()); + + const auto pointFPropertyManagers = manager->findChildren(); + for (QtPointFPropertyManager *manager : pointFPropertyManagers) + d_ptr->m_doubleSpinBoxFactory->removePropertyManager(manager->subDoublePropertyManager()); + + const auto sizePropertyManagers = manager->findChildren(); + for (QtSizePropertyManager *manager : sizePropertyManagers) + d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager()); + + const auto sizeFPropertyManagers = manager->findChildren(); + for (QtSizeFPropertyManager *manager : sizeFPropertyManagers) + d_ptr->m_doubleSpinBoxFactory->removePropertyManager(manager->subDoublePropertyManager()); + + const auto rectPropertyManagers = manager->findChildren(); + for (QtRectPropertyManager *manager : rectPropertyManagers) + d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager()); + + const auto rectFPropertyManagers = manager->findChildren(); + for (QtRectFPropertyManager *manager : rectFPropertyManagers) + d_ptr->m_doubleSpinBoxFactory->removePropertyManager(manager->subDoublePropertyManager()); + + const auto colorPropertyManagers = manager->findChildren(); + for (QtColorPropertyManager *manager : colorPropertyManagers) { + d_ptr->m_colorEditorFactory->removePropertyManager(manager); + d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager()); + } + + const auto enumPropertyManagers = manager->findChildren(); + for (QtEnumPropertyManager *manager : enumPropertyManagers) + d_ptr->m_comboBoxFactory->removePropertyManager(manager); + + const auto sizePolicyPropertyManagers = manager->findChildren(); + for (QtSizePolicyPropertyManager *manager : sizePolicyPropertyManagers) { + d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager()); + d_ptr->m_comboBoxFactory->removePropertyManager(manager->subEnumPropertyManager()); + } + + const auto fontPropertyManagers = manager->findChildren(); + for (QtFontPropertyManager *manager : fontPropertyManagers) { + d_ptr->m_fontEditorFactory->removePropertyManager(manager); + d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager()); + d_ptr->m_comboBoxFactory->removePropertyManager(manager->subEnumPropertyManager()); + d_ptr->m_checkBoxFactory->removePropertyManager(manager->subBoolPropertyManager()); + } + + const auto cursorPropertyManagers = manager->findChildren(); + for (QtCursorPropertyManager *manager : cursorPropertyManagers) + d_ptr->m_cursorEditorFactory->removePropertyManager(manager); + + const auto flagPropertyManagers = manager->findChildren(); + for (QtFlagPropertyManager *manager : flagPropertyManagers) + d_ptr->m_checkBoxFactory->removePropertyManager(manager->subBoolPropertyManager()); +} + +QT_END_NAMESPACE + +#include "moc_qtvariantproperty.cpp" diff --git a/external/QtPropertyBrowser/src/qtvariantproperty.h b/external/QtPropertyBrowser/src/qtvariantproperty.h new file mode 100644 index 000000000..440dbd905 --- /dev/null +++ b/external/QtPropertyBrowser/src/qtvariantproperty.h @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTVARIANTPROPERTY_H +#define QTVARIANTPROPERTY_H + +#include "qtpropertybrowser.h" +#include +#include + +QT_BEGIN_NAMESPACE + +class QRegularExpression; + +typedef QMap QtIconMap; + +class QtVariantPropertyManager; + +class QT_QTPROPERTYBROWSER_EXPORT QtVariantProperty : public QtProperty +{ +public: + ~QtVariantProperty(); + QVariant value() const; + QVariant attributeValue(const QString &attribute) const; + int valueType() const; + int propertyType() const; + + void setValue(const QVariant &value); + void setAttribute(const QString &attribute, const QVariant &value); +protected: + QtVariantProperty(QtVariantPropertyManager *manager); +private: + friend class QtVariantPropertyManager; + QScopedPointer d_ptr; +}; + +class QT_QTPROPERTYBROWSER_EXPORT QtVariantPropertyManager : public QtAbstractPropertyManager +{ + Q_OBJECT +public: + QtVariantPropertyManager(QObject *parent = 0); + ~QtVariantPropertyManager(); + + virtual QtVariantProperty *addProperty(int propertyType, const QString &name = QString()); + + int propertyType(const QtProperty *property) const; + int valueType(const QtProperty *property) const; + QtVariantProperty *variantProperty(const QtProperty *property) const; + + virtual bool isPropertyTypeSupported(int propertyType) const; + virtual int valueType(int propertyType) const; + virtual QStringList attributes(int propertyType) const; + virtual int attributeType(int propertyType, const QString &attribute) const; + + virtual QVariant value(const QtProperty *property) const; + virtual QVariant attributeValue(const QtProperty *property, const QString &attribute) const; + + static int enumTypeId(); + static int flagTypeId(); + static int groupTypeId(); + static int iconMapTypeId(); +public Q_SLOTS: + virtual void setValue(QtProperty *property, const QVariant &val); + virtual void setAttribute(QtProperty *property, + const QString &attribute, const QVariant &value); +Q_SIGNALS: + void valueChanged(QtProperty *property, const QVariant &val); + void attributeChanged(QtProperty *property, + const QString &attribute, const QVariant &val); +protected: + bool hasValue(const QtProperty *property) const override; + QString valueText(const QtProperty *property) const override; + QIcon valueIcon(const QtProperty *property) const override; + void initializeProperty(QtProperty *property) override; + void uninitializeProperty(QtProperty *property) override; + QtProperty *createProperty() override; +private: + QScopedPointer d_ptr; + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, double, double)) + Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, double)) + Q_PRIVATE_SLOT(d_func(), void slotDecimalsChanged(QtProperty *, int)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, bool)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QString &)) + Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty *, const QRegularExpression &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, QDate)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, QDate, QDate)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, QTime)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QDateTime &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QKeySequence &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QChar &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QLocale &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QPoint &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QPointF &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QSize &)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, const QSize &, const QSize &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QSizeF &)) + Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, const QSizeF &, const QSizeF &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QRect &)) + Q_PRIVATE_SLOT(d_func(), void slotConstraintChanged(QtProperty *, const QRect &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QRectF &)) + Q_PRIVATE_SLOT(d_func(), void slotConstraintChanged(QtProperty *, const QRectF &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QColor &)) + Q_PRIVATE_SLOT(d_func(), void slotEnumNamesChanged(QtProperty *, const QStringList &)) + Q_PRIVATE_SLOT(d_func(), void slotEnumIconsChanged(QtProperty *, const QMap &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QSizePolicy &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QFont &)) + Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QCursor &)) + Q_PRIVATE_SLOT(d_func(), void slotFlagNamesChanged(QtProperty *, const QStringList &)) + + Q_PRIVATE_SLOT(d_func(), void slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *)) + Q_PRIVATE_SLOT(d_func(), void slotPropertyRemoved(QtProperty *, QtProperty *)) + Q_DECLARE_PRIVATE(QtVariantPropertyManager) + Q_DISABLE_COPY_MOVE(QtVariantPropertyManager) +}; + +class QT_QTPROPERTYBROWSER_EXPORT QtVariantEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtVariantEditorFactory(QObject *parent = 0); + ~QtVariantEditorFactory(); +protected: + void connectPropertyManager(QtVariantPropertyManager *manager) override; + QWidget *createEditor(QtVariantPropertyManager *manager, QtProperty *property, + QWidget *parent) override; + void disconnectPropertyManager(QtVariantPropertyManager *manager) override; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QtVariantEditorFactory) + Q_DISABLE_COPY_MOVE(QtVariantEditorFactory) +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QIcon) +Q_DECLARE_METATYPE(QtIconMap) +#endif From 64f99bf120ab41d314565fd33433629bd47e2704 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Wed, 16 Jul 2025 15:33:31 +0330 Subject: [PATCH 017/124] Add dockable panel for properties --- .../include/FloatingProperties.hpp | 91 ++++ .../include/GraphEditorMainWindow.hpp | 16 +- .../src/FloatingProperties.cpp | 513 ++++++++++++++++++ .../src/GraphEditorMainWindow.cpp | 159 +++++- 4 files changed, 771 insertions(+), 8 deletions(-) create mode 100644 examples/epen_graph_editor/include/FloatingProperties.hpp create mode 100644 examples/epen_graph_editor/src/FloatingProperties.cpp diff --git a/examples/epen_graph_editor/include/FloatingProperties.hpp b/examples/epen_graph_editor/include/FloatingProperties.hpp new file mode 100644 index 000000000..058259c03 --- /dev/null +++ b/examples/epen_graph_editor/include/FloatingProperties.hpp @@ -0,0 +1,91 @@ +#ifndef FLOATINGPROPERTIES_HPP +#define FLOATINGPROPERTIES_HPP + +#include +#include + +QT_BEGIN_NAMESPACE +class QVBoxLayout; +class QScrollArea; +class QLabel; +class QLineEdit; +class QSpinBox; +class QDoubleSpinBox; +class QCheckBox; +class QComboBox; +QT_END_NAMESPACE + +class GraphEditorWindow; + +class FloatingProperties : public QWidget +{ + Q_OBJECT + +public: + enum DockPosition { + Floating, + DockedLeft, + DockedRight + }; + + explicit FloatingProperties(GraphEditorWindow *parent = nullptr); + + void setDockPosition(DockPosition position); + DockPosition dockPosition() const { return m_dockPosition; } + bool isDocked() const { return m_dockPosition != Floating; } + void updatePosition(); + +signals: + void propertyChanged(const QString &name, const QVariant &value); + void nodeSelected(int nodeId); + void nodeDeselected(); + +public slots: + void updatePropertiesForNode(int nodeId); + void clearProperties(); + +protected: + void paintEvent(QPaintEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void showEvent(QShowEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + +private: + void setupUI(); + void connectSignals(); + DockPosition checkDockingZone(const QPoint &pos); + void applyDocking(DockPosition position); + void updateDockedGeometry(); + void clearPropertyWidgets(); + void addPropertyWidget(const QString &label, QWidget *widget); + + GraphEditorWindow *m_graphEditor; + QVBoxLayout *m_layout; + QVBoxLayout *m_propertiesLayout; + QWidget *m_contentWidget; + QScrollArea *m_scrollArea; + QPropertyAnimation *m_geometryAnimation; + + // Dragging state + bool m_dragging; + QPoint m_dragStartPosition; + DockPosition m_dockPosition; + DockPosition m_previewDockPosition; + QRect m_floatingGeometry; + + // Docking settings + int m_dockMargin; + int m_dockingDistance; + int m_dockedWidth; + int m_floatHeight; + + // Current node + int m_currentNodeId; + + // Property widgets + QList m_propertyWidgets; +}; + +#endif // FLOATINGPROPERTIES_HPP \ No newline at end of file diff --git a/examples/epen_graph_editor/include/GraphEditorMainWindow.hpp b/examples/epen_graph_editor/include/GraphEditorMainWindow.hpp index c5deb9c84..43b14ad5b 100644 --- a/examples/epen_graph_editor/include/GraphEditorMainWindow.hpp +++ b/examples/epen_graph_editor/include/GraphEditorMainWindow.hpp @@ -16,6 +16,7 @@ using QtNodes::DataFlowGraphModel; using QtNodes::GraphicsView; class FloatingToolbar; +class FloatingProperties; class SimpleGraphModel; class GraphEditorWindow : public GraphicsView @@ -27,11 +28,16 @@ class GraphEditorWindow : public GraphicsView public slots: // Slot for creating a node at a specific position - void createNodeAtPosition(const QPointF &scenePos,const QString nodeType); + void createNodeAtPosition(const QPointF &scenePos, const QString nodeType); // Slot for creating a node at cursor position void createNodeAtCursor(); void goToMode(QString mode); + + // Slots for node selection and property changes + void onNodeSelected(int nodeId); + void onNodeDeselected(); + void onPropertyChanged(const QString &name, const QVariant &value); protected: // Override to maintain toolbar position @@ -45,13 +51,17 @@ public slots: private: void createFloatingToolbar(); + void createFloatingProperties(); void setupNodeCreation(); QPointer m_toolbar; - //SimpleGraphModel *m_graphModel; - bool m_toolbarCreated; // This was missing! + QPointer m_properties; + + bool m_toolbarCreated; + bool m_propertiesCreated; QString _currentMode; DataFlowModel *_model; + int m_currentSelectedNodeId; }; #endif // GRAPH_EDITOR_WINDOW \ No newline at end of file diff --git a/examples/epen_graph_editor/src/FloatingProperties.cpp b/examples/epen_graph_editor/src/FloatingProperties.cpp new file mode 100644 index 000000000..8b43069f3 --- /dev/null +++ b/examples/epen_graph_editor/src/FloatingProperties.cpp @@ -0,0 +1,513 @@ +#include "FloatingProperties.hpp" +#include "GraphEditorMainWindow.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +FloatingProperties::FloatingProperties(GraphEditorWindow *parent) + : QWidget(parent) + , m_graphEditor(parent) + , m_dragging(false) + , m_dockPosition(Floating) + , m_previewDockPosition(Floating) + , m_dockMargin(0) + , m_dockingDistance(40) + , m_dockedWidth(250) // Wider for properties + , m_currentNodeId(-1) +{ + // Keep it as a child widget with these flags + setWindowFlags(Qt::SubWindow | Qt::FramelessWindowHint); + setAttribute(Qt::WA_TranslucentBackground); + + // Create animation for smooth transitions + m_geometryAnimation = new QPropertyAnimation(this, "geometry"); + m_geometryAnimation->setDuration(200); + m_geometryAnimation->setEasingCurve(QEasingCurve::OutCubic); + + setupUI(); + connectSignals(); + + // Initial floating size and position + setFixedWidth(200); + if (parent) { + // Position on the right side by default + m_floatingGeometry = QRect(parent->width() - 220, + 20, + 200, + height()); + setGeometry(m_floatingGeometry); + } + + // Ensure properties panel is on top + raise(); + m_floatHeight = height(); + + // Start docked to the right by default + setDockPosition(DockPosition::DockedRight); +} + +void FloatingProperties::setupUI() +{ + // Create scroll area for when docked + m_scrollArea = new QScrollArea(this); + m_scrollArea->setWidgetResizable(true); + m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + m_scrollArea->setFrameShape(QFrame::NoFrame); + + m_contentWidget = new QWidget(); + m_contentWidget->setObjectName("PropertiesContent"); + + QFont labelFont = QApplication::font(); + labelFont.setPointSize(10); + + m_scrollArea->setStyleSheet("QScrollArea {" + " background: transparent;" + " border: none;" + "}" + "QScrollBar:vertical {" + " background: #f0f0f0;" + " width: 10px;" + " border-radius: 5px;" + "}" + "QScrollBar::handle:vertical {" + " background: #c0c0c0;" + " border-radius: 5px;" + " min-height: 20px;" + "}" + "QScrollBar::handle:vertical:hover {" + " background: #a0a0a0;" + "}"); + + m_contentWidget->setStyleSheet("#PropertiesContent {" + " background-color: #f5f5f5;" + " border: 1px solid #ccc;" + " border-radius: 6px;" + "}" + "QLabel {" + " color: #555;" + " font-size: 10px;" + " font-weight: bold;" + " margin-top: 5px;" + "}" + "QLineEdit, QSpinBox, QDoubleSpinBox, QComboBox {" + " padding: 4px 6px;" + " border: 1px solid #bbb;" + " border-radius: 3px;" + " background-color: white;" + " font-size: 11px;" + "}" + "QLineEdit:focus, QSpinBox:focus, QDoubleSpinBox:focus, QComboBox:focus {" + " border-color: #0078d4;" + " outline: none;" + "}" + "QCheckBox {" + " font-size: 11px;" + " spacing: 5px;" + "}" + "QCheckBox::indicator {" + " width: 16px;" + " height: 16px;" + "}"); + + // Set scroll area content + m_scrollArea->setWidget(m_contentWidget); + + // Main layout for this widget + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->addWidget(m_scrollArea); + + // Content layout + m_layout = new QVBoxLayout(m_contentWidget); + m_layout->setContentsMargins(8, 8, 8, 8); + m_layout->setSpacing(4); + + // Title bar for dragging + QLabel *title = new QLabel("Properties"); + title->setAlignment(Qt::AlignCenter); + title->setStyleSheet("font-weight: bold;" + "padding: 8px;" + "background-color: #e0e0e0;" + "border-radius: 4px;" + "margin-bottom: 5px;"); + title->setCursor(Qt::SizeAllCursor); + m_layout->addWidget(title); + + // Properties section + m_propertiesLayout = new QVBoxLayout(); + m_propertiesLayout->setSpacing(6); + m_layout->addLayout(m_propertiesLayout); + + // Initial "no selection" message + QLabel *noSelectionLabel = new QLabel("No node selected"); + noSelectionLabel->setAlignment(Qt::AlignCenter); + noSelectionLabel->setStyleSheet("color: #999; font-style: italic; padding: 20px;"); + m_propertiesLayout->addWidget(noSelectionLabel); + + m_layout->addStretch(); + + // Initial size + m_contentWidget->adjustSize(); + adjustSize(); +} + +void FloatingProperties::connectSignals() +{ + // Connect to property change signals when values are modified +} + +void FloatingProperties::updatePropertiesForNode(int nodeId) +{ + if (m_currentNodeId == nodeId) { + return; // Already showing this node's properties + } + + m_currentNodeId = nodeId; + clearPropertyWidgets(); + + // Example properties - you would get these from your node model + QLabel *nodeHeader = new QLabel(QString("Node #%1").arg(nodeId)); + nodeHeader->setStyleSheet("font-size: 12px; font-weight: bold; color: #333; padding: 5px 0;"); + m_propertiesLayout->addWidget(nodeHeader); + m_propertyWidgets.append(nodeHeader); + + // Add separator + QFrame *separator = new QFrame(); + separator->setFrameShape(QFrame::HLine); + separator->setFrameShadow(QFrame::Sunken); + m_propertiesLayout->addWidget(separator); + m_propertyWidgets.append(separator); + + // Example properties based on node type + // You would customize this based on your actual node properties + + // Name property + QLineEdit *nameEdit = new QLineEdit(); + nameEdit->setText(QString("Node_%1").arg(nodeId)); + connect(nameEdit, &QLineEdit::textChanged, [this](const QString &text) { + emit propertyChanged("name", text); + }); + addPropertyWidget("Name:", nameEdit); + + // Type property (read-only) + QComboBox *typeCombo = new QComboBox(); + typeCombo->addItems({"Video Input", "Video Output", "Process", "Image", "Buffer"}); + typeCombo->setCurrentIndex(nodeId % 5); // Example selection + connect(typeCombo, QOverload::of(&QComboBox::currentIndexChanged), [this](int index) { + emit propertyChanged("type", index); + }); + addPropertyWidget("Type:", typeCombo); + + // Position properties + QDoubleSpinBox *xSpin = new QDoubleSpinBox(); + xSpin->setRange(-9999, 9999); + xSpin->setValue(100.0 * nodeId); // Example value + xSpin->setSuffix(" px"); + connect(xSpin, QOverload::of(&QDoubleSpinBox::valueChanged), [this](double value) { + emit propertyChanged("x", value); + }); + addPropertyWidget("X Position:", xSpin); + + QDoubleSpinBox *ySpin = new QDoubleSpinBox(); + ySpin->setRange(-9999, 9999); + ySpin->setValue(50.0 * nodeId); // Example value + ySpin->setSuffix(" px"); + connect(ySpin, QOverload::of(&QDoubleSpinBox::valueChanged), [this](double value) { + emit propertyChanged("y", value); + }); + addPropertyWidget("Y Position:", ySpin); + + // Size properties + QSpinBox *widthSpin = new QSpinBox(); + widthSpin->setRange(50, 500); + widthSpin->setValue(150); + widthSpin->setSuffix(" px"); + connect(widthSpin, QOverload::of(&QSpinBox::valueChanged), [this](int value) { + emit propertyChanged("width", value); + }); + addPropertyWidget("Width:", widthSpin); + + QSpinBox *heightSpin = new QSpinBox(); + heightSpin->setRange(50, 500); + heightSpin->setValue(100); + heightSpin->setSuffix(" px"); + connect(heightSpin, QOverload::of(&QSpinBox::valueChanged), [this](int value) { + emit propertyChanged("height", value); + }); + addPropertyWidget("Height:", heightSpin); + + // Enabled property + QCheckBox *enabledCheck = new QCheckBox("Enabled"); + enabledCheck->setChecked(true); + connect(enabledCheck, &QCheckBox::toggled, [this](bool checked) { + emit propertyChanged("enabled", checked); + }); + m_propertiesLayout->addWidget(enabledCheck); + m_propertyWidgets.append(enabledCheck); + + // Add some spacing at the end + m_propertiesLayout->addSpacing(10); + + // Update the content size + m_contentWidget->adjustSize(); +} + +void FloatingProperties::clearProperties() +{ + m_currentNodeId = -1; + clearPropertyWidgets(); + + QLabel *noSelectionLabel = new QLabel("No node selected"); + noSelectionLabel->setAlignment(Qt::AlignCenter); + noSelectionLabel->setStyleSheet("color: #999; font-style: italic; padding: 20px;"); + m_propertiesLayout->addWidget(noSelectionLabel); + m_propertyWidgets.append(noSelectionLabel); +} + +void FloatingProperties::clearPropertyWidgets() +{ + for (QWidget *widget : m_propertyWidgets) { + m_propertiesLayout->removeWidget(widget); + widget->deleteLater(); + } + m_propertyWidgets.clear(); +} + +void FloatingProperties::addPropertyWidget(const QString &label, QWidget *widget) +{ + QLabel *labelWidget = new QLabel(label); + m_propertiesLayout->addWidget(labelWidget); + m_propertiesLayout->addWidget(widget); + m_propertyWidgets.append(labelWidget); + m_propertyWidgets.append(widget); +} + +void FloatingProperties::updatePosition() +{ + if (m_dockPosition != Floating) { + updateDockedGeometry(); + } +} + +void FloatingProperties::setDockPosition(DockPosition position) +{ + if (m_dockPosition == position) + return; + + m_dockPosition = position; + + if (position == Floating) { + // Restore floating geometry + setMinimumSize(0, 0); + setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + setFixedWidth(200); + + if (m_geometryAnimation->state() == QAbstractAnimation::Running) { + m_geometryAnimation->stop(); + } + m_geometryAnimation->setStartValue(geometry()); + m_geometryAnimation->setEndValue(m_floatingGeometry); + m_geometryAnimation->start(); + } else { + // Apply docked geometry + updateDockedGeometry(); + } +} + +FloatingProperties::DockPosition FloatingProperties::checkDockingZone(const QPoint &pos) +{ + if (!parentWidget()) + return Floating; + + int parentWidth = parentWidget()->width(); + + // Check left edge + if (pos.x() <= m_dockingDistance) { + return DockedLeft; + } + + // Check right edge + if (pos.x() + width() >= parentWidth - m_dockingDistance) { + return DockedRight; + } + + return Floating; +} + +void FloatingProperties::applyDocking(DockPosition position) +{ + setDockPosition(position); +} + +void FloatingProperties::updateDockedGeometry() +{ + if (!parentWidget() || m_dockPosition == Floating) { + return; + } + + QRect targetGeometry; + int parentHeight = parentWidget()->height(); + + // Remove size constraints for docking + setMinimumSize(0, 0); + setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + + switch (m_dockPosition) { + case DockedLeft: + targetGeometry = QRect(m_dockMargin, + m_dockMargin, + m_dockedWidth, + parentHeight - 2 * m_dockMargin); + break; + case DockedRight: + targetGeometry = QRect(parentWidget()->width() - m_dockedWidth - m_dockMargin, + m_dockMargin, + m_dockedWidth, + parentHeight - 2 * m_dockMargin); + break; + default: + return; + } + + if (m_geometryAnimation->state() == QAbstractAnimation::Running) { + m_geometryAnimation->stop(); + } + m_geometryAnimation->setStartValue(geometry()); + m_geometryAnimation->setEndValue(targetGeometry); + m_geometryAnimation->start(); + + m_contentWidget->setStyleSheet("#PropertiesContent {" + " background-color: #f5f5f5;" + " border: 1px solid #ccc;" + " border-radius: 0px;" + "}"); +} + +void FloatingProperties::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + // Draw shadow + QRect shadowRect = rect().adjusted(4, 4, -4, -4); + painter.fillRect(shadowRect, QColor(0, 0, 0, 30)); + + // Draw docking preview + if (m_dragging && m_previewDockPosition != Floating && m_previewDockPosition != m_dockPosition) { + painter.setPen(QPen(QColor(0, 120, 215), 2)); + painter.setBrush(QColor(0, 120, 215, 20)); + painter.drawRoundedRect(rect().adjusted(1, 1, -1, -1), 6, 6); + } + + QWidget::paintEvent(event); +} + +void FloatingProperties::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + QLabel *title = findChild(); + if (title && title->geometry().contains(event->pos())) { + m_dragging = true; + m_dragStartPosition = event->pos(); + + // Store current geometry if floating + if (m_dockPosition == Floating) { + m_floatingGeometry = geometry(); + } + + raise(); // Bring to front when dragging + } + } + QWidget::mousePressEvent(event); +} + +void FloatingProperties::mouseMoveEvent(QMouseEvent *event) +{ + if (m_dragging && (event->buttons() & Qt::LeftButton)) { + QPoint newPos = pos() + event->pos() - m_dragStartPosition; + + // If currently docked, undock first + if (m_dockPosition != Floating) { + m_dockPosition = Floating; + setFixedWidth(200); + // Adjust position to keep mouse on title bar + newPos = QPoint(event->globalPosition().x() - m_dragStartPosition.x(), + event->globalPosition().y() - m_dragStartPosition.y()); + if (parentWidget()) { + newPos = parentWidget()->mapFromGlobal(newPos); + } + setFixedHeight(m_floatHeight); + m_contentWidget->setStyleSheet("#PropertiesContent {" + " background-color: #f5f5f5;" + " border: 1px solid #ccc;" + " border-radius: 6px;" + "}"); + } + + // Keep within parent bounds + if (parentWidget()) { + int maxX = parentWidget()->width() - width(); + int maxY = parentWidget()->height() - height(); + newPos.setX(qMax(0, qMin(newPos.x(), maxX))); + newPos.setY(qMax(0, qMin(newPos.y(), maxY))); + } + + move(newPos); + + // Check for docking zones + m_previewDockPosition = checkDockingZone(newPos); + + // Remember floating position + if (m_previewDockPosition == Floating) { + m_floatingGeometry = QRect(newPos, size()); + } + + update(); // Repaint for preview + } + QWidget::mouseMoveEvent(event); +} + +void FloatingProperties::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton && m_dragging) { + m_dragging = false; + + // Apply docking if in zone + if (m_previewDockPosition != Floating) { + applyDocking(m_previewDockPosition); + } + + m_previewDockPosition = Floating; + update(); + } + QWidget::mouseReleaseEvent(event); +} + +void FloatingProperties::showEvent(QShowEvent *event) +{ + QWidget::showEvent(event); + updatePosition(); + raise(); // Ensure properties panel is on top +} + +void FloatingProperties::resizeEvent(QResizeEvent *event) +{ + QWidget::resizeEvent(event); + + // If docked, maintain the docked state + if (m_dockPosition != Floating) { + updateDockedGeometry(); + } +} \ No newline at end of file diff --git a/examples/epen_graph_editor/src/GraphEditorMainWindow.cpp b/examples/epen_graph_editor/src/GraphEditorMainWindow.cpp index 16c67fb18..4375641ae 100644 --- a/examples/epen_graph_editor/src/GraphEditorMainWindow.cpp +++ b/examples/epen_graph_editor/src/GraphEditorMainWindow.cpp @@ -1,5 +1,6 @@ #include "GraphEditorMainWindow.hpp" #include "FloatingToolbar.hpp" +#include "FloatingProperties.hpp" #include #include #include @@ -19,9 +20,12 @@ using QtNodes::StyleCollection; GraphEditorWindow::GraphEditorWindow(DataFlowGraphicsScene *scene, DataFlowModel *model) : GraphicsView(scene) , m_toolbar(nullptr) + , m_properties(nullptr) , m_toolbarCreated(false) + , m_propertiesCreated(false) , _currentMode("pan") , _model(model) + , m_currentSelectedNodeId(-1) { // Setup context menu //setupNodeCreation(); @@ -32,6 +36,7 @@ GraphEditorWindow::GraphEditorWindow(DataFlowGraphicsScene *scene, DataFlowModel setAcceptDrops(true); viewport()->setAcceptDrops(true); // Important for drag and drop + // Create initial nodes QtNodes::NodeId newIdInput = _model->addNodeType(NodeTypes::Video_Input); QPointF inputScenePos = mapToScene(0, 0); _model->setNodeData(newIdInput, NodeRole::Position, inputScenePos); @@ -41,10 +46,14 @@ GraphEditorWindow::GraphEditorWindow(DataFlowGraphicsScene *scene, DataFlowModel _model->setNodeData(newIdOutput, NodeRole::Position, outputScenePos); _model->addConnection(ConnectionId{newIdInput, 0, newIdOutput, 0}); + setupScale(0.8); } -GraphEditorWindow::~GraphEditorWindow() {} +GraphEditorWindow::~GraphEditorWindow() +{ + // Cleanup is handled by QPointer +} void GraphEditorWindow::showEvent(QShowEvent *event) { @@ -56,12 +65,19 @@ void GraphEditorWindow::showEvent(QShowEvent *event) // Use a timer to ensure the window is fully rendered QTimer::singleShot(100, this, [this]() { createFloatingToolbar(); }); } + + // Create properties panel + if (!m_propertiesCreated && isVisible()) { + m_propertiesCreated = true; + // Create properties panel slightly after toolbar + QTimer::singleShot(150, this, [this]() { createFloatingProperties(); }); + } } + void GraphEditorWindow::moveEvent(QMoveEvent *event) { GraphicsView::moveEvent(event); - - // The toolbar will handle its own position updates through event filter + // The toolbars will handle their own position updates through event filter } void GraphEditorWindow::resizeEvent(QResizeEvent *event) @@ -72,11 +88,30 @@ void GraphEditorWindow::resizeEvent(QResizeEvent *event) if (m_toolbar && m_toolbar->isVisible() && m_toolbar->isDocked()) { m_toolbar->updatePosition(); } + + // Update properties position if it's docked + if (m_properties && m_properties->isVisible() && m_properties->isDocked()) { + m_properties->updatePosition(); + } } void GraphEditorWindow::mousePressEvent(QMouseEvent *event) { GraphicsView::mousePressEvent(event); + + // Example: Check if a node was clicked and select it + // You'll need to implement this based on your scene's node handling + QGraphicsItem *item = scene()->itemAt(mapToScene(event->pos()), QTransform()); + if (item) { + // Check if this is a node item and get its ID + // This is a simplified example - adjust based on your actual node implementation + // auto nodeItem = dynamic_cast(item); + // if (nodeItem) { + // onNodeSelected(nodeItem->nodeId()); + // } + } else { + onNodeDeselected(); + } } void GraphEditorWindow::dragEnterEvent(QDragEnterEvent *event) @@ -137,17 +172,63 @@ void GraphEditorWindow::createFloatingToolbar() m_toolbar->show(); m_toolbar->raise(); - // Set initial dock position (optional - start docked to right) - // m_toolbar->setDockPosition(FloatingToolbar::DockedRight); + // Set initial dock position (optional - start docked to left) + // m_toolbar->setDockPosition(FloatingToolbar::DockedLeft); qDebug() << "Toolbar created. Visible:" << m_toolbar->isVisible() << "Geometry:" << m_toolbar->geometry(); } +void GraphEditorWindow::createFloatingProperties() +{ + qDebug() << "Creating floating properties panel..."; + + // Create the floating properties panel + m_properties = new FloatingProperties(this); + + if (!m_properties) { + qDebug() << "Failed to create properties panel!"; + return; + } + + // Connect properties panel signals + connect(m_properties, &FloatingProperties::propertyChanged, + this, &GraphEditorWindow::onPropertyChanged); + + // Connect to the properties panel's node selection signals if needed + connect(m_properties, &FloatingProperties::nodeSelected, + this, &GraphEditorWindow::onNodeSelected); + connect(m_properties, &FloatingProperties::nodeDeselected, + this, &GraphEditorWindow::onNodeDeselected); + + // If you have node selection in your scene, connect it + // Example (adjust based on your actual implementation): + // auto dataFlowScene = dynamic_cast(scene()); + // if (dataFlowScene) { + // connect(dataFlowScene, &DataFlowGraphicsScene::nodeSelected, + // this, &GraphEditorWindow::onNodeSelected); + // connect(dataFlowScene, &DataFlowGraphicsScene::nodeDeselected, + // this, &GraphEditorWindow::onNodeDeselected); + // } + + // Show the properties panel + m_properties->show(); + m_properties->raise(); + + // Start docked to the right by default + // m_properties->setDockPosition(FloatingProperties::DockedRight); + + qDebug() << "Properties panel created. Visible:" << m_properties->isVisible() + << "Geometry:" << m_properties->geometry(); +} + void GraphEditorWindow::createNodeAtPosition(const QPointF &scenePos, const QString nodeType) { QtNodes::NodeId newId = _model->addNodeName(nodeType); _model->setNodeData(newId, NodeRole::Position, scenePos); + + // Select the newly created node + onNodeSelected(static_cast(newId)); } void GraphEditorWindow::createNodeAtCursor() @@ -161,4 +242,72 @@ void GraphEditorWindow::goToMode(QString mode) { _currentMode = mode; qDebug() << "Mode changed to:" << mode; + + // Handle different modes + if (mode == "VideoInput") { + createNodeAtCursor(); + } else if (mode == "VideoOutput") { + // Create video output node + QPointF posView = mapToScene(mapFromGlobal(QCursor::pos())); + createNodeAtPosition(posView, "VideoOutput"); + } else if (mode == "Process") { + // Create process node + QPointF posView = mapToScene(mapFromGlobal(QCursor::pos())); + createNodeAtPosition(posView, "Process"); + } + // Add more mode handlers as needed } + +void GraphEditorWindow::onNodeSelected(int nodeId) +{ + m_currentSelectedNodeId = nodeId; + + if (m_properties) { + m_properties->updatePropertiesForNode(nodeId); + } + + qDebug() << "Node selected:" << nodeId; +} + +void GraphEditorWindow::onNodeDeselected() +{ + m_currentSelectedNodeId = -1; + + if (m_properties) { + m_properties->clearProperties(); + } + + qDebug() << "Node deselected"; +} + +void GraphEditorWindow::onPropertyChanged(const QString &name, const QVariant &value) +{ + qDebug() << "Property changed:" << name << "=" << value; + + // Handle property changes here + // Update your node model with the new property value + if (_model && m_currentSelectedNodeId >= 0) { + QtNodes::NodeId nodeId = static_cast(m_currentSelectedNodeId); + + if (name == "name") { + // Update node name + // _model->setNodeData(nodeId, NodeRole::Name, value); + } else if (name == "x" || name == "y") { + // Update node position + QPointF currentPos = _model->nodeData(nodeId, NodeRole::Position).toPointF(); + if (name == "x") { + currentPos.setX(value.toDouble()); + } else { + currentPos.setY(value.toDouble()); + } + _model->setNodeData(nodeId, NodeRole::Position, currentPos); + } else if (name == "width" || name == "height") { + // Update node size if supported + // _model->setNodeData(nodeId, NodeRole::Size, value); + } else if (name == "enabled") { + // Update node enabled state + // _model->setNodeData(nodeId, NodeRole::Enabled, value); + } + // Add more property handlers as needed + } +} \ No newline at end of file From 7c611123a6c3cc0f78d9dc7bc6e4e8548b4ea481 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Wed, 16 Jul 2025 15:54:39 +0330 Subject: [PATCH 018/124] Add Properties to Properties Panel --- .../include/FloatingProperties.hpp | 10 +- .../src/FloatingProperties.cpp | 273 +++++++++++++++--- 2 files changed, 240 insertions(+), 43 deletions(-) diff --git a/examples/epen_graph_editor/include/FloatingProperties.hpp b/examples/epen_graph_editor/include/FloatingProperties.hpp index 058259c03..448251f7b 100644 --- a/examples/epen_graph_editor/include/FloatingProperties.hpp +++ b/examples/epen_graph_editor/include/FloatingProperties.hpp @@ -3,6 +3,12 @@ #include #include +#include +#include +#include +#include "qtpropertymanager.h" +#include "qtvariantproperty.h" +#include "qttreepropertybrowser.h" QT_BEGIN_NAMESPACE class QVBoxLayout; @@ -29,6 +35,7 @@ class FloatingProperties : public QWidget }; explicit FloatingProperties(GraphEditorWindow *parent = nullptr); + ~FloatingProperties(); void setDockPosition(DockPosition position); DockPosition dockPosition() const { return m_dockPosition; } @@ -60,7 +67,7 @@ public slots: void updateDockedGeometry(); void clearPropertyWidgets(); void addPropertyWidget(const QString &label, QWidget *widget); - + QtTreePropertyBrowser* getPropertyWidget(); GraphEditorWindow *m_graphEditor; QVBoxLayout *m_layout; QVBoxLayout *m_propertiesLayout; @@ -86,6 +93,7 @@ public slots: // Property widgets QList m_propertyWidgets; + QtTreePropertyBrowser *_properties; }; #endif // FLOATINGPROPERTIES_HPP \ No newline at end of file diff --git a/examples/epen_graph_editor/src/FloatingProperties.cpp b/examples/epen_graph_editor/src/FloatingProperties.cpp index 8b43069f3..316a89ec6 100644 --- a/examples/epen_graph_editor/src/FloatingProperties.cpp +++ b/examples/epen_graph_editor/src/FloatingProperties.cpp @@ -23,7 +23,7 @@ FloatingProperties::FloatingProperties(GraphEditorWindow *parent) , m_previewDockPosition(Floating) , m_dockMargin(0) , m_dockingDistance(40) - , m_dockedWidth(250) // Wider for properties + , m_dockedWidth(250) // Wider for properties , m_currentNodeId(-1) { // Keep it as a child widget with these flags @@ -42,10 +42,7 @@ FloatingProperties::FloatingProperties(GraphEditorWindow *parent) setFixedWidth(200); if (parent) { // Position on the right side by default - m_floatingGeometry = QRect(parent->width() - 220, - 20, - 200, - height()); + m_floatingGeometry = QRect(parent->width() - 220, 20, 200, height()); setGeometry(m_floatingGeometry); } @@ -90,36 +87,37 @@ void FloatingProperties::setupUI() " background: #a0a0a0;" "}"); - m_contentWidget->setStyleSheet("#PropertiesContent {" - " background-color: #f5f5f5;" - " border: 1px solid #ccc;" - " border-radius: 6px;" - "}" - "QLabel {" - " color: #555;" - " font-size: 10px;" - " font-weight: bold;" - " margin-top: 5px;" - "}" - "QLineEdit, QSpinBox, QDoubleSpinBox, QComboBox {" - " padding: 4px 6px;" - " border: 1px solid #bbb;" - " border-radius: 3px;" - " background-color: white;" - " font-size: 11px;" - "}" - "QLineEdit:focus, QSpinBox:focus, QDoubleSpinBox:focus, QComboBox:focus {" - " border-color: #0078d4;" - " outline: none;" - "}" - "QCheckBox {" - " font-size: 11px;" - " spacing: 5px;" - "}" - "QCheckBox::indicator {" - " width: 16px;" - " height: 16px;" - "}"); + m_contentWidget->setStyleSheet( + "#PropertiesContent {" + " background-color: #f5f5f5;" + " border: 1px solid #ccc;" + " border-radius: 6px;" + "}" + "QLabel {" + " color: #555;" + " font-size: 10px;" + " font-weight: bold;" + " margin-top: 5px;" + "}" + "QLineEdit, QSpinBox, QDoubleSpinBox, QComboBox {" + " padding: 4px 6px;" + " border: 1px solid #bbb;" + " border-radius: 3px;" + " background-color: white;" + " font-size: 11px;" + "}" + "QLineEdit:focus, QSpinBox:focus, QDoubleSpinBox:focus, QComboBox:focus {" + " border-color: #0078d4;" + " outline: none;" + "}" + "QCheckBox {" + " font-size: 11px;" + " spacing: 5px;" + "}" + "QCheckBox::indicator {" + " width: 16px;" + " height: 16px;" + "}"); // Set scroll area content m_scrollArea->setWidget(m_contentWidget); @@ -151,10 +149,13 @@ void FloatingProperties::setupUI() m_layout->addLayout(m_propertiesLayout); // Initial "no selection" message - QLabel *noSelectionLabel = new QLabel("No node selected"); + /*QLabel *noSelectionLabel = new QLabel("No node selected"); noSelectionLabel->setAlignment(Qt::AlignCenter); noSelectionLabel->setStyleSheet("color: #999; font-style: italic; padding: 20px;"); - m_propertiesLayout->addWidget(noSelectionLabel); + m_propertiesLayout->addWidget(noSelectionLabel);*/ + + _properties = getPropertyWidget(); + m_propertiesLayout->addWidget(_properties); m_layout->addStretch(); @@ -163,6 +164,188 @@ void FloatingProperties::setupUI() adjustSize(); } +QtTreePropertyBrowser *FloatingProperties::getPropertyWidget() +{ + QtVariantPropertyManager *variantManager = new QtVariantPropertyManager(); + + int i = 0; + QtProperty *topItem = variantManager->addProperty(QtVariantPropertyManager::groupTypeId(), + QString::number(i++) + + QLatin1String(" Group Property")); + + QtVariantProperty *item = variantManager->addProperty(QVariant::Bool, + QString::number(i++) + + QLatin1String(" Bool Property")); + item->setValue(true); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::Int, + QString::number(i++) + QLatin1String(" Int Property")); + item->setValue(20); + item->setAttribute(QLatin1String("minimum"), 0); + item->setAttribute(QLatin1String("maximum"), 100); + item->setAttribute(QLatin1String("singleStep"), 10); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::Int, + QString::number(i++) + + QLatin1String(" Int Property (ReadOnly)")); + item->setValue(20); + item->setAttribute(QLatin1String("minimum"), 0); + item->setAttribute(QLatin1String("maximum"), 100); + item->setAttribute(QLatin1String("singleStep"), 10); + item->setAttribute(QLatin1String("readOnly"), true); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::Double, + QString::number(i++) + QLatin1String(" Double Property")); + item->setValue(1.2345); + item->setAttribute(QLatin1String("singleStep"), 0.1); + item->setAttribute(QLatin1String("decimals"), 3); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::Double, + QString::number(i++) + + QLatin1String(" Double Property (ReadOnly)")); + item->setValue(1.23456); + item->setAttribute(QLatin1String("singleStep"), 0.1); + item->setAttribute(QLatin1String("decimals"), 5); + item->setAttribute(QLatin1String("readOnly"), true); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::String, + QString::number(i++) + QLatin1String(" String Property")); + item->setValue("Value"); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::String, + QString::number(i++) + + QLatin1String(" String Property (Password)")); + item->setAttribute(QLatin1String("echoMode"), QLineEdit::Password); + item->setValue("Password"); + topItem->addSubProperty(item); + + // Readonly String Property + item = variantManager->addProperty(QVariant::String, + QString::number(i++) + + QLatin1String(" String Property (ReadOnly)")); + item->setAttribute(QLatin1String("readOnly"), true); + item->setValue("readonly text"); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::Date, + QString::number(i++) + QLatin1String(" Date Property")); + item->setValue(QDate::currentDate().addDays(2)); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::Time, + QString::number(i++) + QLatin1String(" Time Property")); + item->setValue(QTime::currentTime()); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::DateTime, + QString::number(i++) + QLatin1String(" DateTime Property")); + item->setValue(QDateTime::currentDateTime()); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::KeySequence, + QString::number(i++) + + QLatin1String(" KeySequence Property")); + item->setValue(QKeySequence(Qt::ControlModifier | Qt::Key_Q)); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::Char, + QString::number(i++) + QLatin1String(" Char Property")); + item->setValue(QChar(386)); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::Locale, + QString::number(i++) + QLatin1String(" Locale Property")); + item->setValue(QLocale(QLocale::Polish, QLocale::Poland)); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::Point, + QString::number(i++) + QLatin1String(" Point Property")); + item->setValue(QPoint(10, 10)); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::PointF, + QString::number(i++) + QLatin1String(" PointF Property")); + item->setValue(QPointF(1.2345, -1.23451)); + item->setAttribute(QLatin1String("decimals"), 3); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::Size, + QString::number(i++) + QLatin1String(" Size Property")); + item->setValue(QSize(20, 20)); + item->setAttribute(QLatin1String("minimum"), QSize(10, 10)); + item->setAttribute(QLatin1String("maximum"), QSize(30, 30)); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::SizeF, + QString::number(i++) + QLatin1String(" SizeF Property")); + item->setValue(QSizeF(1.2345, 1.2345)); + item->setAttribute(QLatin1String("decimals"), 3); + item->setAttribute(QLatin1String("minimum"), QSizeF(0.12, 0.34)); + item->setAttribute(QLatin1String("maximum"), QSizeF(20.56, 20.78)); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::Rect, + QString::number(i++) + QLatin1String(" Rect Property")); + item->setValue(QRect(10, 10, 20, 20)); + topItem->addSubProperty(item); + item->setAttribute(QLatin1String("constraint"), QRect(0, 0, 50, 50)); + + item = variantManager->addProperty(QVariant::RectF, + QString::number(i++) + QLatin1String(" RectF Property")); + item->setValue(QRectF(1.2345, 1.2345, 1.2345, 1.2345)); + topItem->addSubProperty(item); + item->setAttribute(QLatin1String("constraint"), QRectF(0, 0, 50, 50)); + item->setAttribute(QLatin1String("decimals"), 3); + + item = variantManager->addProperty(QtVariantPropertyManager::enumTypeId(), + QString::number(i++) + QLatin1String(" Enum Property")); + QStringList enumNames; + enumNames << "Enum0" << "Enum1" << "Enum2"; + item->setAttribute(QLatin1String("enumNames"), enumNames); + item->setValue(1); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QtVariantPropertyManager::flagTypeId(), + QString::number(i++) + QLatin1String(" Flag Property")); + QStringList flagNames; + flagNames << "Flag0" << "Flag1" << "Flag2"; + item->setAttribute(QLatin1String("flagNames"), flagNames); + item->setValue(5); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::SizePolicy, + QString::number(i++) + QLatin1String(" SizePolicy Property")); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::Font, + QString::number(i++) + QLatin1String(" Font Property")); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::Cursor, + QString::number(i++) + QLatin1String(" Cursor Property")); + topItem->addSubProperty(item); + + item = variantManager->addProperty(QVariant::Color, + QString::number(i++) + QLatin1String(" Color Property")); + topItem->addSubProperty(item); + + QtVariantEditorFactory *variantFactory = new QtVariantEditorFactory(); + + QtTreePropertyBrowser *variantEditor = new QtTreePropertyBrowser(); + variantEditor->setFactoryForManager(variantManager, variantFactory); + variantEditor->addProperty(topItem); + variantEditor->setPropertiesWithoutValueMarked(true); + variantEditor->setRootIsDecorated(false); + + return variantEditor; +} + void FloatingProperties::connectSignals() { // Connect to property change signals when values are modified @@ -204,7 +387,7 @@ void FloatingProperties::updatePropertiesForNode(int nodeId) // Type property (read-only) QComboBox *typeCombo = new QComboBox(); typeCombo->addItems({"Video Input", "Video Output", "Process", "Image", "Buffer"}); - typeCombo->setCurrentIndex(nodeId % 5); // Example selection + typeCombo->setCurrentIndex(nodeId % 5); // Example selection connect(typeCombo, QOverload::of(&QComboBox::currentIndexChanged), [this](int index) { emit propertyChanged("type", index); }); @@ -213,7 +396,7 @@ void FloatingProperties::updatePropertiesForNode(int nodeId) // Position properties QDoubleSpinBox *xSpin = new QDoubleSpinBox(); xSpin->setRange(-9999, 9999); - xSpin->setValue(100.0 * nodeId); // Example value + xSpin->setValue(100.0 * nodeId); // Example value xSpin->setSuffix(" px"); connect(xSpin, QOverload::of(&QDoubleSpinBox::valueChanged), [this](double value) { emit propertyChanged("x", value); @@ -222,7 +405,7 @@ void FloatingProperties::updatePropertiesForNode(int nodeId) QDoubleSpinBox *ySpin = new QDoubleSpinBox(); ySpin->setRange(-9999, 9999); - ySpin->setValue(50.0 * nodeId); // Example value + ySpin->setValue(50.0 * nodeId); // Example value ySpin->setSuffix(" px"); connect(ySpin, QOverload::of(&QDoubleSpinBox::valueChanged), [this](double value) { emit propertyChanged("y", value); @@ -259,7 +442,7 @@ void FloatingProperties::updatePropertiesForNode(int nodeId) // Add some spacing at the end m_propertiesLayout->addSpacing(10); - + // Update the content size m_contentWidget->adjustSize(); } @@ -268,7 +451,7 @@ void FloatingProperties::clearProperties() { m_currentNodeId = -1; clearPropertyWidgets(); - + QLabel *noSelectionLabel = new QLabel("No node selected"); noSelectionLabel->setAlignment(Qt::AlignCenter); noSelectionLabel->setStyleSheet("color: #999; font-style: italic; padding: 20px;"); @@ -395,6 +578,11 @@ void FloatingProperties::updateDockedGeometry() "}"); } +FloatingProperties::~FloatingProperties() +{ + delete _properties; +} + void FloatingProperties::paintEvent(QPaintEvent *event) { QPainter painter(this); @@ -510,4 +698,5 @@ void FloatingProperties::resizeEvent(QResizeEvent *event) if (m_dockPosition != Floating) { updateDockedGeometry(); } + _properties->setFixedHeight(height()); } \ No newline at end of file From e1ed663f5392b4b19f4759324818c231c26ab916 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Wed, 16 Jul 2025 19:34:00 +0330 Subject: [PATCH 019/124] Refactoring floating panel class --- .../include/FloatingPanelBase.hpp | 96 ++++ .../include/FloatingProperties.hpp | 60 +-- .../include/FloatingToolbar.hpp | 66 +-- .../epen_graph_editor/src/DataFlowModel.cpp | 5 - .../src/FloatingPanelBase.cpp | 326 +++++++++++++ .../src/FloatingProperties.cpp | 455 ++---------------- .../epen_graph_editor/src/FloatingToolbar.cpp | 417 +++------------- 7 files changed, 532 insertions(+), 893 deletions(-) create mode 100644 examples/epen_graph_editor/include/FloatingPanelBase.hpp create mode 100644 examples/epen_graph_editor/src/FloatingPanelBase.cpp diff --git a/examples/epen_graph_editor/include/FloatingPanelBase.hpp b/examples/epen_graph_editor/include/FloatingPanelBase.hpp new file mode 100644 index 000000000..9e541fa79 --- /dev/null +++ b/examples/epen_graph_editor/include/FloatingPanelBase.hpp @@ -0,0 +1,96 @@ +#ifndef FLOATING_PANEL_BASE_HPP +#define FLOATING_PANEL_BASE_HPP + +#include +#include + +QT_BEGIN_NAMESPACE +class QVBoxLayout; +class QScrollArea; +class QLabel; +QT_END_NAMESPACE + +class GraphEditorWindow; + +class FloatingPanelBase : public QWidget +{ + Q_OBJECT + +public: + enum DockPosition { + Floating, + DockedLeft, + DockedRight + }; + + explicit FloatingPanelBase(GraphEditorWindow *parent = nullptr, const QString &title = "Panel"); + virtual ~FloatingPanelBase(); + + // Docking API + void setDockPosition(DockPosition position); + DockPosition dockPosition() const { return m_dockPosition; } + bool isDocked() const { return m_dockPosition != Floating; } + void updatePosition(); + + // Panel configuration + void setDockedWidth(int width) { m_dockedWidth = width; } + int dockedWidth() const { return m_dockedWidth; } + void setFloatingWidth(int width) { m_floatingWidth = width; } + int floatingWidth() const { return m_floatingWidth; } + +protected: + // Override these to customize panel behavior + virtual void setupUI() = 0; + virtual void connectSignals() = 0; + virtual QString getPanelStyleSheet() const; + virtual QString getContentStyleSheet() const; + + // Event handlers + void paintEvent(QPaintEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void showEvent(QShowEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + + // Helper methods for derived classes + void setupBaseUI(const QString &title); + GraphEditorWindow *getGraphEditor() const { return m_graphEditor; } + QVBoxLayout *getContentLayout() const { return m_contentLayout; } + QWidget *getContentWidget() const { return m_contentWidget; } + QScrollArea *getScrollArea() const { return m_scrollArea; } + +private: + // Docking helpers + DockPosition checkDockingZone(const QPoint &pos); + void applyDocking(DockPosition position); + void updateDockedGeometry(); + +protected: + GraphEditorWindow *m_graphEditor; + QVBoxLayout *m_mainLayout; + QVBoxLayout *m_contentLayout; + QWidget *m_contentWidget; + QScrollArea *m_scrollArea; + QPropertyAnimation *m_geometryAnimation; + QLabel *m_titleLabel; + + // Dragging state + bool m_dragging; + QPoint m_dragStartPosition; + DockPosition m_dockPosition; + DockPosition m_previewDockPosition; + QRect m_floatingGeometry; + + // Docking settings + int m_dockMargin; + int m_dockingDistance; + int m_dockedWidth; + int m_floatingWidth; + int m_floatHeight; + + // Panel title + QString m_panelTitle; +}; + +#endif // FLOATING_PANEL_BASE_HPP \ No newline at end of file diff --git a/examples/epen_graph_editor/include/FloatingProperties.hpp b/examples/epen_graph_editor/include/FloatingProperties.hpp index 448251f7b..d8aa81bd3 100644 --- a/examples/epen_graph_editor/include/FloatingProperties.hpp +++ b/examples/epen_graph_editor/include/FloatingProperties.hpp @@ -1,8 +1,7 @@ #ifndef FLOATINGPROPERTIES_HPP #define FLOATINGPROPERTIES_HPP -#include -#include +#include "FloatingPanelBase.hpp" #include #include #include @@ -12,36 +11,16 @@ QT_BEGIN_NAMESPACE class QVBoxLayout; -class QScrollArea; -class QLabel; -class QLineEdit; -class QSpinBox; -class QDoubleSpinBox; -class QCheckBox; -class QComboBox; QT_END_NAMESPACE -class GraphEditorWindow; - -class FloatingProperties : public QWidget +class FloatingProperties : public FloatingPanelBase { Q_OBJECT public: - enum DockPosition { - Floating, - DockedLeft, - DockedRight - }; - explicit FloatingProperties(GraphEditorWindow *parent = nullptr); ~FloatingProperties(); - void setDockPosition(DockPosition position); - DockPosition dockPosition() const { return m_dockPosition; } - bool isDocked() const { return m_dockPosition != Floating; } - void updatePosition(); - signals: void propertyChanged(const QString &name, const QVariant &value); void nodeSelected(int nodeId); @@ -52,41 +31,18 @@ public slots: void clearProperties(); protected: - void paintEvent(QPaintEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; - void mouseMoveEvent(QMouseEvent *event) override; - void mouseReleaseEvent(QMouseEvent *event) override; - void showEvent(QShowEvent *event) override; + // Implement virtual functions from base class + void setupUI() override; + void connectSignals() override; void resizeEvent(QResizeEvent *event) override; private: - void setupUI(); - void connectSignals(); - DockPosition checkDockingZone(const QPoint &pos); - void applyDocking(DockPosition position); - void updateDockedGeometry(); void clearPropertyWidgets(); void addPropertyWidget(const QString &label, QWidget *widget); - QtTreePropertyBrowser* getPropertyWidget(); - GraphEditorWindow *m_graphEditor; - QVBoxLayout *m_layout; - QVBoxLayout *m_propertiesLayout; - QWidget *m_contentWidget; - QScrollArea *m_scrollArea; - QPropertyAnimation *m_geometryAnimation; - - // Dragging state - bool m_dragging; - QPoint m_dragStartPosition; - DockPosition m_dockPosition; - DockPosition m_previewDockPosition; - QRect m_floatingGeometry; + QtTreePropertyBrowser* getPropertyWidget(); - // Docking settings - int m_dockMargin; - int m_dockingDistance; - int m_dockedWidth; - int m_floatHeight; + // Properties layout + QVBoxLayout *m_propertiesLayout; // Current node int m_currentNodeId; diff --git a/examples/epen_graph_editor/include/FloatingToolbar.hpp b/examples/epen_graph_editor/include/FloatingToolbar.hpp index d157afcc2..a8be4c7c4 100644 --- a/examples/epen_graph_editor/include/FloatingToolbar.hpp +++ b/examples/epen_graph_editor/include/FloatingToolbar.hpp @@ -1,37 +1,17 @@ #ifndef FLOATING_TOOLBAR_HPP #define FLOATING_TOOLBAR_HPP +#include "FloatingPanelBase.hpp" #include "DraggableButton.hpp" -#include -class QVBoxLayout; -class QPushButton; -class GraphEditorWindow; -class QPropertyAnimation; -class QScrollArea; - -class FloatingToolbar : public QWidget +class FloatingToolbar : public FloatingPanelBase { Q_OBJECT public: - enum DockPosition { - Floating, - DockedLeft, - DockedRight - }; - explicit FloatingToolbar(GraphEditorWindow *parent = nullptr); ~FloatingToolbar() = default; - // Position the toolbar within the parent window - void updatePosition(); - - // Docking functions - void setDockPosition(DockPosition position); - DockPosition getDockPosition() const { return m_dockPosition; } - bool isDocked() const { return m_dockPosition != Floating; } - signals: void specificNodeRequested(QString actionName); void fillColorChanged(const QColor &color); @@ -40,48 +20,12 @@ class FloatingToolbar : public QWidget void resetViewRequested(); protected: - // Override for custom painting - void paintEvent(QPaintEvent *event) override; - - // Mouse events for dragging - void mousePressEvent(QMouseEvent *event) override; - void mouseMoveEvent(QMouseEvent *event) override; - void mouseReleaseEvent(QMouseEvent *event) override; - - // Override to update position when shown - void showEvent(QShowEvent *event) override; - void resizeEvent(QResizeEvent *event) override; + // Implement virtual functions from base class + void setupUI() override; + void connectSignals() override; private: - void setupUI(); - void connectSignals(); QString createSafeButtonText(const QString &icon, const QString &text); - - // Docking helpers - DockPosition checkDockingZone(const QPoint &pos); - void applyDocking(DockPosition position); - void updateDockedGeometry(); - - GraphEditorWindow *m_graphEditor; - QVBoxLayout *m_layout; - QWidget *m_contentWidget; - QScrollArea *m_scrollArea; - - // Dragging support - bool m_dragging; - QPoint m_dragStartPosition; - QRect m_floatingGeometry; // Remember size and position when floating - - // Docking state - DockPosition m_dockPosition; - DockPosition m_previewDockPosition; - int m_dockMargin; - int m_dockingDistance; // Distance from edge to trigger docking - int m_dockedWidth; // Width when docked - int _floatHeight; - - // Animation - QPropertyAnimation *m_geometryAnimation; }; #endif // FLOATING_TOOLBAR_HPP \ No newline at end of file diff --git a/examples/epen_graph_editor/src/DataFlowModel.cpp b/examples/epen_graph_editor/src/DataFlowModel.cpp index 6294f0a2d..710b923ba 100644 --- a/examples/epen_graph_editor/src/DataFlowModel.cpp +++ b/examples/epen_graph_editor/src/DataFlowModel.cpp @@ -121,11 +121,6 @@ QVariant DataFlowModel::nodeData(NodeId nodeId, NodeRole role) const } } } - if (role == NodeRole::Caption && nodeTypeName != "VideoOutput") { - QString fullCaption = DataFlowGraphModel::nodeData(nodeId, role).toString() + "
[" - + _nodeNames[nodeId] + "]"; - return fullCaption; - } return DataFlowGraphModel::nodeData(nodeId, role); } diff --git a/examples/epen_graph_editor/src/FloatingPanelBase.cpp b/examples/epen_graph_editor/src/FloatingPanelBase.cpp new file mode 100644 index 000000000..22c6c53e5 --- /dev/null +++ b/examples/epen_graph_editor/src/FloatingPanelBase.cpp @@ -0,0 +1,326 @@ +#include "FloatingPanelBase.hpp" +#include "GraphEditorMainWindow.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +FloatingPanelBase::FloatingPanelBase(GraphEditorWindow *parent, const QString &title) + : QWidget(parent) + , m_graphEditor(parent) + , m_dragging(false) + , m_dockPosition(Floating) + , m_previewDockPosition(Floating) + , m_dockMargin(0) + , m_dockingDistance(40) + , m_dockedWidth(200) + , m_floatingWidth(150) + , m_panelTitle(title) +{ + // Keep it as a child widget with these flags + setWindowFlags(Qt::SubWindow | Qt::FramelessWindowHint); + setAttribute(Qt::WA_TranslucentBackground); + + // Create animation for smooth transitions + m_geometryAnimation = new QPropertyAnimation(this, "geometry"); + m_geometryAnimation->setDuration(200); + m_geometryAnimation->setEasingCurve(QEasingCurve::OutCubic); +} + +FloatingPanelBase::~FloatingPanelBase() {} + +void FloatingPanelBase::setupBaseUI(const QString &title) +{ + // Create scroll area for when docked + m_scrollArea = new QScrollArea(this); + m_scrollArea->setWidgetResizable(true); + m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + m_scrollArea->setFrameShape(QFrame::NoFrame); + + m_contentWidget = new QWidget(); + m_contentWidget->setObjectName(m_panelTitle.replace(" ", "") + "Content"); + + // Apply panel-specific style + m_scrollArea->setStyleSheet(getPanelStyleSheet()); + m_contentWidget->setStyleSheet(getContentStyleSheet()); + + // Set scroll area content + m_scrollArea->setWidget(m_contentWidget); + + // Main layout for this widget + m_mainLayout = new QVBoxLayout(this); + m_mainLayout->setContentsMargins(0, 0, 0, 0); + m_mainLayout->addWidget(m_scrollArea); + + // Content layout + m_contentLayout = new QVBoxLayout(m_contentWidget); + m_contentLayout->setContentsMargins(8, 8, 8, 8); + m_contentLayout->setSpacing(4); + + // Title bar for dragging + m_titleLabel = new QLabel(title); + m_titleLabel->setAlignment(Qt::AlignCenter); + m_titleLabel->setStyleSheet("font-weight: bold;" + "padding: 8px;" + "background-color: #e0e0e0;" + "border-radius: 4px;" + "margin-bottom: 5px;"); + m_titleLabel->setCursor(Qt::SizeAllCursor); + m_contentLayout->addWidget(m_titleLabel); +} + +QString FloatingPanelBase::getPanelStyleSheet() const +{ + return "QScrollArea {" + " background: transparent;" + " border: none;" + "}" + "QScrollBar:vertical {" + " background: #f0f0f0;" + " width: 10px;" + " border-radius: 5px;" + "}" + "QScrollBar::handle:vertical {" + " background: #c0c0c0;" + " border-radius: 5px;" + " min-height: 20px;" + "}" + "QScrollBar::handle:vertical:hover {" + " background: #a0a0a0;" + "}"; +} + +QString FloatingPanelBase::getContentStyleSheet() const +{ + QString title = m_panelTitle; + QString replacedTitle = title.replace(" ", ""); + QString objectName = replacedTitle + "Content"; + return QString("#%1 {" + " background-color: #f5f5f5;" + " border: 1px solid #ccc;" + " border-radius: 6px;" + "}") + .arg(objectName); +} + +void FloatingPanelBase::updatePosition() +{ + if (m_dockPosition != Floating) { + updateDockedGeometry(); + } +} + +void FloatingPanelBase::setDockPosition(DockPosition position) +{ + if (m_dockPosition == position) + return; + + m_dockPosition = position; + + if (position == Floating) { + // Restore floating geometry + setMinimumSize(0, 0); + setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + setFixedWidth(m_floatingWidth); + + if (m_geometryAnimation->state() == QAbstractAnimation::Running) { + m_geometryAnimation->stop(); + } + m_geometryAnimation->setStartValue(geometry()); + m_geometryAnimation->setEndValue(m_floatingGeometry); + m_geometryAnimation->start(); + } else { + // Apply docked geometry + updateDockedGeometry(); + } +} + +FloatingPanelBase::DockPosition FloatingPanelBase::checkDockingZone(const QPoint &pos) +{ + if (!parentWidget()) + return Floating; + + int parentWidth = parentWidget()->width(); + + // Check left edge + if (pos.x() <= m_dockingDistance) { + return DockedLeft; + } + + // Check right edge + if (pos.x() + width() >= parentWidth - m_dockingDistance) { + return DockedRight; + } + + return Floating; +} + +void FloatingPanelBase::applyDocking(DockPosition position) +{ + setDockPosition(position); +} + +void FloatingPanelBase::updateDockedGeometry() +{ + if (!parentWidget() || m_dockPosition == Floating) { + return; + } + + QRect targetGeometry; + int parentHeight = parentWidget()->height(); + + // Remove size constraints for docking + setMinimumSize(0, 0); + setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + + switch (m_dockPosition) { + case DockedLeft: + targetGeometry = QRect(m_dockMargin, + m_dockMargin, + m_dockedWidth, + parentHeight - 2 * m_dockMargin); + break; + case DockedRight: + targetGeometry = QRect(parentWidget()->width() - m_dockedWidth - m_dockMargin, + m_dockMargin, + m_dockedWidth, + parentHeight - 2 * m_dockMargin); + break; + default: + return; + } + + if (m_geometryAnimation->state() == QAbstractAnimation::Running) { + m_geometryAnimation->stop(); + } + m_geometryAnimation->setStartValue(geometry()); + m_geometryAnimation->setEndValue(targetGeometry); + m_geometryAnimation->start(); + + // Update style for docked state (remove border radius) + QString objectName = m_panelTitle.replace(" ", "") + "Content"; + m_contentWidget->setStyleSheet(QString("#%1 {" + " background-color: #f5f5f5;" + " border: 1px solid #ccc;" + " border-radius: 0px;" + "}") + .arg(objectName)); +} + +void FloatingPanelBase::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + // Draw shadow + QRect shadowRect = rect().adjusted(4, 4, -4, -4); + painter.fillRect(shadowRect, QColor(0, 0, 0, 30)); + + // Draw docking preview + if (m_dragging && m_previewDockPosition != Floating && m_previewDockPosition != m_dockPosition) { + painter.setPen(QPen(QColor(0, 120, 215), 2)); + painter.setBrush(QColor(0, 120, 215, 20)); + painter.drawRoundedRect(rect().adjusted(1, 1, -1, -1), 6, 6); + } + + QWidget::paintEvent(event); +} + +void FloatingPanelBase::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + if (m_titleLabel && m_titleLabel->geometry().contains(event->pos())) { + m_dragging = true; + m_dragStartPosition = event->pos(); + + // Store current geometry if floating + if (m_dockPosition == Floating) { + m_floatingGeometry = geometry(); + } + + raise(); // Bring to front when dragging + } + } + QWidget::mousePressEvent(event); +} + +void FloatingPanelBase::mouseMoveEvent(QMouseEvent *event) +{ + if (m_dragging && (event->buttons() & Qt::LeftButton)) { + QPoint newPos = pos() + event->pos() - m_dragStartPosition; + + // If currently docked, undock first + if (m_dockPosition != Floating) { + m_dockPosition = Floating; + setFixedWidth(m_floatingWidth); + // Adjust position to keep mouse on title bar + newPos = QPoint(event->globalPosition().x() - m_dragStartPosition.x(), + event->globalPosition().y() - m_dragStartPosition.y()); + if (parentWidget()) { + newPos = parentWidget()->mapFromGlobal(newPos); + } + setFixedHeight(m_floatHeight); + m_contentWidget->setStyleSheet(getContentStyleSheet()); + } + + // Keep within parent bounds + if (parentWidget()) { + int maxX = parentWidget()->width() - width(); + int maxY = parentWidget()->height() - height(); + newPos.setX(qMax(0, qMin(newPos.x(), maxX))); + newPos.setY(qMax(0, qMin(newPos.y(), maxY))); + } + + move(newPos); + + // Check for docking zones + m_previewDockPosition = checkDockingZone(newPos); + + // Remember floating position + if (m_previewDockPosition == Floating) { + m_floatingGeometry = QRect(newPos, size()); + } + + update(); // Repaint for preview + } + QWidget::mouseMoveEvent(event); +} + +void FloatingPanelBase::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton && m_dragging) { + m_dragging = false; + + // Apply docking if in zone + if (m_previewDockPosition != Floating) { + applyDocking(m_previewDockPosition); + } + + m_previewDockPosition = Floating; + update(); + } + QWidget::mouseReleaseEvent(event); +} + +void FloatingPanelBase::showEvent(QShowEvent *event) +{ + QWidget::showEvent(event); + updatePosition(); + raise(); // Ensure panel is on top +} + +void FloatingPanelBase::resizeEvent(QResizeEvent *event) +{ + QWidget::resizeEvent(event); + + // If docked, maintain the docked state + if (m_dockPosition != Floating) { + updateDockedGeometry(); + } +} \ No newline at end of file diff --git a/examples/epen_graph_editor/src/FloatingProperties.cpp b/examples/epen_graph_editor/src/FloatingProperties.cpp index 316a89ec6..0eb18da0b 100644 --- a/examples/epen_graph_editor/src/FloatingProperties.cpp +++ b/examples/epen_graph_editor/src/FloatingProperties.cpp @@ -8,41 +8,27 @@ #include #include #include -#include -#include -#include -#include #include #include FloatingProperties::FloatingProperties(GraphEditorWindow *parent) - : QWidget(parent) - , m_graphEditor(parent) - , m_dragging(false) - , m_dockPosition(Floating) - , m_previewDockPosition(Floating) - , m_dockMargin(0) - , m_dockingDistance(40) - , m_dockedWidth(250) // Wider for properties + : FloatingPanelBase(parent, "Properties") , m_currentNodeId(-1) + , _properties(nullptr) { - // Keep it as a child widget with these flags - setWindowFlags(Qt::SubWindow | Qt::FramelessWindowHint); - setAttribute(Qt::WA_TranslucentBackground); - - // Create animation for smooth transitions - m_geometryAnimation = new QPropertyAnimation(this, "geometry"); - m_geometryAnimation->setDuration(200); - m_geometryAnimation->setEasingCurve(QEasingCurve::OutCubic); + // Set panel-specific dimensions + setFloatingWidth(200); + setDockedWidth(250); // Wider for properties + // Initialize UI setupUI(); connectSignals(); // Initial floating size and position - setFixedWidth(200); + setFixedWidth(floatingWidth()); if (parent) { // Position on the right side by default - m_floatingGeometry = QRect(parent->width() - 220, 20, 200, height()); + m_floatingGeometry = QRect(parent->width() - 220, 20, floatingWidth(), height()); setGeometry(m_floatingGeometry); } @@ -54,45 +40,21 @@ FloatingProperties::FloatingProperties(GraphEditorWindow *parent) setDockPosition(DockPosition::DockedRight); } -void FloatingProperties::setupUI() +FloatingProperties::~FloatingProperties() { - // Create scroll area for when docked - m_scrollArea = new QScrollArea(this); - m_scrollArea->setWidgetResizable(true); - m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - m_scrollArea->setFrameShape(QFrame::NoFrame); + delete _properties; +} - m_contentWidget = new QWidget(); - m_contentWidget->setObjectName("PropertiesContent"); +void FloatingProperties::setupUI() +{ + // Call base class setup + setupBaseUI("Properties"); QFont labelFont = QApplication::font(); labelFont.setPointSize(10); - m_scrollArea->setStyleSheet("QScrollArea {" - " background: transparent;" - " border: none;" - "}" - "QScrollBar:vertical {" - " background: #f0f0f0;" - " width: 10px;" - " border-radius: 5px;" - "}" - "QScrollBar::handle:vertical {" - " background: #c0c0c0;" - " border-radius: 5px;" - " min-height: 20px;" - "}" - "QScrollBar::handle:vertical:hover {" - " background: #a0a0a0;" - "}"); - - m_contentWidget->setStyleSheet( - "#PropertiesContent {" - " background-color: #f5f5f5;" - " border: 1px solid #ccc;" - " border-radius: 6px;" - "}" + // Additional style for property widgets + QString additionalStyle = "QLabel {" " color: #555;" " font-size: 10px;" @@ -117,50 +79,25 @@ void FloatingProperties::setupUI() "QCheckBox::indicator {" " width: 16px;" " height: 16px;" - "}"); - - // Set scroll area content - m_scrollArea->setWidget(m_contentWidget); - - // Main layout for this widget - QVBoxLayout *mainLayout = new QVBoxLayout(this); - mainLayout->setContentsMargins(0, 0, 0, 0); - mainLayout->addWidget(m_scrollArea); - - // Content layout - m_layout = new QVBoxLayout(m_contentWidget); - m_layout->setContentsMargins(8, 8, 8, 8); - m_layout->setSpacing(4); - - // Title bar for dragging - QLabel *title = new QLabel("Properties"); - title->setAlignment(Qt::AlignCenter); - title->setStyleSheet("font-weight: bold;" - "padding: 8px;" - "background-color: #e0e0e0;" - "border-radius: 4px;" - "margin-bottom: 5px;"); - title->setCursor(Qt::SizeAllCursor); - m_layout->addWidget(title); + "}"; + + getContentWidget()->setStyleSheet(getContentWidget()->styleSheet() + additionalStyle); + + QVBoxLayout *layout = getContentLayout(); // Properties section m_propertiesLayout = new QVBoxLayout(); m_propertiesLayout->setSpacing(6); - m_layout->addLayout(m_propertiesLayout); - - // Initial "no selection" message - /*QLabel *noSelectionLabel = new QLabel("No node selected"); - noSelectionLabel->setAlignment(Qt::AlignCenter); - noSelectionLabel->setStyleSheet("color: #999; font-style: italic; padding: 20px;"); - m_propertiesLayout->addWidget(noSelectionLabel);*/ + layout->addLayout(m_propertiesLayout); + // Initialize property browser _properties = getPropertyWidget(); m_propertiesLayout->addWidget(_properties); - m_layout->addStretch(); + layout->addStretch(); // Initial size - m_contentWidget->adjustSize(); + getContentWidget()->adjustSize(); adjustSize(); } @@ -204,35 +141,11 @@ QtTreePropertyBrowser *FloatingProperties::getPropertyWidget() item->setAttribute(QLatin1String("decimals"), 3); topItem->addSubProperty(item); - item = variantManager->addProperty(QVariant::Double, - QString::number(i++) - + QLatin1String(" Double Property (ReadOnly)")); - item->setValue(1.23456); - item->setAttribute(QLatin1String("singleStep"), 0.1); - item->setAttribute(QLatin1String("decimals"), 5); - item->setAttribute(QLatin1String("readOnly"), true); - topItem->addSubProperty(item); - item = variantManager->addProperty(QVariant::String, QString::number(i++) + QLatin1String(" String Property")); item->setValue("Value"); topItem->addSubProperty(item); - item = variantManager->addProperty(QVariant::String, - QString::number(i++) - + QLatin1String(" String Property (Password)")); - item->setAttribute(QLatin1String("echoMode"), QLineEdit::Password); - item->setValue("Password"); - topItem->addSubProperty(item); - - // Readonly String Property - item = variantManager->addProperty(QVariant::String, - QString::number(i++) - + QLatin1String(" String Property (ReadOnly)")); - item->setAttribute(QLatin1String("readOnly"), true); - item->setValue("readonly text"); - topItem->addSubProperty(item); - item = variantManager->addProperty(QVariant::Date, QString::number(i++) + QLatin1String(" Date Property")); item->setValue(QDate::currentDate().addDays(2)); @@ -248,33 +161,11 @@ QtTreePropertyBrowser *FloatingProperties::getPropertyWidget() item->setValue(QDateTime::currentDateTime()); topItem->addSubProperty(item); - item = variantManager->addProperty(QVariant::KeySequence, - QString::number(i++) - + QLatin1String(" KeySequence Property")); - item->setValue(QKeySequence(Qt::ControlModifier | Qt::Key_Q)); - topItem->addSubProperty(item); - - item = variantManager->addProperty(QVariant::Char, - QString::number(i++) + QLatin1String(" Char Property")); - item->setValue(QChar(386)); - topItem->addSubProperty(item); - - item = variantManager->addProperty(QVariant::Locale, - QString::number(i++) + QLatin1String(" Locale Property")); - item->setValue(QLocale(QLocale::Polish, QLocale::Poland)); - topItem->addSubProperty(item); - item = variantManager->addProperty(QVariant::Point, QString::number(i++) + QLatin1String(" Point Property")); item->setValue(QPoint(10, 10)); topItem->addSubProperty(item); - item = variantManager->addProperty(QVariant::PointF, - QString::number(i++) + QLatin1String(" PointF Property")); - item->setValue(QPointF(1.2345, -1.23451)); - item->setAttribute(QLatin1String("decimals"), 3); - topItem->addSubProperty(item); - item = variantManager->addProperty(QVariant::Size, QString::number(i++) + QLatin1String(" Size Property")); item->setValue(QSize(20, 20)); @@ -282,27 +173,6 @@ QtTreePropertyBrowser *FloatingProperties::getPropertyWidget() item->setAttribute(QLatin1String("maximum"), QSize(30, 30)); topItem->addSubProperty(item); - item = variantManager->addProperty(QVariant::SizeF, - QString::number(i++) + QLatin1String(" SizeF Property")); - item->setValue(QSizeF(1.2345, 1.2345)); - item->setAttribute(QLatin1String("decimals"), 3); - item->setAttribute(QLatin1String("minimum"), QSizeF(0.12, 0.34)); - item->setAttribute(QLatin1String("maximum"), QSizeF(20.56, 20.78)); - topItem->addSubProperty(item); - - item = variantManager->addProperty(QVariant::Rect, - QString::number(i++) + QLatin1String(" Rect Property")); - item->setValue(QRect(10, 10, 20, 20)); - topItem->addSubProperty(item); - item->setAttribute(QLatin1String("constraint"), QRect(0, 0, 50, 50)); - - item = variantManager->addProperty(QVariant::RectF, - QString::number(i++) + QLatin1String(" RectF Property")); - item->setValue(QRectF(1.2345, 1.2345, 1.2345, 1.2345)); - topItem->addSubProperty(item); - item->setAttribute(QLatin1String("constraint"), QRectF(0, 0, 50, 50)); - item->setAttribute(QLatin1String("decimals"), 3); - item = variantManager->addProperty(QtVariantPropertyManager::enumTypeId(), QString::number(i++) + QLatin1String(" Enum Property")); QStringList enumNames; @@ -311,26 +181,6 @@ QtTreePropertyBrowser *FloatingProperties::getPropertyWidget() item->setValue(1); topItem->addSubProperty(item); - item = variantManager->addProperty(QtVariantPropertyManager::flagTypeId(), - QString::number(i++) + QLatin1String(" Flag Property")); - QStringList flagNames; - flagNames << "Flag0" << "Flag1" << "Flag2"; - item->setAttribute(QLatin1String("flagNames"), flagNames); - item->setValue(5); - topItem->addSubProperty(item); - - item = variantManager->addProperty(QVariant::SizePolicy, - QString::number(i++) + QLatin1String(" SizePolicy Property")); - topItem->addSubProperty(item); - - item = variantManager->addProperty(QVariant::Font, - QString::number(i++) + QLatin1String(" Font Property")); - topItem->addSubProperty(item); - - item = variantManager->addProperty(QVariant::Cursor, - QString::number(i++) + QLatin1String(" Cursor Property")); - topItem->addSubProperty(item); - item = variantManager->addProperty(QVariant::Color, QString::number(i++) + QLatin1String(" Color Property")); topItem->addSubProperty(item); @@ -412,39 +262,11 @@ void FloatingProperties::updatePropertiesForNode(int nodeId) }); addPropertyWidget("Y Position:", ySpin); - // Size properties - QSpinBox *widthSpin = new QSpinBox(); - widthSpin->setRange(50, 500); - widthSpin->setValue(150); - widthSpin->setSuffix(" px"); - connect(widthSpin, QOverload::of(&QSpinBox::valueChanged), [this](int value) { - emit propertyChanged("width", value); - }); - addPropertyWidget("Width:", widthSpin); - - QSpinBox *heightSpin = new QSpinBox(); - heightSpin->setRange(50, 500); - heightSpin->setValue(100); - heightSpin->setSuffix(" px"); - connect(heightSpin, QOverload::of(&QSpinBox::valueChanged), [this](int value) { - emit propertyChanged("height", value); - }); - addPropertyWidget("Height:", heightSpin); - - // Enabled property - QCheckBox *enabledCheck = new QCheckBox("Enabled"); - enabledCheck->setChecked(true); - connect(enabledCheck, &QCheckBox::toggled, [this](bool checked) { - emit propertyChanged("enabled", checked); - }); - m_propertiesLayout->addWidget(enabledCheck); - m_propertyWidgets.append(enabledCheck); - // Add some spacing at the end m_propertiesLayout->addSpacing(10); // Update the content size - m_contentWidget->adjustSize(); + getContentWidget()->adjustSize(); } void FloatingProperties::clearProperties() @@ -477,226 +299,11 @@ void FloatingProperties::addPropertyWidget(const QString &label, QWidget *widget m_propertyWidgets.append(widget); } -void FloatingProperties::updatePosition() -{ - if (m_dockPosition != Floating) { - updateDockedGeometry(); - } -} - -void FloatingProperties::setDockPosition(DockPosition position) -{ - if (m_dockPosition == position) - return; - - m_dockPosition = position; - - if (position == Floating) { - // Restore floating geometry - setMinimumSize(0, 0); - setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); - setFixedWidth(200); - - if (m_geometryAnimation->state() == QAbstractAnimation::Running) { - m_geometryAnimation->stop(); - } - m_geometryAnimation->setStartValue(geometry()); - m_geometryAnimation->setEndValue(m_floatingGeometry); - m_geometryAnimation->start(); - } else { - // Apply docked geometry - updateDockedGeometry(); - } -} - -FloatingProperties::DockPosition FloatingProperties::checkDockingZone(const QPoint &pos) -{ - if (!parentWidget()) - return Floating; - - int parentWidth = parentWidget()->width(); - - // Check left edge - if (pos.x() <= m_dockingDistance) { - return DockedLeft; - } - - // Check right edge - if (pos.x() + width() >= parentWidth - m_dockingDistance) { - return DockedRight; - } - - return Floating; -} - -void FloatingProperties::applyDocking(DockPosition position) -{ - setDockPosition(position); -} - -void FloatingProperties::updateDockedGeometry() -{ - if (!parentWidget() || m_dockPosition == Floating) { - return; - } - - QRect targetGeometry; - int parentHeight = parentWidget()->height(); - - // Remove size constraints for docking - setMinimumSize(0, 0); - setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); - - switch (m_dockPosition) { - case DockedLeft: - targetGeometry = QRect(m_dockMargin, - m_dockMargin, - m_dockedWidth, - parentHeight - 2 * m_dockMargin); - break; - case DockedRight: - targetGeometry = QRect(parentWidget()->width() - m_dockedWidth - m_dockMargin, - m_dockMargin, - m_dockedWidth, - parentHeight - 2 * m_dockMargin); - break; - default: - return; - } - - if (m_geometryAnimation->state() == QAbstractAnimation::Running) { - m_geometryAnimation->stop(); - } - m_geometryAnimation->setStartValue(geometry()); - m_geometryAnimation->setEndValue(targetGeometry); - m_geometryAnimation->start(); - - m_contentWidget->setStyleSheet("#PropertiesContent {" - " background-color: #f5f5f5;" - " border: 1px solid #ccc;" - " border-radius: 0px;" - "}"); -} - -FloatingProperties::~FloatingProperties() -{ - delete _properties; -} - -void FloatingProperties::paintEvent(QPaintEvent *event) -{ - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - - // Draw shadow - QRect shadowRect = rect().adjusted(4, 4, -4, -4); - painter.fillRect(shadowRect, QColor(0, 0, 0, 30)); - - // Draw docking preview - if (m_dragging && m_previewDockPosition != Floating && m_previewDockPosition != m_dockPosition) { - painter.setPen(QPen(QColor(0, 120, 215), 2)); - painter.setBrush(QColor(0, 120, 215, 20)); - painter.drawRoundedRect(rect().adjusted(1, 1, -1, -1), 6, 6); - } - - QWidget::paintEvent(event); -} - -void FloatingProperties::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) { - QLabel *title = findChild(); - if (title && title->geometry().contains(event->pos())) { - m_dragging = true; - m_dragStartPosition = event->pos(); - - // Store current geometry if floating - if (m_dockPosition == Floating) { - m_floatingGeometry = geometry(); - } - - raise(); // Bring to front when dragging - } - } - QWidget::mousePressEvent(event); -} - -void FloatingProperties::mouseMoveEvent(QMouseEvent *event) -{ - if (m_dragging && (event->buttons() & Qt::LeftButton)) { - QPoint newPos = pos() + event->pos() - m_dragStartPosition; - - // If currently docked, undock first - if (m_dockPosition != Floating) { - m_dockPosition = Floating; - setFixedWidth(200); - // Adjust position to keep mouse on title bar - newPos = QPoint(event->globalPosition().x() - m_dragStartPosition.x(), - event->globalPosition().y() - m_dragStartPosition.y()); - if (parentWidget()) { - newPos = parentWidget()->mapFromGlobal(newPos); - } - setFixedHeight(m_floatHeight); - m_contentWidget->setStyleSheet("#PropertiesContent {" - " background-color: #f5f5f5;" - " border: 1px solid #ccc;" - " border-radius: 6px;" - "}"); - } - - // Keep within parent bounds - if (parentWidget()) { - int maxX = parentWidget()->width() - width(); - int maxY = parentWidget()->height() - height(); - newPos.setX(qMax(0, qMin(newPos.x(), maxX))); - newPos.setY(qMax(0, qMin(newPos.y(), maxY))); - } - - move(newPos); - - // Check for docking zones - m_previewDockPosition = checkDockingZone(newPos); - - // Remember floating position - if (m_previewDockPosition == Floating) { - m_floatingGeometry = QRect(newPos, size()); - } - - update(); // Repaint for preview - } - QWidget::mouseMoveEvent(event); -} - -void FloatingProperties::mouseReleaseEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton && m_dragging) { - m_dragging = false; - - // Apply docking if in zone - if (m_previewDockPosition != Floating) { - applyDocking(m_previewDockPosition); - } - - m_previewDockPosition = Floating; - update(); - } - QWidget::mouseReleaseEvent(event); -} - -void FloatingProperties::showEvent(QShowEvent *event) -{ - QWidget::showEvent(event); - updatePosition(); - raise(); // Ensure properties panel is on top -} - void FloatingProperties::resizeEvent(QResizeEvent *event) { - QWidget::resizeEvent(event); - - // If docked, maintain the docked state - if (m_dockPosition != Floating) { - updateDockedGeometry(); + FloatingPanelBase::resizeEvent(event); + + if (_properties) { + _properties->setFixedHeight(height()); } - _properties->setFixedHeight(height()); } \ No newline at end of file diff --git a/examples/epen_graph_editor/src/FloatingToolbar.cpp b/examples/epen_graph_editor/src/FloatingToolbar.cpp index 9a12e3d42..26c7e9d85 100644 --- a/examples/epen_graph_editor/src/FloatingToolbar.cpp +++ b/examples/epen_graph_editor/src/FloatingToolbar.cpp @@ -6,49 +6,35 @@ #include #include #include -#include -#include -#include -#include -#include +#include #include FloatingToolbar::FloatingToolbar(GraphEditorWindow *parent) - : QWidget(parent) // Always a child widget - , m_graphEditor(parent) - , m_dragging(false) - , m_dockPosition(Floating) - , m_previewDockPosition(Floating) - , m_dockMargin(0) // No margin when docked - , m_dockingDistance(40) - , m_dockedWidth(200) // Wider when docked + : FloatingPanelBase(parent, "Tools") { - // Keep it as a child widget with these flags - setWindowFlags(Qt::SubWindow | Qt::FramelessWindowHint); - setAttribute(Qt::WA_TranslucentBackground); - - // Create animation for smooth transitions - m_geometryAnimation = new QPropertyAnimation(this, "geometry"); - m_geometryAnimation->setDuration(200); - m_geometryAnimation->setEasingCurve(QEasingCurve::OutCubic); + // Set panel-specific dimensions + setFloatingWidth(150); + setDockedWidth(200); + // Initialize UI setupUI(); connectSignals(); // Initial floating size and position - setFixedWidth(150); + setFixedWidth(floatingWidth()); if (parent) { - m_floatingGeometry = QRect((parent->width() - 150) / 2, + m_floatingGeometry = QRect((parent->width() - floatingWidth()) / 2, (parent->height() - height()) / 2, - 150, + floatingWidth(), height()); setGeometry(m_floatingGeometry); } // Ensure toolbar is on top raise(); - _floatHeight = height(); + m_floatHeight = height(); + // Start docked to the left setDockPosition(DockPosition::DockedLeft); } @@ -83,15 +69,8 @@ QString FloatingToolbar::createSafeButtonText(const QString &icon, const QString void FloatingToolbar::setupUI() { - // Create scroll area for when docked - m_scrollArea = new QScrollArea(this); - m_scrollArea->setWidgetResizable(true); - m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - m_scrollArea->setFrameShape(QFrame::NoFrame); - - m_contentWidget = new QWidget(); - m_contentWidget->setObjectName("ToolbarContent"); + // Call base class setup + setupBaseUI("Tools"); QFont buttonFont = QApplication::font(); #ifdef Q_OS_MAC @@ -101,79 +80,38 @@ void FloatingToolbar::setupUI() #endif buttonFont.setPointSize(11); - m_scrollArea->setStyleSheet("QScrollArea {" - " background: transparent;" - " border: none;" - "}" - "QScrollBar:vertical {" - " background: #f0f0f0;" - " width: 10px;" - " border-radius: 5px;" - "}" - "QScrollBar::handle:vertical {" - " background: #c0c0c0;" - " border-radius: 5px;" - " min-height: 20px;" - "}" - "QScrollBar::handle:vertical:hover {" - " background: #a0a0a0;" - "}"); - - m_contentWidget->setStyleSheet("#ToolbarContent {" - " background-color: #f5f5f5;" - " border: 1px solid #ccc;" - " border-radius: 6px;" - "}" - "DraggableButton {" - " padding: 6px 8px;" - " margin: 2px;" - " border: 1px solid #bbb;" - " border-radius: 4px;" - " background-color: white;" - " text-align: left;" - " font-size: 11px;" - "}" - "DraggableButton:hover {" - " background-color: #e0e0e0;" - " border-color: #999;" - "}" - "DraggableButton:pressed {" - " background-color: #d0d0d0;" - "}" - "DraggableButton:disabled {" - " background-color: #f0f0f0;" - " color: #999;" - "}"); - - // Set scroll area content - m_scrollArea->setWidget(m_contentWidget); - - // Main layout for this widget - QVBoxLayout *mainLayout = new QVBoxLayout(this); - mainLayout->setContentsMargins(0, 0, 0, 0); - mainLayout->addWidget(m_scrollArea); - - // Content layout - m_layout = new QVBoxLayout(m_contentWidget); - m_layout->setContentsMargins(8, 8, 8, 8); - m_layout->setSpacing(4); - - // Title bar for dragging - QLabel *title = new QLabel("Tools"); - title->setAlignment(Qt::AlignCenter); - title->setStyleSheet("font-weight: bold;" - "padding: 8px;" - "background-color: #e0e0e0;" - "border-radius: 4px;" - "margin-bottom: 5px;"); - title->setCursor(Qt::SizeAllCursor); - m_layout->addWidget(title); + // Additional style for buttons + QString additionalStyle = + "DraggableButton {" + " padding: 6px 8px;" + " margin: 2px;" + " border: 1px solid #bbb;" + " border-radius: 4px;" + " background-color: white;" + " text-align: left;" + " font-size: 11px;" + "}" + "DraggableButton:hover {" + " background-color: #e0e0e0;" + " border-color: #999;" + "}" + "DraggableButton:pressed {" + " background-color: #d0d0d0;" + "}" + "DraggableButton:disabled {" + " background-color: #f0f0f0;" + " color: #999;" + "}"; + + getContentWidget()->setStyleSheet(getContentWidget()->styleSheet() + additionalStyle); + + QVBoxLayout *layout = getContentLayout(); // Node creation section - m_layout->addSpacing(5); + layout->addSpacing(5); QLabel *nodeLabel = new QLabel("Nodes:"); nodeLabel->setStyleSheet("font-weight: bold; color: #333;"); - m_layout->addWidget(nodeLabel); + layout->addWidget(nodeLabel); struct NodeType { @@ -187,15 +125,11 @@ void FloatingToolbar::setupUI() QVector nodeTypes = { {"Video Input", QString::fromUtf8("\u25C0"), "<", "Create a video input node", true, "VideoInput"}, - {"Video Output", - QString::fromUtf8("\u25B6"), - ">", - "Create a video output node", - false, - "VideoOutput"}, + {"Video Output", QString::fromUtf8("\u25B6"), ">", "Create a video output node", false, "VideoOutput"}, {"Process", QString::fromUtf8("\u2666"), "*", "Create a processing node", true, "Process"}, {"Image", QString::fromUtf8("\u25A1"), "#", "Create an image node", true, "Image"}, - {"Buffer", QString::fromUtf8("\u25AC"), "=", "Create a buffer node", true, "Buffer"}}; + {"Buffer", QString::fromUtf8("\u25AC"), "=", "Create a buffer node", true, "Buffer"} + }; for (const auto &nodeType : nodeTypes) { DraggableButton *btn = new DraggableButton(nodeType.actionName, this); @@ -207,21 +141,21 @@ void FloatingToolbar::setupUI() btn->setChecked(true); btn->setFont(buttonFont); btn->setProperty("nodeType", nodeType.name); - m_layout->addWidget(btn); + layout->addWidget(btn); } // Separator - m_layout->addSpacing(10); + layout->addSpacing(10); QFrame *separator = new QFrame(); separator->setFrameShape(QFrame::HLine); separator->setFrameShadow(QFrame::Sunken); - m_layout->addWidget(separator); - m_layout->addSpacing(5); + layout->addWidget(separator); + layout->addSpacing(5); // View controls QLabel *viewLabel = new QLabel("View:"); viewLabel->setStyleSheet("font-weight: bold; color: #333;"); - m_layout->addWidget(viewLabel); + layout->addWidget(viewLabel); struct ViewControl { @@ -230,267 +164,48 @@ void FloatingToolbar::setupUI() QString fallback; }; - QVector viewControls = {{"Zoom In", QString::fromUtf8("\u2295"), "+"}, - {"Zoom Out", QString::fromUtf8("\u2296"), "-"}, - {"Reset View", QString::fromUtf8("\u21BA"), "R"}}; + QVector viewControls = { + {"Zoom In", QString::fromUtf8("\u2295"), "+"}, + {"Zoom Out", QString::fromUtf8("\u2296"), "-"}, + {"Reset View", QString::fromUtf8("\u21BA"), "R"} + }; - QPushButton *btnZoomIn = new QPushButton( - createSafeButtonText(viewControls[0].icon, viewControls[0].name)); - QPushButton *btnZoomOut = new QPushButton( - createSafeButtonText(viewControls[1].icon, viewControls[1].name)); - QPushButton *btnResetView = new QPushButton( - createSafeButtonText(viewControls[2].icon, viewControls[2].name)); + QPushButton *btnZoomIn = new QPushButton(createSafeButtonText(viewControls[0].icon, viewControls[0].name)); + QPushButton *btnZoomOut = new QPushButton(createSafeButtonText(viewControls[1].icon, viewControls[1].name)); + QPushButton *btnResetView = new QPushButton(createSafeButtonText(viewControls[2].icon, viewControls[2].name)); btnZoomIn->setFont(buttonFont); btnZoomOut->setFont(buttonFont); btnResetView->setFont(buttonFont); - m_layout->addWidget(btnZoomIn); - m_layout->addWidget(btnZoomOut); - m_layout->addWidget(btnResetView); + layout->addWidget(btnZoomIn); + layout->addWidget(btnZoomOut); + layout->addWidget(btnResetView); connect(btnZoomIn, &QPushButton::clicked, this, &FloatingToolbar::zoomInRequested); connect(btnZoomOut, &QPushButton::clicked, this, &FloatingToolbar::zoomOutRequested); connect(btnResetView, &QPushButton::clicked, this, &FloatingToolbar::resetViewRequested); - m_layout->addStretch(); + layout->addStretch(); // Initial size - m_contentWidget->adjustSize(); + getContentWidget()->adjustSize(); adjustSize(); } void FloatingToolbar::connectSignals() { - if (m_graphEditor) { + if (getGraphEditor()) { connect(this, &FloatingToolbar::zoomInRequested, [this]() { - m_graphEditor->scale(1.2, 1.2); + getGraphEditor()->scale(1.2, 1.2); }); connect(this, &FloatingToolbar::zoomOutRequested, [this]() { - m_graphEditor->scale(0.8, 0.8); + getGraphEditor()->scale(0.8, 0.8); }); connect(this, &FloatingToolbar::resetViewRequested, [this]() { - m_graphEditor->resetTransform(); + getGraphEditor()->resetTransform(); }); } -} - -void FloatingToolbar::updatePosition() -{ - if (m_dockPosition != Floating) { - updateDockedGeometry(); - } -} - -void FloatingToolbar::setDockPosition(DockPosition position) -{ - if (m_dockPosition == position) - return; - - m_dockPosition = position; - - if (position == Floating) { - // Restore floating geometry - setMinimumSize(0, 0); - setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); - setFixedWidth(150); - - if (m_geometryAnimation->state() == QAbstractAnimation::Running) { - m_geometryAnimation->stop(); - } - m_geometryAnimation->setStartValue(geometry()); - m_geometryAnimation->setEndValue(m_floatingGeometry); - m_geometryAnimation->start(); - } else { - // Apply docked geometry - updateDockedGeometry(); - } -} - -FloatingToolbar::DockPosition FloatingToolbar::checkDockingZone(const QPoint &pos) -{ - if (!parentWidget()) - return Floating; - - int parentWidth = parentWidget()->width(); - - // Check left edge - if (pos.x() <= m_dockingDistance) { - return DockedLeft; - } - - // Check right edge - if (pos.x() + width() >= parentWidth - m_dockingDistance) { - return DockedRight; - } - - return Floating; -} - -void FloatingToolbar::applyDocking(DockPosition position) -{ - setDockPosition(position); -} - -void FloatingToolbar::updateDockedGeometry() -{ - if (!parentWidget() || m_dockPosition == Floating) { - return; - } - - QRect targetGeometry; - int parentHeight = parentWidget()->height(); - - // Remove size constraints for docking - setMinimumSize(0, 0); - setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); - - switch (m_dockPosition) { - case DockedLeft: - targetGeometry = QRect(m_dockMargin, - m_dockMargin, - m_dockedWidth, - parentHeight - 2 * m_dockMargin); - break; - case DockedRight: - targetGeometry = QRect(parentWidget()->width() - m_dockedWidth - m_dockMargin, - m_dockMargin, - m_dockedWidth, - parentHeight - 2 * m_dockMargin); - break; - default: - return; - } - - if (m_geometryAnimation->state() == QAbstractAnimation::Running) { - m_geometryAnimation->stop(); - } - m_geometryAnimation->setStartValue(geometry()); - m_geometryAnimation->setEndValue(targetGeometry); - m_geometryAnimation->start(); - - m_contentWidget->setStyleSheet("#ToolbarContent {" - " background-color: #f5f5f5;" - " border: 1px solid #ccc;" - " border-radius: 0px;" - "}"); -} - -void FloatingToolbar::paintEvent(QPaintEvent *event) -{ - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - - // Draw shadow - QRect shadowRect = rect().adjusted(4, 4, -4, -4); - painter.fillRect(shadowRect, QColor(0, 0, 0, 30)); - - // Draw docking preview - if (m_dragging && m_previewDockPosition != Floating && m_previewDockPosition != m_dockPosition) { - painter.setPen(QPen(QColor(0, 120, 215), 2)); - painter.setBrush(QColor(0, 120, 215, 20)); - painter.drawRoundedRect(rect().adjusted(1, 1, -1, -1), 6, 6); - } - - QWidget::paintEvent(event); -} - -void FloatingToolbar::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) { - QLabel *title = findChild(); - if (title && title->geometry().contains(event->pos())) { - m_dragging = true; - m_dragStartPosition = event->pos(); - - // Store current geometry if floating - if (m_dockPosition == Floating) { - m_floatingGeometry = geometry(); - } - - raise(); // Bring to front when dragging - } - } - QWidget::mousePressEvent(event); -} - -void FloatingToolbar::mouseMoveEvent(QMouseEvent *event) -{ - if (m_dragging && (event->buttons() & Qt::LeftButton)) { - QPoint newPos = pos() + event->pos() - m_dragStartPosition; - - // If currently docked, undock first - if (m_dockPosition != Floating) { - m_dockPosition = Floating; - setFixedWidth(150); - // Adjust position to keep mouse on title bar - newPos = QPoint(event->globalPosition().x() - m_dragStartPosition.x(), - event->globalPosition().y() - m_dragStartPosition.y()); - if (parentWidget()) { - newPos = parentWidget()->mapFromGlobal(newPos); - } - setFixedHeight(_floatHeight); - m_contentWidget->setStyleSheet("#ToolbarContent {" - " background-color: #f5f5f5;" - " border: 1px solid #ccc;" - " border-radius: 6px;" - "}"); - } - - // Keep within parent bounds - if (parentWidget()) { - int maxX = parentWidget()->width() - width(); - int maxY = parentWidget()->height() - height(); - newPos.setX(qMax(0, qMin(newPos.x(), maxX))); - newPos.setY(qMax(0, qMin(newPos.y(), maxY))); - } - - move(newPos); - - // Check for docking zones - m_previewDockPosition = checkDockingZone(newPos); - - // Remember floating position - if (m_previewDockPosition == Floating) { - m_floatingGeometry = QRect(newPos, size()); - } - - update(); // Repaint for preview - } - QWidget::mouseMoveEvent(event); -} - -void FloatingToolbar::mouseReleaseEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton && m_dragging) { - m_dragging = false; - - // Apply docking if in zone - if (m_previewDockPosition != Floating) { - applyDocking(m_previewDockPosition); - } - - m_previewDockPosition = Floating; - update(); - } - QWidget::mouseReleaseEvent(event); -} - -void FloatingToolbar::showEvent(QShowEvent *event) -{ - QWidget::showEvent(event); - updatePosition(); - raise(); // Ensure toolbar is on top -} - -void FloatingToolbar::resizeEvent(QResizeEvent *event) -{ - QWidget::resizeEvent(event); - - // If docked, maintain the docked state - if (m_dockPosition != Floating) { - updateDockedGeometry(); - } } \ No newline at end of file From de7f661a5c694a90a279dd772707b24177395570 Mon Sep 17 00:00:00 2001 From: mahmoodzaker Date: Wed, 16 Jul 2025 19:38:40 +0330 Subject: [PATCH 020/124] Add buildlib --- .gitignore | 2 +- .../QtPropertyBrowser/buildlib/CMakeLists.txt | 107 ++++++++ .../QtPropertyBrowser/buildlib/buildlib.pro | 13 + .../buildlib/buildlib.vcxproj | 253 ++++++++++++++++++ .../buildlib/buildlib.vcxproj.filters | 146 ++++++++++ .../lib/libQt6PropertyBrowserd.1.0.0.dylib | Bin 0 -> 11813184 bytes .../lib/libQt6PropertyBrowserd.1.dylib | 1 + .../buildlib/lib/libQt6PropertyBrowserd.dylib | 1 + 8 files changed, 522 insertions(+), 1 deletion(-) create mode 100644 external/QtPropertyBrowser/buildlib/CMakeLists.txt create mode 100644 external/QtPropertyBrowser/buildlib/buildlib.pro create mode 100644 external/QtPropertyBrowser/buildlib/buildlib.vcxproj create mode 100644 external/QtPropertyBrowser/buildlib/buildlib.vcxproj.filters create mode 100755 external/QtPropertyBrowser/buildlib/lib/libQt6PropertyBrowserd.1.0.0.dylib create mode 120000 external/QtPropertyBrowser/buildlib/lib/libQt6PropertyBrowserd.1.dylib create mode 120000 external/QtPropertyBrowser/buildlib/lib/libQt6PropertyBrowserd.dylib diff --git a/.gitignore b/.gitignore index fc8ef420c..9f353d970 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ *.pyc CMakeLists.txt.user -build*/ +build/ .vscode/ tags diff --git a/external/QtPropertyBrowser/buildlib/CMakeLists.txt b/external/QtPropertyBrowser/buildlib/CMakeLists.txt new file mode 100644 index 000000000..de17a6bbf --- /dev/null +++ b/external/QtPropertyBrowser/buildlib/CMakeLists.txt @@ -0,0 +1,107 @@ +# CMakeLists.txt for building QtPropertyBrowser library + +# Set build configuration +set(QTPROPERTYBROWSER_BUILDLIB TRUE) + +# Include the qtpropertybrowser settings +include(${CMAKE_CURRENT_SOURCE_DIR}/../src/qtpropertybrowser.cmake) + +# Create the shared library +add_library(${QTPROPERTYBROWSER_LIBNAME} SHARED + ${QTPROPERTYBROWSER_SOURCES} + ${QTPROPERTYBROWSER_HEADERS} + ${QTPROPERTYBROWSER_RESOURCES} +) + +# Link Qt libraries +target_link_libraries(${QTPROPERTYBROWSER_LIBNAME} + PUBLIC + Qt6::Core + Qt6::Widgets +) + +# Set target properties +set_target_properties(${QTPROPERTYBROWSER_LIBNAME} PROPERTIES + VERSION 1.0.0 + SOVERSION 1 + DEBUG_POSTFIX d # Add 'd' suffix for debug builds +) + +# Set output directories +set_target_properties(${QTPROPERTYBROWSER_LIBNAME} PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${QTPROPERTYBROWSER_LIBDIR} + RUNTIME_OUTPUT_DIRECTORY ${QTPROPERTYBROWSER_LIBDIR} + ARCHIVE_OUTPUT_DIRECTORY ${QTPROPERTYBROWSER_LIBDIR} +) + +# Platform-specific settings +if(APPLE) + # Equivalent to CONFIG += absolute_library_soname + set_target_properties(${QTPROPERTYBROWSER_LIBNAME} PROPERTIES + MACOSX_RPATH ON + INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib" + ) +endif() + +# Windows-specific settings +if(WIN32) + # Export definition + target_compile_definitions(${QTPROPERTYBROWSER_LIBNAME} PRIVATE QT_QTPROPERTYBROWSER_EXPORT) + + # Set DLL output directory for Windows + set_target_properties(${QTPROPERTYBROWSER_LIBNAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_DEBUG ${QTPROPERTYBROWSER_LIBDIR} + RUNTIME_OUTPUT_DIRECTORY_RELEASE ${QTPROPERTYBROWSER_LIBDIR} + ) + + # Get Qt installation binary directory + get_target_property(QT_BIN_DIR Qt6::Core LOCATION) + get_filename_component(QT_BIN_DIR ${QT_BIN_DIR} DIRECTORY) + get_filename_component(QT_BIN_DIR ${QT_BIN_DIR} DIRECTORY) + set(QT_BIN_DIR "${QT_BIN_DIR}/bin") + + # Install DLL to Qt bin directory (optional, comment out if not needed) + install(TARGETS ${QTPROPERTYBROWSER_LIBNAME} + RUNTIME DESTINATION ${QT_BIN_DIR} + ) +endif() + +# Include directories +target_include_directories(${QTPROPERTYBROWSER_LIBNAME} + PUBLIC + $ + $ +) + +# Multi-configuration generators (Visual Studio, Xcode) +if(CMAKE_CONFIGURATION_TYPES) + # Set output directories for each configuration + foreach(CONFIG ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER ${CONFIG} CONFIG_UPPER) + set_target_properties(${QTPROPERTYBROWSER_LIBNAME} PROPERTIES + LIBRARY_OUTPUT_DIRECTORY_${CONFIG_UPPER} ${QTPROPERTYBROWSER_LIBDIR} + RUNTIME_OUTPUT_DIRECTORY_${CONFIG_UPPER} ${QTPROPERTYBROWSER_LIBDIR} + ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_UPPER} ${QTPROPERTYBROWSER_LIBDIR} + ) + endforeach() +endif() + +# Install rules +install(TARGETS ${QTPROPERTYBROWSER_LIBNAME} + EXPORT QtPropertyBrowserTargets + LIBRARY DESTINATION ${QTPROPERTYBROWSER_LIBDIR} + ARCHIVE DESTINATION ${QTPROPERTYBROWSER_LIBDIR} + RUNTIME DESTINATION ${QTPROPERTYBROWSER_LIBDIR} +) + +# Install headers +install(FILES ${QTPROPERTYBROWSER_HEADERS} + DESTINATION include/qtpropertybrowser +) + +# Export targets for find_package support (optional) +install(EXPORT QtPropertyBrowserTargets + FILE QtPropertyBrowserTargets.cmake + NAMESPACE QtPropertyBrowser:: + DESTINATION lib/cmake/QtPropertyBrowser +) \ No newline at end of file diff --git a/external/QtPropertyBrowser/buildlib/buildlib.pro b/external/QtPropertyBrowser/buildlib/buildlib.pro new file mode 100644 index 000000000..ce6c13772 --- /dev/null +++ b/external/QtPropertyBrowser/buildlib/buildlib.pro @@ -0,0 +1,13 @@ +TEMPLATE=lib +CONFIG += qt dll shared qtpropertybrowser-buildlib +mac:CONFIG += absolute_library_soname +win32|mac:!wince*:!win32-msvc:!macx-xcode:CONFIG += debug_and_release build_all +include(../src/qtpropertybrowser.pri) +TARGET = $$QTPROPERTYBROWSER_LIBNAME +DESTDIR = $$QTPROPERTYBROWSER_LIBDIR +win32 { + DLLDESTDIR = $$[QT_INSTALL_BINS] + QMAKE_DISTCLEAN += $$[QT_INSTALL_BINS]\\$${QTPROPERTYBROWSER_LIBNAME}.dll +} +target.path = $$DESTDIR +INSTALLS += target diff --git a/external/QtPropertyBrowser/buildlib/buildlib.vcxproj b/external/QtPropertyBrowser/buildlib/buildlib.vcxproj new file mode 100644 index 000000000..9f595e23d --- /dev/null +++ b/external/QtPropertyBrowser/buildlib/buildlib.vcxproj @@ -0,0 +1,253 @@ + + + + + Release + x64 + + + Debug + x64 + + + + {6B65EA97-FCC8-3A0D-9CD8-BBE6ECE020F9} + Qt6PropertyBrowser + QtVS_v304 + 10.0.19041.0 + $(MSBuildProjectDirectory)\QtMsBuild + Qt6PropertyBrowser + + + + ..\lib\ + false + DynamicLibrary + release\ + Qt6PropertyBrowser + v143 + + + ..\lib\ + false + DynamicLibrary + debug\ + Qt6PropertyBrowserd + v143 + + + + + + + + + + + + + + + + + + true + $(ProjectName)d + + + true + false + + + 6.2.2_msvc2019_64 + core;gui;widgets + + + 6.2.2_msvc2019_64 + core;gui;widgets + + + + + + + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -permissive- -Zc:__cplusplus -Zc:externConstexpr -utf-8 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions) + release\ + false + None + 4577;4467;%(DisableSpecificWarnings) + Sync + stdcpp17 + release\ + MaxSpeed + _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_DISABLE_DEPRECATED_BEFORE=0;NDEBUG;QT_NO_DEBUG;QT_QTPROPERTYBROWSER_EXPORT;%(PreprocessorDefinitions) + false + + + MultiThreadedDLL + true + Level3 + true + + + %(AdditionalLibraryDirectories) + true + true + false + true + true + false + true + $(OutDir)\Qt6PropertyBrowser.dll + true + Windows + true + + + Unsigned + None + 0 + + + _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_DISABLE_DEPRECATED_BEFORE=0;NDEBUG;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;%(PreprocessorDefinitions) + + + copy "$(TargetPath)" $(QTDIR)\bin\ +copy "$(TargetPath)" $(SolutionDir)lib +copy "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetName).lib" $(SolutionDir)lib + + + + + + + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -permissive- -Zc:__cplusplus -Zc:externConstexpr -utf-8 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions) + debug\ + false + 4577;4467;%(DisableSpecificWarnings) + Sync + stdcpp17 + debug\ + Disabled + _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_DISABLE_DEPRECATED_BEFORE=0;QT_QTPROPERTYBROWSER_EXPORT;%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + true + true + Level3 + true + + + %(AdditionalLibraryDirectories) + true + true + true + true + $(OutDir)\Qt6PropertyBrowserd.dll + true + Windows + true + + + Unsigned + None + 0 + + + _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_DISABLE_DEPRECATED_BEFORE=0;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;_DEBUG;%(PreprocessorDefinitions) + + + copy "$(TargetPath)" $(QTDIR)\bin\ +copy "$(TargetPath)" $(SolutionDir)lib +copy "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetName).lib" $(SolutionDir)lib + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + + + false + false + + + false + false + + + false + false + + + + + input + input + $(Configuration) + %(Filename).moc + + + input + input + $(Configuration) + %(Filename).moc + + + input + input + $(Configuration) + %(Filename).moc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/QtPropertyBrowser/buildlib/buildlib.vcxproj.filters b/external/QtPropertyBrowser/buildlib/buildlib.vcxproj.filters new file mode 100644 index 000000000..20574c5c6 --- /dev/null +++ b/external/QtPropertyBrowser/buildlib/buildlib.vcxproj.filters @@ -0,0 +1,146 @@ + + + + + {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} + cpp;c;cxx;moc;h;def;odl;idl;res; + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} + qrc;* + false + + + {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} + qrc;* + false + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + \ No newline at end of file diff --git a/external/QtPropertyBrowser/buildlib/lib/libQt6PropertyBrowserd.1.0.0.dylib b/external/QtPropertyBrowser/buildlib/lib/libQt6PropertyBrowserd.1.0.0.dylib new file mode 100755 index 0000000000000000000000000000000000000000..6079761cf726cf5d4fddabf8d3f80c7bc2fa2157 GIT binary patch literal 11813184 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%0DRj4*)l>i+LfxxSbcG>8xD5-H@3V)~4xd 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­biaY5sHOL`f0`viu>X>%_G~F83*MQr#6PZ6m#f~ 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