1 /***************************************************************************
2 File : SubtractLineTool.cpp
3 Project : QtiPlot
4 --------------------------------------------------------------------
5 Copyright : (C) 2010 - 2011 by Ion Vasilief
6 Email (use @ for *) : ion_vasilief*yahoo.fr
7 Description : Plot tool for substracting a straight line
8
9 ***************************************************************************/
10
11 /***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 * This program is distributed in the hope that it will be useful, *
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21 * GNU General Public License for more details. *
22 * *
23 * You should have received a copy of the GNU General Public License *
24 * along with this program; if not, write to the Free Software *
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
26 * Boston, MA 02110-1301 USA *
27 * *
28 ***************************************************************************/
29 #include "SubtractLineTool.h"
30 #include <RangeSelectorTool.h>
31 #include <ApplicationWindow.h>
32 #include <PlotCurve.h>
33
34 #include <qwt_plot_curve.h>
35 #include <qwt_plot_marker.h>
36 #include <qwt_symbol.h>
37
38 #include <QApplication>
39
SubtractLineTool(Graph * graph,ApplicationWindow * app,const QObject * status_target,const char * status_slot)40 SubtractLineTool::SubtractLineTool(Graph *graph, ApplicationWindow *app, const QObject *status_target, const char *status_slot)
41 : PlotToolInterface(graph)
42 {
43 d_selected_points = 0;
44 if (status_target)
45 connect(this, SIGNAL(statusText(const QString&)), status_target, status_slot);
46 d_picker_tool = new ScreenPickerTool(d_graph, this, SIGNAL(statusText(const QString&)));
47 d_graph->canvas()->setCursor(QCursor(QPixmap(":/cursor.png"), -1, -1));
48
49 QString msg = tr("Move cursor and click to select and double-click/press 'Enter' to set the position of the first point!");
50 emit statusText(msg);
51
52 connect(d_picker_tool, SIGNAL(selected(const QwtDoublePoint &)), this, SLOT(selectPoint(const QwtDoublePoint &)));
53 d_graph->canvas()->grabMouse();
54 }
55
~SubtractLineTool()56 SubtractLineTool::~SubtractLineTool()
57 {
58 d_graph->canvas()->releaseMouse();
59
60 if (d_picker_tool)
61 delete d_picker_tool;
62 }
63
selectPoint(const QwtDoublePoint & pos)64 void SubtractLineTool::selectPoint(const QwtDoublePoint &pos)
65 {
66 d_selected_points++;
67 if (d_selected_points == 2){
68 d_line.setP2(QPointF(pos.x(), pos.y()));
69 finalize();
70 } else {
71 d_line.setP1(QPointF(pos.x(), pos.y()));
72
73 d_first_point_marker = new QwtPlotMarker();
74 d_first_point_marker->setLinePen(QPen(Qt::red, 1, Qt::DashLine));
75 d_first_point_marker->setLineStyle(QwtPlotMarker::Cross);
76 d_first_point_marker->setSymbol(QwtSymbol(QwtSymbol::Ellipse, QBrush(), QPen(Qt::red, 1), QSize(12, 12)));
77 d_first_point_marker->setValue(pos.x(), pos.y());
78 d_first_point_marker->attach(d_graph);
79 d_graph->replot();
80
81 QString msg = tr("First point selected! Click to select and double-click/press 'Enter' to set the position of the 2nd point!");
82 emit statusText(msg);
83 }
84 }
85
finalize()86 void SubtractLineTool::finalize()
87 {
88 delete d_picker_tool; d_picker_tool = NULL;
89 d_graph->canvas()->releaseMouse();
90 d_first_point_marker->detach();
91 delete d_first_point_marker;
92
93 if (d_graph->activeTool() && d_graph->activeTool()->rtti() == PlotToolInterface::Rtti_RangeSelector){
94 ((RangeSelectorTool *)d_graph->activeTool())->setEnabled();
95 } else
96 d_graph->canvas()->unsetCursor();
97
98 double den = d_line.dx();
99 double slope = 0.0;
100 double intercept = 0.0;
101 if (den != 0.0){
102 slope = d_line.dy()/den;
103 intercept = d_line.y1() - slope*d_line.x1();
104 }
105
106 for (int i = 0; i < d_graph->curveCount(); i++){
107 DataCurve *c = d_graph->dataCurve(i);
108 if (!c || c->type() == Graph::ErrorBars)
109 continue;
110
111 Table *t = c->table();
112 int yCol = t->colIndex(c->title().text());
113 int startRow = c->startRow(), endRow = c->endRow();
114 if (startRow < 0)
115 startRow = 0;
116 if (endRow < 0)
117 endRow = c->dataSize() - 1;
118 for (int j = startRow; j <= endRow; j++){
119 if (!t->text(j, yCol).isEmpty()){
120 int index = j - startRow;
121 t->setCell(j, yCol, c->y(index) - (c->x(index)*slope + intercept));
122 }
123 }
124 t->notifyChanges(c->title().text());
125 }
126 d_graph->setActiveTool(NULL);
127 }
128