コード例 #1
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;
		}
		
		//llinfos << "Parsing " << pTemplate->mName << llendl;
		
		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;
}
コード例 #2
0
LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
{
	std::string name("name_list");
	node->getAttributeString("name", name);

	LLRect rect;
	createRect(node, rect, parent, LLRect());

	BOOL multi_select = FALSE;
	node->getAttributeBOOL("multi_select", multi_select);

	BOOL draw_border = TRUE;
	node->getAttributeBOOL("draw_border", draw_border);

	BOOL draw_heading = FALSE;
	node->getAttributeBOOL("draw_heading", draw_heading);

	S32 name_column_index = 0;
	node->getAttributeS32("name_column_index", name_column_index);

	LLUICtrlCallback callback = NULL;

	LLNameListCtrl* name_list = new LLNameListCtrl(name,
				   rect,
				   callback,
				   NULL,
				   multi_select,
				   draw_border,
				   name_column_index);

	name_list->setDisplayHeading(draw_heading);
	if (node->hasAttribute("heading_height"))
	{
		S32 heading_height;
		node->getAttributeS32("heading_height", heading_height);
		name_list->setHeadingHeight(heading_height);
	}

	BOOL allow_calling_card_drop = FALSE;
	if (node->getAttributeBOOL("allow_calling_card_drop", allow_calling_card_drop))
	{
		name_list->setAllowCallingCardDrop(allow_calling_card_drop);
	}

	name_list->setScrollListParameters(node);

	name_list->initFromXML(node, parent);

	LLSD columns;
	S32 index = 0;
	S32 total_static = 0;
	LLXMLNodePtr child;
	for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
	{
		if (child->hasName("column"))
		{
			std::string labelname("");
			child->getAttributeString("label", labelname);

			std::string columnname(labelname);
			child->getAttributeString("name", columnname);

			BOOL columndynamicwidth = FALSE;
			child->getAttributeBOOL("dynamicwidth", columndynamicwidth);

			std::string sortname(columnname);
			child->getAttributeString("sort", sortname);
		
			S32 columnwidth = -1;
			if (child->hasAttribute("relwidth"))
			{
				F32 columnrelwidth = 0.f;
				child->getAttributeF32("relwidth", columnrelwidth);
				columns[index]["relwidth"] = columnrelwidth;
			}
			else
			{
				child->getAttributeS32("width", columnwidth);
				columns[index]["width"] = columnwidth;
			}

			LLFontGL::HAlign h_align = LLFontGL::LEFT;
			h_align = LLView::selectFontHAlign(child);

			if(!columndynamicwidth) total_static += llmax(0, columnwidth);

			columns[index]["name"] = columnname;
			columns[index]["label"] = labelname;
			columns[index]["halign"] = (S32)h_align;
			columns[index]["dynamicwidth"] = columndynamicwidth;
			columns[index]["sort"] = sortname;

			index++;
		}
	}
	name_list->setTotalStaticColumnWidth(total_static);
	name_list->setColumnHeadings(columns);


	for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
	{
		if (child->hasName("row"))
		{
			LLUUID id;
			child->getAttributeUUID("id", id);

			LLSD row;

			row["id"] = id;

			S32 column_idx = 0;
			LLXMLNodePtr row_child;
			for (row_child = node->getFirstChild(); row_child.notNull(); row_child = row_child->getNextSibling())
			{
				if (row_child->hasName("column"))
				{
					std::string value = row_child->getTextContents();

					std::string columnname("");
					row_child->getAttributeString("name", columnname);

					std::string font("");
					row_child->getAttributeString("font", font);

					std::string font_style("");
					row_child->getAttributeString("font-style", font_style);

					row["columns"][column_idx]["column"] = columnname;
					row["columns"][column_idx]["value"] = value;
					row["columns"][column_idx]["font"] = font;
					row["columns"][column_idx]["font-style"] = font_style;
					column_idx++;
				}
			}
			name_list->addElement(row);
		}
	}

	std::string contents = node->getTextContents();

	typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
	boost::char_separator<char> sep("\t\n");
	tokenizer tokens(contents, sep);
	tokenizer::iterator token_iter = tokens.begin();

	while(token_iter != tokens.end())
	{
		const std::string& line = *token_iter;
		name_list->addCommentText(line);
		++token_iter;
	}

	return name_list;
}
コード例 #3
0
ファイル: llcombobox.cpp プロジェクト: VirtualReality/Viewer
// static
LLView* LLComboBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
{
	std::string name("combo_box");
	node->getAttributeString("name", name);

	std::string label("");
	node->getAttributeString("label", label);

	LLRect rect;
	createRect(node, rect, parent, LLRect());

	BOOL allow_text_entry = FALSE;
	node->getAttributeBOOL("allow_text_entry", allow_text_entry);

	S32 max_chars = 20;
	node->getAttributeS32("max_chars", max_chars);

	LLUICtrlCallback callback = NULL;

	LLComboBox* combo_box = new LLComboBox(name,
							rect, 
							label,
							callback,
							NULL);
	combo_box->setAllowTextEntry(allow_text_entry, max_chars);

	combo_box->initFromXML(node, parent);

	const std::string& contents = node->getValue();

	if (contents.find_first_not_of(" \n\t") != contents.npos)
	{
		llerrs << "Legacy combo box item format used! Please convert to <combo_item> tags!" << llendl;
	}
	else
	{
		LLXMLNodePtr child;
		for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
		{
			if (child->hasName("combo_item"))
			{
				std::string label = child->getTextContents();

				std::string value = label;
				child->getAttributeString("value", value);
				
				LLScrollListItem * item=combo_box->add(label, LLSD(value) );
				
				if(item && child->hasAttribute("tool_tip"))
				{
					std::string tool_tip = label;
					child->getAttributeString("tool_tip", tool_tip);
					item->setToolTip(tool_tip);
				}
			}
		}
	}

	// if providing user text entry or descriptive label
	// don't select an item under the hood
	if (!combo_box->acceptsTextInput() && combo_box->mLabel.empty())
	{
		combo_box->selectFirstItem();
	}

	return combo_box;
}
コード例 #4
0
ファイル: llpanel.cpp プロジェクト: otwstephanie/hpa2oar
BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)
{
	const LLPanel::Params& default_params(LLUICtrlFactory::getDefaultParams<LLPanel>());
	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);
		}

		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
				LLXUIParser::instance().readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName());
				Params output_params(params);
				setupParamsForExport(output_params, parent);
				output_node->setName(node->getName()->mString);
				LLXUIParser::instance().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;
			}

			LLXUIParser::instance().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
		LLXUIParser::instance().readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName());

		if (output_node)
		{
			Params output_params(params);
			setupParamsForExport(output_params, parent);
			output_node->setName(node->getName()->mString);
			LLXUIParser::instance().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;
}
コード例 #5
0
ファイル: llradiogroup.cpp プロジェクト: Nora28/imprudence
// static
LLView* LLRadioGroup::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
{
	std::string name("radio_group");
	node->getAttributeString("name", name);

	U32 initial_value = 0;
	node->getAttributeU32("initial_value", initial_value);

	BOOL draw_border = TRUE;
	node->getAttributeBOOL("draw_border", draw_border);

	LLRect rect;
	createRect(node, rect, parent, LLRect());

	LLRadioGroup* radio_group = new LLRadioGroup(name, 
		rect,
		initial_value,
		NULL,
		NULL,
		draw_border);

	const std::string& contents = node->getValue();

	LLRect group_rect = radio_group->getRect();

	LLFontGL *font = LLView::selectFont(node);

	if (contents.find_first_not_of(" \n\t") != contents.npos)
	{
		// ...old school default vertical layout
		typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
		boost::char_separator<char> sep("\t\n");
		tokenizer tokens(contents, sep);
		tokenizer::iterator token_iter = tokens.begin();
	
		const S32 HPAD = 4, VPAD = 4;
		S32 cur_y = group_rect.getHeight() - VPAD;
	
		while(token_iter != tokens.end())
		{
			const std::string& line = *token_iter;
			LLRect rect(HPAD, cur_y, group_rect.getWidth() - (2 * HPAD), cur_y - 15);
			cur_y -= VPAD + 15;
			radio_group->addRadioButton(std::string("radio"), line, rect, font);
			++token_iter;
		}
		llwarns << "Legacy radio group format used! Please convert to use <radio_item> tags!" << llendl;
	}
	else
	{
		// ...per pixel layout
		LLXMLNodePtr child;
		for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
		{
			if (child->hasName("radio_item"))
			{
				LLRect item_rect;
				createRect(child, item_rect, radio_group, rect);

				std::string radioname("radio");
				child->getAttributeString("name", radioname);
				std::string item_label = child->getTextContents();
				LLRadioCtrl* radio = radio_group->addRadioButton(radioname, item_label, item_rect, font);

				radio->initFromXML(child, radio_group);
			}
		}
	}

	radio_group->initFromXML(node, parent);

	return radio_group;
}
コード例 #6
0
// static
LLView* LLTabContainer::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
{
	std::string name("tab_container");
	node->getAttributeString("name", name);

	// Figure out if we are creating a vertical or horizontal tab container.
	bool is_vertical = false;
	LLTabContainer::TabPosition tab_position = LLTabContainer::TOP;
	if (node->hasAttribute("tab_position"))
	{
		std::string tab_position_string;
		node->getAttributeString("tab_position", tab_position_string);
		LLStringUtil::toLower(tab_position_string);

		if ("top" == tab_position_string)
		{
			tab_position = LLTabContainer::TOP;
			is_vertical = false;
		}
		else if ("bottom" == tab_position_string)
		{
			tab_position = LLTabContainer::BOTTOM;
			is_vertical = false;
		}
		else if ("left" == tab_position_string)
		{
			is_vertical = true;
		}
	}
	BOOL border = FALSE;
	node->getAttributeBOOL("border", border);

	LLTabContainer*	tab_container = new LLTabContainer(name, LLRect::null, tab_position, border, is_vertical);
	
	S32 tab_min_width = tab_container->mMinTabWidth;
	if (node->hasAttribute("tab_width"))
	{
		node->getAttributeS32("tab_width", tab_min_width);
	}
	else if( node->hasAttribute("tab_min_width"))
	{
		node->getAttributeS32("tab_min_width", tab_min_width);
	}

	S32	tab_max_width = tab_container->mMaxTabWidth;
	if (node->hasAttribute("tab_max_width"))
	{
		node->getAttributeS32("tab_max_width", tab_max_width);
	}

	tab_container->setMinTabWidth(tab_min_width); 
	tab_container->setMaxTabWidth(tab_max_width); 
	
	BOOL hidden(tab_container->getTabsHidden());
	node->getAttributeBOOL("hide_tabs", hidden);
	tab_container->setTabsHidden(hidden);

	tab_container->setPanelParameters(node, parent);

	if (LLFloater::getFloaterHost())
	{
		LLFloater::getFloaterHost()->setTabContainer(tab_container);
	}

	//parent->addChild(tab_container);

	// Add all tab panels.
	LLXMLNodePtr child;
	for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
	{
		LLView *control = factory->createCtrlWidget(tab_container, child);
		if (control && control->isPanel())
		{
			LLPanel* panelp = (LLPanel*)control;
			std::string label;
			child->getAttributeString("label", label);
			if (label.empty())
			{
				label = panelp->getLabel();
			}
			BOOL placeholder = FALSE;
			child->getAttributeBOOL("placeholder", placeholder);
			tab_container->addTabPanel(panelp, label, false,
									   NULL, NULL, 0, placeholder);
		}
	}

	tab_container->selectFirstTab();

	tab_container->postBuild();

	tab_container->initButtons(); // now that we have the correct rect
	
	return tab_container;
}
コード例 #7
0
bool LLNotifications::loadNotifications()
{
	LL_INFOS() << "Reading notifications template" << LL_ENDL;
	// Passing findSkinnedFilenames(constraint=LLDir::ALL_SKINS) makes it
	// output all relevant pathnames instead of just the ones from the most
	// specific skin.
	std::vector<std::string> search_paths =
		gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", LLDir::ALL_SKINS);

	std::string base_filename = search_paths.front();
	LLXMLNodePtr root;
	BOOL success  = LLXMLNode::getLayeredXMLNode(root, search_paths);
	
	if (!success || root.isNull() || !root->hasName( "notifications" ))
	{
		LL_ERRS() << "Problem reading XML from UI Notifications file: " << base_filename << LL_ENDL;
		return false;
	}
	
	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 = LLNotificationTemplates::instance().checkForXMLTemplate(item);
		
		if (!item->hasName("notification"))
		  continue;

		// now we know we have a notification entry, so let's build it
		LLNotificationTemplatePtr pTemplate(new LLNotificationTemplate());

		if (!item->getAttributeString("name", pTemplate->mName))
		{
			LL_WARNS() << "Unable to parse notification with no name" << LL_ENDL;
			continue;
		}
		
		//LL_INFOS() << "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->findString(sound.c_str()));
		}

		for (LLXMLNodePtr child = item->getFirstChild();
			 !child.isNull(); child = child->getNextSibling())
		{
			child = LLNotificationTemplates::instance().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);
                        //LL_WARNS() << "adding " << key << " to unique context" << LL_ENDL;
                    }
                    else
                    {
                        LL_WARNS() << "'unique' has unrecognized subelement " 
                        << formitem->getName()->mString << LL_ENDL;
                    }
                }
            }
            
			// <form>
			if (child->hasName("form"))
			{
                pTemplate->mForm = LLNotificationFormPtr(new LLNotificationForm(pTemplate->mName, child));
			}
		}
		LLNotificationTemplates::instance().addTemplate(pTemplate->mName, pTemplate);
	}
	
	//std::ostringstream ostream;
	//root->writeToOstream(ostream, "\n  ");
	//LL_WARNS() << ostream.str() << LL_ENDL;
	
	return true;
}
コード例 #8
0
ファイル: llxuiparser.cpp プロジェクト: HyangZhao/NaCl-main
void LLXSDWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values)
{
	name_stack_t non_empty_names;
	std::string attribute_name;
	for (name_stack_t::const_iterator it = stack.begin();
		it != stack.end();
		++it)
	{
		const std::string& name = it->first;
		if (!name.empty())
		{
			non_empty_names.push_back(*it);
		}
	}

	for (name_stack_t::const_iterator it = non_empty_names.begin();
		it != non_empty_names.end();
		++it)
	{
		if (!attribute_name.empty())
		{
			attribute_name += ".";
		}
		attribute_name += it->first;
	}

	// only flag non-nested attributes as mandatory, nested attributes have variant syntax
	// that can't be properly constrained in XSD
	// e.g. <foo mandatory.value="bar"/> vs <foo><mandatory value="bar"/></foo>
	bool attribute_mandatory = min_count == 1 && max_count == 1 && non_empty_names.size() == 1;

	// don't bother supporting "Multiple" params as xml attributes
	if (max_count <= 1)
	{
		// add compound attribute to root node
		addAttributeToSchema(mAttributeNode, attribute_name, type, attribute_mandatory, possible_values);
	}

	// now generated nested elements for compound attributes
	if (non_empty_names.size() > 1 && !attribute_mandatory)
	{
		std::string element_name;

		// traverse all but last element, leaving that as an attribute name
		name_stack_t::const_iterator end_it = non_empty_names.end();
		end_it--;

		for (name_stack_t::const_iterator it = non_empty_names.begin();
			it != end_it;
			++it)
		{
			if (it != non_empty_names.begin())
			{
				element_name += ".";
			}
			element_name += it->first;
		}

		std::string short_attribute_name = non_empty_names.back().first;

		LLXMLNodePtr complex_type_node;

		// find existing element node here, starting at tail of child list
		if (mElementNode->mChildren.notNull())
		{
			for(LLXMLNodePtr element = mElementNode->mChildren->tail;
				element.notNull(); 
				element = element->mPrev)
			{
				std::string name;
				if(element->getAttributeString("name", name) && name == element_name)
				{
					complex_type_node = element->mChildren->head;
					break;
				}
			}
		}
		//create complex_type node
		//
		//<xs:element
        //    maxOccurs="1"
        //    minOccurs="0"
        //    name="name">
        //       <xs:complexType>
        //       </xs:complexType>
        //</xs:element>
		if(complex_type_node.isNull())
		{
			complex_type_node = mElementNode->createChild("xs:element", false);

			complex_type_node->createChild("minOccurs", true)->setIntValue(min_count);
			complex_type_node->createChild("maxOccurs", true)->setIntValue(max_count);
			complex_type_node->createChild("name",		true)->setStringValue(element_name);
			complex_type_node = complex_type_node->createChild("xs:complexType", false);
		}

		addAttributeToSchema(complex_type_node, short_attribute_name, type, false, possible_values);
	}
}
コード例 #9
0
ファイル: llxuiparser.cpp プロジェクト: HyangZhao/NaCl-main
void LLXSDWriter::addAttributeToSchema(LLXMLNodePtr type_declaration_node, const std::string& attribute_name, const std::string& type, bool mandatory, const std::vector<std::string>* possible_values)
{
	if (!attribute_name.empty())
	{
		LLXMLNodePtr new_enum_type_node;
		if (possible_values != NULL)
		{
			// custom attribute type, for example
			//<xs:simpleType>
			 // <xs:restriction
			 //    base="xs:string">
			 //     <xs:enumeration
			 //      value="a" />
			 //     <xs:enumeration
			 //      value="b" />
			 //   </xs:restriction>
			 // </xs:simpleType>
			new_enum_type_node = new LLXMLNode("xs:simpleType", false);

			LLXMLNodePtr restriction_node = new_enum_type_node->createChild("xs:restriction", false);
			restriction_node->createChild("base", true)->setStringValue("xs:string");

			for (std::vector<std::string>::const_iterator it = possible_values->begin();
				it != possible_values->end();
				++it)
			{
				LLXMLNodePtr enum_node = restriction_node->createChild("xs:enumeration", false);
				enum_node->createChild("value", true)->setStringValue(*it);
			}
		}

		string_set_t& attributes_written = mAttributesWritten[type_declaration_node];

		string_set_t::iterator found_it = attributes_written.lower_bound(attribute_name);

		// attribute not yet declared
		if (found_it == attributes_written.end() || attributes_written.key_comp()(attribute_name, *found_it))
		{
			attributes_written.insert(found_it, attribute_name);

			LLXMLNodePtr attribute_node = type_declaration_node->createChild("xs:attribute", false);

			// attribute name
			attribute_node->createChild("name", true)->setStringValue(attribute_name);

			if (new_enum_type_node.notNull())
			{
				attribute_node->addChild(new_enum_type_node);
			}
			else
			{
				// simple attribute type
				attribute_node->createChild("type", true)->setStringValue(type);
			}

			// required or optional
			attribute_node->createChild("use", true)->setStringValue(mandatory ? "required" : "optional");
		}
		 // attribute exists...handle collision of same name attributes with potentially different types
		else
		{
			LLXMLNodePtr attribute_declaration;
			if (type_declaration_node.notNull())
			{
				for(LLXMLNodePtr node = type_declaration_node->mChildren->tail; 
					node.notNull(); 
					node = node->mPrev)
				{
					std::string name;
					if (node->getAttributeString("name", name) && name == attribute_name)
					{
						attribute_declaration = node;
						break;
					}
				}
			}

			bool new_type_is_enum = new_enum_type_node.notNull();
			bool existing_type_is_enum = !attribute_declaration->hasAttribute("type");

			// either type is enum, revert to string in collision
			// don't bother to check for enum equivalence
			if (new_type_is_enum || existing_type_is_enum)
			{
				if (attribute_declaration->hasAttribute("type"))
				{
					attribute_declaration->setAttributeString("type", "xs:string");
				}
				else
				{
					attribute_declaration->createChild("type", true)->setStringValue("xs:string");
				}
				attribute_declaration->deleteChildren("xs:simpleType");
			}
			else 
			{
				// check for collision of different standard types
				std::string existing_type;
				attribute_declaration->getAttributeString("type", existing_type);
				// if current type is not the same as the new type, revert to strnig
				if (existing_type != type)
				{
					// ...than use most general type, string
					attribute_declaration->setAttributeString("type", "string");
				}
			}
		}
	}
}
コード例 #10
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);
	}
}