ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
cvSelectionPropertiesWidget.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #pragma once
9 
10 // clang-format off
11 // Qt - must be included before qPCL.h for MOC to work correctly
12 #include <QtGui/QColor>
13 #include <QtWidgets/QGroupBox>
14 #include <QtWidgets/QLabel>
15 #include <QtCore/QObject>
16 #include <QtWidgets/QPushButton>
17 #include <QtWidgets/QScrollArea>
18 #include <QtWidgets/QSpinBox>
19 #include <QtWidgets/QTableWidget>
20 #include <QtWidgets/QToolButton>
21 #include <QtWidgets/QWidget>
22 // clang-format on
23 
24 // Forward declaration
25 class cvExpanderButton;
26 
27 #include "qPCL.h"
28 
29 // LOCAL
30 #include "cvSelectionBase.h"
31 #include "cvSelectionData.h"
32 #include "cvSelectionHighlighter.h" // For SelectionLabelProperties
33 #include "cvSelectionLabelPropertiesDialog.h" // For LabelProperties
34 
35 // Forward declarations
37 class cvTooltipFormatter;
39 class cvSelectionAlgebra;
40 class cvSelectionFilter;
41 class cvSelectionBookmarks;
43 class vtkPolyData;
44 class QPushButton;
45 class QColorDialog;
46 class QDoubleSpinBox;
47 class QCheckBox;
48 class QComboBox;
49 class QLineEdit;
50 class QMenu;
51 class QVBoxLayout;
52 class QSpinBox;
53 class ccHObject;
54 class QScrollArea;
55 
72  public cvSelectionBase {
73  Q_OBJECT
74 
75 public:
79  struct SavedSelection {
80  QString name; // e.g., "s0", "s1"
81  QString type; // e.g., "ID Selection"
82  QColor color; // Display color
83  cvSelectionData data; // The actual selection data
84  };
85 
86  explicit cvSelectionPropertiesWidget(QWidget* parent = nullptr);
87  ~cvSelectionPropertiesWidget() override;
88 
89  // cvSelectionBase interface
90  void setHighlighter(cvSelectionHighlighter* highlighter);
91  void setSelectionManager(cvViewSelectionManager* manager);
92  void syncUIWithHighlighter();
93 
94  bool updateSelection(const cvSelectionData& selectionData,
95  vtkPolyData* polyData = nullptr);
96  void clearSelection();
97 
98  const cvSelectionData& selectionData() const { return m_selectionData; }
100  return m_selectionManager;
101  }
102 
106  void setDataProducerName(const QString& name);
107 
112  void refreshDataProducers();
113 
114 signals:
115  // Highlight/opacity changes
116  void highlightColorChanged(double r, double g, double b, int mode);
117  void highlightOpacityChanged(double opacity, int mode);
118 
119  // Selection Editor signals
120  void expressionChanged(const QString& expression);
122  void selectionAdded(const cvSelectionData& selection);
123  void selectionRemoved(int index);
125 
126  // Find Data actions
129  // Emitted when extraction is successful
133  void findDataRequested(const QString& dataProducer,
134  const QString& elementType,
135  const QString& attribute,
136  const QString& op,
137  const QString& value);
138 
139  // Legacy signals
140  void algebraOperationRequested(int operation);
141  void bookmarkRequested(const QString& name);
142  void annotationRequested(const QString& text);
143 
144 private slots:
145  // === Selection Display slots ===
146  void onCellLabelsClicked();
147  void onPointLabelsClicked();
148  void onEditLabelPropertiesClicked();
149  void onSelectionColorClicked();
150  void onInteractiveSelectionColorClicked();
151  void onEditInteractiveLabelPropertiesClicked();
152  void onLabelPropertiesApplied(
154  void onInteractiveLabelPropertiesApplied(
156 
157  // === Selection Editor slots ===
158  void onExpressionChanged(const QString& text);
159  void onAddActiveSelectionClicked();
160  void onRemoveSelectedSelectionClicked();
161  void onRemoveAllSelectionsClicked();
162  void onActivateCombinedSelectionsClicked();
163  void onSelectionEditorTableSelectionChanged();
164  void onSelectionEditorCellClicked(int row, int column);
165  void onSelectionEditorCellDoubleClicked(int row, int column);
166 
167  // === Find Data / Selected Data slots ===
168  void onAttributeTypeChanged(int index);
169  void onInvertSelectionToggled(bool checked);
170  void onFreezeClicked();
171  void onExtractClicked();
172  void onPlotOverTimeClicked();
173  void onToggleColumnVisibility();
174  void onToggleFieldDataClicked(bool checked);
175 
176  // Create Selection (Find Data) slots
177  void onDataProducerChanged(int index);
178  void onElementTypeChanged(int index);
179  void onFindDataClicked();
180  void onResetClicked();
181  void onClearClicked();
182  void updateAttributeCombo();
183  void updateDataProducerCombo();
184  void addQueryRow(int index = -1,
185  const QString& attribute = QString(),
186  const QString& op = QString(),
187  const QString& value = QString());
188  void removeQueryRow(int index);
189  void updateQueryRowButtons();
190  void performFindData(const QString& attribute,
191  const QString& op,
192  const QString& value,
193  bool isCell);
194  void onSpreadsheetItemClicked(QTableWidgetItem* item);
195 
196  // Legacy slots (existing functionality)
197  void onHoverColorClicked();
198  void onPreselectedColorClicked();
199  void onSelectedColorClicked();
200  void onBoundaryColorClicked();
201  void onHoverOpacityChanged(double value);
202  void onPreselectedOpacityChanged(double value);
203  void onSelectedOpacityChanged(double value);
204  void onBoundaryOpacityChanged(double value);
205  void onExportToMeshClicked();
206  void onExportToPointCloudClicked();
207  void onSelectionTableItemClicked(QTableWidgetItem* item);
208  void onAlgebraOperationTriggered();
209  // Filter methods removed - UI not implemented
210  // Bookmark methods removed - UI not implemented
211  void onAddAnnotationClicked();
212  void onExtractBoundaryClicked();
213 
214  // Highlighter property change handlers (for external property changes)
215  void onHighlighterColorChanged(int mode);
216  void onHighlighterOpacityChanged(int mode);
217  void onHighlighterLabelPropertiesChanged(bool interactive);
218 
219 protected:
220  // Override eventFilter to handle scroll area resize events
221  bool eventFilter(QObject* obj, QEvent* event) override;
222  // Override resizeEvent to handle widget resize (for drag resize)
223  void resizeEvent(QResizeEvent* event) override;
224 
225 private:
226  void setupUi();
227 
228  // ParaView-style sections
229  void setupSelectedDataHeader();
230  void setupCreateSelectionSection();
231  void setupSelectionDisplaySection();
232  void setupSelectionEditorSection();
233  void setupSelectedDataSpreadsheet();
234  void
235  setupCompactStatisticsSection(); // Compact stats (replaces Statistics tab)
236 
237  void updateStatistics(vtkPolyData* polyData,
238  const cvSelectionData* customSelection = nullptr);
239  void updateSelectionList(vtkPolyData* polyData);
240  void updateSpreadsheetData(
241  vtkPolyData* polyData,
242  const cvSelectionData* customSelection = nullptr);
243  void computeBoundingBox(vtkPolyData* polyData, double bounds[6]);
244  QString formatBounds(const double bounds[6]);
245  void showColorDialog(const QString& title,
246  double currentColor[3],
247  int mode);
248  void highlightSingleItem(qint64 id);
249  qint64 extractIdFromItemText(const QString& itemText);
250  // updateBookmarkCombo removed - UI not implemented
251  void updateSelectionEditorTable();
252  QString generateSelectionName();
253  QColor generateSelectionColor() const;
254 
255  // Color synchronization helper
256  void syncInternalColorArray(double r, double g, double b, int mode);
257 
258  // ParaView-style color button icon update helper
259  // Uses QAbstractButton to support both QPushButton and QToolButton
260  void updateColorButtonIcon(QAbstractButton* button, const QColor& color);
261 
262  // Helper to setup collapsible QGroupBox behavior
263  void setupCollapsibleGroupBox(QGroupBox* groupBox);
264 
265  // Helper to update scroll content width (called from resize handlers)
266  void updateScrollContentWidth();
267 
268  // Expression evaluation helpers (ParaView-style selection algebra)
269  cvSelectionData evaluateExpression(const QString& expression);
270  QStringList tokenizeExpression(const QString& expression);
271  cvSelectionData parseOrExpression(const QStringList& tokens, int& pos);
272  cvSelectionData parseXorExpression(const QStringList& tokens, int& pos);
273  cvSelectionData parseAndExpression(const QStringList& tokens, int& pos);
274  cvSelectionData parseUnaryExpression(const QStringList& tokens, int& pos);
275  cvSelectionData parsePrimaryExpression(const QStringList& tokens, int& pos);
276 
277 private:
278  // Core components
279  cvSelectionHighlighter* m_highlighter;
280  cvTooltipFormatter* m_tooltipFormatter;
281  cvViewSelectionManager* m_selectionManager;
282  cvSelectionData m_selectionData;
283  QVector<qint64>
284  m_originalSelectionIds; // Store original IDs for invert toggle
285 
286  // Label properties are now stored in cvSelectionHighlighter (single source
287  // of truth) Local copies only used for dialog initialization before
288  // highlighter is set
289 
290  // Saved selections for Selection Editor
291  QList<SavedSelection> m_savedSelections;
292  QString m_dataProducerName;
293 
294  // Main scroll area
295  QScrollArea* m_scrollArea;
296  QWidget* m_scrollContent;
297 
298  // === Selected Data Header ===
299  cvExpanderButton* m_selectedDataExpander;
300  QWidget* m_selectedDataContainer;
301  QLabel* m_selectedDataLabel;
302  QPushButton* m_freezeButton;
303  QPushButton* m_extractButton;
304  QPushButton* m_plotOverTimeButton;
305 
306  // === Selection Display Section ===
307  cvExpanderButton* m_selectionDisplayExpander;
308  QWidget* m_selectionDisplayContainer;
309  QGroupBox* m_selectionDisplayGroup; // Legacy - may be nullptr
310  // Selection Labels
311  QPushButton* m_cellLabelsButton;
312  QPushButton* m_pointLabelsButton;
313  QMenu* m_cellLabelsMenu;
314  QMenu* m_pointLabelsMenu;
315  QPushButton* m_editLabelPropertiesButton;
316  // Selection Appearance
317  QToolButton* m_selectionColorButton; // ParaView uses QToolButton
318  // (pqColorChooserButton extends
319  // QToolButton)
320  // Interactive Selection
321  QToolButton*
322  m_interactiveSelectionColorButton; // ParaView uses QToolButton
323  QPushButton* m_editInteractiveLabelPropertiesButton;
324 
325  // === Selection Editor Section ===
326  cvExpanderButton* m_selectionEditorExpander;
327  QWidget* m_selectionEditorContainer;
328  QGroupBox* m_selectionEditorGroup; // Legacy - may be nullptr
329  QLabel* m_dataProducerLabel;
330  QLabel* m_dataProducerValue;
331  QLabel* m_elementTypeLabel;
332  QLabel* m_elementTypeValue; // ParaView-style: shows element type in a
333  // styled label
334  QLabel* m_expressionLabel;
335  QLineEdit* m_expressionEdit;
336  QTableWidget* m_selectionEditorTable; // Name, Type, Color columns
337  QToolButton* m_addSelectionButton;
338  QToolButton* m_removeSelectionButton;
339  QToolButton* m_removeAllSelectionsButton;
340  QPushButton* m_activateCombinedSelectionsButton;
341 
342  // === Create Selection Section (ParaView's Find Data) ===
343  cvExpanderButton* m_createSelectionExpander;
344  QWidget* m_createSelectionContainer;
345  QGroupBox* m_createSelectionGroup; // Legacy - may be nullptr
346  QComboBox* m_dataProducerCombo;
347  QComboBox* m_elementTypeCombo;
348  QComboBox* m_attributeCombo;
349  QComboBox* m_operatorCombo;
350  QLineEdit* m_valueEdit;
351  QSpinBox* m_processIdSpinBox;
352  QPushButton* m_findDataButton;
353  QPushButton* m_resetButton;
354  QPushButton* m_clearButton;
355  QVBoxLayout* m_queriesLayout;
356 
357  // Query row structure to manage multiple conditions
358  struct QueryRow {
359  QComboBox* attributeCombo;
360  QComboBox* operatorCombo;
361  QLineEdit* valueEdit;
362  QPushButton* plusButton;
363  QPushButton* minusButton;
364  QWidget* container;
365 
366  // Comparison operator needed for QList
367  bool operator==(const QueryRow& other) const {
368  return container == other.container;
369  }
370  };
371  QList<QueryRow> m_queryRows;
372 
373  // === Selected Data Spreadsheet ===
374  cvExpanderButton* m_selectedDataSpreadsheetExpander;
375  QWidget* m_selectedDataSpreadsheetContainer;
376  QGroupBox* m_selectedDataGroup; // Legacy - may be nullptr
377  QComboBox* m_attributeTypeCombo;
378  QToolButton* m_toggleColumnVisibilityButton;
379  QToolButton* m_toggleFieldDataButton; // ParaView-style: toggle field data
380  // visibility
381  QCheckBox* m_invertSelectionCheck;
382  QTableWidget* m_spreadsheetTable;
383 
384  // === Compact Statistics Section (ParaView-style: no tabs) ===
385  cvExpanderButton* m_compactStatsExpander;
386  QWidget* m_compactStatsContainer;
387  QGroupBox* m_compactStatsGroup; // Legacy - may be nullptr
388  QLabel* m_countLabel;
389  QLabel* m_typeLabel;
390  QLabel* m_boundsLabel;
391  QLabel* m_centerLabel;
392  QLabel* m_volumeLabel;
393 
394  // === Optional: Tab widget pointer (set to nullptr in new design) ===
395  QTabWidget* m_tabWidget;
396 
397  // === Legacy UI elements (kept for backward compatibility, may be nullptr)
398  // === These are initialized to nullptr and can be conditionally shown in
399  // future menus
400  QTableWidget* m_selectionTableWidget; // Legacy selection list table
401  QLabel* m_listInfoLabel; // Legacy "Showing N items" label
402  QComboBox* m_algebraOpCombo; // Algebra operations combo
403  QPushButton* m_applyAlgebraButton; // Apply algebra operation
404  QPushButton* m_extractBoundaryButton; // Extract boundary
405  // Filter UI removed - not implemented
406  // Bookmark UI removed - not implemented
407  QPushButton* m_addAnnotationButton; // Add annotation
408 
409  // Legacy color/opacity controls (may be nullptr in simplified UI)
410  QPushButton* m_hoverColorButton;
411  QPushButton* m_preselectedColorButton;
412  QPushButton* m_selectedColorButton;
413  QPushButton* m_boundaryColorButton;
414  QDoubleSpinBox* m_hoverOpacitySpin;
415  QDoubleSpinBox* m_preselectedOpacitySpin;
416  QDoubleSpinBox* m_selectedOpacitySpin;
417  QDoubleSpinBox* m_boundaryOpacitySpin;
418 
419  // Colors are now stored in cvSelectionHighlighter (single source of truth)
420  // These QColor helpers provide convenient access for UI updates
421  QColor getSelectionColor() const;
422  QColor getInteractiveSelectionColor() const;
423 
424  // Statistics
425  int m_selectionCount;
426  QString m_selectionType;
427  double m_bounds[6];
428  double m_center[3];
429  double m_volume;
430 
431  // Selection name counter
432  int m_selectionNameCounter;
433 
434  // Extract counter (ParaView-style: ExtractSelection1, ExtractSelection2,
435  // ...) Shared between mesh and point cloud for unified indexing
436  int m_extractCounter;
437 
438  // Selection colors palette (like ParaView)
439  static const QColor s_selectionColors[];
440  static const int s_selectionColorsCount;
441 
442  // Current label array selections (for Cell/Point Labels menus)
443  QString m_currentCellLabelArray;
444  QString m_currentPointLabelArray;
445 
446  // For single item highlighting with RED color
447  double m_savedPreselectedColor[3];
448  qint64 m_lastHighlightedId;
449 };
MouseEvent event
std::string name
math::float4 color
#define slots
#define signals
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
cvExpanderButton provides a frame with a toggle mode for collapsible sections.
Selection algebra operations.
Selection annotation manager.
Lightweight base class for all selection-related components.
Encapsulates selection data without exposing VTK types.
Advanced selection filtering system.
Helper class for highlighting selected elements in the visualizer.
Comprehensive selection properties and management widget.
void selectionAdded(const cvSelectionData &selection)
void extractedObjectReady(ccHObject *obj)
void algebraOperationRequested(int operation)
cvViewSelectionManager * selectionManager() const
void findDataRequested(const QString &dataProducer, const QString &elementType, const QString &attribute, const QString &op, const QString &value)
void bookmarkRequested(const QString &name)
const cvSelectionData & selectionData() const
void expressionChanged(const QString &expression)
void highlightColorChanged(double r, double g, double b, int mode)
void highlightOpacityChanged(double opacity, int mode)
void selectionRemoved(int index)
void annotationRequested(const QString &text)
Formatter class for generating tooltip text from VTK data.
Central manager for all selection operations in the view.
constexpr bool operator==(const optional< T > &x, const optional< T > &y)
Definition: Optional.h:615
#define QPCL_ENGINE_LIB_API
Definition: qPCL.h:15
Saved selection entry for Selection Editor.