Engauge Digitizer  2
GeometryWindow.cpp
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 "CallbackGatherXThetaValuesFunctions.h"
8 #include "CmdMediator.h"
9 #include "Curve.h"
10 #include "CurveConnectAs.h"
11 #include "CurveStyle.h"
12 #include "EngaugeAssert.h"
13 #include "GeometryModel.h"
14 #include "GeometryWindow.h"
15 #include "Logger.h"
16 #include "MainWindow.h"
17 #include <QApplication>
18 #include <QClipboard>
19 #include <QItemSelectionModel>
20 #include <QTextStream>
21 #include "WindowTable.h"
22 
23 // Token constraints:
24 // (1) should fit nicely into narrow columns. This eliminates details like Forward and Backward in the distance parameter tokens
25 // (2) should not have any spaces. This simplifies copying and pasting into spreadsheet programs
26 const QString TokenName (QObject::tr ("CurveName:"));
27 const QString TokenFunctionArea (QObject::tr ("FunctionArea:"));
28 const QString TokenPolygonArea (QObject::tr ("PolygonArea:"));
29 const QString TokenX (QObject::tr ("X"));
30 const QString TokenY (QObject::tr ("Y"));
31 const QString TokenIndex (QObject::tr ("Index"));
32 const QString TokenDistanceGraph (QObject::tr ("Distance"));
33 const QString TokenDistancePercent (QObject::tr ("Percent"));
34 
36  WindowAbstractBase (mainWindow)
37 {
38  setVisible (false);
39  setAllowedAreas (Qt::AllDockWidgetAreas);
40  setWindowTitle (tr ("Geometry Window")); // Appears in title bar when undocked
41  setStatusTip (tr ("Geometry Window"));
42  setWhatsThis (tr ("Geometry Window\n\n"
43  "This table displays the following geometry data for the currently selected curve:\n\n"
44  "Function area = Area under the curve if it is a function\n\n"
45  "Polygon area = Area inside the curve if it is a relation. This value is only correct "
46  "if none of the curve lines intersect each other\n\n"
47  "X = X coordinate of each point\n\n"
48  "Y = Y coordinate of each point\n\n"
49  "Index = Point number\n\n"
50  "Distance = Distance along the curve in forward or backward direction, in either graph units "
51  "or as a percentage\n\n"
52  "If drag-and-drop is disabled, a rectangular set of cells may be selected by clicking and dragging. Otherwise, if "
53  "drag-and-drop is enabled, a rectangular set of cells may be selected using Click then Shift+Click, since click and drag "
54  "starts the dragging operation. Drag-and-drop mode is set in the Main Window settings"));
55 
56  createWidgets (mainWindow);
57  loadStrategies();
58  initializeHeader ();
59 }
60 
61 GeometryWindow::~GeometryWindow()
62 {
63 }
64 
66 {
67  // Resize table to remove stale body data
68  resizeTable (NUM_HEADER_ROWS);
69 
70  // Clear stale header data values
71  for (int row = 0; row < NUM_HEADER_ROWS - 1; row++) {
72  m_model->setItem (row, COLUMN_HEADER_VALUE, new QStandardItem (""));
73  }
74 }
75 
76 void GeometryWindow::closeEvent(QCloseEvent * /* event */)
77 {
78  LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::closeEvent";
79 
81 }
82 
84 {
85  return COLUMN_BODY_POINT_IDENTIFIERS;
86 }
87 
88 void GeometryWindow::createWidgets (MainWindow *mainWindow)
89 {
90  m_model = new GeometryModel;
91 
92  m_view = new WindowTable (*m_model);
93  connect (m_view, SIGNAL (signalTableStatusChange ()),
94  mainWindow, SLOT (slotTableStatusChange ()));
95 
96  setWidget (m_view);
97 }
98 
100 {
101  LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::doCopy";
102 
103  QString text = m_model->selectionAsText (m_modelExport.delimiter());
104 
105  if (!text.isEmpty ()) {
106 
107  // Save to clipboard
108  QApplication::clipboard ()->setText (text);
109 
110  }
111 }
112 
113 void GeometryWindow::initializeHeader ()
114 {
115  LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::initializeHeader";
116 
117  resizeTable (NUM_HEADER_ROWS);
118 
119  m_model->setItem (HEADER_ROW_NAME, COLUMN_HEADER_LABEL, new QStandardItem (TokenName));
120  m_model->setItem (HEADER_ROW_FUNC_AREA, COLUMN_HEADER_LABEL, new QStandardItem (TokenFunctionArea));
121  m_model->setItem (HEADER_ROW_POLY_AREA, COLUMN_HEADER_LABEL, new QStandardItem (TokenPolygonArea));
122  m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_X, new QStandardItem (TokenX));
123  m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_Y, new QStandardItem (TokenY));
124  m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_INDEX, new QStandardItem (TokenIndex));
125  m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_DISTANCE_GRAPH_FORWARD, new QStandardItem (TokenDistanceGraph));
126  m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_DISTANCE_PERCENT_FORWARD, new QStandardItem (TokenDistancePercent));
127  m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_DISTANCE_GRAPH_BACKWARD, new QStandardItem (TokenDistanceGraph));
128  m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_DISTANCE_PERCENT_BACKWARD, new QStandardItem (TokenDistancePercent));
129 }
130 
131 void GeometryWindow::loadStrategies ()
132 {
133  LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::loadStrategies";
134 }
135 
136 void GeometryWindow::resizeTable (int rowCount)
137 {
138  LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::resizeTable";
139 
140  unselectAll();
141 
142  m_model->setRowCount (rowCount);
143  m_model->setColumnCount (NUM_BODY_COLUMNS);
144 
145 }
146 
147 void GeometryWindow::slotPointHoverEnter (QString pointIdentifier)
148 {
149  m_model->setCurrentPointIdentifier (pointIdentifier);
150 }
151 
152 void GeometryWindow::slotPointHoverLeave (QString /* pointIdentifier */)
153 {
154  m_model->setCurrentPointIdentifier ("");
155 }
156 
157 void GeometryWindow::unselectAll ()
158 {
159  QItemSelectionModel *selectionModel = m_view->selectionModel ();
160 
161  selectionModel->clearSelection ();
162 }
163 
164 void GeometryWindow::update (const CmdMediator &cmdMediator,
165  const MainWindowModel &modelMainWindow,
166  const QString &curveSelected,
167  const Transformation &transformation)
168 {
169  LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::update";
170 
171  // Save inputs
172  m_modelExport = cmdMediator.document().modelExport();
173  m_model->setDelimiter (m_modelExport.delimiter());
174  m_view->setDragEnabled (modelMainWindow.dragDropExport());
175 
176  // Gather and calculate geometry data
177  const Curve *curve = cmdMediator.document().curveForCurveName (curveSelected);
178 
179  ENGAUGE_CHECK_PTR (curve);
180 
181  const Points points = curve->points();
182 
183  QString funcArea, polyArea;
184  QVector<QString> x, y, distanceGraphForward, distancePercentForward, distanceGraphBackward, distancePercentBackward;
185 
186  CurveStyle curveStyle = cmdMediator.document().modelCurveStyles().curveStyle (curveSelected);
187  m_geometryStrategyContext.calculateGeometry (points,
188  cmdMediator.document().modelCoords(),
189  cmdMediator.document().modelGeneral(),
190  modelMainWindow,
191  transformation,
192  curveStyle.lineStyle().curveConnectAs(),
193  funcArea,
194  polyArea,
195  x,
196  y,
197  distanceGraphForward,
198  distancePercentForward,
199  distanceGraphBackward,
200  distancePercentBackward);
201 
202  // Output to table
203  resizeTable (NUM_HEADER_ROWS + points.count());
204 
205  m_model->setItem (HEADER_ROW_NAME, COLUMN_HEADER_VALUE, new QStandardItem (curveSelected));
206  m_model->setItem (HEADER_ROW_FUNC_AREA, COLUMN_HEADER_VALUE, new QStandardItem (funcArea));
207  m_model->setItem (HEADER_ROW_POLY_AREA, COLUMN_HEADER_VALUE, new QStandardItem (polyArea));
208 
209  if (transformation.transformIsDefined()) {
210 
211  int row = NUM_HEADER_ROWS;
212  int index = 0;
213  for (; index < points.count(); row++, index++) {
214 
215  const Point &point = points.at (index);
216 
217  QPointF posGraph;
218  transformation.transformScreenToRawGraph (point.posScreen (),
219  posGraph);
220 
221  m_model->setItem (row, COLUMN_BODY_X, new QStandardItem (x [index]));
222  m_model->setItem (row, COLUMN_BODY_Y, new QStandardItem (y [index]));
223  m_model->setItem (row, COLUMN_BODY_INDEX, new QStandardItem (QString::number (index + 1)));
224  m_model->setItem (row, COLUMN_BODY_DISTANCE_GRAPH_FORWARD, new QStandardItem (distanceGraphForward [index]));
225  m_model->setItem (row, COLUMN_BODY_DISTANCE_PERCENT_FORWARD, new QStandardItem (distancePercentForward [index]));
226  m_model->setItem (row, COLUMN_BODY_DISTANCE_GRAPH_BACKWARD, new QStandardItem (distanceGraphBackward [index]));
227  m_model->setItem (row, COLUMN_BODY_DISTANCE_PERCENT_BACKWARD, new QStandardItem (distancePercentBackward [index]));
228  m_model->setItem (row, COLUMN_BODY_POINT_IDENTIFIERS, new QStandardItem (point.identifier()));
229  }
230  }
231 
232  // Unselect everything
233  unselectAll ();
234 
235  // Make sure the hidden column stays hidden
236  m_view->setColumnHidden (COLUMN_BODY_POINT_IDENTIFIERS, true);
237 }
238 
239 QTableView *GeometryWindow::view () const
240 {
241  return dynamic_cast<QTableView*> (m_view);
242 }
CurveStyle curveStyle(const QString &curveName) const
CurveStyle in specified curve.
Definition: CurveStyles.cpp:79
CurveConnectAs curveConnectAs() const
Get method for connect type.
Definition: LineStyle.cpp:63
void setCurrentPointIdentifier(const QString &pointIdentifier)
Set the point identifier to be highlighted. Value is empty for no highlighting.
virtual void closeEvent(QCloseEvent *event)
Catch close event so corresponding menu item in MainWindow can be updated accordingly.
virtual QTableView * view() const
QTableView-based class used by child class.
Dockable widget abstract base class.
const Curve * curveForCurveName(const QString &curveName) const
See CurvesGraphs::curveForCurveNames, although this also works for AXIS_CURVE_NAME.
Definition: Document.cpp:332
DocumentModelGeneral modelGeneral() const
Get method for DocumentModelGeneral.
Definition: Document.cpp:717
void slotPointHoverEnter(QString)
Highlight the row for the specified point.
Class that represents one digitized point. The screen-to-graph coordinate transformation is always ex...
Definition: Point.h:23
QPointF posScreen() const
Accessor for screen position.
Definition: Point.cpp:392
virtual void update(const CmdMediator &cmdMediator, const MainWindowModel &modelMainWindow, const QString &curveSelected, const Transformation &transformation)
Populate the table with the specified Curve.
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Definition: CmdMediator.cpp:72
const Points points() const
Return a shallow copy of the Points.
Definition: Curve.cpp:451
QString selectionAsText(ExportDelimiter delimiter) const
Convert the selection into exportable text which is good for text editors.
QString identifier() const
Unique identifier for a specific Point.
Definition: Point.cpp:256
void slotPointHoverLeave(QString)
Unhighlight the row for the specified point.
Affine transformation between screen and graph coordinates, based on digitized axis points...
virtual void doCopy()
Copy the current selection to the clipboard.
void setDelimiter(ExportDelimiter delimiter)
Save output delimiter.
Model for DlgSettingsMainWindow.
LineStyle lineStyle() const
Get method for LineStyle.
Definition: CurveStyle.cpp:26
GeometryWindow(MainWindow *mainWindow)
Single constructor. Parent is needed or else this widget cannot be redocked after being undocked...
ExportDelimiter delimiter() const
Get method for delimiter.
void signalGeometryWindowClosed()
Signal that this QDockWidget was just closed.
static int columnBodyPointIdentifiers()
Hidden column that has the point identifiers.
Container for LineStyle and PointStyle for one Curve.
Definition: CurveStyle.h:18
Table view class with support for both drag-and-drop and copy-and-paste.
Definition: WindowTable.h:17
Container for one set of digitized Points.
Definition: Curve.h:33
Command queue stack.
Definition: CmdMediator.h:23
bool dragDropExport() const
Get method for drag and drop export.
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< QString > &distanceGraphForward, QVector< QString > &distancePercentForward, QVector< QString > &distanceGraphBackward, QVector< QString > &distancePercentBackward) const
Calculate geometry parameters.
DocumentModelExportFormat modelExport() const
Get method for DocumentModelExportFormat.
Definition: Document.cpp:710
Model that adds row highlighting according to the currently select point identifier.
Definition: GeometryModel.h:14
CurveStyles modelCurveStyles() const
Get method for CurveStyles.
Definition: Document.cpp:696
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
Definition: Document.cpp:689
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition: MainWindow.h:89
virtual void clear()
Clear stale information.