void Parser::parse( const QString &xml ) { QDomDocument doc( "kwscl" ); QString errorMsg; int errorLine, errorColumn; bool ok = doc.setContent( xml, true, &errorMsg, &errorLine, &errorColumn ); if ( !ok ) { qDebug( "Error parsing wscl (%d:%d) %s", errorLine, errorColumn, errorMsg.latin1() ); return; } QDomNodeList nodes = doc.elementsByTagName( "Conversation" ); if ( nodes.count() <= 0 ) { qDebug( "No conversation tag found in wscl data" ); return; } QDomElement conversationElement = nodes.item( 0 ).toElement(); mConversation.setName( conversationElement.attribute( "name" ) ); mConversation.setVersion( conversationElement.attribute( "version" ) ); mConversation.setDescription( conversationElement.attribute( "description" ) ); mConversation.setNameSpace( conversationElement.attribute( "targetNamespace" ) ); mConversation.setSchema( conversationElement.attribute( "hrefSchema" ) ); mConversation.setInitialInteraction( conversationElement.attribute( "initialInteraction" ) ); mConversation.setFinalInteraction( conversationElement.attribute( "finalInteraction" ) ); QDomNode node = conversationElement.firstChild(); while ( !node.isNull() ) { QDomElement element = node.toElement(); if ( !element.isNull() ) { if ( element.tagName() == "ConversationInteractions" ) { Interaction::List interactions; QDomNode interactionNode = element.firstChild(); while ( !interactionNode.isNull() ) { QDomElement interactionElement = interactionNode.toElement(); if ( !interactionElement.isNull() ) { if ( interactionElement.tagName() != "Interaction" ) { qDebug( "Expected tag name 'Interaction', got '%s'", interactionElement.tagName().latin1() ); continue; } Interaction interaction; interaction.setId( interactionElement.attribute( "id" ) ); const QString type = interactionElement.attribute( "interactionType" ); if ( type == "ReceiveSend" ) interaction.setType( Interaction::ReceiveSend ); else if ( type == "SendReceive" ) interaction.setType( Interaction::SendReceive ); else if ( type == "Receive" ) interaction.setType( Interaction::Receive ); else if ( type == "Send" ) interaction.setType( Interaction::Send ); else if ( type == "Empty" ) interaction.setType( Interaction::Empty ); else qDebug( "Unknown interaction type '%s'", type.latin1() ); XMLDocument::List inputDocuments; XMLDocument::List outputDocuments; XMLDocument inputDocument; XMLDocument outputDocument; QDomNode contentNode = interactionElement.firstChild(); while ( !contentNode.isNull() ) { QDomElement contentElement = contentNode.toElement(); if ( !contentElement.isNull() ) { const QString tagName = contentElement.tagName(); if ( tagName == "InboundXMLDocument" ) { XMLDocument document; document.setId( contentElement.attribute( "id" ) ); document.setSchema( contentElement.attribute( "hrefSchema" ) ); inputDocuments.append( document ); inputDocument = document; } else if ( tagName == "OutboundXMLDocument" ) { XMLDocument document; document.setId( contentElement.attribute( "id" ) ); document.setSchema( contentElement.attribute( "hrefSchema" ) ); outputDocuments.append( document ); outputDocument = document; } } contentNode = contentNode.nextSibling(); } switch ( interaction.type() ) { case Interaction::ReceiveSend: { ReceiveSendDocument document; document.setInputDocument( inputDocument ); document.setOutputDocuments( outputDocuments ); interaction.setReceiveSendDocument( document ); } break; case Interaction::SendReceive: { SendReceiveDocument document; document.setInputDocuments( inputDocuments ); document.setOutputDocument( outputDocument ); interaction.setSendReceiveDocument( document ); } break; case Interaction::Receive: { ReceiveDocument document; document.setInputDocument( inputDocument ); interaction.setReceiveDocument( document ); } break; case Interaction::Send: { SendDocument document; document.setOutputDocument( outputDocument ); interaction.setSendDocument( document ); } break; case Interaction::Empty: default: break; } interactions.append( interaction ); } interactionNode = interactionNode.nextSibling(); } mConversation.setInteractions( interactions ); } else if ( element.tagName() == "ConversationTransitions" ) { Transition::List transitions; QDomNode transitionNode = element.firstChild(); while ( !transitionNode.isNull() ) { QDomElement transitionElement = transitionNode.toElement(); if ( !transitionElement.isNull() ) { if ( transitionElement.tagName() != "Transition" ) { qDebug( "Expected tag name 'Transition', got '%s'", transitionElement.tagName().latin1() ); continue; } Transition transition; QDomNode contentNode = transitionElement.firstChild(); while ( !contentNode.isNull() ) { QDomElement contentElement = contentNode.toElement(); if ( !contentElement.isNull() ) { const QString tagName = contentElement.tagName(); if ( tagName == "SourceInteraction" ) transition.setSourceInteraction( contentElement.attribute( "href" ) ); else if ( tagName == "DestinationInteraction" ) transition.setDestinationInteraction( contentElement.attribute( "href" ) ); else if ( tagName == "SourceInteractionCondition" ) transition.setSourceInteractionCondition( contentElement.attribute( "href" ) ); else qDebug( "Unknown transition element %s", tagName.latin1() ); } contentNode = contentNode.nextSibling(); } transitions.append( transition ); } transitionNode = transitionNode.nextSibling(); } mConversation.setTransitions( transitions ); } } node = node.nextSibling(); } }
void InteractionProcessor::run() { std::stack<Interaction> undoStack; std::stack<Interaction> redoStack; view.refresh(); while (true) { Interaction interaction = interactionReader.nextInteraction(); if (interaction.type() == InteractionType::quit) { break; } else if (interaction.type() == InteractionType::undo) { if (!undoStack.empty()) { Interaction undoInteraction = undoStack.top(); Command* command = undoInteraction.command(); try { undoStack.pop(); redoStack.push(undoInteraction); command->undo(model); model.clearErrorMessage(); } catch(EditorException& e) { model.setErrorMessage(e.getReason()); delete command; } view.refresh(); } } else if (interaction.type() == InteractionType::redo) { if(!redoStack.empty()) { Interaction redoInteraction = redoStack.top(); Command* command = redoInteraction.command(); try { redoStack.pop(); undoStack.push(redoInteraction); command->execute(model); model.clearErrorMessage(); } catch(EditorException& e) { model.setErrorMessage(e.getReason()); delete command; } view.refresh(); } } else if (interaction.type() == InteractionType::command) { Command* command = interaction.command(); try { command->execute(model); undoStack.push(interaction); model.clearErrorMessage(); } catch (EditorException& e) { model.setErrorMessage(e.getReason()); delete command; } view.refresh(); // Note that you'll want to be more careful about when you delete // commands once you implement undo and redo. For now, since // neither is implemented, I've just deleted it immediately // after executing it. You'll need to wait to delete it until // you don't need it anymore. //delete command; } } while(!undoStack.empty()) { Interaction undoInteraction = undoStack.top(); delete undoInteraction.command(); undoStack.pop(); } while(!redoStack.empty()) { Interaction redoInteraction = redoStack.top(); delete redoInteraction.command(); redoStack.pop(); } }
void InteractionProcessor::run() { view.refresh(); std::vector<Command*> undo; std::vector<Command*> redo; while (true) { Interaction interaction = interactionReader.nextInteraction(); Command* command = interaction.command(); Command* undoCommand = nullptr; Command* redoCommand = nullptr; if (interaction.type() == InteractionType::quit) { for (auto i = undo.begin(); i < undo.end(); i++) { delete *i; } for (auto j = redo.begin(); j < redo.end(); j++) { delete *j; } delete undoCommand; delete redoCommand; delete command; break; } else if (interaction.type() == InteractionType::undo) { if (undo.size() > 0) { undoCommand = undo.back(); try { undoCommand->undo(model); } catch (EditorException& e) { model.setErrorMessage(e.getReason()); } redo.push_back(undoCommand); undo.pop_back(); } view.refresh(); } else if (interaction.type() == InteractionType::redo) { if (redo.size() > 0) { redoCommand = redo.back(); try { redoCommand->execute(model); } catch (EditorException& e) { model.setErrorMessage(e.getReason()); } undo.push_back(redoCommand); redo.pop_back(); } view.refresh(); } else if (interaction.type() == InteractionType::command) { // Command* command = interaction.command(); undo.push_back(command); try { command->execute(model); model.clearErrorMessage(); } catch (EditorException& e) { model.setErrorMessage(e.getReason()); } view.refresh(); // Note that you'll want to be more careful about when you delete // commands once you implement undo and redo. For now, since // neither is implemented, I've just deleted it immediately // after executing it. You'll need to wait to delete it until // you don't need it anymore. } } }