ACF $AcfVersion:0$
TPolygonBasedParamsGuiComp.h
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-2.1-or-later OR GPL-2.0-or-later OR GPL-3.0-or-later OR LicenseRef-ACF-Commercial
2#pragma once
3
4
5// Qt includes
6#include <QtCore/QMimeData>
7#include <QtCore/QByteArray>
8#include <QtCore/QAbstractTableModel>
9#include <QtGui/QDoubleValidator>
10#include <QtGui/QClipboard>
11#if QT_VERSION >= 0x050000
12#include <QtWidgets/QLineEdit>
13#else
14#include <QtGui/QLineEdit>
15#endif
16
17// ACF includes
21#include <i2d/CPolygon.h>
22#include <i2d/CPolyline.h>
23#include <iqt/CSignalBlocker.h>
25
26#include <GeneratedFiles/iqt2d/ui_CPolygonParamsGuiComp.h>
27
28
29namespace iqt2d
30{
31
32
33template <class PolygonBasedShape, class PolygonBasedModel>
36 Ui::CPolygonParamsGuiComp,
37 PolygonBasedShape,
38 PolygonBasedModel>
39{
40public:
45 {
50
55
60 };
61
63 Ui::CPolygonParamsGuiComp,
64 PolygonBasedShape,
65 PolygonBasedModel> BaseClass;
66
67 I_BEGIN_COMPONENT(TPolygonBasedParamsGuiComp);
68 I_ASSIGN(m_nodeListSizeAttrPtr, "NodeListSize", "Fixed height of the node list if set (0 - hide)", false, 0);
69 I_ASSIGN(m_hideCopyPasteAttrPtr, "HideCopyPaste", "Hide Copy & Paste buttons", true, true);
70 I_END_COMPONENT;
71
73
74protected:
75 class TableModel: public QAbstractTableModel
76 {
77 public:
78 typedef QAbstractTableModel BaseClass;
79
81
82 // reimplemented (QAbstractTableModel)
83 virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
84 virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override;
85 virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
86 virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
87 virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
88 virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
89 virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
90
91 using QAbstractTableModel::dataChanged;
92 using QAbstractTableModel::layoutChanged;
93
94 private:
96 };
97
101 QTableView* GetNodeTable();
102
103 virtual void OnInsertNode();
104 virtual void OnRemoveNode();
105 virtual void OnCopyData();
106 virtual void OnPasteData();
107
108 // delegated from QAbstractTableModel
109 virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
110 virtual int columnCount(const QModelIndex& parent = QModelIndex()) const;
111 virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
112 virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
113 virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
114 virtual Qt::ItemFlags flags(const QModelIndex &index) const;
115
116 // reimplemented (iqtgui::CGuiComponentBase)
117 virtual void OnGuiCreated() override;
118 virtual void OnGuiRetranslate() override;
119 virtual void OnGuiDesignChanged() override;
120
121 // reimplemented (iqt2d::TShapeParamsGuiCompBase)
122 virtual bool PopulateActions(QWidget& host, imod::IModel* modelPtr) override;
123 virtual void OnActionTriggered(QAction* actionPtr) override;
124
125 // reimplemented (iqtgui::TGuiObserverWrap)
126 virtual void UpdateGui(const istd::IChangeable::ChangeSet& changeSet) override;
127
128 static bool SetValue(const QVariant& variant, double& result);
129 static QVariant GetValue(double value, int round = 2);
130
131protected:
132 using BaseClass::GetObservedObject;
133 using BaseClass::GetObservedModel;
134 using BaseClass::DoUpdateModel;
136 using BaseClass::NodeParamsTable;
137 using BaseClass::tr;
138 using BaseClass::GetQtWidget;
139 using BaseClass::RemoveButton;
140 using BaseClass::InsertButton;
141 using BaseClass::ToolsButton;
142 using BaseClass::CopyButton;
143 using BaseClass::PasteButton;
144
145protected:
146 I_ATTR(int, m_nodeListSizeAttrPtr);
147 I_ATTR(bool, m_hideCopyPasteAttrPtr);
148
154
155private:
156 TableModel m_tableModel;
157};
158
159
160// public methods
161
162template <class PolygonBasedShape, class PolygonBasedModel>
164: m_flipHorizontalAction(QIcon(":/Icons/FlipHorizontal"), "", this),
165 m_flipVerticalAction(QIcon(":/Icons/FlipVertical"), "", this),
166 m_rotateCwAction(QIcon(":/Icons/RotateRight"), "", this),
167 m_rotateCcwAction(QIcon(":/Icons/RotateLeft"), "", this),
168 m_reversePolarityAction(QIcon(":/Icons/Reverse"), "", this),
169 m_tableModel(this)
170{
171}
172
173
174// protected methods
175
176template <class PolygonBasedShape, class PolygonBasedModel>
181
182
183template <class PolygonBasedShape, class PolygonBasedModel>
185{
186 i2d::CPolygon* objectPtr = GetObservedObject();
187 if (objectPtr != NULL){
188 QItemSelectionModel *select = NodeParamsTable->selectionModel();
189 QModelIndexList selected = select->selectedRows();
190
191 int row = selected.isEmpty()? -1: selected.front().row();
192 if (row >= 0){
193 objectPtr->InsertNode(row, i2d::CVector2d::GetZero());
194 }
195 else{
197 }
198 }
199}
200
201
202template <class PolygonBasedShape, class PolygonBasedModel>
204{
205 PolygonBasedModel* objectPtr = GetObservedObject();
206 if (objectPtr == NULL){
207 return;
208 }
209
211
212 if (objectPtr->Serialize(archive)){
213 QByteArray data((const char*)archive.GetBuffer(), archive.GetBufferSize());
214
215 QMimeData* dataPtr = new QMimeData();
216 dataPtr->setData(typeid (PolygonBasedModel).name(), data);
217
218 QApplication::clipboard()->setMimeData(dataPtr);
219 }
220}
221
222
223template <class PolygonBasedShape, class PolygonBasedModel>
225{
226 PolygonBasedModel* objectPtr = GetObservedObject();
227 if (objectPtr == NULL){
228 return;
229 }
230
231 const QMimeData* dataPtr = QApplication::clipboard()->mimeData();
232 if (dataPtr != NULL){
233 if (dataPtr->hasFormat(typeid (PolygonBasedModel).name())){
234 QByteArray data(dataPtr->data(typeid (PolygonBasedModel).name()));
235
236 iser::CMemoryReadArchive archive(data.data(), data.size());
237
238 objectPtr->Serialize(archive);
239 }
240 }
241}
242
243
244template <class PolygonBasedShape, class PolygonBasedModel>
246{
247 i2d::CPolygon* objectPtr = GetObservedObject();
248 if (objectPtr != NULL){
249 QItemSelectionModel *select = NodeParamsTable->selectionModel();
250 QModelIndexList selected = select->selectedRows();
251
252 int row = selected.isEmpty()? -1: selected.front().row();
253 if (row >= 0){
254 m_tableModel.removeRows(row, 1);
255 }
256 }
257}
258
259
260// delegated from QAbstractTableModel
261
262template <class PolygonBasedShape, class PolygonBasedModel>
264{
265 int retVal = 0;
266
267 i2d::CPolygon* objectPtr = GetObservedObject();
268 if (objectPtr != NULL){
269 retVal = objectPtr->GetNodesCount();
270 }
271
272 return retVal;
273}
274
275
276template <class PolygonBasedShape, class PolygonBasedModel>
278{
279 return 2;
280}
281
282
283template <class PolygonBasedShape, class PolygonBasedModel>
284QVariant TPolygonBasedParamsGuiComp<PolygonBasedShape, PolygonBasedModel>::data(const QModelIndex& index, int role) const
285{
286 if ((role == Qt::DisplayRole) || (role == Qt::EditRole)){
287 i2d::CVector2d retVal(0, 0);
288 i2d::CPolygon* objectPtr = GetObservedObject();
289 if ((objectPtr != NULL) && (index.column() <= 1) && (index.column() >= 0)){
290 retVal = objectPtr->GetNodePos(index.row());
291
292 return GetValue(retVal[index.column()]);
293 }
294 }
295
296 return QVariant();
297}
298
299
300template <class PolygonBasedShape, class PolygonBasedModel>
301bool TPolygonBasedParamsGuiComp<PolygonBasedShape, PolygonBasedModel>::setData(const QModelIndex& index, const QVariant& value, int role)
302{
303 if (role != Qt::EditRole || index.column() < 0 || index.column() > 1 || index.row() < 0)
304 return false;
305
306 i2d::CPolygon* objectPtr = GetObservedObject();
307 if (!objectPtr || index.row() >= objectPtr->GetNodesCount())
308 return false;
309
310 i2d::CVector2d pos = objectPtr->GetNodePos(index.row());
311 if (SetValue(value, pos[index.column()])) {
312 objectPtr->SetNodePos(index.row(), pos); // explicitly set node position to call all the necessary callbacks
313 return true;
314 }
315
316 return false;
317}
318
319
320template <class PolygonBasedShape, class PolygonBasedModel>
321QVariant TPolygonBasedParamsGuiComp<PolygonBasedShape, PolygonBasedModel>::headerData(int section, Qt::Orientation orientation, int role) const
322{
323 if (orientation == Qt::Horizontal){
324 if (role == Qt::DisplayRole){
325 switch (section){
326 case 0:
327 return "X";
328
329 case 1:
330 return "Y";
331 }
332 }
333 }
334
335 return QVariant();
336}
337
338
339template <class PolygonBasedShape, class PolygonBasedModel>
340Qt::ItemFlags TPolygonBasedParamsGuiComp<PolygonBasedShape, PolygonBasedModel>::flags(const QModelIndex& /*index*/) const
341{
342 return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
343}
344
345
346// reimplemented (iqtgui::CGuiComponentBase)
347
348template <class PolygonBasedShape, class PolygonBasedModel>
350{
351 BaseClass::OnGuiCreated();
352
353 NodeParamsTable->setModel(&m_tableModel);
354
355 if (*m_hideCopyPasteAttrPtr){
356 CopyButton->hide();
357 PasteButton->hide();
358 }
359
360 bool isNodeTable = true;
361 if (m_nodeListSizeAttrPtr.IsValid()){
362 if (*m_nodeListSizeAttrPtr > 0){
363 NodeParamsTable->setFixedHeight(qMax(40, *m_nodeListSizeAttrPtr)); // 40 is minimum visible size for 1 row
364 }
365 else{
366 InsertButton->hide();
367 RemoveButton->hide();
368 NodeParamsTable->hide();
369 isNodeTable = false;
370 }
371
372 GetQtWidget()->adjustSize();
373 }
374
375 if (isNodeTable){
376#if QT_VERSION < 0x050000
377 NodeParamsTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
378#else
379 NodeParamsTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
380#endif
381 }
382
383 // tools actions
384 CreateToolsMenu(ToolsButton);
385}
386
387
388template <class PolygonBasedShape, class PolygonBasedModel>
390{
391 BaseClass::OnGuiRetranslate();
392
393 m_flipHorizontalAction.setText(QCoreApplication::translate("iqt2d", "Flip horizontally"));
394 m_flipVerticalAction.setText(QCoreApplication::translate("iqt2d", "Flip vertically"));
395 m_rotateCwAction.setText(QCoreApplication::translate("iqt2d", "Rotate clockwise"));
396 m_rotateCcwAction.setText(QCoreApplication::translate("iqt2d", "Rotate counterclockwise"));
397 m_reversePolarityAction.setText(QCoreApplication::translate("iqt2d", "Reverse line"));
398}
399
400
401template <class PolygonBasedShape, class PolygonBasedModel>
403{
404 BaseClass::OnGuiDesignChanged();
405
406 CopyButton->setIcon(this->GetIcon(":/Icons/Copy"));
407 PasteButton->setIcon(this->GetIcon(":/Icons/Paste"));
408 InsertButton->setIcon(this->GetIcon(":/Icons/Add"));
409 RemoveButton->setIcon(this->GetIcon(":/Icons/Delete"));
410 ToolsButton->setIcon(this->GetIcon(":/Icons/Tools"));
411}
412
413
414// reimplemented (iqt2d::TShapeParamsGuiCompBase)
415
416template <class PolygonBasedShape, class PolygonBasedModel>
418{
419 if (!BaseClass::PopulateActions(host, modelPtr)){
420 return false;
421 }
422
423 i2d::CPolygon* polygonPtr = dynamic_cast<i2d::CPolygon*>(modelPtr);
424 if (polygonPtr == nullptr){
425 return false;
426 }
427
428 host.addAction(&m_flipHorizontalAction);
429 host.addAction(&m_flipVerticalAction);
430 host.addAction(&m_rotateCwAction);
431 host.addAction(&m_rotateCcwAction);
432
433 if (i2d::CPolyline* polylinePtr = dynamic_cast<i2d::CPolyline*>(modelPtr)){
434 host.addAction(&m_reversePolarityAction);
435 }
436
437 return true;
438}
439
440
441template <class PolygonBasedShape, class PolygonBasedModel>
443{
444 Q_ASSERT(actionPtr);
445
446 PolygonBasedModel* modelPtr = dynamic_cast<PolygonBasedModel*>(BaseClass::GetObservedModel());
447 Q_ASSERT(modelPtr);
448
449 if (actionPtr == NULL || modelPtr == NULL){
450 return;
451 }
452
453 if (actionPtr == &m_flipHorizontalAction){
454 modelPtr->FlipByX();
455 }
456 else if (actionPtr == &m_flipVerticalAction){
457 modelPtr->FlipByY();
458 }
459 else if (actionPtr == &m_rotateCwAction){
460 modelPtr->Rotate(M_PI/2);
461 }
462 else if (actionPtr == &m_rotateCcwAction){
463 modelPtr->Rotate(-M_PI/2);
464 }
465 else if (actionPtr == &m_reversePolarityAction){
466 modelPtr->ReverseNodes();
467 }
468}
469
470
471// reimplemented (iqtgui::TGuiObserverWrap)
472
473template <class PolygonBasedShape, class PolygonBasedModel>
475{
476 QModelIndex leftTop = m_tableModel.index(0, 0);
477 QModelIndex rightBottom = m_tableModel.index(rowCount() - 1, columnCount() - 1);
478
479 Q_EMIT m_tableModel.dataChanged(leftTop, rightBottom);
480 Q_EMIT m_tableModel.layoutChanged();
481
482 BaseClass::UpdateGui(changeSet);
483}
484
485
486template <class PolygonBasedShape, class PolygonBasedModel>
488{
489 bool ok;
490 double res = variant.toDouble(&ok);
491
492 if (ok){
493 result = res;
494 }
495
496 return ok;
497}
498
499
500template <class PolygonBasedShape, class PolygonBasedModel>
502{
503 if (round < 0){
504 return value;
505 }
506
507 double p = pow(10.0, round);
508 return qRound(value * p)/p;
509}
510
511
512// public methods of embedded class TableModel
513
514template <class PolygonBasedShape, class PolygonBasedModel>
519
520
521// reimplemented (QAbstractTableModel)
522
523template <class PolygonBasedShape, class PolygonBasedModel>
525{
526 if (m_parentPtr != NULL){
527 return m_parentPtr->rowCount(parent);
528 }
529
530 return 0;
531}
532
533
534template <class PolygonBasedShape, class PolygonBasedModel>
536{
537 if (m_parentPtr != NULL){
538 return m_parentPtr->columnCount(parent);
539 }
540
541 return 0;
542}
543
544
545template <class PolygonBasedShape, class PolygonBasedModel>
547{
548 if (m_parentPtr != NULL){
549 return m_parentPtr->data(index, role);
550 }
551
552 return QVariant();
553}
554
555
556template <class PolygonBasedShape, class PolygonBasedModel>
557bool TPolygonBasedParamsGuiComp<PolygonBasedShape, PolygonBasedModel>::TableModel::setData(const QModelIndex& index, const QVariant& value, int role)
558{
559 if (m_parentPtr != NULL){
560 return m_parentPtr->setData(index, value, role);
561 }
562
563 return false;
564}
565
566
567template <class PolygonBasedShape, class PolygonBasedModel>
568QVariant TPolygonBasedParamsGuiComp<PolygonBasedShape, PolygonBasedModel>::TableModel::headerData(int section, Qt::Orientation orientation, int role) const
569{
570 if (m_parentPtr != NULL){
571 return m_parentPtr->headerData(section, orientation, role);
572 }
573
574 return QVariant();
575}
576
577
578template <class PolygonBasedShape, class PolygonBasedModel>
580{
581 if (m_parentPtr != NULL){
582 return m_parentPtr->flags(index);
583 }
584
585 return Qt::ItemIsSelectable;
586}
587
588template <class PolygonBasedShape, class PolygonBasedModel>
590{
591 Q_EMIT beginRemoveRows(parent, row, row + count - 1);
592
593 i2d::CPolygon* objectPtr = m_parentPtr->GetObservedObject();
594 if (objectPtr != NULL){
595 objectPtr->RemoveNode(row);
596 }
597
598 Q_EMIT endRemoveRows();
599
600 return true;
601}
602
603
604} // namespace iqt2d
605
606
Definition of the data model for a polygon.
Definition CPolygon.h:20
2D-object representing a polyline.
Definition CPolyline.h:19
virtual bool InsertNode(const i2d::CVector2d &position)
Insert a node at the end of node table.
virtual const i2d::CVector2d & GetNodePos(int index) const
Return position of node at specified index.
Definition CPolypoint.h:160
virtual void SetNodePos(int index, const i2d::CVector2d &position)
Set node at specified index.
Definition CPolypoint.h:176
virtual int GetNodesCount() const
Return size of node table.
Definition CPolypoint.h:148
virtual bool RemoveNode(int index)
Remove a node at specified index.
Definition of position or mathematical vector on 2D plane.
Definition CVector2d.h:29
static const CVector2d & GetZero()
Definition CVector2d.h:306
Common interface for model objects, that supports Model/Observer design pattern.
Definition IModel.h:25
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const override
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const override
virtual bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
virtual QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
TableModel(TPolygonBasedParamsGuiComp< PolygonBasedShape, PolygonBasedModel > *parentPtr)
virtual QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
virtual bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
virtual Qt::ItemFlags flags(const QModelIndex &index) const override
virtual bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
virtual void OnActionTriggered(QAction *actionPtr) override
@ CI_Y
Index of the table cell for the X coordinate of the polygon node.
@ CI_X
Index of the table cell for the X coordinate of the polygon node.
static QVariant GetValue(double value, int round=2)
iqt2d::TShapeParamsGuiCompBase< Ui::CPolygonParamsGuiComp, PolygonBasedShape, PolygonBasedModel > BaseClass
virtual bool PopulateActions(QWidget &host, imod::IModel *modelPtr) override
virtual void UpdateGui(const istd::IChangeable::ChangeSet &changeSet) override
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const
virtual QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
QTableView * GetNodeTable()
Get the table with the node data.
virtual Qt::ItemFlags flags(const QModelIndex &index) const
static bool SetValue(const QVariant &variant, double &result)
virtual QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
Implementation of archive using memory buffer to read the persistent objects.
Implementation of archive using memory buffer to store the persistent objects.
const void * GetBuffer() const
Set of change flags (its IDs).
Definition IChangeable.h:36
#define NULL
Definition istd.h:74
This package contains Qt based implementations for 2D graphic objects.