Engauge Digitizer  2
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 
64 void GeometryWindow::closeEvent(QCloseEvent * /* event */)
65 {
66  LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::closeEvent";
67 
69 }
70 
72 {
73  return COLUMN_BODY_POINT_IDENTIFIERS;
74 }
75 
76 void 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 
101 void 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 
119 void GeometryWindow::loadStrategies ()
120 {
121  LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::loadStrategies";
122 }
123 
124 void 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 
135 void GeometryWindow::slotPointHoverEnter (QString pointIdentifier)
136 {
137  m_model->setCurrentPointIdentifier (pointIdentifier);
138 }
139 
140 void GeometryWindow::slotPointHoverLeave (QString /* pointIdentifier */)
141 {
142  m_model->setCurrentPointIdentifier ("");
143 }
144 
145 QString GeometryWindow::tokenCurveName () const
146 {
147  return QString ("%1:").arg (QObject::tr ("CurveName"));
148 }
149 
150 QString GeometryWindow::tokenDistanceGraph () const
151 {
152  return QObject::tr ("Distance");
153 }
154 
155 QString GeometryWindow::tokenDistancePercent () const
156 {
157  return QObject::tr ("Percent");
158 }
159 
160 QString GeometryWindow::tokenFunctionArea () const
161 {
162  return QString ("%1:").arg (QObject::tr ("FunctionArea"));
163 }
164 
165 QString GeometryWindow::tokenIndex () const
166 {
167  return QObject::tr ("Index");
168 }
169 
170 QString GeometryWindow::tokenPolygonArea () const
171 {
172  return QString ("%1:").arg (QObject::tr ("PolygonArea"));
173 }
174 
175 QString GeometryWindow::tokenX () const
176 {
177  return QObject::tr ("X");
178 }
179 
180 QString GeometryWindow::tokenY () const
181 {
182  return QObject::tr ("Y");
183 }
184 
185 void GeometryWindow::unselectAll ()
186 {
187  QItemSelectionModel *selectionModel = m_view->selectionModel ();
188 
189  selectionModel->clearSelection ();
190 }
191 
192 void 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 
209  ENGAUGE_CHECK_PTR (curve);
210 
211  const Points points = curve->points();
212 
213  QString funcArea, polyArea;
214  QVector<QString> x, y, distanceGraphForward, distancePercentForward, distanceGraphBackward, distancePercentBackward;
215  QVector<bool> isPotentialExportAmbiguity;
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,
228  isPotentialExportAmbiguity,
229  distanceGraphForward,
230  distancePercentForward,
231  distanceGraphBackward,
232  distancePercentBackward);
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 
249  m_model->setPotentialExportAmbiguity (isPotentialExportAmbiguity);
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 
287 QTableView *GeometryWindow::view () const
288 {
289  return dynamic_cast<QTableView*> (m_view);
290 }
WindowTable.h
CurveStyles::curveStyle
CurveStyle curveStyle(const QString &curveName) const
CurveStyle in specified curve.
Definition: CurveStyles.cpp:78
Document::modelGeneral
DocumentModelGeneral modelGeneral() const
Get method for DocumentModelGeneral.
Definition: Document.cpp:723
GeometryWindow::view
virtual QTableView * view() const
QTableView-based class used by child class.
Definition: GeometryWindow.cpp:286
Points
QList< Point > Points
Definition: Points.h:12
CurveStyle::lineStyle
LineStyle lineStyle() const
Get method for LineStyle.
Definition: CurveStyle.cpp:25
Document::curveForCurveName
const Curve * curveForCurveName(const QString &curveName) const
See CurvesGraphs::curveForCurveNames, although this also works for AXIS_CURVE_NAME.
Definition: Document.cpp:335
CmdMediator.h
GeometryWindow::slotPointHoverLeave
void slotPointHoverLeave(QString)
Unhighlight the row for the specified point.
Definition: GeometryWindow.cpp:139
GeometryWindow.h
Transformation
Affine transformation between screen and graph coordinates, based on digitized axis points.
Definition: Transformation.h:30
GeometryWindow::doCopy
virtual void doCopy()
Copy the current selection to the clipboard.
Definition: GeometryWindow.cpp:86
EngaugeAssert.h
Curve::points
const Points points() const
Return a shallow copy of the Points.
Definition: Curve.cpp:451
CurveStyle.h
GeometryWindow::~GeometryWindow
virtual ~GeometryWindow()
Definition: GeometryWindow.cpp:47
Curve
Container for one set of digitized Points.
Definition: Curve.h:32
WindowTable
Table view class with support for both drag-and-drop and copy-and-paste.
Definition: WindowTable.h:16
MainWindowModel
Model for DlgSettingsMainWindow.
Definition: MainWindowModel.h:29
CurveStyle
Container for LineStyle and PointStyle for one Curve.
Definition: CurveStyle.h:17
GeometryWindow::slotPointHoverEnter
void slotPointHoverEnter(QString)
Highlight the row for the specified point.
Definition: GeometryWindow.cpp:134
ENGAUGE_CHECK_PTR
#define ENGAUGE_CHECK_PTR(ptr)
#endif
Definition: EngaugeAssert.h:26
MainWindow
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition: MainWindow.h:90
Point::posScreen
QPointF posScreen() const
Accessor for screen position.
Definition: Point.cpp:404
Logger.h
GeometryModel::setPotentialExportAmbiguity
void setPotentialExportAmbiguity(const QVector< bool > &isPotentialExportAmbiguity)
Remember which rows could have ambiguities during export - these will be highlighted.
Definition: GeometryModel.cpp:118
CmdMediator::document
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Definition: CmdMediator.cpp:72
WindowModelBase::selectionAsText
QString selectionAsText(ExportDelimiter delimiter) const
Convert the selection into exportable text which is good for text editors.
Definition: WindowModelBase.cpp:132
LOG4CPP_INFO_S
#define LOG4CPP_INFO_S(logger)
Definition: convenience.h:18
GeometryModel.h
GeometryWindow::update
virtual void update(const CmdMediator &cmdMediator, const MainWindowModel &modelMainWindow, const QString &curveSelected, const Transformation &transformation)
Populate the table with the specified Curve.
Definition: GeometryWindow.cpp:191
GeometryWindow::GeometryWindow
GeometryWindow(MainWindow *mainWindow)
Single constructor. Parent is needed or else this widget cannot be redocked after being undocked.
Definition: GeometryWindow.cpp:21
GeometryWindow::signalGeometryWindowClosed
void signalGeometryWindowClosed()
Signal that this QDockWidget was just closed.
Point::identifier
QString identifier() const
Unique identifier for a specific Point.
Definition: Point.cpp:268
GeometryStrategyContext::calculateGeometry
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.
Definition: GeometryStrategyContext.cpp:30
mainCat
log4cpp::Category * mainCat
Definition: Logger.cpp:14
MainWindow.h
GeometryWindow::columnBodyPointIdentifiers
static int columnBodyPointIdentifiers()
Hidden column that has the point identifiers.
Definition: GeometryWindow.cpp:70
MainWindowModel::dragDropExport
bool dragDropExport() const
Get method for drag and drop export.
Definition: MainWindowModel.cpp:80
DocumentModelExportFormat::delimiter
ExportDelimiter delimiter() const
Get method for delimiter.
Definition: DocumentModelExportFormat.cpp:119
CmdMediator
Command queue stack.
Definition: CmdMediator.h:22
CurveConnectAs.h
Document::modelCoords
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
Definition: Document.cpp:695
Curve.h
Point
Class that represents one digitized point. The screen-to-graph coordinate transformation is always ex...
Definition: Point.h:24
GeometryModel::setCurrentPointIdentifier
void setCurrentPointIdentifier(const QString &pointIdentifier)
Set the point identifier to be highlighted. Value is empty for no highlighting.
Definition: GeometryModel.cpp:83
WindowModelBase::setDelimiter
void setDelimiter(ExportDelimiter delimiter)
Save output delimiter.
Definition: WindowModelBase.cpp:164
Document::modelExport
DocumentModelExportFormat modelExport() const
Get method for DocumentModelExportFormat.
Definition: Document.cpp:716
LineStyle::curveConnectAs
CurveConnectAs curveConnectAs() const
Get method for connect type.
Definition: LineStyle.cpp:63
Document::modelCurveStyles
CurveStyles modelCurveStyles() const
Get method for CurveStyles.
Definition: Document.cpp:702
GeometryWindow::clear
virtual void clear()
Clear stale information.
Definition: GeometryWindow.cpp:52
GeometryModel
Model that adds row highlighting according to the currently select point identifier.
Definition: GeometryModel.h:15
WindowAbstractBase
Dockable widget abstract base class.
Definition: WindowAbstractBase.h:19
GeometryWindow::closeEvent
virtual void closeEvent(QCloseEvent *event)
Catch close event so corresponding menu item in MainWindow can be updated accordingly.
Definition: GeometryWindow.cpp:63