1 /****************************************************************************
2 **
3 ** This file is part of the LibreCAD project, a 2D CAD program
4 **
5 ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
6 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
7 **
8 **
9 ** This file may be distributed and/or modified under the terms of the
10 ** GNU General Public License version 2 as published by the Free Software
11 ** Foundation and appearing in the file gpl-2.0.txt included in the
12 ** packaging of this file.
13 **
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ** GNU General Public License for more details.
18 **
19 ** You should have received a copy of the GNU General Public License
20 ** along with this program; if not, write to the Free Software
21 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 **
23 ** This copyright notice MUST APPEAR in all copies of the script!
24 **
25 **********************************************************************/
26 #include<vector>
27 #include <QAction>
28 #include <QMouseEvent>
29 #include "rs_actiondimleader.h"
30 
31 #include "rs_dialogfactory.h"
32 #include "rs_graphicview.h"
33 #include "rs_commandevent.h"
34 #include "rs_leader.h"
35 #include "rs_line.h"
36 #include "rs_coordinateevent.h"
37 #include "rs_preview.h"
38 #include "rs_debug.h"
39 
40 struct RS_ActionDimLeader::Points {
41 std::vector<RS_Vector> points;
42 };
43 
RS_ActionDimLeader(RS_EntityContainer & container,RS_GraphicView & graphicView)44 RS_ActionDimLeader::RS_ActionDimLeader(RS_EntityContainer& container,
45                                        RS_GraphicView& graphicView)
46         :RS_PreviewActionInterface("Draw leaders",
47                            container, graphicView)
48 	, pPoints(new Points{})
49  {
50 	actionType=RS2::ActionDimLeader;
51     reset();
52 }
53 
54 RS_ActionDimLeader::~RS_ActionDimLeader() = default;
55 
reset()56 void RS_ActionDimLeader::reset() {
57     //data = RS_LineData(RS_Vector(false), RS_Vector(false));
58     //start = RS_Vector(false);
59     //history.clear();
60     pPoints->points.clear();
61 }
62 
init(int status)63 void RS_ActionDimLeader::init(int status) {
64     RS_PreviewActionInterface::init(status);
65 
66     reset();
67 }
68 
69 
70 
trigger()71 void RS_ActionDimLeader::trigger() {
72     RS_PreviewActionInterface::trigger();
73 
74 	if (pPoints->points.size()){
75 
76         RS_Leader* leader = new RS_Leader(container, RS_LeaderData(true));
77         leader->setLayerToActive();
78         leader->setPenToActive();
79 
80 		for(const auto& vp: pPoints->points){
81 			leader->addVertex(vp);
82 		}
83 
84         container->addEntity(leader);
85 
86         // upd. undo list:
87 		if (document) {
88             document->startUndoCycle();
89             document->addUndoable(leader);
90             document->endUndoCycle();
91         }
92 
93         deletePreview();
94         RS_Vector rz = graphicView->getRelativeZero();
95 		graphicView->redraw(RS2::RedrawDrawing);
96         graphicView->moveRelativeZero(rz);
97         //drawSnapper();
98 
99         RS_DEBUG->print("RS_ActionDimLeader::trigger(): leader added: %d",
100                         leader->getId());
101     }
102 }
103 
104 
105 
mouseMoveEvent(QMouseEvent * e)106 void RS_ActionDimLeader::mouseMoveEvent(QMouseEvent* e) {
107     RS_DEBUG->print("RS_ActionDimLeader::mouseMoveEvent begin");
108 
109     RS_Vector mouse = snapPoint(e);
110 	if (getStatus()==SetEndpoint && pPoints->points.size()) {
111         deletePreview();
112 
113 		// fill in lines that were already set:
114 		RS_Vector last(false);
115 		for(const auto& v: pPoints->points){
116 			if (last.valid) {
117 				preview->addEntity(new RS_Line{preview.get(), last, v});
118 			}
119 			last = v;
120 		}
121 
122 		if (pPoints->points.size() ) {
123 			RS_Vector const& p = pPoints->points.back();
124 			preview->addEntity(new RS_Line{preview.get(), p, mouse});
125         }
126         drawPreview();
127     }
128 
129     RS_DEBUG->print("RS_ActionDimLeader::mouseMoveEvent end");
130 }
131 
132 
133 
mouseReleaseEvent(QMouseEvent * e)134 void RS_ActionDimLeader::mouseReleaseEvent(QMouseEvent* e) {
135     if (e->button()==Qt::LeftButton) {
136         RS_CoordinateEvent ce(snapPoint(e));
137         coordinateEvent(&ce);
138     } else if (e->button()==Qt::RightButton) {
139         if (getStatus()==SetEndpoint) {
140             trigger();
141             reset();
142             setStatus(SetStartpoint);
143         } else {
144             deletePreview();
145             init(getStatus()-1);
146         }
147     }
148 }
149 
150 
151 
keyPressEvent(QKeyEvent * e)152 void RS_ActionDimLeader::keyPressEvent(QKeyEvent* e) {
153     if (getStatus()==SetEndpoint && e->key()==Qt::Key_Enter) {
154         trigger();
155         reset();
156         setStatus(SetStartpoint);
157     }
158 }
159 
160 
161 
coordinateEvent(RS_CoordinateEvent * e)162 void RS_ActionDimLeader::coordinateEvent(RS_CoordinateEvent* e) {
163 	if (!e) {
164         return;
165     }
166 
167     RS_Vector mouse = e->getCoordinate();
168 
169     switch (getStatus()) {
170     case SetStartpoint:
171         //data.startpoint = mouse;
172         pPoints->points.clear();
173 	pPoints->points.push_back(mouse);
174         //start = data.startpoint;
175         setStatus(SetEndpoint);
176         graphicView->moveRelativeZero(mouse);
177         break;
178 
179     case SetEndpoint:
180         //data.endpoint = mouse;
181 	pPoints->points.push_back(mouse);
182         //trigger();
183         //data.startpoint = data.endpoint;
184         graphicView->moveRelativeZero(mouse);
185         break;
186 
187     default:
188         break;
189     }
190 }
191 
192 
193 
commandEvent(RS_CommandEvent * e)194 void RS_ActionDimLeader::commandEvent(RS_CommandEvent* e) {
195     QString c = e->getCommand().toLower();
196 
197 	if (checkCommand("help", c)) {
198 		RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
199 										 + getAvailableCommands().join(", "));
200 		return;
201     }
202 
203     // enter to finish
204     if (c=="") {
205         trigger();
206         reset();
207         setStatus(SetStartpoint);
208         //finish();
209     }
210 }
211 
212 
213 
getAvailableCommands()214 QStringList RS_ActionDimLeader::getAvailableCommands() {
215     QStringList cmd;
216 
217     return cmd;
218 }
219 
updateMouseButtonHints()220 void RS_ActionDimLeader::updateMouseButtonHints() {
221 	switch (getStatus()) {
222 	case SetStartpoint:
223 		RS_DIALOGFACTORY->updateMouseWidget(tr("Specify target point"),
224 											tr("Cancel"));
225 		break;
226 	case SetEndpoint:
227 		RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point"),
228 											tr("Finish"));
229 		break;
230 	default:
231 		RS_DIALOGFACTORY->updateMouseWidget();
232 		break;
233 	}
234 }
235 
236 
updateMouseCursor()237 void RS_ActionDimLeader::updateMouseCursor() {
238     graphicView->setMouseCursor(RS2::CadCursor);
239 }
240 
241 // EOF
242