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_actionblocksinsert.h"
30 #include "rs_insert.h"
31 #include "rs_block.h"
32
33 #include "rs_graphic.h"
34 #include "rs_graphicview.h"
35 #include "rs_dialogfactory.h"
36 #include "rs_commandevent.h"
37 #include "rs_coordinateevent.h"
38 #include "rs_creation.h"
39 #include "rs_math.h"
40 #include "rs_preview.h"
41
42 /**
43 * Constructor.
44 */
RS_ActionBlocksInsert(RS_EntityContainer & container,RS_GraphicView & graphicView)45 RS_ActionBlocksInsert::RS_ActionBlocksInsert(RS_EntityContainer& container,
46 RS_GraphicView& graphicView)
47 :RS_PreviewActionInterface("Blocks Insert",
48 container, graphicView)
49 ,block(nullptr)
50 ,lastStatus(SetUndefined)
51 {
52 actionType = RS2::ActionBlocksInsert;
53 reset(); // init data Member
54 }
55
56
57
58 RS_ActionBlocksInsert::~RS_ActionBlocksInsert() = default;
59
60
init(int status)61 void RS_ActionBlocksInsert::init(int status) {
62 RS_PreviewActionInterface::init(status);
63
64 reset();
65
66 if (graphic) {
67 block = graphic->getActiveBlock();
68 if (block) {
69 QString blockName = block->getName();
70 data->name = blockName;
71 if (document->rtti() == RS2::EntityBlock) {
72 QString parentBlockName = ((RS_Block*)(document))->getName();
73 if (parentBlockName == blockName) {
74 RS_DIALOGFACTORY->commandMessage(tr("Block cannot contain an insert of itself."));
75 finish(false);
76 } else {
77 QStringList bnChain = block->findNestedInsert(parentBlockName);
78 if (!bnChain.empty()) {
79 RS_DIALOGFACTORY->commandMessage(blockName
80 + tr(" has nested insert of current block in:\n")
81 + bnChain.join("->")
82 + tr("\nThis block cannot be inserted."));
83 finish(false);
84 }
85 }
86 }
87 } else {
88 finish(false);
89 }
90 }
91 }
92
93
94
reset()95 void RS_ActionBlocksInsert::reset() {
96 data.reset(new RS_InsertData("",
97 RS_Vector(0.0,0.0),
98 RS_Vector(1.0,1.0),
99 0.0,
100 1, 1,
101 RS_Vector(1.0,1.0),
102 NULL,
103 RS2::Update));
104 }
105
106
107
trigger()108 void RS_ActionBlocksInsert::trigger() {
109 deletePreview();
110
111 //RS_Modification m(*container, graphicView);
112 //m.paste(img->insertionPoint);
113 //std::cout << *RS_Clipboard::instance();
114
115 if (block) {
116 RS_Creation creation(container, graphicView);
117 data->updateMode = RS2::Update;
118 creation.createInsert(data.get());
119 }
120
121 graphicView->redraw(RS2::RedrawDrawing);
122
123 //finish();
124 }
125
126
mouseMoveEvent(QMouseEvent * e)127 void RS_ActionBlocksInsert::mouseMoveEvent(QMouseEvent* e) {
128 switch (getStatus()) {
129 case SetTargetPoint:
130 data->insertionPoint = snapPoint(e);
131
132 if (block) {
133 deletePreview();
134 //preview->addAllFrom(*block);
135 //preview->move(data->insertionPoint);
136 RS_Creation creation(preview.get(), nullptr, false);
137 // Create insert as preview only
138 data->updateMode = RS2::PreviewUpdate;
139 creation.createInsert(data.get());
140 drawPreview();
141 }
142 break;
143
144 default:
145 break;
146 }
147 }
148
149
150
mouseReleaseEvent(QMouseEvent * e)151 void RS_ActionBlocksInsert::mouseReleaseEvent(QMouseEvent* e) {
152 if (e->button()==Qt::LeftButton) {
153 RS_CoordinateEvent ce(snapPoint(e));
154 coordinateEvent(&ce);
155 } else if (e->button()==Qt::RightButton) {
156 init(getStatus()-1);
157 }
158 }
159
160
161
coordinateEvent(RS_CoordinateEvent * e)162 void RS_ActionBlocksInsert::coordinateEvent(RS_CoordinateEvent* e) {
163 if (e==NULL) {
164 return;
165 }
166
167 data->insertionPoint = e->getCoordinate();
168 trigger();
169 }
170
171
172
commandEvent(RS_CommandEvent * e)173 void RS_ActionBlocksInsert::commandEvent(RS_CommandEvent* e) {
174 QString c = e->getCommand().toLower();
175
176 if (checkCommand("help", c)) {
177 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
178 + getAvailableCommands().join(", "));
179 return;
180 }
181
182 switch (getStatus()) {
183 case SetTargetPoint:
184 if (checkCommand("angle", c)) {
185 deletePreview();
186 lastStatus = (Status)getStatus();
187 setStatus(SetAngle);
188 } else if (checkCommand("factor", c)) {
189 deletePreview();
190 lastStatus = (Status)getStatus();
191 setStatus(SetFactor);
192 } else if (checkCommand("columns", c)) {
193 deletePreview();
194 lastStatus = (Status)getStatus();
195 setStatus(SetColumns);
196 } else if (checkCommand("rows", c)) {
197 deletePreview();
198 lastStatus = (Status)getStatus();
199 setStatus(SetRows);
200 } else if (checkCommand("columnspacing", c)) {
201 deletePreview();
202 lastStatus = (Status)getStatus();
203 setStatus(SetColumnSpacing);
204 } else if (checkCommand("rowspacing", c)) {
205 deletePreview();
206 lastStatus = (Status)getStatus();
207 setStatus(SetRowSpacing);
208 }
209 break;
210
211 case SetAngle: {
212 bool ok;
213 double a = RS_Math::eval(c, &ok);
214 if (ok) {
215 data->angle = RS_Math::deg2rad(a);
216 } else {
217 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
218 }
219 RS_DIALOGFACTORY->requestOptions(this, true, true);
220 setStatus(lastStatus);
221 }
222 break;
223
224 case SetFactor: {
225 bool ok;
226 double f = RS_Math::eval(c, &ok);
227 if (ok) {
228 setFactor(f);
229 } else {
230 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
231 }
232 RS_DIALOGFACTORY->requestOptions(this, true, true);
233 setStatus(lastStatus);
234 }
235 break;
236
237 case SetColumns: {
238 bool ok;
239 int cols = (int)RS_Math::eval(c, &ok);
240 if (ok) {
241 data->cols = cols;
242 } else {
243 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
244 }
245 RS_DIALOGFACTORY->requestOptions(this, true, true);
246 setStatus(lastStatus);
247 }
248 break;
249
250 case SetRows: {
251 bool ok;
252 int rows = (int)RS_Math::eval(c, &ok);
253 if (ok) {
254 data->rows = rows;
255 } else {
256 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
257 }
258 RS_DIALOGFACTORY->requestOptions(this, true, true);
259 setStatus(lastStatus);
260 }
261 break;
262
263 case SetColumnSpacing: {
264 bool ok;
265 double cs = (int)RS_Math::eval(c, &ok);
266 if (ok) {
267 data->spacing.x = cs;
268 } else {
269 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
270 }
271 RS_DIALOGFACTORY->requestOptions(this, true, true);
272 setStatus(lastStatus);
273 }
274 break;
275
276 case SetRowSpacing: {
277 bool ok;
278 int rs = (int)RS_Math::eval(c, &ok);
279 if (ok) {
280 data->spacing.y = rs;
281 } else {
282 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
283 }
284 RS_DIALOGFACTORY->requestOptions(this, true, true);
285 setStatus(lastStatus);
286 }
287 break;
288
289 default:
290 break;
291 }
292 }
293
getAngle() const294 double RS_ActionBlocksInsert::getAngle() const {
295 return data->angle;
296 }
297
setAngle(double a)298 void RS_ActionBlocksInsert::setAngle(double a) {
299 data->angle = a;
300 }
301
getFactor() const302 double RS_ActionBlocksInsert::getFactor() const {
303 return data->scaleFactor.x;
304 }
305
setFactor(double f)306 void RS_ActionBlocksInsert::setFactor(double f) {
307 data->scaleFactor = RS_Vector(f, f);
308 }
309
getColumns() const310 int RS_ActionBlocksInsert::getColumns() const {
311 return data->cols;
312 }
313
setColumns(int c)314 void RS_ActionBlocksInsert::setColumns(int c) {
315 data->cols = c;
316 }
317
getRows() const318 int RS_ActionBlocksInsert::getRows() const {
319 return data->rows;
320 }
321
setRows(int r)322 void RS_ActionBlocksInsert::setRows(int r) {
323 data->rows = r;
324 }
325
getColumnSpacing() const326 double RS_ActionBlocksInsert::getColumnSpacing() const {
327 return data->spacing.x;
328 }
329
setColumnSpacing(double cs)330 void RS_ActionBlocksInsert::setColumnSpacing(double cs) {
331 data->spacing.x = cs;
332 }
333
getRowSpacing() const334 double RS_ActionBlocksInsert::getRowSpacing() const {
335 return data->spacing.y;
336 }
337
setRowSpacing(double rs)338 void RS_ActionBlocksInsert::setRowSpacing(double rs) {
339 data->spacing.y = rs;
340 }
341
getAvailableCommands()342 QStringList RS_ActionBlocksInsert::getAvailableCommands() {
343 QStringList cmd;
344
345 switch (getStatus()) {
346 case SetTargetPoint:
347 cmd += command("angle");
348 cmd += command("factor");
349 ;
350 cmd += command("columns");
351 cmd += command("rows");
352 cmd += command("columnspacing");
353 cmd += command("rowspacing");
354 break;
355 default:
356 break;
357 }
358
359 return cmd;
360 }
361
362
showOptions()363 void RS_ActionBlocksInsert::showOptions() {
364 RS_ActionInterface::showOptions();
365
366 RS_DIALOGFACTORY->requestOptions(this, true);
367 }
368
369
370
hideOptions()371 void RS_ActionBlocksInsert::hideOptions() {
372 RS_ActionInterface::hideOptions();
373
374 RS_DIALOGFACTORY->requestOptions(this, false);
375 }
376
377
updateMouseButtonHints()378 void RS_ActionBlocksInsert::updateMouseButtonHints() {
379 switch (getStatus()) {
380 case SetTargetPoint:
381 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify reference point"),
382 tr("Cancel"));
383 break;
384 case SetAngle:
385 RS_DIALOGFACTORY->updateMouseWidget(tr("Enter angle:"),
386 "");
387 break;
388 case SetFactor:
389 RS_DIALOGFACTORY->updateMouseWidget(tr("Enter factor:"),
390 "");
391 break;
392 case SetColumns:
393 RS_DIALOGFACTORY->updateMouseWidget(tr("Enter columns:"),
394 "");
395 break;
396 case SetRows:
397 RS_DIALOGFACTORY->updateMouseWidget(tr("Enter rows:"),
398 "");
399 break;
400 case SetColumnSpacing:
401 RS_DIALOGFACTORY->updateMouseWidget(tr("Enter column spacing:"),
402 "");
403 break;
404 case SetRowSpacing:
405 RS_DIALOGFACTORY->updateMouseWidget(tr("Enter row spacing:"),
406 "");
407 break;
408 default:
409 RS_DIALOGFACTORY->updateMouseWidget();
410 break;
411 }
412 }
413
414
415
updateMouseCursor()416 void RS_ActionBlocksInsert::updateMouseCursor() {
417 graphicView->setMouseCursor(RS2::CadCursor);
418 }
419
420 // EOF
421