Engauge Digitizer  2
 All Classes Functions Variables Typedefs Enumerations Friends Pages
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 
24  WindowAbstractBase (mainWindow)
25 {
26  setVisible (false);
27  setAllowedAreas (Qt::AllDockWidgetAreas);
28  setWindowTitle (tr ("Geometry Window")); // Appears in title bar when undocked
29  setStatusTip (tr ("Geometry Window"));
30  setWhatsThis (tr ("Geometry Window\n\n"
31  "This table displays the following geometry data for the currently selected curve:\n\n"
32  "Function area = Area under the curve if it is a function\n\n"
33  "Polygon area = Area inside the curve if it is a relation. This value is only correct "
34  "if none of the curve lines intersect each other\n\n"
35  "X = X coordinate of each point\n\n"
36  "Y = Y coordinate of each point\n\n"
37  "Index = Point number\n\n"
38  "Distance = Distance along the curve in forward or backward direction, in either graph units "
39  "or as a percentage\n\n"
40  "If drag-and-drop is disabled, a rectangular set of cells may be selected by clicking and dragging. Otherwise, if "
41  "drag-and-drop is enabled, a rectangular set of cells may be selected using Click then Shift+Click, since click and drag "
42  "starts the dragging operation. Drag-and-drop mode is set in the Main Window settings"));
43 
44  createWidgets (mainWindow);
45  loadStrategies();
46  initializeHeader ();
47 }
48 
49 GeometryWindow::~GeometryWindow()
50 {
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  // Save inputs
200  m_modelExport = cmdMediator.document().modelExport();
201  m_model->setDelimiter (m_modelExport.delimiter());
202  m_view->setDragEnabled (modelMainWindow.dragDropExport());
203 
204  // Gather and calculate geometry data
205  const Curve *curve = cmdMediator.document().curveForCurveName (curveSelected);
206 
207  ENGAUGE_CHECK_PTR (curve);
208 
209  const Points points = curve->points();
210 
211  QString funcArea, polyArea;
212  QVector<QString> x, y, distanceGraphForward, distancePercentForward, distanceGraphBackward, distancePercentBackward;
213 
214  CurveStyle curveStyle = cmdMediator.document().modelCurveStyles().curveStyle (curveSelected);
215  m_geometryStrategyContext.calculateGeometry (points,
216  cmdMediator.document().modelCoords(),
217  cmdMediator.document().modelGeneral(),
218  modelMainWindow,
219  transformation,
220  curveStyle.lineStyle().curveConnectAs(),
221  funcArea,
222  polyArea,
223  x,
224  y,
225  distanceGraphForward,
226  distancePercentForward,
227  distanceGraphBackward,
228  distancePercentBackward);
229 
230  // Output to table
231  resizeTable (NUM_HEADER_ROWS + points.count());
232 
233  m_model->setItem (HEADER_ROW_NAME, COLUMN_HEADER_VALUE, new QStandardItem (curveSelected));
234  m_model->setItem (HEADER_ROW_FUNC_AREA, COLUMN_HEADER_VALUE, new QStandardItem (funcArea));
235  m_model->setItem (HEADER_ROW_POLY_AREA, COLUMN_HEADER_VALUE, new QStandardItem (polyArea));
236 
237  if (transformation.transformIsDefined()) {
238 
239  int row = NUM_HEADER_ROWS;
240  int index = 0;
241  for (; index < points.count(); row++, index++) {
242 
243  const Point &point = points.at (index);
244 
245  QPointF posGraph;
246  transformation.transformScreenToRawGraph (point.posScreen (),
247  posGraph);
248 
249  m_model->setItem (row, COLUMN_BODY_X, new QStandardItem (x [index]));
250  m_model->setItem (row, COLUMN_BODY_Y, new QStandardItem (y [index]));
251  m_model->setItem (row, COLUMN_BODY_INDEX, new QStandardItem (QString::number (index + 1)));
252  m_model->setItem (row, COLUMN_BODY_DISTANCE_GRAPH_FORWARD, new QStandardItem (distanceGraphForward [index]));
253  m_model->setItem (row, COLUMN_BODY_DISTANCE_PERCENT_FORWARD, new QStandardItem (distancePercentForward [index]));
254  m_model->setItem (row, COLUMN_BODY_DISTANCE_GRAPH_BACKWARD, new QStandardItem (distanceGraphBackward [index]));
255  m_model->setItem (row, COLUMN_BODY_DISTANCE_PERCENT_BACKWARD, new QStandardItem (distancePercentBackward [index]));
256  m_model->setItem (row, COLUMN_BODY_POINT_IDENTIFIERS, new QStandardItem (point.identifier()));
257  }
258  }
259 
260  // Unselect everything
261  unselectAll ();
262 
263  // Make sure the hidden column stays hidden
264  m_view->setColumnHidden (COLUMN_BODY_POINT_IDENTIFIERS, true);
265 }
266 
267 QTableView *GeometryWindow::view () const
268 {
269  return dynamic_cast<QTableView*> (m_view);
270 }
virtual QTableView * view() const
QTableView-based class used by child class.
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.
const Points points() const
Return a shallow copy of the Points.
Definition: Curve.cpp:451
Dockable widget abstract base class.
LineStyle lineStyle() const
Get method for LineStyle.
Definition: CurveStyle.cpp:26
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
Definition: Document.cpp:691
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:25
QPointF posScreen() const
Accessor for screen position.
Definition: Point.cpp:404
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
QString identifier() const
Unique identifier for a specific Point.
Definition: Point.cpp:268
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.
QString selectionAsText(ExportDelimiter delimiter) const
Convert the selection into exportable text which is good for text editors.
void slotPointHoverLeave(QString)
Unhighlight the row for the specified point.
Affine transformation between screen and graph coordinates, based on digitized axis points...
CurveStyles modelCurveStyles() const
Get method for CurveStyles.
Definition: Document.cpp:698
virtual void doCopy()
Copy the current selection to the clipboard.
void setDelimiter(ExportDelimiter delimiter)
Save output delimiter.
Model for DlgSettingsMainWindow.
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
CurveStyle curveStyle(const QString &curveName) const
CurveStyle in specified curve.
Definition: CurveStyles.cpp:79
Command queue stack.
Definition: CmdMediator.h:23
const Curve * curveForCurveName(const QString &curveName) const
See CurvesGraphs::curveForCurveNames, although this also works for AXIS_CURVE_NAME.
Definition: Document.cpp:331
CurveConnectAs curveConnectAs() const
Get method for connect type.
Definition: LineStyle.cpp:63
Model that adds row highlighting according to the currently select point identifier.
Definition: GeometryModel.h:14
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition: MainWindow.h:91
DocumentModelExportFormat modelExport() const
Get method for DocumentModelExportFormat.
Definition: Document.cpp:712
DocumentModelGeneral modelGeneral() const
Get method for DocumentModelGeneral.
Definition: Document.cpp:719
virtual void clear()
Clear stale information.