diff --git a/Modules/IGT/CMakeLists.txt b/Modules/IGT/CMakeLists.txt index 84de8cfe35..7067c79cd6 100644 --- a/Modules/IGT/CMakeLists.txt +++ b/Modules/IGT/CMakeLists.txt @@ -1,46 +1,46 @@ include(MITKIGTHardware.cmake) if(MITK_USE_MICRON_TRACKER) set(INCLUDE_DIRS_INTERNAL ${INCLUDE_DIRS_INTERNAL} ${MITK_MICRON_TRACKER_INCLUDE_DIR}) set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${MITK_MICRON_TRACKER_LIB}) endif(MITK_USE_MICRON_TRACKER) if(MITK_USE_MICROBIRD_TRACKER) set(INCLUDE_DIRS_INTERNAL ${INCLUDE_DIRS_INTERNAL} ${MITK_USE_MICROBIRD_TRACKER_INCLUDE_DIR}) set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${MITK_USE_MICROBIRD_TRACKER_LIB}) endif(MITK_USE_MICROBIRD_TRACKER) MITK_CREATE_MODULE(MitkIGT SUBPROJECTS MITK-IGT - INCLUDE_DIRS IGTFilters IGTTrackingDevices IGTToolManagement + INCLUDE_DIRS IGTFilters IGTTrackingDevices IGTToolManagement IGTExceptionHandling INTERNAL_INCLUDE_DIRS ${INCLUDE_DIRS_INTERNAL} DEPENDS Mitk tinyxml SceneSerialization ADDITIONAL_LIBS "${ADDITIONAL_LIBS}" ) MITK_INSTALL(FILES ${MITK_SOURCE_DIR}/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/ClaronMicron.stl ) MITK_INSTALL(FILES ${MITK_SOURCE_DIR}/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/IntuitiveDaVinci.stl ) MITK_INSTALL(FILES ${MITK_SOURCE_DIR}/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/NDIAurora.stl ) MITK_INSTALL(FILES ${MITK_SOURCE_DIR}/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/NDIAurora_Dome.stl ) MITK_INSTALL(FILES ${MITK_SOURCE_DIR}/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/NDIAuroraCompactFG_Dome.stl ) MITK_INSTALL(FILES ${MITK_SOURCE_DIR}/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/NDIAuroraPlanarFG_Dome.stl ) MITK_INSTALL(FILES ${MITK_SOURCE_DIR}/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/NDIAuroraTabletopFG_Dome.stl ) MITK_INSTALL(FILES ${MITK_SOURCE_DIR}/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/NDIAuroraTabletopFG_Prototype_Dome.stl ) MITK_INSTALL(FILES ${MITK_SOURCE_DIR}/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/NDIPolaris.stl ) MITK_INSTALL(FILES ${MITK_SOURCE_DIR}/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/NDIPolarisVicra.stl ) MITK_INSTALL(FILES ${MITK_SOURCE_DIR}/Modules/IGT/IGTTrackingDevices/TrackingVolumeData/StandardVolume.stl ) MITK_CHECK_MODULE(_RESULT MitkIGT) if(_RESULT) message(STATUS "IGTTutorialStep1 won't be built. Missing: ${_RESULT}") else(_RESULT) ## create IGT config configure_file(mitkIGTConfig.h.in ${PROJECT_BINARY_DIR}/mitkIGTConfig.h @ONLY) # add test programm for serial communication classADD_EXECUTABLE(SerialCommunicationTest IGTTrackingDevices/mitkSerialCommunicationTest.cpp)target_link_libraries(SerialCommunicationTest mitkIGT Mitk tinyxml PocoXML) add_subdirectory(IGTTutorial) add_subdirectory(Testing) endif(_RESULT) diff --git a/Modules/IGT/IGTExceptionHandling/mitkIGTIOException.cpp b/Modules/IGT/IGTExceptionHandling/mitkIGTIOException.cpp new file mode 100644 index 0000000000..299c95c703 --- /dev/null +++ b/Modules/IGT/IGTExceptionHandling/mitkIGTIOException.cpp @@ -0,0 +1,17 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkIGTIOException.h" diff --git a/Modules/IGT/IGTExceptionHandling/mitkIGTIOException.h b/Modules/IGT/IGTExceptionHandling/mitkIGTIOException.h new file mode 100644 index 0000000000..5c526c97f9 --- /dev/null +++ b/Modules/IGT/IGTExceptionHandling/mitkIGTIOException.h @@ -0,0 +1,34 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef IGTIOEXCEPTION_H_INCLUDED +#define IGTIOEXCEPTION_H_INCLUDED + +#include "mitkIGTException.h" +#include "mitkExceptionMacro.h" + +namespace mitk { + /**Documentation + * \brief An object of this class represents an exception of the MITK-IGT module which are releated to the hardware (e.g. connection problems, etc.). + * + * \ingroup IGT + */ class MitkIGT_EXPORT IGTIOException : public mitk::IGTException + { + public: + mitkExceptionClassMacro(IGTIOException,mitk::IGTException); + }; +} // namespace mitk +#endif diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.cpp b/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.cpp index aad1e3bc7c..4dee64981f 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.cpp +++ b/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.cpp @@ -1,536 +1,568 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkNavigationDataPlayer.h" //for the pause #include #include #include +//for exceptions +#include "mitkIGTException.h" +#include "mitkIGTIOException.h" + +// default constructor of type mitk mitk::NavigationDataPlayer::NavigationDataPlayer() : mitk::NavigationDataPlayerBase() { m_NumberOfOutputs = 0; m_Pause = false; m_Playing = false; m_Stream = NULL; m_PlayerMode = NormalFile; m_FileName = ""; m_FileVersion = 1; m_Playing = false; m_Pause = false; m_NumberOfOutputs = 0; m_StartPlayingTimeStamp = 0.0; m_PauseTimeStamp = 0.0; m_parentElement = NULL; m_currentNode = NULL; m_StreamEnd = false; m_StreamSetOutsideFromClass = false; //To get a start time mitk::TimeStamp::GetInstance()->Start(this); } mitk::NavigationDataPlayer::~NavigationDataPlayer() { StopPlaying(); delete m_parentElement; } void mitk::NavigationDataPlayer::GenerateData() { //Only produce new output if the player is started - if (!m_Playing) + if (!m_Playing) // !m_Playing=true means player has started { //The output is not valid anymore for (unsigned int index = 0; index < m_NumberOfOutputs; index++) { mitk::NavigationData* output = this->GetOutput(index); assert(output); mitk::NavigationData::Pointer nd = mitk::NavigationData::New(); mitk::NavigationData::PositionType position; mitk::NavigationData::OrientationType orientation(0.0,0.0,0.0,0.0); position.Fill(0.0); nd->SetPosition(position); nd->SetOrientation(orientation); nd->SetDataValid(false); output->Graft(nd); } return; } //first of all get current time TimeStampType now = mitk::TimeStamp::GetInstance()->GetElapsed(); //now we make a little time arithmetic //to get the elapsed time since the start of the player TimeStampType timeSinceStart = now - m_StartPlayingTimeStamp; - //init the vectors std::vector< NavigationData::Pointer > nextCandidates; std::vector< NavigationData::Pointer > lastCandidates; std::vector< NavigationData::TimeStampType > currentTimeOfData; - for (unsigned int index=0; index < m_NumberOfOutputs; index++) { - + // m_NextToPlayNavigationData - vector nextCandidates.push_back(m_NextToPlayNavigationData.at(index)); lastCandidates.push_back(m_NextToPlayNavigationData.at(index)); currentTimeOfData.push_back(timeSinceStart + m_StartTimeOfData.at(index)); } if (m_NextToPlayNavigationData.size() != m_NumberOfOutputs) { MITK_ERROR << "Mismatch in data"; return; } // Now we try to find next NavigationData in the stream: // This means we step through the stream of NavigationDatas until we find // a NavigationData which has a current timestamp (currentTimeOfData) greater - // then the current playing time. Then we store the data in + // than the current playing time. Then we store the data in // m_NextToPlayNavigationData and take the last data (lastCandidates) for the // output of this filter. // // The loop will stop when a suitable NavigationData is found or we reach EOF. // The timestamps of each recorded NavigationData should be equal // therefore we take always the time from the first. - while( nextCandidates[0]->GetTimeStamp() < currentTimeOfData[0]) { for (unsigned int index=0; index < m_NumberOfOutputs; index++) { lastCandidates[index] = nextCandidates.at(index); - + // m_FileVersion indicates which XML encoding is used switch(m_FileVersion) { case 1: nextCandidates[index] = ReadVersion1(); break; default: //this case should not happen! therefore the return at this point return; break; } //check if the input stream delivered a correct NavigationData object + //Stops playing because there is now more nextCandidate, the file ended for all outputs for (unsigned int i = 0; i < m_NumberOfOutputs; i++) { if (nextCandidates.at(index).IsNull()) { m_StreamEnd = true; StopPlaying(); return; //the case if no NavigationData is found, e.g. EOF, bad stream } } } } + //Now lastCandidates stores the new output and nextCandidates is stored to the m_NextToPlay vector for (unsigned int index = 0; index < m_NumberOfOutputs; index++) { mitk::NavigationData* output = this->GetOutput(index); assert(output); - + //always takes the lastCandidate, because we can not go to the next Candidata at the current moment output->Graft(lastCandidates.at(index)); m_NextToPlayNavigationData[index] = nextCandidates.at(index); } } void mitk::NavigationDataPlayer::UpdateOutputInformation() { this->Modified(); // make sure that we need to be updated Superclass::UpdateOutputInformation(); } void mitk::NavigationDataPlayer::InitPlayer() { - if (m_Stream == NULL) - { + if (m_Stream == NULL){ StreamInvalid("Playing not possible. Wrong file name or path?"); return; } if (!m_Stream->good()) { - StreamInvalid("Playing not possible. Stream is not good!"); + StreamInvalid("Playing not possible. Stream is not good!"); return; } - - m_FileVersion = GetFileVersion(m_Stream); //first get the file version - //check if we have a valid version + +m_FileVersion = GetFileVersion(m_Stream); //first get the file version + + + +//check if we have a valid version +//m_FileVersion has to be always be bigger than 1 for playing if (m_FileVersion < 1) - { - StreamInvalid("Playing not possible. Invalid file version!"); - return; + { + StreamInvalid("Playing not possible. Invalid file version!"); + return; } - //now read the number of Tracked Tools + //now read the number of Tracked Tools if(m_NumberOfOutputs == 0){m_NumberOfOutputs = GetNumberOfNavigationDatas(m_Stream);} //with the information about the tracked tool number we can generate the output if (m_NumberOfOutputs > 0) { //Generate the output only if there are changes to the amount of outputs //This happens when the player is stopped and start again with different file if (this->GetNumberOfOutputs() != m_NumberOfOutputs) {SetNumberOfOutputs(m_NumberOfOutputs);} //initialize the player with first data GetFirstData(); //set stream valid m_ErrorMessage = ""; m_StreamValid = true; } else { StreamInvalid("The input stream seems to have NavigationData incompatible format"); return; } } unsigned int mitk::NavigationDataPlayer::GetFileVersion(std::istream* stream) { if (stream==NULL) { MITK_ERROR << "No input stream set!"; - return 0; + mitkThrowException(mitk::IGTException)<<"No input stream set!"; } if (!stream->good()) { - MITK_ERROR << "Stream not good!"; - return 0; + MITK_ERROR << "Stream is not good!"; + mitkThrowException(mitk::IGTException)<<"Stream is not good!"; + return 0; //add an exception here? } int version = 1; TiXmlDeclaration* dec = new TiXmlDeclaration(); *stream >> *dec; if(strcmp(dec->Version(),"") == 0){ MITK_ERROR << "The input stream seems to have XML incompatible format"; - return 0; + mitkThrowException(mitk::IGTIOException) << "The input stream seems to have XML incompatible format"; } m_parentElement = new TiXmlElement(""); *stream >> *m_parentElement; //2nd line this is the file version std::string tempValue = m_parentElement->Value(); if(tempValue != "Version") { if(tempValue == "Data"){ m_parentElement->QueryIntAttribute("version",&version); } } else { m_parentElement->QueryIntAttribute("Ver",&version); } if (version > 0) return version; else return 0; } unsigned int mitk::NavigationDataPlayer::GetNumberOfNavigationDatas(std::istream* stream) { if (stream == NULL) - { + { + mitkThrowException(mitk::IGTException)<<"No input stream set!"; MITK_ERROR << "No input stream set!"; return 0; } if (!stream->good()) - { + { + mitkThrowException(mitk::IGTException)<<"Stream not good!"; MITK_ERROR << "Stream not good!"; return 0; } //If something has changed in a future version of the XML definition e.g. navigationcount or addional parameters //catch this here with a select case block (see GenerateData() method) int numberOfTools = 0; std::string tempValue = m_parentElement->Value(); if(tempValue == "Version"){ *stream >> *m_parentElement; } m_parentElement->QueryIntAttribute("ToolCount",&numberOfTools); if (numberOfTools > 0) return numberOfTools; return 0; } mitk::NavigationData::Pointer mitk::NavigationDataPlayer::ReadVersion1() { if (m_Stream == NULL) { m_Playing = false; + mitkThrowException(mitk::IGTException) << "Playing not possible. Wrong file name or path? "; MITK_ERROR << "Playing not possible. Wrong file name or path? "; return NULL; } if (!m_Stream->good()) { m_Playing = false; + mitkThrowException(mitk::IGTException) << "Playing not possible. Stream is not good!"; MITK_ERROR << "Playing not possible. Stream is not good!"; return NULL; } /*TiXmlElement* elem = new TiXmlElement(""); m_currentNode = m_parentElement->IterateChildren(m_currentNode); if(m_currentNode) { elem = m_currentNode->ToElement(); }*/ TiXmlElement* elem; m_currentNode = m_parentElement->IterateChildren(m_currentNode); bool delElem; if(m_currentNode) { elem = m_currentNode->ToElement(); + if(elem==NULL){mitkThrowException(mitk::IGTException) << "DamagedFileException!"; + } + //maybe: throw "DamagedFileException" if elem is NULL? delElem = false; } else { elem = new TiXmlElement(""); delElem = true; } mitk::NavigationData::Pointer nd = this->ReadNavigationData(elem); if(delElem) delete elem; return nd; } - void mitk::NavigationDataPlayer::StartPlaying() { if (m_Stream == NULL) { m_Playing = false; - //Perhaps the SetStream method was not called so we do this when a FileName is set with SetStream(PlayerMode) if (m_FileName != "") { - //The PlayerMode is initialized with LastSetStream - //SetStream also calls InitPlayer() - SetStream(m_PlayerMode); + //The PlayerMode is initialized with LastSetStream + //CreateStreamFromFilename also calls InitPlayer() + try + { + CreateStreamFromFilename(); + } + catch(mitk::IGTIOException e) + { + MITK_ERROR << "Cannot create stream from filename, please check the stream"; + throw e; //todo replace by macro + } + catch(mitk::IGTException e2) + { + MITK_ERROR << "Cannot open the file, please check the file"; + throw e2;//todo replace by macro + } } //now check again if (m_Stream == NULL) { StopPlaying(); MITK_ERROR << "Playing not possible. Wrong file name or path?"; - return; + mitkThrowException(mitk::IGTException) << "Playing not possible. Wrong file name or path?"; } } if (!m_Playing && m_Stream->good()) { - m_Playing = true; //starts the player + m_Playing = true; m_StartPlayingTimeStamp = mitk::TimeStamp::GetInstance()->GetElapsed(); } else { MITK_ERROR << "Player already started or stream is not good!"; StopPlaying(); } } + + void mitk::NavigationDataPlayer::StopPlaying() { //re init all data!! for playing again with different data //only PlayerMode and FileName are not changed m_Pause = false; m_Playing = false; if (!m_StreamSetOutsideFromClass) {delete m_Stream;} m_Stream = NULL; m_FileVersion = 1; m_Playing = false; m_Pause = false; m_StartPlayingTimeStamp = 0.0; m_PauseTimeStamp = 0.0; m_NextToPlayNavigationData.clear(); m_StartTimeOfData.clear(); } void mitk::NavigationDataPlayer::GetFirstData() { //Here we read the first lines of input (dependend on the number of inputs) for (unsigned int index=0; index < m_NumberOfOutputs; index++) { //Here we init the vector for later use m_NextToPlayNavigationData.push_back(NULL); m_StartTimeOfData.push_back(0.0); mitk::NavigationData::Pointer nd = this->GetOutput(index); switch(m_FileVersion) { case 1: m_NextToPlayNavigationData[index] = ReadVersion1(); //check if there is valid data in it if (m_NextToPlayNavigationData[index].IsNull()) { m_StreamEnd = true; StopPlaying(); - MITK_ERROR << "XML File is corrupt or has no NavigationData" << std::endl; + //Exception is thrown + mitkThrowException(mitk::IGTIOException) << "XML File is corrupt or has no NavigationData"; return; } //Have a look it the output was set already without this check the pipline will disconnect after a start/stop cycle if (nd.IsNull()) this->SetNthOutput(index, m_NextToPlayNavigationData[index]); m_StartTimeOfData[index] = m_NextToPlayNavigationData[index]->GetTimeStamp(); break; - default: //this case should not happen! therefore the return at this point + default: //this case should not happen! therefore the return at this point return; break; } } } void mitk::NavigationDataPlayer::Pause() { //player runs and pause was called -> pause the player if(m_Playing && !m_Pause) { m_Playing = false; m_Pause = true; m_PauseTimeStamp = mitk::TimeStamp::GetInstance()->GetElapsed(); } else { MITK_ERROR << "Player is either not started or already is paused" << std::endl; } } void mitk::NavigationDataPlayer::Resume() { //player is in pause mode -> play at the last position if(!m_Playing && m_Pause) { m_Playing = true; m_Pause = false; mitk::NavigationData::TimeStampType now = mitk::TimeStamp::GetInstance()->GetElapsed(); // in this case m_StartPlayingTimeStamp is set to the total elapsed time with NO playback m_StartPlayingTimeStamp = now - (m_PauseTimeStamp - m_StartPlayingTimeStamp); } else { MITK_ERROR << "Player is not paused!" << std::endl; } } -void mitk::NavigationDataPlayer::SetStream( PlayerMode /*mode*/ ) +void mitk::NavigationDataPlayer::CreateStreamFromFilename() { m_Stream = NULL; if (!itksys::SystemTools::FileExists(m_FileName.c_str())) { - MITK_ERROR << "File dont exist!" << std::endl; + //Exception is thrown + mitkThrowException(mitk::IGTIOException) << "File does not exist!"; return; } switch(m_PlayerMode) { + // so we can only read normal files not zip file case NormalFile: m_Stream = new std::ifstream(m_FileName.c_str()); m_StreamSetOutsideFromClass = false; break; case ZipFile: - m_Stream = NULL; MITK_ERROR << "Sorry no ZipFile support yet"; - break; + // Exception is thrown, if the stream is NULL default: m_Stream = NULL; + mitkThrowException(mitk::IGTException)<<"The stream is NULL"; break; } this->Modified(); InitPlayer(); } void mitk::NavigationDataPlayer::SetStream( std::istream* stream ) { if ( (stream == NULL) || (!stream->good())) { + // throw an exception for stream=NULL or it is not good + mitkThrowException(mitk::IGTException) << "The stream is NULL or it is not good"; m_StreamEnd = true; - MITK_ERROR << "The stream is not good"; return; } m_Stream = stream; m_StreamSetOutsideFromClass = true; this->Modified(); InitPlayer(); } bool mitk::NavigationDataPlayer::IsAtEnd() { return this->m_StreamEnd; } void mitk::NavigationDataPlayer::StreamInvalid(std::string message) { m_StreamEnd = true; StopPlaying(); m_ErrorMessage = message; m_StreamValid = false; - MITK_ERROR << m_ErrorMessage; + mitkThrowException(mitk::IGTIOException) << "Invalid stream!"; return; -} +} \ No newline at end of file diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.h b/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.h index 7f714bd76f..2be6c0e6b8 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.h +++ b/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.h @@ -1,205 +1,227 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKNavigationDataPlayer_H_HEADER_INCLUDED_ #define MITKNavigationDataPlayer_H_HEADER_INCLUDED_ #include #include #include //for the Recording Mode enum #include "mitkTrackingDevice.h" #include #include "tinyxml.h" #include namespace mitk { /**Documentation * \brief This class is used to play recorded (see mitkNavigationDataRecorder class) files. * * If you want to play a file you have to set an input stream. This can be an own one (use StartPlaying(std::istream*)) * or a preset (use StartPlaying()). The presets are NormalFile and ZipFile and can be set with the method * SetPlayerMode(PlayerMode). The presets need a FileName. Therefore the FileName must be set before the preset. * For pausing the player call Pause(). A call of Resume() will continue the playing. * * * \ingroup IGT */ class MitkIGT_EXPORT NavigationDataPlayer : public NavigationDataPlayerBase { public: mitkClassMacro(NavigationDataPlayer, NavigationDataPlayerBase); itkNewMacro(Self); /** * \brief sets the file name and path for the PlayerMode NormalFile and ZipFile */ itkSetStringMacro(FileName); /** * \brief returns the file name and path for the PlayerMode NormalFile and ZipFile */ itkGetStringMacro(FileName); /** * \brief Used for pipeline update just to tell the pipeline that we always have to update */ virtual void UpdateOutputInformation(); /** * \brief This method starts the player. * * Before the stream has to be set. Either with a PlayingMode (SetStream(PlayerMode)) and FileName. Or * with an own inputstream (SetStream(istream*)). + * + * @throws mitk::IGTIOException Throws an exception if the file cannot be opened + * @throws mitk::IGTIOException Throws an exception if there is no file choosen + * @throws mitk::IGTException Throws an exception if there is no stream (i.e stream=NULL) + * @throws mitk::IGTIOException Throws an exception if the file is damaged */ void StartPlaying(); /** * \brief Stops the player and closes the stream. After a call of StopPlaying() * StartPlaying() must be called to get new output data * * \warning the output is generated in this method because we know first about the number of output after * reading the first lines of the XML file. Therefore you should assign your output after the call of this method */ void StopPlaying(); /** * \brief This method pauses the player. If you want to play again call Resume() * *\warning This method is not tested yet. It is not save to use! */ void Pause(); /** * \brief This method resumes the player when it was paused. * *\warning This method is not tested yet. It is not save to use! */ void Resume(); /** * \brief This method checks if player arrived at end of file. * *\warning This method is not tested yet. It is not save to use! */ bool IsAtEnd(); /** * \brief The PlayerMode is used for generating a presetted output stream. You do not need to * set it if you want to use your own stream. * * There are: * NormalFile: ifstream * ZipFile: not implemented yet * *\warning The ZipFile Mode is not implemented yet */ enum PlayerMode { NormalFile, ZipFile }; - /** - * \brief sets the recording mode which causes different types of output streams - * This method is overloaded with SetStream( ostream* ) - */ - void SetStream(PlayerMode mode); - /** * \brief sets the recording mode which causes different types of output streams * This method is overloaded with SetStream( PlayerMode ) + * + *@throws mitk::IGTException Throws an exception if stream is NULL or if it is not good. */ void SetStream(std::istream* stream); + + + protected: NavigationDataPlayer(); virtual ~NavigationDataPlayer(); typedef mitk::NavigationData::TimeStampType TimeStampType; /** * \brief filter execute method */ virtual void GenerateData(); + + /** + * \brief sets the recording mode which causes different types of output streams + * This method is overloaded with SetStream( ostream* ) + * + * @throws mitk::IGTIOException Throws an exception if file does not exist + * @throws mitk::IGTException Throws an exception if the stream is NULL + */ + void CreateStreamFromFilename(); + + /** - * \brief Returns the file version out of the XML document. + * \brief Returns the file version out of the XML document. + * @throws Throws an exception if stream is NULL + * @throws Throws an exception if stream in not good */ unsigned int GetFileVersion(std::istream* stream); /** * \brief Returns the number of tracked tools out of the XML document. + * @throw Throws an exception if stream is NULL (exception havent been thrown yet)????????? + * @throw Throws an exception if the input stream seems to have XML incompatible format */ unsigned int GetNumberOfNavigationDatas(std::istream* stream); /** * \brief Gets the first data for initializing the player */ void GetFirstData(); /** * \brief This method reads one line of the XML document and returns the data as a NavigationData object * If there is a new file version another method must be added which reads this data. + * @throws mitk::IGTException Throws an exceptions if file is damaged */ mitk::NavigationData::Pointer ReadVersion1(); /** * \brief This method initializes the player with first data */ void InitPlayer(); std::istream* m_Stream; ///< stores a pointer to the input stream bool m_StreamSetOutsideFromClass; ///< stores if the stream was created in this class and must be deleted in the end PlayerMode m_PlayerMode; ///< stores the mode for the presetted PlayerMode sieh enum PlayerMode std::string m_FileName; ///< stores the filename unsigned int m_FileVersion; ///< indicates which XML encoding is used bool m_Playing; ///< indicates whether the generateoutput method generates new output or not bool m_Pause; ///< indicates if the player is paused unsigned int m_NumberOfOutputs; ///< stores the number of outputs known from the XML document TimeStampType m_StartPlayingTimeStamp; ///< the starttime of the playing set in the method StartPlaying() TimeStampType m_PauseTimeStamp; ///< stores the beginning of a pause std::vector m_NextToPlayNavigationData; ///< stores the next possible candidate for playing std::vector m_StartTimeOfData; ///< stores the start time of the different tools TiXmlElement * m_parentElement; TiXmlNode * m_currentNode; bool m_StreamEnd; ///< stores if the input stream arrived at end - + /** + *@throws mitk::IGTIOException Throws an exception if the stream is invalid + **/ void StreamInvalid(std::string message); ///< help method which sets the stream invalid and displays an error }; } // namespace mitk #endif /* MITKNavigationDataPlayer_H_HEADER_INCLUDED_ */ diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataPlayerBase.cpp b/Modules/IGT/IGTFilters/mitkNavigationDataPlayerBase.cpp index affee18ae2..e91ea81065 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataPlayerBase.cpp +++ b/Modules/IGT/IGTFilters/mitkNavigationDataPlayerBase.cpp @@ -1,118 +1,119 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkNavigationDataPlayerBase.h" mitk::NavigationDataPlayerBase::NavigationDataPlayerBase() { m_StreamValid = true; m_ErrorMessage = ""; } mitk::NavigationDataPlayerBase::~NavigationDataPlayerBase() { } void mitk::NavigationDataPlayerBase::UpdateOutputInformation() { this->Modified(); // make sure that we need to be updated Superclass::UpdateOutputInformation(); } mitk::NavigationData::Pointer mitk::NavigationDataPlayerBase::ReadNavigationData(TiXmlElement* elem) { + if (elem == NULL) {mitkThrow() << "Error: Element is NULL!";} + mitk::NavigationData::Pointer nd = mitk::NavigationData::New(); mitk::NavigationData::PositionType position; mitk::NavigationData::OrientationType orientation(0.0,0.0,0.0,0.0); mitk::NavigationData::TimeStampType timestamp = -1; mitk::NavigationData::CovarianceMatrixType matrix; bool hasPosition = true; bool hasOrientation = true; bool dataValid = false; position.Fill(0.0); matrix.SetIdentity(); - elem->QueryDoubleAttribute("Time",×tamp); if (timestamp == -1) { return NULL; //the calling method should check the return value if it is valid/not NULL } elem->QueryFloatAttribute("X", &position[0]); elem->QueryFloatAttribute("Y", &position[1]); elem->QueryFloatAttribute("Z", &position[2]); elem->QueryFloatAttribute("QX", &orientation[0]); elem->QueryFloatAttribute("QY", &orientation[1]); elem->QueryFloatAttribute("QZ", &orientation[2]); elem->QueryFloatAttribute("QR", &orientation[3]); elem->QueryFloatAttribute("C00", &matrix[0][0]); elem->QueryFloatAttribute("C01", &matrix[0][1]); elem->QueryFloatAttribute("C02", &matrix[0][2]); elem->QueryFloatAttribute("C03", &matrix[0][3]); elem->QueryFloatAttribute("C04", &matrix[0][4]); elem->QueryFloatAttribute("C05", &matrix[0][5]); elem->QueryFloatAttribute("C10", &matrix[1][0]); elem->QueryFloatAttribute("C11", &matrix[1][1]); elem->QueryFloatAttribute("C12", &matrix[1][2]); elem->QueryFloatAttribute("C13", &matrix[1][3]); elem->QueryFloatAttribute("C14", &matrix[1][4]); elem->QueryFloatAttribute("C15", &matrix[1][5]); int tmpval = 0; elem->QueryIntAttribute("Valid", &tmpval); if (tmpval == 0) dataValid = false; else dataValid = true; tmpval = 0; elem->QueryIntAttribute("hO", &tmpval); if (tmpval == 0) hasOrientation = false; else hasOrientation = true; tmpval = 0; elem->QueryIntAttribute("hP", &tmpval); if (tmpval == 0) hasPosition = false; else hasPosition = true; nd->SetTimeStamp(timestamp); nd->SetPosition(position); nd->SetOrientation(orientation); nd->SetCovErrorMatrix(matrix); nd->SetDataValid(dataValid); nd->SetHasOrientation(hasOrientation); nd->SetHasPosition(hasPosition); return nd; } diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataPlayerBase.h b/Modules/IGT/IGTFilters/mitkNavigationDataPlayerBase.h index 61a598b12b..fe48097463 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataPlayerBase.h +++ b/Modules/IGT/IGTFilters/mitkNavigationDataPlayerBase.h @@ -1,77 +1,78 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKNavigationDataPlayerBase_H_HEADER_INCLUDED_ #define MITKNavigationDataPlayerBase_H_HEADER_INCLUDED_ #include #include "tinyxml.h" namespace mitk{ /**Documentation * \brief This class is a slightly changed reimplementation of the * NavigationDataPlayer which does not care about timestamps and just * outputs the navigationdatas in their sequential order * * \ingroup IGT */ class MitkIGT_EXPORT NavigationDataPlayerBase : public NavigationDataSource { public: mitkClassMacro(NavigationDataPlayerBase, NavigationDataSource); /** * \brief Used for pipeline update just to tell the pipeline that we always have to update */ virtual void UpdateOutputInformation(); /** @return Returns an error message if there was one (e.g. if the stream is invalid). * Returns an empty string if there was no error in the current stream. */ itkGetStringMacro(ErrorMessage); /** @return Retruns if the current stream is valid or not. */ itkGetMacro(StreamValid,bool); /** * \brief This method checks if player arrived at end of file. * *\warning This method is not tested yet. It is not save to use! */ bool IsAtEnd(); protected: NavigationDataPlayerBase(); virtual ~NavigationDataPlayerBase(); virtual void GenerateData() = 0; /** * \brief Creates NavigationData from XML element and returns it + * @throw mitk::Exception Throws an exception if elem is NULL. */ mitk::NavigationData::Pointer ReadNavigationData(TiXmlElement* elem); bool m_StreamValid; ///< stores if the input stream is valid or not std::string m_ErrorMessage; ///< stores the error message if the stream is invalid }; } // namespace mitk #endif /* MITKNavigationDataSequentialPlayer_H_HEADER_INCLUDED_ */ diff --git a/Modules/IGT/Testing/files.cmake b/Modules/IGT/Testing/files.cmake index 4c70dc3ca9..e380216f2c 100644 --- a/Modules/IGT/Testing/files.cmake +++ b/Modules/IGT/Testing/files.cmake @@ -1,49 +1,49 @@ set(MODULE_TESTS mitkCameraVisualizationTest.cpp mitkClaronInterfaceTest.cpp mitkClaronToolTest.cpp mitkClaronTrackingDeviceTest.cpp mitkInternalTrackingToolTest.cpp mitkNavigationDataDisplacementFilterTest.cpp mitkNavigationDataLandmarkTransformFilterTest.cpp mitkNavigationDataObjectVisualizationFilterTest.cpp mitkNavigationDataTest.cpp mitkNavigationDataRecorderTest.cpp mitkNavigationDataReferenceTransformFilterTest.cpp mitkNavigationDataSequentialPlayerTest.cpp mitkNavigationDataSourceTest.cpp mitkNavigationDataToMessageFilterTest.cpp mitkNavigationDataToNavigationDataFilterTest.cpp mitkNavigationDataToPointSetFilterTest.cpp mitkNavigationDataTransformFilterTest.cpp mitkNDIPassiveToolTest.cpp mitkNDIProtocolTest.cpp mitkNDITrackingDeviceTest.cpp mitkTimeStampTest.cpp mitkTrackingVolumeGeneratorTest.cpp mitkTrackingDeviceTest.cpp mitkTrackingToolTest.cpp mitkVirtualTrackingDeviceTest.cpp - # mitkNavigationDataPlayerTest.cpp # deactivated see bug 11636 + mitkNavigationDataPlayerTest.cpp # deactivated see bug 11636 mitkTrackingDeviceSourceTest.cpp mitkTrackingDeviceSourceConfiguratorTest.cpp mitkNavigationDataEvaluationFilterTest.cpp mitkTrackingTypesTest.cpp # ------------------ Navigation Tool Management Tests ------------------- mitkNavigationToolStorageTest.cpp mitkNavigationToolStorageSerializerAndDeserializerTest.cpp mitkNavigationToolTest.cpp mitkNavigationToolReaderAndWriterTest.cpp # ----------------------------------------------------------------------- # ------------------ Deavtivated Tests ---------------------------------- # ----------------------------------------------------------------------- ) set(MODULE_CUSTOM_TESTS mitkNDIAuroraHardwareTest.cpp mitkNDIPolarisHardwareTest.cpp mitkClaronTrackingDeviceHardwareTest.cpp ) \ No newline at end of file diff --git a/Modules/IGT/Testing/mitkNavigationDataPlayerTest.cpp b/Modules/IGT/Testing/mitkNavigationDataPlayerTest.cpp index 4af31878ad..709f6e52fb 100644 --- a/Modules/IGT/Testing/mitkNavigationDataPlayerTest.cpp +++ b/Modules/IGT/Testing/mitkNavigationDataPlayerTest.cpp @@ -1,351 +1,550 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkNavigationDataPlayer.h" #include "mitkNavigationData.h" #include "mitkTestingMacros.h" #include "mitkStandardFileLocations.h" #include "mitkTimeStamp.h" #include #include #include +#include "mitkIGTException.h" +#include "mitkIGTIOException.h" + + + +#include + class mitkNavigationDataPlayerTestClass { public: static void TestInstantiation() { // let's create an object of our class mitk::NavigationDataPlayer::Pointer player = mitk::NavigationDataPlayer::New(); // first test: did this work? // using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since // it makes no sense to continue without an object. MITK_TEST_CONDITION_REQUIRED(player.IsNotNull(), "Testing instantiation"); } static void TestSimpleDataPlay() { std::string tmp = ""; // let's create an object of our class mitk::NavigationDataPlayer::Pointer player = mitk::NavigationDataPlayer::New(); std::string file = mitk::StandardFileLocations::GetInstance()->FindFile("NavigationDataTestData.xml", "Modules/IGT/Testing/Data"); player->SetFileName( file ); MITK_TEST_CONDITION_REQUIRED( strcmp(player->GetFileName(), file.c_str()) == 0, "Testing SetFileName and GetFileName"); - - player->SetStream( mitk::NavigationDataPlayer::NormalFile ); + //exception is thrown in StartPlaying method player->StartPlaying(); player->Update(); - player->StopPlaying(); + player->StopPlaying();; mitk::NavigationData::Pointer nd = player->GetOutput(); mitk::Point3D pnt; pnt[0] = 1; pnt[1] = 0; pnt[2] = 3; MITK_TEST_CONDITION_REQUIRED( nd->GetPosition() == pnt, "Testing position of replayed NavigaionData" ); player = mitk::NavigationDataPlayer::New(); player->SetFileName( file ); - player->SetStream( mitk::NavigationDataPlayer::NormalFile ); - + std::vector times, refTimes; refTimes.resize(5); refTimes[0] = 3.9; refTimes[1] = 83.6; refTimes[2] = 174.4; refTimes[3] = 275.0; refTimes[4] = 385.39; std::vector points, refPoints; refPoints.resize(5); refPoints[0][0] = 1; refPoints[0][1] = 0; refPoints[0][2] = 3; refPoints[1][0] = 2; refPoints[1][1] = 1; refPoints[1][2] = 4; refPoints[2][0] = 3; refPoints[2][1] = 2; refPoints[2][2] = 5; refPoints[3][0] = 4; refPoints[3][1] = 3; refPoints[3][2] = 6; refPoints[4][0] = 5; refPoints[4][1] = 4; refPoints[4][2] = 7; mitk::TimeStamp::Pointer timer = mitk::TimeStamp::GetInstance(); timer->Initialize(); itk::Object::Pointer obj = itk::Object::New(); mitk::Point3D oldPos; oldPos[0] = 1; oldPos[1] = 0; oldPos[2] = 3; timer->Start( obj ); player->StartPlaying(); while( times.size()<5 ) { player->Update(); pnt = player->GetOutput()->GetPosition(); if ( pnt != oldPos ) { times.push_back( timer->GetElapsed(obj) ); points.push_back(oldPos); oldPos = pnt; } } player->StopPlaying(); // if this test fails, it may be because the dartclient runs on a virtual machine. // Under these circumstances, it may be impossible to achieve a time-accuracy of 10ms for ( int i=0;i<5;i++ ) { if ((times[i]>refTimes[i]-150 && times[i]refTimes[i]-150 && times[i]FindFile("NavigationDataTestData.xml", "Modules/IGT/Testing/Data"); player->SetFileName( file ); MITK_TEST_CONDITION_REQUIRED( strcmp(player->GetFileName(), file.c_str()) == 0, "Testing SetFileName and GetFileName"); - player->SetStream( mitk::NavigationDataPlayer::NormalFile ); player->StartPlaying(); player->Update(); + mitk::NavigationData::Pointer nd = player->GetOutput(); + mitk::Point3D pnt; + pnt[0] = 1; + pnt[1] = 0; + pnt[2] = 3; + + MITK_TEST_CONDITION_REQUIRED( nd->GetPosition() == pnt, "Testing position of replayed NavigaionData" ); + MITK_TEST_OUTPUT(<<"Test double call of Pause() method!"); player->Pause(); //test pause method player->Pause(); //call again to see if this causes an error MITK_TEST_OUTPUT(<<"Test double call of Resume() method!"); player->Resume(); //test resume method player->Resume(); //call again to see if this causes an error player->Update(); player->StopPlaying(); - mitk::NavigationData::Pointer nd = player->GetOutput(); - mitk::Point3D pnt; - pnt[0] = 1; - pnt[1] = 0; - pnt[2] = 3; - - MITK_TEST_CONDITION_REQUIRED( nd->GetPosition() == pnt, "Testing position of replayed NavigaionData" ); - player = mitk::NavigationDataPlayer::New(); player->SetFileName( file ); - player->SetStream( mitk::NavigationDataPlayer::NormalFile ); std::vector times, refTimes; refTimes.resize(5); refTimes[0] = 3.9; refTimes[1] = 83.6; refTimes[2] = 174.4; refTimes[3] = 275.0; refTimes[4] = 385.39; std::vector points, refPoints; refPoints.resize(5); refPoints[0][0] = 1; refPoints[0][1] = 0; refPoints[0][2] = 3; refPoints[1][0] = 2; refPoints[1][1] = 1; refPoints[1][2] = 4; refPoints[2][0] = 3; refPoints[2][1] = 2; refPoints[2][2] = 5; refPoints[3][0] = 4; refPoints[3][1] = 3; refPoints[3][2] = 6; refPoints[4][0] = 5; refPoints[4][1] = 4; refPoints[4][2] = 7; mitk::TimeStamp::Pointer timer = mitk::TimeStamp::GetInstance(); timer->Initialize(); itk::Object::Pointer obj = itk::Object::New(); mitk::Point3D oldPos; oldPos[0] = 1; oldPos[1] = 0; oldPos[2] = 3; timer->Start( obj ); player->StartPlaying(); MITK_TEST_CONDITION_REQUIRED(!player->IsAtEnd(), "Testing method IsAtEnd() #0"); while( times.size()<3 ) { player->Update(); pnt = player->GetOutput()->GetPosition(); if ( pnt != oldPos ) { times.push_back( timer->GetElapsed(obj) ); points.push_back(oldPos); oldPos = pnt; } } MITK_TEST_OUTPUT(<<"Test pause method!"); player->Pause(); MITK_TEST_CONDITION_REQUIRED(!player->IsAtEnd(), "Testing method IsAtEnd() #1"); MITK_TEST_OUTPUT(<<"Test resume method!"); player->Resume(); while( times.size()<5 ) { player->Update(); pnt = player->GetOutput()->GetPosition(); if ( pnt != oldPos ) { times.push_back( timer->GetElapsed(obj) ); points.push_back(oldPos); oldPos = pnt; } } player->StopPlaying(); // if this test fails, it may be because the dartclient runs on a virtual machine. // Under these circumstances, it may be impossible to achieve a time-accuracy of 10ms for ( int i=0;i<5;i++ ) { if ((times[i]>refTimes[i]-150 && times[i]refTimes[i]-150 && times[i]IsAtEnd(), "Testing method IsAtEnd() #2"); } static void TestInvalidStream() { MITK_TEST_OUTPUT(<<"#### Testing invalid input data: errors are expected. ####"); //declarate test variables mitk::NavigationDataPlayer::Pointer player; std::string file; //case 0: stream not set player = mitk::NavigationDataPlayer::New(); - player->SetStream( mitk::NavigationDataPlayer::ZipFile ); + bool InvalidStreamException0 = false; + try + { player->StartPlaying(); + } + catch(mitk::IGTException) + { + InvalidStreamException0=true; player->Update(); player->StopPlaying(); MITK_TEST_OUTPUT(<<"#0: Tested stream not set. Application should not crash."); + } + + MITK_TEST_CONDITION_REQUIRED(InvalidStreamException0, "Testing Invalid Stream method if exception (stream not set) was thrown."); //case 1: non-existing file player = mitk::NavigationDataPlayer::New(); + bool InvalidStreamException1 = false; player->SetFileName( "ffdsd" ); - player->SetStream( mitk::NavigationDataPlayer::NormalFile ); + try + { player->StartPlaying(); + } + catch(mitk::IGTException) + { + InvalidStreamException1=true; player->Update(); player->StopPlaying(); MITK_TEST_OUTPUT(<<"#1: Tested non-existing file. Application should not crash."); + } + MITK_TEST_CONDITION_REQUIRED(InvalidStreamException1, "Testing Invalid Stream method if exception (non-existing file) was thrown."); + //case 2: wrong file format player = mitk::NavigationDataPlayer::New(); + bool InvalidStreamException2 = false; file = mitk::StandardFileLocations::GetInstance()->FindFile("SROMFile.rom", "Modules/IGT/Testing/Data"); player->SetFileName( file ); - player->SetStream( mitk::NavigationDataPlayer::NormalFile ); + try + { player->StartPlaying(); + } + catch(mitk::IGTException) + { + InvalidStreamException2=true; player->Update(); player->StopPlaying(); MITK_TEST_OUTPUT(<<"#2: Tested wrong file format. Application should not crash."); + } + + MITK_TEST_CONDITION_REQUIRED(InvalidStreamException2, "Testing Invalid Stream method if exception (wrong file format) was thrown."); //case 3: wrong file version player = mitk::NavigationDataPlayer::New(); file = mitk::StandardFileLocations::GetInstance()->FindFile("InvalidVersionNavigationDataTestData.xml", "Modules/IGT/Testing/Data"); player->SetFileName( file ); - player->SetStream( mitk::NavigationDataPlayer::NormalFile ); + bool InvalidStreamException3 = false; + try + { player->StartPlaying(); + } + catch(mitk::IGTException) + { + InvalidStreamException3 = true; player->Update(); player->StopPlaying(); MITK_TEST_OUTPUT(<<"#3: Tested wrong file version. Application should not crash."); + } + MITK_TEST_CONDITION_REQUIRED(InvalidStreamException3, "Testing Invalid Stream method if exception (wrong file version) was thrown."); //case 4: wrong file player = mitk::NavigationDataPlayer::New(); player->SetFileName( "cs:\fsd/$%§²³ffdsd" ); - player->SetStream( mitk::NavigationDataPlayer::NormalFile ); + bool InvalidStreamException4=false; + try + { player->StartPlaying(); - player->Update(); - player->StopPlaying(); + } + catch(mitk::IGTException) + { + InvalidStreamException4=true; MITK_TEST_OUTPUT(<<"#4: Tested wrong file. Application should not crash."); + } + + MITK_TEST_CONDITION_REQUIRED(InvalidStreamException4, "Testing Invalid Stream method if exception (wrong file) was thrown."); //case 5: null stream player = mitk::NavigationDataPlayer::New(); - player->SetStream( NULL ); + bool InvalidStreamException5=false; + try + { player->StartPlaying(); + } + catch(mitk::IGTException) + { + InvalidStreamException5=true; player->Update(); player->StopPlaying(); MITK_TEST_OUTPUT(<<"#5: Tested null stream. Application should not crash."); + } - //case 6: empty stream + MITK_TEST_CONDITION_REQUIRED(InvalidStreamException5, "Testing Invalid Stream method if exception (null stream) was thrown."); + + //case 6: empty stream, exception is thrown in setstream player = mitk::NavigationDataPlayer::New(); - std::ifstream* myEmptyStream = new std::ifstream(""); + bool InvalidStreamException6=false; + std::ifstream* myEmptyStream; + try + { + myEmptyStream = new std::ifstream(""); player->SetStream( myEmptyStream ); - player->StartPlaying(); - player->Update(); - player->StopPlaying(); + } + catch(mitk::IGTException) + { + InvalidStreamException6=true; MITK_TEST_OUTPUT(<<"#6: Tested empty stream. Application should not crash."); + } + MITK_TEST_CONDITION_REQUIRED(InvalidStreamException6, "Testing Invalid Stream method if exception (empty stream) was thrown."); + + + //case 7: wrong stream player = mitk::NavigationDataPlayer::New(); file = mitk::StandardFileLocations::GetInstance()->FindFile("SROMFile.rom", "Modules/IGT/Testing/Data"); - std::ifstream* myWrongStream = new std::ifstream(file.c_str()); + + bool InvalidStreamException7=false; + std::ifstream* myWrongStream; + myWrongStream = new std::ifstream(file.c_str()); + try + { player->SetStream( myWrongStream ); - player->StartPlaying(); - player->Update(); - player->StopPlaying(); + } + catch(mitk::IGTIOException) + { + InvalidStreamException7=true; MITK_TEST_OUTPUT(<<"#7: Tested wrong stream. Application should not crash."); + } + + MITK_TEST_CONDITION_REQUIRED(InvalidStreamException7, "Testing Invalid Stream method if exception (wrong stream) was thrown."); + + //case 8: invalid player = mitk::NavigationDataPlayer::New(); file = mitk::StandardFileLocations::GetInstance()->FindFile("InvalidDataNavigationDataTestData.xml", "Modules/IGT/Testing/Data"); player->SetFileName( file ); - player->SetStream( mitk::NavigationDataPlayer::NormalFile ); + bool InvalidStreamException8=false; + try + { player->StartPlaying(); - player->Update(); - player->StopPlaying(); + } + catch(mitk::IGTIOException) + { + InvalidStreamException8=true; MITK_TEST_OUTPUT(<<"#8: Tested invalid file version. Application should not crash."); + } + MITK_TEST_CONDITION_REQUIRED(InvalidStreamException8, "Testing Invalid Stream method if exception (Invalid) was thrown."); //clean up delete myEmptyStream; delete myWrongStream; } + + static void TestSetStreamExceptions() + { + mitk::NavigationDataPlayer::Pointer myTestPlayer = mitk::NavigationDataPlayer::New(); + std::string file = mitk::StandardFileLocations::GetInstance()->FindFile("NavigationDataTestData.xml", "Modules/IGT/Testing/Data"); + myTestPlayer->SetFileName( file ); + + + bool exceptionThrown=false; + + try + { + std::istream* stream=NULL; + myTestPlayer->SetStream(stream); + } + catch(mitk::IGTException) + { + exceptionThrown = true; + MITK_TEST_OUTPUT(<<"#9: Tested exceptions in SetStream. Application should not crash."); + + } + MITK_TEST_CONDITION_REQUIRED(exceptionThrown, "Testing SetStream method in exception was thrown."); + + } + + static void TestStartPlayingExceptions() + { + MITK_INFO <<"In the following, exceptions are tested. Errors will occur and are expected."; + + + //Case1 Testing if stream=NULL + mitk::NavigationDataPlayer::Pointer myTestPlayer1 = mitk::NavigationDataPlayer::New(); + bool exceptionThrown1 = false; + try + { + myTestPlayer1->StartPlaying(); + + } + catch(mitk::IGTException) + { + exceptionThrown1 = true; + myTestPlayer1->StopPlaying(); + MITK_TEST_OUTPUT(<<"#10: Tested exception for the case when stream=NULL in StartPlaying. Application should not crash."); + } + + MITK_TEST_CONDITION_REQUIRED(exceptionThrown1, "Testing StartPlaying method if exception (stream=NULL) was thrown."); + + //Case2 Testing if file does not exist + mitk::NavigationDataPlayer::Pointer myTestPlayer2 = mitk::NavigationDataPlayer::New(); + myTestPlayer2->SetFileName("ffdsd"); + bool exceptionThrown2 = false; + try{ + myTestPlayer2->StartPlaying(); + } + catch(mitk::IGTIOException) + { + exceptionThrown2 = true; + myTestPlayer2->StopPlaying(); + MITK_TEST_OUTPUT(<<"#11: Tested exception for the case when file does not exist in StartPlaying. Application should not crash."); + } + MITK_TEST_CONDITION_REQUIRED(exceptionThrown2, "Testing StartPlaying method if exception is thrown when file does not exist."); + + + //Case3 Testing if wrong file format + mitk::NavigationDataPlayer::Pointer myTestPlayer3 = mitk::NavigationDataPlayer::New(); + std::string file3 = mitk::StandardFileLocations::GetInstance()->FindFile("SROMFile.rom", "Modules/IGT/Testing/Data"); + myTestPlayer3->SetFileName( file3 ); + bool exceptionThrown3 = false; + try{ + myTestPlayer3->StartPlaying(); + } + catch(mitk::IGTIOException) + { + exceptionThrown3 = true; + myTestPlayer3->StopPlaying(); + MITK_TEST_OUTPUT(<<"#12: Tested exception for the case when file format is wrong in StartPlaying. Application should not crash."); + } + MITK_TEST_CONDITION_REQUIRED(exceptionThrown3, "Testing StartPlaying method if exception (file format is wrong) was thrown."); + + + //Case4 Testing if wrong file version + mitk::NavigationDataPlayer::Pointer myTestPlayer4 = mitk::NavigationDataPlayer::New(); + std::string file4 = mitk::StandardFileLocations::GetInstance()->FindFile("InvalidVersionNavigationDataTestData.xml", "Modules/IGT/Testing/Data"); + myTestPlayer4->SetFileName( file3 ); + bool exceptionThrown4 = false; + try{ + myTestPlayer4->StartPlaying(); + } + catch(mitk::IGTIOException) + { + exceptionThrown4 = true; + myTestPlayer4->StopPlaying(); + MITK_TEST_OUTPUT(<<"#13: Tested exception for the case when file version is wrong in StartPlaying. Application should not crash."); + } + MITK_TEST_CONDITION_REQUIRED(exceptionThrown4, "Testing StartPlaying method if exception (file version is wrong) was thrown."); + + //Case5 Testing if not existing file name + mitk::NavigationDataPlayer::Pointer myTestPlayer5 = mitk::NavigationDataPlayer::New(); + myTestPlayer5->SetFileName("ffdsd"); + bool exceptionThrown5 = false; + try{ + myTestPlayer5->StartPlaying(); + } + catch(mitk::IGTIOException) + { + exceptionThrown5 = true; + myTestPlayer5->StopPlaying(); + MITK_TEST_OUTPUT(<<"#14: Tested exception for the case when non-existing file name in StartPlaying. Application should not crash."); + } + MITK_TEST_CONDITION_REQUIRED(exceptionThrown5, "Testing StartPlaying method if exception (non-existing file name) was thrown."); + + } - }; +}; /**Documentation * test for the class "NavigationDataPlayer". */ + int mitkNavigationDataPlayerTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("NavigationDataPlayer"); std::string tmp = ""; mitkNavigationDataPlayerTestClass::TestInstantiation(); mitkNavigationDataPlayerTestClass::TestSimpleDataPlay(); + mitkNavigationDataPlayerTestClass::TestSetStreamExceptions(); + mitkNavigationDataPlayerTestClass::TestStartPlayingExceptions(); mitkNavigationDataPlayerTestClass::TestPauseAndResume(); mitkNavigationDataPlayerTestClass::TestInvalidStream(); // always end with this! MITK_TEST_END(); } + + + diff --git a/Modules/IGT/files.cmake b/Modules/IGT/files.cmake index 147e232381..0730d714ad 100644 --- a/Modules/IGT/files.cmake +++ b/Modules/IGT/files.cmake @@ -1,62 +1,63 @@ set(CPP_FILES IGTFilters/mitkNavigationDataLandmarkTransformFilter.cpp IGTFilters/mitkNavigationDataReferenceTransformFilter.cpp IGTFilters/mitkNavigationDataTransformFilter.cpp IGTFilters/mitkNavigationDataRecorder.cpp IGTFilters/mitkNavigationDataPlayer.cpp IGTFilters/mitkNavigationDataPlayerBase.cpp IGTFilters/mitkNavigationDataObjectVisualizationFilter.cpp IGTFilters/mitkCameraVisualization.cpp IGTFilters/mitkNavigationData.cpp IGTFilters/mitkNavigationDataDisplacementFilter.cpp IGTFilters/mitkNavigationDataSequentialPlayer.cpp IGTFilters/mitkNavigationDataSource.cpp IGTFilters/mitkNavigationDataToMessageFilter.cpp IGTFilters/mitkNavigationDataToNavigationDataFilter.cpp IGTFilters/mitkNavigationDataToPointSetFilter.cpp IGTFilters/mitkNavigationDataEvaluationFilter.cpp IGTFilters/mitkTrackingDeviceSource.cpp IGTFilters/mitkTrackingVolumeGenerator.cpp IGTFilters/mitkTimeStamp.cpp IGTFilters/mitkRealTimeClock.cpp IGTFilters/mitkTrackingDeviceSourceConfigurator.cpp IGTTrackingDevices/mitkClaronTool.cpp IGTTrackingDevices/mitkClaronTrackingDevice.cpp IGTTrackingDevices/mitkInternalTrackingTool.cpp IGTTrackingDevices/mitkNDIPassiveTool.cpp IGTTrackingDevices/mitkNDIProtocol.cpp IGTTrackingDevices/mitkNDITrackingDevice.cpp IGTTrackingDevices/mitkSerialCommunication.cpp IGTTrackingDevices/mitkTrackingDevice.cpp IGTTrackingDevices/mitkTrackingTool.cpp IGTTrackingDevices/mitkVirtualTrackingDevice.cpp IGTTrackingDevices/mitkVirtualTrackingTool.cpp IGTToolManagement/mitkNavigationToolStorage.cpp IGTToolManagement/mitkNavigationToolStorageSerializer.cpp IGTToolManagement/mitkNavigationToolStorageDeserializer.cpp IGTToolManagement/mitkNavigationTool.cpp IGTToolManagement/mitkNavigationToolReader.cpp IGTToolManagement/mitkNavigationToolWriter.cpp IGTExceptionHandling/mitkIGTException.cpp IGTExceptionHandling/mitkIGTHardwareException.cpp + IGTExceptionHandling/mitkIGTIOException.cpp ) if(MITK_USE_MICRON_TRACKER) set(CPP_FILES ${CPP_FILES} IGTTrackingDevices/mitkClaronInterface.cpp) else() set(CPP_FILES ${CPP_FILES} IGTTrackingDevices/mitkClaronInterfaceStub.cpp) endif(MITK_USE_MICRON_TRACKER) if(MITK_USE_MICROBIRD_TRACKER) set(CPP_FILES ${CPP_FILES} IGTTrackingDevices/mitkMicroBirdTrackingDevice.cpp) endif(MITK_USE_MICROBIRD_TRACKER) if(WIN32) set(CPP_FILES ${CPP_FILES} IGTFilters/mitkWindowsRealTimeClock.cpp) else() set(CPP_FILES ${CPP_FILES} IGTFilters/mitkLinuxRealTimeClock.cpp) endif(WIN32) diff --git a/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidget.cpp b/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidget.cpp index 00eb05729e..ac8bebd51c 100644 --- a/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidget.cpp +++ b/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidget.cpp @@ -1,548 +1,560 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkIGTPlayerWidget.h" //mitk headers #include "mitkTrackingTypes.h" #include #include #include #include #include #include #include +#include //qt headers #include #include #include QmitkIGTPlayerWidget::QmitkIGTPlayerWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f) ,m_RealTimePlayer(NULL) ,m_SequentialPlayer(NULL) ,m_StartTime(-1.0) ,m_CurrentSequentialPointNumber(0) { m_Controls = NULL; CreateQtPartControl(this); CreateConnections(); m_Controls->samplePositionHorizontalSlider->setVisible(false); this->ResetLCDNumbers(); // reset lcd numbers at start } QmitkIGTPlayerWidget::~QmitkIGTPlayerWidget() { m_PlayingTimer->stop(); m_RealTimePlayer = NULL; m_PlayingTimer = NULL; } void QmitkIGTPlayerWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkIGTPlayerWidgetControls; m_Controls->setupUi(parent); m_PlayingTimer = new QTimer(this); // initialize update timer } } void QmitkIGTPlayerWidget::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->selectPushButton), SIGNAL(clicked()), this, SLOT(OnSelectPressed()) ); // open file dialog connect( (QObject*)(m_Controls->playPushButton), SIGNAL(clicked(bool)), this, SLOT(OnPlayButtonClicked(bool)) ); // play button connect( (QObject*)(m_PlayingTimer), SIGNAL(timeout()), this, SLOT(OnPlaying()) ); // update timer connect( (QObject*) (m_Controls->beginPushButton), SIGNAL(clicked()), this, SLOT(OnGoToBegin()) ); // reset player and go to begin connect( (QObject*) (m_Controls->stopPushButton), SIGNAL(clicked()), this, SLOT(OnGoToEnd()) ); // reset player // pass this widgets protected combobox signal to public signal connect( (QObject*) (m_Controls->trajectorySelectComboBox), SIGNAL(currentIndexChanged(int)), this, SIGNAL(SignalCurrentTrajectoryChanged(int)) ); // pass this widgets protected checkbox signal to public signal connect( m_Controls->splineModeCheckBox, SIGNAL(toggled(bool)), this, SIGNAL(SignalSplineModeToggled(bool)) ); connect( m_Controls->sequencialModeCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnSequencialModeToggled(bool)) ); connect( m_Controls->samplePositionHorizontalSlider, SIGNAL(sliderPressed()), this, SLOT(OnSliderPressed()) ); connect( m_Controls->samplePositionHorizontalSlider, SIGNAL(sliderReleased()), this, SLOT(OnSliderReleased()) ); } } bool QmitkIGTPlayerWidget::IsTrajectoryInSplineMode() { return m_Controls->splineModeCheckBox->isChecked(); } bool QmitkIGTPlayerWidget::CheckInputFileValid() { QFile file(m_CmpFilename); // check if file exists if(!file.exists()) { QMessageBox::warning(NULL, "IGTPlayer: Error", "No valid input file was loaded. Please load input file first!"); return false; } return true; } unsigned int QmitkIGTPlayerWidget::GetNumberOfTools() { unsigned int result = 0; if(this->GetCurrentPlaybackMode() == RealTimeMode) { if(m_RealTimePlayer.IsNotNull()) result = m_RealTimePlayer->GetNumberOfOutputs(); } else if(this->GetCurrentPlaybackMode() == SequentialMode) { if(m_SequentialPlayer.IsNotNull()) result = m_SequentialPlayer->GetNumberOfOutputs(); } // at the moment this works only if player is initialized return result; } void QmitkIGTPlayerWidget::SetUpdateRate(unsigned int msecs) { m_PlayingTimer->setInterval((int) msecs); // set update timer update rate } void QmitkIGTPlayerWidget::OnPlayButtonClicked(bool checked) { if(CheckInputFileValid()) // no playing possible without valid input file { PlaybackMode currentMode = this->GetCurrentPlaybackMode(); bool isRealTimeMode = currentMode == RealTimeMode; bool isSequentialMode = currentMode == SequentialMode; if(checked) // play { if( (isRealTimeMode && m_RealTimePlayer.IsNull()) || (isSequentialMode && m_SequentialPlayer.IsNull())) // start play { if(isRealTimeMode) { m_RealTimePlayer = mitk::NavigationDataPlayer::New(); m_RealTimePlayer->SetFileName(m_CmpFilename.toStdString()); - m_RealTimePlayer->StartPlaying(); + try + { + m_RealTimePlayer->StartPlaying(); + } + catch(mitk::IGTException) + { + std::string errormessage = "Error during start playing. Invalid or wrong file?"; + QMessageBox::warning(NULL, "IGTPlayer: Error", errormessage.c_str()); + m_Controls->playPushButton->setChecked(false); + m_RealTimePlayer = NULL; + return; + } } else if(isSequentialMode) { m_SequentialPlayer = mitk::NavigationDataSequentialPlayer::New(); m_SequentialPlayer->SetFileName(m_CmpFilename.toStdString()); m_Controls->samplePositionHorizontalSlider->setMinimum(0); m_Controls->samplePositionHorizontalSlider->setMaximum(m_SequentialPlayer->GetNumberOfSnapshots()); m_Controls->samplePositionHorizontalSlider->setEnabled(true); } m_PlayingTimer->start(100); emit SignalPlayingStarted(); } else // resume play { if(isRealTimeMode) m_RealTimePlayer->Resume(); m_PlayingTimer->start(100); emit SignalPlayingResumed(); } } else // pause { if(isRealTimeMode) m_RealTimePlayer->Pause(); m_PlayingTimer->stop(); emit SignalPlayingPaused(); } } else m_Controls->playPushButton->setChecked(false); // uncheck play button if file unvalid } QmitkIGTPlayerWidget::PlaybackMode QmitkIGTPlayerWidget::GetCurrentPlaybackMode() { if(m_Controls->sequencialModeCheckBox->isChecked()) return SequentialMode; else return RealTimeMode; } QTimer* QmitkIGTPlayerWidget::GetPlayingTimer() { return m_PlayingTimer; } void QmitkIGTPlayerWidget::OnStopPlaying() { this->StopPlaying(); } void QmitkIGTPlayerWidget::StopPlaying() { m_PlayingTimer->stop(); emit SignalPlayingStopped(); if(m_RealTimePlayer.IsNotNull()) m_RealTimePlayer->StopPlaying(); m_RealTimePlayer = NULL; m_SequentialPlayer = NULL; m_StartTime = -1; // set starttime back m_CurrentSequentialPointNumber = 0; m_Controls->samplePositionHorizontalSlider->setSliderPosition(m_CurrentSequentialPointNumber); m_Controls->sampleLCDNumber->display(static_cast(m_CurrentSequentialPointNumber)); this->ResetLCDNumbers(); m_Controls->playPushButton->setChecked(false); // set play button unchecked } void QmitkIGTPlayerWidget::OnPlaying() { PlaybackMode currentMode = this->GetCurrentPlaybackMode(); bool isRealTimeMode = currentMode == RealTimeMode; bool isSequentialMode = currentMode == SequentialMode; if(isRealTimeMode && m_RealTimePlayer.IsNull()) return; else if(isSequentialMode && m_SequentialPlayer.IsNull()) return; if(isRealTimeMode && m_StartTime < 0) m_StartTime = m_RealTimePlayer->GetOutput()->GetTimeStamp(); // get playback start time if(isRealTimeMode && !m_RealTimePlayer->IsAtEnd()) { m_RealTimePlayer->Update(); // update player int msc = (int) (m_RealTimePlayer->GetOutput()->GetTimeStamp() - m_StartTime); // calculation for playing time display int ms = msc % 1000; msc = (msc - ms) / 1000; int s = msc % 60; int min = (msc-s) / 60; // set lcd numbers m_Controls->msecLCDNumber->display(ms); m_Controls->secLCDNumber->display(s); m_Controls->minLCDNumber->display(min); emit SignalPlayerUpdated(); // player successfully updated } else if(isSequentialMode && (m_CurrentSequentialPointNumber < m_SequentialPlayer->GetNumberOfSnapshots())) { m_SequentialPlayer->Update(); // update sequential player m_Controls->samplePositionHorizontalSlider->setSliderPosition(m_CurrentSequentialPointNumber++); // refresh slider position m_Controls->sampleLCDNumber->display(static_cast(m_CurrentSequentialPointNumber)); //for debugging purposes //std::cout << "Sample: " << m_CurrentSequentialPointNumber << " X: " << m_SequentialPlayer->GetOutput(0)->GetPosition()[0] << " Y: " << m_SequentialPlayer->GetOutput(0)->GetPosition()[1] << " Y: " << m_SequentialPlayer->GetOutput(0)->GetPosition()[2] << std::endl; emit SignalPlayerUpdated(); // player successfully updated } else this->StopPlaying(); // if player is at EOF } const std::vector QmitkIGTPlayerWidget::GetNavigationDatas() { std::vector navDatas; if(this->GetCurrentPlaybackMode() == RealTimeMode && m_RealTimePlayer.IsNotNull()) { for(unsigned int i=0; i < m_RealTimePlayer->GetNumberOfOutputs(); ++i) { navDatas.push_back(m_RealTimePlayer->GetOutput(i)); // push back current navigation data for each tool } } else if(this->GetCurrentPlaybackMode() == SequentialMode && m_SequentialPlayer.IsNotNull()) { for(unsigned int i=0; i < m_SequentialPlayer->GetNumberOfOutputs(); ++i) { navDatas.push_back(m_SequentialPlayer->GetOutput(i)); // push back current navigation data for each tool } } return navDatas; } const mitk::PointSet::Pointer QmitkIGTPlayerWidget::GetNavigationDatasPointSet() { mitk::PointSet::Pointer result = mitk::PointSet::New(); mitk::PointSet::PointType pointType; PlaybackMode currentMode = this->GetCurrentPlaybackMode(); bool isRealTimeMode = currentMode == RealTimeMode; bool isSequentialMode = currentMode == SequentialMode; if( (isRealTimeMode && m_RealTimePlayer.IsNotNull()) || (isSequentialMode && m_SequentialPlayer.IsNotNull())) { int numberOfOutputs = 0; if(isRealTimeMode) numberOfOutputs = m_RealTimePlayer->GetNumberOfOutputs(); else if(isSequentialMode) numberOfOutputs = m_SequentialPlayer->GetNumberOfOutputs(); for(unsigned int i=0; i < m_RealTimePlayer->GetNumberOfOutputs(); ++i) { mitk::NavigationData::PositionType position; if(isRealTimeMode) position = m_RealTimePlayer->GetOutput(i)->GetPosition(); else if(isSequentialMode) position = m_SequentialPlayer->GetOutput(i)->GetPosition(); pointType[0] = position[0]; pointType[1] = position[1]; pointType[2] = position[2]; result->InsertPoint(i,pointType); // insert current ND as Pointtype in PointSet for return } } return result; } const mitk::PointSet::PointType QmitkIGTPlayerWidget::GetNavigationDataPoint(unsigned int index) { if( index > this->GetNumberOfTools() || index < 0 ) throw std::out_of_range("Tool Index out of range!"); PlaybackMode currentMode = this->GetCurrentPlaybackMode(); bool isRealTimeMode = currentMode == RealTimeMode; bool isSequentialMode = currentMode == SequentialMode; // create return PointType from current ND for tool index mitk::PointSet::PointType result; if( (isRealTimeMode && m_RealTimePlayer.IsNotNull()) || (isSequentialMode && m_SequentialPlayer.IsNotNull())) { mitk::NavigationData::PositionType position; if(isRealTimeMode) position = m_RealTimePlayer->GetOutput(index)->GetPosition(); else if(isSequentialMode) position = m_SequentialPlayer->GetOutput(index)->GetPosition(); result[0] = position[0]; result[1] = position[1]; result[2] = position[2]; } return result; } void QmitkIGTPlayerWidget::SetInputFileName(const QString& inputFileName) { this->OnGoToEnd(); /// stops playing and resets lcd numbers QString oldName = m_CmpFilename; m_CmpFilename.clear(); m_CmpFilename = inputFileName; QFile file(m_CmpFilename); if(m_CmpFilename.isEmpty() || !file.exists()) { QMessageBox::warning(NULL, "Warning", QString("Please enter valid path! Using previous path again.")); m_CmpFilename=oldName; m_Controls->inputFileLineEdit->setText(m_CmpFilename); } } void QmitkIGTPlayerWidget::SetRealTimePlayer( mitk::NavigationDataPlayer::Pointer player ) { if(player.IsNotNull()) m_RealTimePlayer = player; } void QmitkIGTPlayerWidget::SetSequentialPlayer( mitk::NavigationDataSequentialPlayer::Pointer player ) { if(player.IsNotNull()) m_SequentialPlayer = player; } void QmitkIGTPlayerWidget::OnSelectPressed() { QString oldName = m_CmpFilename; m_CmpFilename.clear(); m_CmpFilename = QFileDialog::getOpenFileName(this, "Load tracking data", QDir::currentPath(),"XML files (*.xml)"); if (m_CmpFilename.isEmpty())//if something went wrong or user pressed cancel in the save dialog m_CmpFilename=oldName; else { this->OnGoToEnd(); /// stops playing and resets lcd numbers emit SignalInputFileChanged(); } m_Controls->inputFileLineEdit->setText(m_CmpFilename); } void QmitkIGTPlayerWidget::OnGoToEnd() { this->StopPlaying(); // reset lcd numbers this->ResetLCDNumbers(); } void QmitkIGTPlayerWidget::OnGoToBegin() { // stop player manual so no PlayingStopped() m_PlayingTimer->stop(); if(this->GetCurrentPlaybackMode() == RealTimeMode && m_RealTimePlayer.IsNotNull()) { m_RealTimePlayer->StopPlaying(); m_RealTimePlayer = NULL; // set player to NULL so it can be initialized again if playback is called afterwards } m_StartTime = -1; // set starttime back //reset view elements m_Controls->playPushButton->setChecked(false); this->ResetLCDNumbers(); } void QmitkIGTPlayerWidget::ResetLCDNumbers() { m_Controls->minLCDNumber->display(QString("00")); m_Controls->secLCDNumber->display(QString("00")); m_Controls->msecLCDNumber->display(QString("000")); } void QmitkIGTPlayerWidget::SetTrajectoryNames(const QStringList toolNames) { QComboBox* cBox = m_Controls->trajectorySelectComboBox; if(cBox->count() > 0) this->ClearTrajectorySelectCombobox(); // before making changed to QComboBox it is recommended to disconnet it's SIGNALS and SLOTS disconnect( (QObject*) (m_Controls->trajectorySelectComboBox), SIGNAL(currentIndexChanged(int)), this, SIGNAL(SignalCurrentTrajectoryChanged(int)) ); if(!toolNames.isEmpty()) m_Controls->trajectorySelectComboBox->insertItems(0, toolNames); // adding current tool names to combobox // reconnect after performed changes connect( (QObject*) (m_Controls->trajectorySelectComboBox), SIGNAL(currentIndexChanged(int)), this, SIGNAL(SignalCurrentTrajectoryChanged(int)) ); } int QmitkIGTPlayerWidget::GetResolution() { return m_Controls->resolutionSpinBox->value(); // return currently selected trajectory resolution } void QmitkIGTPlayerWidget::ClearTrajectorySelectCombobox() { // before making changed to QComboBox it is recommended to disconnet it's SIGNALS and SLOTS disconnect( (QObject*) (m_Controls->trajectorySelectComboBox), SIGNAL(currentIndexChanged(int)), this, SIGNAL(SignalCurrentTrajectoryChanged(int)) ); m_Controls->trajectorySelectComboBox->clear(); // reconnect after performed changes connect( (QObject*) (m_Controls->trajectorySelectComboBox), SIGNAL(currentIndexChanged(int)), this, SIGNAL(SignalCurrentTrajectoryChanged(int)) ); } void QmitkIGTPlayerWidget::OnSequencialModeToggled(bool toggled) { this->StopPlaying(); // stop playing when mode is changed if(toggled) { m_Controls->samplePositionHorizontalSlider->setEnabled(true); // enable slider if sequential mode } else if(!toggled) { m_Controls->samplePositionHorizontalSlider->setSliderPosition(0); // set back and disable slider m_Controls->samplePositionHorizontalSlider->setDisabled(true); } } void QmitkIGTPlayerWidget::OnSliderReleased() { int currentSliderValue = m_Controls->samplePositionHorizontalSlider->value(); // current slider value selected through user movement if(currentSliderValue > m_CurrentSequentialPointNumber) // at the moment only forward scrolling is possible { m_SequentialPlayer->GoToSnapshot(currentSliderValue); // move player to selected snapshot m_CurrentSequentialPointNumber = currentSliderValue; m_Controls->sampleLCDNumber->display(currentSliderValue); // update lcdnumber in widget } else m_Controls->samplePositionHorizontalSlider->setValue(m_CurrentSequentialPointNumber); } void QmitkIGTPlayerWidget::OnSliderPressed() { if(m_Controls->playPushButton->isChecked()) // check if widget is playing m_Controls->playPushButton->click(); // perform click to pause the play }