XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements)
{
    XmlElement* node = nullptr;

    skipNextWhiteSpace();
    if (outOfData)
        return nullptr;

    if (*input == '<')
    {
        ++input;
        String::CharPointerType endOfToken (XmlIdentifierChars::findEndOfToken (input));

        if (endOfToken == input)
        {
            // no tag name - but allow for a gap after the '<' before giving an error
            skipNextWhiteSpace();
            endOfToken = XmlIdentifierChars::findEndOfToken (input);

            if (endOfToken == input)
            {
                setLastError ("tag name missing", false);
                return node;
            }
        }

        node = new XmlElement (input, endOfToken);
        input = endOfToken;
        LinkedListPointer<XmlElement::XmlAttributeNode>::Appender attributeAppender (node->attributes);

        // look for attributes
        for (;;)
        {
            skipNextWhiteSpace();

            const juce_wchar c = *input;

            // empty tag..
            if (c == '/' && input[1] == '>')
            {
                input += 2;
                break;
            }

            // parse the guts of the element..
            if (c == '>')
            {
                ++input;

                if (alsoParseSubElements)
                    readChildElements (*node);

                break;
            }

            // get an attribute..
            if (XmlIdentifierChars::isIdentifierChar (c))
            {
                String::CharPointerType attNameEnd (XmlIdentifierChars::findEndOfToken (input));

                if (attNameEnd != input)
                {
                    const String::CharPointerType attNameStart (input);
                    input = attNameEnd;

                    skipNextWhiteSpace();

                    if (readNextChar() == '=')
                    {
                        skipNextWhiteSpace();

                        const juce_wchar nextChar = *input;

                        if (nextChar == '"' || nextChar == '\'')
                        {
                            XmlElement::XmlAttributeNode* const newAtt
                                = new XmlElement::XmlAttributeNode (attNameStart, attNameEnd);

                            readQuotedString (newAtt->value);
                            attributeAppender.append (newAtt);
                            continue;
                        }
                    }
                    else
                    {
                        setLastError ("expected '=' after attribute '"
                                        + String (attNameStart, attNameEnd) + "'", false);
                        return node;
                    }
                }
            }
            else
            {
                if (! outOfData)
                    setLastError ("illegal character found in " + node->getTagName() + ": '" + c + "'", false);
            }

            break;
        }
    }

    return node;
}
/**
*  @brief
*    Constructor
*/
PLSceneTexture::PLSceneTexture(PLScene &cScene, const String &sName, bool bNormalMap_xGxR) :
	m_pScene(&cScene),
	m_sName(sName),
	m_nReferenceCount(0)
{
	// Cut of the path of the map name - if there's one
	String sAbsBitmapFilename = m_sName;

	// Get the texture name
	m_sName = sName;

	// Check options
	if (g_SEOptions.bCopyTextures) {
		// Can we use the given absolute filename?
		HANDLE hFile = CreateFileW(sAbsBitmapFilename.GetUnicode(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
		if (hFile == INVALID_HANDLE_VALUE) {
			// Get the current path of the loaded 3ds Max scene
			String sCurFilePath = Url(GetCOREInterface()->GetCurFilePath().data()).CutFilename();
			if (sCurFilePath.GetLength()) {
				// Compose absolute filename by just concatenating the two filenames (for relative filenames)
				String sBitmapFilename = sCurFilePath + sAbsBitmapFilename;
				hFile = CreateFileW(sBitmapFilename.GetUnicode(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
				if (hFile == INVALID_HANDLE_VALUE) {
					// Get the filename without any path information
					String sFilenameOnly  = Url(sName).GetFilename().GetASCII();

					// Compose absolute filename
					if (sFilenameOnly.GetLength()) {
						char nLastCharacter = sCurFilePath[sCurFilePath.GetLength()-1];
						if (nLastCharacter == '\\' || nLastCharacter == '/')
							sBitmapFilename = sCurFilePath + sFilenameOnly;
						else
							sBitmapFilename = sCurFilePath + "\\" + sFilenameOnly;
						hFile = CreateFileW(sBitmapFilename.GetUnicode(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
						if (hFile == INVALID_HANDLE_VALUE) {
							// Check map directories
							int nMapDirCount = TheManager->GetMapDirCount();
							for (int nMapDir=0; nMapDir<nMapDirCount; nMapDir++) {
								const String sMapDir = TheManager->GetMapDir(nMapDir);
								const uint32 nLength = sMapDir.GetLength();
								if (nLength) {
									nLastCharacter = sMapDir[nLength-1];
									if (nLastCharacter == '\\' || nLastCharacter == '/')
										sBitmapFilename = sMapDir + sFilenameOnly;
									else
										sBitmapFilename = sMapDir + '\\' + sFilenameOnly;
									hFile = CreateFileW(sBitmapFilename.GetUnicode(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
									if (hFile != INVALID_HANDLE_VALUE)
										break;
									else
										sAbsBitmapFilename = sBitmapFilename;
								}
							}
						} else {
							sAbsBitmapFilename = sBitmapFilename;
						}
					}
				} else {
					sAbsBitmapFilename = sBitmapFilename;
				}
			}
		}
		if (hFile != INVALID_HANDLE_VALUE) {
			// Get source file time and close it
			FILETIME sSourceCreationTime;
			FILETIME sSourceLastAccessTime;
			FILETIME sSourceLastWriteTime;
			GetFileTime(hFile, &sSourceCreationTime, &sSourceLastAccessTime, &sSourceLastWriteTime);
			CloseHandle(hFile);

			// Cut of the filename
			String sFilename = Url(g_SEOptions.sFilename).CutFilename();

			// Construct the absolute target filename
			uint32 nLength = sFilename.GetLength();
			if (nLength) {
				sFilename = sFilename + m_sName;

				// Is there already such a file? If yes, check the file times...
				hFile = CreateFileW(sFilename.GetUnicode(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
				if (hFile != INVALID_HANDLE_VALUE) {
					// Get target file time and close it
					FILETIME sTargetCreationTime;
					FILETIME sTargetLastAccessTime;
					FILETIME sTargetLastWriteTime;
					GetFileTime(hFile, &sTargetCreationTime, &sTargetLastAccessTime, &sTargetLastWriteTime);
					CloseHandle(hFile);

					// Compare file time
					long nResult = CompareFileTime(&sTargetLastWriteTime, &sSourceLastWriteTime);
					if (nResult >= 0)
						return; // Nothing to do :)
				}

				{ // Before we copy, we need to ensure that the target directory is there, else 'CopyFile()' will fail!
					Directory cDirectory(Url(sFilename).CutFilename());
					cDirectory.CreateRecursive();
				}

				// Copy the texture (bitmap)
				CopyFileW(sAbsBitmapFilename.GetUnicode(), sFilename.GetUnicode(), false);

				// If there's a 'plt'-file for the texture, copy it, too
				int nIndex = sFilename.LastIndexOf(".");
				if (nIndex >= 0) {
					sFilename.Delete(nIndex);
					sFilename += ".plt";
					nIndex = sAbsBitmapFilename.LastIndexOf(".");
					if (nIndex >= 0) {
						sAbsBitmapFilename.Delete(nIndex);
						sAbsBitmapFilename += ".plt";
						if (!CopyFileW(sAbsBitmapFilename.GetUnicode(), sFilename.GetUnicode(), false)) {
							// Failed to copy the 'plt'-file...
							if (bNormalMap_xGxR) {
								// Create an automatic 'plt'-file...
								// Create XML document
								XmlDocument cDocument;

								// Add declaration
								XmlDeclaration *pDeclaration = new XmlDeclaration("1.0", "ISO-8859-1", "");
								cDocument.LinkEndChild(*pDeclaration);

								// Add texture
								XmlElement *pTextureElement = new XmlElement("Texture");

								// Setup attribute
								pTextureElement->SetAttribute("Version", "1");

								// Add general
								XmlElement *pGeneralElement = new XmlElement("Node");
								pGeneralElement->SetAttribute("Compression", "DXT5_xGxR");

								// Link general element
								pTextureElement->LinkEndChild(*pGeneralElement);

								// Link material element
								cDocument.LinkEndChild(*pTextureElement);

								// Save settings
								if (cDocument.Save(sFilename))
									g_pLog->LogFLine(PLLog::Hint, "Created '%s'", sFilename.GetASCII());
								else
									g_pLog->LogFLine(PLLog::Error, "Can't create '%s'!", sFilename.GetASCII());
							}
						}
					}
				}
			}
		} else {
			g_pLog->LogFLine(PLLog::Error, "Can't find texture (bitmap) '%s'!", m_sName.GetASCII());
		}
	}
}
bool OwlNestSettings::downloadFromServer(CommandID commandID) {
    String nodeString, optionString, warningString;
    PropertySet* props = ApplicationConfiguration::getApplicationProperties();
    switch (commandID){
    case ApplicationCommands::checkForFirmwareUpdates:
      warningString = "Beware that this procedure can make your OWL unresponsive!";
      nodeString = "firmwares";
      optionString = props->getValue("firmware-dfu-options");
      break;
    case ApplicationCommands::checkForBootloaderUpdates:
      warningString = "Beware that this procedure can brick your OWL!";
      nodeString = "bootloaders";
      optionString = props->getValue("bootloader-dfu-options");
      break;
    default:
      return false;
    }
    
    String xmlFilename ("updates.xml");
    URL url(props->getValue("owl-updates-dir-url")+xmlFilename);
    ScopedPointer<XmlElement> xmlUpdates;
    if(url.isWellFormed())
      xmlUpdates = url.readEntireXmlStream(0);
    if(xmlUpdates == NULL) {
      AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Connection Error", "Server connection failed");
      return false;
    }
    XmlElement* filesNode = xmlUpdates->getChildByName(nodeString);
    StringArray names;
    XmlElement* child = filesNode->getFirstChildElement();
    while(child != nullptr){
      names.add(child->getStringAttribute("name"));
      child = child->getNextElement();
    }
    AlertWindow popup("Download File From Server", "Choose file:", juce::AlertWindow::InfoIcon);
    popup.addButton("Cancel", 0, juce::KeyPress(), juce::KeyPress());
    popup.addButton("Download", 1, juce::KeyPress(), juce::KeyPress());
    popup.addComboBox("box", names);
    if(popup.runModalLoop()==0)
      return false;
    popup.setVisible(false);
    String selectedFilename(popup.getComboBoxComponent("box")->getText());
    URL fwUrl(props->getValue("owl-updates-dir-url")+selectedFilename);
    ScopedPointer<InputStream> strm;
    strm = fwUrl.createInputStream(0);
    if(strm == NULL){
      AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Connection Error", "File unavailable", "Continue");
      return false;
    }
    File theTargetFile(ApplicationConfiguration::getApplicationDirectory().getChildFile(selectedFilename));
    FileChooser chooser("Save As", theTargetFile, "*.bin");
    bool succeeded = false;
    if(!chooser.browseForFileToSave(true))
      return false;
    theTargetFile = chooser.getResult();
    TemporaryFile temp (theTargetFile);
    ScopedPointer<FileOutputStream> out(temp.getFile().createOutputStream());
    if(out != nullptr) {
      out->writeFromInputStream(*strm, strm->getTotalLength());
      out = nullptr; // deletes the stream
      succeeded = temp.overwriteTargetFileWithTemporary();
    }
    if(!succeeded){
      AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "File Error", "Failed to save file", "Continue");
      return false;
    }
    if(AlertWindow::showOkCancelBox(AlertWindow::QuestionIcon, "Update Device", 
				    "Would you like to update your OWL with this binary now? "+warningString, "Yes", "No"))
    {
        DBG("pathName"<< theTargetFile.getFullPathName());
        DBG("optionString " << optionString);
        return deviceFirmwareUpdate(theTargetFile, optionString);
    }
    return true;
}
void FlowData::load()
{
	if(!mReady)
	{
		Timer timer(true);
		
		XmlDocument * pointsDoc = new XmlDocument(dataSource);
		XmlElement rootNode = pointsDoc->rootNode();
		
		if(rootNode.hasChildren())
		{
			XmlElement tagNode = rootNode.findChild("tag");
			XmlElement drawingNode = tagNode.findChild("drawing");
			
			// Now get all the drawingNode's children.. and only worry about the stroke nodes.
			if(drawingNode.hasChildren())
			{
				std::vector<XmlElement> strokeNodes = drawingNode.children();
				
				// std::vector<XmlElement> strokeNodes = rootNode.xpath("//tag/drawing//stroke");
				
				if(strokeNodes.size() > 0)
				{
					int totalPoints = 0;
					
					// Now declare some variables to reuse in our loop.
					FlowPoint lastPt(Vec2f::zero(), Vec2f::zero(), -1.f);
					
					for(std::vector<XmlElement>::iterator it = strokeNodes.begin(); it < strokeNodes.end(); it++)
					{
						XmlElement strokeNode = *it;
						
						if(strokeNode.name() == "stroke")
						{
							// Get all the point nodes.
							std::vector<XmlElement> pointNodes = strokeNode.children();
							
							// Create a new stroke 
							std::vector<FlowPoint> * stroke = new std::vector<FlowPoint>;
							
							for(std::vector<XmlElement>::iterator it2 = pointNodes.begin(); it2 < pointNodes.end(); it2++)
							{
								XmlElement ptNode = *it2;
								if(ptNode.name() == "pt")
								{
									std::string xVal = ptNode.findChild("x").value();
									// float x = fromString( xVal );
									float x = boost::lexical_cast<float>( xVal );
									
									std::string yVal = ptNode.findChild("y").value();
									// float y = fromString( yVal );
									float y = boost::lexical_cast<float>( yVal );
									
									std::string timeVal = ptNode.findChild("time").value();
									// float time = fromString( timeVal );
									float time = boost::lexical_cast<float>( timeVal );
									
									x = mRemapMinX + (mRemapMaxX - mRemapMinX) * x;
									y = mRemapMinY + (mRemapMaxY - mRemapMinY) * y;
									Vec2f pos(x, y);
									Vec2f vel;
									if(lastPt.time > -1)
									{
										vel.x = pos.x - lastPt.getX();
										vel.y = pos.y - lastPt.getY();
									}
									FlowPoint pt(pos, vel, time);
									
									bool shouldAddPoint = false;
									if(ignoreRedundantPositions == true)
									{
										if(lastPt.time > -1)
										{
											if(pt.getX() != lastPt.getX() && pt.getY() != lastPt.getY())
											{
												shouldAddPoint = true;
											}  
										}
										else
										{
											shouldAddPoint = true;
										}
									}
									else
									{
										shouldAddPoint = true;
									}
									
									if(shouldAddPoint)
									{
										totalPoints++;
										stroke->push_back(pt);
										lastPt = FlowPoint(pt.pos, pt.vel, pt.time);
									}
								}
							}
							
							// Now see if our stroke is long enough.
							if(stroke->size() > minNumberOfPointsInStroke)
							{
								mStrokes.push_back(stroke);
							}
						}
					}
					
					// We're done.
					timer.stop();
					
					
					std::cout << "FlowData :: GML file parsing complete. Elapsed seconds: " << toString( timer.getSeconds() ) << std::endl;
					std::cout << "FlowData :: Total number of points: " << totalPoints << std::endl;
					std::cout << "FlowData :: Number of strokes: " << mStrokes.size() << std::endl;
					
					if(mStrokes.size() > 0)
						mReady = true;
				}
			}
		}
	}
}
Exemple #5
0
void UIComponent::saveStateToXml(XmlElement* xml)
{
    XmlElement* uiComponentState = xml->createNewChildElement("UICOMPONENT");
    uiComponentState->setAttribute("isProcessorListOpen",processorList->isOpen());
    uiComponentState->setAttribute("isEditorViewportOpen",editorViewportButton->isOpen());
}
XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements)
{
    XmlElement* node = nullptr;

    skipNextWhiteSpace();
    if (outOfData)
        return nullptr;

    const int openBracket = input.indexOf ((juce_wchar) '<');

    if (openBracket >= 0)
    {
        input += openBracket + 1;
        int tagLen = findNextTokenLength();

        if (tagLen == 0)
        {
            // no tag name - but allow for a gap after the '<' before giving an error
            skipNextWhiteSpace();
            tagLen = findNextTokenLength();

            if (tagLen == 0)
            {
                setLastError ("tag name missing", false);
                return node;
            }
        }

        node = new XmlElement (String (input, (size_t) tagLen));
        input += tagLen;
        LinkedListPointer<XmlElement::XmlAttributeNode>::Appender attributeAppender (node->attributes);

        // look for attributes
        for (;;)
        {
            skipNextWhiteSpace();

            const juce_wchar c = *input;

            // empty tag..
            if (c == '/' && input[1] == '>')
            {
                input += 2;
                break;
            }

            // parse the guts of the element..
            if (c == '>')
            {
                ++input;

                if (alsoParseSubElements)
                    readChildElements (node);

                break;
            }

            // get an attribute..
            if (XmlIdentifierChars::isIdentifierChar (c))
            {
                const int attNameLen = findNextTokenLength();

                if (attNameLen > 0)
                {
                    const String::CharPointerType attNameStart (input);
                    input += attNameLen;

                    skipNextWhiteSpace();

                    if (readNextChar() == '=')
                    {
                        skipNextWhiteSpace();

                        const juce_wchar nextChar = *input;

                        if (nextChar == '"' || nextChar == '\'')
                        {
                            XmlElement::XmlAttributeNode* const newAtt
                                = new XmlElement::XmlAttributeNode (String (attNameStart, (size_t) attNameLen),
                                                                    String::empty);

                            readQuotedString (newAtt->value);
                            attributeAppender.append (newAtt);
                            continue;
                        }
                    }
                }
            }
            else
            {
                if (! outOfData)
                    setLastError ("illegal character found in " + node->getTagName() + ": '" + c + "'", false);
            }

            break;
        }
    }

    return node;
}
String AudioDeviceManager::initialiseFromXML (const XmlElement& xml,
                                              const bool selectDefaultDeviceOnFailure,
                                              const String& preferredDefaultDeviceName,
                                              const AudioDeviceSetup* preferredSetupOptions)
{
    lastExplicitSettings = new XmlElement (xml);

    String error;
    AudioDeviceSetup setup;

    if (preferredSetupOptions != nullptr)
        setup = *preferredSetupOptions;

    if (xml.getStringAttribute ("audioDeviceName").isNotEmpty())
    {
        setup.inputDeviceName = setup.outputDeviceName
            = xml.getStringAttribute ("audioDeviceName");
    }
    else
    {
        setup.inputDeviceName  = xml.getStringAttribute ("audioInputDeviceName");
        setup.outputDeviceName = xml.getStringAttribute ("audioOutputDeviceName");
    }

    currentDeviceType = xml.getStringAttribute ("deviceType");

    if (findType (currentDeviceType) == nullptr)
    {
        if (AudioIODeviceType* const type = findType (setup.inputDeviceName, setup.outputDeviceName))
            currentDeviceType = type->getTypeName();
        else if (availableDeviceTypes.size() > 0)
            currentDeviceType = availableDeviceTypes.getUnchecked(0)->getTypeName();
    }

    setup.bufferSize = xml.getIntAttribute ("audioDeviceBufferSize");
    setup.sampleRate = xml.getDoubleAttribute ("audioDeviceRate");

    setup.inputChannels .parseString (xml.getStringAttribute ("audioDeviceInChans",  "11"), 2);
    setup.outputChannels.parseString (xml.getStringAttribute ("audioDeviceOutChans", "11"), 2);

    setup.useDefaultInputChannels  = ! xml.hasAttribute ("audioDeviceInChans");
    setup.useDefaultOutputChannels = ! xml.hasAttribute ("audioDeviceOutChans");

    error = setAudioDeviceSetup (setup, true);

    midiInsFromXml.clear();

    forEachXmlChildElementWithTagName (xml, c, "MIDIINPUT")
        midiInsFromXml.add (c->getStringAttribute ("name"));

    const StringArray allMidiIns (MidiInput::getDevices());

    for (int i = allMidiIns.size(); --i >= 0;)
        setMidiInputEnabled (allMidiIns[i], midiInsFromXml.contains (allMidiIns[i]));

    if (error.isNotEmpty() && selectDefaultDeviceOnFailure)
        error = initialise (numInputChansNeeded, numOutputChansNeeded,
                            nullptr, false, preferredDefaultDeviceName);

    setDefaultMidiOutput (xml.getStringAttribute ("defaultMidiOutput"));

    return error;
}
//[-------------------------------------------------------]
//[ Private virtual PLSceneNode functions                 ]
//[-------------------------------------------------------]
void PLSceneSpline::WriteToFile(XmlElement &cSceneElement, const String &sApplicationDrive, const String &sApplicationDir)
{
	// Do NOT save it as scene node, it's just a 'resource'

	// Get path filename
	const String sFilename = sApplicationDrive + sApplicationDir + PLTools::GetResourceFilename(PLTools::ResourcePath, GetName() + ".path");

	// Get the IGame spline object of the given IGame node
	IGameObject *pIGameObject = GetIGameNode()->GetIGameObject();
	if (pIGameObject) {
		// Check the type of the IGame object
		if (pIGameObject->GetIGameType() == IGameObject::IGAME_SPLINE && pIGameObject->InitializeData()) {
			IGameSpline &cIGameSpline = *static_cast<IGameSpline*>(pIGameObject);
			if (cIGameSpline.GetNumberOfSplines () > 0) {
				// We only support spline 0
				IGameSpline3D *pIGameSpline3D = cIGameSpline.GetIGameSpline3D(0);
				if (pIGameSpline3D) {
					// Get the local transform matrix
					GMatrix mTransform = cIGameSpline.GetIGameObjectTM();

					// Get the 3ds Max shape object
					ShapeObject *pMaxShapeObject = static_cast<ShapeObject*>(pIGameObject->GetMaxObject()->ConvertToType(TIME_PosInfinity, Class_ID(GENERIC_SHAPE_CLASS_ID, 0)));
					if (pMaxShapeObject != nullptr && pMaxShapeObject->NumberOfCurves() == cIGameSpline.GetNumberOfSplines()) {
						// Create XML document
						XmlDocument cDocument;

						// Add declaration
						XmlDeclaration *pDeclaration = new XmlDeclaration("1.0", "ISO-8859-1", "");
						cDocument.LinkEndChild(*pDeclaration);

						// Add path
						XmlElement *pPathElement = new XmlElement("Path");

						// Setup attributes
						pPathElement->SetAttribute("Version", "1");
						pPathElement->SetAttribute("Closed",  String::Format("%d", pMaxShapeObject->CurveClosed(0, 0)));

						// Add all nodes
						for (int nKnot=0; nKnot<pIGameSpline3D->GetIGameKnotCount(); nKnot++) {
							IGameKnot *pIGameKnot = pIGameSpline3D->GetIGameKnot(nKnot);
							if (pIGameKnot) {
								// Get knot point in object space (although it is not documented it looks like object space...)
								Point3 cPoint = pIGameKnot->GetKnotPoint();

								// We really need to flip the coordinates to OpenGL style, IGame is not doing this automatically...
								cPoint = PLTools::Convert3dsMaxVectorToOpenGLVector(cPoint);

								// Transform to world space
								cPoint = cPoint*mTransform;

								// If there's a parent container, make the position of this scene node relative to it
								PLSceneContainer *pContainer = GetContainer();
								if (pContainer)
									cPoint -= pContainer->GetWorldSpaceCenter();

								// Add node
								XmlElement *pNodeElement = new XmlElement("Node");
								pNodeElement->SetAttribute("Name",     String::Format("%d",       nKnot));
								pNodeElement->SetAttribute("Position", String::Format("%f %f %f", cPoint.x, cPoint.y, cPoint.z));

								// Link general element
								pPathElement->LinkEndChild(*pNodeElement);
							}
						}

						// Link material element
						cDocument.LinkEndChild(*pPathElement);

						// Save settings
						if (cDocument.Save(sFilename))
							g_pLog->LogFLine(PLLog::Hint, "Created '%s'", sFilename.GetASCII());
						else
							g_pLog->LogFLine(PLLog::Error, "Can't create '%s'!", sFilename.GetASCII());
					}
				}
			}
		} else {
			g_pLog->LogFLine(PLLog::Error, "%s: IGame object is no known spline object!", GetIGameNode()->GetName());
		}

		// Release the IGame object
		GetIGameNode()->ReleaseIGameObject();
	} else {
		g_pLog->LogFLine(PLLog::Error, "%s: IGame node has no IGame object!", GetIGameNode()->GetName());
	}
}
void DemoJuceFilter::getStateInformation (MemoryBlock& destData)
{
    XmlElement xmlState (T("MYPLUGINSETTINGS"));
    xmlState.setAttribute (T("pluginVersion"), 1);
    copyXmlToBinary (xmlState, destData);
}
void MLPluginProcessor::setStateFromXML(const XmlElement& xmlState, bool setViewAttributes)
{
	if (!(xmlState.hasTagName (JucePlugin_Name))) return;
	if (!(mEngine.getCompileStatus() == MLProc::OK)) return; // TODO revisit need to compile first
	
	// only the differences between default parameters and the program state are saved in an XML program,
	// so the first step is to set the default parameters.
	setDefaultParameters();
	
	// get program version of saved state
	unsigned blobVersion = xmlState.getIntAttribute ("pluginVersion");
	unsigned pluginVersion = JucePlugin_VersionCode;
	
	if (blobVersion > pluginVersion)
	{
		// TODO show error to user
		MLError() << "MLPluginProcessor::setStateFromXML: saved program version is newer than plugin version!\n";
		return;
	}
    
	// try to load scale if a scale attribute exists
    // TODO auto save all state including this
 	const String scaleDir = xmlState.getStringAttribute ("scaleDir"); // look for old-style dir attribute
	const String scaleName = xmlState.getStringAttribute ("scaleName");
    String fullName;
    if(scaleName != String::empty)
    {
        fullName = scaleName;
        if(scaleDir != String::empty)
        {
            fullName = scaleDir + String("/") + fullName + ".scl";
        }
    }
    else
    {
        fullName = "12-equal";
    }
    std::string fullScaleName(fullName.toUTF8());
	setProperty("key_scale", fullScaleName);
	
	// get preset name saved in blob.  when saving from AU host, name will also be set from RestoreState().
	const String presetName = xmlState.getStringAttribute ("presetName");
	setProperty("preset", std::string(presetName.toUTF8()));
    
	/*
     debug() << "MLPluginProcessor: setStateFromXML: loading program " << presetName << ", version " << std::hex << blobVersion << std::dec << "\n";
     MemoryOutputStream myStream;
     xmlState->writeToStream (myStream, "");
     debug() << myStream.toString();
     */
	
	// get plugin-specific translation table for updating older versions of data
	std::map<MLSymbol, MLSymbol> translationTable;
	
	// TODO move this into Aalto!
	// make translation tables based on program version.
	//
	if (blobVersion <= 0x00010120)
	{
		// translate seq parameters
		for(unsigned n=0; n<16; ++n)
		{
			std::stringstream pName;
			std::stringstream pName2;
			pName << "seq_value" << n;
			pName2 << "seq_pulse" << n;
			MLSymbol oldSym(pName.str());
			MLSymbol newSym = MLSymbol("seq_value#").withFinalNumber(n);
			MLSymbol oldSym2(pName2.str());
			MLSymbol newSym2 = MLSymbol("seq_pulse#").withFinalNumber(n);
			translationTable[oldSym] = newSym;
			translationTable[oldSym2] = newSym2;
		}
	}
	
	if (blobVersion <= 0x00010200)
	{
		MLSymbol oldSym = MLSymbol("seq_value");
		MLSymbol newSym = MLSymbol("seq_value").withFinalNumber(0);
		MLSymbol oldSym2 = MLSymbol("seq_pulse");
		MLSymbol newSym2 = MLSymbol("seq_pulse").withFinalNumber(0);
		translationTable[oldSym] = newSym;
		translationTable[oldSym2] = newSym2;
		
		// translate seq parameters
		for(unsigned n=1; n<16; ++n)
		{
			oldSym = MLSymbol("seq_value#").withFinalNumber(n);
			newSym = MLSymbol("seq_value").withFinalNumber(n);
			oldSym2 = MLSymbol("seq_pulse#").withFinalNumber(n);
			newSym2 = MLSymbol("seq_pulse").withFinalNumber(n);
			translationTable[oldSym] = newSym;
			translationTable[oldSym2] = newSym2;
		}
	}
	
	// get patcher matrix from old-style input params
	String patcherInputStr ("patcher_input_");
	
	// get params from xml
	const unsigned numAttrs = xmlState.getNumAttributes();
	
	for(unsigned i=0; i<numAttrs; ++i)
	{
		// get name / value pair.
		const String& attrName = xmlState.getAttributeName(i);
		const MLParamValue paramVal = xmlState.getDoubleAttribute(attrName);
		
		// if not a patcher input setting,
		if (!attrName.contains(patcherInputStr))
		{
			// see if we have this named parameter in our engine.
			MLSymbol paramSym = XMLAttrToSymbol(attrName);
			const int pIdx = getParameterIndex(paramSym);
			
			if (pIdx >= 0)
			{
				// debug() << "setStateFromXML: <" << paramSym << " = " << paramVal << ">\n";
				setProperty(paramSym, paramVal);
			}
			else // try finding a match through translation table.
			{
				//debug() << "Looking for parameter " << paramSym << " in table...\n";
				std::map<MLSymbol, MLSymbol>::iterator it;
				it = translationTable.find(paramSym);
				if (it != translationTable.end())
				{
					const MLSymbol newSym = translationTable[paramSym];
					const int pNewIdx = getParameterIndex(newSym);
					if (pNewIdx >= 0)
					{
						//debug() << "translated parameter to " << newSym << " .\n";
						setProperty(newSym, paramVal);
					}
					else
					{
						MLError() << "MLPluginProcessor::setStateFromXML: no such parameter! \n";
					}
				}
				else
				{
					// fail silently on unfound params, because we have deprecated some but they may still
					// be around in old presets.
					//debug() << "MLPluginProcessor::setStateFromXML: parameter " << paramSym << " not found!\n";
				}
			}
		}
	}
	
	// get editor state from XML
    if(setViewAttributes)
	{
		int x = xmlState.getIntAttribute("editor_x");
		int y = xmlState.getIntAttribute("editor_y");
		int width = xmlState.getIntAttribute("editor_width");
		int height = xmlState.getIntAttribute("editor_height");
		mEditorRect = MLRect(x, y, width, height);
		mEditorNumbersOn = xmlState.getIntAttribute("editor_num", 1);
		mEditorAnimationsOn = xmlState.getIntAttribute("editor_anim", 1);
	}
}
bool JucerDocument::loadFromXml (const XmlElement& xml)
{
    if (xml.hasTagName (jucerCompXmlTag)
         && getTypeName().equalsIgnoreCase (xml.getStringAttribute ("documentType")))
    {
        className = xml.getStringAttribute ("className", defaultClassName);
        templateFile = xml.getStringAttribute ("template", String::empty);
        componentName = xml.getStringAttribute ("componentName", String::empty);
        parentClasses = xml.getStringAttribute ("parentClasses", defaultParentClasses);
        constructorParams = xml.getStringAttribute ("constructorParams", String::empty);
        variableInitialisers = xml.getStringAttribute ("variableInitialisers", String::empty);

        fixedSize = xml.getBoolAttribute ("fixedSize", false);
        initialWidth = xml.getIntAttribute ("initialWidth", 300);
        initialHeight = xml.getIntAttribute ("initialHeight", 200);

        snapGridPixels = xml.getIntAttribute ("snapPixels", snapGridPixels);
        snapActive = xml.getBoolAttribute ("snapActive", snapActive);
        snapShown = xml.getBoolAttribute ("snapShown", snapShown);

        componentOverlayOpacity = (float) xml.getDoubleAttribute ("overlayOpacity", 0.0);

        activeExtraMethods.clear();

        if (XmlElement* const methods = xml.getChildByName ("METHODS"))
            forEachXmlChildElementWithTagName (*methods, e, "METHOD")
                activeExtraMethods.addIfNotAlreadyThere (e->getStringAttribute ("name"));

        activeExtraMethods.trim();
        activeExtraMethods.removeEmptyStrings();

        changed();
        getUndoManager().clearUndoHistory();
        return true;
    }

    return false;
}
XmlElement* JucerDocument::createXml() const
{
    XmlElement* doc = new XmlElement (jucerCompXmlTag);

    doc->setAttribute ("documentType", getTypeName());
    doc->setAttribute ("className", className);

    if (templateFile.trim().isNotEmpty())
        doc->setAttribute ("template", templateFile);

    doc->setAttribute ("componentName", componentName);
    doc->setAttribute ("parentClasses", parentClasses);
    doc->setAttribute ("constructorParams", constructorParams);
    doc->setAttribute ("variableInitialisers", variableInitialisers);
    doc->setAttribute ("snapPixels", snapGridPixels);
    doc->setAttribute ("snapActive", snapActive);
    doc->setAttribute ("snapShown", snapShown);
    doc->setAttribute ("overlayOpacity", String (componentOverlayOpacity, 3));
    doc->setAttribute ("fixedSize", fixedSize);
    doc->setAttribute ("initialWidth", initialWidth);
    doc->setAttribute ("initialHeight", initialHeight);

    if (activeExtraMethods.size() > 0)
    {
        XmlElement* extraMethods = new XmlElement ("METHODS");
        doc->addChildElement (extraMethods);

        for (int i = 0; i < activeExtraMethods.size(); ++i)
        {
            XmlElement* e = new XmlElement ("METHOD");
            extraMethods ->addChildElement (e);
            e->setAttribute ("name", activeExtraMethods[i]);
        }
    }

    return doc;
}