diff options
52 files changed, 903 insertions, 274 deletions
| diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index b5a73ec1d1..f14d947734 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -676,6 +676,17 @@ long LLStringOps::sLocalTimeOffset = 0;  bool LLStringOps::sPacificDaylightTime = 0;  std::map<std::string, std::string> LLStringOps::datetimeToCodes; +std::vector<std::string> LLStringOps::sWeekDayList; +std::vector<std::string> LLStringOps::sWeekDayShortList; +std::vector<std::string> LLStringOps::sMonthList; +std::vector<std::string> LLStringOps::sMonthShortList; + + +std::string LLStringOps::sDayFormat; +std::string LLStringOps::sAM; +std::string LLStringOps::sPM; + +  S32	LLStringOps::collate(const llwchar* a, const llwchar* b)  {   	#if LL_WINDOWS @@ -724,6 +735,50 @@ void LLStringOps::setupDatetimeInfo (bool daylight)  	datetimeToCodes["timezone"]	= "%Z";		// PST  } +void tokenizeStringToArray(const std::string& data, std::vector<std::string>& output) +{ +	output.clear(); +	size_t length = data.size(); +	 +	// tokenize it and put it in the array +	std::string cur_word; +	for(size_t i = 0; i < length; ++i) +	{ +		if(data[i] == ':') +		{ +			output.push_back(cur_word); +			cur_word.clear(); +		} +		else +		{ +			cur_word.append(1, data[i]); +		} +	} +	output.push_back(cur_word); +} + +void LLStringOps::setupWeekDaysNames(const std::string& data) +{ +	tokenizeStringToArray(data,sWeekDayList); +} +void LLStringOps::setupWeekDaysShortNames(const std::string& data) +{ +	tokenizeStringToArray(data,sWeekDayShortList); +} +void LLStringOps::setupMonthNames(const std::string& data) +{ +	tokenizeStringToArray(data,sMonthList); +} +void LLStringOps::setupMonthShortNames(const std::string& data) +{ +	tokenizeStringToArray(data,sMonthShortList); +} +void LLStringOps::setupDayFormat(const std::string& data) +{ +	sDayFormat = data; +} + +  std::string LLStringOps::getDatetimeCode (std::string key)  {  	std::map<std::string, std::string>::iterator iter; @@ -819,6 +874,10 @@ namespace LLStringFn  //////////////////////////////////////////////////////////// +// Forward specialization of LLStringUtil::format before use in LLStringUtil::formatDatetime. +template<> +S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions); +  //static  template<>   void LLStringUtil::getTokens(const std::string& instr, std::vector<std::string >& tokens, const std::string& delims) @@ -998,7 +1057,53 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token,  		}  		return true;  	} -	replacement = datetime.toHTTPDateString(code); + +	//EXT-7013 +	//few codes are not suppotred by strtime function (example - weekdays for Japanise) +	//so use predefined ones +	 +	//if sWeekDayList is not empty than current locale doesn't support +        //weekday name. +	time_t loc_seconds = (time_t) secFromEpoch; +	if(LLStringOps::sWeekDayList.size() == 7 && code == "%A") +	{ +		struct tm * gmt = gmtime (&loc_seconds); +		replacement = LLStringOps::sWeekDayList[gmt->tm_wday]; +	} +	else if(LLStringOps::sWeekDayShortList.size() == 7 && code == "%a") +	{ +		struct tm * gmt = gmtime (&loc_seconds); +		replacement = LLStringOps::sWeekDayShortList[gmt->tm_wday]; +	} +	else if(LLStringOps::sMonthList.size() == 12 && code == "%B") +	{ +		struct tm * gmt = gmtime (&loc_seconds); +		replacement = LLStringOps::sWeekDayList[gmt->tm_mon]; +	} +	else if( !LLStringOps::sDayFormat.empty() && code == "%d" ) +	{ +		struct tm * gmt = gmtime (&loc_seconds); +		LLStringUtil::format_map_t args; +		args["[MDAY]"] = llformat ("%d", gmt->tm_mday); +		replacement = LLStringOps::sDayFormat; +		LLStringUtil::format(replacement, args); +	} +	else if( !LLStringOps::sAM.empty() && !LLStringOps::sPM.empty() && code == "%p" ) +	{ +		struct tm * gmt = gmtime (&loc_seconds); +		if(gmt->tm_hour<12) +		{ +			replacement = LLStringOps::sAM; +		} +		else +		{ +			replacement = LLStringOps::sPM; +		} +	} +	else +	{ +		replacement = datetime.toHTTPDateString(code); +	}  	// *HACK: delete leading zero from hour string in case 'hour12' (code = %I) time format  	// to show time without leading zero, e.g. 08:16 -> 8:16 (EXT-2738). diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 96588b29b9..ad8f8632a2 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -154,9 +154,19 @@ private:  	static long sPacificTimeOffset;  	static long sLocalTimeOffset;  	static bool sPacificDaylightTime; +  	static std::map<std::string, std::string> datetimeToCodes;  public: +	static std::vector<std::string> sWeekDayList; +	static std::vector<std::string> sWeekDayShortList; +	static std::vector<std::string> sMonthList; +	static std::vector<std::string> sMonthShortList; +	static std::string sDayFormat; + +	static std::string sAM; +	static std::string sPM; +  	static char toUpper(char elem) { return toupper((unsigned char)elem); }  	static llwchar toUpper(llwchar elem) { return towupper(elem); } @@ -185,6 +195,14 @@ public:  	static S32	collate(const llwchar* a, const llwchar* b);  	static void setupDatetimeInfo(bool pacific_daylight_time); + +	static void setupWeekDaysNames(const std::string& data); +	static void setupWeekDaysShortNames(const std::string& data); +	static void setupMonthNames(const std::string& data); +	static void setupMonthShortNames(const std::string& data); +	static void setupDayFormat(const std::string& data); + +  	static long getPacificTimeOffset(void) { return sPacificTimeOffset;}  	static long getLocalTimeOffset(void) { return sLocalTimeOffset;}  	// Is the Pacific time zone (aka server time zone) diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index 5d1d57cbb2..8e0245c451 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -65,6 +65,7 @@ LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)   , mFitParent(params.fit_parent)   , mAutoScrolling( false )   , mAutoScrollRate( 0.f ) + , mSelectedTab( NULL )  {    mSingleExpansion = params.single_expansion;  	if(mFitParent && !mSingleExpansion) @@ -76,6 +77,7 @@ LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)  LLAccordionCtrl::LLAccordionCtrl() : LLPanel()   , mAutoScrolling( false )   , mAutoScrollRate( 0.f ) + , mSelectedTab( NULL )  {  	mSingleExpansion = false;  	mFitParent = false; @@ -689,6 +691,28 @@ S32	LLAccordionCtrl::notifyParent(const LLSD& info)  			}  			return 0;  		} +		else if(str_action == "select_current") +		{ +			for(size_t i=0;i<mAccordionTabs.size();++i) +			{ +				// Set selection to the currently focused tab. +				if(mAccordionTabs[i]->hasFocus()) +				{ +					if (mAccordionTabs[i] != mSelectedTab) +					{ +						if (mSelectedTab) +						{ +							mSelectedTab->setSelected(false); +						} +						mSelectedTab = mAccordionTabs[i]; +						mSelectedTab->setSelected(true); +					} + +					return 1; +				} +			} +			return 0; +		}  	}  	else if (info.has("scrollToShowRect"))  	{ diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h index ab7d6548ca..a029201c90 100644 --- a/indra/llui/llaccordionctrl.h +++ b/indra/llui/llaccordionctrl.h @@ -130,6 +130,7 @@ private:  	bool			mFitParent;  	bool			mAutoScrolling;  	F32				mAutoScrollRate; +	LLAccordionCtrlTab* mSelectedTab;  }; diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index b09c108ec3..83e67980a3 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -76,6 +76,8 @@ public:  	std::string getTitle();  	void	setTitle(const std::string& title, const std::string& hl); +	void	setSelected(bool is_selected) { mIsSelected = is_selected; } +  	virtual void onMouseEnter(S32 x, S32 y, MASK mask);  	virtual void onMouseLeave(S32 x, S32 y, MASK mask);  	virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); @@ -103,6 +105,7 @@ private:  	LLUIColor mHeaderBGColor;  	bool mNeedsHighlight; +	bool mIsSelected;  	LLFrameTimer mAutoOpenTimer;  }; @@ -115,7 +118,8 @@ LLAccordionCtrlTab::LLAccordionCtrlTabHeader::LLAccordionCtrlTabHeader(  	const LLAccordionCtrlTabHeader::Params& p)  : LLUICtrl(p)  , mHeaderBGColor(p.header_bg_color()) -,mNeedsHighlight(false), +, mNeedsHighlight(false) +, mIsSelected(false),  	mImageCollapsed(p.header_collapse_img),  	mImageCollapsedPressed(p.header_collapse_img_pressed),  	mImageExpanded(p.header_expand_img), @@ -187,7 +191,7 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw()  	// Only show green "focus" background image if the accordion is open,  	// because the user's mental model of focus is that it goes away after  	// the accordion is closed. -	if (getParent()->hasFocus() +	if (getParent()->hasFocus() || mIsSelected  		/*&& !(collapsible && !expanded)*/ // WHY??  		)  	{ @@ -301,6 +305,7 @@ LLAccordionCtrlTab::Params::Params()  	,header_image_focused("header_image_focused")  	,header_text_color("header_text_color")  	,fit_panel("fit_panel",true) +	,selection_enabled("selection_enabled", false)  {  	mouse_opaque(false);  } @@ -331,6 +336,11 @@ LLAccordionCtrlTab::LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&p)  	mHeader = LLUICtrlFactory::create<LLAccordionCtrlTabHeader>(headerParams);  	addChild(mHeader, 1); +	if (p.selection_enabled) +	{ +		LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLAccordionCtrlTab::selectOnFocusReceived, this)); +	} +  	reshape(100, 200,FALSE);  } @@ -498,6 +508,15 @@ boost::signals2::connection LLAccordionCtrlTab::setFocusLostCallback(const focus  	return boost::signals2::connection();  } +void LLAccordionCtrlTab::setSelected(bool is_selected) +{ +	LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME); +	if (header) +	{ +		header->setSelected(is_selected); +	} +} +  LLView*	LLAccordionCtrlTab::findContainerView()  {  	for(child_list_const_iter_t it = getChildList()->begin();  @@ -513,6 +532,11 @@ LLView*	LLAccordionCtrlTab::findContainerView()  	return NULL;  } +void LLAccordionCtrlTab::selectOnFocusReceived() +{ +	if (getParent()) // A parent may not be set if tabs are added dynamically. +		getParent()->notifyParent(LLSD().with("action", "select_current")); +}  S32 LLAccordionCtrlTab::getHeaderHeight()  { @@ -713,6 +737,7 @@ void LLAccordionCtrlTab::showAndFocusHeader()  {  	LLAccordionCtrlTabHeader* header = getChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);	  	header->setFocus(true); +	header->setSelected(true);  	LLRect screen_rc;  	LLRect selected_rc = header->getRect(); diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index f5b7fd0af6..83a9024a74 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -88,6 +88,8 @@ public:  		Optional<bool>			fit_panel; +		Optional<bool>			selection_enabled; +  		Optional<S32>			padding_left;  		Optional<S32>			padding_right;  		Optional<S32>			padding_top; @@ -121,6 +123,8 @@ public:  	boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb);  	boost::signals2::connection setFocusLostCallback(const focus_signal_t::slot_type& cb); +	void setSelected(bool is_selected); +  	bool getCollapsible() {return mCollapsible;};  	void setCollapsible(bool collapsible) {mCollapsible = collapsible;}; @@ -199,6 +203,9 @@ protected:  	void drawChild(const LLRect& root_rect,LLView* child);  	LLView* findContainerView	(); + +	void selectOnFocusReceived(); +  private:  	class LLAccordionCtrlTabHeader; diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 0255061b12..a8f72183fd 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -128,6 +128,7 @@ LLButton::LLButton(const LLButton::Params& p)  	mImageSelected(p.image_selected),  	mImageDisabled(p.image_disabled),  	mImageDisabledSelected(p.image_disabled_selected), +	mImageFlash(p.image_flash),  	mImagePressed(p.image_pressed),  	mImagePressedSelected(p.image_pressed_selected),  	mImageHoverSelected(p.image_hover_selected), @@ -635,14 +636,24 @@ void LLButton::draw()  	if (mFlashing)  	{ -		LLColor4 flash_color = mFlashBgColor.get(); -		use_glow_effect = TRUE; -		glow_type = LLRender::BT_ALPHA; // blend the glow - -		if (mNeedsHighlight) // highlighted AND flashing -			glow_color = (glow_color*0.5f + flash_color*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity +		// if we have icon for flashing, use it as image for button +		if(flash && mImageFlash->getName() != "FlashIconAbsent") +		{ +			// setting flash to false to avoid its further influence on glow +			flash = false; +			imagep = mImageFlash; +		} +		// else use usual flashing via flash_color  		else -			glow_color = flash_color; +		{ +			LLColor4 flash_color = mFlashBgColor.get(); +			use_glow_effect = TRUE; +			glow_type = LLRender::BT_ALPHA; // blend the glow +			if (mNeedsHighlight) // highlighted AND flashing +				glow_color = (glow_color*0.5f + flash_color*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity +			else +				glow_color = flash_color; +		}  	}  	if (mNeedsHighlight && !imagep) @@ -1018,6 +1029,11 @@ void LLButton::setImageHoverUnselected(LLPointer<LLUIImage> image)  	mImageHoverUnselected = image;  } +void LLButton::setImageFlash(LLPointer<LLUIImage> image) +{ +	mImageFlash = image; +} +  void LLButton::setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment, const LLColor4& color)  {  	if (image_name.empty()) diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index a4d81ed6c3..b251c3d65d 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -84,6 +84,7 @@ public:  								image_hover_unselected,  								image_disabled_selected,  								image_disabled, +								image_flash,  								image_pressed,  								image_pressed_selected,  								image_overlay; @@ -246,6 +247,7 @@ public:  	void			setImageHoverUnselected(LLPointer<LLUIImage> image);  	void			setImageDisabled(LLPointer<LLUIImage> image);  	void			setImageDisabledSelected(LLPointer<LLUIImage> image); +	void			setImageFlash(LLPointer<LLUIImage> image);  	void			setImagePressed(LLPointer<LLUIImage> image);  	void			setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; } @@ -310,6 +312,12 @@ private:  	LLPointer<LLUIImage>		mImagePressed;  	LLPointer<LLUIImage>		mImagePressedSelected; +	/* There are two ways an image can flash- by making changes in color according to flash_color attribute +	   or by changing icon from current to the one specified in image_flash. Second way is used only if +	   the name of flash icon is different from "FlashIconAbsent" which is there by default. First way is used  +	   otherwise. */ +	LLPointer<LLUIImage>		mImageFlash; +  	LLUIColor					mHighlightColor;  	LLUIColor					mFlashBgColor; diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 30fc7babae..986cfe75a1 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -197,10 +197,13 @@ static LLDefaultChildRegistry::Register<LLTabContainer> r2("tab_container");  LLTabContainer::TabParams::TabParams()  :	tab_top_image_unselected("tab_top_image_unselected"),  	tab_top_image_selected("tab_top_image_selected"), +	tab_top_image_flash("tab_top_image_flash"),  	tab_bottom_image_unselected("tab_bottom_image_unselected"),  	tab_bottom_image_selected("tab_bottom_image_selected"), +	tab_bottom_image_flash("tab_bottom_image_flash"),  	tab_left_image_unselected("tab_left_image_unselected"), -	tab_left_image_selected("tab_left_image_selected") +	tab_left_image_selected("tab_left_image_selected"), +	tab_left_image_flash("tab_left_image_flash")  {}  LLTabContainer::Params::Params() @@ -879,16 +882,19 @@ void LLTabContainer::update_images(LLTabTuple* tuple, TabParams params, LLTabCon  		{  			tuple->mButton->setImageUnselected(static_cast<LLUIImage*>(params.tab_top_image_unselected));  			tuple->mButton->setImageSelected(static_cast<LLUIImage*>(params.tab_top_image_selected)); +			tuple->mButton->setImageFlash(static_cast<LLUIImage*>(params.tab_top_image_flash));  		}  		else if (pos == LLTabContainer::BOTTOM)  		{  			tuple->mButton->setImageUnselected(static_cast<LLUIImage*>(params.tab_bottom_image_unselected));  			tuple->mButton->setImageSelected(static_cast<LLUIImage*>(params.tab_bottom_image_selected)); +			tuple->mButton->setImageFlash(static_cast<LLUIImage*>(params.tab_bottom_image_flash));  		}  		else if (pos == LLTabContainer::LEFT)  		{  			tuple->mButton->setImageUnselected(static_cast<LLUIImage*>(params.tab_left_image_unselected));  			tuple->mButton->setImageSelected(static_cast<LLUIImage*>(params.tab_left_image_selected)); +			tuple->mButton->setImageFlash(static_cast<LLUIImage*>(params.tab_left_image_flash));  		}  	}  } diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index 50ec2679f6..a2dc15aaf9 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -67,10 +67,13 @@ public:  	{  		Optional<LLUIImage*>				tab_top_image_unselected,  											tab_top_image_selected, +											tab_top_image_flash,  											tab_bottom_image_unselected,  											tab_bottom_image_selected, +											tab_bottom_image_flash,  											tab_left_image_unselected, -											tab_left_image_selected;		 +											tab_left_image_selected, +											tab_left_image_flash;		  		TabParams();  	}; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 50d1491523..9ba44e787b 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -379,6 +379,7 @@ set(viewer_SOURCE_FILES      llregionposition.cpp      llremoteparcelrequest.cpp      llsavedsettingsglue.cpp +    llsaveoutfitcombobtn.cpp      llscreenchannel.cpp      llscriptfloater.cpp      llscrollingpanelparam.cpp @@ -894,6 +895,7 @@ set(viewer_HEADER_FILES      llresourcedata.h      llrootview.h      llsavedsettingsglue.h +    llsaveoutfitcombobtn.h      llscreenchannel.h      llscriptfloater.h      llscrollingpanelparam.h diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp index 43a0d48d8b..ef0b97d376 100644 --- a/indra/newview/llagentwearablesfetch.cpp +++ b/indra/newview/llagentwearablesfetch.cpp @@ -40,6 +40,50 @@  #include "llstartup.h"  #include "llvoavatarself.h" + +class LLOrderMyOutfitsOnDestroy: public LLInventoryCallback +{ +public: +	LLOrderMyOutfitsOnDestroy() {}; + +	virtual ~LLOrderMyOutfitsOnDestroy() +	{ +		const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); +		if (my_outfits_id.isNull()) return; + +		LLInventoryModel::cat_array_t* cats; +		LLInventoryModel::item_array_t* items; +		gInventory.getDirectDescendentsOf(my_outfits_id, cats, items); +		if (!cats) return; + +		//My Outfits should at least contain saved initial outfit and one another outfit +		if (cats->size() < 2) +		{ +			llwarning("My Outfits category was not populated properly", 0); +			return; +		} + +		llinfos << "Starting updating My Outfits with wearables ordering information" << llendl; + +		for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin(); +			outfit_iter != cats->end(); ++outfit_iter) +		{ +			const LLUUID& cat_id = (*outfit_iter)->getUUID(); +			if (cat_id.isNull()) continue; + +			// saved initial outfit already contains wearables ordering information +			if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue; + +			LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id); +		} + +		llinfos << "Finished updating My Outfits with wearables ordering information" << llendl; +	} + +	/* virtual */ void fire(const LLUUID& inv_item) {}; +}; + +  LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) :  	LLInventoryFetchDescendentsObserver(cof_id)  { @@ -483,6 +527,8 @@ void LLLibraryOutfitsFetch::contentsDone()  	LLInventoryModel::cat_array_t cat_array;  	LLInventoryModel::item_array_t wearable_array; +	LLPointer<LLOrderMyOutfitsOnDestroy> order_myoutfits_on_destroy = new LLOrderMyOutfitsOnDestroy; +  	for (uuid_vec_t::const_iterator folder_iter = mImportedClothingFolders.begin();  		 folder_iter != mImportedClothingFolders.end();  		 ++folder_iter) @@ -518,7 +564,7 @@ void LLLibraryOutfitsFetch::contentsDone()  								item->getName(),  								item->getDescription(),  								LLAssetType::AT_LINK, -								NULL); +								order_myoutfits_on_destroy);  		}  	} diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index c417f8bdf5..f27e632180 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1790,10 +1790,16 @@ struct WearablesOrderComparator  	U32 mControlSize;  }; -void LLAppearanceMgr::updateClothingOrderingInfo() +void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id)  { +	if (cat_id.isNull()) +	{ +		cat_id = getCOF(); +	} + +	// COF is processed if cat_id is not specified  	LLInventoryModel::item_array_t wear_items; -	getDescendentsOfAssetType(getCOF(), wear_items, LLAssetType::AT_CLOTHING, false); +	getDescendentsOfAssetType(cat_id, wear_items, LLAssetType::AT_CLOTHING, false);  	wearables_by_type_t items_by_type(LLWearableType::WT_COUNT);  	divvyWearablesByType(wear_items, items_by_type); diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 96541beb7d..dbde055c3a 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -154,15 +154,16 @@ public:  	//Divvy items into arrays by wearable type  	static void divvyWearablesByType(const LLInventoryModel::item_array_t& items, wearables_by_type_t& items_by_type); +	//Check ordering information on wearables stored in links' descriptions and update if it is invalid +	// COF is processed if cat_id is not specified +	void updateClothingOrderingInfo(LLUUID cat_id = LLUUID::null); +  protected:  	LLAppearanceMgr();  	~LLAppearanceMgr();  private: -	//Check ordering information on wearables stored in links' descriptions and update if it is invalid -	void updateClothingOrderingInfo(); -  	void filterWearableItems(LLInventoryModel::item_array_t& items, S32 max_per_type);  	void getDescendentsOfAssetType(const LLUUID& category,  diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index b9eb99230b..b1619b3c07 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -892,7 +892,16 @@ bool LLAppViewer::init()  	}  	LLViewerMedia::initClass(); -	 + +	LLStringOps::setupWeekDaysNames(LLTrans::getString("dateTimeWeekdaysNames")); +	LLStringOps::setupWeekDaysShortNames(LLTrans::getString("dateTimeWeekdaysShortNames")); +	LLStringOps::setupMonthNames(LLTrans::getString("dateTimeMonthNames")); +	LLStringOps::setupMonthShortNames(LLTrans::getString("dateTimeMonthShortNames")); +	LLStringOps::setupDayFormat(LLTrans::getString("dateTimeDayFormat")); + +	LLStringOps::sAM = LLTrans::getString("dateTimeAM"); +	LLStringOps::sPM = LLTrans::getString("dateTimePM"); +  	return true;  } diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index a057421135..ff1e8a9657 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -198,6 +198,12 @@ LLBottomTray::~LLBottomTray()  		S32 custom_width = mNearbyChatBar->getRect().getWidth();  		gSavedSettings.setS32("ChatBarCustomWidth", custom_width);  	} + +	// emulate previous floater behavior to be hidden on startup. +	// override effect of save_visibility=true. +	// this attribute is necessary to button.initial_callback=Button.SetFloaterToggle works properly: +	//		i.g when floater changes its visibility - button changes its toggle state. +	getChild<LLUICtrl>("search_btn")->setControlValue(false);  }  // *TODO Vadim: why void* ? diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index 0864d63919..ee366f4e3c 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -43,6 +43,8 @@  #include "llmenugl.h"  #include "llviewermenu.h"  #include "llwearableitemslist.h" +#include "llpaneloutfitedit.h" +#include "llsidetray.h"  static LLRegisterPanelClassWrapper<LLCOFAccordionListAdaptor> t_cof_accodion_list_adaptor("accordion_list_adaptor"); @@ -135,8 +137,10 @@ protected:  		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;  		LLUUID selected_id = mUUIDs.back(); -		registrar.add("BodyPart.Replace", boost::bind(&LLAppearanceMgr::wearItemOnAvatar, -			LLAppearanceMgr::getInstance(), selected_id, true, true)); +		// *HACK* need to pass pointer to LLPanelOutfitEdit instead of LLSideTray::getInstance()->getPanel(). +		// LLSideTray::getInstance()->getPanel() is rather slow variant +		LLPanelOutfitEdit* panel_oe = dynamic_cast<LLPanelOutfitEdit*>(LLSideTray::getInstance()->getPanel("panel_outfit_edit")); +		registrar.add("BodyPart.Replace", boost::bind(&LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked, panel_oe, selected_id));  		registrar.add("BodyPart.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));  		enable_registrar.add("BodyPart.OnEnable", boost::bind(&CofBodyPartContextMenu::onEnable, this, _2)); @@ -419,6 +423,7 @@ void LLCOFWearables::addClothingTypesDummies(const LLAppearanceMgr::wearables_by  		LLWearableType::EType w_type = static_cast<LLWearableType::EType>(type);  		LLPanelInventoryListItemBase* item_panel = LLPanelDummyClothingListItem::create(w_type);  		if(!item_panel) continue; +		item_panel->childSetAction("btn_add", mCOFCallbacks.mAddWearable);  		mClothing->addItem(item_panel, LLUUID::null, ADD_BOTTOM, false);  	}  } @@ -438,6 +443,13 @@ bool LLCOFWearables::getSelectedUUIDs(uuid_vec_t& selected_ids)  	return selected_ids.size() != 0;  } +LLPanel* LLCOFWearables::getSelectedItem() +{ +	if (!mLastSelectedList) return NULL; + +	return mLastSelectedList->getSelectedItem(); +} +  void LLCOFWearables::clear()  {  	mAttachments->clear(); diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h index 590aa709dd..8f8bda2be8 100644 --- a/indra/newview/llcofwearables.h +++ b/indra/newview/llcofwearables.h @@ -107,6 +107,7 @@ public:  		typedef boost::function<void (void*)> cof_callback_t; +		cof_callback_t mAddWearable;  		cof_callback_t mMoveWearableCloser;  		cof_callback_t mMoveWearableFurther;  		cof_callback_t mEditWearable; @@ -123,6 +124,8 @@ public:  	LLUUID getSelectedUUID();  	bool getSelectedUUIDs(uuid_vec_t& selected_ids); +	LLPanel* getSelectedItem(); +  	void refresh();  	void clear(); diff --git a/indra/newview/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp index fd99f673e0..28e159421c 100644 --- a/indra/newview/llfilteredwearablelist.cpp +++ b/indra/newview/llfilteredwearablelist.cpp @@ -37,32 +37,10 @@  #include "llinventoryitemslist.h"  #include "llinventorymodel.h" -class LLFindNonLinksByMask : public LLInventoryCollectFunctor -{ -public: -	LLFindNonLinksByMask(U64 mask) -		: mFilterMask(mask) -	{} - -	virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) -	{ -		if(item && !item->getIsLinkType() && (mFilterMask & (1LL << item->getInventoryType())) ) -		{ -			return true; -		} - -		return false; -	} -private: -	U64 mFilterMask; -}; - -////////////////////////////////////////////////////////////////////////// - -LLFilteredWearableListManager::LLFilteredWearableListManager(LLInventoryItemsList* list, U64 filter_mask) +LLFilteredWearableListManager::LLFilteredWearableListManager(LLInventoryItemsList* list, LLInventoryCollectFunctor* collector)  : mWearableList(list) -, mFilterMask(filter_mask) +, mCollector(collector)  {  	llassert(mWearableList);  	gInventory.addObserver(this); @@ -84,9 +62,9 @@ void LLFilteredWearableListManager::changed(U32 mask)  	populateList();  } -void LLFilteredWearableListManager::setFilterMask(U64 mask) +void LLFilteredWearableListManager::setFilterCollector(LLInventoryCollectFunctor* collector)  { -	mFilterMask = mask; +	mCollector = collector;  	populateList();  } @@ -94,14 +72,16 @@ void LLFilteredWearableListManager::populateList()  {  	LLInventoryModel::cat_array_t cat_array;  	LLInventoryModel::item_array_t item_array; -	LLFindNonLinksByMask collector(mFilterMask); -	gInventory.collectDescendentsIf( -		gInventory.getRootFolderID(), -		cat_array, -		item_array, -		LLInventoryModel::EXCLUDE_TRASH, -		collector); +	if(mCollector) +	{ +		gInventory.collectDescendentsIf( +				gInventory.getRootFolderID(), +				cat_array, +				item_array, +				LLInventoryModel::EXCLUDE_TRASH, +				*mCollector); +	}  	// Probably will also need to get items from Library (waiting for reply in EXT-6724). diff --git a/indra/newview/llfilteredwearablelist.h b/indra/newview/llfilteredwearablelist.h index 0780c02442..b7825c07af 100644 --- a/indra/newview/llfilteredwearablelist.h +++ b/indra/newview/llfilteredwearablelist.h @@ -32,6 +32,7 @@  #ifndef LL_LLFILTEREDWEARABLELIST_H  #define LL_LLFILTEREDWEARABLELIST_H +#include "llinventoryfunctions.h"  #include "llinventoryobserver.h"  class LLInventoryItemsList; @@ -42,7 +43,7 @@ class LLFilteredWearableListManager : public LLInventoryObserver  	LOG_CLASS(LLFilteredWearableListManager);  public: -	LLFilteredWearableListManager(LLInventoryItemsList* list, U64 filter_mask); +	LLFilteredWearableListManager(LLInventoryItemsList* list, LLInventoryCollectFunctor* collector);  	~LLFilteredWearableListManager();  	/** LLInventoryObserver implementation @@ -51,9 +52,9 @@ public:  	/*virtual*/ void changed(U32 mask);  	/** -	 * Sets new filter and applies it immediately +	 * Sets new collector and applies it immediately  	 */ -	void setFilterMask(U64 mask); +	void setFilterCollector(LLInventoryCollectFunctor* collector);  	/**  	 * Populates wearable list with filtered data. @@ -62,7 +63,7 @@ public:  private:  	LLInventoryItemsList* mWearableList; -	U64 mFilterMask; +	LLInventoryCollectFunctor* mCollector;  };  #endif //LL_LLFILTEREDWEARABLELIST_H diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index f67d91cfa5..0cc4b0e389 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -371,6 +371,11 @@ bool LLFindWearablesOfType::operator()(LLInventoryCategory* cat, LLInventoryItem  	return true;  } +void LLFindWearablesOfType::setType(LLWearableType::EType type) +{ +	mWearableType = type; +} +  ///----------------------------------------------------------------------------  /// LLAssetIDMatches   ///---------------------------------------------------------------------------- diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 8b96ba29d9..bb365573d7 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -252,6 +252,37 @@ public:  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFindNonLinksByMask +// +// +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLFindNonLinksByMask : public LLInventoryCollectFunctor +{ +public: +	LLFindNonLinksByMask(U64 mask) +		: mFilterMask(mask) +	{} + +	virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) +	{ +		if(item && !item->getIsLinkType() && (mFilterMask & (1LL << item->getInventoryType())) ) +		{ +			return true; +		} + +		return false; +	} + +	void setFilterMask(U64 mask) +	{ +		mFilterMask = mask; +	} + +private: +	U64 mFilterMask; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Class LLFindWearables  //  // Collects wearables based on item type. @@ -272,8 +303,10 @@ public:  	LLFindWearablesOfType(LLWearableType::EType type) : mWearableType(type) {}  	virtual ~LLFindWearablesOfType() {}  	virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); +	void setType(LLWearableType::EType type); -	const LLWearableType::EType mWearableType; +private: +	LLWearableType::EType mWearableType;  };  /**                    Inventory Collector Functions diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h index 807952948b..03ad7c2184 100644 --- a/indra/newview/llinventoryitemslist.h +++ b/indra/newview/llinventoryitemslist.h @@ -133,6 +133,9 @@ public:  	/** Get the description of a corresponding inventory item */  	const std::string& getDescription() const { return mItem->getDescription(); } +	/** Get the associated inventory item */ +	LLViewerInventoryItem* getItem() const { return mItem; } +  	virtual ~LLPanelInventoryListItemBase(){}  protected: diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 680ed35fa2..46f531fdd9 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -34,6 +34,7 @@  #include "message.h" +#include "llappviewer.h"  #include "llfloaterreg.h"  #include "lltrans.h" @@ -388,6 +389,7 @@ BOOL LLNearbyChatBar::postBuild()  	mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this));  	mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this);  	mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this)); +	mChatBox->setFocusReceivedCallback(boost::bind(&LLNearbyChatBar::onChatBoxFocusReceived, this));  	mChatBox->setIgnoreArrowKeys( FALSE );   	mChatBox->setCommitOnFocusLost( FALSE ); @@ -545,6 +547,11 @@ void LLNearbyChatBar::onChatBoxFocusLost(LLFocusableElement* caller, void* userd  	gAgent.stopTyping();  } +void LLNearbyChatBar::onChatBoxFocusReceived() +{ +	mChatBox->setEnabled(!gDisconnected); +} +  EChatType LLNearbyChatBar::processChatTypeTriggers(EChatType type, std::string &str)  {  	U32 length = str.length(); diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index 5af3152662..83c174fd10 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -122,6 +122,7 @@ protected:  	static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);  	static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata);  	static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata); +	void onChatBoxFocusReceived();  	void sendChat( EChatType type );  	void onChatBoxCommit(); diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 17a2db7a43..8f189a1e9f 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -82,7 +82,6 @@ LLOutfitsList::LLOutfitsList()  	:	LLPanel()  	,	mAccordion(NULL)  	,	mListCommands(NULL) -	,	mSelectedList(NULL)  {  	mCategoriesObserver = new LLInventoryCategoriesObserver();  	gInventory.addObserver(mCategoriesObserver); @@ -208,6 +207,8 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)  		// Setting list refresh callback to apply filter on list change.  		list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onFilteredWearableItemsListRefresh, this, _1)); +		list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3)); +  		// Fetch the new outfit contents.  		cat->fetch(); @@ -237,23 +238,27 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)  		outfits_map_t::iterator outfits_iter = mOutfitsMap.find((*iter));  		if (outfits_iter != mOutfitsMap.end())  		{ -			// An outfit is removed from the list. Do the following: -			// 1. Remove outfit accordion tab from accordion. -			mAccordion->removeCollapsibleCtrl(outfits_iter->second); -  			const LLUUID& outfit_id = outfits_iter->first; +			LLAccordionCtrlTab* tab = outfits_iter->second; -			// 2. Remove outfit category from observer to stop monitoring its changes. +			// An outfit is removed from the list. Do the following: +			// 1. Remove outfit category from observer to stop monitoring its changes.  			mCategoriesObserver->removeCategory(outfit_id); -			// 3. Reset selection if selected outfit is being removed. -			if (mSelectedOutfitUUID == outfit_id) +			// 2. Remove selected lists map entry. +			mSelectedListsMap.erase(outfit_id); + +			// 3. Reset currently selected outfit id if it is being removed. +			if (outfit_id == mSelectedOutfitUUID)  			{ -				changeOutfitSelection(NULL, LLUUID()); +				mSelectedOutfitUUID = LLUUID();  			}  			// 4. Remove category UUID to accordion tab mapping.  			mOutfitsMap.erase(outfits_iter); + +			// 5. Remove outfit tab from accordion. +			mAccordion->removeCollapsibleCtrl(tab);  		}  	} @@ -283,6 +288,8 @@ void LLOutfitsList::onSelectionChange(LLUICtrl* ctrl)  void LLOutfitsList::performAction(std::string action)  { +	if (mSelectedOutfitUUID.isNull()) return; +  	LLViewerInventoryCategory* cat = gInventory.getCategory(mSelectedOutfitUUID);  	if (!cat) return; @@ -367,14 +374,28 @@ void LLOutfitsList::updateOutfitTab(const LLUUID& category_id)  void LLOutfitsList::changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id)  { -	// Reset selection in previously selected tab -	// if a new one is selected. -	if (list && mSelectedList && mSelectedList != list) +	MASK mask = gKeyboard->currentMask(TRUE); + +	// Reset selection in all previously selected tabs except for the current +	// if new selection is started. +	if (list && !(mask & MASK_CONTROL))  	{ -		mSelectedList->resetSelection(); +		for (wearables_lists_map_t::iterator iter = mSelectedListsMap.begin(); +				iter != mSelectedListsMap.end(); +				++iter) +		{ +			LLWearableItemsList* selected_list = (*iter).second; +			if (selected_list != list) +			{ +				selected_list->resetSelection(); +			} +		} + +		// Clear current selection. +		mSelectedListsMap.clear();  	} -	mSelectedList = list; +	mSelectedListsMap.insert(wearables_lists_map_value_t(category_id, list));  	mSelectedOutfitUUID = category_id;  } @@ -494,6 +515,13 @@ void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const  		S32 header_bottom = tab->getLocalRect().getHeight() - tab->getHeaderHeight();  		if(y >= header_bottom)  		{ +			// Focus tab header to trigger tab selection change. +			LLUICtrl* header = tab->findChild<LLUICtrl>("dd_header"); +			if (header) +			{ +				header->setFocus(TRUE); +			} +  			uuid_vec_t selected_uuids;  			selected_uuids.push_back(cat_id);  			mOutfitMenu->show(ctrl, selected_uuids, x, y); @@ -501,4 +529,26 @@ void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const  	}  } +void LLOutfitsList::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y) +{ +	LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(ctrl); +	if (!list) return; + +	uuid_vec_t selected_uuids; + +	// Collect seleted items from all selected lists. +	for (wearables_lists_map_t::iterator iter = mSelectedListsMap.begin(); +			iter != mSelectedListsMap.end(); +			++iter) +	{ +		uuid_vec_t uuids; +		(*iter).second->getSelectedUUIDs(uuids); + +		S32 prev_size = selected_uuids.size(); +		selected_uuids.resize(prev_size + uuids.size()); +		std::copy(uuids.begin(), uuids.end(), selected_uuids.begin() + prev_size); +	} + +	LLWearableItemsList::ContextMenu::instance().show(list, selected_uuids, x, y); +}  // EOF diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index b6b3d6ae46..1da7360c2e 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -108,12 +108,17 @@ private:  	void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id); +	void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y); +  	LLInventoryCategoriesObserver* 	mCategoriesObserver;  	LLAccordionCtrl*				mAccordion;  	LLPanel*						mListCommands; -	LLWearableItemsList*			mSelectedList; +	typedef	std::map<LLUUID, LLWearableItemsList*>		wearables_lists_map_t; +	typedef wearables_lists_map_t::value_type			wearables_lists_map_value_t; +	wearables_lists_map_t			mSelectedListsMap; +  	LLUUID							mSelectedOutfitUUID;  	std::string 					mFilterSubString; diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 9e51aaceca..78de384cdc 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -61,6 +61,7 @@  #include "llinventorymodelbackgroundfetch.h"  #include "llpaneloutfitsinventory.h"  #include "lluiconstants.h" +#include "llsaveoutfitcombobtn.h"  #include "llscrolllistctrl.h"  #include "lltextbox.h"  #include "lluictrlfactory.h" @@ -68,6 +69,7 @@  #include "llsidepanelappearance.h"  #include "lltoggleablemenu.h"  #include "llwearablelist.h" +#include "llwearableitemslist.h"  static LLRegisterPanelClassWrapper<LLPanelOutfitEdit> t_outfit_edit("panel_outfit_edit"); @@ -75,7 +77,6 @@ const U64 WEARABLE_MASK = (1LL << LLInventoryType::IT_WEARABLE);  const U64 ATTACHMENT_MASK = (1LL << LLInventoryType::IT_ATTACHMENT) | (1LL << LLInventoryType::IT_OBJECT);  const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK; -static const std::string SAVE_BTN("save_btn");  static const std::string REVERT_BTN("revert_btn");  class LLCOFObserver : public LLInventoryObserver @@ -215,7 +216,10 @@ LLPanelOutfitEdit::LLPanelOutfitEdit()  	mCOFObserver(NULL),  	mGearMenu(NULL),  	mCOFDragAndDropObserver(NULL), -	mInitialized(false) +	mInitialized(false), +	mAddWearablesPanel(NULL), +	mWearableListMaskCollector(NULL), +	mWearableListTypeCollector(NULL)  {  	mSavedFolderState = new LLSaveFolderState();  	mSavedFolderState->setApply(FALSE); @@ -237,6 +241,9 @@ LLPanelOutfitEdit::~LLPanelOutfitEdit()  	delete mCOFObserver;  	delete mCOFDragAndDropObserver; + +	delete mWearableListMaskCollector; +	delete mWearableListTypeCollector;  }  BOOL LLPanelOutfitEdit::postBuild() @@ -252,16 +259,17 @@ BOOL LLPanelOutfitEdit::postBuild()  	mFolderViewBtn = getChild<LLButton>("folder_view_btn");  	mListViewBtn = getChild<LLButton>("list_view_btn"); +	mAddToOutfitBtn = getChild<LLButton>("add_to_outfit_btn");  	childSetCommitCallback("filter_button", boost::bind(&LLPanelOutfitEdit::showWearablesFilter, this), NULL);  	childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredFolderWearablesPanel, this), NULL);  	childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredWearablesPanel, this), NULL); -	childSetCommitCallback("gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL);  	childSetCommitCallback("wearables_gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL);  	mCOFWearables = getChild<LLCOFWearables>("cof_wearables_list");  	mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onOutfitItemSelectionChange, this)); +	mCOFWearables->getCOFCallbacks().mAddWearable = boost::bind(&LLPanelOutfitEdit::onAddWearableClicked, this);  	mCOFWearables->getCOFCallbacks().mEditWearable = boost::bind(&LLPanelOutfitEdit::onEditWearableClicked, this);  	mCOFWearables->getCOFCallbacks().mDeleteWearable = boost::bind(&LLPanelOutfitEdit::onRemoveFromOutfitClicked, this);  	mCOFWearables->getCOFCallbacks().mMoveWearableCloser = boost::bind(&LLPanelOutfitEdit::moveWearable, this, true); @@ -269,6 +277,7 @@ BOOL LLPanelOutfitEdit::postBuild()  	mCOFWearables->childSetAction("add_btn", boost::bind(&LLPanelOutfitEdit::toggleAddWearablesPanel, this)); +	mAddWearablesPanel = getChild<LLPanel>("add_wearables_panel");  	mInventoryItemsPanel = getChild<LLInventoryPanel>("inventory_items");  	mInventoryItemsPanel->setFilterTypes(ALL_ITEMS_MASK); @@ -299,18 +308,14 @@ BOOL LLPanelOutfitEdit::postBuild()  	childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance())); -	childSetAction(SAVE_BTN, boost::bind(&LLPanelOutfitEdit::saveOutfit, this, false)); -	childSetAction("save_flyout_btn", boost::bind(&LLPanelOutfitEdit::showSaveMenu, this)); - -	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar save_registar; -	save_registar.add("Outfit.Save.Action", boost::bind(&LLPanelOutfitEdit::saveOutfit, this, false)); -	save_registar.add("Outfit.SaveAsNew.Action", boost::bind(&LLPanelOutfitEdit::saveOutfit, this, true)); -	mSaveMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_save_outfit.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +	mWearableListMaskCollector = new LLFindNonLinksByMask(ALL_ITEMS_MASK); +	mWearableListTypeCollector = new LLFindWearablesOfType(LLWearableType::WT_NONE);  	mWearableItemsPanel = getChild<LLPanel>("filtered_wearables_panel");  	mWearableItemsList = getChild<LLInventoryItemsList>("filtered_wearables_list"); -	mWearableListManager = new LLFilteredWearableListManager(mWearableItemsList, ALL_ITEMS_MASK); +	mWearableListManager = new LLFilteredWearableListManager(mWearableItemsList, mWearableListMaskCollector); +	mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));  	return TRUE;  } @@ -335,7 +340,16 @@ void LLPanelOutfitEdit::moveWearable(bool closer_to_body)  void LLPanelOutfitEdit::toggleAddWearablesPanel()  { -	childSetVisible("add_wearables_panel", !childIsVisible("add_wearables_panel")); +	BOOL current_visibility = mAddWearablesPanel->getVisible(); +	mAddWearablesPanel->setVisible(!current_visibility); + +	mFolderViewBtn->setVisible(!current_visibility); +	mListViewBtn->setVisible(!current_visibility); +	mAddToOutfitBtn->setVisible(!current_visibility); + +	// Change right dummy icon to fill the toggled buttons space. +	childSetVisible("add_wearables_dummy_icon", !current_visibility); +	childSetVisible("dummy_right_icon", current_visibility);  }  void LLPanelOutfitEdit::showWearablesFilter() @@ -373,33 +387,6 @@ void LLPanelOutfitEdit::showFilteredFolderWearablesPanel()  	mFolderViewBtn->setToggleState(TRUE);  } -void LLPanelOutfitEdit::saveOutfit(bool as_new) -{ -	if (!as_new && LLAppearanceMgr::getInstance()->updateBaseOutfit()) -	{ -		// we don't need to ask for an outfit name, and updateBaseOutfit() successfully saved. -		// If updateBaseOutfit fails, ask for an outfit name anyways -		return; -	} - -	LLPanelOutfitsInventory* panel_outfits_inventory = LLPanelOutfitsInventory::findInstance(); -	if (panel_outfits_inventory) -	{ -		panel_outfits_inventory->onSave(); -	} - -	//*TODO how to get to know when base outfit is updated or new outfit is created? -} - -void LLPanelOutfitEdit::showSaveMenu() -{ -	S32 x, y; -	LLUI::getMousePositionLocal(this, &x, &y); - -	mSaveMenu->updateParent(LLMenuGL::sMenuContainer); -	LLMenuGL::showPopup(this, mSaveMenu, x, y); -} -  void LLPanelOutfitEdit::onTypeFilterChanged(LLUICtrl* ctrl)  {  	LLComboBox* type_filter = dynamic_cast<LLComboBox*>(ctrl); @@ -408,7 +395,9 @@ void LLPanelOutfitEdit::onTypeFilterChanged(LLUICtrl* ctrl)  	{  		U32 curr_filter_type = type_filter->getCurrentIndex();  		mInventoryItemsPanel->setFilterTypes(mLookItemTypes[curr_filter_type].inventoryMask); -		mWearableListManager->setFilterMask(mLookItemTypes[curr_filter_type].inventoryMask); + +		mWearableListMaskCollector->setFilterMask(mLookItemTypes[curr_filter_type].inventoryMask); +		mWearableListManager->setFilterCollector(mWearableListMaskCollector);  	}  	mSavedFolderState->setApply(TRUE); @@ -488,6 +477,25 @@ void LLPanelOutfitEdit::onAddToOutfitClicked(void)  	LLAppearanceMgr::getInstance()->wearItemOnAvatar(selected_id);  } +void LLPanelOutfitEdit::onAddWearableClicked(void) +{ +	LLPanelDummyClothingListItem* item = dynamic_cast<LLPanelDummyClothingListItem*>(mCOFWearables->getSelectedItem()); + +	if(item) +	{ +		showFilteredWearableItemsList(item->getWearableType()); +	} +} + +void LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked(LLUUID selected_item_id) +{ +	LLViewerInventoryItem* item = gInventory.getLinkedItem(selected_item_id); + +	if (item && item->getType() == LLAssetType::AT_BODYPART) +	{ +		showFilteredWearableItemsList(item->getWearableType()); +	} +}  void LLPanelOutfitEdit::onRemoveFromOutfitClicked(void)  { @@ -676,10 +684,10 @@ void LLPanelOutfitEdit::updateVerbs()  	bool outfit_is_dirty = LLAppearanceMgr::getInstance()->isOutfitDirty();  	bool has_baseoutfit = LLAppearanceMgr::getInstance()->getBaseOutfitUUID().notNull(); -	childSetEnabled(SAVE_BTN, outfit_is_dirty); +	mSaveComboBtn->setSaveBtnEnabled(outfit_is_dirty);  	childSetEnabled(REVERT_BTN, outfit_is_dirty && has_baseoutfit); -	mSaveMenu->setItemEnabled("save_outfit", outfit_is_dirty); +	mSaveComboBtn->setMenuItemEnabled("save_outfit", outfit_is_dirty);  	mStatus->setText(outfit_is_dirty ? getString("unsaved_changes") : getString("now_editing")); @@ -723,4 +731,12 @@ void LLPanelOutfitEdit::onGearMenuItemClick(const LLSD& data)  	}  } +void LLPanelOutfitEdit::showFilteredWearableItemsList(LLWearableType::EType type) +{ +	mWearableListTypeCollector->setType(type); +	mWearableListManager->setFilterCollector(mWearableListTypeCollector); +	mAddWearablesPanel->setVisible(TRUE); +	showFilteredWearablesPanel(); +} +  // EOF diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 1bf69c5606..1569c55732 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -59,6 +59,9 @@ class LLToggleableMenu;  class LLFilterEditor;  class LLFilteredWearableListManager;  class LLMenuGL; +class LLFindNonLinksByMask; +class LLFindWearablesOfType; +class LLSaveOutfitComboBtn;  class LLPanelOutfitEdit : public LLPanel  { @@ -93,8 +96,6 @@ public:  	void showWearablesFilter();  	void showFilteredWearablesPanel();  	void showFilteredFolderWearablesPanel(); -	void saveOutfit(bool as_new = false); -	void showSaveMenu();  	void onTypeFilterChanged(LLUICtrl* ctrl);  	void onSearchEdit(const std::string& string); @@ -103,6 +104,8 @@ public:  	void onOutfitItemSelectionChange(void);  	void onRemoveFromOutfitClicked(void);  	void onEditWearableClicked(void); +	void onAddWearableClicked(void); +	void onReplaceBodyPartMenuItemClicked(LLUUID selected_item_id);  	void displayCurrentOutfit();  	void updateCurrentOutfitName(); @@ -129,6 +132,7 @@ private:  	void onGearButtonClick(LLUICtrl* clicked_button);  	void onGearMenuItemClick(const LLSD& data); +	void showFilteredWearableItemsList(LLWearableType::EType type);  	LLTextBox*			mCurrentOutfitName; @@ -140,7 +144,11 @@ private:  	LLButton*			mEditWearableBtn;  	LLButton*			mFolderViewBtn;  	LLButton*			mListViewBtn; -	LLToggleableMenu*	mSaveMenu; +	LLButton*			mAddToOutfitBtn; +	LLPanel*			mAddWearablesPanel; + +	LLFindNonLinksByMask*  mWearableListMaskCollector; +	LLFindWearablesOfType* mWearableListTypeCollector;  	LLFilteredWearableListManager* 	mWearableListManager;  	LLInventoryItemsList* 			mWearableItemsList; @@ -154,6 +162,8 @@ private:  	LLCOFWearables*		mCOFWearables;  	LLMenuGL*			mGearMenu;  	bool				mInitialized; +	std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn; +  };  #endif // LL_LLPANELOUTFITEDIT_H diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index a7e8f497d9..21f69d3470 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -50,6 +50,7 @@  #include "llmodaldialog.h"  #include "llnotificationsutil.h"  #include "lloutfitslist.h" +#include "llsaveoutfitcombobtn.h"  #include "llsidepanelappearance.h"  #include "llsidetray.h"  #include "lltabcontainer.h" @@ -101,6 +102,8 @@ BOOL LLPanelOutfitsInventory::postBuild()  		LLInventoryModelBackgroundFetch::instance().start(outfits_cat);  	} +	mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this, true)); +  	return TRUE;  } @@ -373,7 +376,6 @@ void LLPanelOutfitsInventory::initListCommandsHandlers()  	mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelOutfitsInventory::onGearButtonClick, this));  	mListCommands->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this)); -	mListCommands->childSetAction("make_outfit_btn", boost::bind(&LLPanelOutfitsInventory::onAddButtonClick, this));  	mListCommands->childSetAction("wear_btn", boost::bind(&LLPanelOutfitsInventory::onWearButtonClick, this));  	LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>("trash_btn"); @@ -396,7 +398,7 @@ void LLPanelOutfitsInventory::updateListCommands()  	mListCommands->childSetEnabled("trash_btn", trash_enabled);  	mListCommands->childSetEnabled("wear_btn", wear_enabled);  	mListCommands->childSetVisible("wear_btn", wear_enabled); -	mListCommands->childSetEnabled("make_outfit_btn", make_outfit_enabled); +	mSaveComboBtn->setSaveBtnEnabled(make_outfit_enabled);  }  void LLPanelOutfitsInventory::onGearButtonClick() @@ -404,11 +406,6 @@ void LLPanelOutfitsInventory::onGearButtonClick()  	showActionMenu(mMenuGearDefault,"options_gear_btn");  } -void LLPanelOutfitsInventory::onAddButtonClick() -{ -	onSave(); -} -  void LLPanelOutfitsInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name)  {  	if (menu) diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h index a0fe91cd80..7bdd37c16c 100644 --- a/indra/newview/llpaneloutfitsinventory.h +++ b/indra/newview/llpaneloutfitsinventory.h @@ -46,6 +46,7 @@ class LLButton;  class LLMenuGL;  class LLSidepanelAppearance;  class LLTabContainer; +class LLSaveOutfitComboBtn;  class LLPanelOutfitsInventory : public LLPanel  { @@ -86,7 +87,7 @@ private:  	LLSaveFolderState*		mSavedFolderState;  	LLTabContainer*			mAppearanceTabs;  	std::string 			mFilterSubString; - +	std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn;  public:  	//////////////////////////////////////////////////////////////////////////////////  	// tab panels @@ -117,7 +118,6 @@ protected:  	void updateListCommands();  	void onGearButtonClick();  	void onWearButtonClick(); -	void onAddButtonClick();  	void showActionMenu(LLMenuGL* menu, std::string spawning_view_name);  	void onTrashButtonClick();  	void onClipboardAction(const LLSD& userdata); diff --git a/indra/newview/llsaveoutfitcombobtn.cpp b/indra/newview/llsaveoutfitcombobtn.cpp new file mode 100644 index 0000000000..b9b577084b --- /dev/null +++ b/indra/newview/llsaveoutfitcombobtn.cpp @@ -0,0 +1,97 @@ +/**  + * @file llsaveoutfitcombobtn.cpp + * @brief Represents outfit save/save as combo button. + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + *  + * Copyright (c) 2010, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llappearancemgr.h" +#include "llpaneloutfitsinventory.h" +#include "llsaveoutfitcombobtn.h" +#include "llviewermenu.h" + +static const std::string SAVE_BTN("save_btn"); +static const std::string SAVE_FLYOUT_BTN("save_flyout_btn"); + +LLSaveOutfitComboBtn::LLSaveOutfitComboBtn(LLPanel* parent, bool saveAsDefaultAction): +	mParent(parent), mSaveAsDefaultAction(saveAsDefaultAction) +{ +	// register action mapping before creating menu +	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar save_registar; +	save_registar.add("Outfit.Save.Action", boost::bind( +			&LLSaveOutfitComboBtn::saveOutfit, this, false)); +	save_registar.add("Outfit.SaveAs.Action", boost::bind( +			&LLSaveOutfitComboBtn::saveOutfit, this, true)); + +	mParent->childSetAction(SAVE_BTN, boost::bind(&LLSaveOutfitComboBtn::saveOutfit, this, mSaveAsDefaultAction)); +	mParent->childSetAction(SAVE_FLYOUT_BTN, boost::bind(&LLSaveOutfitComboBtn::showSaveMenu, this)); + +	mSaveMenu = LLUICtrlFactory::getInstance()->createFromFile< +			LLToggleableMenu> ("menu_save_outfit.xml", gMenuHolder, +			LLViewerMenuHolderGL::child_registry_t::instance()); +} + +void LLSaveOutfitComboBtn::showSaveMenu() +{ +	S32 x, y; +	LLUI::getMousePositionLocal(mParent, &x, &y); + +	mSaveMenu->updateParent(LLMenuGL::sMenuContainer); +	LLMenuGL::showPopup(mParent, mSaveMenu, x, y); +} + +void LLSaveOutfitComboBtn::saveOutfit(bool as_new) +{ +	if (!as_new && LLAppearanceMgr::getInstance()->updateBaseOutfit()) +	{ +		// we don't need to ask for an outfit name, and updateBaseOutfit() successfully saved. +		// If updateBaseOutfit fails, ask for an outfit name anyways +		return; +	} + +	LLPanelOutfitsInventory* panel_outfits_inventory = +			LLPanelOutfitsInventory::findInstance(); +	if (panel_outfits_inventory) +	{ +		panel_outfits_inventory->onSave(); +	} + +	//*TODO how to get to know when base outfit is updated or new outfit is created? +} + +void LLSaveOutfitComboBtn::setMenuItemEnabled(const std::string& item, bool enabled) +{ +	mSaveMenu->setItemEnabled("save_outfit", enabled); +} + +void LLSaveOutfitComboBtn::setSaveBtnEnabled(bool enabled) +{ +	mParent->childSetEnabled(SAVE_BTN, enabled); +} diff --git a/indra/newview/llsaveoutfitcombobtn.h b/indra/newview/llsaveoutfitcombobtn.h new file mode 100644 index 0000000000..fec7122194 --- /dev/null +++ b/indra/newview/llsaveoutfitcombobtn.h @@ -0,0 +1,60 @@ +/**  + * @file llsaveoutfitcombobtn.h + * @brief Represents outfit save/save as combo button. + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + *  + * Copyright (c) 2010, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLSAVEOUTFITCOMBOBTN_H +#define LL_LLSAVEOUTFITCOMBOBTN_H + +class LLButton; + +#include "lltoggleablemenu.h" + +/** + * Represents outfit Save/Save As combo button. + */ +class LLSaveOutfitComboBtn +{ +	LOG_CLASS(LLSaveOutfitComboBtn); +public: +	LLSaveOutfitComboBtn(LLPanel* parent, bool saveAsDefaultAction = false); + +	void showSaveMenu(); +	void saveOutfit(bool as_new = false); +	void setMenuItemEnabled(const std::string& item, bool enabled); +	void setSaveBtnEnabled(bool enabled); + +private: +	bool mSaveAsDefaultAction; +	LLPanel* mParent; +	LLToggleableMenu* mSaveMenu; +}; + +#endif // LL_LLSAVEOUTFITCOMBOBTN_H diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index fb7577c008..161cd40cfc 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -251,6 +251,11 @@ BOOL LLPanelDummyClothingListItem::postBuild()  	return TRUE;  } +LLWearableType::EType LLPanelDummyClothingListItem::getWearableType() const +{ +	return mWearableType; +} +  LLPanelDummyClothingListItem::LLPanelDummyClothingListItem(LLWearableType::EType w_type)   : LLPanelWearableListItem(NULL)   , mWearableType(w_type) diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index 7ad1b5a3ad..de024ed220 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -162,6 +162,7 @@ public:  	/*virtual*/ void updateItem();  	/*virtual*/ BOOL postBuild(); +	LLWearableType::EType getWearableType() const;  protected:  	LLPanelDummyClothingListItem(LLWearableType::EType w_type); diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Left_Flash.png b/indra/newview/skins/default/textures/containers/Toolbar_Left_Flash.pngBinary files differ new file mode 100644 index 0000000000..9f1e2a469d --- /dev/null +++ b/indra/newview/skins/default/textures/containers/Toolbar_Left_Flash.png diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Flash.png b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Flash.pngBinary files differ new file mode 100644 index 0000000000..dd73d655e9 --- /dev/null +++ b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Flash.png diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Right_Flash.png b/indra/newview/skins/default/textures/containers/Toolbar_Right_Flash.pngBinary files differ new file mode 100644 index 0000000000..f6b775c2a0 --- /dev/null +++ b/indra/newview/skins/default/textures/containers/Toolbar_Right_Flash.png diff --git a/indra/newview/skins/default/textures/icons/Generic_Group_Large.png b/indra/newview/skins/default/textures/icons/Generic_Group_Large.pngBinary files differ index c067646c65..de8a39fc8a 100644 --- a/indra/newview/skins/default/textures/icons/Generic_Group_Large.png +++ b/indra/newview/skins/default/textures/icons/Generic_Group_Large.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 29c72a414b..072ea40ee4 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -527,15 +527,18 @@ with the same filename but different name    <texture name="Tool_Grab" file_name="build/Tool_Grab.png" preload="false" />    <texture name="Tool_Zoom" file_name="build/Tool_Zoom.png" preload="false" /> +  <texture name="Toolbar_Left_Flash" file_name="containers/Toolbar_Left_Flash.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" />    <texture name="Toolbar_Left_Off" file_name="containers/Toolbar_Left_Off.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" />    <texture name="Toolbar_Left_Over" file_name="containers/Toolbar_Left_Over.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" />    <texture name="Toolbar_Left_Selected" file_name="containers/Toolbar_Left_Selected.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" />    <texture name="Toolbar_Middle_Off" file_name="containers/Toolbar_Middle_Off.png" preload="false" scale.left="1" scale.bottom="2" scale.top="24" scale.right="30" />    <texture name="Toolbar_Middle_Over" file_name="containers/Toolbar_Middle_Over.png" preload="false" scale.left="1" scale.bottom="2" scale.top="24" scale.right="30" />    <texture name="Toolbar_Middle_Selected" file_name="containers/Toolbar_Middle_Selected.png" preload="false" scale.left="1" scale.bottom="2" scale.top="24" scale.right="30" /> +  <texture name="Toolbar_Middle_Flash" file_name="containers/Toolbar_Middle_Flash.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" />    <texture name="Toolbar_Right_Off" file_name="containers/Toolbar_Right_Off.png" preload="false" scale.left="1" scale.bottom="4" scale.top="24" scale.right="26" />    <texture name="Toolbar_Right_Over" file_name="containers/Toolbar_Right_Over.png" preload="false" scale.left="1" scale.bottom="4" scale.top="24" scale.right="26" />    <texture name="Toolbar_Right_Selected" file_name="containers/Toolbar_Right_Selected.png" preload="false" scale.left="1" scale.bottom="4" scale.top="24" scale.right="26" /> +  <texture name="Toolbar_Right_Flash" file_name="containers/Toolbar_Right_Flash.png" preload="false" scale.left="1" scale.bottom="4" scale.top="24" scale.right="26" />    <texture name="Tooltip" file_name="widgets/Tooltip.png" preload="true" scale.left="2" scale.top="16" scale.right="100" scale.bottom="3" /> diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml index ced8c29199..e123de46c2 100644 --- a/indra/newview/skins/default/xui/en/floater_im_container.xml +++ b/indra/newview/skins/default/xui/en/floater_im_container.xml @@ -27,7 +27,14 @@       halign="left"       use_ellipses="true"       top="0" -     width="394" /> +     width="394"> +      <first_tab +       tab_bottom_image_flash="Toolbar_Left_Flash"/> +      <middle_tab +       tab_bottom_image_flash="Toolbar_Middle_Flash"/> +      <last_tab +       tab_bottom_image_flash="Toolbar_Right_Flash"/> +    </tab_container>      <icon       color="DefaultShadowLight"       enabled="false" diff --git a/indra/newview/skins/default/xui/en/floater_search.xml b/indra/newview/skins/default/xui/en/floater_search.xml index 9ca18d455b..49b3b58113 100644 --- a/indra/newview/skins/default/xui/en/floater_search.xml +++ b/indra/newview/skins/default/xui/en/floater_search.xml @@ -9,6 +9,7 @@   name="floater_search"   help_topic="floater_search"   save_rect="true" + save_visibility="true"   single_instance="true"   title="FIND"   width="650"> diff --git a/indra/newview/skins/default/xui/en/menu_save_outfit.xml b/indra/newview/skins/default/xui/en/menu_save_outfit.xml index a8778df7f6..6285bf7417 100644 --- a/indra/newview/skins/default/xui/en/menu_save_outfit.xml +++ b/indra/newview/skins/default/xui/en/menu_save_outfit.xml @@ -14,9 +14,9 @@          </menu_item_call>      <menu_item_call        name="save_as_new_outfit"  -     label="Save As New"> +     label="Save As">          <menu_item_call.on_click  -         function="Outfit.SaveAsNew.Action" +         function="Outfit.SaveAs.Action"           userdata="" />      </menu_item_call>  </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml index 066992b25d..44437d01eb 100644 --- a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml +++ b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml @@ -8,6 +8,7 @@   height="45"   layout="topleft"   name="Mockup Tab" + selection_enabled="true"   title="Mockup Tab"   translate="false"   width="0"> @@ -18,5 +19,6 @@       multi_select="true"       name="wearable_items_list"       translate="false" +     use_internal_context_menu="false"      />  </accordion_tab> diff --git a/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml index 6d02dd41de..23a08344ea 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml @@ -25,49 +25,58 @@          can_apply_immediately="true"          default_image_name="Default"          follows="left|top" -        height="100" +        height="115"          label="Head Tattoo"          layout="topleft" -        left="30" +        left="20"          name="Head Tattoo"          tool_tip="Click to choose a picture"          top="10" -        width="94" /> +        width="115" > +         <texture_picker.commit_callback +             function="TexturePicker.Commit" /> +       </texture_picker>         <texture_picker          can_apply_immediately="true"          default_image_name="Default"          follows="left|top" -        height="100" +        height="115"          label="Upper Tattoo"          layout="topleft"          left_pad="30"          name="Upper Tattoo"          tool_tip="Click to choose a picture"          top="10" -        width="94" /> +        width="115" > +         <texture_picker.commit_callback +             function="TexturePicker.Commit" /> +       </texture_picker>         <texture_picker          can_apply_immediately="true"          default_image_name="Default"          follows="left|top" -        height="100" +        height="115"          label="Lower Tattoo"          layout="topleft" -        left="30" +        left="20"          name="Lower Tattoo"          tool_tip="Click to choose a picture"          top_pad="10" -        width="94" /> +        width="115" > +         <texture_picker.commit_callback +             function="TexturePicker.Commit" /> +       </texture_picker>         <color_swatch          can_apply_immediately="true"          follows="left|top" -        height="80" +        height="115"          label="Color/Tint"          layout="topleft" -        left_pad="20" +        left_pad="30"          name="Color/Tint"          tool_tip="Click to open color picker" -        top="10" -        width="64" > +        top_delta="0" +        width="115" >           <color_swatch.commit_callback               function="ColorSwatch.Commit" />         </color_swatch> diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index bc984ccc44..abd96c89e7 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -160,7 +160,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap       clip="false"       default_tab_group="2"       follows="all" -     height="495" +     height="468"       width="313"       layout="topleft"       orientation="vertical" @@ -170,7 +170,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap       left="5">          <layout_panel           layout="topleft" -         height="220" +         height="193"           label="IM Control Panel"           min_height="100"           name="outfit_wearables_panel" @@ -190,40 +190,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap               name="cof_wearables_list"               top="0"               width="311" /> - -          <!-- Button bar --> -          <panel -             background_visible="true" -             bevel_style="none" -             follows="bottom|left|right" -             height="27" -             label="bottom_panel" -             layout="topleft" -             left="0" -             name="edit_panel" -             top="193" -             width="313"> -                <button -                 follows="bottom|left" -                 height="25" -                 image_hover_unselected="Toolbar_Left_Over" -                 image_overlay="OptionsMenu_Off" -                 image_selected="Toolbar_Left_Selected" -                 image_unselected="Toolbar_Left_Off" -                 layout="topleft" -                 left="0" -                 name="gear_menu_btn" -                 top="1" -                 width="31" /> -                <icon -                 follows="bottom|left|right" -                 height="25" -                 image_name="Toolbar_Right_Off" -                 layout="topleft" -                 left_pad="1" -                 name="dummy_right_icon" -                 width="281" /> -            </panel>          </layout_panel> @@ -232,7 +198,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap           bg_alpha_color="DkGray2"           auto_resize="true"           default_tab_group="3" -         height="211" +         height="184"           min_height="210"           name="add_wearables_panel"           width="313" @@ -360,82 +326,98 @@ It is calculated as border_size + 2*UIResizeBarOverlap  		            </panel>                  </layout_panel>              </layout_stack> - -            <panel -             background_visible="true" -             bevel_style="none" -             follows="left|right|bottom" -             height="27" -             label="add_wearables_button_bar" -             layout="topleft" -             left="0" -             name="add_wearables_button_bar" -             top_pad="0" -             width="313"> -                <button -                 follows="bottom|left" -                 height="25" -                 image_hover_unselected="Toolbar_Left_Over" -                 image_overlay="OptionsMenu_Off" -                 image_selected="Toolbar_Left_Selected" -                 image_unselected="Toolbar_Left_Off" -                 layout="topleft" -                 left="0" -                 name="wearables_gear_menu_btn" -                 top="1" -                 width="31" /> -                <button -                 follows="bottom|left" -                 height="25" -                 image_hover_unselected="Toolbar_Middle_Over" -                 image_overlay="Hierarchy_View_Disabled" -                 image_selected="Toolbar_Middle_Selected" -                 image_unselected="Toolbar_Middle_Off" -                 is_toggle="true" -                 layout="topleft" -                 left_pad="1" -                 name="folder_view_btn" -                 top="1" -                 width="31" /> -                <button -                 follows="bottom|left" -                 height="25" -                 image_hover_unselected="Toolbar_Middle_Over" -                 image_overlay="List_View_On" -                 image_selected="Toolbar_Middle_Selected" -                 image_unselected="Toolbar_Middle_Off" -                 is_toggle="true" -                 layout="topleft" -                 left_pad="1" -                 name="list_view_btn" -                 top="1" -                 width="31" /> -                <button -                 follows="bottom|left" -                 height="25" -                 image_hover_unselected="Toolbar_Middle_Over" -                 image_overlay="AddItem_Off" -                 image_selected="Toolbar_Middle_Selected" -                 image_unselected="Toolbar_Middle_Off" -                 label="" -                 layout="topleft" -                 left_pad="1" -                 name="add_to_outfit_btn" -                 top="1" -                 width="31" /> -                <icon -                 follows="bottom|left|right" -                 height="25" -                 image_name="Toolbar_Right_Off" -                 layout="topleft" -                 left_pad="1" -                 name="dummy_right_icon" -                 width="184" > -                 </icon> -            </panel> -        </layout_panel> +       </layout_panel>      </layout_stack> +    <!-- Button bar --> +    <panel +     background_visible="true" +     bevel_style="none" +     follows="left|right|bottom" +     height="27" +     label="add_wearables_button_bar" +     layout="topleft" +     left="4" +     name="add_wearables_button_bar" +     top_pad="0" +     width="313"> +        <button +         follows="bottom|left" +         height="25" +         image_hover_unselected="Toolbar_Left_Over" +         image_overlay="OptionsMenu_Off" +         image_selected="Toolbar_Left_Selected" +         image_unselected="Toolbar_Left_Off" +         layout="topleft" +         left="0" +         name="wearables_gear_menu_btn" +         top="1" +         width="31" /> +        <button +         follows="bottom|left" +         height="25" +         image_hover_unselected="Toolbar_Middle_Over" +         image_overlay="Hierarchy_View_Disabled" +         image_selected="Toolbar_Middle_Selected" +         image_unselected="Toolbar_Middle_Off" +         is_toggle="true" +         layout="topleft" +         left_pad="1" +         name="folder_view_btn" +         top="1" +         visible="false" +         width="31" /> +        <button +         follows="bottom|left" +         height="25" +         image_hover_unselected="Toolbar_Middle_Over" +         image_overlay="List_View_On" +         image_selected="Toolbar_Middle_Selected" +         image_unselected="Toolbar_Middle_Off" +         is_toggle="true" +         layout="topleft" +         left_pad="1" +         name="list_view_btn" +         top="1" +         visible="false" +         width="31" /> +        <button +         follows="bottom|left" +         height="25" +         image_hover_unselected="Toolbar_Middle_Over" +         image_overlay="AddItem_Off" +         image_selected="Toolbar_Middle_Selected" +         image_unselected="Toolbar_Middle_Off" +         label="" +         layout="topleft" +         left_pad="1" +         name="add_to_outfit_btn" +         top="1" +         visible="false" +         width="31" /> +       <icon +        follows="bottom|left|right" +        height="25" +        image_name="Toolbar_Right_Off" +        layout="topleft" +        left_pad="1" +        name="add_wearables_dummy_icon" +        top="1" +        visible="false" +        width="184" > +       </icon> +       <icon +        follows="bottom|left|right" +        height="25" +        image_name="Toolbar_Right_Off" +        layout="topleft" +        left="32" +        name="dummy_right_icon" +        top="1" +        width="281" > +       </icon> +    </panel> +      <panel       follows="left|right|bottom"       height="30" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml index 9e59651bd1..13e1f5ba5c 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml @@ -93,17 +93,30 @@           left_pad="1"           name="trash_btn"           tool_tip="Remove selected item" -         width="31"/> -	 <button -	  follows="bottom|left" -		height="23"  -      label="Save Outfit"  -      layout="topleft" -      name="make_outfit_btn" -      tool_tip="Save appearance as an outfit" +         width="31"/>          +     <button +       follows="bottom|left" +       height="23" +       label="Save As" +       left="0"          +       layout="topleft" +       name="save_btn"         top_pad="6" -       left="0" -      width="153" /> +       width="155" /> +     <button +       follows="bottom|left" +       height="23" +       name="save_flyout_btn" +       label="" +       layout="topleft" +       left_pad="-20" +       tab_stop="false" +       image_selected="SegmentedBtn_Right_Selected_Press" +       image_unselected="SegmentedBtn_Right_Off" +       image_pressed="SegmentedBtn_Right_Press" +       image_pressed_selected="SegmentedBtn_Right_Selected_Press" +       image_overlay="Arrow_Small_Up" +       width="20"/>       <button        follows="bottom|left|right"         height="23"  diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 3ec445f9ad..078426d3d9 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3182,4 +3182,19 @@ Abuse Report</string>          If you continue to experience problems, please check your network and firewall setup.    </string> +  <!-- overriding datetime formating.  +	leave emtpy in for current localization this is not needed  +	list of values should be separated with ':' +        example: +	<string name="dateTimeWeekdaysShortNames"> +	Son:Mon:Tue:Wed:Thu:Fri:Sat +	</string>  	 +  --> +  <string name="dateTimeWeekdaysNames"></string> +  <string name="dateTimeWeekdaysShortNames"></string> +  <string name="dateTimeMonthNames"></string> +  <string name="dateTimeMonthShortNames"></string> +  <string name="dateTimeDayFormat"></string> +  <string name="dateTimeAM"></string> +  <string name="dateTimePM"></string>    </strings> diff --git a/indra/newview/skins/default/xui/en/widgets/button.xml b/indra/newview/skins/default/xui/en/widgets/button.xml index c4f0fe5208..6dcc27b469 100644 --- a/indra/newview/skins/default/xui/en/widgets/button.xml +++ b/indra/newview/skins/default/xui/en/widgets/button.xml @@ -7,6 +7,7 @@          image_selected="PushButton_Selected"          image_disabled_selected="PushButton_Selected_Disabled"          image_disabled="PushButton_Disabled" +        image_flash="FlashIconAbsent"          image_top_pad="0"          image_bottom_pad="0"          imgoverlay_label_space="1" diff --git a/indra/newview/skins/default/xui/en/widgets/tab_container.xml b/indra/newview/skins/default/xui/en/widgets/tab_container.xml index 8d6b0c1cfe..30b0a8462a 100644 --- a/indra/newview/skins/default/xui/en/widgets/tab_container.xml +++ b/indra/newview/skins/default/xui/en/widgets/tab_container.xml @@ -13,20 +13,29 @@ label_pad_left - padding to the left of tab button labels                 label_pad_left="4">    <first_tab tab_top_image_unselected="TabTop_Left_Off"                 tab_top_image_selected="TabTop_Left_Selected" +               tab_top_image_flash="FlashIconAbsent"                 tab_bottom_image_unselected="Toolbar_Left_Off"                 tab_bottom_image_selected="Toolbar_Left_Selected" +               tab_bottom_image_flash="FlashIconAbsent"                 tab_left_image_unselected="SegmentedBtn_Left_Disabled" -               tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/> +               tab_left_image_selected="SegmentedBtn_Left_Selected_Over" +               tab_left_image_flash="FlashIconAbsent"/>    <middle_tab tab_top_image_unselected="TabTop_Middle_Off"                 tab_top_image_selected="TabTop_Middle_Selected" +               tab_top_image_flash="FlashIconAbsent"                 tab_bottom_image_unselected="Toolbar_Middle_Off"                 tab_bottom_image_selected="Toolbar_Middle_Selected" +               tab_bottom_image_flash="FlashIconAbsent"                 tab_left_image_unselected="SegmentedBtn_Left_Disabled" -               tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/> +               tab_left_image_selected="SegmentedBtn_Left_Selected_Over" +               tab_left_image_flash="FlashIconAbsent"/>    <last_tab tab_top_image_unselected="TabTop_Right_Off"                 tab_top_image_selected="TabTop_Right_Selected" +               tab_top_image_flash="FlashIconAbsent"                 tab_bottom_image_unselected="Toolbar_Right_Off"                 tab_bottom_image_selected="Toolbar_Right_Selected" +               tab_bottom_image_flash="FlashIconAbsent"                 tab_left_image_unselected="SegmentedBtn_Left_Disabled" -               tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/> +               tab_left_image_selected="SegmentedBtn_Left_Selected_Over" +               tab_left_image_flash="FlashIconAbsent"/>  </tab_container> diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index c0bb14afba..dfc12bc1cb 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?>  <!-- This file contains strings that used to be hardcoded in the source.       It is only for those strings which do not belong in a floater.       For example, the strings used in avatar chat bubbles, and strings @@ -3762,4 +3762,22 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ  	<string name="texture_load_dimensions_error">  		[WIDTH]*[HEIGHT] 以上の画像は読み込めません  	</string> +	<!-- overriding datetime formating. leave emtpy in for current localization this is not needed --> +	<string name="dateTimeWeekdaysNames"> +	Sunday:Monday:Tuesday:Wednesday:Thursday:Friday:Saturday +	</string> +	<string name="dateTimeWeekdaysShortNames"> +	Son:Mon:Tue:Wed:Thu:Fri:Sat +	</string> +	<string name="dateTimeMonthNames"> +	January:February:March:April:May:June:July:August:September:October:November:December +	</string> +	<string name="dateTimeMonthNames"> +	Jan:Feb:Mar:Apr:May:Jun:Jul:Aug:Sep:Oct:Nov:Dec +	</string> +	<string name="dateTimeDayFormat"> +		[MDAY] D +	</string> +        <string name="dateTimeAM">AM</string> +        <string name="dateTimePM">PM</string>  </strings> diff --git a/install.xml b/install.xml index 1265963fb1..ccebe2fe50 100644 --- a/install.xml +++ b/install.xml @@ -1386,23 +1386,23 @@ anguage Infrstructure (CLI) international standard</string>            <key>darwin</key>            <map>              <key>md5sum</key> -            <string>4d29351a842fafe617de65a8183da160</string> +            <string>aa144917d0e33453d3c2cc2c05c6c47c</string>              <key>url</key> -            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-3.1.0001.8744-darwin-20100519.tar.bz2</uri> +            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-3.1.0001.8821-darwin-20100529.tar.bz2</uri>            </map>            <key>linux</key>            <map>              <key>md5sum</key> -            <string>7541138c439b1c0312610d18968f27d2</string> +            <string>98f7945755f3ee8e52f685a3eff4d7be</string>              <key>url</key> -            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-3.1.0001.8744-linux-20100519.tar.bz2</uri> +            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-3.1.0001.8821-linux-20100529.tar.bz2</uri>            </map>            <key>windows</key>            <map>              <key>md5sum</key> -            <string>5d2b049ca5239da2dcebde91f7f25a43</string> +            <string>e8fdd46cb026c2ec72c4489eb3bf39c1</string>              <key>url</key> -            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-3.1.0001.8744-windows-20100519.tar.bz2</uri> +            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-3.1.0001.8821-windows-20100529.tar.bz2</uri>            </map>          </map>        </map> | 
