1 /*
2  * Copyright (C) 2010-2015 by Stephen Allewell
3  * steve.allewell@gmail.com
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  */
10 
11 
12 #include "Commands.h"
13 
14 #include <QApplication>
15 #include <QClipboard>
16 #include <QMimeData>
17 
18 #include <KLocalizedString>
19 
20 #include "BackgroundImage.h"
21 #include "Document.h"
22 #include "Editor.h"
23 #include "Floss.h"
24 #include "FlossScheme.h"
25 #include "MainWindow.h"
26 #include "Palette.h"
27 #include "Preview.h"
28 #include "SchemeManager.h"
29 #include "StitchData.h"
30 
31 
FilePropertiesCommand(Document * document)32 FilePropertiesCommand::FilePropertiesCommand(Document *document)
33     :   QUndoCommand(i18n("File Properties")),
34         m_document(document)
35 {
36 }
37 
38 
redo()39 void FilePropertiesCommand::redo()
40 {
41     QUndoCommand::redo();
42     m_document->editor()->readDocumentSettings();
43     m_document->preview()->readDocumentSettings();
44     m_document->palette()->update();
45 }
46 
47 
undo()48 void FilePropertiesCommand::undo()
49 {
50     QUndoCommand::undo();
51     m_document->editor()->readDocumentSettings();
52     m_document->preview()->readDocumentSettings();
53     m_document->palette()->update();
54 }
55 
56 
ImportImageCommand(Document * document)57 ImportImageCommand::ImportImageCommand(Document *document)
58     :   QUndoCommand(i18n("Import Image")),
59         m_document(document)
60 {
61 }
62 
63 
redo()64 void ImportImageCommand::redo()
65 {
66     QUndoCommand::redo();
67     m_document->editor()->readDocumentSettings();
68     m_document->preview()->readDocumentSettings();
69     m_document->palette()->update();
70 }
71 
72 
undo()73 void ImportImageCommand::undo()
74 {
75     QUndoCommand::undo();
76     m_document->editor()->readDocumentSettings();
77     m_document->preview()->readDocumentSettings();
78     m_document->palette()->update();
79 }
80 
81 
PaintStitchesCommand(Document * document)82 PaintStitchesCommand::PaintStitchesCommand(Document *document)
83     :   QUndoCommand(i18n("Paint Stitches")),
84         m_document(document)
85 {
86 }
87 
88 
redo()89 void PaintStitchesCommand::redo()
90 {
91     QUndoCommand::redo();
92     m_document->editor()->drawContents();
93     m_document->preview()->drawContents();
94 }
95 
96 
undo()97 void PaintStitchesCommand::undo()
98 {
99     QUndoCommand::undo();
100     m_document->editor()->drawContents();
101     m_document->preview()->drawContents();
102 }
103 
104 
PaintKnotsCommand(Document * document)105 PaintKnotsCommand::PaintKnotsCommand(Document *document)
106     :   QUndoCommand(i18n("Paint Knots")),
107         m_document(document)
108 {
109 }
110 
111 
redo()112 void PaintKnotsCommand::redo()
113 {
114     QUndoCommand::redo();
115     m_document->editor()->drawContents();
116     m_document->preview()->drawContents();
117 }
118 
119 
undo()120 void PaintKnotsCommand::undo()
121 {
122     QUndoCommand::undo();
123     m_document->editor()->drawContents();
124     m_document->preview()->drawContents();
125 }
126 
127 
DrawLineCommand(Document * document)128 DrawLineCommand::DrawLineCommand(Document *document)
129     :   QUndoCommand(i18n("Draw Line")),
130         m_document(document)
131 {
132 }
133 
134 
redo()135 void DrawLineCommand::redo()
136 {
137     QUndoCommand::redo();
138     m_document->editor()->drawContents();
139     m_document->preview()->drawContents();
140 }
141 
142 
undo()143 void DrawLineCommand::undo()
144 {
145     QUndoCommand::undo();
146     m_document->editor()->drawContents();
147     m_document->preview()->drawContents();
148 }
149 
150 
EraseStitchesCommand(Document * document)151 EraseStitchesCommand::EraseStitchesCommand(Document *document)
152     :   QUndoCommand(i18n("Erase Stitches")),
153         m_document(document)
154 {
155 }
156 
157 
redo()158 void EraseStitchesCommand::redo()
159 {
160     QUndoCommand::redo();
161     m_document->editor()->drawContents();
162     m_document->preview()->drawContents();
163 }
164 
165 
undo()166 void EraseStitchesCommand::undo()
167 {
168     QUndoCommand::undo();
169     m_document->editor()->drawContents();
170     m_document->preview()->drawContents();
171 }
172 
173 
DrawRectangleCommand(Document * document)174 DrawRectangleCommand::DrawRectangleCommand(Document *document)
175     :   QUndoCommand(i18n("Draw Rectangle")),
176         m_document(document)
177 {
178 }
179 
180 
redo()181 void DrawRectangleCommand::redo()
182 {
183     QUndoCommand::redo();
184     m_document->editor()->drawContents();
185     m_document->preview()->drawContents();
186 }
187 
188 
undo()189 void DrawRectangleCommand::undo()
190 {
191     QUndoCommand::undo();
192     m_document->editor()->drawContents();
193     m_document->preview()->drawContents();
194 }
195 
196 
FillRectangleCommand(Document * document)197 FillRectangleCommand::FillRectangleCommand(Document *document)
198     :   QUndoCommand(i18n("Fill Rectangle")),
199         m_document(document)
200 {
201 }
202 
203 
redo()204 void FillRectangleCommand::redo()
205 {
206     QUndoCommand::redo();
207     m_document->editor()->drawContents();
208     m_document->preview()->drawContents();
209 }
210 
211 
undo()212 void FillRectangleCommand::undo()
213 {
214     QUndoCommand::undo();
215     m_document->editor()->drawContents();
216     m_document->preview()->drawContents();
217 }
218 
219 
220 
DrawEllipseCommand(Document * document)221 DrawEllipseCommand::DrawEllipseCommand(Document *document)
222     :   QUndoCommand(i18n("Draw Ellipse")),
223         m_document(document)
224 {
225 }
226 
227 
redo()228 void DrawEllipseCommand::redo()
229 {
230     QUndoCommand::redo();
231     m_document->editor()->drawContents();
232     m_document->preview()->drawContents();
233 }
234 
235 
undo()236 void DrawEllipseCommand::undo()
237 {
238     QUndoCommand::undo();
239     m_document->editor()->drawContents();
240     m_document->preview()->drawContents();
241 }
242 
243 
FillEllipseCommand(Document * document)244 FillEllipseCommand::FillEllipseCommand(Document *document)
245     :   QUndoCommand(i18n("Fill Ellipse")),
246         m_document(document)
247 {
248 }
249 
250 
redo()251 void FillEllipseCommand::redo()
252 {
253     QUndoCommand::redo();
254     m_document->editor()->drawContents();
255     m_document->preview()->drawContents();
256 }
257 
258 
undo()259 void FillEllipseCommand::undo()
260 {
261     QUndoCommand::undo();
262     m_document->editor()->drawContents();
263     m_document->preview()->drawContents();
264 }
265 
266 
FillPolygonCommand(Document * document)267 FillPolygonCommand::FillPolygonCommand(Document *document)
268     :   QUndoCommand(i18n("Fill Polygon")),
269         m_document(document)
270 {
271 }
272 
273 
redo()274 void FillPolygonCommand::redo()
275 {
276     QUndoCommand::redo();
277     m_document->editor()->drawContents();
278     m_document->preview()->drawContents();
279 }
280 
281 
undo()282 void FillPolygonCommand::undo()
283 {
284     QUndoCommand::undo();
285     m_document->editor()->drawContents();
286     m_document->preview()->drawContents();
287 }
288 
289 
AddStitchCommand(Document * document,const QPoint & location,Stitch::Type type,int colorIndex,QUndoCommand * parent)290 AddStitchCommand::AddStitchCommand(Document *document, const QPoint &location, Stitch::Type type, int colorIndex, QUndoCommand *parent)
291     :   QUndoCommand(i18n("Add Stitch"), parent),
292         m_document(document),
293         m_cell(location),
294         m_type(type),
295         m_colorIndex(colorIndex),
296         m_original(nullptr)
297 {
298 }
299 
300 
~AddStitchCommand()301 AddStitchCommand::~AddStitchCommand()
302 {
303     delete m_original;
304 }
305 
306 
redo()307 void AddStitchCommand::redo()
308 {
309     m_original = m_document->pattern()->stitches().stitchQueueAt(m_cell);
310 
311     if (m_original) {
312         m_document->pattern()->stitches().replaceStitchQueueAt(m_cell, new StitchQueue(m_original));
313     }
314 
315     m_document->pattern()->stitches().addStitch(m_cell, m_type, m_colorIndex);
316 }
317 
318 
undo()319 void AddStitchCommand::undo()
320 {
321     delete m_document->pattern()->stitches().takeStitchQueueAt(m_cell);
322 
323     if (m_original) {
324         m_document->pattern()->stitches().replaceStitchQueueAt(m_cell, m_original);
325         m_original = nullptr;
326     }
327 }
328 
329 
DeleteStitchCommand(Document * document,const QPoint & cell,Stitch::Type type,int colorIndex,QUndoCommand * parent)330 DeleteStitchCommand::DeleteStitchCommand(Document *document, const QPoint &cell, Stitch::Type type, int colorIndex, QUndoCommand *parent)
331     :   QUndoCommand(i18n("Delete Stitches"), parent),
332         m_document(document),
333         m_cell(cell),
334         m_type(type),
335         m_colorIndex(colorIndex),
336         m_original(nullptr)
337 {
338 }
339 
340 
~DeleteStitchCommand()341 DeleteStitchCommand::~DeleteStitchCommand()
342 {
343     delete m_original;
344 }
345 
346 
redo()347 void DeleteStitchCommand::redo()
348 {
349     m_original = m_document->pattern()->stitches().stitchQueueAt(m_cell);
350 
351     if (m_original) {
352         m_original = m_document->pattern()->stitches().replaceStitchQueueAt(m_cell, new StitchQueue(m_original));
353         m_document->pattern()->stitches().deleteStitch(m_cell, m_type, m_colorIndex);
354     }
355 }
356 
357 
undo()358 void DeleteStitchCommand::undo()
359 {
360     if (m_original) {
361         delete m_document->pattern()->stitches().replaceStitchQueueAt(m_cell, m_original);
362         m_original = nullptr;
363     }
364 }
365 
366 
AddBackstitchCommand(Document * document,const QPoint & start,const QPoint & end,int colorIndex)367 AddBackstitchCommand::AddBackstitchCommand(Document *document, const QPoint &start, const QPoint &end, int colorIndex)
368     :   QUndoCommand(i18n("Add Backstitch")),
369         m_document(document),
370         m_start(start),
371         m_end(end),
372         m_colorIndex(colorIndex)
373 {
374 }
375 
376 
redo()377 void AddBackstitchCommand::redo()
378 {
379     m_document->pattern()->stitches().addBackstitch(m_start, m_end, m_colorIndex);
380     m_document->editor()->drawContents();
381     m_document->preview()->drawContents();
382 }
383 
384 
undo()385 void AddBackstitchCommand::undo()
386 {
387     delete m_document->pattern()->stitches().takeBackstitch(m_start, m_end, m_colorIndex);
388     m_document->editor()->drawContents();
389     m_document->preview()->drawContents();
390 }
391 
392 
DeleteBackstitchCommand(Document * document,const QPoint & start,const QPoint & end,int colorIndex)393 DeleteBackstitchCommand::DeleteBackstitchCommand(Document *document, const QPoint &start, const QPoint &end, int colorIndex)
394     :   QUndoCommand(i18n("Delete Backstitch")),
395         m_document(document),
396         m_start(start),
397         m_end(end),
398         m_colorIndex(colorIndex),
399         m_backstitch(nullptr)
400 {
401 }
402 
403 
~DeleteBackstitchCommand()404 DeleteBackstitchCommand::~DeleteBackstitchCommand()
405 {
406     delete m_backstitch;
407 }
408 
409 
redo()410 void DeleteBackstitchCommand::redo()
411 {
412     m_backstitch = m_document->pattern()->stitches().takeBackstitch(m_start, m_end, m_colorIndex);
413     m_document->editor()->drawContents();
414     m_document->preview()->drawContents();
415 }
416 
417 
undo()418 void DeleteBackstitchCommand::undo()
419 {
420     m_document->pattern()->stitches().addBackstitch(m_backstitch);
421     m_backstitch = nullptr;
422     m_document->editor()->drawContents();
423     m_document->preview()->drawContents();
424 }
425 
426 
AddKnotCommand(Document * document,const QPoint & snap,int colorIndex,QUndoCommand * parent)427 AddKnotCommand::AddKnotCommand(Document *document, const QPoint &snap, int colorIndex, QUndoCommand *parent)
428     :   QUndoCommand(i18n("Add Knot"), parent),
429         m_document(document),
430         m_snap(snap),
431         m_colorIndex(colorIndex)
432 {
433 }
434 
435 
redo()436 void AddKnotCommand::redo()
437 {
438     m_document->pattern()->stitches().addFrenchKnot(m_snap, m_colorIndex);
439 }
440 
441 
undo()442 void AddKnotCommand::undo()
443 {
444     delete m_document->pattern()->stitches().takeFrenchKnot(m_snap, m_colorIndex);
445 }
446 
447 
DeleteKnotCommand(Document * document,const QPoint & snap,int colorIndex,QUndoCommand * parent)448 DeleteKnotCommand::DeleteKnotCommand(Document *document, const QPoint &snap, int colorIndex, QUndoCommand *parent)
449     :   QUndoCommand(i18n("Delete Knots"), parent),
450         m_document(document),
451         m_snap(snap),
452         m_colorIndex(colorIndex),
453         m_knot(nullptr)
454 {
455 }
456 
457 
~DeleteKnotCommand()458 DeleteKnotCommand::~DeleteKnotCommand()
459 {
460     delete m_knot;
461 }
462 
463 
redo()464 void DeleteKnotCommand::redo()
465 {
466     m_knot = m_document->pattern()->stitches().takeFrenchKnot(m_snap, m_colorIndex);
467 }
468 
469 
undo()470 void DeleteKnotCommand::undo()
471 {
472     m_document->pattern()->stitches().addFrenchKnot(m_knot);
473     m_knot = nullptr;
474 }
475 
476 
SetPropertyCommand(Document * document,const QString & name,const QVariant & value,QUndoCommand * parent)477 SetPropertyCommand::SetPropertyCommand(Document *document, const QString &name, const QVariant &value, QUndoCommand *parent)
478     :   QUndoCommand(i18n("Set Property"), parent),
479         m_document(document),
480         m_name(name),
481         m_value(value)
482 {
483 }
484 
485 
redo()486 void SetPropertyCommand::redo()
487 {
488     m_oldValue = m_document->property(m_name);
489     m_document->setProperty(m_name, m_value);
490 }
491 
492 
undo()493 void SetPropertyCommand::undo()
494 {
495     m_document->setProperty(m_name, m_oldValue);
496 }
497 
498 
AddBackgroundImageCommand(Document * document,QSharedPointer<BackgroundImage> backgroundImage,MainWindow * mainWindow)499 AddBackgroundImageCommand::AddBackgroundImageCommand(Document *document, QSharedPointer<BackgroundImage> backgroundImage, MainWindow *mainWindow)
500     :   QUndoCommand(i18n("Add Background Image")),
501         m_document(document),
502         m_backgroundImage(backgroundImage),
503         m_mainWindow(mainWindow)
504 {
505 }
506 
507 
redo()508 void AddBackgroundImageCommand::redo()
509 {
510     m_document->backgroundImages().addBackgroundImage(m_backgroundImage);
511     m_mainWindow->updateBackgroundImageActionLists();
512     m_document->editor()->drawContents();
513 }
514 
515 
undo()516 void AddBackgroundImageCommand::undo()
517 {
518     m_document->backgroundImages().removeBackgroundImage(m_backgroundImage);
519     m_mainWindow->updateBackgroundImageActionLists();
520     m_document->editor()->drawContents();
521 }
522 
523 
FitBackgroundImageCommand(Document * document,QSharedPointer<BackgroundImage> backgroundImage,const QRect & rect)524 FitBackgroundImageCommand::FitBackgroundImageCommand(Document *document, QSharedPointer<BackgroundImage> backgroundImage, const QRect &rect)
525     :   QUndoCommand(i18n("Fit Background to Selection")),
526         m_document(document),
527         m_backgroundImage(backgroundImage),
528         m_rect(rect)
529 {
530 }
531 
532 
redo()533 void FitBackgroundImageCommand::redo()
534 {
535     m_rect = m_document->backgroundImages().fitBackgroundImage(m_backgroundImage, m_rect);
536     m_document->editor()->resetSelectionArea();
537     m_document->editor()->drawContents();
538 }
539 
540 
undo()541 void FitBackgroundImageCommand::undo()
542 {
543     redo(); // same code required
544 }
545 
546 
ShowBackgroundImageCommand(Document * document,QSharedPointer<BackgroundImage> backgroundImage,bool visible)547 ShowBackgroundImageCommand::ShowBackgroundImageCommand(Document *document, QSharedPointer<BackgroundImage> backgroundImage, bool visible)
548     :   QUndoCommand(i18n("Show Background Image")),
549         m_document(document),
550         m_backgroundImage(backgroundImage),
551         m_visible(visible)
552 {
553 }
554 
555 
redo()556 void ShowBackgroundImageCommand::redo()
557 {
558     m_visible = m_document->backgroundImages().showBackgroundImage(m_backgroundImage, m_visible);
559     m_document->editor()->drawContents();
560 }
561 
562 
undo()563 void ShowBackgroundImageCommand::undo()
564 {
565     redo(); // same code required
566 }
567 
568 
RemoveBackgroundImageCommand(Document * document,QSharedPointer<BackgroundImage> backgroundImage,MainWindow * mainWindow)569 RemoveBackgroundImageCommand::RemoveBackgroundImageCommand(Document *document, QSharedPointer<BackgroundImage> backgroundImage, MainWindow *mainWindow)
570     :   QUndoCommand(i18n("Remove Background Image")),
571         m_document(document),
572         m_backgroundImage(backgroundImage),
573         m_mainWindow(mainWindow)
574 {
575 }
576 
577 
~RemoveBackgroundImageCommand()578 RemoveBackgroundImageCommand::~RemoveBackgroundImageCommand()
579 {
580     // TODO resolve ownership of m_backgroundImage
581     // delete m_backgroundImage;
582     // m_backgroundImage may also be deleted by the document, potential for a crash or memory leak
583 }
584 
585 
redo()586 void RemoveBackgroundImageCommand::redo()
587 {
588     m_document->backgroundImages().removeBackgroundImage(m_backgroundImage);
589     m_mainWindow->updateBackgroundImageActionLists();
590 
591     if (m_backgroundImage->isVisible()) {
592         m_document->editor()->drawContents();
593     }
594 }
595 
596 
undo()597 void RemoveBackgroundImageCommand::undo()
598 {
599     m_document->backgroundImages().addBackgroundImage(m_backgroundImage);
600     m_mainWindow->updateBackgroundImageActionLists();
601 
602     if (m_backgroundImage->isVisible()) {
603         m_document->editor()->drawContents();
604     }
605 }
606 
607 
AddDocumentFlossCommand(Document * document,int key,DocumentFloss * documentFloss,QUndoCommand * parent)608 AddDocumentFlossCommand::AddDocumentFlossCommand(Document *document, int key, DocumentFloss *documentFloss, QUndoCommand *parent)
609     :   QUndoCommand(parent),
610         m_document(document),
611         m_key(key),
612         m_documentFloss(documentFloss)
613 {
614 }
615 
616 
redo()617 void AddDocumentFlossCommand::redo()
618 {
619     m_document->pattern()->palette().add(m_key, m_documentFloss);
620 }
621 
622 
undo()623 void AddDocumentFlossCommand::undo()
624 {
625     m_document->pattern()->palette().remove(m_key);
626 }
627 
628 
RemoveDocumentFlossCommand(Document * document,int key,DocumentFloss * documentFloss,QUndoCommand * parent)629 RemoveDocumentFlossCommand::RemoveDocumentFlossCommand(Document *document, int key, DocumentFloss *documentFloss, QUndoCommand *parent)
630     :   QUndoCommand(parent),
631         m_document(document),
632         m_key(key),
633         m_documentFloss(documentFloss)
634 {
635 }
636 
637 
~RemoveDocumentFlossCommand()638 RemoveDocumentFlossCommand::~RemoveDocumentFlossCommand()
639 {
640     delete m_documentFloss;
641 }
642 
643 
redo()644 void RemoveDocumentFlossCommand::redo()
645 {
646     m_document->pattern()->palette().remove(m_key);
647 }
648 
649 
undo()650 void RemoveDocumentFlossCommand::undo()
651 {
652     m_document->pattern()->palette().add(m_key, m_documentFloss);
653 }
654 
655 
ReplaceDocumentFlossCommand(Document * document,int key,DocumentFloss * documentFloss)656 ReplaceDocumentFlossCommand::ReplaceDocumentFlossCommand(Document *document, int key, DocumentFloss *documentFloss)
657     :   QUndoCommand(),
658         m_document(document),
659         m_key(key),
660         m_documentFloss(documentFloss)
661 {
662 }
663 
664 
~ReplaceDocumentFlossCommand()665 ReplaceDocumentFlossCommand::~ReplaceDocumentFlossCommand()
666 {
667     delete m_documentFloss;
668 }
669 
670 
redo()671 void ReplaceDocumentFlossCommand::redo()
672 {
673     m_documentFloss = m_document->pattern()->palette().replace(m_key, m_documentFloss);
674 }
675 
676 
undo()677 void ReplaceDocumentFlossCommand::undo()
678 {
679     redo(); // same code required
680 }
681 
682 
ClearUnusedFlossesCommand(Document * document)683 ClearUnusedFlossesCommand::ClearUnusedFlossesCommand(Document *document)
684     :   QUndoCommand(i18n("Clear Unused Flosses")),
685         m_document(document)
686 {
687 }
688 
689 
redo()690 void ClearUnusedFlossesCommand::redo()
691 {
692     QUndoCommand::redo();
693     m_document->palette()->update();
694 }
695 
696 
undo()697 void ClearUnusedFlossesCommand::undo()
698 {
699     QUndoCommand::undo();
700     m_document->palette()->update();
701 }
702 
703 
ResizeDocumentCommand(Document * document,int width,int height,QUndoCommand * parent)704 ResizeDocumentCommand::ResizeDocumentCommand(Document *document, int width, int height, QUndoCommand *parent)
705     :   QUndoCommand(i18n("Resize Document"), parent),
706         m_document(document),
707         m_width(width),
708         m_height(height)
709 {
710 }
711 
712 
redo()713 void ResizeDocumentCommand::redo()
714 {
715     m_originalWidth = m_document->pattern()->stitches().width();
716     m_originalHeight = m_document->pattern()->stitches().height();
717     QRect extents = m_document->pattern()->stitches().extents();
718     int minx = std::min(extents.left(), m_width - extents.width());
719     m_xOffset = minx - extents.left();
720     int miny = std::min(extents.top(), m_height - extents.height());
721     m_yOffset = miny - extents.top();
722     m_document->pattern()->stitches().movePattern(m_xOffset, m_yOffset);
723     m_document->pattern()->stitches().resize(m_width, m_height);
724 }
725 
726 
undo()727 void ResizeDocumentCommand::undo()
728 {
729     m_document->pattern()->stitches().resize(m_originalWidth, m_originalHeight);
730     m_document->pattern()->stitches().movePattern(-m_xOffset, -m_yOffset);
731 }
732 
733 
CropToPatternCommand(Document * document)734 CropToPatternCommand::CropToPatternCommand(Document *document)
735     :   QUndoCommand(i18n("Crop to Pattern")),
736         m_document(document)
737 {
738 }
739 
740 
redo()741 void CropToPatternCommand::redo()
742 {
743     m_originalWidth = m_document->pattern()->stitches().width();
744     m_originalHeight = m_document->pattern()->stitches().height();
745     QRect extents = m_document->pattern()->stitches().extents();
746     m_xOffset = -extents.left();
747     m_yOffset = -extents.top();
748     m_document->pattern()->stitches().movePattern(m_xOffset, m_yOffset);
749     m_document->pattern()->stitches().resize(extents.width(), extents.height());
750     m_document->editor()->readDocumentSettings();
751     m_document->preview()->readDocumentSettings();
752 }
753 
754 
undo()755 void CropToPatternCommand::undo()
756 {
757     m_document->pattern()->stitches().resize(m_originalWidth, m_originalHeight);
758     m_document->pattern()->stitches().movePattern(-m_xOffset, -m_yOffset);
759     m_document->editor()->readDocumentSettings();
760     m_document->preview()->readDocumentSettings();
761 }
762 
763 
CropToSelectionCommand(Document * document,const QRect & selectionArea)764 CropToSelectionCommand::CropToSelectionCommand(Document *document, const QRect &selectionArea)
765     :   QUndoCommand(i18n("Crop to Selection")),
766         m_document(document),
767         m_selectionArea(selectionArea)
768 {
769 }
770 
771 
redo()772 void CropToSelectionCommand::redo()
773 {
774     QList<Stitch::Type> maskStitches;
775     maskStitches << Stitch::TLQtr << Stitch::TRQtr << Stitch::BLQtr << Stitch::BTHalf << Stitch::TL3Qtr << Stitch::BRQtr
776                  << Stitch::TBHalf << Stitch::TR3Qtr << Stitch::BL3Qtr << Stitch::BR3Qtr << Stitch::Full << Stitch::TLSmallHalf
777                  << Stitch::TRSmallHalf << Stitch::BLSmallHalf << Stitch::BRSmallHalf << Stitch::TLSmallFull << Stitch::TRSmallFull
778                  << Stitch::BLSmallFull << Stitch::BRSmallFull;
779 
780     QDataStream stream(&m_originalPattern, QIODevice::WriteOnly);
781     stream << m_document->pattern()->stitches();
782 
783     Pattern *pattern = m_document->pattern()->copy(m_selectionArea, -1, maskStitches, false, false);
784     m_document->pattern()->stitches().clear();
785     m_document->pattern()->stitches().resize(m_selectionArea.width(), m_selectionArea.height());
786     m_document->pattern()->paste(pattern, QPoint(0, 0), true);
787     delete pattern;
788 
789     m_document->editor()->readDocumentSettings();
790     m_document->preview()->readDocumentSettings();
791 }
792 
793 
undo()794 void CropToSelectionCommand::undo()
795 {
796     QDataStream stream(&m_originalPattern, QIODevice::ReadOnly);
797     stream >> m_document->pattern()->stitches();
798     m_originalPattern.clear();
799 
800     m_document->editor()->readDocumentSettings();
801     m_document->preview()->readDocumentSettings();
802 }
803 
804 
InsertColumnsCommand(Document * document,const QRect & selectionArea)805 InsertColumnsCommand::InsertColumnsCommand(Document *document, const QRect &selectionArea)
806     :   QUndoCommand(i18n("Insert Columns")),
807         m_document(document),
808         m_selectionArea(selectionArea)
809 {
810 }
811 
812 
redo()813 void InsertColumnsCommand::redo()
814 {
815     m_document->pattern()->stitches().insertColumns(m_selectionArea.left(), m_selectionArea.width());
816 
817     auto backgroundImageIterator = m_document->backgroundImages().backgroundImages();
818 
819     while (backgroundImageIterator.hasNext()) {
820         auto backgroundImage = backgroundImageIterator.next();
821 
822         if (backgroundImage->location().left() >= m_selectionArea.left()) {
823             backgroundImage->setLocation(backgroundImage->location().translated(m_selectionArea.width(), 0));
824         }
825     }
826 
827     m_document->editor()->readDocumentSettings();
828     m_document->preview()->readDocumentSettings();
829 }
830 
831 
undo()832 void InsertColumnsCommand::undo()
833 {
834     m_document->pattern()->stitches().removeColumns(m_selectionArea.left(), m_selectionArea.width());
835 
836     auto backgroundImageIterator = m_document->backgroundImages().backgroundImages();
837 
838     while (backgroundImageIterator.hasNext()) {
839         auto backgroundImage = backgroundImageIterator.next();
840 
841         if (backgroundImage->location().left() > m_selectionArea.left()) {
842             backgroundImage->setLocation(backgroundImage->location().translated(-m_selectionArea.width(), 0));
843         }
844     }
845 
846     m_document->editor()->readDocumentSettings();
847     m_document->preview()->readDocumentSettings();
848 }
849 
850 
InsertRowsCommand(Document * document,const QRect & selectionArea)851 InsertRowsCommand::InsertRowsCommand(Document *document, const QRect &selectionArea)
852     :   QUndoCommand(i18n("Insert Rows")),
853         m_document(document),
854         m_selectionArea(selectionArea)
855 {
856 }
857 
858 
redo()859 void InsertRowsCommand::redo()
860 {
861     m_document->pattern()->stitches().insertRows(m_selectionArea.top(), m_selectionArea.height());
862 
863     auto backgroundImageIterator = m_document->backgroundImages().backgroundImages();
864 
865     while (backgroundImageIterator.hasNext()) {
866         auto backgroundImage = backgroundImageIterator.next();
867 
868         if (backgroundImage->location().top() >= m_selectionArea.top()) {
869             backgroundImage->setLocation(backgroundImage->location().translated(0, m_selectionArea.height()));
870         }
871     }
872 
873     m_document->editor()->readDocumentSettings();
874     m_document->preview()->readDocumentSettings();
875 }
876 
877 
undo()878 void InsertRowsCommand::undo()
879 {
880     m_document->pattern()->stitches().removeRows(m_selectionArea.top(), m_selectionArea.height());
881 
882     auto backgroundImageIterator = m_document->backgroundImages().backgroundImages();
883 
884     while (backgroundImageIterator.hasNext()) {
885         auto backgroundImage = backgroundImageIterator.next();
886 
887         if (backgroundImage->location().top() > m_selectionArea.top()) {
888             backgroundImage->setLocation(backgroundImage->location().translated(0, -m_selectionArea.height()));
889         }
890     }
891 
892     m_document->editor()->readDocumentSettings();
893     m_document->preview()->readDocumentSettings();
894 }
895 
896 
ExtendPatternCommand(Document * document,int top,int left,int right,int bottom)897 ExtendPatternCommand::ExtendPatternCommand(Document *document, int top, int left, int right, int bottom)
898     :   QUndoCommand(i18n("Extend Pattern")),
899         m_document(document),
900         m_top(top),
901         m_left(left),
902         m_right(right),
903         m_bottom(bottom)
904 {
905 }
906 
907 
redo()908 void ExtendPatternCommand::redo()
909 {
910     StitchData &stitchData = m_document->pattern()->stitches();
911     stitchData.resize(stitchData.width() + m_left + m_right, stitchData.height() + m_top + m_bottom);
912     stitchData.movePattern(m_left, m_top);
913     auto backgroundImageIterator = m_document->backgroundImages().backgroundImages();
914 
915     while (backgroundImageIterator.hasNext()) {
916         auto backgroundImage = backgroundImageIterator.next();
917         backgroundImage->setLocation(backgroundImage->location().translated(m_left, m_top));
918     }
919 
920     m_document->editor()->readDocumentSettings();
921     m_document->preview()->readDocumentSettings();
922 }
923 
924 
undo()925 void ExtendPatternCommand::undo()
926 {
927     StitchData &stitchData = m_document->pattern()->stitches();
928     stitchData.movePattern(-m_left, -m_top);
929     stitchData.resize(stitchData.width() - m_left - m_right, stitchData.height() - m_top - m_bottom);
930     auto backgroundImageIterator = m_document->backgroundImages().backgroundImages();
931 
932     while (backgroundImageIterator.hasNext()) {
933         auto backgroundImage = backgroundImageIterator.next();
934         backgroundImage->setLocation(backgroundImage->location().translated(-m_left, -m_top));
935     }
936 
937     m_document->editor()->readDocumentSettings();
938     m_document->preview()->readDocumentSettings();
939 }
940 
941 
CentrePatternCommand(Document * document)942 CentrePatternCommand::CentrePatternCommand(Document *document)
943     :   QUndoCommand(i18n("Center Pattern")),
944         m_document(document)
945 {
946 }
947 
948 
redo()949 void CentrePatternCommand::redo()
950 {
951     QRect extents = m_document->pattern()->stitches().extents();
952 
953     m_xOffset = ((m_document->pattern()->stitches().width() - extents.width()) / 2) - extents.left();
954     m_yOffset = ((m_document->pattern()->stitches().height() - extents.height()) / 2) - extents.top();
955 
956     if (m_xOffset || m_yOffset) {
957         m_document->pattern()->stitches().movePattern(m_xOffset, m_yOffset);
958 
959         m_document->editor()->drawContents();
960         m_document->preview()->drawContents();
961     }
962 }
963 
964 
965 
undo()966 void CentrePatternCommand::undo()
967 {
968     if (m_xOffset || m_yOffset) {
969         m_document->pattern()->stitches().movePattern(-m_xOffset, -m_yOffset);
970 
971         m_document->editor()->drawContents();
972         m_document->preview()->drawContents();
973     }
974 }
975 
976 
UpdateDocumentPaletteCommand(Document * document,const DocumentPalette & palette)977 UpdateDocumentPaletteCommand::UpdateDocumentPaletteCommand(Document *document, const DocumentPalette &palette)
978     :   QUndoCommand(i18n("Update Palette")),
979         m_document(document),
980         m_palette(palette)
981 {
982 }
983 
984 
redo()985 void UpdateDocumentPaletteCommand::redo()
986 {
987     DocumentPalette palette = m_document->pattern()->palette();
988     m_document->pattern()->palette() = m_palette;
989     m_palette = palette;
990 
991     m_document->editor()->drawContents();
992     m_document->preview()->drawContents();
993     m_document->palette()->update();
994 }
995 
996 
undo()997 void UpdateDocumentPaletteCommand::undo()
998 {
999     redo(); // swaps the palette back
1000 }
1001 
1002 
ChangeSchemeCommand(Document * document,const QString & schemeName,QUndoCommand * parent)1003 ChangeSchemeCommand::ChangeSchemeCommand(Document *document, const QString &schemeName, QUndoCommand *parent)
1004     :   QUndoCommand(i18n("Change Floss Scheme"), parent),
1005         m_document(document),
1006         m_schemeName(schemeName)
1007 {
1008 }
1009 
1010 
redo()1011 void ChangeSchemeCommand::redo()
1012 {
1013     QDataStream stream(&m_originalPalette, QIODevice::WriteOnly);
1014     stream << m_document->pattern()->palette();
1015     m_document->pattern()->palette().setSchemeName(m_schemeName);
1016 
1017     m_document->editor()->drawContents();
1018     m_document->preview()->drawContents();
1019     m_document->palette()->update();
1020 }
1021 
1022 
undo()1023 void ChangeSchemeCommand::undo()
1024 {
1025     QDataStream stream(&m_originalPalette, QIODevice::ReadOnly);
1026     stream >> m_document->pattern()->palette();
1027     m_originalPalette.clear();
1028 
1029     m_document->editor()->drawContents();
1030     m_document->preview()->drawContents();
1031     m_document->palette()->update();
1032 }
1033 
1034 
EditorReadDocumentSettingsCommand(Editor * editor)1035 EditorReadDocumentSettingsCommand::EditorReadDocumentSettingsCommand(Editor *editor)
1036     :   QUndoCommand(),
1037         m_editor(editor)
1038 {
1039 }
1040 
1041 
redo()1042 void EditorReadDocumentSettingsCommand::redo()
1043 {
1044     m_editor->readDocumentSettings();
1045 }
1046 
1047 
undo()1048 void EditorReadDocumentSettingsCommand::undo()
1049 {
1050     redo(); // same code required
1051 }
1052 
1053 
PreviewReadDocumentSettingsCommand(Preview * preview)1054 PreviewReadDocumentSettingsCommand::PreviewReadDocumentSettingsCommand(Preview *preview)
1055     :   QUndoCommand(),
1056         m_preview(preview)
1057 {
1058 }
1059 
1060 
redo()1061 void PreviewReadDocumentSettingsCommand::redo()
1062 {
1063     m_preview->readDocumentSettings();
1064 }
1065 
1066 
undo()1067 void PreviewReadDocumentSettingsCommand::undo()
1068 {
1069     redo(); // same code required
1070 }
1071 
1072 
PaletteReplaceColorCommand(Document * document,int originalIndex,int replacementIndex)1073 PaletteReplaceColorCommand::PaletteReplaceColorCommand(Document *document, int originalIndex, int replacementIndex)
1074     :   QUndoCommand(i18n("Replace Color")),
1075         m_document(document),
1076         m_originalIndex(originalIndex),
1077         m_replacementIndex(replacementIndex)
1078 {
1079 }
1080 
1081 
redo()1082 void PaletteReplaceColorCommand::redo()
1083 {
1084     if (m_stitches.count() || m_backstitches.count() || m_knots.count()) {
1085         // populated from a previous redo call
1086         // iterator over the existing pointers
1087         for (Stitch *stitch : m_stitches) {
1088             stitch->colorIndex = m_replacementIndex;
1089         }
1090 
1091         for (Backstitch *backstitch : m_backstitches) {
1092             backstitch->colorIndex = m_replacementIndex;
1093         }
1094 
1095         for (Knot *knot : m_knots) {
1096             knot->colorIndex = m_replacementIndex;
1097         }
1098     } else {
1099         // search the stitch data for stitches of the required color
1100         StitchData &stitchData = m_document->pattern()->stitches();
1101 
1102         for (int row = 0 ; row < stitchData.height() ; ++row) {
1103             for (int col = 0 ; col < stitchData.width() ; ++col) {
1104                 StitchQueue *queue = stitchData.stitchQueueAt(QPoint(col, row));
1105 
1106                 if (queue) {
1107                     QListIterator<Stitch *> stitchIterator(*queue);
1108 
1109                     while (stitchIterator.hasNext()) {
1110                         Stitch *stitch = stitchIterator.next();
1111 
1112                         if (stitch->colorIndex == m_originalIndex) {
1113                             m_stitches.append(stitch);
1114                             stitch->colorIndex = m_replacementIndex;
1115                         }
1116                     }
1117                 }
1118             }
1119         }
1120 
1121         QListIterator<Backstitch *> backstitchIterator = stitchData.backstitchIterator();
1122 
1123         while (backstitchIterator.hasNext()) {
1124             Backstitch *backstitch = backstitchIterator.next();
1125 
1126             if (backstitch->colorIndex == m_originalIndex) {
1127                 m_backstitches.append(backstitch);
1128                 backstitch->colorIndex = m_replacementIndex;
1129             }
1130         }
1131 
1132         QListIterator<Knot *> knotIterator = stitchData.knotIterator();
1133 
1134         while (knotIterator.hasNext()) {
1135             Knot *knot = knotIterator.next();
1136 
1137             if (knot->colorIndex == m_originalIndex) {
1138                 m_knots.append(knot);
1139                 knot->colorIndex = m_replacementIndex;
1140             }
1141         }
1142     }
1143 
1144     m_document->editor()->drawContents();
1145     m_document->preview()->drawContents();
1146     m_document->palette()->update();
1147 }
1148 
1149 
undo()1150 void PaletteReplaceColorCommand::undo()
1151 {
1152     QListIterator<Stitch *> stitchIterator(m_stitches);
1153 
1154     while (stitchIterator.hasNext()) {
1155         stitchIterator.next()->colorIndex = m_originalIndex;
1156     }
1157 
1158     QListIterator<Backstitch *> backstitchIterator(m_backstitches);
1159 
1160     while (backstitchIterator.hasNext()) {
1161         backstitchIterator.next()->colorIndex = m_originalIndex;
1162     }
1163 
1164     QListIterator<Knot *> knotIterator(m_knots);
1165 
1166     while (knotIterator.hasNext()) {
1167         knotIterator.next()->colorIndex = m_originalIndex;
1168     }
1169 
1170     m_document->editor()->drawContents();
1171     m_document->preview()->drawContents();
1172     m_document->palette()->update();
1173 }
1174 
1175 
PaletteSwapColorCommand(Document * document,int originalIndex,int swappedIndex)1176 PaletteSwapColorCommand::PaletteSwapColorCommand(Document *document, int originalIndex, int swappedIndex)
1177     :   QUndoCommand(i18n("Swap Colors")),
1178         m_document(document),
1179         m_originalIndex(originalIndex),
1180         m_swappedIndex(swappedIndex)
1181 {
1182 }
1183 
1184 
redo()1185 void PaletteSwapColorCommand::redo()
1186 {
1187     m_document->pattern()->palette().swap(m_originalIndex, m_swappedIndex);
1188     m_document->editor()->drawContents();
1189     m_document->preview()->drawContents();
1190     m_document->palette()->update();
1191 }
1192 
1193 
undo()1194 void PaletteSwapColorCommand::undo()
1195 {
1196     redo();
1197 }
1198 
1199 
UpdatePrinterConfigurationCommand(Document * document,const PrinterConfiguration & printerConfiguration)1200 UpdatePrinterConfigurationCommand::UpdatePrinterConfigurationCommand(Document *document, const PrinterConfiguration &printerConfiguration)
1201     :   QUndoCommand(i18n("Update Printer Configuration")),
1202         m_document(document),
1203         m_printerConfiguration(printerConfiguration)
1204 {
1205 }
1206 
1207 
redo()1208 void UpdatePrinterConfigurationCommand::redo()
1209 {
1210     PrinterConfiguration original = m_document->printerConfiguration();
1211     m_document->setPrinterConfiguration(m_printerConfiguration);
1212     m_printerConfiguration = original;
1213 }
1214 
1215 
undo()1216 void UpdatePrinterConfigurationCommand::undo()
1217 {
1218     redo();
1219 }
1220 
1221 
EditCutCommand(Document * document,const QRect & selectionArea,int colorMask,const QList<Stitch::Type> & stitchMasks,bool excludeBackstitches,bool excludeKnots)1222 EditCutCommand::EditCutCommand(Document *document, const QRect &selectionArea, int colorMask, const QList<Stitch::Type> &stitchMasks, bool excludeBackstitches, bool excludeKnots)
1223     :   QUndoCommand(i18n("Cut")),
1224         m_document(document),
1225         m_selectionArea(selectionArea),
1226         m_colorMask(colorMask),
1227         m_stitchMasks(stitchMasks),
1228         m_excludeBackstitches(excludeBackstitches),
1229         m_excludeKnots(excludeKnots),
1230         m_originalPattern(nullptr)
1231 {
1232 }
1233 
1234 
~EditCutCommand()1235 EditCutCommand::~EditCutCommand()
1236 {
1237     delete m_originalPattern;
1238 }
1239 
1240 
redo()1241 void EditCutCommand::redo()
1242 {
1243     m_originalPattern = m_document->pattern()->cut(m_selectionArea, m_colorMask, m_stitchMasks, m_excludeBackstitches, m_excludeKnots);
1244 
1245     QByteArray data;
1246     QDataStream stream(&data, QIODevice::WriteOnly);
1247     stream << *m_originalPattern;
1248 
1249     QMimeData *mimeData = new QMimeData();
1250     mimeData->setData(QStringLiteral("application/kxstitch"), data);
1251 
1252     QApplication::clipboard()->setMimeData(mimeData);
1253 
1254     m_document->editor()->drawContents();
1255     m_document->preview()->drawContents();
1256 }
1257 
1258 
undo()1259 void EditCutCommand::undo()
1260 {
1261     m_document->pattern()->paste(m_originalPattern, m_selectionArea.topLeft(), true);
1262     delete m_originalPattern;
1263     m_originalPattern = nullptr;
1264 
1265     m_document->editor()->drawContents();
1266     m_document->preview()->drawContents();
1267 }
1268 
1269 
EditPasteCommand(Document * document,Pattern * pattern,const QPoint & cell,bool merge,const QString & source)1270 EditPasteCommand::EditPasteCommand(Document *document, Pattern *pattern, const QPoint &cell, bool merge, const QString &source)
1271     :   QUndoCommand(source),
1272         m_document(document),
1273         m_pastePattern(pattern),
1274         m_cell(cell),
1275         m_merge(merge)
1276 {
1277 }
1278 
1279 
redo()1280 void EditPasteCommand::redo()
1281 {
1282     QDataStream stream(&m_originalPattern, QIODevice::WriteOnly);
1283     stream << *(m_document->pattern());
1284     m_document->pattern()->paste(m_pastePattern, m_cell, m_merge);
1285 
1286     m_document->editor()->drawContents();
1287     m_document->preview()->drawContents();
1288     m_document->palette()->update();
1289 }
1290 
1291 
undo()1292 void EditPasteCommand::undo()
1293 {
1294     QDataStream stream(&m_originalPattern, QIODevice::ReadOnly);
1295     m_document->pattern()->clear();
1296     stream >> *(m_document->pattern());
1297     m_originalPattern.clear();
1298 
1299     m_document->editor()->drawContents();
1300     m_document->preview()->drawContents();
1301     m_document->palette()->update();
1302 }
1303 
1304 
MirrorSelectionCommand(Document * document,const QRect & selectionArea,int colorMask,const QList<Stitch::Type> & stitchMasks,bool excludeBackstitches,bool excludeKnots,Qt::Orientation orientation,bool copies,const QByteArray & originalPatternData,Pattern * invertedPattern,const QPoint & pasteCell,bool merge)1305 MirrorSelectionCommand::MirrorSelectionCommand(Document *document, const QRect &selectionArea, int colorMask, const QList<Stitch::Type> &stitchMasks, bool excludeBackstitches, bool excludeKnots, Qt::Orientation orientation, bool copies, const QByteArray &originalPatternData, Pattern *invertedPattern, const QPoint &pasteCell, bool merge)
1306     :   QUndoCommand(i18n("Mirror Selection")),
1307         m_document(document),
1308         m_selectionArea(selectionArea),
1309         m_colorMask(colorMask),
1310         m_stitchMasks(stitchMasks),
1311         m_excludeBackstitches(excludeBackstitches),
1312         m_excludeKnots(excludeKnots),
1313         m_orientation(orientation),
1314         m_copies(copies),
1315         m_originalPatternData(originalPatternData),
1316         m_invertedPattern(invertedPattern),
1317         m_pasteCell(pasteCell),
1318         m_merge(merge)
1319 {
1320 }
1321 
1322 
~MirrorSelectionCommand()1323 MirrorSelectionCommand::~MirrorSelectionCommand()
1324 {
1325     delete m_invertedPattern;
1326 }
1327 
1328 
redo()1329 void MirrorSelectionCommand::redo()
1330 {
1331     if (!m_copies) {
1332         delete m_document->pattern()->cut(m_selectionArea, m_colorMask, m_stitchMasks, m_excludeBackstitches, m_excludeKnots);
1333     }
1334 
1335     m_document->pattern()->paste(m_invertedPattern, m_pasteCell, m_merge);
1336 
1337     m_document->editor()->drawContents();
1338     m_document->preview()->drawContents();
1339 }
1340 
1341 
undo()1342 void MirrorSelectionCommand::undo()
1343 {
1344     m_document->pattern()->stitches().clear();
1345     QDataStream stream(&m_originalPatternData, QIODevice::ReadOnly);
1346     stream >> m_document->pattern()->stitches();
1347 
1348     m_document->editor()->drawContents();
1349     m_document->preview()->drawContents();
1350 }
1351 
1352 
RotateSelectionCommand(Document * document,const QRect & selectionArea,int colorMask,const QList<Stitch::Type> & stitchMasks,bool excludeBackstitches,bool excludeKnots,StitchData::Rotation rotation,bool copies,const QByteArray & originalPatternData,Pattern * rotatedPattern,const QPoint & pasteCell,bool merge)1353 RotateSelectionCommand::RotateSelectionCommand(Document *document, const QRect &selectionArea, int colorMask, const QList<Stitch::Type> &stitchMasks, bool excludeBackstitches, bool excludeKnots, StitchData::Rotation rotation, bool copies, const QByteArray &originalPatternData, Pattern *rotatedPattern, const QPoint &pasteCell, bool merge)
1354     :   QUndoCommand(i18n("Rotate Selection")),
1355         m_document(document),
1356         m_selectionArea(selectionArea),
1357         m_colorMask(colorMask),
1358         m_stitchMasks(stitchMasks),
1359         m_excludeBackstitches(excludeBackstitches),
1360         m_excludeKnots(excludeKnots),
1361         m_rotation(rotation),
1362         m_copies(copies),
1363         m_originalPatternData(originalPatternData),
1364         m_rotatedPattern(rotatedPattern),
1365         m_pasteCell(pasteCell),
1366         m_merge(merge)
1367 {
1368 }
1369 
1370 
~RotateSelectionCommand()1371 RotateSelectionCommand::~RotateSelectionCommand()
1372 {
1373     delete m_rotatedPattern;
1374 }
1375 
1376 
redo()1377 void RotateSelectionCommand::redo()
1378 {
1379     if (!m_copies) {
1380         delete m_document->pattern()->cut(m_selectionArea, m_colorMask, m_stitchMasks, m_excludeBackstitches, m_excludeKnots);
1381     }
1382 
1383     m_document->pattern()->paste(m_rotatedPattern, m_pasteCell, m_merge);
1384 
1385     m_document->editor()->drawContents();
1386     m_document->preview()->drawContents();
1387 }
1388 
1389 
undo()1390 void RotateSelectionCommand::undo()
1391 {
1392     m_document->pattern()->stitches().clear();
1393     QDataStream stream(&m_originalPatternData, QIODevice::ReadOnly);
1394     stream >> m_document->pattern()->stitches();
1395 
1396     m_document->editor()->drawContents();
1397     m_document->preview()->drawContents();
1398 }
1399 
1400 
AlphabetCommand(Document * document)1401 AlphabetCommand::AlphabetCommand(Document *document)
1402     :   QUndoCommand(i18n("Alphabet")),
1403         m_document(document)
1404 {
1405 }
1406 
1407 
~AlphabetCommand()1408 AlphabetCommand::~AlphabetCommand()
1409 {
1410     qDeleteAll(m_children);
1411 }
1412 
1413 
redo()1414 void AlphabetCommand::redo()
1415 {
1416     for (int i = 0 ; i < m_children.size() ; ++i) {
1417         m_children.at(i)->redo();
1418     }
1419 }
1420 
1421 
undo()1422 void AlphabetCommand::undo()
1423 {
1424     for (int i = m_children.size() - 1 ; i >= 0 ; --i) {
1425         m_children.at(i)->undo();
1426     }
1427 }
1428 
1429 
push(QUndoCommand * child)1430 void AlphabetCommand::push(QUndoCommand *child)
1431 {
1432     m_children.append(child);
1433     child->redo();
1434 }
1435 
1436 
pop()1437 QUndoCommand *AlphabetCommand::pop()
1438 {
1439     if (m_children.isEmpty()) {
1440         return nullptr;
1441     }
1442 
1443     m_children.last()->undo();
1444     return m_children.takeLast();
1445 }
1446 
1447 
childCount() const1448 int AlphabetCommand::childCount() const
1449 {
1450     return m_children.count();
1451 }
1452 
1453 
ConfigurationCommand(MainWindow * mainWindow)1454 ConfigurationCommand::ConfigurationCommand(MainWindow *mainWindow)
1455     :   QUndoCommand(i18n("Configure KXStitch")),
1456         m_mainWindow(mainWindow)
1457 {
1458 }
1459 
1460 
redo()1461 void ConfigurationCommand::redo()
1462 {
1463     QUndoCommand::redo();
1464     m_mainWindow->loadSettings();
1465 }
1466 
1467 
undo()1468 void ConfigurationCommand::undo()
1469 {
1470     QUndoCommand::undo();
1471     m_mainWindow->loadSettings();
1472 }
1473