@ -1,6 +1,5 @@
# include <QFile>
# include <QJsonDocument>
# include <QJsonObject>
# include <QJsonArray>
# include <QMetaEnum>
# include <QFileInfo>
@ -40,51 +39,57 @@ void KeyMap::loadKeyMap(const QString &json)
QJsonParseError jsonError ;
QJsonDocument jsonDoc ;
QJsonObject rootObj ;
QPair < ActionType , int > switchKey ;
jsonDoc = QJsonDocument : : fromJson ( json . toUtf8 ( ) , & jsonError ) ;
if ( jsonError . error ! = QJsonParseError : : NoError )
{
if ( jsonError . error ! = QJsonParseError : : NoError ) {
errorString = QString ( " json error: %1 " ) . arg ( jsonError . errorString ( ) ) ;
goto parseError ;
}
// switchKey
rootObj = jsonDoc . object ( ) ;
if ( rootObj . contains ( " switchKey " ) & & rootObj . value ( " switchKey " ) . isString ( ) ) {
QPair < ActionType , int > p = getItemKey ( rootObj , " switchKey " ) ;
if ( p . first = = AT_INVALID ) {
errorString = QString ( " json error: switchKey invalid " ) ;
if ( ! checkItemString ( rootObj , " switchKey " ) ) {
errorString = QString ( " json error: no find switchKey " ) ;
goto parseError ;
}
m_switchType = p . first ;
m_switchKey = p . second ;
} else {
errorString = QString ( " json error: no find switchKey" ) ;
switchKey = getItemKey ( rootObj , " switchKey " ) ;
if ( switchKey . first = = AT_INVALID ) {
errorString = QString ( " json error: switchKey invalid " ) ;
goto parseError ;
}
m_switchKey . type = switchKey . first ;
m_switchKey . key = switchKey . second ;
// mouseMoveMap
if ( rootObj . contains ( " mouseMoveMap " ) & & rootObj . value ( " mouseMoveMap " ) . isObject ( ) ) {
QJsonObject mouseMoveMap = rootObj . value ( " mouseMoveMap " ) . toObject ( ) ;
if ( mouseMoveMap . contains ( " speedRatio " ) & & mouseMoveMap . value ( " speedRatio " ) . isDouble ( ) ) {
m_mouseMoveMap . speedRatio = mouseMoveMap . value ( " speedRatio " ) . toInt ( ) ;
} else {
if ( checkItemObject ( rootObj , " mouseMoveMap " ) ) {
QJsonObject mouseMoveMap = getItemObject ( rootObj , " mouseMoveMap " ) ;
KeyMapNode keyMapNode ;
keyMapNode . type = KMT_MOUSE_MOVE ;
if ( ! checkItemDouble ( mouseMoveMap , " speedRatio " ) ) {
errorString = QString ( " json error: mouseMoveMap on find speedRatio " ) ;
goto parseError ;
}
if ( mouseMoveMap . contains ( " startPos " ) & & mouseMoveMap . value ( " startPos " ) . isObject ( ) ) {
QJsonObject startPos = mouseMoveMap . value ( " startPos " ) . toObject ( ) ;
if ( startPos . contains ( " x " ) & & startPos . value ( " x " ) . isDouble ( ) ) {
m_mouseMoveMap . startPos . setX ( startPos . value ( " x " ) . toDouble ( ) ) ;
}
if ( startPos . contains ( " y " ) & & startPos . value ( " y " ) . isDouble ( ) ) {
m_mouseMoveMap . startPos . setY ( startPos . value ( " y " ) . toDouble ( ) ) ;
}
} else {
keyMapNode . data . mouseMove . speedRatio = static_cast < int > ( getItemDouble ( mouseMoveMap , " speedRatio " ) ) ;
if ( ! checkItemObject ( mouseMoveMap , " startPos " ) ) {
errorString = QString ( " json error: mouseMoveMap on find startPos " ) ;
goto parseError ;
}
QJsonObject startPos = mouseMoveMap . value ( " startPos " ) . toObject ( ) ;
if ( checkItemDouble ( startPos , " x " ) ) {
keyMapNode . data . mouseMove . startPos . setX ( getItemDouble ( startPos , " x " ) ) ;
}
if ( checkItemDouble ( startPos , " y " ) ) {
keyMapNode . data . mouseMove . startPos . setY ( getItemDouble ( startPos , " y " ) ) ;
}
m_idxMouseMove = m_keyMapNodes . size ( ) ;
m_keyMapNodes . push_back ( keyMapNode ) ;
}
// keyMapNodes
@ -103,7 +108,7 @@ void KeyMap::loadKeyMap(const QString &json)
goto parseError ;
}
KeyMap : : KeyMapType type = getItem Type( node , " type " ) ;
KeyMap : : KeyMapType type = getItem KeyMap Type( node , " type " ) ;
switch ( type ) {
case KeyMap : : KMT_CLICK :
{
@ -113,45 +118,45 @@ void KeyMap::loadKeyMap(const QString &json)
break ;
}
QPair < ActionType , int > key = getItemKey ( node , " key " ) ;
if ( key . first = = AT_INVALID ) {
if ( key . first = = AT_INVALID ) {
qWarning ( ) < < " json error: keyMapNodes node invalid key: " < < node . value ( " key " ) . toString ( ) ;
break ;
}
KeyMapNode keyMapNode ;
keyMapNode . type = type ;
keyMapNode . click. keyNode . type = key . first ;
keyMapNode . click. keyNode . key = key . second ;
keyMapNode . click. keyNode . pos = getItemPos ( node , " pos " ) ;
keyMapNode . click. switchMap = getItem SwitchMap ( node , " switchMap " ) ;
keyMapNode . data. click. keyNode . type = key . first ;
keyMapNode . data. click. keyNode . key = key . second ;
keyMapNode . data. click. keyNode . pos = getItemPos ( node , " pos " ) ;
keyMapNode . data. click. switchMap = getItem Bool ( node , " switchMap " ) ;
m_keyMapNodes . push_back ( keyMapNode ) ;
}
break ;
case KeyMap : : KMT_CLICK_TWICE :
{
// safe check
if ( ! checkForClick Doubl e( node ) ) {
if ( ! checkForClick Twic e( node ) ) {
qWarning ( ) < < " json error: keyMapNodes node format error " ;
break ;
}
QPair < ActionType , int > key = getItemKey ( node , " key " ) ;
if ( key . first = = AT_INVALID ) {
if ( key . first = = AT_INVALID ) {
qWarning ( ) < < " json error: keyMapNodes node invalid key: " < < node . value ( " key " ) . toString ( ) ;
break ;
}
KeyMapNode keyMapNode ;
keyMapNode . type = type ;
keyMapNode . click. keyNode . type = key . first ;
keyMapNode . click. keyNode . key = key . second ;
keyMapNode . click. keyNode . pos = getItemPos ( node , " pos " ) ;
keyMapNode . click. switchMap = getItem SwitchMap ( node , " switchMap " ) ;
keyMapNode . data. click. keyNode . type = key . first ;
keyMapNode . data. click. keyNode . key = key . second ;
keyMapNode . data. click. keyNode . pos = getItemPos ( node , " pos " ) ;
keyMapNode . data. click. switchMap = getItem Bool ( node , " switchMap " ) ;
m_keyMapNodes . push_back ( keyMapNode ) ;
}
break ;
case KeyMap : : KMT_STEER_WHEEL :
{
// safe check
if ( ! checkForSteerWhell ( node ) ) {
if ( ! checkForSteerWhell ( node ) ) {
qWarning ( ) < < " json error: keyMapNodes node format error " ;
break ;
}
@ -159,33 +164,40 @@ void KeyMap::loadKeyMap(const QString &json)
QPair < ActionType , int > rightKey = getItemKey ( node , " rightKey " ) ;
QPair < ActionType , int > upKey = getItemKey ( node , " upKey " ) ;
QPair < ActionType , int > downKey = getItemKey ( node , " downKey " ) ;
if ( leftKey . first = = AT_INVALID | | rightKey . first = = AT_INVALID
| | upKey . first = = AT_INVALID | | downKey . first = = AT_INVALID )
{
if ( leftKey . first = = AT_INVALID )
if ( leftKey . first = = AT_INVALID | | rightKey . first = = AT_INVALID
| | upKey . first = = AT_INVALID | | downKey . first = = AT_INVALID ) {
if ( leftKey . first = = AT_INVALID ) {
qWarning ( ) < < " json error: keyMapNodes node invalid key: " < < node . value ( " leftKey " ) . toString ( ) ;
if ( rightKey . first = = AT_INVALID )
}
if ( rightKey . first = = AT_INVALID ) {
qWarning ( ) < < " json error: keyMapNodes node invalid key: " < < node . value ( " rightKey " ) . toString ( ) ;
if ( upKey . first = = AT_INVALID )
}
if ( upKey . first = = AT_INVALID ) {
qWarning ( ) < < " json error: keyMapNodes node invalid key: " < < node . value ( " upKey " ) . toString ( ) ;
if ( downKey . first = = AT_INVALID )
}
if ( downKey . first = = AT_INVALID ) {
qWarning ( ) < < " json error: keyMapNodes node invalid key: " < < node . value ( " downKey " ) . toString ( ) ;
}
break ;
}
KeyMapNode keyMapNode ;
keyMapNode . type = type ;
keyMapNode . steerWheel . left = { leftKey . first , leftKey . second ,
getItemNumber ( node , " leftOffset " ) } ;
keyMapNode . steerWheel . right = { rightKey . first , rightKey . second ,
getItemNumber ( node , " rightOffset " ) } ;
keyMapNode . steerWheel . up = { upKey . first , upKey . second ,
getItemNumber ( node , " upOffset " ) } ;
keyMapNode . steerWheel . down = { downKey . first , downKey . second ,
getItemNumber ( node , " downOffset " ) } ;
keyMapNode . steerWheel . centerPos = getItemPos ( node , " centerPos " ) ;
keyMapNode . data . steerWheel . left = { leftKey . first , leftKey . second ,
QPointF ( 0 , 0 ) , QPointF ( 0 , 0 ) ,
getItemDouble ( node , " leftOffset " ) } ;
keyMapNode . data . steerWheel . right = { rightKey . first , rightKey . second ,
QPointF ( 0 , 0 ) , QPointF ( 0 , 0 ) ,
getItemDouble ( node , " rightOffset " ) } ;
keyMapNode . data . steerWheel . up = { upKey . first , upKey . second ,
QPointF ( 0 , 0 ) , QPointF ( 0 , 0 ) ,
getItemDouble ( node , " upOffset " ) } ;
keyMapNode . data . steerWheel . down = { downKey . first , downKey . second ,
QPointF ( 0 , 0 ) , QPointF ( 0 , 0 ) ,
getItemDouble ( node , " downOffset " ) } ;
keyMapNode . data . steerWheel . centerPos = getItemPos ( node , " centerPos " ) ;
m_idxSteerWheel = m_keyMapNodes . size ( ) ;
m_keyMapNodes . push_back ( keyMapNode ) ;
}
@ -193,22 +205,22 @@ void KeyMap::loadKeyMap(const QString &json)
case KeyMap : : KMT_DRAG :
{
// safe check
if ( ! checkForDrag ( node ) ) {
if ( ! checkForDrag ( node ) ) {
qWarning ( ) < < " json error: keyMapNodes node format error " ;
break ;
}
QPair < ActionType , int > key = getItemKey ( node , " key " ) ;
if ( key . first = = AT_INVALID ) {
if ( key . first = = AT_INVALID ) {
qWarning ( ) < < " json error: keyMapNodes node invalid key: " < < node . value ( " key " ) . toString ( ) ;
break ;
}
KeyMapNode keyMapNode ;
keyMapNode . type = type ;
keyMapNode . d rag. type = key . first ;
keyMapNode . d rag. key = key . second ;
keyMapNode . d rag. startP os = getItemPos ( node , " startPos " ) ;
keyMapNode . d rag. endPos = getItemPos ( node , " endPos " ) ;
keyMapNode . d ata. d rag. keyNode . type = key . first ;
keyMapNode . d ata. d rag. keyNode . key = key . second ;
keyMapNode . d ata. drag . keyNode . p os = getItemPos ( node , " startPos " ) ;
keyMapNode . d ata. d rag. keyNode. ext endPos = getItemPos ( node , " endPos " ) ;
m_keyMapNodes . push_back ( keyMapNode ) ;
break ;
}
@ -220,7 +232,7 @@ void KeyMap::loadKeyMap(const QString &json)
}
// this must be called after m_keyMapNodes is stable
makeReverseMap ( ) ;
q Warning ( ) < < " Script updated. " ;
q Info ( ) < < " Script updated. " ;
parseError :
if ( ! errorString . isEmpty ( ) ) {
@ -231,45 +243,41 @@ parseError:
const KeyMap : : KeyMapNode & KeyMap : : getKeyMapNode ( int key )
{
auto p = rmapKey . value ( key , & m_invalidNode ) ;
if ( p = = & m_invalidNode )
return * rmapMouse . value ( key , & m_invalidNode ) ;
auto p = m_rmapKey . value ( key , & m_invalidNode ) ;
if ( p = = & m_invalidNode ) {
return * m_rmapMouse . value ( key , & m_invalidNode ) ;
}
return * p ;
}
const KeyMap : : KeyMapNode & KeyMap : : getKeyMapNodeKey ( int key )
{
return * rmapKey. value ( key , & m_invalidNode ) ;
return * m_ rmapKey. value ( key , & m_invalidNode ) ;
}
const KeyMap : : KeyMapNode & KeyMap : : getKeyMapNodeMouse ( int key )
{
return * rmapMouse. value ( key , & m_invalidNode ) ;
return * m_ rmapMouse. value ( key , & m_invalidNode ) ;
}
bool KeyMap : : isSwitchOnKeyboard ( )
{
return m_switch T ype = = AT_KEY ;
return m_switch Key. t ype = = AT_KEY ;
}
int KeyMap : : getSwitchKey ( )
{
return m_switchKey ;
}
const KeyMap : : MouseMoveMap & KeyMap : : getMouseMoveMap ( )
{
return m_mouseMoveMap ;
return m_switchKey . key ;
}
const KeyMap : : KeyMapNode & KeyMap : : get SteerWheel Map( )
const KeyMap : : KeyMapNode & KeyMap : : getMouseMoveMap ( )
{
return m_keyMapNodes [ m_idx SteerWheel ] ;
return m_keyMapNodes [ m_idxMouseMove ] ;
}
bool KeyMap : : isValidMouseMoveMap ( )
{
return ! m_mouseMoveMap . startPos . isNull ( ) ;
return m_idxMouseMove ! = - 1 ;
}
bool KeyMap : : isValidSteerWheelMap ( )
@ -279,39 +287,39 @@ bool KeyMap::isValidSteerWheelMap()
void KeyMap : : makeReverseMap ( )
{
rmapKey. clear ( ) ;
rmapMouse. clear ( ) ;
for ( int i = 0 ; i < m_keyMapNodes . size ( ) ; + + i ) {
m_ rmapKey. clear ( ) ;
m_ rmapMouse. clear ( ) ;
for ( int i = 0 ; i < m_keyMapNodes . size ( ) ; + + i ) {
auto & node = m_keyMapNodes [ i ] ;
switch ( node . type ) {
case KMT_CLICK :
{
QMultiHash < int , KeyMapNode * > & m = node . click. keyNode . type = = AT_KEY ? rmapKey : rmapMouse;
m . insert ( node . click. keyNode . key , & node ) ;
QMultiHash < int , KeyMapNode * > & m = node . data. click. keyNode . type = = AT_KEY ? m_ rmapKey : m_ rmapMouse;
m . insert ( node . data. click. keyNode . key , & node ) ;
}
break ;
case KMT_CLICK_TWICE :
{
QMultiHash < int , KeyMapNode * > & m = node . clickTwice. keyNode . type = = AT_KEY ? rmapKey : rmapMouse;
m . insert ( node . clickTwice. keyNode . key , & node ) ;
QMultiHash < int , KeyMapNode * > & m = node . data. clickTwice. keyNode . type = = AT_KEY ? m_ rmapKey : m_ rmapMouse;
m . insert ( node . data. clickTwice. keyNode . key , & node ) ;
}
break ;
case KMT_STEER_WHEEL :
{
QMultiHash < int , KeyMapNode * > & ml = node . steerWheel. left . type = = AT_KEY ? rmapKey : rmapMouse;
ml . insert ( node . steerWheel. left . key , & node ) ;
QMultiHash < int , KeyMapNode * > & mr = node . steerWheel. right . type = = AT_KEY ? rmapKey : rmapMouse;
mr . insert ( node . steerWheel. right . key , & node ) ;
QMultiHash < int , KeyMapNode * > & mu = node . steerWheel. up . type = = AT_KEY ? rmapKey : rmapMouse;
mu . insert ( node . steerWheel. up . key , & node ) ;
QMultiHash < int , KeyMapNode * > & md = node . steerWheel. down . type = = AT_KEY ? rmapKey : rmapMouse;
md . insert ( node . steerWheel. down . key , & node ) ;
QMultiHash < int , KeyMapNode * > & ml = node . data. steerWheel. left . type = = AT_KEY ? m_ rmapKey : m_ rmapMouse;
ml . insert ( node . data. steerWheel. left . key , & node ) ;
QMultiHash < int , KeyMapNode * > & mr = node . data. steerWheel. right . type = = AT_KEY ? m_ rmapKey : m_ rmapMouse;
mr . insert ( node . data. steerWheel. right . key , & node ) ;
QMultiHash < int , KeyMapNode * > & mu = node . data. steerWheel. up . type = = AT_KEY ? m_ rmapKey : m_ rmapMouse;
mu . insert ( node . data. steerWheel. up . key , & node ) ;
QMultiHash < int , KeyMapNode * > & md = node . data. steerWheel. down . type = = AT_KEY ? m_ rmapKey : m_ rmapMouse;
md . insert ( node . data. steerWheel. down . key , & node ) ;
}
break ;
case KMT_DRAG :
{
QMultiHash < int , KeyMapNode * > & m = node . d rag. type = = AT_KEY ? rmapKey : rmapMouse;
m . insert ( node . d rag. key , & node ) ;
QMultiHash < int , KeyMapNode * > & m = node . d ata. d rag. keyNode. type = = AT_KEY ? m_ rmapKey : m_ rmapMouse;
m . insert ( node . d ata. d rag. keyNode . key , & node ) ;
}
break ;
default :
@ -320,87 +328,96 @@ void KeyMap::makeReverseMap()
}
}
// ---- check and get of json item ----
bool KeyMap : : checkItemKey ( const QJsonObject & node , const QString & name )
QString KeyMap : : getItemString ( const QJsonObject & node , const QString & name )
{
return node . contains( name ) & & node . value( name ) . is String( ) ;
return node . value ( name ) . toString ( ) ;
}
bool KeyMap : : checkItemPos ( const QJsonObject & node , const QString & name )
double KeyMap : : getItemDouble ( const QJsonObject & node , const QString & name )
{
if ( node . contains ( name ) & & node . value ( name ) . isObject ( ) ) {
QJsonObject pos = node . value ( name ) . toObject ( ) ;
return pos . contains ( " x " ) & & pos . value ( " x " ) . isDouble ( )
& & pos . contains ( " y " ) & & pos . value ( " y " ) . isDouble ( ) ;
}
return false ;
return node . value ( name ) . toDouble ( ) ;
}
bool KeyMap : : checkItemDouble ( const QJsonObject & node , const QString & name )
bool KeyMap : : getItemBool ( const QJsonObject & node , const QString & name )
{
return node . contains( name ) & & node . value( name ) . isDouble( ) ;
return node . value ( name ) . toBool ( false ) ;
}
bool KeyMap : : checkItemSwitchMap ( const QJsonObject & node , const QString & name )
QJsonObject KeyMap : : getItemObject ( const QJsonObject & node , const QString & name )
{
return ! node . contains ( name ) | | node . value ( name ) . isBool ( ) ;
return node . value ( name ) . toObject ( ) ;
}
KeyMap: : KeyMapType KeyMap : : getItemType ( const QJsonObject & node , const QString & name )
QPointF KeyMap : : getItemPos ( const QJsonObject & node , const QString & name )
{
Q String value = node . value ( name ) . toString ( ) ;
return static_cast < KeyMap : : KeyMapType > ( m_metaEnumKeyMapType . keyToValue ( value . toStdString ( ) . c_str ( ) ) ) ;
Q JsonObject pos = node . value ( name ) . toObject ( ) ;
return QPointF ( pos . value ( " x " ) . toDouble ( ) , pos . value ( " y " ) . toDouble ( ) ) ;
}
QPair < KeyMap : : ActionType , int > KeyMap : : getItemKey ( const QJsonObject & node , const QString & name )
{
QString value = node. value ( name ) . toString ( ) ;
QString value = getItemString( node , name ) ;
int key = m_metaEnumKey . keyToValue ( value . toStdString ( ) . c_str ( ) ) ;
int btn = m_metaEnumMouseButtons . keyToValue ( value . toStdString ( ) . c_str ( ) ) ;
if ( key = = - 1 & & btn = = - 1 ) {
if ( key = = - 1 & & btn = = - 1 ) {
return { AT_INVALID , - 1 } ;
} else if ( key ! = - 1 ) {
} else if ( key ! = - 1 ) {
return { AT_KEY , key } ;
} else {
} else {
return { AT_MOUSE , btn } ;
}
}
QPointF KeyMap : : getItemPos ( const QJsonObject & node , const QString & name )
KeyMap: : KeyMapType KeyMap : : getItemKeyMapType ( const QJsonObject & node , const QString & name )
{
Q JsonObject pos = node . value ( name ) . toObject ( ) ;
return QPointF ( pos . value ( " x " ) . toDouble ( ) , pos . value ( " y " ) . toDouble ( ) ) ;
Q String value = getItemString ( node , name ) ;
return static_cast < KeyMap : : KeyMapType > ( m_metaEnumKeyMapType . keyToValue ( value . toStdString ( ) . c_str ( ) ) ) ;
}
double KeyMap : : getItemNumber ( const QJsonObject & node , const QString & name )
bool KeyMap : : checkItemString ( const QJsonObject & node , const QString & name )
{
return node . value( name ) . toDouble ( ) ;
return node . contains( name ) & & node . value( name ) . isString ( ) ;
}
bool KeyMap : : getItemSwitchMap ( const QJsonObject & node , const QString & name )
bool KeyMap : : checkItemDouble ( const QJsonObject & node , const QString & name )
{
return node . value( name ) . toBool( false ) ;
return node . contains( name ) & & node . value( name ) . isDouble( ) ;
}
bool KeyMap : : checkItemBool ( const QJsonObject & node , const QString & name )
{
return node . contains ( name ) & & node . value ( name ) . isBool ( ) ;
}
bool KeyMap : : checkItemObject ( const QJsonObject & node , const QString & name )
{
return node . contains ( name ) & & node . value ( name ) . isObject ( ) ;
}
// ---- check for key-map node ----
bool KeyMap : : checkItemPos ( const QJsonObject & node , const QString & name )
{
if ( node . contains ( name ) & & node . value ( name ) . isObject ( ) ) {
QJsonObject pos = node . value ( name ) . toObject ( ) ;
return pos . contains ( " x " ) & & pos . value ( " x " ) . isDouble ( )
& & pos . contains ( " y " ) & & pos . value ( " y " ) . isDouble ( ) ;
}
return false ;
}
bool KeyMap : : checkForClick ( const QJsonObject & node )
{
return checkItemKey ( node , " key " ) & & checkItemPos ( node , " pos " )
& & checkItemSwitchMap ( node , " switchMap " ) ;
return checkForClickTwice ( node ) & & checkItemBool ( node , " switchMap " ) ;
}
bool KeyMap : : checkForClickDouble ( const QJsonObject & node )
bool KeyMap : : checkForClick Twic e( const QJsonObject & node )
{
return check ForClick( node ) ;
return check ItemString( node , " key " ) & & checkItemPos ( node , " pos " ) ;
}
bool KeyMap : : checkForSteerWhell ( const QJsonObject & node )
{
return checkItem Key ( node , " leftKey " ) & & checkItem Key ( node , " rightKey " )
& & checkItem Key ( node , " upKey " ) & & checkItem Key ( node , " downKey " )
return checkItem String ( node , " leftKey " ) & & checkItem String ( node , " rightKey " )
& & checkItem String ( node , " upKey " ) & & checkItem String ( node , " downKey " )
& & checkItemDouble ( node , " leftOffset " ) & & checkItemDouble ( node , " rightOffset " )
& & checkItemDouble ( node , " upOffset " ) & & checkItemDouble ( node , " downOffset " )
& & checkItemPos ( node , " centerPos " ) ;
@ -408,8 +425,7 @@ bool KeyMap::checkForSteerWhell(const QJsonObject& node)
bool KeyMap : : checkForDrag ( const QJsonObject & node )
{
return checkItemKey ( node , " key " )
& & checkItemPos ( node , " startPos " ) & & checkItemPos ( node , " endPos " )
& & checkItemSwitchMap ( node , " switchMap " ) ;
return checkItemString ( node , " key " )
& & checkItemPos ( node , " startPos " ) & & checkItemPos ( node , " endPos " ) ;
}