1 /************************************************************************
2 **
3 ** @file undogroup.cpp
4 ** @author Roman Telezhynskyi <dismine(at)gmail.com>
5 ** @date 18 3, 2020
6 **
7 ** @brief
8 ** @copyright
9 ** This source code is part of the Valentina project, a pattern making
10 ** program, whose allow create and modeling patterns of clothing.
11 ** Copyright (C) 2020 Valentina project
12 ** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
13 **
14 ** Valentina is free software: you can redistribute it and/or modify
15 ** it under the terms of the GNU General Public License as published by
16 ** the Free Software Foundation, either version 3 of the License, or
17 ** (at your option) any later version.
18 **
19 ** Valentina is distributed in the hope that it will be useful,
20 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 ** GNU General Public License for more details.
23 **
24 ** You should have received a copy of the GNU General Public License
25 ** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
26 **
27 *************************************************************************/
28
29 #include "undogroup.h"
30
31 #include <QDomNode>
32 #include <QDomNodeList>
33
34 #include "../vmisc/vabstractvalapplication.h"
35 #include "../vmisc/def.h"
36 #include "../vwidgets/vmaingraphicsview.h"
37 #include "../ifc/xml/vabstractpattern.h"
38 #include "vundocommand.h"
39 #include "../vtools/tools/vdatatool.h"
40
41 //AddGroup
42 //---------------------------------------------------------------------------------------------------------------------
AddGroup(const QDomElement & xml,VAbstractPattern * doc,QUndoCommand * parent)43 AddGroup::AddGroup(const QDomElement &xml, VAbstractPattern *doc, QUndoCommand *parent)
44 : VUndoCommand(xml, doc, parent), nameActivDraw(doc->GetNameActivPP())
45 {
46 setText(tr("add group"));
47 nodeId = doc->GetParametrId(xml);
48 }
49
50 //---------------------------------------------------------------------------------------------------------------------
undo()51 void AddGroup::undo()
52 {
53 qCDebug(vUndo, "Undo.");
54
55 doc->ChangeActivPP(nameActivDraw);//Without this user will not see this change
56
57 QDomElement groups = doc->CreateGroups();
58 if (not groups.isNull())
59 {
60 QDomElement group = doc->elementById(nodeId, VAbstractPattern::TagGroup);
61 if (group.isElement())
62 {
63 group.setAttribute(VAbstractPattern::AttrVisible, trueStr);
64 doc->ParseGroups(groups);
65 if (groups.removeChild(group).isNull())
66 {
67 qCDebug(vUndo, "Can't delete group.");
68 return;
69 }
70 emit UpdateGroups();
71 }
72 else
73 {
74 if (groups.childNodes().isEmpty())
75 {
76 QDomNode parent = groups.parentNode();
77 parent.removeChild(groups);
78 }
79
80 qCDebug(vUndo, "Can't get group by id = %u.", nodeId);
81 return;
82 }
83 }
84 else
85 {
86 qCDebug(vUndo, "Can't get tag Groups.");
87 return;
88 }
89
90 VMainGraphicsView::NewSceneRect(VAbstractValApplication::VApp()->getCurrentScene(),
91 VAbstractValApplication::VApp()->getSceneView());
92 if (VAbstractValApplication::VApp()->GetDrawMode() == Draw::Calculation)
93 {
94 emit doc->SetCurrentPP(nameActivDraw);//Return current pattern piece after undo
95 }
96 }
97
98 //---------------------------------------------------------------------------------------------------------------------
redo()99 void AddGroup::redo()
100 {
101 qCDebug(vUndo, "Redo.");
102
103 doc->ChangeActivPP(nameActivDraw);//Without this user will not see this change
104
105 QDomElement groups = doc->CreateGroups();
106 if (not groups.isNull())
107 {
108 groups.appendChild(xml);
109 doc->ParseGroups(groups);
110 emit UpdateGroups();
111 }
112 else
113 {
114 qCDebug(vUndo, "Can't get tag Groups.");
115 return;
116 }
117
118 VMainGraphicsView::NewSceneRect(VAbstractValApplication::VApp()->getCurrentScene(),
119 VAbstractValApplication::VApp()->getSceneView());
120 }
121
122 //RenameGroup
123 //---------------------------------------------------------------------------------------------------------------------
RenameGroup(VAbstractPattern * doc,quint32 id,const QString & name,QUndoCommand * parent)124 RenameGroup::RenameGroup(VAbstractPattern *doc, quint32 id, const QString &name, QUndoCommand *parent)
125 : VUndoCommand(QDomElement(), doc, parent),
126 newName(name)
127 {
128 setText(tr("rename group"));
129 nodeId = id;
130 oldName = doc->GetGroupName(nodeId);
131 }
132
133 //---------------------------------------------------------------------------------------------------------------------
undo()134 void RenameGroup::undo()
135 {
136 qCDebug(vUndo, "Undo.");
137 doc->SetGroupName(nodeId, oldName);
138 emit UpdateGroups();
139 emit doc->UpdateToolTip();
140 }
141
142 //---------------------------------------------------------------------------------------------------------------------
redo()143 void RenameGroup::redo()
144 {
145 qCDebug(vUndo, "Redo.");
146
147 doc->SetGroupName(nodeId, newName);
148 emit UpdateGroups();
149 emit doc->UpdateToolTip();
150 }
151
152 //ChangeGroupOptions
153 //---------------------------------------------------------------------------------------------------------------------
ChangeGroupOptions(VAbstractPattern * doc,quint32 id,const QString & name,const QStringList & tags,QUndoCommand * parent)154 ChangeGroupOptions::ChangeGroupOptions(VAbstractPattern *doc, quint32 id, const QString &name, const QStringList &tags,
155 QUndoCommand *parent)
156 : VUndoCommand(QDomElement(), doc, parent),
157 newName(name),
158 newTags(tags)
159 {
160 setText(tr("rename group"));
161 nodeId = id;
162 oldName = doc->GetGroupName(nodeId);
163 oldTags = doc->GetGroupTags(nodeId);
164 }
165
166 //---------------------------------------------------------------------------------------------------------------------
undo()167 void ChangeGroupOptions::undo()
168 {
169 qCDebug(vUndo, "Undo.");
170 doc->SetGroupName(nodeId, oldName);
171 doc->SetGroupTags(nodeId, oldTags);
172 emit UpdateGroups();
173 emit doc->UpdateToolTip();
174 }
175
176 //---------------------------------------------------------------------------------------------------------------------
redo()177 void ChangeGroupOptions::redo()
178 {
179 qCDebug(vUndo, "Redo.");
180 doc->SetGroupName(nodeId, newName);
181 doc->SetGroupTags(nodeId, newTags);
182 emit UpdateGroups();
183 emit doc->UpdateToolTip();
184 }
185
186 //AddItemToGroup
187 //---------------------------------------------------------------------------------------------------------------------
AddItemToGroup(const QDomElement & xml,VAbstractPattern * doc,quint32 groupId,QUndoCommand * parent)188 AddItemToGroup::AddItemToGroup(const QDomElement &xml, VAbstractPattern *doc, quint32 groupId, QUndoCommand *parent)
189 : VUndoCommand(xml, doc, parent), nameActivDraw(doc->GetNameActivPP())
190 {
191 setText(tr("Add item to group"));
192 nodeId = groupId;
193 }
194
195 //---------------------------------------------------------------------------------------------------------------------
undo()196 void AddItemToGroup::undo()
197 {
198 qCDebug(vUndo, "Undo the add item to group");
199 performUndoRedo(true);
200 }
201
202 //---------------------------------------------------------------------------------------------------------------------
redo()203 void AddItemToGroup::redo()
204 {
205 qCDebug(vUndo, "Redo the add item to group");
206 performUndoRedo(false);
207 }
208
209 //---------------------------------------------------------------------------------------------------------------------
performUndoRedo(bool isUndo)210 void AddItemToGroup::performUndoRedo(bool isUndo)
211 {
212 doc->ChangeActivPP(nameActivDraw);//Without this user will not see this change
213
214 QDomElement group = doc->elementById(nodeId, VAbstractPattern::TagGroup);
215 if (group.isElement())
216 {
217 if(isUndo)
218 {
219 if (group.removeChild(xml).isNull())
220 {
221 qCDebug(vUndo, "Can't delete item.");
222 return;
223 }
224
225 // set the item visible. Because if the undo is done when unvisible and it's not in any group after the
226 // undo, it stays unvisible until the entire drawing is completly rerendered.
227 quint32 objectId = doc->GetParametrUInt(xml, QStringLiteral("object"), NULL_ID_STR);
228 quint32 toolId = doc->GetParametrUInt(xml, QStringLiteral("tool"), NULL_ID_STR);
229 VDataTool* tool = VAbstractPattern::getTool(toolId);
230 tool->GroupVisibility(objectId,true);
231 }
232 else // is redo
233 {
234
235 if (group.appendChild(xml).isNull())
236 {
237 qCDebug(vUndo, "Can't add item.");
238 return;
239 }
240 }
241
242 doc->SetModified(true);
243 emit VAbstractValApplication::VApp()->getCurrentDocument()->patternChanged(false);
244
245 QDomElement groups = doc->CreateGroups();
246 if (not groups.isNull())
247 {
248 doc->ParseGroups(groups);
249 } else
250 {
251 qCDebug(vUndo, "Can't get tag Groups.");
252 return;
253 }
254
255 emit UpdateGroups();
256 }
257 else
258 {
259 qCDebug(vUndo, "Can't get group by id = %u.", nodeId);
260 return;
261 }
262
263 VMainGraphicsView::NewSceneRect(VAbstractValApplication::VApp()->getCurrentScene(),
264 VAbstractValApplication::VApp()->getSceneView());
265 if (VAbstractValApplication::VApp()->GetDrawMode() == Draw::Calculation)
266 {
267 emit doc->SetCurrentPP(nameActivDraw);//Return current pattern piece after undo
268 }
269 }
270
271 //RemoveItemFromGroup
272 //---------------------------------------------------------------------------------------------------------------------
RemoveItemFromGroup(const QDomElement & xml,VAbstractPattern * doc,quint32 groupId,QUndoCommand * parent)273 RemoveItemFromGroup::RemoveItemFromGroup(const QDomElement &xml, VAbstractPattern *doc, quint32 groupId,
274 QUndoCommand *parent)
275 : VUndoCommand(xml, doc, parent), nameActivDraw(doc->GetNameActivPP())
276 {
277 setText(tr("Remove item from group"));
278 nodeId = groupId;
279 }
280
281 //---------------------------------------------------------------------------------------------------------------------
undo()282 void RemoveItemFromGroup::undo()
283 {
284 qCDebug(vUndo, "Undo the remove item from group");
285 performUndoRedo(true);
286 }
287
288 //---------------------------------------------------------------------------------------------------------------------
redo()289 void RemoveItemFromGroup::redo()
290 {
291 qCDebug(vUndo, "Redo the add item to group");
292 performUndoRedo(false);
293 }
294
295 //---------------------------------------------------------------------------------------------------------------------
performUndoRedo(bool isUndo)296 void RemoveItemFromGroup::performUndoRedo(bool isUndo)
297 {
298 doc->ChangeActivPP(nameActivDraw);//Without this user will not see this change
299
300 QDomElement group = doc->elementById(nodeId, VAbstractPattern::TagGroup);
301 if (group.isElement())
302 {
303 if(isUndo)
304 {
305 if (group.appendChild(xml).isNull())
306 {
307 qCDebug(vUndo, "Can't add the item.");
308 return;
309 }
310 }
311 else // is redo
312 {
313 if (group.removeChild(xml).isNull())
314 {
315 qCDebug(vUndo, "Can't delete item.");
316 return;
317 }
318
319 // set the item visible. Because if the undo is done when unvisibile and it's not in any group after the
320 // undo, it stays unvisible until the entire drawing is completly rerendered.
321 quint32 objectId = doc->GetParametrUInt(xml, QStringLiteral("object"), NULL_ID_STR);
322 quint32 toolId = doc->GetParametrUInt(xml, QStringLiteral("tool"), NULL_ID_STR);
323 VDataTool* tool = VAbstractPattern::getTool(toolId);
324 tool->GroupVisibility(objectId,true);
325 }
326
327 doc->SetModified(true);
328 emit VAbstractValApplication::VApp()->getCurrentDocument()->patternChanged(false);
329
330 QDomElement groups = doc->CreateGroups();
331 if (not groups.isNull())
332 {
333 doc->ParseGroups(groups);
334 } else
335 {
336 qCDebug(vUndo, "Can't get tag Groups.");
337 return;
338 }
339
340 emit UpdateGroups();
341 }
342 else
343 {
344 qCDebug(vUndo, "Can't get group by id = %u.", nodeId);
345 return;
346 }
347
348 VMainGraphicsView::NewSceneRect(VAbstractValApplication::VApp()->getCurrentScene(),
349 VAbstractValApplication::VApp()->getSceneView());
350
351 if (VAbstractValApplication::VApp()->GetDrawMode() == Draw::Calculation)
352 {
353 emit doc->SetCurrentPP(nameActivDraw);//Return current pattern piece after undo
354 }
355 }
356
357 //ChangeGroupVisibility
358 //---------------------------------------------------------------------------------------------------------------------
ChangeGroupVisibility(VAbstractPattern * doc,vidtype id,bool visible,QUndoCommand * parent)359 ChangeGroupVisibility::ChangeGroupVisibility(VAbstractPattern *doc, vidtype id, bool visible, QUndoCommand *parent)
360 : VUndoCommand(QDomElement(), doc, parent),
361 m_newVisibility(visible),
362 m_nameActivDraw(doc->GetNameActivPP())
363 {
364 setText(tr("change group visibility"));
365 nodeId = id;
366 QDomElement group = doc->elementById(nodeId, VAbstractPattern::TagGroup);
367 if (group.isElement())
368 {
369 m_oldVisibility = doc->GetParametrBool(group, VAbstractPattern::AttrVisible, trueStr);
370 }
371 else
372 {
373 qDebug("Can't get group by id = %u.", id);
374 }
375 }
376
377 //---------------------------------------------------------------------------------------------------------------------
undo()378 void ChangeGroupVisibility::undo()
379 {
380 qCDebug(vUndo, "Undo.");
381
382 Do(m_oldVisibility);
383 }
384
385 //---------------------------------------------------------------------------------------------------------------------
redo()386 void ChangeGroupVisibility::redo()
387 {
388 qCDebug(vUndo, "Redo.");
389
390 Do(m_newVisibility);
391 }
392
393 //---------------------------------------------------------------------------------------------------------------------
Do(bool visible)394 void ChangeGroupVisibility::Do(bool visible)
395 {
396 doc->ChangeActivPP(m_nameActivDraw);//Without this user will not see this change
397
398 QDomElement group = doc->elementById(nodeId, VAbstractPattern::TagGroup);
399 if (group.isElement())
400 {
401 doc->SetAttribute(group, VAbstractPattern::AttrVisible, visible);
402
403 QDomElement groups = doc->CreateGroups();
404 if (not groups.isNull())
405 {
406 doc->ParseGroups(groups);
407 }
408
409 emit UpdateGroup(nodeId, visible);
410
411 VMainGraphicsView::NewSceneRect(VAbstractValApplication::VApp()->getCurrentScene(),
412 VAbstractValApplication::VApp()->getSceneView());
413 }
414 else
415 {
416 qDebug("Can't get group by id = %u.", nodeId);
417 }
418 }
419
420 //ChangeMultipleGroupsVisibility
421 //---------------------------------------------------------------------------------------------------------------------
ChangeMultipleGroupsVisibility(VAbstractPattern * doc,const QVector<vidtype> & groups,bool visible,QUndoCommand * parent)422 ChangeMultipleGroupsVisibility::ChangeMultipleGroupsVisibility(VAbstractPattern *doc, const QVector<vidtype> &groups,
423 bool visible, QUndoCommand *parent)
424 : VUndoCommand(QDomElement(), doc, parent),
425 m_groups(groups),
426 m_newVisibility(visible),
427 m_nameActivDraw(doc->GetNameActivPP())
428 {
429 setText(tr("change multiple groups visibility"));
430
431 for(auto & groupId : m_groups)
432 {
433 QDomElement group = doc->elementById(groupId, VAbstractPattern::TagGroup);
434 if (group.isElement())
435 {
436 m_oldVisibility.insert(groupId, doc->GetParametrBool(group, VAbstractPattern::AttrVisible, trueStr));
437 }
438 else
439 {
440 qDebug("Can't get group by id = %u.", groupId);
441 }
442 }
443
444 }
445
446 //---------------------------------------------------------------------------------------------------------------------
undo()447 void ChangeMultipleGroupsVisibility::undo()
448 {
449 qCDebug(vUndo, "Undo.");
450
451 doc->ChangeActivPP(m_nameActivDraw);//Without this user will not see this change
452
453 QMap<vidtype, bool> groupsState;
454
455 QMap<vidtype, bool>::const_iterator i = m_oldVisibility.constBegin();
456 while (i != m_oldVisibility.constEnd())
457 {
458 QDomElement group = doc->elementById(i.key(), VAbstractPattern::TagGroup);
459 if (group.isElement())
460 {
461 doc->SetAttribute(group, VAbstractPattern::AttrVisible, i.value());
462 groupsState.insert(i.key(), i.value());
463 }
464 else
465 {
466 qDebug("Can't get group by id = %u.", i.key());
467 }
468 ++i;
469 }
470
471 if (not groupsState.isEmpty())
472 {
473 QDomElement groups = doc->CreateGroups();
474 if (not groups.isNull())
475 {
476 doc->ParseGroups(groups);
477 }
478
479 VMainGraphicsView::NewSceneRect(VAbstractValApplication::VApp()->getCurrentScene(),
480 VAbstractValApplication::VApp()->getSceneView());
481
482 emit UpdateMultipleGroups(groupsState);
483 }
484 }
485
486 //---------------------------------------------------------------------------------------------------------------------
redo()487 void ChangeMultipleGroupsVisibility::redo()
488 {
489 qCDebug(vUndo, "ChangeMultipleGroupsVisibility::redo");
490
491 doc->ChangeActivPP(m_nameActivDraw);//Without this user will not see this change
492
493 QMap<vidtype, bool> groupsState;
494
495 for (auto& groupId : m_groups)
496 {
497 QDomElement group = doc->elementById(groupId, VAbstractPattern::TagGroup);
498 if (group.isElement())
499 {
500 doc->SetAttribute(group, VAbstractPattern::AttrVisible, m_newVisibility);
501 groupsState.insert(groupId, m_newVisibility);
502 }
503 else
504 {
505 qDebug("Can't get group by id = %u.", groupId);
506 }
507 }
508
509 if (not groupsState.isEmpty())
510 {
511 QDomElement groups = doc->CreateGroups();
512 if (not groups.isNull())
513 {
514 doc->ParseGroups(groups);
515 }
516
517 VMainGraphicsView::NewSceneRect(VAbstractValApplication::VApp()->getCurrentScene(),
518 VAbstractValApplication::VApp()->getSceneView());
519
520 emit UpdateMultipleGroups(groupsState);
521 }
522 }
523
524 //DelGroup
525 //---------------------------------------------------------------------------------------------------------------------
DelGroup(VAbstractPattern * doc,quint32 id,QUndoCommand * parent)526 DelGroup::DelGroup(VAbstractPattern *doc, quint32 id, QUndoCommand *parent)
527 : VUndoCommand(QDomElement(), doc, parent), nameActivDraw(doc->GetNameActivPP())
528 {
529 setText(tr("delete group"));
530 nodeId = id;
531 xml = doc->CloneNodeById(nodeId);
532 }
533
534 //---------------------------------------------------------------------------------------------------------------------
undo()535 void DelGroup::undo()
536 {
537 qCDebug(vUndo, "Undo.");
538
539 if (VAbstractValApplication::VApp()->GetDrawMode() == Draw::Calculation)
540 {
541 emit doc->SetCurrentPP(nameActivDraw);//Without this user will not see this change
542 }
543
544 QDomElement groups = doc->CreateGroups();
545 if (not groups.isNull())
546 {
547 groups.appendChild(xml);
548 doc->ParseGroups(groups);
549 emit UpdateGroups();
550 }
551 else
552 {
553 qCDebug(vUndo, "Can't get tag Groups.");
554 return;
555 }
556
557 VMainGraphicsView::NewSceneRect(VAbstractValApplication::VApp()->getCurrentScene(),
558 VAbstractValApplication::VApp()->getSceneView());
559 }
560
561 //---------------------------------------------------------------------------------------------------------------------
redo()562 void DelGroup::redo()
563 {
564 qCDebug(vUndo, "Redo.");
565
566 if (VAbstractValApplication::VApp()->GetDrawMode() == Draw::Calculation)
567 {//Keep first!
568 emit doc->SetCurrentPP(nameActivDraw);//Without this user will not see this change
569 }
570 QDomElement groups = doc->CreateGroups();
571 if (not groups.isNull())
572 {
573 QDomElement group = doc->elementById(nodeId, VAbstractPattern::TagGroup);
574 if (group.isElement())
575 {
576 group.setAttribute(VAbstractPattern::AttrVisible, trueStr);
577 doc->ParseGroups(groups);
578 if (groups.removeChild(group).isNull())
579 {
580 qCDebug(vUndo, "Can't delete group.");
581 return;
582 }
583 emit UpdateGroups();
584
585 if (groups.childNodes().isEmpty())
586 {
587 QDomNode parent = groups.parentNode();
588 parent.removeChild(groups);
589 }
590 }
591 else
592 {
593 qCDebug(vUndo, "Can't get group by id = %u.", nodeId);
594 return;
595 }
596 }
597 else
598 {
599 qCDebug(vUndo, "Can't get tag Groups.");
600 return;
601 }
602
603 VMainGraphicsView::NewSceneRect(VAbstractValApplication::VApp()->getCurrentScene(),
604 VAbstractValApplication::VApp()->getSceneView());
605 }
606