コード例 #1
0
ファイル: llxuiparser.cpp プロジェクト: HyangZhao/NaCl-main
bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLInitParam::BaseBlock& block)
{
	typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
	boost::char_separator<char> sep(".");

	bool values_parsed = false;

	// submit attributes for current node
	values_parsed |= readAttributes(nodep, block);

	// treat text contents of xml node as "value" parameter
	std::string text_contents = nodep->getSanitizedValue();
	if (!text_contents.empty())
	{
		mCurReadNode = nodep;
		mNameStack.push_back(std::make_pair(std::string("value"), newParseGeneration()));
		// child nodes are not necessarily valid parameters (could be a child widget)
		// so don't complain once we've recursed
		bool silent = mCurReadDepth > 0;
		if (!block.submitValue(mNameStack, *this, true))
		{
			mNameStack.pop_back();
			block.submitValue(mNameStack, *this, silent);
		}
		else
		{
			mNameStack.pop_back();
		}
	}

	// then traverse children
	// child node must start with last name of parent node (our "scope")
	// for example: "<button><button.param nested_param1="foo"><param.nested_param2 nested_param3="bar"/></button.param></button>"
	// which equates to the following nesting:
	// button
	//     param
	//         nested_param1
	//         nested_param2
	//             nested_param3	
	mCurReadDepth++;
	for(LLXMLNodePtr childp = nodep->getFirstChild(); childp.notNull();)
	{
		std::string child_name(childp->getName()->mString);
		S32 num_tokens_pushed = 0;

		// for non "dotted" child nodes	check to see if child node maps to another widget type
		// and if not, treat as a child element of the current node
		// e.g. <button><rect left="10"/></button> will interpret <rect> as "button.rect"
		// since there is no widget named "rect"
		if (child_name.find(".") == std::string::npos) 
		{
			mNameStack.push_back(std::make_pair(child_name, newParseGeneration()));
			num_tokens_pushed++;
		}
		else
		{
			// parse out "dotted" name into individual tokens
			tokenizer name_tokens(child_name, sep);

			tokenizer::iterator name_token_it = name_tokens.begin();
			if(name_token_it == name_tokens.end()) 
			{
				childp = childp->getNextSibling();
				continue;
			}

			// check for proper nesting
			if(!scope.empty() && *name_token_it != scope)
			{
				childp = childp->getNextSibling();
				continue;
			}

			// now ignore first token
			++name_token_it; 

			// copy remaining tokens on to our running token list
			for(tokenizer::iterator token_to_push = name_token_it; token_to_push != name_tokens.end(); ++token_to_push)
			{
				mNameStack.push_back(std::make_pair(*token_to_push, newParseGeneration()));
				num_tokens_pushed++;
			}
		}

		// recurse and visit children XML nodes
		if(readXUIImpl(childp, mNameStack.empty() ? scope : mNameStack.back().first, block))
		{
			// child node successfully parsed, remove from DOM

			values_parsed = true;
			LLXMLNodePtr node_to_remove = childp;
			childp = childp->getNextSibling();

			nodep->deleteChild(node_to_remove);
		}
		else
		{
			childp = childp->getNextSibling();
		}

		while(num_tokens_pushed-- > 0)
		{
			mNameStack.pop_back();
		}
	}
	mCurReadDepth--;
	return values_parsed;
}
コード例 #2
0
//static 
void LLUICtrlFactory::copyName(LLXMLNodePtr src, LLXMLNodePtr dest)
{
	dest->setName(src->getName()->mString);
}
コード例 #3
0
bool LLNotifications::loadTemplates()
{
	const std::string xml_filename = "notifications.xml";
	LLXMLNodePtr root;
	
	BOOL success  = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
	
	if (!success || root.isNull() || !root->hasName( "notifications" ))
	{
		llerrs << "Problem reading UI Notifications file: " << xml_filename << llendl;
		return false;
	}
	
	clearTemplates();
	
	for (LLXMLNodePtr item = root->getFirstChild();
		 item.notNull(); item = item->getNextSibling())
	{
		// we do this FIRST so that item can be changed if we 
		// encounter a usetemplate -- we just replace the
		// current xml node and keep processing
		item = checkForXMLTemplate(item);
		
		if (item->hasName("global"))
		{
			std::string global_name;
			if (item->getAttributeString("name", global_name))
			{
				mGlobalStrings[global_name] = item->getTextContents();
			}
			continue;
		}
		
		if (item->hasName("template"))
		{
			// store an xml template; templates must have a single node (can contain
			// other nodes)
			std::string name;
			item->getAttributeString("name", name);
			LLXMLNodePtr ptr = item->getFirstChild();
			mXmlTemplates[name] = ptr;
			continue;
		}
		
		if (!item->hasName("notification"))
		{
            llwarns << "Unexpected entity " << item->getName()->mString << 
                       " found in " << xml_filename << llendl;
			continue;
		}
		
		// now we know we have a notification entry, so let's build it
		LLNotificationTemplatePtr pTemplate(new LLNotificationTemplate());

		if (!item->getAttributeString("name", pTemplate->mName))
		{
			llwarns << "Unable to parse notification with no name" << llendl;
			continue;
		}
		
		LL_DEBUGS("Notifications") << "Parsing " << pTemplate->mName << LL_ENDL;
		
		pTemplate->mMessage = item->getTextContents();
		pTemplate->mDefaultFunctor = pTemplate->mName;
		item->getAttributeString("type", pTemplate->mType);
		item->getAttributeString("icon", pTemplate->mIcon);
		item->getAttributeString("label", pTemplate->mLabel);
		item->getAttributeU32("duration", pTemplate->mExpireSeconds);
		item->getAttributeU32("expireOption", pTemplate->mExpireOption);

		std::string priority;
		item->getAttributeString("priority", priority);
		pTemplate->mPriority = NOTIFICATION_PRIORITY_NORMAL;
		if (!priority.empty())
		{
			if (priority == "low")      pTemplate->mPriority = NOTIFICATION_PRIORITY_LOW;
			if (priority == "normal")   pTemplate->mPriority = NOTIFICATION_PRIORITY_NORMAL;
			if (priority == "high")     pTemplate->mPriority = NOTIFICATION_PRIORITY_HIGH;
			if (priority == "critical") pTemplate->mPriority = NOTIFICATION_PRIORITY_CRITICAL;
		}
		
		item->getAttributeString("functor", pTemplate->mDefaultFunctor);

		BOOL persist = false;
		item->getAttributeBOOL("persist", persist);
		pTemplate->mPersist = persist;
		
		std::string sound;
		item->getAttributeString("sound", sound);
		if (!sound.empty())
		{
			// TODO: test for bad sound effect name / missing effect
			pTemplate->mSoundEffect = LLUUID(LLUI::sConfigGroup->getString(sound.c_str()));
		}

		for (LLXMLNodePtr child = item->getFirstChild();
			 !child.isNull(); child = child->getNextSibling())
		{
			child = checkForXMLTemplate(child);
			
			// <url>
			if (child->hasName("url"))
			{
				pTemplate->mURL = child->getTextContents();
				child->getAttributeU32("option", pTemplate->mURLOption);
			}
			
            if (child->hasName("unique"))
            {
                pTemplate->mUnique = true;
                for (LLXMLNodePtr formitem = child->getFirstChild();
                     !formitem.isNull(); formitem = formitem->getNextSibling())
                {
                    if (formitem->hasName("context"))
                    {
                        std::string key;
                        formitem->getAttributeString("key", key);
                        pTemplate->mUniqueContext.push_back(key);
                        //llwarns << "adding " << key << " to unique context" << llendl;
                    }
                    else
                    {
                        llwarns << "'unique' has unrecognized subelement " 
                        << formitem->getName()->mString << llendl;
                    }
                }
            }
            
			// <form>
			if (child->hasName("form"))
			{
                pTemplate->mForm = LLNotificationFormPtr(new LLNotificationForm(pTemplate->mName, child));
			}
		}
		addTemplate(pTemplate->mName, pTemplate);
	}
	
	//std::ostringstream ostream;
	//root->writeToOstream(ostream, "\n  ");
	//llwarns << ostream.str() << llendl;
	
	return true;
}
コード例 #4
0
void LLUICtrl::initFromXML(LLXMLNodePtr node, LLView* parent)
{
	std::string name;
	if(node->getAttributeString("name", name))
		setName(name);

	BOOL has_tab_stop = hasTabStop();
	node->getAttributeBOOL("tab_stop", has_tab_stop);

	setTabStop(has_tab_stop);

	node->getAttributeBOOL("requests_front", mRequestsFront);

	std::string str = node->getName()->mString;
	std::string attrib_str;
	LLXMLNodePtr child_node;

	//Since so many other callback 'types' piggyback off of the commitcallback registrar as well as use the same callback signature
	//we can assemble a nice little static list to iterate down instead of copy-pasting mostly similar code for each instance.
	//Validate/enable callbacks differ, as it uses its own registry/callback signature. This could be worked around with a template, but keeping
	//all the code local to this scope is more beneficial.
	typedef boost::signals2::connection (LLUICtrl::*commit_fn)( const commit_signal_t::slot_type& cb );
	static std::pair<std::string,commit_fn> sCallbackRegistryMap[3] = 
	{
		std::pair<std::string,commit_fn>(".commit_callback",&LLUICtrl::setCommitCallback),
		std::pair<std::string,commit_fn>(".mouseenter_callback",&LLUICtrl::setMouseEnterCallback),
		std::pair<std::string,commit_fn>(".mouseleave_callback",&LLUICtrl::setMouseLeaveCallback)
	};
	for(S32 i= 0; i < sizeof(sCallbackRegistryMap)/sizeof(sCallbackRegistryMap[0]);++i)
	{
		if(node->getChild((str+sCallbackRegistryMap[i].first).c_str(),child_node,false))
		{
			if(child_node->getAttributeString("function",attrib_str))
			{
				commit_callback_t* func = (CommitCallbackRegistry::getValue(attrib_str));
				if (func)
				{
					if(child_node->getAttributeString("parameter",attrib_str))
						(this->*sCallbackRegistryMap[i].second)(boost::bind((*func), this, LLSD(attrib_str)));
					else
						(this->*sCallbackRegistryMap[i].second)(commit_signal_t::slot_type(*func));
				}
			}
		}
	}

	if(node->getChild((str+".validate_callback").c_str(),child_node,false))
	{
		if(child_node->getAttributeString("function",attrib_str))
		{
			enable_callback_t* func = (EnableCallbackRegistry::getValue(attrib_str));
			if (func)
			{
				if(child_node->getAttributeString("parameter",attrib_str))
					setValidateCallback(boost::bind((*func), this, LLSD(attrib_str)));
				else
					setValidateCallback(enable_signal_t::slot_type(*func));
			}
		}
	}
	LLView::initFromXML(node, parent);
	
	if (node->getAttributeString("enabled_control", attrib_str))
	{
		LLControlVariable* control = findControl(attrib_str);
		if (control)
			setEnabledControlVariable(control);
	}

	if (node->getAttributeString("disabled_control", attrib_str))
	{
		LLControlVariable* control = findControl(attrib_str);
		if (control)
			setDisabledControlVariable(control);
	}

	if(node->getAttributeString("visibility_control",attrib_str) || node->getAttributeString("visiblity_control",attrib_str))
	{
		LLControlVariable* control = findControl(attrib_str);
		if (control)
			setMakeVisibleControlVariable(control);
	}
	if(node->getAttributeString("invisibility_control",attrib_str) || node->getAttributeString("invisiblity_control",attrib_str))
	{
		LLControlVariable* control = findControl(attrib_str);
		if (control)
			setMakeInvisibleControlVariable(control);
	}
}
コード例 #5
0
ファイル: llpanel.cpp プロジェクト: OS-Development/VW.Kirsten
BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node, const LLPanel::Params& default_params)
{
	Params params(default_params);
	{
		LLFastTimer timer(FTM_PANEL_SETUP);

		LLXMLNodePtr referenced_xml;
		std::string xml_filename = mXMLFilename;
		
		// if the panel didn't provide a filename, check the node
		if (xml_filename.empty())
		{
			node->getAttributeString("filename", xml_filename);
			setXMLFilename(xml_filename);
		}

		LLXUIParser parser;

		if (!xml_filename.empty())
		{
			LLUICtrlFactory::instance().pushFileName(xml_filename);

			LLFastTimer timer(FTM_EXTERNAL_PANEL_LOAD);
			if (output_node)
			{
				//if we are exporting, we want to export the current xml
				//not the referenced xml
				parser.readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName());
				Params output_params(params);
				setupParamsForExport(output_params, parent);
				output_node->setName(node->getName()->mString);
				parser.writeXUI(output_node, output_params, &default_params);
				return TRUE;
			}
		
			if (!LLUICtrlFactory::getLayeredXMLNode(xml_filename, referenced_xml))
			{
				llwarns << "Couldn't parse panel from: " << xml_filename << llendl;

				return FALSE;
			}

			parser.readXUI(referenced_xml, params, LLUICtrlFactory::getInstance()->getCurFileName());

			// add children using dimensions from referenced xml for consistent layout
			setShape(params.rect);
			LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instance());

			LLUICtrlFactory::instance().popFileName();
		}

		// ask LLUICtrlFactory for filename, since xml_filename might be empty
		parser.readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName());

		if (output_node)
		{
			Params output_params(params);
			setupParamsForExport(output_params, parent);
			output_node->setName(node->getName()->mString);
			parser.writeXUI(output_node, output_params, &default_params);
		}
		
		params.from_xui = true;
		applyXUILayout(params, parent);
		{
			LLFastTimer timer(FTM_PANEL_CONSTRUCTION);
			initFromParams(params);
		}

		// add children
		LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node);

		// Connect to parent after children are built, because tab containers
		// do a reshape() on their child panels, which requires that the children
		// be built/added. JC
		if (parent)
		{
			S32 tab_group = params.tab_group.isProvided() ? params.tab_group() : parent->getLastTabGroup();
			parent->addChild(this, tab_group);
		}

		{
			LLFastTimer timer(FTM_PANEL_POSTBUILD);
			postBuild();
		}
	}
	return TRUE;
}