Beispiel #1
0
bool CGUIWindow::Load(TiXmlElement* pRootElement)
{
  if (!pRootElement)
    return false;
  
  if (strcmpi(pRootElement->Value(), "window"))
  {
    CLog::Log(LOGERROR, "file : XML file doesnt contain <window>");
    return false;
  }

  // we must create copy of root element as we will manipulate it when resolving includes
  // and we don't want original root element to change
  pRootElement = (TiXmlElement*)pRootElement->Clone();

  // set the scaling resolution so that any control creation or initialisation can
  // be done with respect to the correct aspect ratio
  g_graphicsContext.SetScalingResolution(m_coordsRes, m_needsScaling);

  // Resolve any includes that may be present and save conditions used to do it
  g_SkinInfo->ResolveIncludes(pRootElement, &m_xmlIncludeConditions);
  // now load in the skin file
  SetDefaults();

  CGUIControlFactory::GetInfoColor(pRootElement, "backgroundcolor", m_clearBackground, GetID());
  CGUIControlFactory::GetActions(pRootElement, "onload", m_loadActions);
  CGUIControlFactory::GetActions(pRootElement, "onunload", m_unloadActions);
  CGUIControlFactory::GetHitRect(pRootElement, m_hitRect);

  TiXmlElement *pChild = pRootElement->FirstChildElement();
  while (pChild)
  {
    std::string strValue = pChild->Value();
    if (strValue == "type" && pChild->FirstChild())
    {
      // if we have are a window type (ie not a dialog), and we have <type>dialog</type>
      // then make this window act like a dialog
      if (!IsDialog() && strcmpi(pChild->FirstChild()->Value(), "dialog") == 0)
        m_isDialog = true;
    }
    else if (strValue == "previouswindow" && pChild->FirstChild())
    {
      m_previousWindow = CButtonTranslator::TranslateWindow(pChild->FirstChild()->Value());
    }
    else if (strValue == "defaultcontrol" && pChild->FirstChild())
    {
      const char *always = pChild->Attribute("always");
      if (always && strcmpi(always, "true") == 0)
        m_defaultAlways = true;
      m_defaultControl = atoi(pChild->FirstChild()->Value());
    }
    else if(strValue == "menucontrol" && pChild->FirstChild())
    {
      m_menuControlID = atoi(pChild->FirstChild()->Value());
    }
    else if (strValue == "visible" && pChild->FirstChild())
    {
      std::string condition;
      CGUIControlFactory::GetConditionalVisibility(pRootElement, condition);
      m_visibleCondition = g_infoManager.Register(condition, GetID());
    }
    else if (strValue == "animation" && pChild->FirstChild())
    {
      CRect rect(0, 0, (float)m_coordsRes.iWidth, (float)m_coordsRes.iHeight);
      CAnimation anim;
      anim.Create(pChild, rect, GetID());
      m_animations.push_back(anim);
    }
    else if (strValue == "zorder" && pChild->FirstChild())
    {
      m_renderOrder = atoi(pChild->FirstChild()->Value());
    }
    else if (strValue == "coordinates")
    {
      XMLUtils::GetFloat(pChild, "posx", m_posX);
      XMLUtils::GetFloat(pChild, "posy", m_posY);
      XMLUtils::GetFloat(pChild, "left", m_posX);
      XMLUtils::GetFloat(pChild, "top", m_posY);

      TiXmlElement *originElement = pChild->FirstChildElement("origin");
      while (originElement)
      {
        COrigin origin;
        originElement->QueryFloatAttribute("x", &origin.x);
        originElement->QueryFloatAttribute("y", &origin.y);
        if (originElement->FirstChild())
          origin.condition = g_infoManager.Register(originElement->FirstChild()->Value(), GetID());
        m_origins.push_back(origin);
        originElement = originElement->NextSiblingElement("origin");
      }
    }
    else if (strValue == "camera")
    { // z is fixed
      pChild->QueryFloatAttribute("x", &m_camera.x);
      pChild->QueryFloatAttribute("y", &m_camera.y);
      m_hasCamera = true;
    }
    else if (strValue == "depth" && pChild->FirstChild())
    { 
      float stereo = (float)atof(pChild->FirstChild()->Value());;
      m_stereo = std::max(-1.f, std::min(1.f, stereo));
    }
    else if (strValue == "controls")
    {
      TiXmlElement *pControl = pChild->FirstChildElement();
      while (pControl)
      {
        if (strcmpi(pControl->Value(), "control") == 0)
        {
          LoadControl(pControl, NULL, CRect(0, 0, (float)m_coordsRes.iWidth, (float)m_coordsRes.iHeight));
        }
        pControl = pControl->NextSiblingElement();
      }
    }

    pChild = pChild->NextSiblingElement();
  }
  LoadAdditionalTags(pRootElement);

  m_windowLoaded = true;
  OnWindowLoaded();
  delete pRootElement;
  return true;
}
Beispiel #2
0
void CButtonTranslator::MapWindowActions(TiXmlNode *pWindow, int windowID)
{
  if (!pWindow || windowID == WINDOW_INVALID) 
    return;

  TiXmlNode* pDevice;

  const char* types[] = {"gamepad", "remote", "universalremote", "keyboard", "mouse", "appcommand", NULL};
  for (int i = 0; types[i]; ++i)
  {
    CStdString type(types[i]);
    if (HasDeviceType(pWindow, type))
    {
      pDevice = pWindow->FirstChild(type);
      TiXmlElement *pDeviceElement = pDevice->ToElement();
      CStdString deviceName;
      //check if exists, if not use "default"
      deviceName = pDeviceElement->Attribute("name");
      if (deviceName.empty())
        deviceName = "default";

      std::map<CStdString, std::map<int, buttonMap> >::iterator deviceMapIt = deviceMappings.find(deviceName);
      if (deviceMapIt == deviceMappings.end())
      {
        //First time encountering this device, lets initialise the buttonMap for it.
        deviceMapIt = deviceMappings.insert(pair<CStdString, std::map<int, buttonMap> >(deviceName, std::map<int, buttonMap>())).first;
      }
      
      std::map<int, buttonMap>::iterator windowIt = deviceMapIt->second.find(windowID);
      if (windowIt == deviceMapIt->second.end())
      {
        //add it now
        windowIt = deviceMapIt->second.insert(pair<int, buttonMap>(windowID, buttonMap())).first;
      }
      buttonMap& windowMap = windowIt->second;

      TiXmlElement *pButton = pDevice->FirstChildElement();

      while (pButton)
      {
        uint32_t buttonCode=0;
        if (type == "gamepad")
            buttonCode = TranslateGamepadString(pButton->Value());
        else if (type == "remote")
            buttonCode = TranslateRemoteString(pButton->Value());
        else if (type == "universalremote")
            buttonCode = TranslateUniversalRemoteString(pButton->Value());
        else if (type == "keyboard")
            buttonCode = TranslateKeyboardButton(pButton);
        else if (type == "mouse")
            buttonCode = TranslateMouseCommand(pButton->Value());
        else if (type == "appcommand")
            buttonCode = TranslateAppCommand(pButton->Value());

        if (buttonCode && pButton->FirstChild())
          MapAction(buttonCode, pButton->FirstChild()->Value(), windowMap);
        pButton = pButton->NextSiblingElement();
      }
    }
  }

#if defined(HAS_SDL_JOYSTICK) || defined(HAS_EVENT_SERVER)
  if ((pDevice = pWindow->FirstChild("joystick")) != NULL)
  {
    // map joystick actions
    while (pDevice)
    {
      MapJoystickActions(windowID, pDevice);
      pDevice = pDevice->NextSibling("joystick");
    }
  }
#endif
}
Beispiel #3
0
	void Map::ParseText(const string &text) 
	{
		// Create a tiny xml document and use it to parse the text.
		TiXmlDocument doc;
		doc.Parse(text.c_str());
	
		// Check for parsing errors.
		if (doc.Error()) 
		{
			has_error = true;
			error_code = TMX_PARSING_ERROR;
			error_text = doc.ErrorDesc();
			return;
		}

		TiXmlNode *mapNode = doc.FirstChild("map");
		TiXmlElement* mapElem = mapNode->ToElement();

		// Read the map attributes.
		mapElem->Attribute("version", &version);
		mapElem->Attribute("width", &width);
		mapElem->Attribute("height", &height);
		mapElem->Attribute("tilewidth", &tile_width);
		mapElem->Attribute("tileheight", &tile_height);

		// Read the orientation
		std::string orientationStr = mapElem->Attribute("orientation");

		if (!orientationStr.compare("orthogonal")) 
		{
			orientation = TMX_MO_ORTHOGONAL;
		} 
		else if (!orientationStr.compare("isometric")) 
		{
			orientation = TMX_MO_ISOMETRIC;
		}
		else if (!orientationStr.compare("staggered")) 
		{
			orientation = TMX_MO_STAGGERED;
		}
		

		const TiXmlNode *node = mapElem->FirstChild();
		int zOrder = 0;
		while( node )
		{
			// Read the map properties.
			if( strcmp( node->Value(), "properties" ) == 0 )
			{
				properties.Parse(node);			
			}

			// Iterate through all of the tileset elements.
			if( strcmp( node->Value(), "tileset" ) == 0 )
			{
				// Allocate a new tileset and parse it.
				Tileset *tileset = new Tileset();
				tileset->Parse(node->ToElement());

				// Add the tileset to the list.
				tilesets.push_back(tileset);
			}

			// Iterate through all of the layer elements.			
			if( strcmp( node->Value(), "layer" ) == 0 )
			{
				// Allocate a new layer and parse it.
				Layer *layer = new Layer(this);
				layer->Parse(node);
				layer->SetZOrder( zOrder );
				++zOrder;

				// Add the layer to the list.
				layers.push_back(layer);
			}

			// Iterate through all of the imagen layer elements.			
			if( strcmp( node->Value(), "imagelayer" ) == 0 )
			{
				// Allocate a new layer and parse it.
				ImageLayer *imageLayer = new ImageLayer(this);
				imageLayer->Parse(node);
				imageLayer->SetZOrder( zOrder );
				++zOrder;

				// Add the layer to the list.
				image_layers.push_back(imageLayer);
			}

			// Iterate through all of the objectgroup elements.
			if( strcmp( node->Value(), "objectgroup" ) == 0 )
			{
				// Allocate a new object group and parse it.
				ObjectGroup *objectGroup = new ObjectGroup();
				objectGroup->Parse(node);
				objectGroup->SetZOrder( zOrder );
				++zOrder;
		
				// Add the object group to the list.
				object_groups.push_back(objectGroup);
			}

			node = node->NextSibling();
		}
	}
Beispiel #4
0
void CExternalPlayer::GetCustomRegexpReplacers(TiXmlElement *pRootElement,
                                               std::vector<std::string>& settings)
{
  int iAction = 0; // overwrite
  // for backward compatibility
  const char* szAppend = pRootElement->Attribute("append");
  if ((szAppend && stricmp(szAppend, "yes") == 0))
    iAction = 1;
  // action takes precedence if both attributes exist
  const char* szAction = pRootElement->Attribute("action");
  if (szAction)
  {
    iAction = 0; // overwrite
    if (stricmp(szAction, "append") == 0)
      iAction = 1; // append
    else if (stricmp(szAction, "prepend") == 0)
      iAction = 2; // prepend
  }
  if (iAction == 0)
    settings.clear();

  TiXmlElement* pReplacer = pRootElement->FirstChildElement("replacer");
  int i = 0;
  while (pReplacer)
  {
    if (pReplacer->FirstChild())
    {
      const char* szGlobal = pReplacer->Attribute("global");
      const char* szStop = pReplacer->Attribute("stop");
      bool bGlobal = szGlobal && stricmp(szGlobal, "true") == 0;
      bool bStop = szStop && stricmp(szStop, "true") == 0;

      std::string strMatch;
      std::string strPat;
      std::string strRep;
      XMLUtils::GetString(pReplacer,"match",strMatch);
      XMLUtils::GetString(pReplacer,"pat",strPat);
      XMLUtils::GetString(pReplacer,"rep",strRep);

      if (!strPat.empty() && !strRep.empty())
      {
        CLog::Log(LOGDEBUG,"  Registering replacer:");
        CLog::Log(LOGDEBUG,"    Match:[%s] Pattern:[%s] Replacement:[%s]", strMatch.c_str(), strPat.c_str(), strRep.c_str());
        CLog::Log(LOGDEBUG,"    Global:[%s] Stop:[%s]", bGlobal?"true":"false", bStop?"true":"false");
        // keep literal commas since we use comma as a seperator
        StringUtils::Replace(strMatch, ",",",,");
        StringUtils::Replace(strPat, ",",",,");
        StringUtils::Replace(strRep, ",",",,");

        std::string strReplacer = strMatch + " , " + strPat + " , " + strRep + " , " + (bGlobal ? "g" : "") + (bStop ? "s" : "");
        if (iAction == 2)
          settings.insert(settings.begin() + i++, 1, strReplacer);
        else
          settings.push_back(strReplacer);
      }
      else
      {
        // error message about missing tag
        if (strPat.empty())
          CLog::Log(LOGERROR,"  Missing <Pat> tag");
        else
          CLog::Log(LOGERROR,"  Missing <Rep> tag");
      }
    }

    pReplacer = pReplacer->NextSiblingElement("replacer");
  }
}
Beispiel #5
0
int main()
{
    //
    // We start with the 'demoStart' todo list. Process it. And
    // should hopefully end up with the todo list as illustrated.
    //
    const char* demoStart =
        "<?xml version=\"1.0\"  standalone='no' >\n"
        "<!-- Our to do list data -->"
        "<ToDo>\n"
        "<!-- Do I need a secure PDA? -->\n"
        "<Item priority=\"1\" distance='close'> Go to the <bold>Toy store!</bold></Item>"
        "<Item priority=\"2\" distance='none'> Do bills   </Item>"
        "<Item priority=\"2\" distance='far &amp; back'> Look for Evil Dinosaurs! </Item>"
        "</ToDo>";

    {

    #ifdef TIXML_USE_STL
        /*  What the todo list should look like after processing.
            In stream (no formatting) representation. */
        const char* demoEnd =
            "<?xml version=\"1.0\" standalone=\"no\" ?>"
            "<!-- Our to do list data -->"
            "<ToDo>"
            "<!-- Do I need a secure PDA? -->"
            "<Item priority=\"2\" distance=\"close\">Go to the"
            "<bold>Toy store!"
            "</bold>"
            "</Item>"
            "<Item priority=\"1\" distance=\"far\">Talk to:"
            "<Meeting where=\"School\">"
            "<Attendee name=\"Marple\" position=\"teacher\" />"
            "<Attendee name=\"Voel\" position=\"counselor\" />"
            "</Meeting>"
            "<Meeting where=\"Lunch\" />"
            "</Item>"
            "<Item priority=\"2\" distance=\"here\">Do bills"
            "</Item>"
            "</ToDo>";
    #endif

        // The example parses from the character string (above):
        #if defined( WIN32 ) && defined( TUNE )
        _CrtMemCheckpoint( &startMemState );
        #endif

        {
            // Write to a file and read it back, to check file I/O.

            TiXmlDocument doc( "demotest.xml" );
            doc.Parse( demoStart );

            if ( doc.Error() )
            {
                printf( "Error in %s: %s\n", doc.Value(), doc.ErrorDesc() );
                exit( 1 );
            }
            doc.SaveFile();
        }

        TiXmlDocument doc( "demotest.xml" );
        bool loadOkay = doc.LoadFile();

        if ( !loadOkay )
        {
            printf( "Could not load test file 'demotest.xml'. Error='%s'. Exiting.\n", doc.ErrorDesc() );
            exit( 1 );
        }

        printf( "** Demo doc read from disk: ** \n\n" );
        printf( "** Printing via doc.Print **\n" );
        doc.Print( stdout );

        {
            printf( "** Printing via TiXmlPrinter **\n" );
            TiXmlPrinter printer;
            doc.Accept( &printer );
            fprintf( stdout, "%s", printer.CStr() );
        }
        #ifdef TIXML_USE_STL
        {
            printf( "** Printing via operator<< **\n" );
            std::cout << doc;
        }
        #endif
        TiXmlNode* node = 0;
        TiXmlElement* todoElement = 0;
        TiXmlElement* itemElement = 0;


        // --------------------------------------------------------
        // An example of changing existing attributes, and removing
        // an element from the document.
        // --------------------------------------------------------

        // Get the "ToDo" element.
        // It is a child of the document, and can be selected by name.
        node = doc.FirstChild( "ToDo" );
        assert( node );
        todoElement = node->ToElement();
        assert( todoElement  );

        // Going to the toy store is now our second priority...
        // So set the "priority" attribute of the first item in the list.
        node = todoElement->FirstChildElement();    // This skips the "PDA" comment.
        assert( node );
        itemElement = node->ToElement();
        assert( itemElement  );
        itemElement->SetAttribute( "priority", 2 );

        // Change the distance to "doing bills" from
        // "none" to "here". It's the next sibling element.
        itemElement = itemElement->NextSiblingElement();
        assert( itemElement );
        itemElement->SetAttribute( "distance", "here" );

        // Remove the "Look for Evil Dinosaurs!" item.
        // It is 1 more sibling away. We ask the parent to remove
        // a particular child.
        itemElement = itemElement->NextSiblingElement();
        todoElement->RemoveChild( itemElement );

        itemElement = 0;

        // --------------------------------------------------------
        // What follows is an example of created elements and text
        // nodes and adding them to the document.
        // --------------------------------------------------------

        // Add some meetings.
        TiXmlElement item( "Item" );
        item.SetAttribute( "priority", "1" );
        item.SetAttribute( "distance", "far" );

        TiXmlText text( "Talk to:" );

        TiXmlElement meeting1( "Meeting" );
        meeting1.SetAttribute( "where", "School" );

        TiXmlElement meeting2( "Meeting" );
        meeting2.SetAttribute( "where", "Lunch" );

        TiXmlElement attendee1( "Attendee" );
        attendee1.SetAttribute( "name", "Marple" );
        attendee1.SetAttribute( "position", "teacher" );

        TiXmlElement attendee2( "Attendee" );
        attendee2.SetAttribute( "name", "Voel" );
        attendee2.SetAttribute( "position", "counselor" );

        // Assemble the nodes we've created:
        meeting1.InsertEndChild( attendee1 );
        meeting1.InsertEndChild( attendee2 );

        item.InsertEndChild( text );
        item.InsertEndChild( meeting1 );
        item.InsertEndChild( meeting2 );

        // And add the node to the existing list after the first child.
        node = todoElement->FirstChild( "Item" );
        assert( node );
        itemElement = node->ToElement();
        assert( itemElement );

        todoElement->InsertAfterChild( itemElement, item );

        printf( "\n** Demo doc processed: ** \n\n" );
        doc.Print( stdout );


    #ifdef TIXML_USE_STL
        printf( "** Demo doc processed to stream: ** \n\n" );
        cout << doc << endl << endl;
    #endif

        // --------------------------------------------------------
        // Different tests...do we have what we expect?
        // --------------------------------------------------------

        int count = 0;
        TiXmlElement*   element;

        //////////////////////////////////////////////////////

    #ifdef TIXML_USE_STL
        cout << "** Basic structure. **\n";
        ostringstream outputStream( ostringstream::out );
        outputStream << doc;
        XmlTest( "Output stream correct.",  string( demoEnd ).c_str(),
                                            outputStream.str().c_str(), true );
    #endif

        node = doc.RootElement();
        assert( node );
        XmlTest( "Root element exists.", true, ( node != 0 && node->ToElement() ) );
        XmlTest ( "Root element value is 'ToDo'.", "ToDo",  node->Value());

        node = node->FirstChild();
        XmlTest( "First child exists & is a comment.", true, ( node != 0 && node->ToComment() ) );
        node = node->NextSibling();
        XmlTest( "Sibling element exists & is an element.", true, ( node != 0 && node->ToElement() ) );
        XmlTest ( "Value is 'Item'.", "Item", node->Value() );

        node = node->FirstChild();
        XmlTest ( "First child exists.", true, ( node != 0 && node->ToText() ) );
        XmlTest ( "Value is 'Go to the'.", "Go to the", node->Value() );


        //////////////////////////////////////////////////////
        printf ("\n** Iterators. **\n");

        // Walk all the top level nodes of the document.
        count = 0;
        for( node = doc.FirstChild();
             node;
             node = node->NextSibling() )
        {
            count++;
        }
        XmlTest( "Top level nodes, using First / Next.", 3, count );

        count = 0;
        for( node = doc.LastChild();
             node;
             node = node->PreviousSibling() )
        {
            count++;
        }
        XmlTest( "Top level nodes, using Last / Previous.", 3, count );

        // Walk all the top level nodes of the document,
        // using a different syntax.
        count = 0;
        for( node = doc.IterateChildren( 0 );
             node;
             node = doc.IterateChildren( node ) )
        {
            count++;
        }
        XmlTest( "Top level nodes, using IterateChildren.", 3, count );

        // Walk all the elements in a node.
        count = 0;
        for( element = todoElement->FirstChildElement();
             element;
             element = element->NextSiblingElement() )
        {
            count++;
        }
        XmlTest( "Children of the 'ToDo' element, using First / Next.",
            3, count );

        // Walk all the elements in a node by value.
        count = 0;
        for( node = todoElement->FirstChild( "Item" );
             node;
             node = node->NextSibling( "Item" ) )
        {
            count++;
        }
        XmlTest( "'Item' children of the 'ToDo' element, using First/Next.", 3, count );

        count = 0;
        for( node = todoElement->LastChild( "Item" );
             node;
             node = node->PreviousSibling( "Item" ) )
        {
            count++;
        }
        XmlTest( "'Item' children of the 'ToDo' element, using Last/Previous.", 3, count );

    #ifdef TIXML_USE_STL
        {
            cout << "\n** Parsing. **\n";
            istringstream parse0( "<Element0 attribute0='foo0' attribute1= noquotes attribute2 = '&gt;' />" );
            TiXmlElement element0( "default" );
            parse0 >> element0;

            XmlTest ( "Element parsed, value is 'Element0'.", "Element0", element0.Value() );
            XmlTest ( "Reads attribute 'attribute0=\"foo0\"'.", "foo0", element0.Attribute( "attribute0" ));
            XmlTest ( "Reads incorrectly formatted 'attribute1=noquotes'.", "noquotes", element0.Attribute( "attribute1" ) );
            XmlTest ( "Read attribute with entity value '>'.", ">", element0.Attribute( "attribute2" ) );
        }
    #endif

        {
            const char* error = "<?xml version=\"1.0\" standalone=\"no\" ?>\n"
                                "<passages count=\"006\" formatversion=\"20020620\">\n"
                                "    <wrong error>\n"
                                "</passages>";

            TiXmlDocument docTest;
            docTest.Parse( error );
            XmlTest( "Error row", docTest.ErrorRow(), 3 );
            XmlTest( "Error column", docTest.ErrorCol(), 17 );
            //printf( "error=%d id='%s' row %d col%d\n", (int) doc.Error(), doc.ErrorDesc(), doc.ErrorRow()+1, doc.ErrorCol() + 1 );

        }

    #ifdef TIXML_USE_STL
        {
            //////////////////////////////////////////////////////
            cout << "\n** Streaming. **\n";

            // Round trip check: stream in, then stream back out to verify. The stream
            // out has already been checked, above. We use the output

            istringstream inputStringStream( outputStream.str() );
            TiXmlDocument document0;

            inputStringStream >> document0;

            ostringstream outputStream0( ostringstream::out );
            outputStream0 << document0;

            XmlTest( "Stream round trip correct.",  string( demoEnd ).c_str(),
                                                    outputStream0.str().c_str(), true );

            std::string str;
            str << document0;

            XmlTest( "String printing correct.", string( demoEnd ).c_str(),
                                                 str.c_str(), true );
        }
    #endif
    }

    {
        const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />";

        TiXmlDocument doc;
        doc.Parse( str );

        TiXmlElement* ele = doc.FirstChildElement();

        int iVal, result;
        double dVal;

        result = ele->QueryDoubleAttribute( "attr0", &dVal );
        XmlTest( "Query attribute: int as double", result, TIXML_SUCCESS );
        XmlTest( "Query attribute: int as double", (int)dVal, 1 );
        result = ele->QueryDoubleAttribute( "attr1", &dVal );
        XmlTest( "Query attribute: double as double", (int)dVal, 2 );
        result = ele->QueryIntAttribute( "attr1", &iVal );
        XmlTest( "Query attribute: double as int", result, TIXML_SUCCESS );
        XmlTest( "Query attribute: double as int", iVal, 2 );
        result = ele->QueryIntAttribute( "attr2", &iVal );
        XmlTest( "Query attribute: not a number", result, TIXML_WRONG_TYPE );
        result = ele->QueryIntAttribute( "bar", &iVal );
        XmlTest( "Query attribute: does not exist", result, TIXML_NO_ATTRIBUTE );
    }

    {
        const char* str =   "\t<?xml version=\"1.0\" standalone=\"no\" ?>\t<room doors='2'>\n"
                            "</room>";

        TiXmlDocument doc;
        doc.SetTabSize( 8 );
        doc.Parse( str );

        TiXmlHandle docHandle( &doc );
        TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" );

        assert( docHandle.Node() );
        assert( roomHandle.Element() );

        TiXmlElement* room = roomHandle.Element();
        assert( room );
        TiXmlAttribute* doors = room->FirstAttribute();
        assert( doors );

        XmlTest( "Location tracking: Tab 8: room row", room->Row(), 1 );
        XmlTest( "Location tracking: Tab 8: room col", room->Column(), 49 );
        XmlTest( "Location tracking: Tab 8: doors row", doors->Row(), 1 );
        XmlTest( "Location tracking: Tab 8: doors col", doors->Column(), 55 );
    }

    {
        const char* str =   "\t<?xml version=\"1.0\" standalone=\"no\" ?>\t<room doors='2'>\n"
                            "  <!-- Silly example -->\n"
                            "    <door wall='north'>A great door!</door>\n"
                            "\t<door wall='east'/>"
                            "</room>";

        TiXmlDocument doc;
        doc.Parse( str );

        TiXmlHandle docHandle( &doc );
        TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" );
        TiXmlHandle commentHandle = docHandle.FirstChildElement( "room" ).FirstChild();
        TiXmlHandle textHandle = docHandle.FirstChildElement( "room" ).ChildElement( "door", 0 ).FirstChild();
        TiXmlHandle door0Handle = docHandle.FirstChildElement( "room" ).ChildElement( 0 );
        TiXmlHandle door1Handle = docHandle.FirstChildElement( "room" ).ChildElement( 1 );

        assert( docHandle.Node() );
        assert( roomHandle.Element() );
        assert( commentHandle.Node() );
        assert( textHandle.Text() );
        assert( door0Handle.Element() );
        assert( door1Handle.Element() );

        TiXmlDeclaration* declaration = doc.FirstChild()->ToDeclaration();
        assert( declaration );
        TiXmlElement* room = roomHandle.Element();
        assert( room );
        TiXmlAttribute* doors = room->FirstAttribute();
        assert( doors );
        TiXmlText* text = textHandle.Text();
        TiXmlComment* comment = commentHandle.Node()->ToComment();
        assert( comment );
        TiXmlElement* door0 = door0Handle.Element();
        TiXmlElement* door1 = door1Handle.Element();

        XmlTest( "Location tracking: Declaration row", declaration->Row(), 1 );
        XmlTest( "Location tracking: Declaration col", declaration->Column(), 5 );
        XmlTest( "Location tracking: room row", room->Row(), 1 );
        XmlTest( "Location tracking: room col", room->Column(), 45 );
        XmlTest( "Location tracking: doors row", doors->Row(), 1 );
        XmlTest( "Location tracking: doors col", doors->Column(), 51 );
        XmlTest( "Location tracking: Comment row", comment->Row(), 2 );
        XmlTest( "Location tracking: Comment col", comment->Column(), 3 );
        XmlTest( "Location tracking: text row", text->Row(), 3 );
        XmlTest( "Location tracking: text col", text->Column(), 24 );
        XmlTest( "Location tracking: door0 row", door0->Row(), 3 );
        XmlTest( "Location tracking: door0 col", door0->Column(), 5 );
        XmlTest( "Location tracking: door1 row", door1->Row(), 4 );
        XmlTest( "Location tracking: door1 col", door1->Column(), 5 );
    }


    // --------------------------------------------------------
    // UTF-8 testing. It is important to test:
    //  1. Making sure name, value, and text read correctly
    //  2. Row, Col functionality
    //  3. Correct output
    // --------------------------------------------------------
    printf ("\n** UTF-8 **\n");
    {
        TiXmlDocument doc( "utf8test.xml" );
        doc.LoadFile();
        if ( doc.Error() && doc.ErrorId() == TiXmlBase::TIXML_ERROR_OPENING_FILE ) {
            printf( "WARNING: File 'utf8test.xml' not found.\n"
                    "(Are you running the test from the wrong directory?)\n"
                    "Could not test UTF-8 functionality.\n" );
        }
        else
        {
            TiXmlHandle docH( &doc );
            // Get the attribute "value" from the "Russian" element and check it.
            TiXmlElement* element = docH.FirstChildElement( "document" ).FirstChildElement( "Russian" ).Element();
            const unsigned char correctValue[] = {  0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU,
                                                    0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 };

            XmlTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ), true );
            XmlTest( "UTF-8: Russian value row.", 4, element->Row() );
            XmlTest( "UTF-8: Russian value column.", 5, element->Column() );

            const unsigned char russianElementName[] = {    0xd0U, 0xa0U, 0xd1U, 0x83U,
                                                            0xd1U, 0x81U, 0xd1U, 0x81U,
                                                            0xd0U, 0xbaU, 0xd0U, 0xb8U,
                                                            0xd0U, 0xb9U, 0 };
            const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>";

            TiXmlText* text = docH.FirstChildElement( "document" ).FirstChildElement( (const char*) russianElementName ).Child( 0 ).Text();
            XmlTest( "UTF-8: Browsing russian element name.",
                     russianText,
                     text->Value(),
                     true );
            XmlTest( "UTF-8: Russian element name row.", 7, text->Row() );
            XmlTest( "UTF-8: Russian element name column.", 47, text->Column() );

            TiXmlDeclaration* dec = docH.Child( 0 ).Node()->ToDeclaration();
            XmlTest( "UTF-8: Declaration column.", 1, dec->Column() );
            XmlTest( "UTF-8: Document column.", 1, doc.Column() );

            // Now try for a round trip.
            doc.SaveFile( "utf8testout.xml" );

            // Check the round trip.
            char savedBuf[256];
            char verifyBuf[256];
            int okay = 1;

            FILE* saved  = fopen( "utf8testout.xml", "r" );
            FILE* verify = fopen( "utf8testverify.xml", "r" );
            if ( saved && verify )
            {
                while ( fgets( verifyBuf, 256, verify ) )
                {
                    fgets( savedBuf, 256, saved );
                    if ( strcmp( verifyBuf, savedBuf ) )
                    {
                        okay = 0;
                        break;
                    }
                }
                fclose( saved );
                fclose( verify );
            }
            XmlTest( "UTF-8: Verified multi-language round trip.", 1, okay );

            // On most Western machines, this is an element that contains
            // the word "resume" with the correct accents, in a latin encoding.
            // It will be something else completely on non-wester machines,
            // which is why TinyXml is switching to UTF-8.
            const char latin[] = "<element>r\x82sum\x82</element>";

            TiXmlDocument latinDoc;
            latinDoc.Parse( latin, 0, TIXML_ENCODING_LEGACY );

            text = latinDoc.FirstChildElement()->FirstChild()->ToText();
            XmlTest( "Legacy encoding: Verify text element.", "r\x82sum\x82", text->Value() );
        }
    }

    //////////////////////
    // Copy and assignment
    //////////////////////
    printf ("\n** Copy and Assignment **\n");
    {
        TiXmlElement element( "foo" );
        element.Parse( "<element name='value' />", 0, TIXML_ENCODING_UNKNOWN );

        TiXmlElement elementCopy( element );
        TiXmlElement elementAssign( "foo" );
        elementAssign.Parse( "<incorrect foo='bar'/>", 0, TIXML_ENCODING_UNKNOWN );
        elementAssign = element;

        XmlTest( "Copy/Assign: element copy #1.", "element", elementCopy.Value() );
        XmlTest( "Copy/Assign: element copy #2.", "value", elementCopy.Attribute( "name" ) );
        XmlTest( "Copy/Assign: element assign #1.", "element", elementAssign.Value() );
        XmlTest( "Copy/Assign: element assign #2.", "value", elementAssign.Attribute( "name" ) );
        XmlTest( "Copy/Assign: element assign #3.", true, ( 0 == elementAssign.Attribute( "foo" )) );

        TiXmlComment comment;
        comment.Parse( "<!--comment-->", 0, TIXML_ENCODING_UNKNOWN );
        TiXmlComment commentCopy( comment );
        TiXmlComment commentAssign;
        commentAssign = commentCopy;
        XmlTest( "Copy/Assign: comment copy.", "comment", commentCopy.Value() );
        XmlTest( "Copy/Assign: comment assign.", "comment", commentAssign.Value() );

        TiXmlUnknown unknown;
        unknown.Parse( "<[unknown]>", 0, TIXML_ENCODING_UNKNOWN );
        TiXmlUnknown unknownCopy( unknown );
        TiXmlUnknown unknownAssign;
        unknownAssign.Parse( "incorrect", 0, TIXML_ENCODING_UNKNOWN );
        unknownAssign = unknownCopy;
        XmlTest( "Copy/Assign: unknown copy.", "[unknown]", unknownCopy.Value() );
        XmlTest( "Copy/Assign: unknown assign.", "[unknown]", unknownAssign.Value() );

        TiXmlText text( "TextNode" );
        TiXmlText textCopy( text );
        TiXmlText textAssign( "incorrect" );
        textAssign = text;
        XmlTest( "Copy/Assign: text copy.", "TextNode", textCopy.Value() );
        XmlTest( "Copy/Assign: text assign.", "TextNode", textAssign.Value() );

        TiXmlDeclaration dec;
        dec.Parse( "<?xml version='1.0' encoding='UTF-8'?>", 0, TIXML_ENCODING_UNKNOWN );
        TiXmlDeclaration decCopy( dec );
        TiXmlDeclaration decAssign;
        decAssign = dec;

        XmlTest( "Copy/Assign: declaration copy.", "UTF-8", decCopy.Encoding() );
        XmlTest( "Copy/Assign: text assign.", "UTF-8", decAssign.Encoding() );

        TiXmlDocument doc;
        elementCopy.InsertEndChild( textCopy );
        doc.InsertEndChild( decAssign );
        doc.InsertEndChild( elementCopy );
        doc.InsertEndChild( unknownAssign );

        TiXmlDocument docCopy( doc );
        TiXmlDocument docAssign;
        docAssign = docCopy;

        #ifdef TIXML_USE_STL
        std::string original, copy, assign;
        original << doc;
        copy << docCopy;
        assign << docAssign;
        XmlTest( "Copy/Assign: document copy.", original.c_str(), copy.c_str(), true );
        XmlTest( "Copy/Assign: document assign.", original.c_str(), assign.c_str(), true );

        #endif
    }

    //////////////////////////////////////////////////////
#ifdef TIXML_USE_STL
    printf ("\n** Parsing, no Condense Whitespace **\n");
    TiXmlBase::SetCondenseWhiteSpace( false );
    {
        istringstream parse1( "<start>This  is    \ntext</start>" );
        TiXmlElement text1( "text" );
        parse1 >> text1;

        XmlTest ( "Condense white space OFF.", "This  is    \ntext",
                    text1.FirstChild()->Value(),
                    true );
    }
    TiXmlBase::SetCondenseWhiteSpace( true );
#endif

    //////////////////////////////////////////////////////
    // GetText();
    {
        const char* str = "<foo>This is text</foo>";
        TiXmlDocument doc;
        doc.Parse( str );
        const TiXmlElement* element = doc.RootElement();

        XmlTest( "GetText() normal use.", "This is text", element->GetText() );

        str = "<foo><b>This is text</b></foo>";
        doc.Clear();
        doc.Parse( str );
        element = doc.RootElement();

        XmlTest( "GetText() contained element.", element->GetText() == 0, true );

        str = "<foo>This is <b>text</b></foo>";
        doc.Clear();
        TiXmlBase::SetCondenseWhiteSpace( false );
        doc.Parse( str );
        TiXmlBase::SetCondenseWhiteSpace( true );
        element = doc.RootElement();

        XmlTest( "GetText() partial.", "This is ", element->GetText() );
    }


    //////////////////////////////////////////////////////
    // CDATA
    {
        const char* str =   "<xmlElement>"
                                "<![CDATA["
                                    "I am > the rules!\n"
                                    "...since I make symbolic puns"
                                "]]>"
                            "</xmlElement>";
        TiXmlDocument doc;
        doc.Parse( str );
        doc.Print();

        XmlTest( "CDATA parse.", doc.FirstChildElement()->FirstChild()->Value(),
                                 "I am > the rules!\n...since I make symbolic puns",
                                 true );

        #ifdef TIXML_USE_STL
        //cout << doc << '\n';

        doc.Clear();

        istringstream parse0( str );
        parse0 >> doc;
        //cout << doc << '\n';

        XmlTest( "CDATA stream.", doc.FirstChildElement()->FirstChild()->Value(),
                                 "I am > the rules!\n...since I make symbolic puns",
                                 true );
        #endif

        TiXmlDocument doc1 = doc;
        //doc.Print();

        XmlTest( "CDATA copy.", doc1.FirstChildElement()->FirstChild()->Value(),
                                 "I am > the rules!\n...since I make symbolic puns",
                                 true );
    }
    {
        // [ 1482728 ] Wrong wide char parsing
        char buf[256];
        buf[255] = 0;
        for( int i=0; i<255; ++i ) {
            buf[i] = (char)((i>=32) ? i : 32);
        }
        TIXML_STRING str( "<xmlElement><![CDATA[" );
        str += buf;
        str += "]]></xmlElement>";

        TiXmlDocument doc;
        doc.Parse( str.c_str() );

        TiXmlPrinter printer;
        printer.SetStreamPrinting();
        doc.Accept( &printer );

        XmlTest( "CDATA with all bytes #1.", str.c_str(), printer.CStr(), true );

        #ifdef TIXML_USE_STL
        doc.Clear();
        istringstream iss( printer.Str() );
        iss >> doc;
        std::string out;
        out << doc;
        XmlTest( "CDATA with all bytes #2.", out.c_str(), printer.CStr(), true );
        #endif
    }
    {
        // [ 1480107 ] Bug-fix for STL-streaming of CDATA that contains tags
        // CDATA streaming had a couple of bugs, that this tests for.
        const char* str =   "<xmlElement>"
                                "<![CDATA["
                                    "<b>I am > the rules!</b>\n"
                                    "...since I make symbolic puns"
                                "]]>"
                            "</xmlElement>";
        TiXmlDocument doc;
        doc.Parse( str );
        doc.Print();

        XmlTest( "CDATA parse. [ 1480107 ]", doc.FirstChildElement()->FirstChild()->Value(),
                                 "<b>I am > the rules!</b>\n...since I make symbolic puns",
                                 true );

        #ifdef TIXML_USE_STL

        doc.Clear();

        istringstream parse0( str );
        parse0 >> doc;

        XmlTest( "CDATA stream. [ 1480107 ]", doc.FirstChildElement()->FirstChild()->Value(),
                                 "<b>I am > the rules!</b>\n...since I make symbolic puns",
                                 true );
        #endif

        TiXmlDocument doc1 = doc;
        //doc.Print();

        XmlTest( "CDATA copy. [ 1480107 ]", doc1.FirstChildElement()->FirstChild()->Value(),
                                 "<b>I am > the rules!</b>\n...since I make symbolic puns",
                                 true );
    }
    //////////////////////////////////////////////////////
    // Visit()



    //////////////////////////////////////////////////////
    printf( "\n** Fuzzing... **\n" );

    const int FUZZ_ITERATION = 300;

    // The only goal is not to crash on bad input.
    int len = (int) strlen( demoStart );
    for( int i=0; i<FUZZ_ITERATION; ++i )
    {
        char* demoCopy = new char[ len+1 ];
        strcpy( demoCopy, demoStart );

        demoCopy[ i%len ] = (char)((i+1)*3);
        demoCopy[ (i*7)%len ] = '>';
        demoCopy[ (i*11)%len ] = '<';

        TiXmlDocument xml;
        xml.Parse( demoCopy );

        delete [] demoCopy;
    }
    printf( "** Fuzzing Complete. **\n" );

    //////////////////////////////////////////////////////
    printf ("\n** Bug regression tests **\n");

    // InsertBeforeChild and InsertAfterChild causes crash.
    {
        TiXmlElement parent( "Parent" );
        TiXmlElement childText0( "childText0" );
        TiXmlElement childText1( "childText1" );
        TiXmlNode* childNode0 = parent.InsertEndChild( childText0 );
        TiXmlNode* childNode1 = parent.InsertBeforeChild( childNode0, childText1 );

        XmlTest( "Test InsertBeforeChild on empty node.", ( childNode1 == parent.FirstChild() ), true );
    }

    {
        // InsertBeforeChild and InsertAfterChild causes crash.
        TiXmlElement parent( "Parent" );
        TiXmlElement childText0( "childText0" );
        TiXmlElement childText1( "childText1" );
        TiXmlNode* childNode0 = parent.InsertEndChild( childText0 );
        TiXmlNode* childNode1 = parent.InsertAfterChild( childNode0, childText1 );

        XmlTest( "Test InsertAfterChild on empty node. ", ( childNode1 == parent.LastChild() ), true );
    }

    // Reports of missing constructors, irregular string problems.
    {
        // Missing constructor implementation. No test -- just compiles.
        TiXmlText text( "Missing" );

        #ifdef TIXML_USE_STL
            // Missing implementation:
            TiXmlDocument doc;
            string name = "missing";
            doc.LoadFile( name );

            TiXmlText textSTL( name );
        #else
            // verifying some basic string functions:
            TiXmlString a;
            TiXmlString b( "Hello" );
            TiXmlString c( "ooga" );

            c = " World!";
            a = b;
            a += c;
            a = a;

            XmlTest( "Basic TiXmlString test. ", "Hello World!", a.c_str() );
        #endif
    }

    // Long filenames crashing STL version
    {
        TiXmlDocument doc( "midsummerNightsDreamWithAVeryLongFilenameToConfuseTheStringHandlingRoutines.xml" );
        bool loadOkay = doc.LoadFile();
        loadOkay = true;    // get rid of compiler warning.
        // Won't pass on non-dev systems. Just a "no crash" check.
        //XmlTest( "Long filename. ", true, loadOkay );
    }

    {
        // Entities not being written correctly.
        // From Lynn Allen

        const char* passages =
            "<?xml version=\"1.0\" standalone=\"no\" ?>"
            "<passages count=\"006\" formatversion=\"20020620\">"
                "<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
                " It also has &lt;, &gt;, and &amp;, as well as a fake copyright &#xA9;.\"> </psg>"
            "</passages>";

        TiXmlDocument doc( "passages.xml" );
        doc.Parse( passages );
        TiXmlElement* psg = doc.RootElement()->FirstChildElement();
        const char* context = psg->Attribute( "context" );
        const char* expected = "Line 5 has \"quotation marks\" and 'apostrophe marks'. It also has <, >, and &, as well as a fake copyright \xC2\xA9.";

        XmlTest( "Entity transformation: read. ", expected, context, true );

        FILE* textfile = fopen( "textfile.txt", "w" );
        if ( textfile )
        {
            psg->Print( textfile, 0 );
            fclose( textfile );
        }
        textfile = fopen( "textfile.txt", "r" );
        assert( textfile );
        if ( textfile )
        {
            char buf[ 1024 ];
            fgets( buf, 1024, textfile );
            XmlTest( "Entity transformation: write. ",
                     "<psg context=\'Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
                     " It also has &lt;, &gt;, and &amp;, as well as a fake copyright \xC2\xA9.' />",
                     buf,
                     true );
        }
        fclose( textfile );
    }

    {
        FILE* textfile = fopen( "test5.xml", "w" );
        if ( textfile )
        {
            fputs("<?xml version='1.0'?><a.elem xmi.version='2.0'/>", textfile);
            fclose(textfile);

            TiXmlDocument doc;
            doc.LoadFile( "test5.xml" );
            XmlTest( "dot in element attributes and names", doc.Error(), 0);
        }
    }

    {
        FILE* textfile = fopen( "test6.xml", "w" );
        if ( textfile )
        {
            fputs("<element><Name>1.1 Start easy ignore fin thickness&#xA;</Name></element>", textfile );
            fclose(textfile);

            TiXmlDocument doc;
            bool result = doc.LoadFile( "test6.xml" );
            XmlTest( "Entity with one digit.", result, true );

            TiXmlText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText();
            XmlTest( "Entity with one digit.",
                        text->Value(), "1.1 Start easy ignore fin thickness\n" );
        }
    }

    {
        // DOCTYPE not preserved (950171)
        //
        const char* doctype =
            "<?xml version=\"1.0\" ?>"
            "<!DOCTYPE PLAY SYSTEM 'play.dtd'>"
            "<!ELEMENT title (#PCDATA)>"
            "<!ELEMENT books (title,authors)>"
            "<element />";

        TiXmlDocument doc;
        doc.Parse( doctype );
        doc.SaveFile( "test7.xml" );
        doc.Clear();
        doc.LoadFile( "test7.xml" );

        TiXmlHandle docH( &doc );
        TiXmlUnknown* unknown = docH.Child( 1 ).Unknown();
        XmlTest( "Correct value of unknown.", "!DOCTYPE PLAY SYSTEM 'play.dtd'", unknown->Value() );
        #ifdef TIXML_USE_STL
        TiXmlNode* node = docH.Child( 2 ).Node();
        std::string str;
        str << (*node);
        XmlTest( "Correct streaming of unknown.", "<!ELEMENT title (#PCDATA)>", str.c_str() );
        #endif
    }

    {
        // [ 791411 ] Formatting bug
        // Comments do not stream out correctly.
        const char* doctype =
            "<!-- Somewhat<evil> -->";
        TiXmlDocument doc;
        doc.Parse( doctype );

        TiXmlHandle docH( &doc );
        TiXmlComment* comment = docH.Child( 0 ).Node()->ToComment();

        XmlTest( "Comment formatting.", " Somewhat<evil> ", comment->Value() );
        #ifdef TIXML_USE_STL
        std::string str;
        str << (*comment);
        XmlTest( "Comment streaming.", "<!-- Somewhat<evil> -->", str.c_str() );
        #endif
    }

    {
        // [ 870502 ] White space issues
        TiXmlDocument doc;
        TiXmlText* text;
        TiXmlHandle docH( &doc );

        const char* doctype0 = "<element> This has leading and trailing space </element>";
        const char* doctype1 = "<element>This has  internal space</element>";
        const char* doctype2 = "<element> This has leading, trailing, and  internal space </element>";

        TiXmlBase::SetCondenseWhiteSpace( false );
        doc.Clear();
        doc.Parse( doctype0 );
        text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
        XmlTest( "White space kept.", " This has leading and trailing space ", text->Value() );

        doc.Clear();
        doc.Parse( doctype1 );
        text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
        XmlTest( "White space kept.", "This has  internal space", text->Value() );

        doc.Clear();
        doc.Parse( doctype2 );
        text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
        XmlTest( "White space kept.", " This has leading, trailing, and  internal space ", text->Value() );

        TiXmlBase::SetCondenseWhiteSpace( true );
        doc.Clear();
        doc.Parse( doctype0 );
        text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
        XmlTest( "White space condensed.", "This has leading and trailing space", text->Value() );

        doc.Clear();
        doc.Parse( doctype1 );
        text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
        XmlTest( "White space condensed.", "This has internal space", text->Value() );

        doc.Clear();
        doc.Parse( doctype2 );
        text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
        XmlTest( "White space condensed.", "This has leading, trailing, and internal space", text->Value() );
    }

    {
        // Double attributes
        const char* doctype = "<element attr='red' attr='blue' />";

        TiXmlDocument doc;
        doc.Parse( doctype );

        XmlTest( "Parsing repeated attributes.", 0, (int)doc.Error() ); // not an  error to tinyxml
        XmlTest( "Parsing repeated attributes.", "blue", doc.FirstChildElement( "element" )->Attribute( "attr" ) );
    }

    {
        // Embedded null in stream.
        const char* doctype = "<element att\0r='red' attr='blue' />";

        TiXmlDocument doc;
        doc.Parse( doctype );
        XmlTest( "Embedded null throws error.", true, doc.Error() );

        #ifdef TIXML_USE_STL
        istringstream strm( doctype );
        doc.Clear();
        doc.ClearError();
        strm >> doc;
        XmlTest( "Embedded null throws error.", true, doc.Error() );
        #endif
    }

    {
            // Legacy mode test. (This test may only pass on a western system)
            const char* str =
                        "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"
                        "<?>"
                        "C?nt?nt???????"
                        "</?>";

            TiXmlDocument doc;
            doc.Parse( str );

            TiXmlHandle docHandle( &doc );
            TiXmlHandle aHandle = docHandle.FirstChildElement( "?" );
            TiXmlHandle tHandle = aHandle.Child( 0 );
            assert( aHandle.Element() );
            assert( tHandle.Text() );
            XmlTest( "ISO-8859-1 Parsing.", "C?nt?nt???????", tHandle.Text()->Value() );
    }

    {
        // Empty documents should return TIXML_ERROR_PARSING_EMPTY, bug 1070717
        const char* str = "    ";
        TiXmlDocument doc;
        doc.Parse( str );
        XmlTest( "Empty document error TIXML_ERROR_DOCUMENT_EMPTY", TiXmlBase::TIXML_ERROR_DOCUMENT_EMPTY, doc.ErrorId() );
    }
    #ifndef TIXML_USE_STL
    {
        // String equality. [ 1006409 ] string operator==/!= no worky in all cases
        TiXmlString temp;
        XmlTest( "Empty tinyxml string compare equal", ( temp == "" ), true );

        TiXmlString    foo;
        TiXmlString    bar( "" );
        XmlTest( "Empty tinyxml string compare equal", ( foo == bar ), true );
    }

    #endif
    {
        // Bug [ 1195696 ] from marlonism
        TiXmlBase::SetCondenseWhiteSpace(false);
        TiXmlDocument xml;
        xml.Parse("<text><break/>This hangs</text>");
        XmlTest( "Test safe error return.", xml.Error(), false );
    }

    {
        // Bug [ 1243992 ] - another infinite loop
        TiXmlDocument doc;
        doc.SetCondenseWhiteSpace(false);
        doc.Parse("<p><pb></pb>test</p>");
    }
    {
        // Low entities
        TiXmlDocument xml;
        xml.Parse( "<test>&#x0e;</test>" );
        const char result[] = { 0x0e, 0 };
        XmlTest( "Low entities.", xml.FirstChildElement()->GetText(), result );
        xml.Print();
    }
    {
        // Bug [ 1451649 ] Attribute values with trailing quotes not handled correctly
        TiXmlDocument xml;
        xml.Parse( "<foo attribute=bar\" />" );
        XmlTest( "Throw error with bad end quotes.", xml.Error(), true );
    }
    #ifdef TIXML_USE_STL
    {
        // Bug [ 1449463 ] Consider generic query
        TiXmlDocument xml;
        xml.Parse( "<foo bar='3' barStr='a string'/>" );

        TiXmlElement* ele = xml.FirstChildElement();
        double d;
        int i;
        float f;
        bool b;
        //std::string str;

        XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &d ), TIXML_SUCCESS );
        XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &i ), TIXML_SUCCESS );
        XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &f ), TIXML_SUCCESS );
        XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &b ), TIXML_WRONG_TYPE );
        XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "nobar", &b ), TIXML_NO_ATTRIBUTE );
        //XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "barStr", &str ), TIXML_SUCCESS );

        XmlTest( "QueryValueAttribute", (d==3.0), true );
        XmlTest( "QueryValueAttribute", (i==3), true );
        XmlTest( "QueryValueAttribute", (f==3.0f), true );
        //XmlTest( "QueryValueAttribute", (str==std::string( "a string" )), true );
    }
    #endif

    #ifdef TIXML_USE_STL
    {
        // [ 1505267 ] redundant malloc in TiXmlElement::Attribute
        TiXmlDocument xml;
        xml.Parse( "<foo bar='3' />" );
        TiXmlElement* ele = xml.FirstChildElement();
        double d;
        int i;

        std::string bar = "bar";

        const std::string* atrrib = ele->Attribute( bar );
        ele->Attribute( bar, &d );
        ele->Attribute( bar, &i );

        XmlTest( "Attribute", atrrib->empty(), false );
        XmlTest( "Attribute", (d==3.0), true );
        XmlTest( "Attribute", (i==3), true );
    }
    #endif

    {
        // [ 1356059 ] Allow TiXMLDocument to only be at the top level
        TiXmlDocument xml, xml2;
        xml.InsertEndChild( xml2 );
        XmlTest( "Document only at top level.", xml.Error(), true );
        XmlTest( "Document only at top level.", xml.ErrorId(), TiXmlBase::TIXML_ERROR_DOCUMENT_TOP_ONLY );
    }

    {
        // [ 1663758 ] Failure to report error on bad XML
        TiXmlDocument xml;
        xml.Parse("<x>");
        XmlTest("Missing end tag at end of input", xml.Error(), true);
        xml.Parse("<x> ");
        XmlTest("Missing end tag with trailing whitespace", xml.Error(), true);
    }

    {
        // [ 1635701 ] fail to parse files with a tag separated into two lines
        // I'm not sure this is a bug. Marked 'pending' for feedback.
        TiXmlDocument xml;
        xml.Parse( "<title><p>text</p\n><title>" );
        //xml.Print();
        //XmlTest( "Tag split by newline", xml.Error(), false );
    }

    #ifdef TIXML_USE_STL
    {
        // [ 1475201 ] TinyXML parses entities in comments
        TiXmlDocument xml;
        istringstream parse1( "<!-- declarations for <head> & <body> -->"
                              "<!-- far &amp; away -->" );
        parse1 >> xml;

        TiXmlNode* e0 = xml.FirstChild();
        TiXmlNode* e1 = e0->NextSibling();
        TiXmlComment* c0 = e0->ToComment();
        TiXmlComment* c1 = e1->ToComment();

        XmlTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true );
        XmlTest( "Comments ignore entities.", " far &amp; away ", c1->Value(), true );
    }
    #endif

    {
        // [ 1475201 ] TinyXML parses entities in comments
        TiXmlDocument xml;
        xml.Parse("<!-- declarations for <head> & <body> -->"
                  "<!-- far &amp; away -->" );

        TiXmlNode* e0 = xml.FirstChild();
        TiXmlNode* e1 = e0->NextSibling();
        TiXmlComment* c0 = e0->ToComment();
        TiXmlComment* c1 = e1->ToComment();

        XmlTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true );
        XmlTest( "Comments ignore entities.", " far &amp; away ", c1->Value(), true );
    }
    /*
    {
        TiXmlDocument xml;
        xml.Parse( "<tag>/</tag>" );
        xml.Print();
        xml.FirstChild()->Print( stdout, 0 );
        xml.FirstChild()->Type();
    }
    */

    /*  1417717 experiment
    {
        TiXmlDocument xml;
        xml.Parse("<text>Dan & Tracie</text>");
        xml.Print(stdout);
    }
    {
        TiXmlDocument xml;
        xml.Parse("<text>Dan &foo; Tracie</text>");
        xml.Print(stdout);
    }
    */
    #if defined( WIN32 ) && defined( TUNE )
    _CrtMemCheckpoint( &endMemState );
    //_CrtMemDumpStatistics( &endMemState );

    _CrtMemState diffMemState;
    _CrtMemDifference( &diffMemState, &startMemState, &endMemState );
    _CrtMemDumpStatistics( &diffMemState );
    #endif

    printf ("\nPass %d, Fail %d\n", gPass, gFail);
    return gFail;
}
Beispiel #6
0
// \brief Load the config file (sounds.xml) for nav sounds
// Can be located in a folder "sounds" in the skin or from a
// subfolder of the folder "sounds" in the root directory of
// xbmc
bool CGUIAudioManager::Load()
{
  CSingleLock lock(m_cs);

  UnLoad();

  if (CSettings::Get().GetString("lookandfeel.soundskin")=="OFF")
    return true;
  else
    Enable(true);

  std::string soundSkin = CSettings::Get().GetString("lookandfeel.soundskin");

  if (soundSkin == "SKINDEFAULT")
  {
    m_strMediaDir = URIUtils::AddFileToFolder(g_SkinInfo->Path(), "sounds");
  }
  else
  {
    //check if sound skin is located in home, otherwise fallback to built-ins
    m_strMediaDir = URIUtils::AddFileToFolder("special://home/sounds", soundSkin);
    if (!XFILE::CDirectory::Exists(m_strMediaDir))
      m_strMediaDir = URIUtils::AddFileToFolder("special://xbmc/sounds", soundSkin);
  }

  std::string strSoundsXml = URIUtils::AddFileToFolder(m_strMediaDir, "sounds.xml");

  //  Load our xml file
  CXBMCTinyXML xmlDoc;

  CLog::Log(LOGINFO, "Loading %s", strSoundsXml.c_str());

  //  Load the config file
  if (!xmlDoc.LoadFile(strSoundsXml))
  {
    CLog::Log(LOGNOTICE, "%s, Line %d\n%s", strSoundsXml.c_str(), xmlDoc.ErrorRow(), xmlDoc.ErrorDesc());
    return false;
  }

  TiXmlElement* pRoot = xmlDoc.RootElement();
  std::string strValue = pRoot->Value();
  if ( strValue != "sounds")
  {
    CLog::Log(LOGNOTICE, "%s Doesn't contain <sounds>", strSoundsXml.c_str());
    return false;
  }

  //  Load sounds for actions
  TiXmlElement* pActions = pRoot->FirstChildElement("actions");
  if (pActions)
  {
    TiXmlNode* pAction = pActions->FirstChild("action");

    while (pAction)
    {
      TiXmlNode* pIdNode = pAction->FirstChild("name");
      int id = 0;    // action identity
      if (pIdNode && pIdNode->FirstChild())
      {
        CButtonTranslator::TranslateActionString(pIdNode->FirstChild()->Value(), id);
      }

      TiXmlNode* pFileNode = pAction->FirstChild("file");
      std::string strFile;
      if (pFileNode && pFileNode->FirstChild())
        strFile += pFileNode->FirstChild()->Value();

      if (id > 0 && !strFile.empty())
      {
        std::string filename = URIUtils::AddFileToFolder(m_strMediaDir, strFile);
        IAESound *sound = LoadSound(filename);
        if (sound)
          m_actionSoundMap.insert(pair<int, IAESound *>(id, sound));
      }

      pAction = pAction->NextSibling();
    }
  }

  //  Load window specific sounds
  TiXmlElement* pWindows = pRoot->FirstChildElement("windows");
  if (pWindows)
  {
    TiXmlNode* pWindow = pWindows->FirstChild("window");

    while (pWindow)
    {
      int id = 0;

      TiXmlNode* pIdNode = pWindow->FirstChild("name");
      if (pIdNode)
      {
        if (pIdNode->FirstChild())
          id = CButtonTranslator::TranslateWindow(pIdNode->FirstChild()->Value());
      }

      CWindowSounds sounds;
      sounds.initSound   = LoadWindowSound(pWindow, "activate"  );
      sounds.deInitSound = LoadWindowSound(pWindow, "deactivate");

      if (id > 0)
        m_windowSoundMap.insert(pair<int, CWindowSounds>(id, sounds));

      pWindow = pWindow->NextSibling();
    }
  }

  return true;
}
Beispiel #7
0
CGUIControl* CGUIControlFactory::Create(int parentID, const CRect &rect, TiXmlElement* pControlNode, bool insideContainer)
{
  // get the control type
  CStdString strType = GetType(pControlNode);
  CGUIControl::GUICONTROLTYPES type = TranslateControlType(strType);

  int id = 0;
  float posX = 0, posY = 0;
  float width = 0, height = 0;
  float minWidth = 0;

  int left = 0, right = 0, up = 0, down = 0, next = 0, prev = 0;
  vector<CGUIActionDescriptor> leftActions, rightActions, upActions, downActions, nextActions, prevActions;

  int pageControl = 0;
  CGUIInfoColor colorDiffuse(0xFFFFFFFF);
  int defaultControl = 0;
  bool  defaultAlways = false;
  CStdString strTmp;
  int singleInfo = 0;
  CStdString strLabel;
  int iUrlSet=0;
  int iToggleSelect;

  float spinWidth = 16;
  float spinHeight = 16;
  float spinPosX = 0, spinPosY = 0;
  float checkWidth = 0, checkHeight = 0;
  CStdString strSubType;
  int iType = SPIN_CONTROL_TYPE_TEXT;
  int iMin = 0;
  int iMax = 100;
  int iInterval = 1;
  float fMin = 0.0f;
  float fMax = 1.0f;
  float fInterval = 0.1f;
  bool bReverse = true;
  bool bReveal = false;
  CTextureInfo textureBackground, textureLeft, textureRight, textureMid, textureOverlay;
  CTextureInfo textureNib, textureNibFocus, textureBar, textureBarFocus;
  CTextureInfo textureLeftFocus, textureRightFocus;
  CTextureInfo textureUp, textureDown;
  CTextureInfo textureUpFocus, textureDownFocus;
  CTextureInfo texture, borderTexture;
  CGUIInfoLabel textureFile;
  CTextureInfo textureCheckMark, textureCheckMarkNF;
  CTextureInfo textureFocus, textureNoFocus;
  CTextureInfo textureAltFocus, textureAltNoFocus;
  CTextureInfo textureRadioOn, textureRadioOff;
  CTextureInfo imageNoFocus, imageFocus;
  CGUIInfoLabel texturePath;
  CRect borderSize;

  float sliderWidth = 150, sliderHeight = 16;
  CPoint offset;

  bool bHasPath = false;
  vector<CGUIActionDescriptor> clickActions;
  vector<CGUIActionDescriptor> altclickActions;
  vector<CGUIActionDescriptor> focusActions;
  vector<CGUIActionDescriptor> unfocusActions;
  vector<CGUIActionDescriptor> textChangeActions;
  CStdString strTitle = "";
  CStdString strRSSTags = "";

  int iNumSlots = 7;
  float buttonGap = 5;
  int iDefaultSlot = 2;
  int iMovementRange = 0;
  bool bHorizontal = false;
  int iAlpha = 0;
  bool bWrapAround = true;
  bool bSmoothScrolling = true;
  CAspectRatio aspect;
#ifdef PRE_SKIN_VERSION_9_10_COMPATIBILITY
  if (insideContainer)  // default for inside containers is keep
    aspect.ratio = CAspectRatio::AR_KEEP;
#endif

  int iVisibleCondition = 0;
  CGUIInfoBool allowHiddenFocus(false);
  int enableCondition = 0;

  vector<CAnimation> animations;

  bool bScrollLabel = false;
  bool bPulse = true;
  unsigned int timePerImage = 0;
  unsigned int fadeTime = 0;
  unsigned int timeToPauseAtEnd = 0;
  bool randomized = false;
  bool loop = true;
  bool wrapMultiLine = false;
  ORIENTATION orientation = VERTICAL;
  bool showOnePage = true;
  bool scrollOut = true;
  int preloadItems = 0;

  CLabelInfo labelInfo;
  CLabelInfo spinInfo;

  CGUIInfoColor textColor3;
  CGUIInfoColor headlineColor;

  float radioWidth = 0;
  float radioHeight = 0;
  float radioPosX = 0;
  float radioPosY = 0;

  CStdString altLabel;
  CStdString strLabel2;
  CStdString action;

  int focusPosition = 0;
  int scrollTime = 200;
  int timeBlocks = 36;
  int rulerUnit = 12;
  bool useControlCoords = false;
  bool renderFocusedLast = false;

  CRect hitRect;
  CPoint camera;
  bool   hasCamera = false;
  bool resetOnLabelChange = true;
  bool bPassword = false;

  /////////////////////////////////////////////////////////////////////////////
  // Read control properties from XML
  //

  if (!pControlNode->Attribute("id", (int*) &id))
    XMLUtils::GetInt(pControlNode, "id", (int&) id);       // backward compatibility - not desired
  // TODO: Perhaps we should check here whether id is valid for focusable controls
  // such as buttons etc.  For labels/fadelabels/images it does not matter

  XMLUtils::GetFloat(pControlNode, "posx", posX);
  XMLUtils::GetFloat(pControlNode, "posy", posY);
  // Convert these from relative coords
  CStdString pos;
  XMLUtils::GetString(pControlNode, "posx", pos);
  if (pos.Right(1) == "r")
    posX = rect.Width() - posX;
  XMLUtils::GetString(pControlNode, "posy", pos);
  if (pos.Right(1) == "r")
    posY = rect.Height() - posY;

  GetDimension(pControlNode, "width", width, minWidth);
  XMLUtils::GetFloat(pControlNode, "height", height);
  XMLUtils::GetFloat(pControlNode, "offsetx", offset.x);
  XMLUtils::GetFloat(pControlNode, "offsety", offset.y);

  // adjust width and height accordingly for groups.  Groups should
  // take the width/height of the parent (adjusted for positioning)
  // if none is defined.
  if (type == CGUIControl::GUICONTROL_GROUP || type == CGUIControl::GUICONTROL_GROUPLIST)
  {
    if (!width)
      width = max(rect.x2 - posX, 0.0f);
    if (!height)
      height = max(rect.y2 - posY, 0.0f);
  }

  hitRect.SetRect(posX, posY, posX + width, posY + height);
  GetHitRect(pControlNode, hitRect);

  if (!GetNavigation(pControlNode, "onup", up, upActions)) up = id - 1;
  if (!GetNavigation(pControlNode, "ondown", down, downActions)) down = id + 1;
  if (!GetNavigation(pControlNode, "onleft", left, leftActions)) left = id;
  if (!GetNavigation(pControlNode, "onright", right, rightActions)) right = id;
  if (!GetNavigation(pControlNode, "onnext", next, nextActions)) next = id;
  if (!GetNavigation(pControlNode, "onprev", prev, prevActions)) prev = id;

  if (XMLUtils::GetInt(pControlNode, "defaultcontrol", defaultControl))
  {
    const char *always = pControlNode->FirstChildElement("defaultcontrol")->Attribute("always");
    if (always && strnicmp(always, "true", 4) == 0)
      defaultAlways = true;
  }
  XMLUtils::GetInt(pControlNode, "pagecontrol", pageControl);

  GetInfoColor(pControlNode, "colordiffuse", colorDiffuse);

  GetConditionalVisibility(pControlNode, iVisibleCondition, allowHiddenFocus);
  GetCondition(pControlNode, "enable", enableCondition);

  CRect animRect(posX, posY, posX + width, posY + height);
  GetAnimations(pControlNode, animRect, animations);

  GetInfoColor(pControlNode, "textcolor", labelInfo.textColor);
  GetInfoColor(pControlNode, "focusedcolor", labelInfo.focusedColor);
  GetInfoColor(pControlNode, "disabledcolor", labelInfo.disabledColor);
  GetInfoColor(pControlNode, "shadowcolor", labelInfo.shadowColor);
  GetInfoColor(pControlNode, "selectedcolor", labelInfo.selectedColor);
  XMLUtils::GetFloat(pControlNode, "textoffsetx", labelInfo.offsetX);
  XMLUtils::GetFloat(pControlNode, "textoffsety", labelInfo.offsetY);
  int angle = 0;  // use the negative angle to compensate for our vertically flipped cartesian plane
  if (XMLUtils::GetInt(pControlNode, "angle", angle)) labelInfo.angle = (float)-angle;
  CStdString strFont;
  if (XMLUtils::GetString(pControlNode, "font", strFont))
    labelInfo.font = g_fontManager.GetFont(strFont);
  GetAlignment(pControlNode, "align", labelInfo.align);
  uint32_t alignY = 0;
  if (GetAlignmentY(pControlNode, "aligny", alignY))
    labelInfo.align |= alignY;
  if (XMLUtils::GetFloat(pControlNode, "textwidth", labelInfo.width))
    labelInfo.align |= XBFONT_TRUNCATED;

  GetMultipleString(pControlNode, "onclick", clickActions);
  GetMultipleString(pControlNode, "ontextchange", textChangeActions);
  GetMultipleString(pControlNode, "onfocus", focusActions);
  GetMultipleString(pControlNode, "onunfocus", unfocusActions);
  GetMultipleString(pControlNode, "altclick", altclickActions);

  CStdString infoString;
  if (XMLUtils::GetString(pControlNode, "info", infoString))
    singleInfo = g_infoManager.TranslateString(infoString);

  GetTexture(pControlNode, "texturefocus", textureFocus);
  GetTexture(pControlNode, "texturenofocus", textureNoFocus);
  GetTexture(pControlNode, "alttexturefocus", textureAltFocus);
  GetTexture(pControlNode, "alttexturenofocus", textureAltNoFocus);
  CStdString strToggleSelect;
  XMLUtils::GetString(pControlNode, "usealttexture", strToggleSelect);
  XMLUtils::GetString(pControlNode, "selected", strToggleSelect);
  iToggleSelect = g_infoManager.TranslateString(strToggleSelect);

  XMLUtils::GetBoolean(pControlNode, "haspath", bHasPath);

  GetTexture(pControlNode, "textureup", textureUp);
  GetTexture(pControlNode, "texturedown", textureDown);
  GetTexture(pControlNode, "textureupfocus", textureUpFocus);
  GetTexture(pControlNode, "texturedownfocus", textureDownFocus);

  GetTexture(pControlNode, "textureleft", textureLeft);
  GetTexture(pControlNode, "textureright", textureRight);
  GetTexture(pControlNode, "textureleftfocus", textureLeftFocus);
  GetTexture(pControlNode, "texturerightfocus", textureRightFocus);

  GetInfoColor(pControlNode, "spincolor", spinInfo.textColor);
  if (XMLUtils::GetString(pControlNode, "spinfont", strFont))
    spinInfo.font = g_fontManager.GetFont(strFont);
  if (!spinInfo.font) spinInfo.font = labelInfo.font;

  XMLUtils::GetFloat(pControlNode, "spinwidth", spinWidth);
  XMLUtils::GetFloat(pControlNode, "spinheight", spinHeight);
  XMLUtils::GetFloat(pControlNode, "spinposx", spinPosX);
  XMLUtils::GetFloat(pControlNode, "spinposy", spinPosY);

  XMLUtils::GetFloat(pControlNode, "markwidth", checkWidth);
  XMLUtils::GetFloat(pControlNode, "markheight", checkHeight);
  XMLUtils::GetFloat(pControlNode, "sliderwidth", sliderWidth);
  XMLUtils::GetFloat(pControlNode, "sliderheight", sliderHeight);
  GetTexture(pControlNode, "texturecheckmark", textureCheckMark);
  GetTexture(pControlNode, "texturecheckmarknofocus", textureCheckMarkNF);
  GetTexture(pControlNode, "textureradiofocus", textureRadioOn);    // backward compatibility
  GetTexture(pControlNode, "textureradionofocus", textureRadioOff);
  GetTexture(pControlNode, "textureradioon", textureRadioOn);
  GetTexture(pControlNode, "textureradiooff", textureRadioOff);

  GetTexture(pControlNode, "texturesliderbackground", textureBackground);
  GetTexture(pControlNode, "texturesliderbar", textureBar);
  GetTexture(pControlNode, "texturesliderbarfocus", textureBarFocus);
  GetTexture(pControlNode, "textureslidernib", textureNib);
  GetTexture(pControlNode, "textureslidernibfocus", textureNibFocus);

  XMLUtils::GetString(pControlNode, "title", strTitle);
  XMLUtils::GetString(pControlNode, "tagset", strRSSTags);
  GetInfoColor(pControlNode, "headlinecolor", headlineColor);
  GetInfoColor(pControlNode, "titlecolor", textColor3);

  if (XMLUtils::GetString(pControlNode, "subtype", strSubType))
  {
    strSubType.ToLower();

    if ( strSubType == "int")
      iType = SPIN_CONTROL_TYPE_INT;
    else if ( strSubType == "page")
      iType = SPIN_CONTROL_TYPE_PAGE;
    else if ( strSubType == "float")
      iType = SPIN_CONTROL_TYPE_FLOAT;
    else
      iType = SPIN_CONTROL_TYPE_TEXT;
  }

  if (!GetIntRange(pControlNode, "range", iMin, iMax, iInterval))
  {
    GetFloatRange(pControlNode, "range", fMin, fMax, fInterval);
  }

  XMLUtils::GetBoolean(pControlNode, "reverse", bReverse);
  XMLUtils::GetBoolean(pControlNode, "reveal", bReveal);

  GetTexture(pControlNode, "texturebg", textureBackground);
  GetTexture(pControlNode, "lefttexture", textureLeft);
  GetTexture(pControlNode, "midtexture", textureMid);
  GetTexture(pControlNode, "righttexture", textureRight);
  GetTexture(pControlNode, "overlaytexture", textureOverlay);

  // the <texture> tag can be overridden by the <info> tag
  GetInfoTexture(pControlNode, "texture", texture, textureFile);

  GetTexture(pControlNode, "bordertexture", borderTexture);

  GetTexture(pControlNode, "imagefolder", imageNoFocus);
  GetTexture(pControlNode, "imagefolderfocus", imageFocus);

  // fade label can have a whole bunch, but most just have one
  vector<CGUIInfoLabel> infoLabels;
  GetInfoLabels(pControlNode, "label", infoLabels);

  GetString(pControlNode, "label", strLabel);
  GetString(pControlNode, "altlabel", altLabel);
  GetString(pControlNode, "label2", strLabel2);

  XMLUtils::GetBoolean(pControlNode, "wrapmultiline", wrapMultiLine);
  XMLUtils::GetInt(pControlNode,"urlset",iUrlSet);

  // stuff for button scroller
  if ( XMLUtils::GetString(pControlNode, "orientation", strTmp) )
  {
    if (strTmp.ToLower() == "horizontal")
    {
      bHorizontal = true;
      orientation = HORIZONTAL;
    }
  }
  XMLUtils::GetFloat(pControlNode, "buttongap", buttonGap);
  XMLUtils::GetFloat(pControlNode, "itemgap", buttonGap);
  XMLUtils::GetInt(pControlNode, "numbuttons", iNumSlots);
  XMLUtils::GetInt(pControlNode, "movement", iMovementRange);
  XMLUtils::GetInt(pControlNode, "defaultbutton", iDefaultSlot);
  XMLUtils::GetInt(pControlNode, "alpha", iAlpha);
  XMLUtils::GetBoolean(pControlNode, "wraparound", bWrapAround);
  XMLUtils::GetBoolean(pControlNode, "smoothscrolling", bSmoothScrolling);
  GetAspectRatio(pControlNode, "aspectratio", aspect);
  XMLUtils::GetBoolean(pControlNode, "scroll", bScrollLabel);
  XMLUtils::GetBoolean(pControlNode,"pulseonselect", bPulse);
  XMLUtils::GetInt(pControlNode, "timeblocks", timeBlocks);
  XMLUtils::GetInt(pControlNode, "rulerunit", rulerUnit);

  GetInfoTexture(pControlNode, "imagepath", texture, texturePath);

  XMLUtils::GetUInt(pControlNode,"timeperimage", timePerImage);
  XMLUtils::GetUInt(pControlNode,"fadetime", fadeTime);
  XMLUtils::GetUInt(pControlNode,"pauseatend", timeToPauseAtEnd);
  XMLUtils::GetBoolean(pControlNode, "randomize", randomized);
  XMLUtils::GetBoolean(pControlNode, "loop", loop);
  XMLUtils::GetBoolean(pControlNode, "scrollout", scrollOut);

  XMLUtils::GetFloat(pControlNode, "radiowidth", radioWidth);
  XMLUtils::GetFloat(pControlNode, "radioheight", radioHeight);
  XMLUtils::GetFloat(pControlNode, "radioposx", radioPosX);
  XMLUtils::GetFloat(pControlNode, "radioposy", radioPosY);
  CStdString borderStr;
  if (XMLUtils::GetString(pControlNode, "bordersize", borderStr))
    GetRectFromString(borderStr, borderSize);

  XMLUtils::GetBoolean(pControlNode, "showonepage", showOnePage);
  XMLUtils::GetInt(pControlNode, "focusposition", focusPosition);
  XMLUtils::GetInt(pControlNode, "scrolltime", scrollTime);
  XMLUtils::GetInt(pControlNode, "preloaditems", preloadItems, 0, 2);

  XMLUtils::GetBoolean(pControlNode, "usecontrolcoords", useControlCoords);
  XMLUtils::GetBoolean(pControlNode, "renderfocusedlast", renderFocusedLast);
  XMLUtils::GetBoolean(pControlNode, "resetonlabelchange", resetOnLabelChange);

  XMLUtils::GetBoolean(pControlNode, "password", bPassword);

  // view type
  VIEW_TYPE viewType = VIEW_TYPE_NONE;
  CStdString viewLabel;
  if (type == CGUIControl::GUICONTAINER_PANEL)
  {
    viewType = VIEW_TYPE_ICON;
    viewLabel = g_localizeStrings.Get(536);
  }
  else if (type == CGUIControl::GUICONTAINER_LIST)
  {
    viewType = VIEW_TYPE_LIST;
    viewLabel = g_localizeStrings.Get(535);
  }
  else
  {
    viewType = VIEW_TYPE_WRAP;
    viewLabel = g_localizeStrings.Get(541);
  }
  TiXmlElement *itemElement = pControlNode->FirstChildElement("viewtype");
  if (itemElement && itemElement->FirstChild())
  {
    CStdString type = itemElement->FirstChild()->Value();
    if (type == "list")
      viewType = VIEW_TYPE_LIST;
    else if (type == "icon")
      viewType = VIEW_TYPE_ICON;
    else if (type == "biglist")
      viewType = VIEW_TYPE_BIG_LIST;
    else if (type == "bigicon")
      viewType = VIEW_TYPE_BIG_ICON;
    else if (type == "wide")
      viewType = VIEW_TYPE_WIDE;
    else if (type == "bigwide")
      viewType = VIEW_TYPE_BIG_WIDE;
    else if (type == "wrap")
      viewType = VIEW_TYPE_WRAP;
    else if (type == "bigwrap")
      viewType = VIEW_TYPE_BIG_WRAP;
    const char *label = itemElement->Attribute("label");
    if (label)
      viewLabel = CGUIInfoLabel::GetLabel(FilterLabel(label));
  }

  TiXmlElement *cam = pControlNode->FirstChildElement("camera");
  if (cam)
  {
    hasCamera = true;
    cam->QueryFloatAttribute("x", &camera.x);
    cam->QueryFloatAttribute("y", &camera.y);
  }

  XMLUtils::GetInt(pControlNode, "scrollspeed", labelInfo.scrollSpeed);
  spinInfo.scrollSpeed = labelInfo.scrollSpeed;

  GetString(pControlNode, "scrollsuffix", labelInfo.scrollSuffix);
  spinInfo.scrollSuffix = labelInfo.scrollSuffix;

  XMLUtils::GetString(pControlNode, "action", action);

  /////////////////////////////////////////////////////////////////////////////
  // Instantiate a new control using the properties gathered above
  //

  CGUIControl *control = NULL;
  if (type == CGUIControl::GUICONTROL_GROUP)
  {
    if (insideContainer)
    {
      control = new CGUIListGroup(parentID, id, posX, posY, width, height);
    }
    else
    {
      control = new CGUIControlGroup(
        parentID, id, posX, posY, width, height);
      ((CGUIControlGroup *)control)->SetDefaultControl(defaultControl, defaultAlways);
      ((CGUIControlGroup *)control)->SetRenderFocusedLast(renderFocusedLast);
    }
  }
  else if (type == CGUIControl::GUICONTROL_GROUPLIST)
  {
    control = new CGUIControlGroupList(
      parentID, id, posX, posY, width, height, buttonGap, pageControl, orientation, useControlCoords, labelInfo.align, scrollTime);
    ((CGUIControlGroup *)control)->SetRenderFocusedLast(renderFocusedLast);
  }
  else if (type == CGUIControl::GUICONTROL_LABEL)
  {
    const CGUIInfoLabel &content = (infoLabels.size()) ? infoLabels[0] : CGUIInfoLabel("");
    if (insideContainer)
    { // inside lists we use CGUIListLabel
      control = new CGUIListLabel(parentID, id, posX, posY, width, height, labelInfo, content, bScrollLabel);
    }
    else
    {
      control = new CGUILabelControl(
        parentID, id, posX, posY, width, height,
        labelInfo, wrapMultiLine, bHasPath);
      ((CGUILabelControl *)control)->SetInfo(content);
      ((CGUILabelControl *)control)->SetWidthControl(minWidth, bScrollLabel);
    }
  }
  else if (type == CGUIControl::GUICONTROL_EDIT)
  {
    control = new CGUIEditControl(
      parentID, id, posX, posY, width, height, textureFocus, textureNoFocus,
      labelInfo, strLabel);

    if (bPassword)
      ((CGUIEditControl *) control)->SetInputType(CGUIEditControl::INPUT_TYPE_PASSWORD, 0);
    ((CGUIEditControl *) control)->SetTextChangeActions(textChangeActions);
  }
  else if (type == CGUIControl::GUICONTROL_VIDEO)
  {
    control = new CGUIVideoControl(
      parentID, id, posX, posY, width, height);
  }
  else if (type == CGUIControl::GUICONTROL_FADELABEL)
  {
    control = new CGUIFadeLabelControl(
      parentID, id, posX, posY, width, height,
      labelInfo, scrollOut, timeToPauseAtEnd, resetOnLabelChange);

    ((CGUIFadeLabelControl *)control)->SetInfo(infoLabels);
  }
  else if (type == CGUIControl::GUICONTROL_RSS)
  {
    control = new CGUIRSSControl(
      parentID, id, posX, posY, width, height,
      labelInfo, textColor3, headlineColor, strRSSTags);

    std::map<int,CSettings::RssSet>::iterator iter=g_settings.m_mapRssUrls.find(iUrlSet);
    if (iter != g_settings.m_mapRssUrls.end())
    {
      ((CGUIRSSControl *)control)->SetUrls(iter->second.url,iter->second.rtl);
      ((CGUIRSSControl *)control)->SetIntervals(iter->second.interval);
    }
    else
      CLog::Log(LOGERROR,"invalid rss url set referenced in skin");
  }
  else if (type == CGUIControl::GUICONTROL_BUTTON)
  {
    control = new CGUIButtonControl(
      parentID, id, posX, posY, width, height,
      textureFocus, textureNoFocus,
      labelInfo);

    ((CGUIButtonControl *)control)->SetLabel(strLabel);
    ((CGUIButtonControl *)control)->SetLabel2(strLabel2);
    ((CGUIButtonControl *)control)->SetClickActions(clickActions);
    ((CGUIButtonControl *)control)->SetFocusActions(focusActions);
    ((CGUIButtonControl *)control)->SetUnFocusActions(unfocusActions);
  }
  else if (type == CGUIControl::GUICONTROL_TOGGLEBUTTON)
  {
    control = new CGUIToggleButtonControl(
      parentID, id, posX, posY, width, height,
      textureFocus, textureNoFocus,
      textureAltFocus, textureAltNoFocus, labelInfo);

    ((CGUIToggleButtonControl *)control)->SetLabel(strLabel);
    ((CGUIToggleButtonControl *)control)->SetAltLabel(altLabel);
    ((CGUIToggleButtonControl *)control)->SetClickActions(clickActions);
    ((CGUIToggleButtonControl *)control)->SetAltClickActions(altclickActions);
    ((CGUIToggleButtonControl *)control)->SetFocusActions(focusActions);
    ((CGUIToggleButtonControl *)control)->SetUnFocusActions(unfocusActions);
    ((CGUIToggleButtonControl *)control)->SetToggleSelect(iToggleSelect);
  }
  else if (type == CGUIControl::GUICONTROL_CHECKMARK)
  {
    control = new CGUICheckMarkControl(
      parentID, id, posX, posY, width, height,
      textureCheckMark, textureCheckMarkNF,
      checkWidth, checkHeight, labelInfo);

    ((CGUICheckMarkControl *)control)->SetLabel(strLabel);
  }
  else if (type == CGUIControl::GUICONTROL_RADIO)
  {
    control = new CGUIRadioButtonControl(
      parentID, id, posX, posY, width, height,
      textureFocus, textureNoFocus,
      labelInfo,
      textureRadioOn, textureRadioOff);

    ((CGUIRadioButtonControl *)control)->SetLabel(strLabel);
    ((CGUIRadioButtonControl *)control)->SetRadioDimensions(radioPosX, radioPosY, radioWidth, radioHeight);
    ((CGUIRadioButtonControl *)control)->SetToggleSelect(iToggleSelect);
    ((CGUIRadioButtonControl *)control)->SetClickActions(clickActions);
    ((CGUIRadioButtonControl *)control)->SetFocusActions(focusActions);
    ((CGUIRadioButtonControl *)control)->SetUnFocusActions(unfocusActions);
  }
  else if (type == CGUIControl::GUICONTROL_MULTISELECT)
  {
    CGUIInfoLabel label;
    if (infoLabels.size())
      label = infoLabels[0];
    control = new CGUIMultiSelectTextControl(
      parentID, id, posX, posY, width, height,
      textureFocus, textureNoFocus, labelInfo, label);
  }
  else if (type == CGUIControl::GUICONTROL_SPIN)
  {
    control = new CGUISpinControl(
      parentID, id, posX, posY, width, height,
      textureUp, textureDown, textureUpFocus, textureDownFocus,
      labelInfo, iType);

    ((CGUISpinControl *)control)->SetReverse(bReverse);

    if (iType == SPIN_CONTROL_TYPE_INT)
    {
      ((CGUISpinControl *)control)->SetRange(iMin, iMax);
    }
    else if (iType == SPIN_CONTROL_TYPE_PAGE)
    {
      ((CGUISpinControl *)control)->SetRange(iMin, iMax);
      ((CGUISpinControl *)control)->SetShowRange(true);
      ((CGUISpinControl *)control)->SetReverse(false);
      ((CGUISpinControl *)control)->SetShowOnePage(showOnePage);
    }
    else if (iType == SPIN_CONTROL_TYPE_FLOAT)
    {
      ((CGUISpinControl *)control)->SetFloatRange(fMin, fMax);
      ((CGUISpinControl *)control)->SetFloatInterval(fInterval);
    }
  }
  else if (type == CGUIControl::GUICONTROL_SLIDER)
  {
    control = new CGUISliderControl(
      parentID, id, posX, posY, width, height,
      textureBar, textureNib, textureNibFocus, SPIN_CONTROL_TYPE_TEXT);

    ((CGUISliderControl *)control)->SetInfo(singleInfo);
    ((CGUISliderControl *)control)->SetAction(action);
  }
  else if (type == CGUIControl::GUICONTROL_SETTINGS_SLIDER)
  {
    labelInfo.align |= XBFONT_CENTER_Y;    // always center text vertically
    control = new CGUISettingsSliderControl(
      parentID, id, posX, posY, width, height, sliderWidth, sliderHeight, textureFocus, textureNoFocus,
      textureBar, textureNib, textureNibFocus, labelInfo, SPIN_CONTROL_TYPE_TEXT);

    ((CGUISettingsSliderControl *)control)->SetText(strLabel);
    ((CGUISettingsSliderControl *)control)->SetInfo(singleInfo);
  }
  else if (type == CGUIControl::GUICONTROL_SCROLLBAR)
  {
    control = new CGUIScrollBar(
      parentID, id, posX, posY, width, height,
      textureBackground, textureBar, textureBarFocus, textureNib, textureNibFocus, orientation, showOnePage);
  }
  else if (type == CGUIControl::GUICONTROL_PROGRESS)
  {
    control = new CGUIProgressControl(
      parentID, id, posX, posY, width, height,
      textureBackground, textureLeft, textureMid, textureRight,
      textureOverlay, bReveal);
    ((CGUIProgressControl *)control)->SetInfo(singleInfo);
  }
  else if (type == CGUIControl::GUICONTROL_IMAGE)
  {
    if (strType == "largeimage")
      texture.useLarge = true;

    // use a bordered texture if we have <bordersize> or <bordertexture> specified.
    if (borderTexture.filename.IsEmpty() && borderStr.IsEmpty())
      control = new CGUIImage(
        parentID, id, posX, posY, width, height, texture);
    else
      control = new CGUIBorderedImage(
        parentID, id, posX, posY, width, height, texture, borderTexture, borderSize);
#ifdef PRE_SKIN_VERSION_9_10_COMPATIBILITY
    if (insideContainer && textureFile.IsConstant())
      aspect.ratio = CAspectRatio::AR_STRETCH;
#endif
    ((CGUIImage *)control)->SetInfo(textureFile);
    ((CGUIImage *)control)->SetAspectRatio(aspect);
    ((CGUIImage *)control)->SetCrossFade(fadeTime);
  }
  else if (type == CGUIControl::GUICONTROL_MULTI_IMAGE)
  {
    control = new CGUIMultiImage(
      parentID, id, posX, posY, width, height, texture, timePerImage, fadeTime, randomized, loop, timeToPauseAtEnd);
    ((CGUIMultiImage *)control)->SetInfo(texturePath);
    ((CGUIMultiImage *)control)->SetAspectRatio(aspect);
  }
  else if (type == CGUIControl::GUICONTAINER_LIST)
  {
    control = new CGUIListContainer(parentID, id, posX, posY, width, height, orientation, scrollTime, preloadItems);
    ((CGUIListContainer *)control)->LoadLayout(pControlNode);
    ((CGUIListContainer *)control)->LoadContent(pControlNode);
    ((CGUIListContainer *)control)->SetType(viewType, viewLabel);
    ((CGUIListContainer *)control)->SetPageControl(pageControl);
    ((CGUIListContainer *)control)->SetRenderOffset(offset);
  }
  else if (type == CGUIControl::GUICONTAINER_WRAPLIST)
  {
    control = new CGUIWrappingListContainer(parentID, id, posX, posY, width, height, orientation, scrollTime, preloadItems, focusPosition);
    ((CGUIWrappingListContainer *)control)->LoadLayout(pControlNode);
    ((CGUIWrappingListContainer *)control)->LoadContent(pControlNode);
    ((CGUIWrappingListContainer *)control)->SetType(viewType, viewLabel);
    ((CGUIWrappingListContainer *)control)->SetPageControl(pageControl);
    ((CGUIWrappingListContainer *)control)->SetRenderOffset(offset);
  }
  else if (type == CGUIControl::GUICONTAINER_EPGGRID)
  {
    control = new CGUIEPGGridContainer(parentID, id, posX, posY, width, height, orientation, scrollTime, preloadItems, timeBlocks, rulerUnit);
    ((CGUIEPGGridContainer *)control)->LoadLayout(pControlNode);
//    ((CGUIEPGGridContainer *)control)->LoadContent(pControlNode); ///
  }
  else if (type == CGUIControl::GUICONTAINER_FIXEDLIST)
  {
    control = new CGUIFixedListContainer(parentID, id, posX, posY, width, height, orientation, scrollTime, preloadItems, focusPosition, iMovementRange);
    ((CGUIFixedListContainer *)control)->LoadLayout(pControlNode);
    ((CGUIFixedListContainer *)control)->LoadContent(pControlNode);
    ((CGUIFixedListContainer *)control)->SetType(viewType, viewLabel);
    ((CGUIFixedListContainer *)control)->SetPageControl(pageControl);
    ((CGUIFixedListContainer *)control)->SetRenderOffset(offset);
  }
  else if (type == CGUIControl::GUICONTAINER_PANEL)
  {
    control = new CGUIPanelContainer(parentID, id, posX, posY, width, height, orientation, scrollTime, preloadItems);
    ((CGUIPanelContainer *)control)->LoadLayout(pControlNode);
    ((CGUIPanelContainer *)control)->LoadContent(pControlNode);
    ((CGUIPanelContainer *)control)->SetType(viewType, viewLabel);
    ((CGUIPanelContainer *)control)->SetPageControl(pageControl);
    ((CGUIPanelContainer *)control)->SetRenderOffset(offset);
  }
  else if (type == CGUIControl::GUICONTROL_TEXTBOX)
  {
    control = new CGUITextBox(
      parentID, id, posX, posY, width, height,
      labelInfo, scrollTime);

    ((CGUITextBox *)control)->SetPageControl(pageControl);
    if (infoLabels.size())
      ((CGUITextBox *)control)->SetInfo(infoLabels[0]);
    ((CGUITextBox *)control)->SetAutoScrolling(pControlNode);
  }
  else if (type == CGUIControl::GUICONTROL_SELECTBUTTON)
  {
    control = new CGUISelectButtonControl(
      parentID, id, posX, posY,
      width, height, textureFocus, textureNoFocus,
      labelInfo,
      textureBackground, textureLeft, textureLeftFocus, textureRight, textureRightFocus);

    ((CGUISelectButtonControl *)control)->SetLabel(strLabel);
  }
  else if (type == CGUIControl::GUICONTROL_MOVER)
  {
    control = new CGUIMoverControl(
      parentID, id, posX, posY, width, height,
      textureFocus, textureNoFocus);
  }
  else if (type == CGUIControl::GUICONTROL_RESIZE)
  {
    control = new CGUIResizeControl(
      parentID, id, posX, posY, width, height,
      textureFocus, textureNoFocus);
  }
  else if (type == CGUIControl::GUICONTROL_BUTTONBAR)
  {
    control = new CGUIButtonScroller(
      parentID, id, posX, posY, width, height, buttonGap, iNumSlots, iDefaultSlot,
      iMovementRange, bHorizontal, iAlpha, bWrapAround, bSmoothScrolling,
      textureFocus, textureNoFocus, labelInfo);
    ((CGUIButtonScroller *)control)->LoadButtons(pControlNode);
  }
  else if (type == CGUIControl::GUICONTROL_SPINEX)
  {
    control = new CGUISpinControlEx(
      parentID, id, posX, posY, width, height, spinWidth, spinHeight,
      labelInfo, textureFocus, textureNoFocus, textureUp, textureDown, textureUpFocus, textureDownFocus,
      labelInfo, iType);

    ((CGUISpinControlEx *)control)->SetSpinPosition(spinPosX);
    ((CGUISpinControlEx *)control)->SetText(strLabel);
    ((CGUISpinControlEx *)control)->SetReverse(bReverse);
  }
  else if (type == CGUIControl::GUICONTROL_VISUALISATION)
  {
    control = new CGUIVisualisationControl(parentID, id, posX, posY, width, height);
  }

  // things that apply to all controls
  if (control)
  {
    control->SetHitRect(hitRect);
    control->SetVisibleCondition(iVisibleCondition, allowHiddenFocus);
    control->SetEnableCondition(enableCondition);
    control->SetAnimations(animations);
    control->SetColorDiffuse(colorDiffuse);
    control->SetNavigation(up, down, left, right);
    control->SetTabNavigation(next,prev);
    control->SetNavigationActions(upActions, downActions, leftActions, rightActions);
    control->SetPulseOnSelect(bPulse);
    if (hasCamera)
      control->SetCamera(camera);
  }
  return control;
}
Beispiel #8
0
void upgradeFrom3_0()
{
    // 3.0 had process definition files in /etc/sipxpbx/process.d
    UtlString oldProcessDefinitionDirectory =
        SipXecsService::Path(SipXecsService::ConfigurationDirType, "process-old.d");

    OsSysLog::add(FAC_SUPERVISOR, PRI_DEBUG,"upgradeFrom3_0: searching '%s'",
                  oldProcessDefinitionDirectory.data()
                 );

    if ( !OsFileSystem::exists( oldProcessDefinitionDirectory) )
    {
        return;
    }

    OsFileIterator definitions(oldProcessDefinitionDirectory);
    OsPath    oldProcessDefinitionFile;
    bool okToRemoveDir = true;   // set to false if any pre-4.0 process file cannot be upgraded
    for ( OsStatus iteratorStatus = definitions.findFirst(oldProcessDefinitionFile,
                                    OLD_PROCESS_DEFINITION_NAME_PATTERN,
                                    OsFileIterator::FILES);
            OS_SUCCESS == iteratorStatus;
            iteratorStatus = definitions.findNext(oldProcessDefinitionFile)
        )
    {
        OsPath oldProcessDefinitionPath( oldProcessDefinitionDirectory
                                         +OsPath::separator
                                         +oldProcessDefinitionFile
                                       );
        OsSysLog::add(FAC_SUPERVISOR, PRI_INFO,"upgradeFrom3_0: reading pre-4.0 process def '%s'",
                      oldProcessDefinitionPath.data()
                     );

        // read the process name and the watchdog enable setting,
        // and enable the process if necessary
        TiXmlDocument processDefinitionDoc(oldProcessDefinitionPath);

        bool definitionValid = true;
        UtlString errorMsg;
        if ( processDefinitionDoc.LoadFile() )
        {
            TiXmlElement *subroot = processDefinitionDoc.RootElement();
            if (subroot != NULL)
            {
                bool bEnabled=false;
                const char *enableString = subroot->Attribute("enable");
                if (enableString == NULL || strcmp(enableString, "true")==0)
                {
                    bEnabled=true;
                }

                TiXmlElement* processDefElement = subroot->FirstChildElement("process_definitions");
                if (processDefElement)
                {
                    TiXmlNode *pGroupNode = processDefElement->FirstChild("group");
                    if (pGroupNode)
                    {
                        TiXmlElement *processElement = pGroupNode->FirstChildElement("process");
                        if (processElement)
                        {
                            const char *pMsg = processElement->Attribute("name");
                            UtlString processName = pMsg;

                            // enable or disable process based on setting in old process def file
                            SipxProcess* newProcess;
                            if ((newProcess=SipxProcessManager::getInstance()->findProcess(processName)))
                            {
                                if (bEnabled)
                                {
                                    OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE,
                                                  "upgradeFrom3_0: enabling process '%s'", processName.data());
                                    newProcess->enable();
                                }
                                else
                                {
                                    OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE,
                                                  "upgradeFrom3_0: disabling process '%s'", processName.data());
                                    newProcess->disable();
                                }

                                if (OS_SUCCESS == OsFileSystem::remove(oldProcessDefinitionPath))
                                {
                                    OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE,
                                                  "upgradeFrom3_0: removing pre-4.0 process def file '%s'",
                                                  oldProcessDefinitionPath.data());
                                }
                                else
                                {
                                    OsSysLog::add(FAC_SUPERVISOR, PRI_ERR,
                                                  "upgradeFrom3_0: failed to remove pre-4.0 process def file '%s'",
                                                  oldProcessDefinitionPath.data());
                                }
                            }
                            else
                            {
                                OsSysLog::add(FAC_SUPERVISOR, PRI_ERR,
                                              "upgradeFrom3_0: could not find process '%s'", processName.data());
                                okToRemoveDir = false;
                            }
                        }
                        else
                        {
                            definitionValid = false;
                        }
                    }
                    else
                    {
                        definitionValid = false;
                    }
                }
                else
                {
                    definitionValid = false;
                }
            }
            else
            {
                definitionValid = false;
            }
        }
        else
        {
            definitionValid = false;
        }

        if ( !definitionValid )
        {
            // Invalid document format.  Log the issue and continue to the next process xml file.
            XmlErrorMsg(processDefinitionDoc, errorMsg);
            OsSysLog::add(FAC_SUPERVISOR, PRI_ERR,
                          "upgradeFrom3_0: ignoring invalid pre-4.0 process xml file '%s' (%s)",
                          oldProcessDefinitionFile.data(), errorMsg.data());
            okToRemoveDir = false;
        }
    }

    // remove the old process defn directory (succeeds only if it is empty)
    if (OS_SUCCESS == OsFileSystem::remove(oldProcessDefinitionDirectory))
    {
        OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE,
                      "upgradeFrom3_0: all process data has been migrated from "
                      "pre-4.0 process def directory '%s', "
                      "and the directory has been deleted.",
                      oldProcessDefinitionDirectory.data());
    }
    else
    {
        // rmdir may fail because files still exist (e.g. editor backup files).
        // Log whether upgrade succeeded or not.
        if ( okToRemoveDir )
        {
            OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE,
                          "upgradeFrom3_0: all process data has been migrated from "
                          "pre-4.0 process def directory '%s', "
                          "and the directory may safely be deleted.",
                          oldProcessDefinitionDirectory.data());
        }
        else
        {
            OsSysLog::add(FAC_SUPERVISOR, PRI_WARNING,
                          "upgradeFrom3_0: some process data could not be migrated from "
                          "pre-4.0 process def directory '%s'. ",
                          oldProcessDefinitionDirectory.data());
        }
    }
}
Beispiel #9
0
bool CGUIWindow::Load(TiXmlDocument &xmlDoc)
{
  TiXmlElement* pRootElement = xmlDoc.RootElement();
  if (strcmpi(pRootElement->Value(), "window"))
  {
    CLog::Log(LOGERROR, "file : XML file doesnt contain <window>");
    return false;
  }

  // set the scaling resolution so that any control creation or initialisation can
  // be done with respect to the correct aspect ratio
  g_graphicsContext.SetScalingResolution(m_coordsRes, m_needsScaling);

  // Resolve any includes that may be present
  g_SkinInfo->ResolveIncludes(pRootElement);
  // now load in the skin file
  SetDefaults();

  CGUIControlFactory::GetInfoColor(pRootElement, "backgroundcolor", m_clearBackground);
  CGUIControlFactory::GetMultipleString(pRootElement, "onload", m_loadActions);
  CGUIControlFactory::GetMultipleString(pRootElement, "onunload", m_unloadActions);
  CGUIControlFactory::GetHitRect(pRootElement, m_hitRect);

  TiXmlElement *pChild = pRootElement->FirstChildElement();
  while (pChild)
  {
    CStdString strValue = pChild->Value();
    if (strValue == "type" && pChild->FirstChild())
    {
      // if we have are a window type (ie not a dialog), and we have <type>dialog</type>
      // then make this window act like a dialog
      if (!IsDialog() && strcmpi(pChild->FirstChild()->Value(), "dialog") == 0)
        m_isDialog = true;
    }
    else if (strValue == "previouswindow" && pChild->FirstChild())
    {
      m_previousWindow = CButtonTranslator::TranslateWindow(pChild->FirstChild()->Value());
    }
    else if (strValue == "defaultcontrol" && pChild->FirstChild())
    {
      const char *always = pChild->Attribute("always");
      if (always && strcmpi(always, "true") == 0)
        m_defaultAlways = true;
      m_defaultControl = atoi(pChild->FirstChild()->Value());
    }
    else if (strValue == "visible" && pChild->FirstChild())
    {
      CStdString condition;
      CGUIControlFactory::GetConditionalVisibility(pRootElement, condition);
      m_visibleCondition = g_infoManager.Register(condition, GetID());
    }
    else if (strValue == "animation" && pChild->FirstChild())
    {
      CRect rect(0, 0, (float)m_coordsRes.iWidth, (float)m_coordsRes.iHeight);
      CAnimation anim;
      anim.Create(pChild, rect, GetID());
      m_animations.push_back(anim);
    }
    else if (strValue == "zorder" && pChild->FirstChild())
    {
      m_renderOrder = atoi(pChild->FirstChild()->Value());
    }
    else if (strValue == "coordinates")
    {
      XMLUtils::GetFloat(pChild, "posx", m_posX);
      XMLUtils::GetFloat(pChild, "posy", m_posY);

      TiXmlElement *originElement = pChild->FirstChildElement("origin");
      while (originElement)
      {
        COrigin origin;
        originElement->QueryFloatAttribute("x", &origin.x);
        originElement->QueryFloatAttribute("y", &origin.y);
        if (originElement->FirstChild())
          origin.condition = g_infoManager.Register(originElement->FirstChild()->Value(), GetID());
        m_origins.push_back(origin);
        originElement = originElement->NextSiblingElement("origin");
      }
    }
    else if (strValue == "camera")
    { // z is fixed
      pChild->QueryFloatAttribute("x", &m_camera.x);
      pChild->QueryFloatAttribute("y", &m_camera.y);
      m_hasCamera = true;
    }
    else if (strValue == "controls")
    {
      TiXmlElement *pControl = pChild->FirstChildElement();
      while (pControl)
      {
        if (strcmpi(pControl->Value(), "control") == 0)
        {
          LoadControl(pControl, NULL);
        }
        pControl = pControl->NextSiblingElement();
      }
    }
    else if (strValue == "allowoverlay")
    {
      bool overlay = false;
      if (XMLUtils::GetBoolean(pRootElement, "allowoverlay", overlay))
        m_overlayState = overlay ? OVERLAY_STATE_SHOWN : OVERLAY_STATE_HIDDEN;
    }

    pChild = pChild->NextSiblingElement();
  }
  LoadAdditionalTags(pRootElement);

  m_windowLoaded = true;
  OnWindowLoaded();
  return true;
}
Beispiel #10
0
void CMusicInfoScraper::FindAlbuminfo()
{
  CStdString strAlbum=m_strAlbum;
  CStdString strHTML;
  m_vecAlbums.erase(m_vecAlbums.begin(), m_vecAlbums.end());

  CScraperParser parser;
  if (!parser.Load(_P("q:\\system\\scrapers\\music\\"+m_info.strPath)))
    return;

  if (!m_info.settings.GetPluginRoot() || m_info.settings.GetSettings().IsEmpty())
  {
    m_info.settings.LoadSettingsXML(_P("q:\\system\\scrapers\\music\\"+m_info.strPath));
    m_info.settings.SaveFromDefault();
  }

  parser.m_param[0] = strAlbum;
  parser.m_param[1] = m_strArtist;
  CUtil::URLEncode(parser.m_param[0]);
  CUtil::URLEncode(parser.m_param[1]);

  CScraperUrl scrURL;
  scrURL.ParseString(parser.Parse("CreateAlbumSearchUrl"));
  if (!CScraperUrl::Get(scrURL.m_url[0], strHTML, m_http) || strHTML.size() == 0)
  {
    CLog::Log(LOGERROR, "%s: Unable to retrieve web site",__FUNCTION__);
    return;
  }

  parser.m_param[0] = strHTML;
  CStdString strXML = parser.Parse("GetAlbumSearchResults",&m_info.settings);
  if (strXML.IsEmpty())
  {
    CLog::Log(LOGERROR, "%s: Unable to parse web site",__FUNCTION__);
    return;
  }

  if (strXML.Find("encoding=\"utf-8\"") < 0)
    g_charsetConverter.stringCharsetToUtf8(strXML);

  // ok, now parse the xml file
  TiXmlDocument doc;
  doc.Parse(strXML.c_str(),0,TIXML_ENCODING_UTF8);
  if (!doc.RootElement())
  {
    CLog::Log(LOGERROR, "%s: Unable to parse xml",__FUNCTION__);
    return;
  }
  TiXmlHandle docHandle( &doc );
  TiXmlElement* album = docHandle.FirstChild( "results" ).FirstChild( "entity" ).Element();
  if (!album)
    return;

  while (album)
  {
    TiXmlNode* title = album->FirstChild("title");
    TiXmlElement* link = album->FirstChildElement("url");
    TiXmlNode* artist = album->FirstChild("artist");
    TiXmlNode* year = album->FirstChild("year");
    if (title && title->FirstChild())
    {
      CStdString strTitle = title->FirstChild()->Value();
      CStdString strArtist;
      CStdString strAlbumName;

      if (artist && artist->FirstChild())
      {
        strArtist = artist->FirstChild()->Value();
        strAlbumName.Format("%s - %s",strArtist.c_str(),strTitle.c_str());
      }
      else
        strAlbumName = strTitle;

      if (year && year->FirstChild())
        strAlbumName.Format("%s (%s)",strAlbumName.c_str(),year->FirstChild()->Value());

      CScraperUrl url;
      if (!link)
        url.ParseString(scrURL.m_xml);

      while (link && link->FirstChild())
      {
        url.ParseElement(link);
        link = link->NextSiblingElement("url");
      }
      CMusicAlbumInfo newAlbum(strTitle, strArtist, strAlbumName, url);
      m_vecAlbums.push_back(newAlbum);
    }
    album = album->NextSiblingElement();
  }
  
  if (m_vecAlbums.size()>0)
    m_bSuccessfull=true;

  return;
}
Beispiel #11
0
bool CRSSDirectory::GetDirectory(const CStdString& path, CFileItemList &items)
{
  CStdString strPath(path);
  URIUtils::RemoveSlashAtEnd(strPath);
  std::map<CStdString,CDateTime>::iterator it;
  items.SetPath(strPath);
  CSingleLock lock(m_section);
  if ((it=m_cache.find(strPath)) != m_cache.end())
  {
    if (it->second > CDateTime::GetCurrentDateTime() && 
        items.Load())
      return true;
    m_cache.erase(it);
  }
  lock.Leave();

  CXBMCTinyXML xmlDoc;
  if (!xmlDoc.LoadFile(strPath))
  {
    CLog::Log(LOGERROR,"failed to load xml from <%s>. error: <%d>", strPath.c_str(), xmlDoc.ErrorId());
    return false;
  }
  if (xmlDoc.Error())
  {
    CLog::Log(LOGERROR,"error parsing xml doc from <%s>. error: <%d>", strPath.c_str(), xmlDoc.ErrorId());
    return false;
  }

  TiXmlElement* rssXmlNode = xmlDoc.RootElement();

  if (!rssXmlNode)
    return false;

  TiXmlHandle docHandle( &xmlDoc );
  TiXmlElement* channelXmlNode = docHandle.FirstChild( "rss" ).FirstChild( "channel" ).Element();
  if (channelXmlNode)
    ParseItem(&items, channelXmlNode, path);
  else
    return false;

  TiXmlElement* child = NULL;
  for (child = channelXmlNode->FirstChildElement("item"); child; child = child->NextSiblingElement())
  {
    // Create new item,
    CFileItemPtr item(new CFileItem());
    ParseItem(item.get(), child, path);

    item->SetProperty("isrss", "1");

    if (!item->GetPath().IsEmpty())
      items.Add(item);
  }

  items.AddSortMethod(SORT_METHOD_UNSORTED , 231, LABEL_MASKS("%L", "%D", "%L", ""));    // FileName, Duration | Foldername, empty
  items.AddSortMethod(SORT_METHOD_LABEL    , 551, LABEL_MASKS("%L", "%D", "%L", ""));    // FileName, Duration | Foldername, empty
  items.AddSortMethod(SORT_METHOD_SIZE     , 553, LABEL_MASKS("%L", "%I", "%L", "%I"));  // FileName, Size | Foldername, Size
  items.AddSortMethod(SORT_METHOD_DATE     , 552, LABEL_MASKS("%L", "%J", "%L", "%J"));  // FileName, Date | Foldername, Date

  CDateTime time = CDateTime::GetCurrentDateTime();
  int mins = 60;
  TiXmlElement* ttl = docHandle.FirstChild("rss").FirstChild("ttl").Element();
  if (ttl)
    mins = strtol(ttl->FirstChild()->Value(),NULL,10);
  time += CDateTimeSpan(0,0,mins,0);
  items.SetPath(strPath);
  items.Save();
  CSingleLock lock2(m_section);
  m_cache.insert(make_pair(strPath,time));

  return true;
}
void CSettingsManager::read_SettingsXML()
{
  TiXmlDocument xmlDoc;
  if(!xmlDoc.LoadFile(m_XMLFilename))
  {
    KODI->Log(LOG_NOTICE, "No initial settings XML file found.");
    return;
  }

  TiXmlElement *pRootElement = xmlDoc.RootElement();
  if(!pRootElement)
  {
    KODI->Log(LOG_NOTICE, "Settings XML file is empty.");
    return;
  }

  string mainCategory = pRootElement->Value();
  for(TiXmlNode *pGroupNode = pRootElement->FirstChild(); pGroupNode != NULL; pGroupNode = pRootElement->IterateChildren(pGroupNode))
  {
    if(pGroupNode->ValueStr() == "settings_group")
    {
      ATTRIBUTES_LIST groupAttributesList;
      if(pGroupNode && pGroupNode->Type() == TiXmlNode::TINYXML_ELEMENT)
      {
        getAttributesAsList(pGroupNode->ToElement(), groupAttributesList);
      }

      if(pGroupNode && pGroupNode->Type() == TiXmlNode::TINYXML_ELEMENT && groupAttributesList.size() == 2 && pGroupNode->ValueStr() == "settings_group")
      {
        string subCategory = "";
        string groupName = "";
        for(ATTRIBUTES_LIST::iterator iter = groupAttributesList.begin(); iter != groupAttributesList.end(); iter++)
        {
          if(iter->first == "sub_category")
          {
            subCategory = iter->second;
          }

          if(iter->first == "group_name")
          {
            groupName = iter->second;
          }
        }

        for(TiXmlNode *pKeyNode = pGroupNode->FirstChild(); pKeyNode != NULL; pKeyNode = pGroupNode->IterateChildren(pKeyNode))
        {
          if(pKeyNode && pKeyNode->Type() == TiXmlNode::TINYXML_ELEMENT && pKeyNode->ValueStr() == "setting")
          {
            ATTRIBUTES_LIST settingAttributesList;
            if(getAttributesAsList(pKeyNode->ToElement(), settingAttributesList) == 2)
            {
              string key = "";
              ISettingsElement::SettingsTypes type = ISettingsElement::UNKNOWN_SETTING;
              string value = "";
              for(ATTRIBUTES_LIST::iterator iter = settingAttributesList.begin(); iter != settingAttributesList.end(); iter++)
              {
                if(iter->first == "key")
                {
                  key = iter->second;
                }
                else
                {
                  type = CSettingsHelpers::TranslateTypeStrToEnum(iter->first);
                  value = iter->second;
                }
              }

              ISettingsElement *setting = find_Setting(mainCategory, subCategory, groupName, key);
              if(setting && setting->get_Type() == type)
              {
                switch(type)
                  {
                    case ISettingsElement::STRING_SETTING:
                      STRING_SETTINGS(setting)->set_Setting(value);
                    break;

                    case ISettingsElement::UNSIGNED_INT_SETTING:
                      {
                        unsigned int val = stringToVal<unsigned int>(value);
                        UNSIGNED_INT_SETTINGS(setting)->set_Setting(val);
                      }
                    break;

                    case ISettingsElement::INT_SETTING:
                      {
                        int val = stringToVal<int>(value);
                        INT_SETTINGS(setting)->set_Setting(val);
                      }
                    break;

                    case ISettingsElement::FLOAT_SETTING:
                      {
                        float val = stringToVal<float>(value);
                        FLOAT_SETTINGS(setting)->set_Setting(val);
                      }
                    break;

                    case ISettingsElement::DOUBLE_SETTING:
                      {
                        double val = stringToVal<double>(value);
                        DOUBLE_SETTINGS(setting)->set_Setting(val);
                      }
                    break;

                    case ISettingsElement::BOOL_SETTING:
                      if(value == "true" || value == "TRUE" || value == "True")
                      {
                        bool val = true;
                        BOOL_SETTINGS(setting)->set_Setting(val);
                      }
                      else if(value == "false" || value == "FALSE" || value == "False")
                      {
                        bool val = false;
                        BOOL_SETTINGS(setting)->set_Setting(val);
                      }
                      else
                      {
                        KODI->Log(LOG_ERROR, "CSettingsManager: Failed reading bool setting");
                      }
                    break;

                    default:
                      KODI->Log(LOG_ERROR, "CSettingsManager: Unknown settings type!");
                    break;
                  }
              }
              else
              {
                KODI->Log(LOG_ERROR, "CSettingsManager: Read settings element does not match the created settings element type!");
              }
            }
          }
        }
      }
    }
  }
}
Beispiel #13
0
void CScraperParser::ParseExpression(const std::string& input, std::string& dest, TiXmlElement* element, bool bAppend)
{
  std::string strOutput = XMLUtils::GetAttribute(element, "output");

  TiXmlElement* pExpression = element->FirstChildElement("expression");
  if (pExpression)
  {
    bool bInsensitive=true;
    const char* sensitive = pExpression->Attribute("cs");
    if (sensitive)
      if (stricmp(sensitive,"yes") == 0)
        bInsensitive=false; // match case sensitive

    CRegExp::utf8Mode eUtf8 = CRegExp::autoUtf8;
    const char* const strUtf8 = pExpression->Attribute("utf8");
    if (strUtf8)
    {
      if (stricmp(strUtf8, "yes") == 0)
        eUtf8 = CRegExp::forceUtf8;
      else if (stricmp(strUtf8, "no") == 0)
        eUtf8 = CRegExp::asciiOnly;
      else if (stricmp(strUtf8, "auto") == 0)
        eUtf8 = CRegExp::autoUtf8;
    }

    CRegExp reg(bInsensitive, eUtf8);
    std::string strExpression;
    if (pExpression->FirstChild())
      strExpression = pExpression->FirstChild()->Value();
    else
      strExpression = "(.*)";
    ReplaceBuffers(strExpression);
    ReplaceBuffers(strOutput);

    if (!reg.RegComp(strExpression.c_str()))
    {
      return;
    }

    bool bRepeat = false;
    const char* szRepeat = pExpression->Attribute("repeat");
    if (szRepeat)
      if (stricmp(szRepeat,"yes") == 0)
        bRepeat = true;

    const char* szClear = pExpression->Attribute("clear");
    if (szClear)
      if (stricmp(szClear,"yes") == 0)
        dest=""; // clear no matter if regexp fails

    bool bClean[MAX_SCRAPER_BUFFERS];
    GetBufferParams(bClean,pExpression->Attribute("noclean"),true);

    bool bTrim[MAX_SCRAPER_BUFFERS];
    GetBufferParams(bTrim,pExpression->Attribute("trim"),false);

    bool bFixChars[MAX_SCRAPER_BUFFERS];
    GetBufferParams(bFixChars,pExpression->Attribute("fixchars"),false);

    bool bEncode[MAX_SCRAPER_BUFFERS];
    GetBufferParams(bEncode,pExpression->Attribute("encode"),false);

    int iOptional = -1;
    pExpression->QueryIntAttribute("optional",&iOptional);

    int iCompare = -1;
    pExpression->QueryIntAttribute("compare",&iCompare);
    if (iCompare > -1)
      StringUtils::ToLower(m_param[iCompare-1]);
    std::string curInput = input;
    for (int iBuf=0;iBuf<MAX_SCRAPER_BUFFERS;++iBuf)
    {
      if (bClean[iBuf])
        InsertToken(strOutput,iBuf+1,"!!!CLEAN!!!");
      if (bTrim[iBuf])
        InsertToken(strOutput,iBuf+1,"!!!TRIM!!!");
      if (bFixChars[iBuf])
        InsertToken(strOutput,iBuf+1,"!!!FIXCHARS!!!");
      if (bEncode[iBuf])
        InsertToken(strOutput,iBuf+1,"!!!ENCODE!!!");
    }
    int i = reg.RegFind(curInput.c_str());
    while (i > -1 && (i < (int)curInput.size() || curInput.empty()))
    {
      if (!bAppend)
      {
        dest = "";
        bAppend = true;
      }
      std::string strCurOutput=strOutput;

      if (iOptional > -1) // check that required param is there
      {
        char temp[12];
        sprintf(temp,"\\%i",iOptional);
        std::string szParam = reg.GetReplaceString(temp);
        CRegExp reg2;
        reg2.RegComp("(.*)(\\\\\\(.*\\\\2.*)\\\\\\)(.*)");
        int i2=reg2.RegFind(strCurOutput.c_str());
        while (i2 > -1)
        {
          std::string szRemove(reg2.GetMatch(2));
          int iRemove = szRemove.size();
          int i3 = strCurOutput.find(szRemove);
          if (!szParam.empty())
          {
            strCurOutput.erase(i3+iRemove,2);
            strCurOutput.erase(i3,2);
          }
          else
            strCurOutput.replace(strCurOutput.begin()+i3,strCurOutput.begin()+i3+iRemove+2,"");

          i2 = reg2.RegFind(strCurOutput.c_str());
        }
      }

      int iLen = reg.GetFindLen();
      // nasty hack #1 - & means \0 in a replace string
      StringUtils::Replace(strCurOutput, "&","!!!AMPAMP!!!");
      std::string result = reg.GetReplaceString(strCurOutput.c_str());
      if (!result.empty())
      {
        std::string strResult(result);
        StringUtils::Replace(strResult, "!!!AMPAMP!!!","&");
        Clean(strResult);
        ReplaceBuffers(strResult);
        if (iCompare > -1)
        {
          std::string strResultNoCase = strResult;
          StringUtils::ToLower(strResultNoCase);
          if (strResultNoCase.find(m_param[iCompare-1]) != std::string::npos)
            dest += strResult;
        }
        else
          dest += strResult;
      }
      if (bRepeat && iLen > 0)
      {
        curInput.erase(0,i+iLen>(int)curInput.size()?curInput.size():i+iLen);
        i = reg.RegFind(curInput.c_str());
      }
      else
        i = -1;
    }
  }
}