Engauge Digitizer 2
Loading...
Searching...
No Matches
CmdAbstract.cpp
Go to the documentation of this file.
1/******************************************************************************************************
2 * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3 * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4 * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5 ******************************************************************************************************/
6
7#include "CmdAbstract.h"
8#include "DataKey.h"
9#include "DigitizeState.h"
10#include "Document.h"
12#include "DocumentSerialize.h"
13#include "EngaugeAssert.h"
14#include "GraphicsItemType.h"
15#include "GraphicsScene.h"
16#include "GraphicsView.h"
17#include "GuidelineState.h"
18#include "Logger.h"
19#include "MainWindow.h"
20#include "Point.h"
21#include <QGraphicsItem>
22#include <QXmlStreamReader>
23#include <QXmlStreamWriter>
24#include "Xml.h"
25
28 const QString &cmdDescription) :
29 QUndoCommand (cmdDescription),
30 m_mainWindow (mainWindow),
31 m_document (document),
32 m_isFirstRedo (true),
33 m_digitizeState (mainWindow.digitizeState ())
34{
35 LOG4CPP_INFO_S ((*mainCat)) << "CmdAbstract::CmdAbstract";
36}
37
41
42void CmdAbstract::baseAttributes (QXmlStreamWriter &writer) const
43{
44 writer.writeAttribute(DOCUMENT_SERIALIZE_DIGITIZE_STATE, QString::number (m_digitizeState));
45 writer.writeAttribute(DOCUMENT_SERIALIZE_DIGITIZE_STATE_STRING, digitizeStateAsString (m_digitizeState));
46}
47
49{
50 return m_document;
51}
52
54{
55 return m_document;
56}
57
58void CmdAbstract::leafAttributes (const QXmlStreamAttributes &attributes,
59 const QStringList &requiredAttributesLeaf,
60 QXmlStreamReader &reader)
61{
62 // Check for leaf class if called directly, or for base class if called indirectly through leafAndBaseAttributes
63 QStringList::const_iterator itr;
64 QStringList missingAttributes;
65 for (itr = requiredAttributesLeaf.begin (); itr != requiredAttributesLeaf.end (); itr++) {
66
67 QString attribute = *itr;
68 if (!attributes.hasAttribute (attribute)) {
69 missingAttributes << attribute;
70 }
71 }
72
73 if (missingAttributes.size () > 0) {
74 xmlExitWithError (reader,
75 QString ("Missing attribute(s) %1"). arg (missingAttributes.join (", ")));
76 }
77}
78
79void CmdAbstract::leafAndBaseAttributes (const QXmlStreamAttributes &attributes,
80 const QStringList &requiredAttributesLeaf,
81 QXmlStreamReader &reader)
82{
83 // Aggregate attributes for leaf and this abstract class
84 QStringList requiredAttributes = requiredAttributesLeaf;
85 requiredAttributes << DOCUMENT_SERIALIZE_DIGITIZE_STATE;
86
87 // Check as if this base class was a leaf class
88 leafAttributes (attributes,
89 requiredAttributes,
90 reader);
91
92 // Extract parent class attributes
93 m_digitizeState = static_cast<DigitizeState> (attributes.value (DOCUMENT_SERIALIZE_DIGITIZE_STATE).toInt());
94}
95
97{
98 return m_mainWindow;
99}
100
101void CmdAbstract::redo ()
102{
103 // Note that m_identifierIndexBeforeRedo and m_identifierIndexAfterRedo are not set until below (at which point they are logged)
104 LOG4CPP_INFO_S ((*mainCat)) << "CmdAbstract::redo";
105
106 if (m_isFirstRedo) {
107
108 m_identifierIndexBeforeRedo = Point::identifierIndex ();
109
110 } else {
111
112 // Reset state. The first time this is called, this is a noop since m_identifierIndex was just set to
113 // GraphicsPointAbstractBase::identifierIndex in the constructor of this class
114 Point::setIdentifierIndex (m_identifierIndexBeforeRedo);
115
116 }
117
118 // Invoke the leaf class redo method
119 cmdRedo ();
120
121 if (m_isFirstRedo) {
122
123 m_isFirstRedo = false;
124 m_identifierIndexAfterRedo = Point::identifierIndex();
125
126 }
127
128 LOG4CPP_INFO_S ((*mainCat)) << "CmdAbstract::redo identifierIndex=" << m_identifierIndexBeforeRedo << "->"
129 << m_identifierIndexAfterRedo;
130}
131
132void CmdAbstract::resetSelection(const PointIdentifiers &pointIdentifiersToSelect)
133{
134 LOG4CPP_INFO_S ((*mainCat)) << "CmdAbstract::resetSelection";
135
136 QList<QGraphicsItem *> items = mainWindow().view().items();
137 QList<QGraphicsItem *>::iterator itrS;
138 for (itrS = items.begin (); itrS != items.end (); itrS++) {
139
140 QGraphicsItem *item = *itrS;
141 bool selected = false;
142 if (item->data (DATA_KEY_GRAPHICS_ITEM_TYPE).toInt () == GRAPHICS_ITEM_TYPE_POINT) {
143
144 QString pointIdentifier = item->data (DATA_KEY_IDENTIFIER).toString ();
145
146 selected = pointIdentifiersToSelect.contains (pointIdentifier);
147 }
148
149 item->setSelected (selected);
150 }
151}
152
154{
155 LOG4CPP_INFO_S ((*mainCat)) << "CmdAbstract::restoreState";
156
157 m_mainWindow.updateDigitizeStateIfSoftwareTriggered (m_digitizeState);
158}
159
161{
162 // LOG4CPP_INFO_S is below
163
164 DocumentHashGenerator documentHashGenerator;
165 DocumentHash documentHash = documentHashGenerator.generate (document);
166
167 if (m_documentHashPost.count() == 0) {
168
169 // This is the first time through here so save the initial value
170 m_documentHashPost = documentHash;
171
172 } else {
173
174 // This is not the first time through here so compare the current value to the initial value
175 ENGAUGE_ASSERT (documentHash == m_documentHashPost);
176
177 }
178
179 LOG4CPP_INFO_S ((*mainCat)) << "CmdAbstract::saveOrCheckPostCommandDocumentStateHash stateHash=" << m_documentHashPost.data ();
180
181}
182
184{
185 // LOG4CPP_INFO_S is below
186
187 DocumentHashGenerator documentHashGenerator;
188 DocumentHash documentHash = documentHashGenerator.generate (document);
189
190 if (m_documentHashPre.count() == 0) {
191
192 // This is the first time through here so save the initial value
193 m_documentHashPre = documentHash;
194
195 } else {
196
197 // This is not the first time through here so compare the current value to the initial value
198 ENGAUGE_ASSERT (documentHash == m_documentHashPre);
199
200 }
201
202 LOG4CPP_INFO_S ((*mainCat)) << "CmdAbstract::saveOrCheckPreCommandDocumentStateHash stateHash=" << m_documentHashPre.data ();
203
204}
205
206void CmdAbstract::selectAddedPointForMoving (const QString &pointAdded)
207{
208 // Select added points so they can be moved
209 PointIdentifiers pointIdentifiers;
210 pointIdentifiers.setKeyValue (pointAdded, true);
211 resetSelection(pointIdentifiers);
212}
213
214void CmdAbstract::selectAddedPointsForMoving (const QStringList &pointsAdded)
215{
216 // Select added points so they can be moved
217 PointIdentifiers pointIdentifiers;
218 QStringList::const_iterator itr;
219 for (itr = pointsAdded.begin(); itr != pointsAdded.end(); itr++) {
220 QString pointAdded = *itr;
221 pointIdentifiers.setKeyValue (pointAdded, true);
222 }
223 resetSelection(pointIdentifiers);
224}
225
226void CmdAbstract::undo ()
227{
228 LOG4CPP_INFO_S ((*mainCat)) << "CmdAbstract::undo identifierIndex=" << m_identifierIndexAfterRedo << "->"
229 << m_identifierIndexBeforeRedo;
230
231 Point::setIdentifierIndex (m_identifierIndexAfterRedo);
232
233 // Invoke the leaf class undo method
234 cmdUndo ();
235
236 Point::setIdentifierIndex (m_identifierIndexBeforeRedo);
237}
@ DATA_KEY_GRAPHICS_ITEM_TYPE
Definition DataKey.h:15
@ DATA_KEY_IDENTIFIER
Definition DataKey.h:14
QString digitizeStateAsString(DigitizeState state)
DigitizeState
Set of possible states of Digitize toolbar.
QByteArray DocumentHash
const QString DOCUMENT_SERIALIZE_DIGITIZE_STATE
const QString DOCUMENT_SERIALIZE_DIGITIZE_STATE_STRING
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT.
@ GRAPHICS_ITEM_TYPE_POINT
log4cpp::Category * mainCat
Definition Logger.cpp:14
void xmlExitWithError(QXmlStreamReader &reader, const QString &message)
Show specified message for an error while reading xml, then quit.
Definition Xml.cpp:25
Document & document()
Return the Document that this command will modify during redo and undo.
void selectAddedPointForMoving(const QString &pointAdded)
Select point that was just added so it can be moved by the user next for convenience.
MainWindow & mainWindow()
Return the MainWindow so it can be updated by this command as a last step.
virtual void cmdUndo()=0
Undo method that is called when QUndoStack is moved one command backward.
void saveOrCheckPostCommandDocumentStateHash(const Document &document)
Save, when called the first time, a hash value representing the state of the Document.
void restoreState()
Before any other operations associated with a Cmd class are performed, this method is called to resto...
void leafAttributes(const QXmlStreamAttributes &attributes, const QStringList &requiredAttributesLeaf, QXmlStreamReader &reader)
Same as often-used leafAndBaseAttributes, except this is used in the special case where a class inher...
void saveOrCheckPreCommandDocumentStateHash(const Document &document)
Save, when called the first time, a hash value representing the state of the Document.
void resetSelection(const PointIdentifiers &pointIdentifiersToSelect)
Call this (for consistency) after writing leaf class attributes, to write the base class attributes.
virtual ~CmdAbstract()
void leafAndBaseAttributes(const QXmlStreamAttributes &attributes, const QStringList &requiredAttributesLeaf, QXmlStreamReader &reader)
Before reading leaf class attributes, check all required attributes from leaf and this base class are...
void baseAttributes(QXmlStreamWriter &writer) const
After writing leaf class attributes, this writes the base class atributes.
CmdAbstract(MainWindow &mainWindow, Document &document, const QString &cmdDescription)
Single constructor.
void selectAddedPointsForMoving(const QStringList &pointsAdded)
Select points that were just added so they can be moved by the user next for convenience.
virtual void cmdRedo()=0
Redo method that is called when QUndoStack is moved one command forward.
Generates a DocumentHash value representing the state of the entire Document.
DocumentHash generate(const Document &document) const
Generate the hash for external storage.
Storage of one imported image and the data attached to that image.
Definition Document.h:44
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition MainWindow.h:95
GraphicsView & view()
View for the QImage and QGraphicsItems, without const.
Hash table class that tracks point identifiers as the key, with a corresponding boolean value.
bool contains(const QString &pointIdentifier) const
True if specified entry exists in the table.
void setKeyValue(const QString &pointIdentifier, bool value)
Set key/value pair.
static unsigned int identifierIndex()
Return the current index for storage in case we need to reset it later while performing a Redo.
Definition Point.cpp:273
static void setIdentifierIndex(unsigned int identifierIndex)
Reset the current index while performing a Redo.
Definition Point.cpp:478
#define LOG4CPP_INFO_S(logger)
Definition convenience.h:18