00001 #include "constants.h"
00002
00003 #include "serializers.h"
00004 #include "state.h"
00005 #include "stateManager.h"
00006 #include "transition.h"
00007 #include "oneStateTransition.h"
00008 #include "twoStatesTransition.h"
00009 #include "transitionManager.h"
00010 #include "editor.h"
00011 #include "label.h"
00012
00013 #include <QGraphicsItem>
00014 #include <QPoint>
00015 #include <QList>
00016 #include <QString>
00017 #include <QDataStream>
00018 #include <QMetaType>
00019
00020
00021
00022
00023
00024 #define SS_PARAMS(obj, xx) obj.m_stateName xx \
00025 obj.m_pos xx obj.m_typeName xx obj.m_label xx \
00026 obj.m_dimmed xx obj.m_stateLineStyle xx \
00027 obj.m_stateLineWidth xx obj.m_stateLineColor xx \
00028 obj.m_stateLabelColor xx obj.m_stateLabelScale xx \
00029 obj.m_stateFillStatus xx obj.m_stateFillColor xx \
00030 obj.m_dimStateLineStyle xx obj.m_dimStateLineColor xx \
00031 obj.m_dimStateLineCoef xx obj.m_dimStateLabelColor xx \
00032 obj.m_dimStateFillColor xx obj.m_stateLineDoubleCoef xx \
00033 obj.m_stateLineDoubleSep xx obj.m_stateLabelSize
00034
00035
00036 QDataStream &operator<<(QDataStream &out, const StateSerializer &s)
00037 {
00038 Q_ASSERT(s.m_valid && "do NOT use uninitialized serializer!");
00039 out << SS_PARAMS(s, <<);
00040
00041 return out;
00042 }
00043
00044 QDataStream &operator>>(QDataStream &in, StateSerializer &s)
00045 {
00046 in >> SS_PARAMS(s, >>);
00047
00048 s.m_valid = true;
00049 return in;
00050 }
00051
00052 StateSerializer::StateSerializer(const State &s)
00053 : m_valid(true), m_stateName(s.name), m_pos(s.pos()),
00054 m_typeName(s.getTypeName()), m_label(s.label), m_dimmed(s.dimmed),
00055 m_stateLineStyle(s.stateLineStyle),
00056 m_stateLineWidth(s.stateLineWidth), m_stateLineColor(s.stateLineColor),
00057 m_stateLabelColor(s.stateLabelColor), m_stateLabelScale(s.stateLabelScale),
00058 m_stateFillStatus(s.stateFillStatus), m_stateFillColor(s.stateFillColor),
00059 m_dimStateLineStyle(s.dimStateLineStyle), m_dimStateLineColor(s.dimStateLineColor),
00060 m_dimStateLineCoef(s.dimStateLineCoef), m_dimStateLabelColor(s.dimStateLabelColor),
00061 m_dimStateFillColor(s.dimStateFillColor), m_stateLineDoubleCoef(s.stateLineDoubleCoef),
00062 m_stateLineDoubleSep(s.stateLineDoubleSep), m_stateLabelSize(s.stateLabelSize)
00063 {}
00064
00065 StateSerializer::StateSerializer(const StateSerializer &other)
00066 : m_valid(other.m_valid), m_stateName(other.m_stateName), m_pos(other.m_pos),
00067 m_typeName(other.m_typeName), m_label(other.m_label), m_dimmed(other.m_dimmed),
00068 m_stateLineStyle(other.m_stateLineStyle),
00069 m_stateLineWidth(other.m_stateLineWidth), m_stateLineColor(other.m_stateLineColor),
00070 m_stateLabelColor(other.m_stateLabelColor), m_stateLabelScale(other.m_stateLabelScale),
00071 m_stateFillStatus(other.m_stateFillStatus), m_stateFillColor(other.m_stateFillColor),
00072 m_dimStateLineStyle(other.m_dimStateLineStyle), m_dimStateLineColor(other.m_dimStateLineColor),
00073 m_dimStateLineCoef(other.m_dimStateLineCoef), m_dimStateLabelColor(other.m_dimStateLabelColor),
00074 m_dimStateFillColor(other.m_dimStateFillColor), m_stateLineDoubleCoef(other.m_stateLineDoubleCoef),
00075 m_stateLineDoubleSep(other.m_stateLineDoubleSep), m_stateLabelSize(other.m_stateLabelSize)
00076 {}
00077
00078 State* StateSerializer::createState(Editor *editor, const QPoint &pos)
00079 {
00080 if (m_valid)
00081 {
00082 StateManager *stateManager = StateManager::getInstance();
00083
00084 QString name = editor->getUniqueAutoName();
00085 editor->increaseNewStateNumber();
00086
00087 State *state = stateManager->createState(
00088 m_typeName, editor, pos , m_label, name, m_dimmed
00089 );
00090
00091 state->stateLineStyle = (Qt::PenStyle) m_stateLineStyle;
00092 state->setStateLineWidth(m_stateLineWidth);
00093 state->stateLineColor = m_stateLineColor;
00094 state->stateLabelColor = m_stateLabelColor;
00095 state->setStateLabelScale(m_stateLabelScale);
00096 state->stateFillStatus = (Qt::BrushStyle) m_stateFillStatus;
00097 state->stateFillColor = m_stateFillColor;
00098 state->dimStateLineStyle = (Qt::PenStyle) m_dimStateLineStyle;
00099 state->dimStateLineColor = m_dimStateLineColor;
00100 state->setDimStateLineCoef(m_dimStateLineCoef);
00101 state->dimStateLabelColor = m_dimStateLabelColor;
00102 state->dimStateFillColor = m_dimStateFillColor;
00103 state->setStateLineDoubleCoef(m_stateLineDoubleCoef);
00104 state->setStateLineDoubleSep(m_stateLineDoubleSep);
00105 state->stateLabelSize = m_stateLabelSize;
00106
00107 return state;
00108 }
00109 return NULL;
00110 }
00111
00112
00113
00114
00115
00116
00117
00118 #define TS_PARAMS(obj, xx) obj.m_stateNames xx \
00119 obj.m_typeName xx obj.m_label xx obj.m_labelPos xx \
00120 obj.m_dimmed xx obj.m_arcAngleA xx obj.m_arcAngleB xx \
00121 obj.m_nCurv xx obj.m_leftOriented xx obj.m_direction xx obj.m_labels xx \
00122 obj.m_edgeLineStyle xx obj.m_edgeLineWidth xx \
00123 obj.m_edgeLineColor xx obj.m_edgeLabelColor xx \
00124 obj.m_edgeLabelScale xx obj.m_edgeLineDblStatus xx \
00125 obj.m_edgeLineBorderCoef xx obj.m_edgeLineBorderColor xx \
00126 obj.m_edgeLineDblCoef xx obj.m_edgeLineDblSep xx \
00127 obj.m_dimEdgeLineStyle xx obj.m_dimEdgeLineColor xx \
00128 obj.m_dimEdgeLineCoef xx obj.m_dimEdgeLabelColor xx \
00129 obj.m_labels xx obj.m_labelsPositions xx obj.m_labelsLeftOriented
00130
00131 QDataStream &operator<<(QDataStream &out, const TransitionSerializer &s)
00132 {
00133 Q_ASSERT(s.m_valid && "do NOT use uninitialized serializer!");
00134 DBGLOG_SER("stateNames=" << s.m_stateNames);
00135 out << TS_PARAMS(s, <<);
00136 return out;
00137 }
00138
00139 QDataStream &operator>>(QDataStream &in, TransitionSerializer &s)
00140 {
00141 in >> TS_PARAMS(s, >>);
00142 DBGLOG_SER("stateNames=" << s.m_stateNames);
00143 s.m_valid = true;
00144 return in;
00145 }
00146
00147 TransitionSerializer::TransitionSerializer(const Transition &tr)
00148 : m_valid(true), m_typeName(tr.getTypeName()),
00149 m_label(tr.getLabelText()), m_labelPos(tr.getLabelPos()), m_dimmed(tr.dimmed),
00150 m_arcAngleA(tr.getArcAngle()), m_arcAngleB(tr.getArcAngleB()),
00151 m_nCurv(tr.getNCurv()), m_leftOriented(tr.leftOriented),
00152 m_direction(tr.getDirection()), m_edgeLineStyle(tr.edgeLineStyle),
00153 m_edgeLineWidth(tr.edgeLineWidth), m_edgeLineColor(tr.edgeLineColor),
00154 m_edgeLabelColor(tr.edgeLabelColor), m_edgeLabelScale(tr.edgeLabelScale),
00155 m_edgeLineDblStatus(tr.edgeLineDblStatus), m_edgeLineBorderCoef(tr.edgeLineBorderCoef),
00156 m_edgeLineBorderColor(tr.edgeLineBorderColor), m_edgeLineDblCoef(tr.edgeLineDblCoef),
00157 m_edgeLineDblSep(tr.edgeLineDblSep), m_dimEdgeLineStyle(tr.dimEdgeLineStyle),
00158 m_dimEdgeLineColor(tr.dimEdgeLineColor), m_dimEdgeLineCoef(tr.dimEdgeLineCoef),
00159 m_dimEdgeLabelColor(tr.dimEdgeLabelColor)
00160 {
00161 foreach(LabelX *label, tr.getNextLabels())
00162 {
00163 m_labels << label->text();
00164 m_labelsPositions << label->posParam();
00165 m_labelsLeftOriented << label->left();
00166 }
00167
00168 m_stateNames << tr.getStartStateName();
00169 if (tr.hasEndState())
00170 {
00171 m_stateNames << tr.getEndStateName();
00172 }
00173 }
00174
00175 TransitionSerializer::TransitionSerializer(const TransitionSerializer &other)
00176 : m_valid(other.m_valid), m_stateNames(other.m_stateNames), m_typeName(other.m_typeName),
00177 m_label(other.m_label), m_labelPos(other.m_labelPos), m_dimmed(other.m_dimmed),
00178 m_arcAngleA(other.m_arcAngleA), m_arcAngleB(other.m_arcAngleB), m_nCurv(other.m_nCurv),
00179 m_leftOriented(other.m_leftOriented), m_direction(other.m_direction), m_labels(other.m_labels),
00180 m_labelsPositions(other.m_labelsPositions),
00181 m_labelsLeftOriented(other.m_labelsLeftOriented),
00182 m_edgeLineStyle(other.m_edgeLineStyle),
00183 m_edgeLineWidth(other.m_edgeLineWidth), m_edgeLineColor(other.m_edgeLineColor),
00184 m_edgeLabelColor(other.m_edgeLabelColor), m_edgeLabelScale(other.m_edgeLabelScale),
00185 m_edgeLineDblStatus(other.m_edgeLineDblStatus), m_edgeLineBorderCoef(other.m_edgeLineBorderCoef),
00186 m_edgeLineBorderColor(other.m_edgeLineBorderColor), m_edgeLineDblCoef(other.m_edgeLineDblCoef),
00187 m_edgeLineDblSep(other.m_edgeLineDblSep), m_dimEdgeLineStyle(other.m_dimEdgeLineStyle),
00188 m_dimEdgeLineColor(other.m_dimEdgeLineColor), m_dimEdgeLineCoef(other.m_dimEdgeLineCoef),
00189 m_dimEdgeLabelColor(other.m_dimEdgeLabelColor)
00190 {}
00191
00192 Transition* TransitionSerializer::createTransition(Editor *editor, QList<State*> &states)
00193 {
00194 if (m_valid)
00195 {
00196 Q_ASSERT(m_stateNames.count() >= 1);
00197 Q_ASSERT(m_stateNames.count() == states.count());
00198
00199 State *startState = states[0];
00200
00201 TransitionManager *transitionManager = TransitionManager::getInstance();
00202
00203 Transition *transition;
00204 if (m_stateNames.count() == 1)
00205 {
00206 transition = transitionManager->createOneStateTransition(
00207 m_typeName, editor, startState, m_label, m_direction, m_dimmed
00208 );
00209 }
00210 else
00211 {
00212 State *endState = states[1];
00213 Q_ASSERT(startState->getName() != endState->getName());
00214
00215 transition = transitionManager->createTwoStatesTransition(
00216 m_typeName, editor, startState, endState, m_label, m_leftOriented, m_dimmed
00217 );
00218 }
00219
00220 Q_ASSERT(transition && "Transition wasn't created!");
00221
00222 for (int i=0; i < m_labels.count(); ++i)
00223 {
00224 LabelX *label =
00225 new LabelX(transition, m_labels[i], m_labelsLeftOriented[i],
00226 transition->m_labelFontSize, transition->getLabelColor(),
00227 m_labelsPositions[i]);
00228 transition->addNextLabel(label);
00229 }
00230
00231 transition->setArcAngle(m_arcAngleA);
00232 transition->setArcAngleB(m_arcAngleB);
00233 transition->setNCurv(m_nCurv);
00234
00235 transition->edgeLineStyle = (Qt::PenStyle) m_edgeLineStyle;
00236 transition->setEdgeLineWidth(m_edgeLineWidth);
00237 transition->edgeLineColor = m_edgeLineColor;
00238 transition->edgeLabelColor = m_edgeLabelColor;
00239 transition->setEdgeLabelScale(m_edgeLabelScale);
00240 transition->edgeLineDblStatus = m_edgeLineDblStatus;
00241 transition->edgeLineBorderCoef = m_edgeLineBorderCoef;
00242 transition->edgeLineBorderColor = m_edgeLineBorderColor;
00243 transition->edgeLineDblCoef = m_edgeLineDblCoef;
00244 transition->edgeLineDblSep = m_edgeLineDblSep;
00245 transition->dimEdgeLineStyle = (Qt::PenStyle) m_dimEdgeLineStyle;
00246 transition->dimEdgeLineColor = m_dimEdgeLineColor;
00247 transition->setDimEdgeLineCoef(m_dimEdgeLineCoef);
00248 transition->dimEdgeLabelColor = m_dimEdgeLabelColor;
00249
00250 transition->adjust();
00251 return transition;
00252 }
00253 return NULL;
00254 }
00255
00256
00257
00258
00259
00260
00261
00262 QDataStream &operator<<(QDataStream &out, const SelectionSerializer &s)
00263 {
00264 Q_ASSERT(s.m_valid && "do NOT use uninitialized serializer!");
00265
00266 out << s.m_hotSpot;
00267
00268
00269
00270
00271 out << s.m_serializedStates;
00272
00273 out << s.m_serializedTransitions;
00274
00275 return out;
00276 }
00277
00278 QDataStream &operator>>(QDataStream &in, SelectionSerializer &s)
00279 {
00280 in >> s.m_hotSpot;
00281
00282
00283
00284
00285 in >> s.m_serializedStates;
00286
00287 in >> s.m_serializedTransitions;
00288
00289 s.m_valid = true;
00290 return in;
00291 }
00292
00293 SelectionSerializer::SelectionSerializer(const TItemList &items)
00294 : m_valid(true)
00295 {
00296 State *state = NULL;
00297 Transition *transition = NULL;
00298
00299 QRectF boundingBox;
00300
00301 foreach(QGraphicsItem *item, items)
00302 {
00303 if ((state = dynamic_cast<State *>(item)))
00304 {
00305 DBGLOG_SER("state serialized");
00306 m_serializedStates << StateSerializer(*state);
00307 boundingBox |= state->mapToScene(state->boundingRect()).boundingRect();
00308 state = NULL;
00309 }
00310 else if ((transition = dynamic_cast<Transition *>(item)))
00311 {
00312 DBGLOG_SER("transition serialized");
00313 m_serializedTransitions << TransitionSerializer(*transition);
00314 transition = NULL;
00315 }
00316
00317
00318 }
00319
00320 m_hotSpot = boundingBox.center();
00321
00322 DBGLOG_SER(DBGPAR(boundingBox) << DBGPAR(m_hotSpot));
00323 }
00324
00325 SelectionSerializer::SelectionSerializer(const SelectionSerializer &other)
00326 : m_valid(true)
00327 {
00328 m_serializedStates = other.m_serializedStates;
00329
00330 m_serializedTransitions = other.m_serializedTransitions;
00331 }
00332
00333 SelectionSerializer::TItemsPair SelectionSerializer::createItems(Editor *editor, const QPoint &pos)
00334 {
00335 TStateList states;
00336 TTransitionList transitions;
00337 QPointF translation;
00338
00339 TStateNameMap stateMap;
00340 State *state;
00341
00342 for(int i=0; i<m_serializedStates.count(); ++i)
00343 {
00344 translation = m_serializedStates[i].m_pos - m_hotSpot;
00345
00346 state = m_serializedStates[i].createState(editor, pos + translation.toPoint());
00347 Q_ASSERT(state && "state wasn't created!");
00348
00349 stateMap.insert(m_serializedStates[i].m_stateName, state);
00350
00351 DBGLOG_SER("origStateName" << m_serializedStates[i].m_stateName <<
00352 "newstateName=" << state->getName());
00353 states << state;
00354 }
00355
00356 Transition *transition;
00357
00358 for(int i=0; i<m_serializedTransitions.count(); ++i)
00359 {
00360 QList<State *> trStates;
00361 foreach(QString name, m_serializedTransitions[i].m_stateNames)
00362 {
00363 if (!stateMap.contains(name))
00364 {
00365 continue;
00366 }
00367
00368 trStates << stateMap.value(name);
00369 }
00370
00371 if (trStates.count() != m_serializedTransitions[i].m_stateNames.count())
00372 {
00373 DBGLOG_SER("transition dropped");
00374 continue;
00375 }
00376
00377 transition = m_serializedTransitions[i].createTransition(editor, trStates);
00378 transition->assign();
00379
00380 DBGLOG_SER(DBGPAR(trStates));
00381
00382 transitions << transition;
00383 }
00384
00385 return qMakePair(states, transitions);
00386 }
00387
00388