// statobjact.cpp -- static object actions // // Written by Frederic Bouvier, started May 2002. // // Copyright (C) 2002 Frederic Bouvier - fredb@users.sourceforge.net // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // // $Id: statobjact.cpp,v 1.9 2005/05/09 07:02:15 fredb Exp $ #ifdef _MSC_VER #pragma warning( disable : 4786 4503 ) #endif #include "statobjact.hpp" #include "mainwin.hpp" #include "sdutil.hpp" FGSD_ActionID FGSD_MoveStaticObjectAction::_id; FGSD_ActionID FGSD_ChangeStaticObjectAction::_id; FGSD_ActionID FGSD_AddRemoveStaticObjectAction::_id; FGSD_MoveStaticObjectAction::FGSD_MoveStaticObjectAction() : _lon( 0 ) , _lat( 0 ) , _elev( 0 ) , _hdg( 0 ) , _xdepl( 0 ) , _ydepl( 0 ) { } FGSD_MoveStaticObjectAction::FGSD_MoveStaticObjectAction( const char *__name, double __lon, double __lat, double __elev, double __hdg, double __xdepl, double __ydepl ) : _name( __name ) , _lon( __lon ) , _lat( __lat ) , _elev( __elev ) , _hdg( __hdg ) , _xdepl( __xdepl ) , _ydepl( __ydepl ) { size_t pos = _name.find_last_of( '/' ); if ( pos != std::string::npos ) { _path = std::string( _name, 0, pos ); _name.erase( 0, pos + 1 ); } } bool FGSD_MoveStaticObjectAction::undo() { double lon = _lon + _xdepl; double lat = _lat + _ydepl; return _mainWindow->moveStaticObject( _name.c_str(), lon, lat, _elev, _hdg, - _xdepl, - _ydepl ); } bool FGSD_MoveStaticObjectAction::redo( bool __step ) { bool ret = _mainWindow->moveStaticObject( _name.c_str(), _lon, _lat, _elev, _hdg, _xdepl, _ydepl ); if ( __step ) step( 1 ); return ret; } std::string FGSD_MoveStaticObjectAction::name() const { return "move"; } std::string FGSD_MoveStaticObjectAction::description() const { return "move a static object"; } bool FGSD_MoveStaticObjectAction::combine( FGSD_Action *__action ) { bool ret = false; FGSD_MoveStaticObjectAction *act = (FGSD_MoveStaticObjectAction *)__action->convertTo( FGSD_MoveStaticObjectAction::_id ); if ( act && act->_name == _name && act->_lon + act->_xdepl == _lon && act->_lat + act->_ydepl == _lat ) { act->_xdepl += _xdepl; act->_ydepl += _ydepl; ret = true; } return ret; } FGSD_ActionID FGSD_MoveStaticObjectAction::type() const { return _id; } void *FGSD_MoveStaticObjectAction::convertTo( FGSD_ActionID __id ) { return __id == _id ? (void *)this : 0; } FGSD_Action *FGSD_MoveStaticObjectAction::clone() const { return new FGSD_MoveStaticObjectAction( *this ); } bool FGSD_MoveStaticObjectAction::getPosition( bool undo, double &lon, double &lat ) const { lon = _lon; lat = _lat; if ( !undo ) { lon += _xdepl; lat += _ydepl; } return true; } bool FGSD_MoveStaticObjectAction::save( const char *__project, SGPropertyNode *__node ) { SGPropertyNode *node = __node->getChild( "family", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setStringValue( "static-object" ); node = __node->getChild( "name", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setStringValue( name().c_str() ); node = __node->getChild( "object", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setStringValue( _name.c_str() ); node = __node->getChild( "longitude", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setDoubleValue( _lon ); node = __node->getChild( "latitude", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setDoubleValue( _lat ); node = __node->getChild( "altitude", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setDoubleValue( _elev ); node = __node->getChild( "heading", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setDoubleValue( _hdg ); node = __node->getChild( "x-translation", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setDoubleValue( _xdepl ); node = __node->getChild( "y-translation", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setDoubleValue( _ydepl ); return true; } bool FGSD_MoveStaticObjectAction::load( const char *__project, SGPropertyNode *__node ) { bool ret = false; SGPropertyNode *node = __node->getChild( "object" ); if ( node ) { _name = node->getStringValue(); node = __node->getChild( "longitude", 0, true ); if ( node ) { _lon = node->getDoubleValue(); node = __node->getChild( "latitude", 0, true ); if ( node ) { _lat = node->getDoubleValue(); node = __node->getChild( "altitude", 0, true ); if ( node ) { _elev = node->getDoubleValue(); node = __node->getChild( "heading", 0, true ); if ( node ) { _hdg = node->getDoubleValue(); node = __node->getChild( "x-translation", 0, true ); if ( node ) { _xdepl = node->getDoubleValue(); node = __node->getChild( "y-translation", 0, true ); if ( node ) { _ydepl = node->getDoubleValue(); ret = true; } } } } } } } return ret; } //=========================================================================== FGSD_ChangeStaticObjectAction::FGSD_ChangeStaticObjectAction() : _lon( 0 ) , _lat( 0 ) , _elev( 0 ) , _hdg( 0 ) , _rot( 0 ) { } FGSD_ChangeStaticObjectAction::FGSD_ChangeStaticObjectAction( const char *__name, double __lon, double __lat, double __elev, double __hdg, double __rot ) : _name( __name ) , _lon( __lon ) , _lat( __lat ) , _elev( __elev ) , _hdg( __hdg ) , _rot( __rot ) { size_t pos = _name.find_last_of( '/' ); if ( pos != std::string::npos ) { _path = std::string( _name, 0, pos ); _name.erase( 0, pos + 1 ); } } FGSD_ChangeStaticObjectAction::~FGSD_ChangeStaticObjectAction() { } bool FGSD_ChangeStaticObjectAction::undo() { double hdg = _hdg + _rot; return _mainWindow->rotateStaticObject( _name.c_str(), _lon, _lat, _elev, hdg, - _rot ); } bool FGSD_ChangeStaticObjectAction::redo( bool __step ) { bool ret = _mainWindow->rotateStaticObject( _name.c_str(), _lon, _lat, _elev, _hdg, _rot ); if ( __step ) step( 1 ); return ret; } std::string FGSD_ChangeStaticObjectAction::name() const { return "rotate"; } std::string FGSD_ChangeStaticObjectAction::description() const { return "rotate a static object"; } bool FGSD_ChangeStaticObjectAction::combine( FGSD_Action *__action ) { bool ret = false; FGSD_ChangeStaticObjectAction *act = (FGSD_ChangeStaticObjectAction *)__action->convertTo( FGSD_ChangeStaticObjectAction::_id ); if ( act && act->_name == _name && act->_lon == _lon && act->_lat == _lat ) { act->_rot += _rot; ret = true; } return ret; } FGSD_ActionID FGSD_ChangeStaticObjectAction::type() const { return _id; } void *FGSD_ChangeStaticObjectAction::convertTo( FGSD_ActionID __id ) { return __id == _id ? (void *)this : 0; } FGSD_Action *FGSD_ChangeStaticObjectAction::clone() const { return new FGSD_ChangeStaticObjectAction( *this ); } bool FGSD_ChangeStaticObjectAction::getPosition( bool undo, double &lon, double &lat ) const { lon = _lon; lat = _lat; return true; } bool FGSD_ChangeStaticObjectAction::save( const char *__project, SGPropertyNode *__node ) { SGPropertyNode *node = __node->getChild( "family", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setStringValue( "static-object" ); node = __node->getChild( "name", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setStringValue( name().c_str() ); node = __node->getChild( "object", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setStringValue( _name.c_str() ); node = __node->getChild( "longitude", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setDoubleValue( _lon ); node = __node->getChild( "latitude", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setDoubleValue( _lat ); node = __node->getChild( "altitude", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setDoubleValue( _elev ); node = __node->getChild( "heading", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setDoubleValue( _hdg ); node = __node->getChild( "rotation", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setDoubleValue( _rot ); return true; } bool FGSD_ChangeStaticObjectAction::load( const char *__project, SGPropertyNode *__node ) { bool ret = false; SGPropertyNode *node = __node->getChild( "object" ); if ( node ) { _name = node->getStringValue(); node = __node->getChild( "longitude", 0, true ); if ( node ) { _lon = node->getDoubleValue(); node = __node->getChild( "latitude", 0, true ); if ( node ) { _lat = node->getDoubleValue(); node = __node->getChild( "altitude", 0, true ); if ( node ) { _elev = node->getDoubleValue(); node = __node->getChild( "heading", 0, true ); if ( node ) { _hdg = node->getDoubleValue(); node = __node->getChild( "rotation", 0, true ); if ( node ) { _rot = node->getDoubleValue(); ret = true; } } } } } } return ret; } //============================================================================== FGSD_AddRemoveStaticObjectAction::FGSD_AddRemoveStaticObjectAction( bool __add ) : _add( __add ) , _lon( 0 ) , _lat( 0 ) , _elev( 0 ) , _hdg( 0 ) { } FGSD_AddRemoveStaticObjectAction::FGSD_AddRemoveStaticObjectAction( bool __add, const char *__name, double __lon, double __lat, double __elev, double __hdg, std::vector __textures ) : _add( __add ) , _name( __name ) , _textures( __textures ) , _lon( __lon ) , _lat( __lat ) , _elev( __elev ) , _hdg( __hdg ) { size_t pos = _name.find_last_of( '/' ); if ( pos != std::string::npos ) { _path = std::string( _name, 0, pos ); _name.erase( 0, pos + 1 ); } } bool FGSD_AddRemoveStaticObjectAction::undo() { bool ret = false; if ( _add ) { ret = _mainWindow->removeStaticObject( _name.c_str(), _lon, _lat, _elev, _hdg ); } else { ret = _mainWindow->addStaticObject( _name.c_str(), _textures, _lon, _lat, _elev, _hdg ); } return ret; } bool FGSD_AddRemoveStaticObjectAction::redo( bool __step ) { bool ret = false; if ( _add ) { ret = _mainWindow->addStaticObject( _name.c_str(), _textures, _lon, _lat, _elev, _hdg ); } else { ret = _mainWindow->removeStaticObject( _name.c_str(), _lon, _lat, _elev, _hdg ); } if ( __step ) step( 1 ); return ret; } std::string FGSD_AddRemoveStaticObjectAction::name() const { return _add ? "add" : "remove"; } std::string FGSD_AddRemoveStaticObjectAction::description() const { return _add ? "add a static object" : "remove a static object"; } FGSD_ActionID FGSD_AddRemoveStaticObjectAction::type() const { return _id; } void *FGSD_AddRemoveStaticObjectAction::convertTo( FGSD_ActionID __id ) { return __id == _id ? (void *)this : 0; } FGSD_Action *FGSD_AddRemoveStaticObjectAction::clone() const { return new FGSD_AddRemoveStaticObjectAction( *this ); } bool FGSD_AddRemoveStaticObjectAction::getPosition( bool undo, double &lon, double &lat ) const { lon = _lon; lat = _lat; return true; } bool FGSD_AddRemoveStaticObjectAction::save( const char *__project, SGPropertyNode *__node ) { SGPropertyNode *node = __node->getChild( "family", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setStringValue( "static-object" ); node = __node->getChild( "name", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setStringValue( name().c_str() ); node = __node->getChild( "object", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setStringValue( _name.c_str() ); if ( _path.size() ) { bool rel; std::string path = FGSD_Util::buildRelativePath( __project, _path.c_str(), rel ); if ( rel ) node = __node->getChild( "path-rel", 0, true ); else node = __node->getChild( "path", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setStringValue( path.c_str() ); } size_t nb = _textures.size(); for ( size_t i = 0; i < nb; i++ ) { node = __node->getChild( "texture", i, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setStringValue( _textures[ i ].c_str() ); } node = __node->getChild( "longitude", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setDoubleValue( _lon ); node = __node->getChild( "latitude", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setDoubleValue( _lat ); node = __node->getChild( "altitude", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setDoubleValue( _elev ); node = __node->getChild( "heading", 0, true ); node->setAttributes( SGPropertyNode::READ | SGPropertyNode::WRITE | SGPropertyNode::ARCHIVE ); node->setDoubleValue( _hdg ); return true; } bool FGSD_AddRemoveStaticObjectAction::load( const char *__project, SGPropertyNode *__node ) { bool ret = false; SGPropertyNode *node = __node->getChild( "object" ); if ( node ) { _name = node->getStringValue(); bool rel = true; SGPropertyNode *node = __node->getChild( "path-rel" ); if ( !node ) { node = __node->getChild( "path" ); rel = false; } if ( node ) { _path = node->getStringValue(); if ( rel ) _path = FGSD_Util::buildAbsolutePath( __project, _path.c_str() ); } _textures.clear(); std::vector cTexture = __node->getChildren( "texture" ); size_t nb = cTexture.size(); for ( size_t i = 0; i < nb; i++ ) { _textures.push_back( cTexture[ i ]->getStringValue() ); } node = __node->getChild( "longitude", 0, true ); if ( node ) { _lon = node->getDoubleValue(); node = __node->getChild( "latitude", 0, true ); if ( node ) { _lat = node->getDoubleValue(); node = __node->getChild( "altitude", 0, true ); if ( node ) { _elev = node->getDoubleValue(); node = __node->getChild( "heading", 0, true ); if ( node ) { _hdg = node->getDoubleValue(); ret = true; } } } } } return ret; }