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