diff --git a/Core/Code/Interactions/mitkDisplayInteractor.h b/Core/Code/Interactions/mitkDisplayInteractor.h index c78db7be66..7d3e40d812 100644 --- a/Core/Code/Interactions/mitkDisplayInteractor.h +++ b/Core/Code/Interactions/mitkDisplayInteractor.h @@ -1,154 +1,154 @@ /*=================================================================== 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 mitkDisplayInteractor_h #define mitkDisplayInteractor_h #include #include "mitkEventObserver.h" namespace mitk { /** *\class DisplayInteractor *@brief Observer that manages the interaction with the display. * - * This includes the interaction of Zooming, Panning and Scrolling. + * This includes the interaction of Zooming, Panning, Scrolling and adjusting the LevelWindow. * * @ingroup Interaction **/ /** * Inherits from mitk::EventObserver since it doesn't alter any data (only their representation), * and its actions cannot be associated with a DataNode. */ class MITK_CORE_EXPORT DisplayInteractor: public EventObserver { public: - mitkClassMacro(DisplayInteractor, StateMachine); - itkNewMacro(Self); + mitkClassMacro(DisplayInteractor, StateMachine) + itkNewMacro(Self) /** * By this function the Observer gets notifier about new events. * Here it is adapted to pass the events to the state machine in order to use * its infrastructure. * It also checks if event is to be accepted when i already has been processed by a DataInteractor. */ virtual void Notify(InteractionEvent::Pointer interactionEvent, bool isHandled); protected: DisplayInteractor(); virtual ~DisplayInteractor(); /** * Derived function. * Connects the action names used in the state machine pattern with functions implemented within * this EventObserver. This is only necessary here because the events are processed by the state machine. */ void ConnectActionsAndFunctions(); /** * Derived function. * Is executed when config object is set / changed. * Here it is used to read out the parameters set in the configuration file, * and set the member variables accordingly. */ virtual void ConfigurationChanged(); /** * \brief Initializes an interaction, saves the pointers start position for further reference. */ virtual bool Init(StateMachineAction*, InteractionEvent*); /** * \brief Performs panning of the data set in the render window. */ virtual bool Move(StateMachineAction*, InteractionEvent*); /** * \brief Performs zooming relative to mouse/pointer movement. * * Behavior is determined by \see m_ZoomDirection and \see m_ZoomFactor. * */ virtual bool Zoom(StateMachineAction*, InteractionEvent*); /** * \brief Performs scrolling relative to mouse/pointer movement. * * Behavior is determined by \see m_ScrollDirection and \see m_AutoRepeat. * */ virtual bool Scroll(StateMachineAction*, InteractionEvent*); /** * \brief Scrolls one layer up */ virtual bool ScrollOneDown(StateMachineAction*, InteractionEvent*); /** * \brief Scrolls one layer down */ virtual bool ScrollOneUp(StateMachineAction*, InteractionEvent*); /** * \brief Adjusts the level windows relative to mouse/pointer movement. */ virtual bool AdjustLevelWindow(StateMachineAction*, InteractionEvent*); private: /** * \brief Coordinate of the pointer at begin of an interaction */ mitk::Point2D m_StartDisplayCoordinate; /** * \brief Coordinate of the pointer at begin of an interaction translated to mm unit */ mitk::Point2D m_StartCoordinateInMM; /** * \brief Coordinate of the pointer in the last step within an interaction. */ mitk::Point2D m_LastDisplayCoordinate; /** * \brief Current coordinates of the pointer. */ mitk::Point2D m_CurrentDisplayCoordinate; /** * \brief Modifier that defines how many slices are scrolled per pixel that the mouse has moved * * This modifier defines how many slices the scene is scrolled per pixel that the mouse cursor has moved. * By default the modifier is 4. This means that when the user moves the cursor by 4 pixels in Y-direction * the scene is scrolled by one slice. If the user has moved the the cursor by 20 pixels, the scene is * scrolled by 5 slices. * * If the cursor has moved less than m_IndexToSliceModifier pixels the scene is scrolled by one slice. */ int m_IndexToSliceModifier; /** Defines behavior at end of data set. * If set to true it will restart at end of data set from the beginning. */ bool m_AutoRepeat; /** * Defines scroll behavior. * Default is up/down movement of pointer performs scrolling */ std::string m_ScrollDirection; /** * Defines scroll behavior. * Default is up/down movement of pointer performs zooming */ std::string m_ZoomDirection; /** * Determines if the Observer reacts to events that already have been processed by a DataInteractor. * The default value is false. */ bool m_AlwaysReact; /** * Factor to adjust zooming speed. */ float m_ZoomFactor; }; } #endif diff --git a/Core/Code/Interactions/mitkDisplayPositionEvent.h b/Core/Code/Interactions/mitkDisplayPositionEvent.h index 90ec265819..78ed86abb9 100644 --- a/Core/Code/Interactions/mitkDisplayPositionEvent.h +++ b/Core/Code/Interactions/mitkDisplayPositionEvent.h @@ -1,80 +1,82 @@ /*=================================================================== 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 DISPLAYPOSITIONEVENT_H_HEADER_INCLUDED_C184F366 #define DISPLAYPOSITIONEVENT_H_HEADER_INCLUDED_C184F366 #include #include "mitkEvent.h" #include "mitkVector.h" #include "mitkDataNode.h" namespace mitk { /** * \brief Event that stores coordinates * * Stores display position of the mouse. * * If requested, the correspondent 3D world position in mm is calculated via * picking (delegated to the BaseRenderer). Additionally, the mitk::BaseData or * mitk::DataNode corresponding to the picked object in the (3D) scene can * be retrieved. * \ingroup Interaction + * \deprecatedSince{2013_03} mitk::DisplayPositionEvent is deprecated. Use mitk::InteractionPositionEvent instead. + * Refer to \see DataInteractionPage for general information about the concept of the new implementation. */ class MITK_CORE_EXPORT DisplayPositionEvent : public Event { public: /** \brief Constructor with all necessary arguments. * * \param sender is the renderer that caused that event * \param type, button, buttonState, key: information from the Event * \param displPosition is the 2D Position of the mouse */ DisplayPositionEvent(BaseRenderer* sender, int type, int button, int buttonState, int key, const Point2D& displPosition); const Point2D& GetDisplayPosition() const { return m_DisplayPosition; } void SetDisplayPosition(const Point2D& displPosition) { m_DisplayPosition = displPosition; } const Point3D& GetWorldPosition() const; /** Returns node with object at the current position (NULL if not applicable) */ mitk::DataNode *GetPickedObjectNode() const; /** Returns object at the current position (NULL if not applicable) */ mitk::BaseData *GetPickedObject() const; protected: Point2D m_DisplayPosition; mutable Point3D m_WorldPosition; mutable bool m_WorldPositionIsSet; mutable mitk::DataNode::Pointer m_PickedObjectNode; mutable bool m_PickedObjectIsSet; }; typedef DisplayPositionEvent MouseEvent; } // namespace mitk #endif /* DISPLAYPOSITIONozsiEVENT_H_HEADER_INCLUDED_C184F366 */ diff --git a/Core/Code/Interactions/mitkEvent.h b/Core/Code/Interactions/mitkEvent.h index c68e7e05fe..a59464aee4 100644 --- a/Core/Code/Interactions/mitkEvent.h +++ b/Core/Code/Interactions/mitkEvent.h @@ -1,76 +1,80 @@ /*=================================================================== 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 EVENT_H_HEADER_INCLUDED_C1889CEE #define EVENT_H_HEADER_INCLUDED_C1889CEE #include namespace mitk { class BaseRenderer; //##Documentation //## @brief represents an Event with all its information //## //## Class, that stores mouse as well as key-events. Type stores the type of //## event, that has been activated (KeyPress, MouseMove...), Button and Key //## represent the cause of this event and ButtonState holds the Modifiers, //## that might have been pressed during the appearance of this event. //## Ether Button (Mouse) or Key (Keyboard) is set. if both are set //## accidentally then the button is accepted. //## @ingroup Interaction + /** + * \deprecatedSince{2013_03} mitk::Event is deprecated. Use mitk::InteractionEvent instead. + * Refer to \see DataInteractionPage for general information about the concept of the new implementation. + */ class MITK_CORE_EXPORT Event { public: //##Documentation //## @param sender Needed for DisplayCoordinateOperation in DisplayVectorInteractor....???? if not needed, then set on NULL //## @param type Type of Event: Mouse or Key Event? (look in mitkInteractionConst.h) //## @param button Mouse button //## @param buttonState Which other key has been pressed? (Mouse/Keyboard modifier-keys) //## @param key Pressed key Event(mitk::BaseRenderer* sender, int type, int button, int buttonState, int key); virtual ~Event(); mitk::BaseRenderer* GetSender() const; int GetType() const; int GetButton() const; int GetKey() const; bool operator==(const Event& event) const; int GetButtonState() const; protected: mitk::BaseRenderer* m_Sender; int m_Type; int m_Button; int m_ButtonState; int m_Key; }; } // namespace mitk #endif /* EVENT_H_HEADER_INCLUDED_C1889CEE */ diff --git a/Core/Code/Interactions/mitkEventDescription.h b/Core/Code/Interactions/mitkEventDescription.h index 46fa633d3e..fc660a62df 100644 --- a/Core/Code/Interactions/mitkEventDescription.h +++ b/Core/Code/Interactions/mitkEventDescription.h @@ -1,60 +1,66 @@ /*=================================================================== 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 EVENTDESCRIPTION_H_HEADER_INCLUDED_C188FC4D #define EVENTDESCRIPTION_H_HEADER_INCLUDED_C188FC4D #include #include "mitkEvent.h" #include #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4251) #endif namespace mitk { //##Documentation //## @brief adds additional Information (Name and EventID) to an Event //## //## A name and an ID is added to the information of an event, so the event can //## be processed futher on. //## @ingroup Interaction + + /** + * \deprecatedSince{2013_03} EventDescription is deprecated. It will become obsolete. + * All necessary information is now store in the event classes derived from mitk::InteractionEvent . + * Refer to \see DataInteractionPage for general information about the concept of the new implementation. + */ class MITK_CORE_EXPORT EventDescription : public Event { public: EventDescription(int type, int button, int buttonState,int key, std::string name, int id); std::string GetName() const; int GetId() const; private: std::string m_Name; int m_Id; }; } // namespace mitk #ifdef _MSC_VER # pragma warning(pop) #endif #endif /* EVENTDESCRIPTION_H_HEADER_INCLUDED_C188FC4D */ diff --git a/Core/Code/Interactions/mitkEventMapper.h b/Core/Code/Interactions/mitkEventMapper.h index 169e23f1f9..e94f2d88f3 100644 --- a/Core/Code/Interactions/mitkEventMapper.h +++ b/Core/Code/Interactions/mitkEventMapper.h @@ -1,201 +1,208 @@ /*=================================================================== 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 EVENTMAPPER_H_HEADER_INCLUDED #define EVENTMAPPER_H_HEADER_INCLUDED #include #include #include #include #include #include #include namespace mitk { struct ltstr { bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) < 0; } }; typedef std::string msgString; //for friendship wor to set the stateevent after calculating class GlobalInteraction; class StateMachine; class StateEvent; class EventMapperAddOn; //##Documentation //## @brief Maps an Event to its description //## //## EventMapping: //## This class mapps the Events, usually given by the OS or here by QT, to a MITK internal EventId. //## It loads all information from the xml-file (possible, understandable Events with the mitkEventID). //## If an event appears, the method MapEvent is called with the event params. //## This Method looks up the event params, and tries to find an mitkEventId to it. //## If yes, then sends the event and the found ID to the globalStateMachine, which handles all //## further operations of that event. //## For Undo-Mechanism a statechanging StateMachine::HandleEvent is connected to an ObjectEventID and an GroupEventId. //## That way a fine an raw Undo is possible (fine for ObjectID by ObjectID, raw for GroupID for GroupID) //## Here the ObjectEventID gets increased, //## not the GroupEventId(must get increased by a StateMachine, that has the information when a new Group of operation starts) //## @ingroup Interaction + + /** + * \deprecatedSince{2013_03} EventMapper is deprecated. It will become obsolete. + * Mapping from Qt to MITK events is performed now by mitk::QmitkRenderWindow . + * Refer to \see DataInteractionPage for general information about the concept of the new implementation. + */ + class MITK_CORE_EXPORT EventMapper : public vtkXMLParser { public: static EventMapper *New(); vtkTypeMacro(EventMapper,vtkXMLParser); typedef std::vector EventDescriptionVec; typedef std::vector::iterator EventDescriptionVecIter; typedef std::map ConstMap; typedef std::map::iterator ConstMapIter; typedef std::vector< itk::SmartPointer > AddOnVectorType; //##Documentation //## searches the Event in m_EventDescription //## and if included transmits the event to globalInteraction. //## If specified, a custom instance of GlobalInteraction will be used, //## otherwise the method will retrieve the default (singleton) instance. //## the optional parameter should be used in a conference to avoid a //## feedback static bool MapEvent(Event* event, GlobalInteraction* globalInteraction = NULL, int mitkPostedEventID=0 ); //##Documentation //## Searches for the event within stateEvent in the internal map of event descriptions //## If entry found the stateEvent ID is adapted //## maps the Event in m_EventDescription with the ID //## and if found returns true, //## if not found it returns false static bool RefreshStateEvent(StateEvent* stateEvent); //##Documentation //## loads an XML-File containing events and adds definition to internal mapping list //## //## Several files can be loaded. Event descriptions have to be unique or a warning will be displayed. //## If the same file is loaded twice, //## it will only be parsed the first time. //## If a file A, then a file B and then file A is to be loaded, warnings //## will be displayed when loading file A the second time. bool LoadBehavior(std::string fileName); //##Documentation //## loads Events into m_EventDescriptions from xml string //## also involved: EventMapper::startEvent(...) bool LoadBehaviorString(std::string xmlString); //##Documentation //## Try to load standard behavior file "StateMachine.xml" //## //## Search strategy: //## \li try environment variable "MITKCONF" (path to "StateMachine.xml") //## \li try "./StateMachine.xml" //## \li try via source directory (using MITKROOT from cmake-created //## mitkConfig.h) "MITKROOT/Interactions/mitkBaseInteraction/StateMachine.xml" bool LoadStandardBehavior(); //##Documentation //## reads a Tag from an XML-file //## adds Events to m_EventDescription std::string GetStyleName() const; //friendship because of SetStateEvent for computing WorldCoordinates friend class mitk::GlobalInteraction; /** * @brief adds a new EventMapper addon */ void AddEventMapperAddOn(mitk::EventMapperAddOn* newAddOn); /** * @brief removes an EventMapper addon */ void RemoveEventMapperAddOn(mitk::EventMapperAddOn* unusedAddOn); protected: EventMapper(); ~EventMapper(); //##Documentation //##@brief method only for GlobalInteraction to change the Event (from DiplayPositionEvent to PositionEvent) static void SetStateEvent(Event* event); private: //##Documentation //## @brief method used in XLM-Reading; gets called when a start-tag is read void StartElement (const char *elementName, const char **atts); //##Documentation //## @brief reads an XML-String-Attribute std::string ReadXMLStringAttribut( std::string name, const char** atts); //##Documentation //## @brief reads an XML-Integer-Attribute int ReadXMLIntegerAttribut( std::string name, const char** atts ); //##Documentation //## @brief converts the strings given by the XML-Behaviour-File to int inline int convertConstString2ConstInt(std::string input); //static std::string Convert2String(int input); //static std::string Convert2String(double input); //static std::string Convert2String(float input); //##Documentation //## @brief maps the strings to int for convertion from XML-Behaviour-File ConstMap m_EventConstMap; //##Documentation //## @brief stores the information for the connection between QT-Events and the internal EventId. //## gets this information from xml-File static EventDescriptionVec m_EventDescriptions; static std::string m_XmlFileName; static StateEvent m_StateEvent; //##Documentation //## @brief stores the name of the Event-Style loaded static std::string m_StyleName; static const std::string STYLE; static const std::string NAME; static const std::string ID; static const std::string TYPE; static const std::string BUTTON; static const std::string BUTTONSTATE; static const std::string KEY; static const std::string EVENTS; static const std::string EVENT; /** * @brief all available EventMapper addons consisting of one or more input devices */ AddOnVectorType m_AddOnVector; }; } // namespace mitk #endif /* EVENTMAPPER_H_HEADER_INCLUDED_C187864A */ diff --git a/Core/Code/Interactions/mitkGlobalInteraction.h b/Core/Code/Interactions/mitkGlobalInteraction.h index 973ebf51da..816a712f29 100755 --- a/Core/Code/Interactions/mitkGlobalInteraction.h +++ b/Core/Code/Interactions/mitkGlobalInteraction.h @@ -1,317 +1,323 @@ /*=================================================================== 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 GLOBALINTERACTION_H_HEADER_INCLUDED_C152938A #define GLOBALINTERACTION_H_HEADER_INCLUDED_C152938A #include "mitkFocusManager.h" #include #include "mitkStateMachineFactory.h" #include "mitkEventMapper.h" #include "mitkInteractor.h" namespace mitk { class PositionEvent; //##Documentation //## @brief handles all global Events //## //## superior statemachine, that spreads the events to all other interactors //## //## Initialization //## Attention: GlobalInteraction must be initialized by the Initialize() method //## before usage by giving it an XML scheme. Possibilities are giving it an empty string (default), //## the filename of an XML file or the actual XML content as std::string. If an empty string is given, //## the content is tried to be loaded from the default file location. //## //## Concept of sending events: //## In this concept of interaction, the statemachines can be divided into two main statemachines: //## Listeners and interactors. //## Listeners only receive the event to process it, but don't change any data. They want to listen to all events. //## Interactors do change data according to the received event. They do not need to receive all events, only //## those they are interested in. //## Additional to that a EVENT_NOTIFICATION_POLICY can be set. This can be either INFORM_MULTIPLE (the event is passed //## to all listeners) or INFORM_ONE (event is passed to the listener which can handle the event best and only to this one). //## //## To divide these two types of statemachine this class holds three lists and two maps: //## m_ListenerList, m_InteractorList, m_SelectedList and m_InteractorRelevanceMap and m_ListenerRelevanceMap //## The list m_ListenerList holds all listeners. //## m_InteractorList holds all interactors, and the List m_SelectedList holds all machines, that were set to SELECTED or SUBSELECTED. //## m_InteractorRelevanceMap and m_ListenerRelevanceMap map values returned from CanHandleEvent to the asked Interactors and Listeners. //## Through m_InteractorRelevanceMap stepping through interactors, that were not selected and could handle that event, can be done. //## Through m_ListenerRelevanceMap the listener which can handle the event best can be determined. In case of the INFORM_ONE notification policy //## the event is passed to just this listener //## //## First the listeners are informed with the event. //## Then the selected or subselected interactors are asked if they can handle that event. //## They can handle it, if the mode of the interactor after HandleEvent(..) is still in SMSELECTED or SMSUBSELECTED. //## They can't handle it, if the mode changed to SMDESELECTED. Then the interactor is removed from the selected-list. //## In that case, all interactors are asked to calculate and return their area of Relevance. //## An iterator is held on one interactor in the map. With the iterator, the map can be looped through so //## so that several geometric objects, that lie on top of each other, can be selected. //## @ingroup Interaction + + /** + * \deprecatedSince{2013_03} GlobalInteraction is deprecated. It is replaced by mitk::Dispatcher. + * Please use the new implementation described in \see DataInteractionPage . + */ + class MITK_CORE_EXPORT GlobalInteraction : public StateMachine { public: mitkClassMacro(GlobalInteraction, StateMachine); itkNewMacro(Self); typedef std::vector StateMachineList; typedef std::vector StateMachineCPointerList; typedef StateMachineList::iterator StateMachineListIter; typedef StateMachineCPointerList::iterator StateMachineCPointerListIter; typedef std::vector InteractorList; typedef InteractorList::iterator InteractorListIter; typedef std::multimap > InteractorMap; typedef std::multimap > StateMachineMap; typedef InteractorMap::iterator InteractorMapIter; typedef StateMachineMap::iterator StateMachineMapIter; /** * Enum for setting the event notification policy of the GlobalInteraction. */ enum EVENT_NOTIFICATION_POLICY { INFORM_MULTIPLE, /** For setting that all registered listeners are informed */ INFORM_ONE /** For setting that just the listener that can handle the event best is informed */ }; //##Documentation //## @brief add an Interactor to the list of all interactors that are asked for handling an event //## //## returns true in case of success void AddInteractor(Interactor* interactor); //##Documentation //## @brief remove a certain Interactor from the set of interactors that are asked for handling an event //## //## returns true in case of success bool RemoveInteractor(Interactor* interactor); //##Documentation //## @brief returns true, if the given interactor is already added to the Interactor-List bool InteractorRegistered (Interactor* interactor); //##Documentation //## @brief add a Listener to the list of all Listeners that are informed of an event //## //## returns true in case of success void AddListener(StateMachine* listener); //##Documentation //## @brief remove a certain Listener from the set of Listeners that are informed of an event //## //## returns true in case of success bool RemoveListener(StateMachine* listener); //##Documentation //## @brief returns true, if the given interactor is already added to the Listener-List bool ListenerRegistered (StateMachine* listener); //##Documentation //## @brief adds an element in the list in FocusManager //## //## true if success, false if the element is already in list bool AddFocusElement(FocusManager::FocusElement* element); //##Documentation //## @brief Removes an element in FocusManager //## //## true if success, false if the element was not in the list bool RemoveFocusElement(FocusManager::FocusElement* element); //##Documentation //## @brief Returns the focused Element in FocusManager FocusManager::FocusElement* GetFocus(); //##Documentation //## @brief Sets the given Element to focused //## //## returns true if the given element was found and focused bool SetFocus(FocusManager::FocusElement* element); //##Documentation //## @brief Returns the pointer to the FocusManager //## //## to add the observer for an event FocusManager* GetFocusManager(); //##Documentation //## @brief Returns the pointer to the EventMapper //## //## to add an addon EventMapper* GetEventMapper(); /** * @brief Return StateMachineFactory **/ StateMachineFactory* GetStateMachineFactory(); /** * @brief Returns the StartState of the StateMachine with the name type; * * Asks member StateMachineFactory for the StartState. * Returns NULL if no entry with name type is found. **/ State* GetStartState(const char* type); //##Documentation //## @brief Returns the global (singleton) instance of //## GlobalInteraction. Create it, if it does not exist. static GlobalInteraction* GetInstance(); //##Documentation //## @brief Initializes the global (singleton) instance of //## GlobalInteraction via an XML string. Must! be done before usage. Can be done only once. //## Can be used with an empty string (default), a file name with path, or the actual XML content as string. bool Initialize(const char* globalInteractionName, const std::string XMLBehaviorInput = ""); //##Documentation //## @brief Check if GlobalInteraction has already been initialized. Init must! be done before usage. bool IsInitialized() {return m_IsInitialized;} /** * @brief Set the policy of how the global interaction informs listeners and interactors * * INFORM_MULTIPLE broadcasts the event to all listeners and interactors that can handle the event * INFORM_ONE only informs the listener or interactor which can handle the event best **/ void SetEventNotificationPolicy(EVENT_NOTIFICATION_POLICY); /** * Return the current set eventspreading policy * @returns the current event spreading policy **/ EVENT_NOTIFICATION_POLICY GetEventNotificationPolicy() const; //so that the interactors can call AddToSelectedInteractors() and RemoveFromSelectedInteractors() friend class Interactor; protected: /** * @brief Default Constructor with type to load the StateMachinePattern of the StateMachine * @param XMLbehaviorFile the file which contains the statemachine and event patterns * @param type the name of the statemachine pattern this class shall use **/ GlobalInteraction(); /** * @brief Default destructor. **/ ~GlobalInteraction(); virtual bool ExecuteAction(Action* action, mitk::StateEvent const* stateEvent); /* *@brief adds the given interactor to the list of selected interactors. * This list is asked first to handle an event. */ virtual bool AddToSelectedInteractors(Interactor* interactor); /* *@brief removes the given interactor from the list of selected interactors * This list is asked first to handle an event. */ virtual bool RemoveFromSelectedInteractors(Interactor* interactor); private: //##Documentation //##@brief informing all statemachines that are held in the list m_ListenerList void InformListeners(mitk::StateEvent const* stateEvent); //##Documentation //##@brief asking the selected Interactor if an event can be handled //## //## returns false if no Interactor could handle the event bool AskSelected(mitk::StateEvent const* stateEvent); //##Documentation //##@brief asking next interactor of m_RelevanceMap bool AskCurrentInteractor(mitk::StateEvent const* stateEvent); //##Documentation //##@brief filling m_InteractorRelevanceMap //## //## @ params threshold: if the calculated Relevance value is above threshold, then add it to the map void FillInteractorRelevanceMap(mitk::StateEvent const* stateEvent, float threshold); //##Documentation //##@brief filling m_ListenerRelevanceMap //## //## @ params threshold: if the calculated Relevance value is above threshold, then add it to the map void FillListenerRelevanceMap(mitk::StateEvent const* stateEvent, float threshold); void RemoveFlaggedListeners(); StateMachineCPointerList m_ListenersFlaggedForRemoval; //##Documentation //## @brief list of all listening statemachines, that want to receive all events StateMachineList m_ListenerList; //##Documentation //## @brief list of all interactors (statemachine, that change data) InteractorList m_InteractorList; //##Documentation //## @brief list of all interactors, that are in Mode SELECTED or SUBSELECTED InteractorList m_SelectedList; //##Documentation //## @brief map for sorting all interactors by the value returned from CanHandleEvent(..). //## //## With that list certain interactors can be looped through like diving through layers InteractorMap m_InteractorRelevanceMap; //##Documentation //## @brief map for sorting all listeners by the value returned from CanHandleEvent(..). //## //## With that list certain listeners can be looped through like diving through layers StateMachineMap m_ListenerRelevanceMap; //##Documentation //## @brief iterator on an entry in m_RelevanceMap for stepping through interactors InteractorMapIter m_CurrentInteractorIter; //##Documentation //## @brief holds a list of BaseRenderer and one focused FocusManager::Pointer m_FocusManager; /** * @brief StatemachineFactory loads statemachine patterns and provides start states **/ StateMachineFactory* m_StateMachineFactory; /** * @brief EventMapper loads event patterns **/ EventMapper* m_EventMapper; bool m_CurrentlyInInformListenersLoop; bool m_CurrentlyInInformInteractorsLoop; bool m_IsInitialized; EVENT_NOTIFICATION_POLICY m_EventNotificationPolicy; }; } // namespace mitk #endif /* GLOBALINTERACTION_H_HEADER_INCLUDED_C152938A */ diff --git a/Core/Code/Interactions/mitkInteractor.h b/Core/Code/Interactions/mitkInteractor.h index 1178a06d81..8574a27b4f 100755 --- a/Core/Code/Interactions/mitkInteractor.h +++ b/Core/Code/Interactions/mitkInteractor.h @@ -1,170 +1,174 @@ /*=================================================================== 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 INTERACTOR_H_HEADER_INCLUDED #define INTERACTOR_H_HEADER_INCLUDED #include #include "mitkStateMachine.h" #include "mitkGeometry3D.h" #include namespace mitk { class DataNode; class BaseData; //##Documentation //## @brief Interface for an Interactor. //## //## The Interactor is held with a SmartPointer by a DataNode //## and holds its Node with a Pointer. That way Smartpointer doesn't build a circle. //## Different Modes: In order to not send Events to all StateMachines, a StateMachine can be //## in three different modes: //## DESELECTED: this statemachine doesn't wait for an event //## SELECTED: this statemachine just has handled an event and waits for the next one //## SUBSELECTED: depricate; was used for hierarchical statemachines before. //## Guidelines for the modevalues: Selected if the coresponding data is selected, deselected if deselect of data. //## //## In moving the machine is selected. After a new insert the machine is selected, since the data is also selected //## In method ExecuteAction(..) the different actions are divided up through switch/case statements. Each block has to check //## the appropriate type of event to process the actions. Especially in guarding states (a state, that checks certain conditions (e.g. is picked) //## the according Event must be called to continue in states. No return false here! //## @ingroup Interaction +/** + * \deprecatedSince{2013_03} mitk::Interactor is deprecated. Use mitk::DataInteractor instead. + * Refer to \see DataInteractionPage for general information about the concept of the new implementation. + */ class MITK_CORE_EXPORT Interactor : public StateMachine { public: mitkClassMacro(Interactor, StateMachine); /** * @brief NewMacro with two parameters for calling itk::Lightobject::New(..) method **/ mitkNewMacro2Param(Self, const char*, DataNode*); //##Documentation //##@brief Enumeration of the different modes an Interactor can be into. //## See class documentation for further details enum SMMode { SMDESELECTED = 0, SMSELECTED, SMSUBSELECTED }; typedef SMMode ModeType; //##Documentation //## @brief Get the Mode of the Interactor. Use enum SMMode for return parameter SMMode GetMode() const; //##Documentation //## @brief Check the interaction mode bool IsNotSelected() const; //##Documentation //## @brief Check the interaction mode bool IsSelected() const; //##Documentation //## @brief calculates how good the data, this statemachine handles, is hit by the event. //## //## Returns a value between 0 and 1 //## where 0 represents not responsible and 1 represents definitive responsible! //## Standard function to override if needed. //## (Used by GlobalInteraction to decide which DESELECTED statemachine to send the event to.) virtual float CanHandleEvent(StateEvent const* stateEvent) const; /** * @brief Updates the current TimeStep according to the associated data and calls Superclass::HandleEvent() **/ bool HandleEvent(StateEvent const* stateEvent); /** * @brief Method to call if the associated data has changed by the user (loading of data) * This method is called by DataNode::SetData() to tell the interactor to reinitialize. * This method should be overwritten by specialized interactors. * (e.g. PointSetInteractor: go to the right state according to number of loaded points) * Note: It will not be called when the data gets modified (e.g. adding / removing points to a PointSet) **/ virtual void DataChanged(){}; //##Documentation //## @brief adds handling of operations used for mode change. Unrecognized Operations are send to Superclass. //## *ATTENTION*: THIS METHOD SHOULD NOT BE CALLED FROM OTHER CLASSES DIRECTLY! virtual void ExecuteOperation(Operation* operation); static const std::string XML_NODE_NAME; protected: /** * @brief Constructor * @param dataNode is the node, this Interactor is connected to * @param type is the type of StateMachine like declared in the XML-Configure-File * * Interactor connects itself to the DataNode-Interactor-pointer through call of SetInteractor(this) **/ Interactor(const char * type, DataNode* dataNode); /** * @brief Destructor **/ ~Interactor(){} bool OnModeSelect(Action* action, StateEvent const*); bool OnModeDeselect(Action* action, StateEvent const*); bool OnModeSubSelect(Action* action, StateEvent const*); //##Documentation virtual const std::string& GetXMLNodeName() const; //##Documentation //## @brief creates a ModeOperation with the transmitted mode and sends it to this. Undo supported! void CreateModeOperation(ModeType mode); //##Documentation //## @brief convenience method for accessing the data contained in the //## node to which this interactor is associated to BaseData* GetData() const; //##Documentation //## @brief Used by friend class DataNode virtual void SetDataNode( DataNode* dataNode ); /** * @brief Derived from superclass to also check if enough timesteps are instantiated in m_CurrentStateVector * The number of timesteps is read from the dedicated data. * @param[in] timeStep The timeStep that the statemachine has to be set to **/ virtual void UpdateTimeStep(unsigned int timeStep); //##Documentation //## @brief Pointer to the data, this object handles the Interaction for DataNode* m_DataNode; //##Documentation //## @brief Mode of Selection ModeType m_Mode; friend class DataNode; }; }//namespace mitk #endif /* INTERACTOR_H_HEADER_INCLUDED */ diff --git a/Core/Code/Interactions/mitkKeyEvent.h b/Core/Code/Interactions/mitkKeyEvent.h index 080d0e429b..6f4f555edb 100644 --- a/Core/Code/Interactions/mitkKeyEvent.h +++ b/Core/Code/Interactions/mitkKeyEvent.h @@ -1,78 +1,83 @@ /*=================================================================== 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 KeyEvent_H_HEADER_INCLUDED_C184F366 #define KeyEvent_H_HEADER_INCLUDED_C184F366 #include #include "mitkEvent.h" #include "mitkVector.h" namespace mitk { //##Documentation //## @brief Event that stores coordinates and the key which is pressed //## //## Stores display position of the mouse. If requested, the correspondent //## 3D world position in mm is calculated via picking (delegated to the //## BaseRenderer). //## @ingroup Interaction + + /** + * \deprecatedSince{2013_03} KeyEvent is deprecated. Use mitk::InteractionKeyEvent instead. + * Refer to \see DataInteractionPage for general information about the concept of the new implementation. + */ class MITK_CORE_EXPORT KeyEvent : public Event { public: //##Documentation //## @brief Constructor with all necessary arguments. //## //## @param sender is the renderer that caused that event //## @param type, button, buttonState, key: information from the Event //## @param displPosition is the 2D Position of the mouse KeyEvent(BaseRenderer* sender, int type, int button, int buttonState, int key, std::string text, const Point2D& displPosition); const Point2D& GetDisplayPosition() const { return m_DisplayPosition; } void SetDisplayPosition(const Point2D& displPosition) { m_DisplayPosition = displPosition; } const Point3D& GetWorldPosition() const; int GetKey() const { return m_Key; } const char* GetText() const { return m_Text.c_str(); } int GetType() const { return m_Type; } protected: Point2D m_DisplayPosition; int m_Key; std::string m_Text; mutable Point3D m_WorldPosition; mutable bool m_WorldPositionIsSet; }; } // namespace mitk #endif /* DISPLAYPOSITIONozsiEVENT_H_HEADER_INCLUDED_C184F366 */ diff --git a/Core/Code/Interactions/mitkPositionEvent.h b/Core/Code/Interactions/mitkPositionEvent.h index 306284fb9c..689d1d9c94 100644 --- a/Core/Code/Interactions/mitkPositionEvent.h +++ b/Core/Code/Interactions/mitkPositionEvent.h @@ -1,50 +1,55 @@ /*=================================================================== 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 POSITIONEVENT_H_HEADER_INCLUDED_C184F366 #define POSITIONEVENT_H_HEADER_INCLUDED_C184F366 #include #include "mitkDisplayPositionEvent.h" #include "mitkVector.h" namespace mitk { //##Documentation //## @brief Event that stores coordinates //## //## Stores display position of the mouse and 3D world position in mm. //## @ingroup Interaction + + /** + * \deprecatedSince{2013_03} mitk::PositionEvent is deprecated. Use mitk::InteractionPositionEvent instead. + * Refer to \see DataInteractionPage for general information about the concept of the new implementation. + */ class MITK_CORE_EXPORT PositionEvent : public DisplayPositionEvent { public: //##Documentation //## @brief Constructor with all necessary arguments. //## //## @param sender: the widget, that caused that event, so that it can be asked for worldCoordinates. changed later to a focus //## @param type, button, buttonState, key: information from the Event //## @param displPosition: the 2D Position e.g. from the mouse //## @param worldPosition: the 3D position e.g. from a picking PositionEvent(BaseRenderer* sender, int type, int button, int buttonState, int key, const Point2D& displPosition, const Point3D& worldPosition); }; } // namespace mitk #endif /* POSITIONEVENT_H_HEADER_INCLUDED_C184F366 */ diff --git a/Core/Code/Interactions/mitkState.h b/Core/Code/Interactions/mitkState.h index b7530e3e5b..7c43113e0f 100755 --- a/Core/Code/Interactions/mitkState.h +++ b/Core/Code/Interactions/mitkState.h @@ -1,133 +1,134 @@ /*=================================================================== -The Medical Imaging Interaction Toolkit (MITK) + The Medical Imaging Interaction Toolkit (MITK) -Copyright (c) German Cancer Research Center, -Division of Medical and Biological Informatics. -All rights reserved. + 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. + 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. - -===================================================================*/ + See LICENSE.txt or http://www.mitk.org for details. + ===================================================================*/ #ifndef STATE_H_HEADER_INCLUDED_C19A8A5D #define STATE_H_HEADER_INCLUDED_C19A8A5D #include #include #include #include #include #include #include #include "mitkTransition.h" -namespace mitk { +namespace mitk +{ /** - * @brief represents one state with all its necessary information - * - * Name and ID are stored. Also methods for building up, connecting and - * parsing for well formed statemachines are present. - * This class holds a map of transitions to next States. - * @ingroup Interaction - **/ - class MITK_CORE_EXPORT State : public itk::Object + * @brief represents one state with all its necessary information + * + * Name and ID are stored. Also methods for building up, connecting and + * parsing for well formed statemachines are present. + * This class holds a map of transitions to next States. + * @ingroup Interaction + * \deprecatedSince{2013_03} mitk::State is deprecated. Please use the mitk::StateMachineState instead. + * Refer to \see DataInteractionPage for general information about the concept of the new implementation. + */ + + class MITK_CORE_EXPORT State: public itk::Object { public: - mitkClassMacro(State, itk::Object); + mitkClassMacro(State, itk::Object) /** - * @brief static New method to use SmartPointer - **/ - mitkNewMacro2Param(Self, std::string, int); + * @brief static New method to use SmartPointer + **/ + mitkNewMacro2Param(Self, std::string, int) typedef std::map StateMap; typedef std::map > TransitionMap; typedef StateMap::iterator StateMapIter; typedef TransitionMap::iterator TransMapIter; typedef TransitionMap::const_iterator TransMapConstIter; /** - * @brief Add a transition to the map of transitions. - * - * Instances of all added transitions are freed in destructor of this class. - **/ - bool AddTransition( Transition* transition ); + * @brief Add a transition to the map of transitions. + * + * Instances of all added transitions are freed in destructor of this class. + **/ + bool AddTransition(Transition* transition); /** - * @brief hashmap-lookup and returning the Transition. Returns NULL Pointer if not located - **/ + * @brief hashmap-lookup and returning the Transition. Returns NULL Pointer if not located + **/ const Transition* GetTransition(int eventId) const; /** - * @brief Returns the name. - **/ + * @brief Returns the name. + **/ std::string GetName() const; /** - * @brief Returns the Id. - **/ + * @brief Returns the Id. + **/ int GetId() const; /** - * @brief Returns a set of all next States. E.g. to parse through all States. - **/ + * @brief Returns a set of all next States. E.g. to parse through all States. + **/ std::set GetAllNextStates() const; /** - * @brief Check, if this event (eventId) leads to a state. - **/ + * @brief Check, if this event (eventId) leads to a state. + **/ bool IsValidEvent(int eventId) const; /** - * @brief Searches dedicated States of all Transitions and sets *nextState of these Transitions. - * Required for this is a List of all build States of that StateMachine (allStates). This way the StateMachine can be build up. - **/ + * @brief Searches dedicated States of all Transitions and sets *nextState of these Transitions. + * Required for this is a List of all build States of that StateMachine (allStates). This way the StateMachine can be build up. + **/ bool ConnectTransitions(StateMap* allStates); protected: /** - * @brief Default Constructor. Use ::New instead! - * Set the name and the Id of the state. - * Name is to maintain readability during debug and Id is to identify this state inside the StateMachinePattern - **/ + * @brief Default Constructor. Use ::New instead! + * Set the name and the Id of the state. + * Name is to maintain readability during debug and Id is to identify this state inside the StateMachinePattern + **/ State(std::string name, int id); /** - * @brief Default Destructor - **/ + * @brief Default Destructor + **/ ~State(); private: /** - * @brief Name of this State to support readability during debug - **/ + * @brief Name of this State to support readability during debug + **/ std::string m_Name; /** - * @brief Id of this State important for interaction mechanism in StateMachinePattern - * - * All states inside a StateMachinePattern (construct of several states connected with transitions and actions) have to have an own id with which it is identifyable. - **/ + * @brief Id of this State important for interaction mechanism in StateMachinePattern + * + * All states inside a StateMachinePattern (construct of several states connected with transitions and actions) have to have an own id with which it is identifyable. + **/ int m_Id; /** - * @brief map of transitions that lead from this state to the next state - **/ + * @brief map of transitions that lead from this state to the next state + **/ TransitionMap m_Transitions; }; } // namespace mitk - - #endif /* STATE_H_HEADER_INCLUDED_C19A8A5D */ diff --git a/Core/Code/Interactions/mitkStateEvent.h b/Core/Code/Interactions/mitkStateEvent.h index 53d05e7f88..0326d07952 100644 --- a/Core/Code/Interactions/mitkStateEvent.h +++ b/Core/Code/Interactions/mitkStateEvent.h @@ -1,66 +1,72 @@ /*=================================================================== 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 STATEEVENT_H_HEADER_INCLUDED_C188E5BF #define STATEEVENT_H_HEADER_INCLUDED_C188E5BF #include namespace mitk { class Event; //##Documentation //## @brief Class holding an mitk-event and the mitk-event-number for a statechange //## //## Holds an event, with which a statechange of a statemachine shall be //## done. iD represents the mitk-event-number, event all further necessary information like //## the MousePosition or a key. //## Not derived from event to hold only one object stateevent, pass it to the statemachines, //## set the next event and reuse this object //## @ingroup Interaction + + /** + * \deprecatedSince{2013_03} mitk::StateEvent is deprecated. It becomes obsolete. + * Refer to \see DataInteractionPage for general information about the concept of the new implementation. + */ + class MITK_CORE_EXPORT StateEvent { public: StateEvent(); //##Documentation //## @brief Constructor //## @param id: mitk internal EventID //## @param event: the information about the appeared event StateEvent(int id, Event const* event = 0 ); ~StateEvent(); //##Documentation //## @brief to set the params and reuse an object void Set(int id, Event const* event); int GetId() const; mitk::Event const* GetEvent() const; private: int m_Id; mitk::Event const* m_Event; }; } // namespace mitk #endif /* STATEEVENT_H_HEADER_INCLUDED_C188E5BF */ diff --git a/Core/Code/Interactions/mitkStateMachine.h b/Core/Code/Interactions/mitkStateMachine.h index 52e389b291..1a7e848569 100644 --- a/Core/Code/Interactions/mitkStateMachine.h +++ b/Core/Code/Interactions/mitkStateMachine.h @@ -1,301 +1,307 @@ /*=================================================================== 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 STATEMACHINE_H_HEADER_INCLUDED_C18896BD #define STATEMACHINE_H_HEADER_INCLUDED_C18896BD #include #include #include "mitkOperationActor.h" #include #include "mitkState.h" #include "mitkUndoModel.h" namespace mitk { class Action; class StateEvent; class UndoController; // base class of statem machine functors + class MITK_CORE_EXPORT TStateMachineFunctor { public: virtual bool DoAction(Action*, const StateEvent*)=0; // call using function virtual ~TStateMachineFunctor() {} }; // the template functor for arbitrary StateMachine derivations template class TSpecificStateMachineFunctor : public TStateMachineFunctor { public: // constructor - takes pointer to an object and pointer to a member and stores // them in two private variables TSpecificStateMachineFunctor(T* object, bool(T::*memberFunctionPointer)(Action*, const StateEvent*)) :m_Object(object), m_MemberFunctionPointer(memberFunctionPointer) { } virtual ~TSpecificStateMachineFunctor() {} // virtual destructor // override function "Call" virtual bool DoAction(Action* action, const StateEvent* stateEvent) { return (*m_Object.*m_MemberFunctionPointer)(action, stateEvent); // execute member function } private: T* m_Object; // pointer to object bool (T::*m_MemberFunctionPointer)(Action*, const StateEvent*); // pointer to member function }; /// Can be uses by derived classes of StateMachine to connect action IDs to methods /// Assumes that there is a typedef Classname Self in classes that use this macro #define CONNECT_ACTION(a, f) \ StateMachine::AddActionFunction(a, new TSpecificStateMachineFunctor(this, &Self::f)); #define STATEMACHINE_INFO MITK_INFO("StateMachine") << "[type: " << GetType() << "] " #define STATEMACHINE_WARN MITK_WARN("StateMachine") << "[type: " << GetType() << "] " #define STATEMACHINE_FATAL MITK_FATAL("StateMachine") << "[type: " << GetType() << "] " #define STATEMACHINE_ERROR MITK_ERROR("StateMachine") << "[type: " << GetType() << "] " #define STATEMACHINE_DEBUG MITK_DEBUG("StateMachine") << "[type: " << GetType() << "] " /** @brief Superior statemachine @ingroup Interaction Realizes the methods, that every statemachine has to have. Undo can be enabled and disabled through EnableUndo. To implement your own state machine, you have to derive a class from mitk::StateMachine and either - override ExecuteAction() or - Write bool methods that take (Action*, const StateEvent*) as parameter and use the CONNECT_ACTION macro in your constructor The second version is recommended, since it provides more structured code. The following piece of code demonstrates how to use the CONNECT_ACTION macro. The important detail is to provide a typedef classname Self \code class LightSwitch : public StateMachine { public: mitkClassMacro(LightSwitch, StateMachine); // this creates the Self typedef LightSwitch(const char*); bool DoSwitchOn(Action*, const StateEvent*); bool DoSwitchOff(Action*, const StateEvent*); } LightSwitch::LightSwitch(const char* type) :StateMachine(type) { // make sure that AcSWITCHON and AcSWITCHOFF are defined int constants somewhere (e.g. mitkInteractionConst.h) CONNECT_ACTION( AcSWITCHON, DoSwitchOn ); CONNECT_ACTION( AcSWITCHOFF, DoSwitchOff ); } bool LightSwitch::DoSwitchOn(Action*, const StateEvent*) { std::cout << "Enlightenment" << std::endl; } bool LightSwitch::DoSwitchOff(Action*, const StateEvent*) { std::cout << "Confusion" << std::endl; } \endcode What CONNECT_ACTION does, is call StateMachine::AddActionFunction(...) to add some function pointer wrapping class (functor) to a std::map of StateMachine. Whenever StateMachines ExecuteAction is called, StateMachine will lookup the desired Action in its map and call the appropriate method in your derived class. **/ + /** + * \deprecatedSince{2013_03} mitk::StateMachine is deprecated. Use mitk::EventStateMachine instead. + * Refer to \see DataInteractionPage for general information about the concept of the new implementation. + */ + class MITK_CORE_EXPORT StateMachine : public itk::Object, public mitk::OperationActor { public: mitkClassMacro(StateMachine,itk::Object); /** * @brief New Macro with one parameter for creating this object with static New(..) method **/ mitkNewMacro1Param(Self, const char*); /** * @brief Map to connect action IDs with method calls. Use AddActionFunction or (even better) the CONNECT_ACTION macro to fill the map. **/ typedef std::map ActionFunctionsMapType; /** * @brief Type for a vector of StartStatePointers **/ typedef std::vector StartStateVectorType; /** * @brief Get the name and with this the type of the StateMachine **/ std::string GetType() const; /** * @brief handles an Event accordingly to its current State * * Statechange with Undo functionality; * EventMapper gives each event a new objectEventId * and a StateMachine::ExecuteAction can descide weather it gets a * new GroupEventId or not, depending on its state (e.g. finishedNewObject then new GroupEventId). * Object- and group-EventId can also be accessed through static methods from OperationEvent **/ virtual bool HandleEvent(StateEvent const* stateEvent); /** * @brief calculates how good this statemachine can handle the event. * * Returns a value between 0 and 1 * where 0 represents not responsible and 1 represents definitive responsible! * Standard function to override if needed. * (Used by GlobalInteraction to decide which DESELECTED statemachine to send the event to.) **/ virtual float CanHandleEvent(const StateEvent *) const; /** * @brief Enables or disabled Undo. **/ void EnableUndo(bool enable); /** * @brief A statemachine is also an OperationActor due to the UndoMechanism. * * The statechange is done in ExecuteOperation, so that the statechange can be undone by UndoMechanism. * Is set private here and in superclass it is set public, so UndoController * can reach ist, but it can't be overwritten by a subclass * *ATTENTION*: THIS METHOD SHOULD NOT BE CALLED FROM OTHER CLASSES DIRECTLY! **/ virtual void ExecuteOperation(Operation* operation); /** * @brief Friend so that UndoModel can call ExecuteOperation for Undo. **/ friend class UndoModel; friend class GlobalInteraction; protected: /** * @brief Default Constructor. Obsolete to instanciate it with this method! Use ::New(..) method instead. Set the "type" and with this the pattern of the StateMachine **/ StateMachine(const char * type); /** * @brief Default Destructor **/ ~StateMachine(); /** * @brief Adds the Function to ActionList. **/ void AddActionFunction(int action, TStateMachineFunctor* functor); /** * @brief Method called in HandleEvent after Statechange. * * Each statechange has actions, which can be assigned by it's number. * If you are developing a new statemachine, declare all your operations here and send them to Undo-Controller and to the Data. * Object- and group-EventId can also be accessed through static methods from OperationEvent **/ virtual bool ExecuteAction(Action* action, StateEvent const* stateEvent); /** * @brief returns the current state **/ const State* GetCurrentState(unsigned int timeStep = 0) const; /** * @brief if true, then UndoFunctionality is enabled * * Default value is true; **/ bool m_UndoEnabled; /** * @brief Friend protected function of OperationEvent; that way all StateMachines can set GroupEventId to be incremented! **/ void IncCurrGroupEventId(); /** * @brief holds an UndoController, that can be accessed from all StateMachines. For ExecuteAction **/ UndoController* m_UndoController; /** * @brief Resets the current state from the given timeStep to the StartState with undo functionality! Use carefully! * @param[in] timeStep If the statemachine has several timesteps to take care of, specify the according timestep **/ void ResetStatemachineToStartState(unsigned int timeStep = 0); /** * @brief Check if the number of timeSteps is equal to the number of stored StartStates. Nothing is changed if the number is equal. **/ void ExpandStartStateVector(unsigned int timeSteps); /** * @brief initializes m_CurrentStateVector **/ void InitializeStartStates(unsigned int timeSteps); /** * @brief Update the TimeStep of the statemachine with undo-support if undo enabled **/ virtual void UpdateTimeStep(unsigned int timeStep); /** * @brief Current TimeStep if the data which is to be interacted on, has more than 1 TimeStep **/ unsigned int m_TimeStep; private: /** * @brief The type of the StateMachine. This string specifies the StateMachinePattern that is loaded from the StateMachineFactory. **/ std::string m_Type; /** * @brief Points to the current state. **/ StartStateVectorType m_CurrentStateVector; /** * @brief Map of the added Functions **/ ActionFunctionsMapType m_ActionFunctionsMap; }; } // namespace mitk #endif /* STATEMACHINE_H_HEADER_INCLUDED_C18896BD */ diff --git a/Core/Code/Interactions/mitkStateMachineFactory.h b/Core/Code/Interactions/mitkStateMachineFactory.h index 333bf33fae..9840a80224 100755 --- a/Core/Code/Interactions/mitkStateMachineFactory.h +++ b/Core/Code/Interactions/mitkStateMachineFactory.h @@ -1,227 +1,232 @@ /*=================================================================== 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 STATEMACHINEFACTORY_H_HEADER_INCLUDED_C19AEDDD #define STATEMACHINEFACTORY_H_HEADER_INCLUDED_C19AEDDD #include #include "mitkState.h" #include "mitkTransition.h" #include "mitkAction.h" #include #include #include namespace mitk { /** *@brief builds up all specifiyed statemachines and hold them for later access * * According to the XML-File every different statemachine is build up. A new * instance of a new StateMachine grabs a StartState of one certain * state machine. Two instances of one kind of state machine share that * state machine. * During buildprocess at runtime each state machine is parsed for well formed style. * Currently different interaction styles are not yet supported. * To add individual state machine patterns, call LoadBehavior(...) * and it will be parsed added to the internal list of patterns * * @ingroup Interaction **/ + /** + * \deprecatedSince{2013_03} StateMachineFactory is deprecated. Please use mitk::StateMachineContainer instead. + * Refer to \see DataInteractionPage for general information about the concept of the new implementation. + */ + class MITK_CORE_EXPORT StateMachineFactory : public vtkXMLParser { public: static StateMachineFactory *New(); vtkTypeMacro(StateMachineFactory,vtkXMLParser); /** * @brief Typedef for all states that are defined as start-states **/ typedef std::map StartStateMap; typedef StartStateMap::iterator StartStateMapIter; /** * @brief Typedef to be used for parsing all states of one statemachine **/ typedef std::set HistorySet; typedef HistorySet::iterator HistorySetIter; /** * @brief This type holds all states of one statemachine. **/ typedef std::map StateMachineMapType; /** * @brief this type holds all states of all statemachines so that a specific state can be accessed for persistence **/ typedef std::map AllStateMachineMapType; /** * @brief Returns the StartState of the StateMachine with the name type; * * Returns NULL if no entry with name type is found. * Here a Smartpointer is returned to ensure, that StateMachines are also considered during reference counting. **/ State* GetStartState(const char* type); /** * @brief loads the xml file filename and generates the necessary instances **/ bool LoadBehavior(std::string fileName); /** * @brief loads the xml string and generates the necessary instances **/ bool LoadBehaviorString(std::string xmlString); /** * @brief Try to load standard behavior file "StateMachine.xml" * * Search strategy: * \li try environment variable "MITKCONF" (path to "StateMachine.xml") * \li try "./StateMachine.xml" * \li try via source directory (using MITKROOT from cmake-created * mitkConfig.h) "MITKROOT/Interactions/mitkBaseInteraction/StateMachine.xml" **/ bool LoadStandardBehavior(); const std::string& GetLastLoadedBehavior() { return m_LastLoadedBehavior; } /** * @brief Adds the given pattern to the internal list of patterns * * Method to support addition of externaly loaded patterns. * Instances of states, transitions and actions are maintained within this class and freed on destruction. * The states already have to be connected by transitions and actions and checked for errors. * @params type name of the pattern to add. Will be used during initialization of a new interactor. * @params startState the start state of this pattern. * @params allStatesOfStateMachine a map of state ids and its states to hold their reference and delete them in destructor **/ bool AddStateMachinePattern(const char * type, mitk::State* startState, StateMachineMapType* allStatesOfStateMachine); /** * brief To enable StateMachine to access states **/ friend class StateMachine; protected: /** * @brief Default Constructor **/ StateMachineFactory(); /** * @brief Default Destructor **/ ~StateMachineFactory(); /** * @brief Derived from XMLReader **/ void StartElement (const char* elementName, const char **atts); /** * @brief Derived from XMLReader **/ void EndElement (const char* elementName); private: /** * @brief Derived from XMLReader **/ std::string ReadXMLStringAttribut( std::string name, const char** atts); /** * @brief Derived from XMLReader **/ float ReadXMLFloatAttribut( std::string name, const char** atts ); /** * @brief Derived from XMLReader **/ double ReadXMLDoubleAttribut( std::string name, const char** atts ); /** * @brief Derived from XMLReader **/ int ReadXMLIntegerAttribut( std::string name, const char** atts ); /** * @brief Derived from XMLReader **/ bool ReadXMLBooleanAttribut( std::string name, const char** atts ); /** * @brief Returns a Pointer to the desired state if found. **/ mitk::State* GetState( const char* type, int StateId ); /** * @brief Sets the pointers in Transition (setNextState(..)) according to the extracted xml-file content **/ bool ConnectStates(mitk::State::StateMap* states); /** * @brief Recusive method, that parses this pattern of the stateMachine and returns true if correct **/ bool RParse(mitk::State::StateMap* states, mitk::State::StateMapIter thisState, HistorySet *history); /** * @brief Holds all created States that are defined as StartState **/ StartStateMap m_StartStates; /** * @brief Holds all States of one StateMachine to build up the pattern. **/ mitk::State::StateMap m_AllStatesOfOneStateMachine; /** * @brief A pointer to a State to help building up the pattern **/ State::Pointer m_AktState; /** * @brief A pointer to a Transition to help building up the pattern **/ itk::WeakPointer m_AktTransition; /** * @brief A pointer to an Action to help building up the pattern **/ Action::Pointer m_AktAction; /** * @brief map to hold all statemachines to call GetState for friends **/ AllStateMachineMapType m_AllStateMachineMap; std::string m_LastLoadedBehavior; std::string m_AktStateMachineName; /** * @brief Variable to skip a state machine pattern if the state machine name is not unique **/ bool m_SkipStateMachine; }; } // namespace mitk #endif /* STATEMACHINEFACTORY_H_HEADER_INCLUDED_C19AEDDD */ diff --git a/Core/Code/Interactions/mitkStateMachineState.h b/Core/Code/Interactions/mitkStateMachineState.h index 3d7a810b8a..5d32ffdc95 100755 --- a/Core/Code/Interactions/mitkStateMachineState.h +++ b/Core/Code/Interactions/mitkStateMachineState.h @@ -1,86 +1,90 @@ /*=================================================================== 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 SMSTATE_H_HEADER_INCLUDED_C19A8A5D #define SMSTATE_H_HEADER_INCLUDED_C19A8A5D #include #include #include #include #include #include "mitkStateMachineTransition.h" namespace mitk { - - // Dispatcher and State Modes + /** + * \class StateMachineState + * Represents a state of a state machine pattern. + * It holds transitions to other states (mitk::StateMachineTransition) and the mode of the current state, see + * m_StateMode . + */ class MITK_CORE_EXPORT StateMachineState : public itk::Object { public: mitkClassMacro(StateMachineState, itk::Object); mitkNewMacro2Param(Self, std::string, std::string); typedef std::vector StateMap; typedef std::vector TransitionVector; bool AddTransition( StateMachineTransition::Pointer transition ); /** * @brief Return Transition which matches given event description. **/ StateMachineTransition::Pointer GetTransition(std::string eventClass, std::string eventVariant); /** * @brief Returns the name. **/ std::string GetName(); std::string GetMode(); /** * @brief Searches dedicated States of all Transitions and sets *nextState of these Transitions. * Required for this is a List of all build States of that StateMachine (allStates). This way the StateMachine can be build up. **/ bool ConnectTransitions(StateMap* allStates); protected: StateMachineState(std::string name, std::string stateMode); ~StateMachineState(); private: /** * @brief Name of this State. **/ std::string m_Name; /** * State Modus, which determines the behavior of the dispatcher. A State can be in three different modes: * REGULAR - standard dispatcher behavior * GRAB_INPUT - all events are given to the statemachine in this modus, if they are not processed by this statemachine the events are dropped. * PREFER_INPUT - events are first given to this statemachine, and if not processed, offered to the other statemachines. */ std::string m_StateMode; /** * @brief map of transitions that lead from this state to the next state **/ TransitionVector m_Transitions; }; } // namespace mitk #endif /* SMSTATE_H_HEADER_INCLUDED_C19A8A5D */ diff --git a/Core/Code/Interactions/mitkTransition.h b/Core/Code/Interactions/mitkTransition.h index d4233365ae..ce9cfb5132 100755 --- a/Core/Code/Interactions/mitkTransition.h +++ b/Core/Code/Interactions/mitkTransition.h @@ -1,140 +1,144 @@ /*=================================================================== 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 TRANSITION_H_HEADER_INCLUDED_C19AE06B #define TRANSITION_H_HEADER_INCLUDED_C19AE06B #include #include #include #include #include "mitkAction.h" namespace mitk { class State; /** * @brief Connection of two states * * A transition connects two states. * Several actions are stored, that have to be executed after the statechange. * @ingroup Interaction - **/ + * + * \deprecatedSince{2013_03} mitk::Transition is deprecated. Use mitk::StateMachineTransition instead. + * Refer to \see DataInteractionPage for general information about the concept of the new implementation. + */ + class MITK_CORE_EXPORT Transition { public: typedef std::vector< mitk::Action::Pointer > ActionVectorType; typedef ActionVectorType::iterator ActionVectorIterator; typedef const ActionVectorIterator ActionVectorConstIterator; /** * @brief Add the action to this object. **/ void AddAction( Action* action ); /** * @brief Return the name of this object. **/ std::string GetName() const; /** * @brief Get the next state of this object. **/ State* GetNextState() const; /** * @brief Get the Id of the next state of this object. **/ int GetNextStateId() const; /** * @brief Get the eventId of this object. **/ int GetEventId() const; /** * @brief Get the number of actions. **/ unsigned int GetActionCount() const; /** * @brief Get an interator on the first action in list. **/ ActionVectorIterator GetActionBeginIterator() const; /** * @brief Get an interator behind the last action in list. **/ ActionVectorConstIterator GetActionEndIterator() const; /** * @brief Returns true if the given eventId is equal to this eventId. **/ bool IsEvent(int eventId) const; /** * @brief Set the next state of this object. **/ void SetNextState(State* state); /** * @brief Default Constructor * Sets the necessary informations name (to enhance readability during debug), * nextStateId (the Id of the next state) and eventId (the Id of the event that causes the statechange). **/ Transition(std::string name, int nextStateId, int eventId); /** * @brief Default Denstructor **/ ~Transition(); private: /** * @brief For better debugging and reading it stores the name of this. **/ std::string m_Name; /** * @brief a Pointer to the next state of this object. **/ itk::WeakPointer m_NextState; /** * @brief The Id of the next state. **/ int m_NextStateId; /** * @brief The eventId which is associated to this object. **/ int m_EventId; /** * @brief The list of actions, that are executed if this transition is done. **/ mutable std::vector m_Actions; }; } // namespace mitk #endif /* TRANSITION_H_HEADER_INCLUDED_C19AE06B */ diff --git a/Core/Code/Interactions/mitkVtkEventAdapter.h b/Core/Code/Interactions/mitkVtkEventAdapter.h index 7ba8e0e22e..4fc6265f35 100644 --- a/Core/Code/Interactions/mitkVtkEventAdapter.h +++ b/Core/Code/Interactions/mitkVtkEventAdapter.h @@ -1,81 +1,81 @@ /*=================================================================== 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 MITKVTKEVENTADAPTER_H_ #define MITKVTKEVENTADAPTER_H_ // INTERACTION LEGACY #include #include #include #include "mitkMousePressEvent.h" #include "mitkMouseReleaseEvent.h" #include "mitkMouseMoveEvent.h" #include "mitkMouseWheelEvent.h" #include "mitkInteractionKeyEvent.h" #include "vtkRenderWindowInteractor.h" //##Documentation //## @brief Generates MITK events from VTK //## //## This class is the NON-QT dependent pendant to QmitkEventAdapter. //## It provides static functions to set up MITK events from VTK source data //## //## @ingroup Interaction namespace mitk { class BaseRenderer; class MITK_EXPORT VtkEventAdapter { public: /** - * \deprecated{Please switch to the appropriate AdaptMousePress/Move/Release-Event function.} + \deprecatedSince{2013_03} This method can be replaced by mitk::AdaptMousePressEvent / mitk::AdaptMouseMoveEvent / mitk::AdaptMouseReleaseEvent + */ + DEPRECATED(static mitk::MouseEvent AdaptMouseEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi)); + /** + \deprecatedSince{2013_03} This method can be replaced by mitk::AdaptMouseWheelEvent */ - static mitk::MouseEvent AdaptMouseEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi); - /** - * \deprecated{Please switch to the AdaptMouseWheelEvent function.} - */ - static mitk::WheelEvent AdaptWheelEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi); - /** - * \deprecated{Please switch to the AdaptInteractionKeyEvent function.} + DEPRECATED(static mitk::WheelEvent AdaptWheelEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi)); + /** + \deprecatedSince{2013_03} This method can be replaced by mitk::AdaptInteractionKeyEvent */ - static mitk::KeyEvent AdaptKeyEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi); + DEPRECATED(static mitk::KeyEvent AdaptKeyEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi)); /** New events compatible with the revised interaction scheme */ static mitk::MousePressEvent::Pointer AdaptMousePressEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi); static mitk::MouseMoveEvent::Pointer AdaptMouseMoveEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi); static mitk::MouseReleaseEvent::Pointer AdaptMouseReleaseEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi); static mitk::MouseWheelEvent::Pointer AdaptMouseWheelEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi); static mitk::InteractionKeyEvent::Pointer AdaptInteractionKeyEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi); /** * Vtk events do not provide a button state for MouseMove events, therefore this map is used to keep a record of the * button state, which then can be used to provide information for MITK MouseMove events. */ static std::map buttonStateMap; }; } #endif /*QMITKEVENTADAPTER_H_*/ diff --git a/Core/Code/Interactions/mitkWheelEvent.h b/Core/Code/Interactions/mitkWheelEvent.h index 79ca75c1d2..4425703d26 100644 --- a/Core/Code/Interactions/mitkWheelEvent.h +++ b/Core/Code/Interactions/mitkWheelEvent.h @@ -1,55 +1,60 @@ /*=================================================================== 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 WheelEvent_H_HEADER_INCLUDED_C184F366 #define WheelEvent_H_HEADER_INCLUDED_C184F366 #include #include "mitkDisplayPositionEvent.h" #include "mitkVector.h" namespace mitk { //##Documentation //## @brief Event that stores coordinates and rotation on mouse wheel events //## //## Stores display position of the mouse and 3D world position in mm. //## @ingroup Interaction + /** + * \deprecatedSince{2013_03} mitk::WheelEvent is deprecated. Use mitk::MouseWheelEvent instead. + * Refer to \see DataInteractionPage for general information about the concept of the new implementation. + */ + class MITK_CORE_EXPORT WheelEvent : public DisplayPositionEvent { public: //##Documentation //## @brief Constructor with all necessary arguments. //## //## @param sender: the widget, that caused that event, so that it can be asked for worldCoordinates. changed later to a focus //## @param type, button, buttonState, key: information from the Event //## @param displPosition: the 2D Position e.g. from the mouse //## @param worldPosition: the 3D position e.g. from a picking //## @param delta: the movement of the mousewheel WheelEvent(BaseRenderer* sender, int type, int button, int buttonState, int key, const Point2D& displPosition, int delta); int GetDelta() const; protected: int m_Delta; }; } // namespace mitk #endif /* WheelEvent_H_HEADER_INCLUDED_C184F366 */ diff --git a/Core/Code/Testing/Testing/Temporary/CTestCostData.txt b/Core/Code/Testing/Testing/Temporary/CTestCostData.txt deleted file mode 100644 index ed97d539c0..0000000000 --- a/Core/Code/Testing/Testing/Temporary/CTestCostData.txt +++ /dev/null @@ -1 +0,0 @@ ---- diff --git a/Core/Code/Testing/Testing/Temporary/LastTest.log b/Core/Code/Testing/Testing/Temporary/LastTest.log deleted file mode 100644 index 83c8c4ffeb..0000000000 --- a/Core/Code/Testing/Testing/Temporary/LastTest.log +++ /dev/null @@ -1,3 +0,0 @@ -Start testing: Nov 23 15:04 CET ----------------------------------------------------------- -End testing: Nov 23 15:04 CET