| 133 | }; |
| 134 | |
| 135 | LayoutNode parseLayoutNode(const QDomElement& element) { |
| 136 | LayoutNode node; |
| 137 | if (element.isNull()) { |
| 138 | return node; |
| 139 | } |
| 140 | |
| 141 | if (element.tagName() == QStringLiteral("DockSplitter")) { |
| 142 | node.type = LayoutNode::Type::kSplitter; |
| 143 | node.valid = true; |
| 144 | node.orientation = element.attribute(QStringLiteral("orientation")).startsWith(QStringLiteral("|")) ? Qt::Horizontal |
| 145 | : Qt::Vertical; |
| 146 | for (const QString& size : element.attribute(QStringLiteral("sizes")).split(';', Qt::SkipEmptyParts)) { |
| 147 | bool ok = false; |
| 148 | const double value = size.toDouble(&ok); |
| 149 | if (ok) { |
| 150 | node.size_ratios.push_back(value); |
| 151 | } |
| 152 | } |
| 153 | for (QDomElement child = element.firstChildElement(); !child.isNull(); child = child.nextSiblingElement()) { |
| 154 | LayoutNode child_node = parseLayoutNode(child); |
| 155 | if (child_node.valid) { |
| 156 | node.children.push_back(std::move(child_node)); |
| 157 | } |
| 158 | } |
| 159 | node.valid = !node.children.isEmpty(); |
| 160 | return node; |
| 161 | } |
| 162 | |
| 163 | if (element.tagName() == QStringLiteral("DockArea")) { |
| 164 | node.type = LayoutNode::Type::kArea; |
| 165 | node.valid = true; |
| 166 | node.area_id = element.attribute(QStringLiteral("id")); |
| 167 | node.area_name = element.attribute(QStringLiteral("name")); |
| 168 | // node.plots holds the per-dock content element regardless of kind — a |
| 169 | // <plot> (PlotWidget) or an object widget's own tag (<scene3d>, <scene2d>, |
| 170 | // …). Each <DockArea> writes exactly one payload per dock, so collect every |
| 171 | // child element and let restore discriminate by tagName(). |
| 172 | for (QDomElement child = element.firstChildElement(); !child.isNull(); child = child.nextSiblingElement()) { |
| 173 | node.plots.push_back(child); |
| 174 | } |
| 175 | return node; |
| 176 | } |
| 177 | |
| 178 | return node; |
| 179 | } |
| 180 | |
| 181 | // First leaf-area dock element reachable from `node`, descending into the |
| 182 | // first child of each splitter. Used to decide between plot-pool and |
no test coverage detected