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 
27 #include <QAction>
28 #include <QMouseEvent>
29 #include "rs_actiondrawtext.h"
30 
31 #include "rs_dialogfactory.h"
32 #include "rs_graphicview.h"
33 #include "rs_commandevent.h"
34 #include "rs_line.h"
35 #include "rs_text.h"
36 #include "rs_coordinateevent.h"
37 #include "rs_preview.h"
38 #include "rs_debug.h"
39 
40 struct RS_ActionDrawText::Points {
41 	RS_Vector pos;
42 	RS_Vector secPos;
43 };
44 
RS_ActionDrawText(RS_EntityContainer & container,RS_GraphicView & graphicView)45 RS_ActionDrawText::RS_ActionDrawText(RS_EntityContainer& container,
46                                      RS_GraphicView& graphicView)
47         :RS_PreviewActionInterface("Draw Text",
48 						   container, graphicView)
49 		, pPoints(new Points{})
50 		,textChanged(true)
51 {
52 	actionType=RS2::ActionDrawText;
53 }
54 
55 RS_ActionDrawText::~RS_ActionDrawText() = default;
56 
57 
init(int status)58 void RS_ActionDrawText::init(int status) {
59 	RS_ActionInterface::init(status);
60 
61 	switch (status) {
62 	case ShowDialog: {
63 		reset();
64 
65 		RS_Text tmp(NULL, *data);
66 		if (RS_DIALOGFACTORY->requestTextDialog(&tmp)) {
67 			data.reset(new RS_TextData(tmp.getData()));
68 			setStatus(SetPos);
69 			showOptions();
70 		} else {
71 			hideOptions();
72 			setFinished();
73 		}
74 	}
75 		break;
76 
77 	case SetPos:
78 		RS_DIALOGFACTORY->requestOptions(this, true, true);
79 		deletePreview();
80 		preview->setVisible(true);
81 		preparePreview();
82 		break;
83 
84 	default:
85 		break;
86 	}
87 }
88 
89 
90 
reset()91 void RS_ActionDrawText::reset() {
92 	const QString text=data.get()?data->text:"";
93 	data.reset(new RS_TextData(RS_Vector(0.0,0.0), RS_Vector(0.0,0.0),
94                        1.0, 1.0,
95                        RS_TextData::VABaseline,
96                        RS_TextData::HALeft,
97                        RS_TextData::None,
98 					   text,
99                        "standard",
100                        0.0,
101 					   RS2::Update));
102 }
103 
104 
105 
trigger()106 void RS_ActionDrawText::trigger() {
107 
108     RS_DEBUG->print("RS_ActionDrawText::trigger()");
109 
110 	if (pPoints->pos.valid) {
111         deletePreview();
112 
113 		RS_Text* text = new RS_Text(container, *data);
114         text->update();
115         container->addEntity(text);
116 
117         if (document) {
118             document->startUndoCycle();
119             document->addUndoable(text);
120             document->endUndoCycle();
121         }
122 
123                 graphicView->redraw(RS2::RedrawDrawing);
124 
125         textChanged = true;
126 		pPoints->secPos = {};
127         setStatus(SetPos);
128     }
129 }
130 
131 
preparePreview()132 void RS_ActionDrawText::preparePreview() {
133 	if (data->halign == RS_TextData::HAFit || data->halign == RS_TextData::HAAligned) {
134 		if (pPoints->secPos.valid) {
135 			RS_Line* text = new RS_Line(pPoints->pos, pPoints->secPos);
136             preview->addEntity(text);
137         }
138     } else {
139 		data->insertionPoint = pPoints->pos;
140 		RS_Text* text = new RS_Text(preview.get(), *data);
141         text->update();
142         preview->addEntity(text);
143     }
144     textChanged = false;
145 }
146 
147 
mouseMoveEvent(QMouseEvent * e)148 void RS_ActionDrawText::mouseMoveEvent(QMouseEvent* e) {
149     RS_DEBUG->print("RS_ActionDrawText::mouseMoveEvent begin");
150 
151     if (getStatus()==SetPos) {
152         RS_Vector mouse = snapPoint(e);
153 		RS_Vector mov = mouse - pPoints->pos;
154 		pPoints->pos = mouse;
155 		if (textChanged || pPoints->pos.valid == false || preview->isEmpty()) {
156             deletePreview();
157             preparePreview();
158         } else {
159             preview->move(mov);
160             preview->setVisible(true);
161         }
162         drawPreview();
163     } else if (getStatus()==SetSecPos) {
164 		pPoints->secPos = snapPoint(e);
165         deletePreview();
166         preparePreview();
167         drawPreview();
168     }
169 
170     RS_DEBUG->print("RS_ActionDrawText::mouseMoveEvent end");
171 }
172 
173 
174 
mouseReleaseEvent(QMouseEvent * e)175 void RS_ActionDrawText::mouseReleaseEvent(QMouseEvent* e) {
176     if (e->button()==Qt::LeftButton) {
177         RS_CoordinateEvent ce(snapPoint(e));
178         coordinateEvent(&ce);
179     } else if (e->button()==Qt::RightButton) {
180         deletePreview();
181         //init(getStatus()-1);
182         finish(false);
183     }
184 }
185 
186 
187 
coordinateEvent(RS_CoordinateEvent * e)188 void RS_ActionDrawText::coordinateEvent(RS_CoordinateEvent* e) {
189     if (e==NULL) {
190         return;
191     }
192 
193     RS_Vector mouse = e->getCoordinate();
194 
195     switch (getStatus()) {
196     case ShowDialog:
197         break;
198 
199     case SetPos:
200 		data->insertionPoint = mouse;
201 		if (data->halign == RS_TextData::HAFit || data->halign == RS_TextData::HAAligned)
202             setStatus(SetSecPos);
203         else
204             trigger();
205         break;
206 
207     case SetSecPos:
208 		data->secondPoint = mouse;
209         trigger();
210         break;
211 
212     default:
213         break;
214     }
215 }
216 
217 
218 
commandEvent(RS_CommandEvent * e)219 void RS_ActionDrawText::commandEvent(RS_CommandEvent* e) {
220     QString c = e->getCommand().toLower();
221 
222 	if (checkCommand("help", c)) {
223 		RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
224 										 + getAvailableCommands().join(", "));
225 		return;
226 	}
227 
228     switch (getStatus()) {
229     case SetPos:
230         if (checkCommand("text", c)) {
231             deletePreview();
232             graphicView->disableCoordinateInput();
233             setStatus(SetText);
234         }
235         break;
236 
237     case SetText: {
238             setText(e->getCommand());
239 			RS_DIALOGFACTORY->requestOptions(this, true, true);
240             graphicView->enableCoordinateInput();
241             setStatus(SetPos);
242         }
243         break;
244 
245     default:
246         break;
247     }
248 }
249 
250 
251 
getAvailableCommands()252 QStringList RS_ActionDrawText::getAvailableCommands() {
253     QStringList cmd;
254     if (getStatus()==SetPos) {
255         cmd += command("text");
256     }
257     return cmd;
258 }
259 
260 
261 
showOptions()262 void RS_ActionDrawText::showOptions() {
263     RS_ActionInterface::showOptions();
264 
265 	RS_DIALOGFACTORY->requestOptions(this, true, true);
266 }
267 
268 
269 
hideOptions()270 void RS_ActionDrawText::hideOptions() {
271     RS_ActionInterface::hideOptions();
272 
273 	RS_DIALOGFACTORY->requestOptions(this, false);
274 }
275 
276 
277 
updateMouseButtonHints()278 void RS_ActionDrawText::updateMouseButtonHints() {
279 	switch (getStatus()) {
280 	case SetPos:
281 		RS_DIALOGFACTORY->updateMouseWidget(tr("Specify insertion point"),
282 											tr("Cancel"));
283 		break;
284 	case SetSecPos:
285 		RS_DIALOGFACTORY->updateMouseWidget(tr("Specify second point"),
286 											tr("Cancel"));
287 		break;
288 	case ShowDialog:
289 	case SetText:
290 		RS_DIALOGFACTORY->updateMouseWidget(tr("Enter text:"),
291 											tr("Back"));
292 		break;
293 	default:
294 		RS_DIALOGFACTORY->updateMouseWidget();
295 		break;
296 	}
297 }
298 
299 
300 
updateMouseCursor()301 void RS_ActionDrawText::updateMouseCursor() {
302     graphicView->setMouseCursor(RS2::CadCursor);
303 }
304 
setText(const QString & t)305 void RS_ActionDrawText::setText(const QString& t) {
306 	data->text = t;
307     textChanged = true;
308 }
309 
310 
311 
getText() const312 const QString&  RS_ActionDrawText::getText() const{
313 	return data->text;
314 }
315 
316 
setAngle(double a)317 void RS_ActionDrawText::setAngle(double a) {
318 	data->angle = a;
319     textChanged = true;
320 }
321 
getAngle() const322 double RS_ActionDrawText::getAngle() const{
323 	return data->angle;
324 }
325 
326 
327 // EOF
328