00001
00002
00003
00004
00005
00006
00007 #include "CallbackGatherXThetaValuesFunctions.h"
00008 #include "CmdMediator.h"
00009 #include "Curve.h"
00010 #include "CurveConnectAs.h"
00011 #include "CurveStyle.h"
00012 #include "EngaugeAssert.h"
00013 #include "GeometryModel.h"
00014 #include "GeometryWindow.h"
00015 #include "Logger.h"
00016 #include <QApplication>
00017 #include <QClipboard>
00018 #include <QHeaderView>
00019 #include <QItemSelectionModel>
00020 #include <QTableView>
00021 #include <QTextStream>
00022
00023
00024
00025
00026 const QString TokenName (QObject::tr ("CurveName:"));
00027 const QString TokenFunctionArea (QObject::tr ("FunctionArea:"));
00028 const QString TokenPolygonArea (QObject::tr ("PolygonArea:"));
00029 const QString TokenX (QObject::tr ("X"));
00030 const QString TokenY (QObject::tr ("Y"));
00031 const QString TokenIndex (QObject::tr ("Index"));
00032 const QString TokenDistanceGraph (QObject::tr ("Distance"));
00033 const QString TokenDistancePercent (QObject::tr ("Percent"));
00034
00035 GeometryWindow::GeometryWindow (QWidget *parent) :
00036 QDockWidget (parent)
00037 {
00038 setVisible (false);
00039 setAllowedAreas (Qt::AllDockWidgetAreas);
00040 setWindowTitle (tr ("Geometry Window"));
00041 setStatusTip (tr ("Geometry Window"));
00042 setWhatsThis (tr ("Geometry Window\n\n"
00043 "This table displays the following geometry data for the currently selected curve:\n\n"
00044 "Function area = Area under the curve if it is a function\n\n"
00045 "Polygon area = Area inside the curve if it is a relation. This value is only correct "
00046 "if none of the curve lines intersect each other\n\n"
00047 "X = X coordinate of each point\n\n"
00048 "Y = Y coordinate of each point\n\n"
00049 "Index = Point number\n\n"
00050 "Distance = Distance along the curve in forward or backward direction, in either graph units "
00051 "or as a percentage"));
00052
00053 m_model = new GeometryModel;
00054
00055 m_view = new QTableView;
00056 m_view->setModel (m_model);
00057 m_view->horizontalHeader()->hide();
00058 m_view->verticalHeader()->hide();
00059 m_view->setEditTriggers(QAbstractItemView::NoEditTriggers);
00060 connect (m_view->selectionModel(), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)),
00061 this, SLOT (slotSelectionChanged (const QItemSelection &, const QItemSelection &)));
00062
00063 setWidget (m_view);
00064
00065 loadStrategies();
00066
00067 initializeHeader ();
00068 }
00069
00070 GeometryWindow::~GeometryWindow()
00071 {
00072 }
00073
00074 void GeometryWindow::clear ()
00075 {
00076
00077 resizeTable (NUM_HEADER_ROWS);
00078
00079
00080 for (int row = 0; row < NUM_HEADER_ROWS - 1; row++) {
00081 m_model->setItem (row, COLUMN_HEADER_VALUE, new QStandardItem (""));
00082 }
00083 }
00084
00085 void GeometryWindow::closeEvent(QCloseEvent * )
00086 {
00087 LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::closeEvent";
00088
00089 emit signalGeometryWindowClosed();
00090 }
00091
00092 int GeometryWindow::fold2dIndexes (int row,
00093 int col,
00094 int rowLow,
00095 int colLow,
00096 int colHigh) const
00097 {
00098 return (row - rowLow) * (colHigh - colLow + 1) + (col - colLow);
00099 }
00100
00101 int GeometryWindow::columnBodyPointIdentifiers ()
00102 {
00103 return COLUMN_BODY_POINT_IDENTIFIERS;
00104 }
00105
00106 void GeometryWindow::initializeHeader ()
00107 {
00108 LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::initializeHeader";
00109
00110 resizeTable (NUM_HEADER_ROWS);
00111
00112 m_model->setItem (HEADER_ROW_NAME, COLUMN_HEADER_LABEL, new QStandardItem (TokenName));
00113 m_model->setItem (HEADER_ROW_FUNC_AREA, COLUMN_HEADER_LABEL, new QStandardItem (TokenFunctionArea));
00114 m_model->setItem (HEADER_ROW_POLY_AREA, COLUMN_HEADER_LABEL, new QStandardItem (TokenPolygonArea));
00115 m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_X, new QStandardItem (TokenX));
00116 m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_Y, new QStandardItem (TokenY));
00117 m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_INDEX, new QStandardItem (TokenIndex));
00118 m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_DISTANCE_GRAPH_FORWARD, new QStandardItem (TokenDistanceGraph));
00119 m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_DISTANCE_PERCENT_FORWARD, new QStandardItem (TokenDistancePercent));
00120 m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_DISTANCE_GRAPH_BACKWARD, new QStandardItem (TokenDistanceGraph));
00121 m_model->setItem (HEADER_ROW_COLUMN_NAMES, COLUMN_BODY_DISTANCE_PERCENT_BACKWARD, new QStandardItem (TokenDistancePercent));
00122 }
00123
00124 void GeometryWindow::loadStrategies ()
00125 {
00126 LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::loadStrategies";
00127 }
00128
00129 void GeometryWindow::resizeTable (int rowCount)
00130 {
00131 LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::resizeTable";
00132
00133 unselectAll();
00134
00135 m_model->setRowCount (rowCount);
00136 m_model->setColumnCount (NUM_BODY_COLUMNS);
00137
00138 }
00139
00140 void GeometryWindow::slotPointHoverEnter (QString pointIdentifier)
00141 {
00142 m_model->setCurrentPointIdentifier (pointIdentifier);
00143 }
00144
00145 void GeometryWindow::slotPointHoverLeave (QString )
00146 {
00147 m_model->setCurrentPointIdentifier ("");
00148 }
00149
00150 void GeometryWindow::slotSelectionChanged (const QItemSelection & ,
00151 const QItemSelection & )
00152 {
00153 const bool NOT_GNUPLOT = false;
00154
00155 QItemSelectionModel *selectionModel = m_view->selectionModel ();
00156 QModelIndexList selection = selectionModel->selectedIndexes ();
00157
00158 if (selection.size () > 0) {
00159
00160
00161 int rowLow = 0, rowHigh = 0, colLow = 0, colHigh = 0;
00162 bool isFirst = true;
00163 for (QModelIndexList::const_iterator itr = selection.begin(); itr != selection.end(); itr++) {
00164 QModelIndex index = *itr;
00165 if (isFirst || index.row () < rowLow ) rowLow = index.row ();
00166 if (isFirst || index.row () > rowHigh) rowHigh = index.row ();
00167 if (isFirst || index.column () < colLow ) colLow = index.column ();
00168 if (isFirst || index.column () > colHigh) colHigh = index.column ();
00169 isFirst = false;
00170 }
00171
00172 int numRows = rowHigh - rowLow + 1;
00173 int numCols = colHigh - colLow + 1;
00174
00175
00176
00177 QVector<QString> table (numRows * numCols);
00178
00179 for (int i = 0; i < selection.size (); i++) {
00180 QModelIndex index = selection [i];
00181 QVariant data = m_model->data (index);
00182 QString text = data.toString ();
00183 table [fold2dIndexes (index.row(), index.column(), rowLow, colLow, colHigh)] = text;
00184 }
00185
00186
00187 QString output;
00188 QTextStream str (&output);
00189 for (int row = rowLow; row <= rowHigh; row++) {
00190 QString delimiter;
00191 for (int col = colLow; col <= colHigh; col++) {
00192 str << delimiter << table [fold2dIndexes (row, col, rowLow, colLow, colHigh)];
00193 delimiter = exportDelimiterToText (m_modelExport.delimiter(),
00194 NOT_GNUPLOT);
00195 }
00196 str << "\n";
00197 }
00198
00199
00200 QApplication::clipboard ()->setText (output);
00201 }
00202 }
00203
00204 void GeometryWindow::update (const CmdMediator &cmdMediator,
00205 const MainWindowModel &modelMainWindow,
00206 const QString &curveSelected,
00207 const Transformation &transformation)
00208 {
00209 LOG4CPP_INFO_S ((*mainCat)) << "GeometryWindow::update";
00210
00211
00212 m_modelExport = cmdMediator.document().modelExport();
00213
00214
00215 const Curve *curve = cmdMediator.document().curveForCurveName (curveSelected);
00216
00217 ENGAUGE_CHECK_PTR (curve);
00218
00219 const Points points = curve->points();
00220
00221 QString funcArea, polyArea;
00222 QVector<QString> x, y, distanceGraphForward, distancePercentForward, distanceGraphBackward, distancePercentBackward;
00223
00224 CurveStyle curveStyle = cmdMediator.document().modelCurveStyles().curveStyle (curveSelected);
00225 m_geometryStrategyContext.calculateGeometry (points,
00226 cmdMediator.document().modelCoords(),
00227 cmdMediator.document().modelGeneral(),
00228 modelMainWindow,
00229 transformation,
00230 curveStyle.lineStyle().curveConnectAs(),
00231 funcArea,
00232 polyArea,
00233 x,
00234 y,
00235 distanceGraphForward,
00236 distancePercentForward,
00237 distanceGraphBackward,
00238 distancePercentBackward);
00239
00240
00241 resizeTable (NUM_HEADER_ROWS + points.count());
00242
00243 m_model->setItem (HEADER_ROW_NAME, COLUMN_HEADER_VALUE, new QStandardItem (curveSelected));
00244 m_model->setItem (HEADER_ROW_FUNC_AREA, COLUMN_HEADER_VALUE, new QStandardItem (funcArea));
00245 m_model->setItem (HEADER_ROW_POLY_AREA, COLUMN_HEADER_VALUE, new QStandardItem (polyArea));
00246
00247 if (transformation.transformIsDefined()) {
00248
00249 int row = NUM_HEADER_ROWS;
00250 int index = 0;
00251 for (; index < points.count(); row++, index++) {
00252
00253 const Point &point = points.at (index);
00254
00255 QPointF posGraph;
00256 transformation.transformScreenToRawGraph (point.posScreen (),
00257 posGraph);
00258
00259 m_model->setItem (row, COLUMN_BODY_X, new QStandardItem (x [index]));
00260 m_model->setItem (row, COLUMN_BODY_Y, new QStandardItem (y [index]));
00261 m_model->setItem (row, COLUMN_BODY_INDEX, new QStandardItem (QString::number (index + 1)));
00262 m_model->setItem (row, COLUMN_BODY_DISTANCE_GRAPH_FORWARD, new QStandardItem (distanceGraphForward [index]));
00263 m_model->setItem (row, COLUMN_BODY_DISTANCE_PERCENT_FORWARD, new QStandardItem (distancePercentForward [index]));
00264 m_model->setItem (row, COLUMN_BODY_DISTANCE_GRAPH_BACKWARD, new QStandardItem (distanceGraphBackward [index]));
00265 m_model->setItem (row, COLUMN_BODY_DISTANCE_PERCENT_BACKWARD, new QStandardItem (distancePercentBackward [index]));
00266 m_model->setItem (row, COLUMN_BODY_POINT_IDENTIFIERS, new QStandardItem (point.identifier()));
00267 }
00268 }
00269
00270
00271 unselectAll ();
00272
00273
00274 m_view->setColumnHidden (COLUMN_BODY_POINT_IDENTIFIERS, true);
00275 }
00276
00277 void GeometryWindow::unselectAll ()
00278 {
00279 QItemSelectionModel *selectionModel = m_view->selectionModel ();
00280
00281 selectionModel->clearSelection ();
00282 }