Engauge Digitizer 2
Loading...
Searching...
No Matches
GeometryWindow.cpp
Go to the documentation of this file.
1/******************************************************************************************************
2 * (C) 2016 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3 * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4 * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5 ******************************************************************************************************/
6
7#include "CmdMediator.h"
8#include "Curve.h"
9#include "CurveConnectAs.h"
10#include "CurveStyle.h"
11#include "EngaugeAssert.h"
12#include "GeometryModel.h"
13#include "GeometryWindow.h"
14#include "Logger.h"
15#include "MainWindow.h"
16#include <QApplication>
17#include <QClipboard>
18#include <QItemSelectionModel>
19#include <QTextStream>
20#include "WindowTable.h"
21
23 WindowAbstractBase (mainWindow)
24{
25 setVisible (false);
26 setAllowedAreas (Qt::AllDockWidgetAreas);
27 setWindowTitle (tr ("Geometry Window")); // Appears in title bar when undocked
28 setStatusTip (tr ("Geometry Window"));
29 setWhatsThis (tr ("Geometry Window\n\n"
30 "This table displays the following geometry data for the currently selected curve:\n\n"
31 "Function area = Area under the curve if it is a function\n\n"
32 "Polygon area = Area inside the curve if it is a relation. This value is only correct "
33 "if none of the curve lines intersect each other\n\n"
34 "X = X coordinate of each point\n\n"
35 "Y = Y coordinate of each point\n\n"
36 "Index = Point number\n\n"
37 "Distance = Distance along the curve in forward or backward direction, in either graph units "
38 "or as a percentage\n\n"
39 "If drag-and-drop is disabled, a rectangular set of cells may be selected by clicking and dragging. Otherwise, if "
40 "drag-and-drop is enabled, a rectangular set of cells may be selected using Click then Shift+Click, since click and drag "
41 "starts the dragging operation. Drag-and-drop mode is set in the Main Window settings"));
42
43 createWidgets (mainWindow);
44 loadStrategies();
45 initializeHeader ();
46}
47
49{
50 delete m_model;
51}
52
54{
55 // Resize table to remove stale body data
56 resizeTable (NUM_HEADER_ROWS);
57
58 // Clear stale header data values
59 for (int row = 0; row < NUM_HEADER_ROWS - 1; row++) {
60 m_model->setItem (row, COLUMN_HEADER_VALUE, new QStandardItem (""));
61 }
62}
63
65{
66 LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::closeEvent";
67
69}
70
72{
73 return COLUMN_BODY_POINT_IDENTIFIERS;
74}
75
76void GeometryWindow::createWidgets (MainWindow *mainWindow)
77{
78 m_model = new GeometryModel;
79
80 m_view = new WindowTable (*m_model);
81 connect (m_view, SIGNAL (signalTableStatusChange ()),
82 mainWindow, SLOT (slotTableStatusChange ()));
83
84 setWidget (m_view);
85}
86
88{
89 LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::doCopy";
90
91 QString text = m_model->selectionAsText (m_modelExport.delimiter());
92
93 if (!text.isEmpty ()) {
94
95 // Save to clipboard
96 QApplication::clipboard ()->setText (text);
97
98 }
99}
100
101void GeometryWindow::initializeHeader ()
102{
103 LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::initializeHeader";
104
105 resizeTable (NUM_HEADER_ROWS);
106
107 m_model->setItem (HEADER_ROW_NAME, COLUMN_HEADER_LABEL, new QStandardItem (tokenCurveName ()));
108 m_model->setItem (HEADER_ROW_FUNC_AREA, COLUMN_HEADER_LABEL, new QStandardItem (tokenFunctionArea ()));
109 m_model->setItem (HEADER_ROW_POLY_AREA, COLUMN_HEADER_LABEL, new QStandardItem (tokenPolygonArea ()));
110 m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_X, new QStandardItem (tokenX ()));
111 m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_Y, new QStandardItem (tokenY ()));
112 m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_INDEX, new QStandardItem (tokenIndex ()));
113 m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_DISTANCE_GRAPH_FORWARD, new QStandardItem (tokenDistanceGraph ()));
114 m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_DISTANCE_PERCENT_FORWARD, new QStandardItem (tokenDistancePercent ()));
115 m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_DISTANCE_GRAPH_BACKWARD, new QStandardItem (tokenDistanceGraph ()));
116 m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_DISTANCE_PERCENT_BACKWARD, new QStandardItem (tokenDistancePercent ()));
117}
118
119void GeometryWindow::loadStrategies ()
120{
121 LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::loadStrategies";
122}
123
124void GeometryWindow::resizeTable (int rowCount)
125{
126 LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::resizeTable";
127
128 unselectAll();
129
130 m_model->setRowCount (rowCount);
131 m_model->setColumnCount (NUM_BODY_COLUMNS);
132
133}
134
139
141{
142 m_model->setCurrentPointIdentifier ("");
143}
144
145QString GeometryWindow::tokenCurveName () const
146{
147 return QString ("%1:").arg (QObject::tr ("CurveName"));
148}
149
150QString GeometryWindow::tokenDistanceGraph () const
151{
152 return QObject::tr ("Distance");
153}
154
155QString GeometryWindow::tokenDistancePercent () const
156{
157 return QObject::tr ("Percent");
158}
159
160QString GeometryWindow::tokenFunctionArea () const
161{
162 return QString ("%1:").arg (QObject::tr ("FunctionArea"));
163}
164
165QString GeometryWindow::tokenIndex () const
166{
167 return QObject::tr ("Index");
168}
169
170QString GeometryWindow::tokenPolygonArea () const
171{
172 return QString ("%1:").arg (QObject::tr ("PolygonArea"));
173}
174
175QString GeometryWindow::tokenX () const
176{
177 return QObject::tr ("X");
178}
179
180QString GeometryWindow::tokenY () const
181{
182 return QObject::tr ("Y");
183}
184
185void GeometryWindow::unselectAll ()
186{
187 QItemSelectionModel *selectionModel = m_view->selectionModel ();
188
189 selectionModel->clearSelection ();
190}
191
192void GeometryWindow::update (const CmdMediator &cmdMediator,
193 const MainWindowModel &modelMainWindow,
194 const QString &curveSelected,
195 const Transformation &transformation)
196{
197 LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::update";
198
199 const int NUM_LEGEND_ROWS_UNSPANNED = 2; // Match with GeometryModel::NUM_LEGEND_ROWS_UNSPANNED
200
201 // Save inputs
202 m_modelExport = cmdMediator.document().modelExport();
203 m_model->setDelimiter (m_modelExport.delimiter());
204 m_view->setDragEnabled (modelMainWindow.dragDropExport());
205
206 // Gather and calculate geometry data
207 const Curve *curve = cmdMediator.document().curveForCurveName (curveSelected);
208
210
211 const Points points = curve->points();
212
216
217 CurveStyle curveStyle = cmdMediator.document().modelCurveStyles().curveStyle (curveSelected);
218 m_geometryStrategyContext.calculateGeometry (points,
219 cmdMediator.document().modelCoords(),
220 cmdMediator.document().modelGeneral(),
221 modelMainWindow,
222 transformation,
223 curveStyle.lineStyle().curveConnectAs(),
224 funcArea,
225 polyArea,
226 x,
227 y,
233
234 // Was there a potential export ambiguity
235 bool wasAmbiguity = isPotentialExportAmbiguity.contains (true);
236
237 // Unmerge any merged cells from the previous update
238 m_view->clearSpans();
239
240 // Output to table
241 resizeTable (NUM_HEADER_ROWS + points.count() + (wasAmbiguity ? NUM_LEGEND_ROWS_UNSPANNED : 0));
242
243 m_model->setItem (HEADER_ROW_NAME, COLUMN_HEADER_VALUE, new QStandardItem (curveSelected));
244 m_model->setItem (HEADER_ROW_FUNC_AREA, COLUMN_HEADER_VALUE, new QStandardItem (funcArea));
245 m_model->setItem (HEADER_ROW_POLY_AREA, COLUMN_HEADER_VALUE, new QStandardItem (polyArea));
246
247 if (transformation.transformIsDefined()) {
248
250
251 int row = NUM_HEADER_ROWS;
252 for (int index = 0; index < points.count(); row++, index++) {
253
254 const Point &point = points.at (index);
255
256 QPointF posGraph;
257 transformation.transformScreenToRawGraph (point.posScreen (),
258 posGraph);
259
260 m_model->setItem (row, COLUMN_BODY_X, new QStandardItem (x [index]));
261 m_model->setItem (row, COLUMN_BODY_Y, new QStandardItem (y [index]));
262 m_model->setItem (row, COLUMN_BODY_INDEX, new QStandardItem (QString::number (index + 1)));
263 m_model->setItem (row, COLUMN_BODY_DISTANCE_GRAPH_FORWARD, new QStandardItem (distanceGraphForward [index]));
264 m_model->setItem (row, COLUMN_BODY_DISTANCE_PERCENT_FORWARD, new QStandardItem (distancePercentForward [index]));
265 m_model->setItem (row, COLUMN_BODY_DISTANCE_GRAPH_BACKWARD, new QStandardItem (distanceGraphBackward [index]));
266 m_model->setItem (row, COLUMN_BODY_DISTANCE_PERCENT_BACKWARD, new QStandardItem (distancePercentBackward [index]));
267 m_model->setItem (row, COLUMN_BODY_POINT_IDENTIFIERS, new QStandardItem (point.identifier()));
268 }
269
270 if (wasAmbiguity) {
271 // Merge row into one big cell so text fits. Requires unmerge at start of next update
272 m_view->setSpan (row, 0, NUM_LEGEND_ROWS_UNSPANNED, NUM_BODY_COLUMNS);
273 m_model->setItem (row, COLUMN_BODY_X,
274 new QStandardItem (tr ("Highlighted segments may have unexpected values when exported due to overlaps. "
275 "Adjust points or change Settings / Curve Properties / Connect As.")));
276 row++;
277 }
278 }
279
280 // Unselect everything
281 unselectAll ();
282
283 // Make sure the hidden column stays hidden
284 m_view->setColumnHidden (COLUMN_BODY_POINT_IDENTIFIERS, true);
285}
286
287QTableView *GeometryWindow::view () const
288{
289 return dynamic_cast<QTableView*> (m_view);
290}
const int INNER_RADIUS_MIN
#define ENGAUGE_CHECK_PTR(ptr)
#endif
log4cpp::Category * mainCat
Definition Logger.cpp:14
QList< Point > Points
Definition Points.h:13
Command queue stack.
Definition CmdMediator.h:24
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Container for LineStyle and PointStyle for one Curve.
Definition CurveStyle.h:19
LineStyle lineStyle() const
Get method for LineStyle.
CurveStyle curveStyle(const QString &curveName) const
CurveStyle in specified curve.
Container for one set of digitized Points.
Definition Curve.h:34
ExportDelimiter delimiter() const
Get method for delimiter.
DocumentModelGeneral modelGeneral() const
Get method for DocumentModelGeneral.
Definition Document.cpp:723
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
Definition Document.cpp:695
CurveStyles modelCurveStyles() const
Get method for CurveStyles.
Definition Document.cpp:702
DocumentModelExportFormat modelExport() const
Get method for DocumentModelExportFormat.
Definition Document.cpp:716
const Curve * curveForCurveName(const QString &curveName) const
See CurvesGraphs::curveForCurveNames, although this also works for AXIS_CURVE_NAME.
Definition Document.cpp:335
Model that adds row highlighting according to the currently select point identifier.
void setCurrentPointIdentifier(const QString &pointIdentifier)
Set the point identifier to be highlighted. Value is empty for no highlighting.
void setPotentialExportAmbiguity(const QVector< bool > &isPotentialExportAmbiguity)
Remember which rows could have ambiguities during export - these will be highlighted.
void calculateGeometry(const Points &points, const DocumentModelCoords &modelCoords, const DocumentModelGeneral &modelGeneral, const MainWindowModel &modelMainWindow, const Transformation &transformation, CurveConnectAs connectAs, QString &funcArea, QString &polyArea, QVector< QString > &x, QVector< QString > &y, QVector< bool > &isPotentialExportAmbiguity, QVector< QString > &distanceGraphForward, QVector< QString > &distancePercentForward, QVector< QString > &distanceGraphBackward, QVector< QString > &distancePercentBackward) const
Calculate geometry parameters.
static int columnBodyPointIdentifiers()
Hidden column that has the point identifiers.
GeometryWindow(MainWindow *mainWindow)
Single constructor. Parent is needed or else this widget cannot be redocked after being undocked.
virtual void update(const CmdMediator &cmdMediator, const MainWindowModel &modelMainWindow, const QString &curveSelected, const Transformation &transformation)
Populate the table with the specified Curve.
virtual void closeEvent(QCloseEvent *event)
Catch close event so corresponding menu item in MainWindow can be updated accordingly.
void slotPointHoverEnter(QString)
Highlight the row for the specified point.
virtual QTableView * view() const
QTableView-based class used by child class.
void slotPointHoverLeave(QString)
Unhighlight the row for the specified point.
virtual void clear()
Clear stale information.
virtual void doCopy()
Copy the current selection to the clipboard.
virtual ~GeometryWindow()
void signalGeometryWindowClosed()
Signal that this QDockWidget was just closed.
CurveConnectAs curveConnectAs() const
Get method for connect type.
Definition LineStyle.cpp:63
Model for DlgSettingsMainWindow.
bool dragDropExport() const
Get method for drag and drop export.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition MainWindow.h:92
Class that represents one digitized point. The screen-to-graph coordinate transformation is always ex...
Definition Point.h:26
QPointF posScreen() const
Accessor for screen position.
Definition Point.cpp:404
QString identifier() const
Unique identifier for a specific Point.
Definition Point.cpp:268
Affine transformation between screen and graph coordinates, based on digitized axis points.
void transformScreenToRawGraph(const QPointF &coordScreen, QPointF &coordGraph) const
Transform from cartesian pixel screen coordinates to cartesian/polar graph coordinates.
bool transformIsDefined() const
Transform is defined when at least three axis points have been digitized.
Dockable widget abstract base class.
QString selectionAsText(ExportDelimiter delimiter) const
Convert the selection into exportable text which is good for text editors.
void setDelimiter(ExportDelimiter delimiter)
Save output delimiter.
Table view class with support for both drag-and-drop and copy-and-paste.
Definition WindowTable.h:18
#define LOG4CPP_INFO_S(logger)
Definition convenience.h:18