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