diff options
61 files changed, 1166 insertions, 168 deletions
| diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp index 9d4e2fa495..9f83fcca35 100644 --- a/indra/llui/lldraghandle.cpp +++ b/indra/llui/lldraghandle.cpp @@ -249,7 +249,7 @@ void LLDragHandleTop::reshapeTitleBox()  	}  	const LLFontGL* font = LLFontGL::getFontSansSerif();  	S32 title_width = getRect().getWidth(); -	title_width -= 2 * LEFT_PAD + 2 * BORDER_PAD + getButtonsRect().getWidth(); +	title_width -= LEFT_PAD + 2 * BORDER_PAD + getButtonsRect().getWidth();  	S32 title_height = llround(font->getLineHeight());  	LLRect title_rect;  	title_rect.setLeftTopAndSize(  diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index a55e9c0395..79c47a1136 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1788,13 +1788,16 @@ void LLFloater::updateTitleButtons()  					llround((F32)floater_close_box_size * mButtonScale));  			} -			if(!buttons_rect.isValid()) +			// first time here, init 'buttons_rect' +			if(1 == button_count)  			{  				buttons_rect = btn_rect;  			}  			else  			{ -				mDragOnLeft ? buttons_rect.mRight + btn_rect.mRight :  +				// if mDragOnLeft=true then buttons are on top-left side vertically aligned +				// title is not displayed in this case, calculating 'buttons_rect' for future use +				mDragOnLeft ? buttons_rect.mBottom -= btn_rect.mBottom :   					buttons_rect.mLeft = btn_rect.mLeft;  			}  			mButtons[i]->setRect(btn_rect); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 47fde08a9d..b3f7a64efb 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -438,6 +438,7 @@ set(viewer_SOURCE_FILES      lltracker.cpp      lltransientdockablefloater.cpp      lltransientfloatermgr.cpp +    llpanelgenerictip.cpp      lluilistener.cpp      lluploaddialog.cpp      llurl.cpp @@ -940,6 +941,7 @@ set(viewer_HEADER_FILES      lltracker.h      lltransientdockablefloater.h      lltransientfloatermgr.h +    llpanelgenerictip.h      lluiconstants.h      lluilistener.h      lluploaddialog.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index dd38965a5a..3197064281 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10646,6 +10646,28 @@        <key>Value</key>        <real>50.0</real>      </map> +    <key>WellIconFlashCount</key> +    <map> +      <key>Comment</key> +      <string>Number of flashes of IM Well and Notification Well icons after which flashing buttons stay lit up. Requires restart.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>3</integer> +    </map> +    <key>WellIconFlashPeriod</key> +    <map> +      <key>Comment</key> +      <string>Period at which IM Well and Notification Well icons flash (seconds). Requires restart.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <real>0.25</real> +    </map>      <key>WindLightUseAtmosShaders</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index e0f1d5348d..4a30ba3066 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -593,6 +593,55 @@ bool LLAppearanceMgr::getBaseOutfitName(std::string& name)  	return false;  } +const LLUUID LLAppearanceMgr::getBaseOutfitUUID() +{ +	const LLViewerInventoryItem* outfit_link = getBaseOutfitLink(); +	if (!outfit_link || !outfit_link->getIsLinkType()) return LLUUID::null; + +	const LLViewerInventoryCategory* outfit_cat = outfit_link->getLinkedCategory(); +	if (!outfit_cat) return LLUUID::null; + +	if (outfit_cat->getPreferredType() != LLFolderType::FT_OUTFIT) +	{ +		llwarns << "Expected outfit type:" << LLFolderType::FT_OUTFIT << " but got type:" << outfit_cat->getType() << " for folder name:" << outfit_cat->getName() << llendl; +		return LLUUID::null; +	} + +	return outfit_cat->getUUID(); +} + +bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_update) +{ +	if (item_id_to_wear.isNull()) return false; + +	//only the item from a user's inventory is allowed +	if (!gInventory.isObjectDescendentOf(item_id_to_wear, gInventory.getRootFolderID())) return false; + +	LLViewerInventoryItem* item_to_wear = gInventory.getItem(item_id_to_wear); +	if (!item_to_wear) return false; + +	switch (item_to_wear->getType()) +	{ +	case LLAssetType::AT_CLOTHING: +	case LLAssetType::AT_BODYPART: +		// Don't wear anything until initial wearables are loaded, can +		// destroy clothing items. +		if (!gAgentWearables.areWearablesLoaded()) +		{ +			LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded"); +			return false; +		} +		addCOFItemLink(item_to_wear, do_update); +		break; +	case LLAssetType::AT_OBJECT: +		rez_attachment(item_to_wear, NULL); +		break; +	default: return false;; +	} + +	return true; +} +  // Update appearance from outfit folder.  void LLAppearanceMgr::changeOutfit(bool proceed, const LLUUID& category, bool append)  { @@ -1516,6 +1565,28 @@ void LLAppearanceMgr::onFirstFullyVisible()  	autopopulateOutfits();  } +bool LLAppearanceMgr::updateBaseOutfit() +{ +	const LLUUID base_outfit_id = getBaseOutfitUUID(); +	if (base_outfit_id.isNull()) return false; + +	// in a Base Outfit we do not remove items, only links +	purgeCategory(base_outfit_id, false); + +	//COF contains only links so we copy to the Base Outfit only links +	shallowCopyCategoryContents(getCOF(), base_outfit_id, NULL); + +	return true; +} + +void LLAppearanceMgr::wearBaseOutfit() +{ +	const LLUUID& base_outfit_id = getBaseOutfitUUID(); +	if (base_outfit_id.isNull()) return; +	 +	updateCOF(base_outfit_id); +} +  //#define DUMP_CAT_VERBOSE  void LLAppearanceMgr::dumpCat(const LLUUID& cat_id, const std::string& msg) diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 40b8844731..dffd421898 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -75,6 +75,12 @@ public:  	const LLViewerInventoryItem *getBaseOutfitLink();  	bool getBaseOutfitName(std::string &name); +	// find the UUID of the currently worn outfit (Base Outfit) +	const LLUUID getBaseOutfitUUID(); + +	// Wear/attach an item (from a user's inventory) on the agent +	bool wearItemOnAvatar(const LLUUID& item_to_wear, bool do_update = true); +  	// Update the displayed outfit name in UI.  	void updatePanelOutfitName(const std::string& name); @@ -123,6 +129,12 @@ public:  	// Create initial outfits from library.  	void autopopulateOutfits(); +	void wearBaseOutfit(); + +	// Overrides the base outfit with the content from COF +	// @return false if there is no base outfit +	bool updateBaseOutfit(); +  protected:  	LLAppearanceMgr();  	~LLAppearanceMgr(); diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index c85c72837c..764d54a987 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -35,6 +35,8 @@  #include "llavataractions.h" +#include "boost/lambda/lambda.hpp"	// for lambda::constant +  #include "llsd.h"  #include "lldarray.h"  #include "llnotifications.h" @@ -46,6 +48,7 @@  #include "llappviewer.h"		// for gLastVersionChannel  #include "llcachename.h"  #include "llcallingcard.h"		// for LLAvatarTracker +#include "llfloateravatarpicker.h"	// for LLFloaterAvatarPicker  #include "llfloatergroupinvite.h"  #include "llfloatergroups.h"  #include "llfloaterreg.h" @@ -54,6 +57,7 @@  #include "llinventorymodel.h"	// for gInventory.findCategoryUUIDForType  #include "llimview.h"			// for gIMMgr  #include "llmutelist.h" +#include "llnotificationsutil.h"	// for LLNotificationsUtil  #include "llrecentpeople.h"  #include "llsidetray.h"  #include "lltrans.h" @@ -425,6 +429,16 @@ void LLAvatarActions::share(const LLUUID& id)  	}  } +//static +void LLAvatarActions::shareWithAvatars() +{ +	LLFloaterAvatarPicker* picker = +		LLFloaterAvatarPicker::show(NULL, FALSE, TRUE); +	picker->setOkBtnEnableCb(boost::lambda::constant(false)); + +	LLNotificationsUtil::add("ShareNotification"); +} +  // static  void LLAvatarActions::toggleBlock(const LLUUID& id)  { diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 9d8b4b4e23..d106a83eea 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -114,6 +114,11 @@ public:  	static void share(const LLUUID& id);  	/** +	 * Share items with the picked avatars. +	 */ +	static void shareWithAvatars(); + +	/**  	 * Block/unblock the avatar.  	 */  	static void toggleBlock(const LLUUID& id); diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index bed5c01d7a..0b58c8f476 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -189,7 +189,7 @@ void LLCallFloater::draw()  	// Seems this is a problem somewhere in Voice Client (LLVoiceClient::participantAddedEvent)  //	onChange(); -	bool is_moderator_muted = gVoiceClient->getIsModeratorMuted(gAgentID); +	bool is_moderator_muted = LLVoiceClient::getInstance()->getIsModeratorMuted(gAgentID);  	if (mIsModeratorMutedVoice != is_moderator_muted)  	{ @@ -470,7 +470,7 @@ void LLCallFloater::updateAgentModeratorState()  static void get_voice_participants_uuids(uuid_vec_t& speakers_uuids)  {  	// Get a list of participants from VoiceClient -	LLVoiceClient::participantMap *voice_map = gVoiceClient->getParticipantList(); +	LLVoiceClient::participantMap *voice_map = LLVoiceClient::getInstance()->getParticipantList();  	if (voice_map)  	{  		for (LLVoiceClient::participantMap::const_iterator iter = voice_map->begin(); @@ -601,10 +601,13 @@ void LLCallFloater::updateNotInVoiceParticipantState(LLAvatarListItem* item)  			}  		}  		break; -	case STATE_INVITED:  	case STATE_LEFT:  		// nothing to do. These states should not be changed.  		break; +	case STATE_INVITED: +		// If avatar was invited into group chat and went offline it is still exists in mSpeakerStateMap +		// If it goes online it will be rendered as JOINED via LAvatarListItem. +		// Lets update its visual representation. See EXT-6660  	case STATE_UNKNOWN:  		// If an avatarID is not found in a speakers list from VoiceClient and  		// a panel with this ID has an UNKNOWN status this means that this person @@ -725,7 +728,7 @@ void LLCallFloater::connectToChannel(LLVoiceChannel* channel)  void LLCallFloater::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)  {  	// check is voice operational and if it doesn't work hide VCP (EXT-4397) -	if(LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking()) +	if(LLVoiceClient::voiceEnabled() && LLVoiceClient::getInstance()->voiceWorking())  	{  		updateState(new_state);  	} diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 81edb55f93..aef36b677c 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -324,6 +324,8 @@ void LLNearbyChatToastPanel::draw()  			icon->setDrawTooltip(mSourceType == CHAT_SOURCE_AGENT);  			if(mSourceType == CHAT_SOURCE_AGENT)  				icon->setValue(mFromID); +			else if(mSourceType == CHAT_SOURCE_SYSTEM) +				icon->setValue(LLSD("SL_Logo"));  			else  				icon->setValue(LLSD("OBJECT_Icon"));  		} diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index e39384b7b2..05d3d70c74 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -131,8 +131,6 @@ LLSysWellChiclet::Params::Params()  : button("button")  , unread_notifications("unread_notifications")  , max_displayed_count("max_displayed_count", 99) -, flash_to_lit_count("flash_to_lit_count", 3) -, flash_period("flash_period", 0.5F)  {  	button.name("button");  	button.tab_stop(FALSE); @@ -152,7 +150,13 @@ LLSysWellChiclet::LLSysWellChiclet(const Params& p)  	mButton = LLUICtrlFactory::create<LLButton>(button_params);  	addChild(mButton); -	mFlashToLitTimer = new FlashToLitTimer(p.flash_to_lit_count, p.flash_period, boost::bind(&LLSysWellChiclet::changeLitState, this)); +	// use settings from settings.xml to be able change them via Debug settings. See EXT-5973. +	// Due to Timer is implemented as derived class from EventTimer it is impossible to change period +	// in runtime. So, both settings are made as required restart. +	static S32 flash_to_lit_count = gSavedSettings.getS32("WellIconFlashCount"); +	static F32 flash_period = gSavedSettings.getF32("WellIconFlashPeriod"); + +	mFlashToLitTimer = new FlashToLitTimer(flash_to_lit_count, flash_period, boost::bind(&LLSysWellChiclet::changeLitState, this));  }  LLSysWellChiclet::~LLSysWellChiclet() diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index ba17c5970e..97f494b817 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -800,16 +800,6 @@ public:  		 */  		Optional<S32> max_displayed_count; -		/** -		 * How many time chiclet should flash before set "Lit" state. Default value is 3. -		 */ -		Optional<S32> flash_to_lit_count; - -		/** -		 * Period of flashing while setting "Lit" state, in seconds. Default value is 0.5. -		 */ -		Optional<F32> flash_period; -  		Params();  	}; diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 2cb0cdf368..01a699506e 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -38,6 +38,8 @@  #include "llcallingcard.h"  #include "llfocusmgr.h"  #include "llfloaterreg.h" +#include "llimview.h"			// for gIMMgr +#include "lltooldraganddrop.h"	// for LLToolDragAndDrop  #include "llviewercontrol.h"  #include "llworld.h" @@ -370,6 +372,68 @@ void LLFloaterAvatarPicker::setAllowMultiple(BOOL allow_multiple)  	getChild<LLScrollListCtrl>("Friends")->setAllowMultipleSelection(allow_multiple);  } +LLScrollListCtrl* LLFloaterAvatarPicker::getActiveList() +{ +	std::string acvtive_panel_name; +	LLScrollListCtrl* list = NULL; +	LLPanel* active_panel = childGetVisibleTab("ResidentChooserTabs"); +	if(active_panel) +	{ +		acvtive_panel_name = active_panel->getName(); +	} +	if(acvtive_panel_name == "SearchPanel") +	{ +		list = getChild<LLScrollListCtrl>("SearchResults"); +	} +	else if(acvtive_panel_name == "NearMePanel") +	{ +		list = getChild<LLScrollListCtrl>("NearMe"); +	} +	else if (acvtive_panel_name == "FriendsPanel") +	{ +		list = getChild<LLScrollListCtrl>("Friends"); +	} +	return list; +} + +BOOL LLFloaterAvatarPicker::handleDragAndDrop(S32 x, S32 y, MASK mask, +											  BOOL drop, EDragAndDropType cargo_type, +											  void *cargo_data, EAcceptance *accept, +											  std::string& tooltip_msg) +{ +	LLScrollListCtrl* list = getActiveList(); +	if(list) +	{ +		LLRect rc_list; +		LLRect rc_point(x,y,x,y); +		if (localRectToOtherView(rc_point, &rc_list, list)) +		{ +			// Keep selected only one item +			list->deselectAllItems(TRUE); +			list->selectItemAt(rc_list.mLeft, rc_list.mBottom, mask); +			LLScrollListItem* selection = list->getFirstSelected(); +			if (selection) +			{ +				LLUUID session_id = LLUUID::null; +				LLUUID dest_agent_id = selection->getUUID(); +				std::string avatar_name = selection->getColumn(0)->getValue().asString(); +				if (dest_agent_id.notNull() && dest_agent_id != gAgentID) +				{ +					if (drop) +					{ +						// Start up IM before give the item +						session_id = gIMMgr->addSession(avatar_name, IM_NOTHING_SPECIAL, dest_agent_id); +					} +					return LLToolDragAndDrop::handleGiveDragAndDrop(dest_agent_id, session_id, drop, +																	cargo_type, cargo_data, accept); +				} +			} +		} +	} +	*accept = ACCEPT_NO; +	return TRUE; +} +  // static   void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void**)  { diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index 860f3930ef..e69b814f9f 100644 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -37,6 +37,8 @@  #include <vector> +class LLScrollListCtrl; +  class LLFloaterAvatarPicker : public LLFloater  {  public: @@ -59,6 +61,11 @@ public:  	static void processAvatarPickerReply(class LLMessageSystem* msg, void**); +	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, +						   BOOL drop, EDragAndDropType cargo_type, +						   void *cargo_data, EAcceptance *accept, +						   std::string& tooltip_msg); +  private:  	void editKeystroke(class LLLineEditor* caller, void* user_data); @@ -77,6 +84,7 @@ private:  	void find();  	void setAllowMultiple(BOOL allow_multiple); +	LLScrollListCtrl* getActiveList();  	virtual void draw();  	virtual BOOL handleKeyHere(KEY key, MASK mask); diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 03389e62d7..a6a8194685 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -168,6 +168,8 @@ public:  	void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; }  	void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f);  	LLFloaterPostcard* savePostcard(); +	void confirmSavingTexture(bool set_as_profile_pic = false); +	bool onSavingTextureConfirmed(const LLSD& notification, const LLSD& response, bool set_as_profile_pic);  	void saveTexture(bool set_as_profile_pic = false);  	BOOL saveLocal();  	void saveWeb(std::string url); @@ -983,6 +985,26 @@ void profile_pic_upload_callback(const LLUUID& uuid)  	floater->setAsProfilePic(uuid);  } +void LLSnapshotLivePreview::confirmSavingTexture(bool set_as_profile_pic) +{ +	LLSD args; +	args["AMOUNT"] = "10"; // *TODO: there's currently no way to avoid hardcoding the upload price +	LLNotificationsUtil::add("UploadConfirmation", args, LLSD(), +			boost::bind(&LLSnapshotLivePreview::onSavingTextureConfirmed, this, _1, _2, set_as_profile_pic)); +} + +bool LLSnapshotLivePreview::onSavingTextureConfirmed(const LLSD& notification, const LLSD& response, bool set_as_profile_pic) +{ +	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + +	if (option == 0) +	{ +		saveTexture(set_as_profile_pic); +	} + +	return false; +} +  void LLSnapshotLivePreview::saveTexture(bool set_as_profile_pic)  { @@ -1746,7 +1768,7 @@ void LLFloaterSnapshot::Impl::onCommitProfilePic(LLFloaterSnapshot* view)  	if(previewp)  	{ -		previewp->saveTexture(true); +		previewp->confirmSavingTexture(true);  	}  } @@ -1768,7 +1790,7 @@ void LLFloaterSnapshot::Impl::onCommitSnapshot(LLFloaterSnapshot* view, LLSnapsh  		}  		else if (type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE)  		{ -			previewp->saveTexture(); +			previewp->confirmSavingTexture();  		}  		else if (type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD)  		{ diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index e0f155a6a9..92b994ad67 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -297,7 +297,7 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES  				LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, message);  				break;  			case LLVoiceChannel::STATE_CONNECTED : -				message = other_avatar_name + " " + joined_call; +				message = LLTrans::getString("answered_call");  				LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, message);  			default:  				break; @@ -1713,7 +1713,6 @@ void LLOutgoingCallDialog::show(const LLSD& key)  			channel_name = LLTextUtil::formatPhoneNumber(channel_name);  		}  		childSetTextArg("nearby", "[VOICE_CHANNEL_NAME]", channel_name); -		childSetTextArg("nearby_P2P_by_other", "[VOICE_CHANNEL_NAME]", mPayload["disconnected_channel_name"].asString());  		// skipping "You will now be reconnected to nearby" in notification when call is ended by disabling voice,  		// so no reconnection to nearby chat happens (EXT-4397) diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index b552b5ac07..76c0d69dda 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -672,6 +672,11 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	}  	else  	{ +		items.push_back(std::string("Share")); +		if (!canShare()) +		{ +			disabled_items.push_back(std::string("Share")); +		}  		items.push_back(std::string("Open"));  		items.push_back(std::string("Properties")); @@ -1031,6 +1036,38 @@ bool LLInvFVBridge::isInOutfitsSidePanel() const  	return outfit_panel->isTabPanel(my_panel);  } +bool LLInvFVBridge::canShare() +{ +	const LLInventoryModel* model = getInventoryModel(); +	if(!model) +	{ +		return false; +	} + +	LLViewerInventoryItem *item = model->getItem(mUUID); +	if (item) +	{ +		bool allowed = false; +		allowed = LLInventoryCollectFunctor::itemTransferCommonlyAllowed(item); +		if (allowed && +			!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) +		{ +			allowed = false; +		} +		if (allowed && +			!item->getPermissions().allowCopyBy(gAgent.getID())) +		{ +			allowed = false; +		} +		return allowed; +	} + +	LLViewerInventoryCategory* cat = model->getCategory(mUUID); + +	// All categories can be given. +	return cat != NULL; +} +  // +=================================================+  // |        InventoryFVBridgeBuilder                 |  // +=================================================+ @@ -2748,7 +2785,13 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	{  		mDisabledItems.push_back(std::string("Delete System Folder"));  	} -	 + +	mItems.push_back(std::string("Share")); +	if (!canShare()) +	{ +		mDisabledItems.push_back(std::string("Share")); +	} +  	hide_context_entries(menu, mItems, mDisabledItems);  } @@ -3167,6 +3210,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,  			}  			else  			{ +				// store dad inventory item to select added one later. See EXT-4347 +				set_dad_inventory_item(inv_item, mUUID); +  				LLNotification::Params params("MoveInventoryFromObject");  				params.functor.function(boost::bind(move_task_inventory_callback, _1, _2, move_inv));  				LLNotifications::instance().forceResponse(params, 0); @@ -3263,6 +3309,12 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	}  	else  	{ +		items.push_back(std::string("Share")); +		if (!canShare()) +		{ +			disabled_items.push_back(std::string("Share")); +		} +  		items.push_back(std::string("Open"));  		items.push_back(std::string("Properties")); @@ -3351,6 +3403,11 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	}  	else  	{ +		items.push_back(std::string("Share")); +		if (!canShare()) +		{ +			disabled_items.push_back(std::string("Share")); +		}  		items.push_back(std::string("Sound Open"));  		items.push_back(std::string("Properties")); @@ -3397,6 +3454,11 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	}  	else  	{ +		items.push_back(std::string("Share")); +		if (!canShare()) +		{ +			disabled_items.push_back(std::string("Share")); +		}  		items.push_back(std::string("Landmark Open"));  		items.push_back(std::string("Properties")); @@ -3614,6 +3676,11 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	}  	else  	{ +		items.push_back(std::string("Share")); +		if (!canShare()) +		{ +			disabled_items.push_back(std::string("Share")); +		}  		items.push_back(std::string("Open"));  		items.push_back(std::string("Properties")); @@ -3884,6 +3951,11 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	}  	else  	{ +		items.push_back(std::string("Share")); +		if (!canShare()) +		{ +			disabled_items.push_back(std::string("Share")); +		}  		bool is_sidepanel = isInOutfitsSidePanel();  		if (!is_sidepanel) @@ -3942,6 +4014,11 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	}  	else  	{ +		items.push_back(std::string("Share")); +		if (!canShare()) +		{ +			disabled_items.push_back(std::string("Share")); +		}  		items.push_back(std::string("Animation Open"));  		items.push_back(std::string("Properties")); @@ -4218,6 +4295,11 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	}  	else  	{ +		items.push_back(std::string("Share")); +		if (!canShare()) +		{ +			disabled_items.push_back(std::string("Share")); +		}  		bool is_sidepanel = isInOutfitsSidePanel();  		if (!is_sidepanel) @@ -4607,6 +4689,11 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  			can_open = FALSE;  		} +		items.push_back(std::string("Share")); +		if (!canShare()) +		{ +			disabled_items.push_back(std::string("Share")); +		}  		bool is_sidepanel = isInOutfitsSidePanel();  		if (can_open && !is_sidepanel) diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index e7b3785a48..f378d219f6 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -125,6 +125,8 @@ public:  	// Allow context menus to be customized for side panel.  	bool isInOutfitsSidePanel() const; +	bool canShare(); +  	//--------------------------------------------------------------------  	// Convenience functions for adding various common menu options.  	//-------------------------------------------------------------------- diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 83e1bbd5a0..922fcc16c0 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -495,6 +495,69 @@ void LLInventoryExistenceObserver::changed(U32 mask)  	}  } +void LLInventoryMoveFromWorldObserver::changed(U32 mask) +{ +	if(!(mask & LLInventoryObserver::ADD)) +	{ +		return; +	} + +	// nothing is watched +	if (mWatchedAssets.size() == 0) +	{ +		return; +	} + +	LLPointer<LLViewerInventoryItem> item = new LLViewerInventoryItem; +	LLMessageSystem* msg = gMessageSystem; +	S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_InventoryData); +	for(S32 i = 0; i < num_blocks; ++i) +	{ +		item->unpackMessage(msg, _PREHASH_InventoryData, i); +		const LLUUID& asset_uuid = item->getAssetUUID(); +		if (item->getUUID().notNull() && asset_uuid.notNull()) +		{ +			if (isAssetWatched(asset_uuid)) +			{ +				LL_DEBUGS("Inventory_Move") << "Found asset UUID: " << asset_uuid << LL_ENDL; +				mAddedItems.push_back(item->getUUID()); +			} +		} +	} + +	if (mAddedItems.size() == mWatchedAssets.size()) +	{ +		done(); +		LL_DEBUGS("Inventory_Move") << "All watched items are added & processed." << LL_ENDL; +		mAddedItems.clear(); + +		// Unable to clean watched items here due to somebody can require to check them in current frame. +		// set dirty state to clean them while next watch cycle. +		mIsDirty = true; +	} +} + +void LLInventoryMoveFromWorldObserver::watchAsset(const LLUUID& asset_id) +{ +	if(asset_id.notNull()) +	{ +		if (mIsDirty) +		{ +			LL_DEBUGS("Inventory_Move") << "Watched items are dirty. Clean them." << LL_ENDL; +			mWatchedAssets.clear(); +			mIsDirty = false; +		} + +		mWatchedAssets.push_back(asset_id); +		onAssetAdded(asset_id); +	} +} + +bool LLInventoryMoveFromWorldObserver::isAssetWatched( const LLUUID& asset_id ) +{ +	return std::find(mWatchedAssets.begin(), mWatchedAssets.end(), asset_id) != mWatchedAssets.end(); +} +  void LLInventoryAddedObserver::changed(U32 mask)  {  	if(!(mask & LLInventoryObserver::ADD)) diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h index ba70552ebc..b710a9d326 100644 --- a/indra/newview/llinventoryobserver.h +++ b/indra/newview/llinventoryobserver.h @@ -194,6 +194,36 @@ protected:  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLInventoryMovedObserver +// +// This class is used as a base class for doing something when all the +// item for observed asset ids were added into the inventory. +// Derive a class from this class and implement the done() method to do +// something useful. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLInventoryMoveFromWorldObserver : public LLInventoryObserver +{ +public: +	LLInventoryMoveFromWorldObserver() : mIsDirty(false) {} +	virtual void changed(U32 mask); + +	void watchAsset(const LLUUID& asset_id); +	bool isAssetWatched(const LLUUID& asset_id); + +protected: +	virtual void onAssetAdded(const LLUUID& asset_id) {} +	virtual void done() = 0; + +	typedef std::vector<LLUUID> item_ref_t; +	item_ref_t mAddedItems; +	item_ref_t mWatchedAssets; + +private: +	bool mIsDirty; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Class LLInventoryAddedObserver  //  // This class is used as a base class for doing something when  diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index c6c2d23a4b..6ed7723aff 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -38,6 +38,7 @@  #include "llagent.h"  #include "llagentwearables.h"  #include "llappearancemgr.h" +#include "llavataractions.h"  #include "llfloaterinventory.h"  #include "llfloaterreg.h"  #include "llimfloater.h" @@ -99,6 +100,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :  	mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLInventoryPanel::doCreate, this, _2));  	mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2));  	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this)); +	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars));  	if (mStartFolderString != "")  	{ @@ -669,7 +671,8 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  	// If folder view is empty the (x, y) point won't be in its rect  	// so the handler must be called explicitly. -	if (!mFolderRoot->hasVisibleChildren()) +	// but only if was not handled before. See EXT-6746. +	if (!handled && !mFolderRoot->hasVisibleChildren())  	{  		handled = mFolderRoot->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);  	} diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index e199f9f180..9824517ed1 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -56,7 +56,6 @@ LLToastPanelBase* createToastPanel()  	return item;  } -  class LLNearbyChatScreenChannel: public LLScreenChannelBase  {  public: @@ -88,11 +87,7 @@ public:  	{  		for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)  		{ -			LLToast* toast = (*it); -			toast->setVisible(FALSE); -			toast->stopTimer(); -			m_toast_pool.push_back(toast); - +			addToToastPool((*it));  		}  		m_active_toasts.clear();  	}; @@ -105,6 +100,14 @@ public:  	}  protected: +	void	addToToastPool(LLToast* toast) +	{ +		toast->setVisible(FALSE); +		toast->stopTimer(); +		toast->setIsHidden(true); +		m_toast_pool.push_back(toast); +	} +  	void	createOverflowToast(S32 bottom, F32 timer);  	create_toast_panel_callback_t m_create_toast_panel_callback_t; @@ -132,11 +135,12 @@ void LLNearbyChatScreenChannel::onToastFade(LLToast* toast)  	//fade mean we put toast to toast pool  	if(!toast)  		return; -	m_toast_pool.push_back(toast);  	std::vector<LLToast*>::iterator pos = std::find(m_active_toasts.begin(),m_active_toasts.end(),toast);  	if(pos!=m_active_toasts.end())  		m_active_toasts.erase(pos); + +	addToToastPool(toast);  	arrangeToasts();  } @@ -228,7 +232,7 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification)  	toast->reshapeToPanel();  	toast->resetTimer(); -	m_active_toasts.insert(m_active_toasts.begin(),toast); +	m_active_toasts.push_back(toast);  	arrangeToasts();  } @@ -240,7 +244,14 @@ void LLNearbyChatScreenChannel::arrangeToasts()  	hideToastsFromScreen(); -	showToastsBottom();					 +	showToastsBottom(); +} + +int sort_toasts_predicate(LLToast* first,LLToast* second) +{ +	F32 v1 = first->getTimer()->getEventTimer().getElapsedTimeF32(); +	F32 v2 = second->getTimer()->getEventTimer().getElapsedTimeF32(); +	return v1 < v2;  }  void LLNearbyChatScreenChannel::showToastsBottom() @@ -252,39 +263,41 @@ void LLNearbyChatScreenChannel::showToastsBottom()  	S32		bottom = getRect().mBottom;  	S32		margin = gSavedSettings.getS32("ToastGap"); +	//sort active toasts +	std::sort(m_active_toasts.begin(),m_active_toasts.end(),sort_toasts_predicate); + +	//calc max visible item and hide other toasts. +  	for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)  	{ -		LLToast* toast = (*it); -		S32 toast_top = bottom + toast->getRect().getHeight() + margin; +		S32 toast_top = bottom + (*it)->getRect().getHeight() + margin;  		if(toast_top > gFloaterView->getRect().getHeight())  		{  			while(it!=m_active_toasts.end())  			{ -				toast->setVisible(FALSE); -				toast->stopTimer(); -				m_toast_pool.push_back(toast); +				addToToastPool((*it));  				it=m_active_toasts.erase(it);  			}  			break;  		} -		bottom = toast_top - toast->getTopPad(); -	} - -	// use reverse order to provide correct z-order and avoid toast blinking -	for(std::vector<LLToast*>::reverse_iterator it = m_active_toasts.rbegin(); it != m_active_toasts.rend(); ++it) -	{  		LLToast* toast = (*it); -		S32 toast_top = bottom + toast->getTopPad();  		toast_rect = toast->getRect(); -		toast_rect.setLeftTopAndSize(getRect().mLeft , toast_top, toast_rect.getWidth() ,toast_rect.getHeight()); +		toast_rect.setLeftTopAndSize(getRect().mLeft , bottom + toast_rect.getHeight(), toast_rect.getWidth() ,toast_rect.getHeight());  		toast->setRect(toast_rect); +		bottom += toast_rect.getHeight() + margin; +	} +	 +	// use reverse order to provide correct z-order and avoid toast blinking +	 +	for(std::vector<LLToast*>::reverse_iterator it = m_active_toasts.rbegin(); it != m_active_toasts.rend(); ++it) +	{ +		LLToast* toast = (*it);  		toast->setIsHidden(false);  		toast->setVisible(TRUE); -		bottom = toast->getRect().mBottom - margin;  	}  } diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp index afc00bf7ef..407de79c89 100644 --- a/indra/newview/llnotificationtiphandler.cpp +++ b/indra/newview/llnotificationtiphandler.cpp @@ -157,6 +157,7 @@ bool LLTipHandler::processNotification(const LLSD& notify)  		}  		LLToastPanel* notify_box = NULL; +		// TODO: this should be implemented in LLToastPanel::buidPanelFromNotification  		if("FriendOffline" == notification->getName() || "FriendOnline" == notification->getName())  		{  			LLOnlineStatusToast::Params p; @@ -167,6 +168,14 @@ bool LLTipHandler::processNotification(const LLSD& notify)  		}  		else  		{ +			notify_box = LLToastPanel::buidPanelFromNotification(notification); +		} + +		// TODO: this if statement should be removed  after modification of +		// LLToastPanel::buidPanelFromNotification() to allow create generic tip panel +		// for all tip notifications except FriendOnline and FriendOffline +		if (notify_box == NULL) +		{  			notify_box = new LLToastNotifyPanel(notification);  		} diff --git a/indra/newview/llpanelgenerictip.cpp b/indra/newview/llpanelgenerictip.cpp new file mode 100644 index 0000000000..2e977faf09 --- /dev/null +++ b/indra/newview/llpanelgenerictip.cpp @@ -0,0 +1,56 @@ +/**  + * @file llpanelgenerictip.cpp + * @brief Represents a generic panel for a notifytip notifications. As example: + * "SystemMessageTip", "Cancelled", "UploadWebSnapshotDone". + * + * $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 "llpanelgenerictip.h" +#include "llnotifications.h" + +/** + * Generic toast tip panel. + * This is particular case of toast panel that decoupled from LLToastNotifyPanel. + * From now LLToastNotifyPanel is deprecated and will be removed after all  panel + * types are represented in separate classes. + */ +LLPanelGenericTip::LLPanelGenericTip( +		const LLNotificationPtr& notification) : +	LLToastPanel(notification) +{ +	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_generic_tip.xml"); + +	childSetValue("message", notification->getMessage()); + +	// set line max count to 3 in case of a very long name +	snapToMessageHeight(getChild<LLTextBox> ("message"), 3); +} + diff --git a/indra/newview/llpanelgenerictip.h b/indra/newview/llpanelgenerictip.h new file mode 100644 index 0000000000..0eb502498a --- /dev/null +++ b/indra/newview/llpanelgenerictip.h @@ -0,0 +1,47 @@ +/**  + * @file llpanelgenerictip.h + * @brief Represents a generic panel for a notifytip notifications. As example: + * "SystemMessageTip", "Cancelled", "UploadWebSnapshotDone". + * + * $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_PANELGENERICTIP_H +#define LL_PANELGENERICTIP_H + +#include "lltoastpanel.h" + +class LLPanelGenericTip: public LLToastPanel +{ +	// disallow instantiation of this class +private: +	// grant privileges to instantiate this class to LLToastPanel +	friend class LLToastPanel; +	LLPanelGenericTip(const LLNotificationPtr& notification); +}; +#endif /* LL_PANELGENERICTIP_H */ diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index a1cdbdad59..67d40a39b1 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -675,6 +675,7 @@ void LLLandmarksPanel::initListCommandsHandlers()  	trash_btn->setDragAndDropHandler(boost::bind(&LLLandmarksPanel::handleDragAndDropToTrash, this  			,	_4 // BOOL drop  			,	_5 // EDragAndDropType cargo_type +			,	_6 // void* cargo_data  			,	_7 // EAcceptance* accept  			)); @@ -1109,7 +1110,7 @@ void LLLandmarksPanel::onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* own  	pick_panel = NULL;  } -bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept) +bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data , EAcceptance* accept)  {  	*accept = ACCEPT_NO; @@ -1125,7 +1126,21 @@ bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType carg  			if (is_enabled && drop)  			{ -				onClipboardAction("delete"); +				// don't call onClipboardAction("delete") +				// this lead to removing (N * 2 - 1) items if drag N>1 items into trash. EXT-6757 +				// So, let remove items one by one. +				LLInventoryItem* item = static_cast<LLInventoryItem*>(cargo_data); +				if (item) +				{ +					LLFolderViewItem* fv_item = (mCurrentSelectedList && mCurrentSelectedList->getRootFolder()) ? +						mCurrentSelectedList->getRootFolder()->getItemByID(item->getUUID()) : NULL; + +					if (fv_item) +					{ +						// is Item Removable checked inside of remove() +						fv_item->remove(); +					} +				}  			}  		}  		break; diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index da5d683cfc..2d1eb0f091 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -142,7 +142,7 @@ private:  	/**  	 * Processes drag-n-drop of the Landmarks and folders into trash button.  	 */ -	bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept); +	bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept);  	/**  	 * Landmark actions callbacks. Fire when a landmark is loaded from the list. diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 8be4c8402c..0ba373c51b 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -34,6 +34,7 @@  #include "llpanelmaininventory.h"  #include "llagent.h" +#include "llavataractions.h"  #include "lldndbutton.h"  #include "lleconomy.h"  #include "llfilepicker.h" @@ -116,6 +117,7 @@ LLPanelMainInventory::LLPanelMainInventory()  	mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this));  	mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this));  	mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2)); +	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars));  	// Controls  	// *TODO: Just use persistant settings for each of these diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index df74c5dd47..3a82cf6f8b 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -46,6 +46,7 @@  #include "roles_constants.h"  #include "llagent.h" +#include "llavataractions.h"  #include "llcallbacklist.h"  #include "llfloaterbuycurrency.h"  #include "llfloaterreg.h" @@ -1528,6 +1529,7 @@ LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Par  	mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&do_nothing));  	mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&do_nothing));  	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&do_nothing)); +	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars));  }  // Destroys the object diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index cf04ab378f..d1e6d7de42 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -45,6 +45,7 @@  #include "llfloaterreg.h"  #include "llinventoryfunctions.h"  #include "llinventorypanel.h" +#include "llviewermenu.h"  #include "llviewerwindow.h"  #include "llviewerinventory.h"  #include "llbutton.h" @@ -54,12 +55,14 @@  #include "llinventorybridge.h"  #include "llinventorymodel.h"  #include "llinventorymodelbackgroundfetch.h" +#include "llpaneloutfitsinventory.h"  #include "lluiconstants.h"  #include "llscrolllistctrl.h"  #include "lltextbox.h"  #include "lluictrlfactory.h"  #include "llsdutil.h"  #include "llsidepanelappearance.h" +#include "lltoggleablemenu.h"  #include "llwearablelist.h"  static LLRegisterPanelClassWrapper<LLPanelOutfitEdit> t_outfit_edit("panel_outfit_edit"); @@ -114,7 +117,7 @@ private:  LLPanelOutfitEdit::LLPanelOutfitEdit()  :	LLPanel(), mCurrentOutfitID(), mFetchLook(NULL), mSearchFilter(NULL), -mLookContents(NULL), mInventoryItemsPanel(NULL), mAddToLookBtn(NULL), +mLookContents(NULL), mInventoryItemsPanel(NULL), mAddToOutfitBtn(NULL),  mRemoveFromLookBtn(NULL), mLookObserver(NULL)  {  	mSavedFolderState = new LLSaveFolderState(); @@ -172,8 +175,8 @@ BOOL LLPanelOutfitEdit::postBuild()  	mInventoryItemsPanel = getChild<LLInventoryPanel>("inventory_items");  	mInventoryItemsPanel->setFilterTypes(ALL_ITEMS_MASK);  	mInventoryItemsPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); -	// mInventoryItemsPanel->setSelectCallback(boost::bind(&LLPanelOutfitEdit::onInventorySelectionChange, this, _1, _2)); -	// mInventoryItemsPanel->getRootFolder()->setReshapeCallback(boost::bind(&LLPanelOutfitEdit::onInventorySelectionChange, this, _1, _2)); +	mInventoryItemsPanel->setSelectCallback(boost::bind(&LLPanelOutfitEdit::onInventorySelectionChange, this, _1, _2)); +	mInventoryItemsPanel->getRootFolder()->setReshapeCallback(boost::bind(&LLPanelOutfitEdit::onInventorySelectionChange, this, _1, _2));  	LLComboBox* type_filter = getChild<LLComboBox>("inventory_filter");  	type_filter->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onTypeFilterChanged, this, _1)); @@ -197,7 +200,8 @@ BOOL LLPanelOutfitEdit::postBuild()  	mAddToLookBtn->setEnabled(FALSE);  	mAddToLookBtn->setVisible(FALSE); */ -	childSetAction("add_item_btn", boost::bind(&LLPanelOutfitEdit::onAddToLookClicked, this), this); +	childSetAction("add_to_outfit_btn", boost::bind(&LLPanelOutfitEdit::onAddToOutfitClicked, this)); +	childSetEnabled("add_to_outfit_btn", false);  	mUpBtn = getChild<LLButton>("up_btn");  	mUpBtn->setEnabled(TRUE); @@ -228,6 +232,17 @@ BOOL LLPanelOutfitEdit::postBuild()  	childSetAction("remove_item_btn", boost::bind(&LLPanelOutfitEdit::onRemoveFromLookClicked, this), this); +	childSetAction("revert_btn", boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance())); + +	childSetAction("save_btn", boost::bind(&LLPanelOutfitEdit::saveOutfit, this, false)); +	childSetAction("save_as_btn", boost::bind(&LLPanelOutfitEdit::saveOutfit, this, true)); +	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()); +  	return TRUE;  } @@ -236,6 +251,31 @@ void LLPanelOutfitEdit::showAddWearablesPanel()  	childSetVisible("add_wearables_panel", childGetValue("add_btn"));  } +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(); +	} +} + +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); @@ -298,13 +338,18 @@ void LLPanelOutfitEdit::onSearchEdit(const std::string& string)  	mInventoryItemsPanel->setFilterSubString(mSearchString);  } -void LLPanelOutfitEdit::onAddToLookClicked(void) +void LLPanelOutfitEdit::onAddToOutfitClicked(void)  {  	LLFolderViewItem* curr_item = mInventoryItemsPanel->getRootFolder()->getCurSelectedItem(); +	if (!curr_item) return; +  	LLFolderViewEventListener* listenerp  = curr_item->getListener(); -	link_inventory_item(gAgent.getID(), listenerp->getUUID(), mCurrentOutfitID, listenerp->getName(), -						LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL)); -	updateLookInfo(); +	if (!listenerp) return; + +	if (LLAppearanceMgr::getInstance()->wearItemOnAvatar(listenerp->getUUID())) +	{ +		updateLookInfo(); +	}  } @@ -405,6 +450,21 @@ void LLPanelOutfitEdit::onInventorySelectionChange(const std::deque<LLFolderView  	{  		return;  	} + +	LLViewerInventoryItem* item = current_item->getInventoryItem(); +	if (!item) return; + +	switch (item->getType()) +	{ +	case LLAssetType::AT_CLOTHING: +	case LLAssetType::AT_BODYPART: +	case LLAssetType::AT_OBJECT: +		childSetEnabled("add_to_outfit_btn", true); +		break; +	default: +		childSetEnabled("add_to_outfit_btn", false); +		break; +	}  	/* Removing add to look inline button (not part of mvp for viewer 2)  	LLRect btn_rect(current_item->getLocalRect().mRight - 50, diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index ba382d7320..1a8d7d2bef 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -52,6 +52,7 @@ class LLInventoryPanel;  class LLSaveFolderState;  class LLFolderViewItem;  class LLScrollListCtrl; +class LLToggleableMenu;  class LLLookFetchObserver;  class LLFilterEditor; @@ -86,11 +87,13 @@ public:  		// only update the location if there is none already available.  	void showAddWearablesPanel(); +	void saveOutfit(bool as_new = false); +	void showSaveMenu();  	void onTypeFilterChanged(LLUICtrl* ctrl);  	void onSearchEdit(const std::string& string);  	void onInventorySelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action); -	void onAddToLookClicked(void); +	void onAddToOutfitClicked(void);  	void onLookItemSelectionChange(void);  	void onRemoveFromLookClicked(void);  	void onEditWearableClicked(void); @@ -113,10 +116,11 @@ private:  	LLFilterEditor*		mSearchFilter;  	LLSaveFolderState*	mSavedFolderState;  	std::string			mSearchString; -	LLButton*			mAddToLookBtn; +	LLButton*			mAddToOutfitBtn;  	LLButton*			mRemoveFromLookBtn;  	LLButton*			mUpBtn;  	LLButton*			mEditWearableBtn; +	LLToggleableMenu*	mSaveMenu;  	LLLookFetchObserver*		mFetchLook;  	LLInventoryLookObserver*	mLookObserver; diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 7d8b1dea0e..b78268da7b 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -217,8 +217,13 @@ bool LLPanelOutfitsInventory::onSaveCommit(const LLSD& notification, const LLSD&  		if( !outfit_name.empty() )  		{  			LLUUID outfit_folder = gAgentWearables.makeNewOutfitLinks(outfit_name); -			LLSD key; -			LLSideTray::getInstance()->showPanel("panel_outfits_inventory", key); + +			LLSidepanelAppearance* panel_appearance = +				dynamic_cast<LLSidepanelAppearance *>(LLSideTray::getInstance()->getPanel("sidepanel_appearance")); +			if (panel_appearance) +			{ +				panel_appearance->showOutfitsInventoryPanel(); +			}  			if (mAppearanceTabs)  			{ @@ -309,6 +314,12 @@ LLFolderView *LLPanelOutfitsInventory::getRootFolder()  	return mActivePanel->getRootFolder();  } +//static +LLPanelOutfitsInventory* LLPanelOutfitsInventory::findInstance() +{ +	return dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory")); +} +  //////////////////////////////////////////////////////////////////////////////////  // List Commands                                                                // diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h index 41afc2f372..5d0d27ee4f 100644 --- a/indra/newview/llpaneloutfitsinventory.h +++ b/indra/newview/llpaneloutfitsinventory.h @@ -73,6 +73,8 @@ public:  	LLFolderView* getRootFolder(); +	static LLPanelOutfitsInventory* findInstance(); +  protected:  	void updateVerbs();  	bool getIsCorrectType(const LLFolderViewEventListener *listenerp) const; diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index eb245453db..dbb8e962bd 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -632,7 +632,7 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD&  	else if (item == "can_call")  	{  		bool not_agent = mUUIDs.front() != gAgentID; -		bool can_call = not_agent && LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking(); +		bool can_call = not_agent && LLVoiceClient::voiceEnabled() && LLVoiceClient::getInstance()->voiceWorking();  		return can_call;  	} diff --git a/indra/newview/llscrollingpanelparam.cpp b/indra/newview/llscrollingpanelparam.cpp index 7980fe1945..a5518d87d4 100644 --- a/indra/newview/llscrollingpanelparam.cpp +++ b/indra/newview/llscrollingpanelparam.cpp @@ -42,17 +42,14 @@  #include "llbutton.h"  #include "llsliderctrl.h"  #include "llagent.h" +#include "llviewborder.h"  #include "llvoavatarself.h"  // Constants for LLPanelVisualParam  const F32 LLScrollingPanelParam::PARAM_STEP_TIME_THRESHOLD = 0.25f; -const S32 LLScrollingPanelParam::BTN_BORDER = 2;  const S32 LLScrollingPanelParam::PARAM_HINT_WIDTH = 128;  const S32 LLScrollingPanelParam::PARAM_HINT_HEIGHT = 128; -const S32 LLScrollingPanelParam::PARAM_HINT_LABEL_HEIGHT = 16; -const S32 LLScrollingPanelParam::PARAM_PANEL_WIDTH = 2 * (3* BTN_BORDER + PARAM_HINT_WIDTH +  LLPANEL_BORDER_WIDTH); -const S32 LLScrollingPanelParam::PARAM_PANEL_HEIGHT = 2 * BTN_BORDER + PARAM_HINT_HEIGHT + PARAM_HINT_LABEL_HEIGHT + 4 * LLPANEL_BORDER_WIDTH;   // LLScrollingPanelParam  //static @@ -67,14 +64,17 @@ LLScrollingPanelParam::LLScrollingPanelParam( const LLPanel::Params& panel_param  {  	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_scrolling_param.xml"); +	// *HACK To avoid hard coding texture position, lets use border's position for texture.  +	LLViewBorder* left_border = getChild<LLViewBorder>("left_border"); +  	static LLUICachedControl<S32> slider_ctrl_height ("UISliderctrlHeight", 0); -	S32 pos_x = 2 * LLPANEL_BORDER_WIDTH; -	S32 pos_y = 3 * LLPANEL_BORDER_WIDTH + slider_ctrl_height; +	S32 pos_x = left_border->getRect().mLeft + left_border->getBorderWidth(); +	S32 pos_y = left_border->getRect().mBottom + left_border->getBorderWidth();  	F32 min_weight = param->getMinWeight();  	F32 max_weight = param->getMaxWeight();  	mHintMin = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, (LLViewerVisualParam*) wearable->getVisualParam(param->getID()),  min_weight); -	pos_x += PARAM_HINT_WIDTH + 3 * BTN_BORDER; +	pos_x = getChild<LLViewBorder>("right_border")->getRect().mLeft + left_border->getBorderWidth();  	mHintMax = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, (LLViewerVisualParam*) wearable->getVisualParam(param->getID()), max_weight );  	mHintMin->setAllowsUpdates( FALSE ); @@ -162,6 +162,10 @@ void LLScrollingPanelParam::draw()  	childSetVisible("less", mHintMin->getVisible());  	childSetVisible("more", mHintMax->getVisible()); +	// hide borders if texture has been loaded +	childSetVisible("left_border", !mHintMin->getVisible()); +	childSetVisible("right_border", !mHintMax->getVisible()); +  	// Draw all the children except for the labels  	childSetVisible( "min param text", FALSE );  	childSetVisible( "max param text", FALSE ); @@ -171,9 +175,7 @@ void LLScrollingPanelParam::draw()  	gGL.pushUIMatrix();  	{  		const LLRect& r = mHintMin->getRect(); -		F32 left = (F32)(r.mLeft + BTN_BORDER); -		F32 bot  = (F32)(r.mBottom + BTN_BORDER); -		gGL.translateUI(left, bot, 0.f); +		gGL.translateUI((F32)r.mLeft, (F32)r.mBottom, 0.f);  		mHintMin->draw();  	}  	gGL.popUIMatrix(); @@ -181,9 +183,7 @@ void LLScrollingPanelParam::draw()  	gGL.pushUIMatrix();  	{  		const LLRect& r = mHintMax->getRect(); -		F32 left = (F32)(r.mLeft + BTN_BORDER); -		F32 bot  = (F32)(r.mBottom + BTN_BORDER); -		gGL.translateUI(left, bot, 0.f); +		gGL.translateUI((F32)r.mLeft, (F32)r.mBottom, 0.f);  		mHintMax->draw();  	}  	gGL.popUIMatrix(); @@ -191,10 +191,10 @@ void LLScrollingPanelParam::draw()  	// Draw labels on top of the buttons  	childSetVisible( "min param text", TRUE ); -	drawChild(getChild<LLView>("min param text"), BTN_BORDER, BTN_BORDER); +	drawChild(getChild<LLView>("min param text"));  	childSetVisible( "max param text", TRUE ); -	drawChild(getChild<LLView>("max param text"), BTN_BORDER, BTN_BORDER); +	drawChild(getChild<LLView>("max param text"));  }  // static diff --git a/indra/newview/llscrollingpanelparam.h b/indra/newview/llscrollingpanelparam.h index 8c5db64816..fe4ce07166 100644 --- a/indra/newview/llscrollingpanelparam.h +++ b/indra/newview/llscrollingpanelparam.h @@ -75,13 +75,8 @@ public:  	// Constants for LLPanelVisualParam  	const static F32 PARAM_STEP_TIME_THRESHOLD; -	const static S32 BTN_BORDER;  	const static S32 PARAM_HINT_WIDTH;  	const static S32 PARAM_HINT_HEIGHT; -	const static S32 PARAM_HINT_LABEL_HEIGHT; -	const static S32 PARAM_PANEL_WIDTH; -	const static S32 PARAM_PANEL_HEIGHT;  -  public:  	LLViewerVisualParam* mParam; diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index a084c93786..4dbedd6295 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -135,7 +135,7 @@ BOOL LLSidepanelAppearance::postBuild()  		LLButton* back_btn = mOutfitEdit->getChild<LLButton>("back_btn");  		if (back_btn)  		{ -			back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onBackButtonClicked, this)); +			back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::showOutfitsInventoryPanel, this));  		}  	} @@ -176,7 +176,7 @@ void LLSidepanelAppearance::onOpen(const LLSD& key)  	if(key.size() == 0)  		return; - +	  	toggleOutfitEditPanel(TRUE);  	updateVerbs(); @@ -258,12 +258,6 @@ void LLSidepanelAppearance::onNewOutfitButtonClicked()  	}  } - -void LLSidepanelAppearance::onBackButtonClicked() -{ -	toggleOutfitEditPanel(FALSE); -} -  void LLSidepanelAppearance::onEditWearBackClicked()  {  	mEditWearable->saveChanges(); @@ -271,6 +265,30 @@ void LLSidepanelAppearance::onEditWearBackClicked()  	toggleOutfitEditPanel(TRUE);  } +void LLSidepanelAppearance::showOutfitsInventoryPanel() +{ +	mOutfitEdit->setVisible(FALSE); + +	mPanelOutfitsInventory->setVisible(TRUE); + +	mFilterEditor->setVisible(TRUE); +	mEditBtn->setVisible(TRUE); +	mNewOutfitBtn->setVisible(TRUE); +	mCurrOutfitPanel->setVisible(TRUE); +} + +void LLSidepanelAppearance::showOutfitEditPanel() +{ +	mOutfitEdit->setVisible(TRUE); +	 +	mPanelOutfitsInventory->setVisible(FALSE); + +	mFilterEditor->setVisible(FALSE); +	mEditBtn->setVisible(FALSE); +	mNewOutfitBtn->setVisible(FALSE); +	mCurrOutfitPanel->setVisible(FALSE); +} +  void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible)  {  	if (!mOutfitEdit) diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h index 1d78e92a84..0a609797fb 100644 --- a/indra/newview/llsidepanelappearance.h +++ b/indra/newview/llsidepanelappearance.h @@ -63,14 +63,18 @@ public:  	void updateVerbs();  	void onNewOutfitButtonClicked(); +	void showOutfitsInventoryPanel(); +	void showOutfitEditPanel(); +  private:  	void onFilterEdit(const std::string& search_string);  	void onOpenOutfitButtonClicked();  	void onEditAppearanceButtonClicked();  	void onEditButtonClicked(); -	void onBackButtonClicked();  	void onEditWearBackClicked(); + +	//@deprecated use showXXX() methods instead  	void toggleOutfitEditPanel(BOOL visible);  	void toggleWearableEditPanel(BOOL visible, LLWearable* wearable); diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 18e56a9c01..fa543f1371 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -33,6 +33,7 @@  #include "llsidepanelinventory.h"  #include "llagent.h" +#include "llavataractions.h"  #include "llbutton.h"  #include "llinventorybridge.h"  #include "llinventorypanel.h" @@ -151,6 +152,7 @@ void LLSidepanelInventory::onInfoButtonClicked()  void LLSidepanelInventory::onShareButtonClicked()  { +	LLAvatarActions::shareWithAvatars();  }  void LLSidepanelInventory::performActionOnSelection(const std::string &action) @@ -252,7 +254,9 @@ void LLSidepanelInventory::updateVerbs()  	mPlayBtn->setEnabled(FALSE);   	mTeleportBtn->setVisible(FALSE);   	mTeleportBtn->setEnabled(FALSE); -	 + +	mShareBtn->setEnabled(canShare()); +  	const LLInventoryItem *item = getSelectedItem();  	if (!item)  		return; @@ -260,7 +264,6 @@ void LLSidepanelInventory::updateVerbs()  	bool is_single_selection = getSelectedCount() == 1;  	mInfoBtn->setEnabled(is_single_selection); -	mShareBtn->setEnabled(is_single_selection);  	switch(item->getInventoryType())  	{ @@ -285,6 +288,25 @@ void LLSidepanelInventory::updateVerbs()  	}  } +bool LLSidepanelInventory::canShare() +{ +	LLPanelMainInventory* panel_main_inventory = +		mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory"); + +	LLFolderView* root_folder = +		panel_main_inventory->getActivePanel()->getRootFolder(); + +	LLFolderViewItem* current_item = root_folder->hasVisibleChildren() +		? root_folder->getCurSelectedItem() +		: NULL; + +	LLInvFVBridge* bridge = current_item +		? dynamic_cast <LLInvFVBridge*> (current_item->getListener()) +		: NULL; + +	return bridge ? bridge->canShare() : false; +} +  LLInventoryItem *LLSidepanelInventory::getSelectedItem()  {  	LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory"); diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index ee11fb6b54..95eab3571c 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -60,6 +60,7 @@ protected:  	void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);  	// "wear", "teleport", etc.  	void performActionOnSelection(const std::string &action); +	bool canShare();  	void showItemInfoPanel();  	void showTaskInfoPanel(); diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 60657d3fa7..911ed6ade7 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -285,6 +285,12 @@ void LLToast::setVisible(BOOL show)  		}  		LLModalDialog::setFrontmost(FALSE);  	} +	else +	{ +		//hide "hide" button in case toast was hidden without mouse_leave +		if(mHideBtn) +			mHideBtn->setVisible(show); +	}  	LLFloater::setVisible(show);  	if(mPanel)  	{ diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h index 20198a9398..bd07ff9fb1 100644 --- a/indra/newview/lltoast.h +++ b/indra/newview/lltoast.h @@ -63,6 +63,8 @@ public:  	void start() { mEventTimer.start(); }  	void restart() {mEventTimer.reset(); }  	BOOL getStarted() { return mEventTimer.getStarted(); } + +	LLTimer&  getEventTimer() { return mEventTimer;}  private :  	LLToast* mToast;  }; @@ -132,6 +134,8 @@ public:  	//  	void stopTimer() { mTimer->stop(); }  	// +	LLToastLifeTimer* getTimer() { return mTimer.get();} +	//  	virtual void draw();  	//  	virtual void setVisible(BOOL show); diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h index 1c68e4c6b3..a6644c0a7a 100644 --- a/indra/newview/lltoastnotifypanel.h +++ b/indra/newview/lltoastnotifypanel.h @@ -49,6 +49,9 @@ class LLNotificationForm;   * Notification panel should be used for notifications that require a response from the user.   *   * Replaces class LLNotifyBox. + * + * @deprecated this class will be removed after all toast panel types are + *  implemented in separate classes.   */  class LLToastNotifyPanel: public LLToastPanel   { @@ -60,6 +63,8 @@ public:  	 * @param rect an initial rectangle of the toast panel.   	 * If it is null then a loaded from xml rectangle will be used.   	 * @see LLNotification +	 * @deprecated if you intend to instantiate LLToastNotifyPanel - it's point to +	 * implement right class for desired toast panel. @see LLGenericTipPanel as example.  	 */  	LLToastNotifyPanel(LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null);  	virtual ~LLToastNotifyPanel(); diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp index 755e647777..d142a0665b 100644 --- a/indra/newview/lltoastpanel.cpp +++ b/indra/newview/lltoastpanel.cpp @@ -32,14 +32,14 @@  #include "llviewerprecompiledheaders.h" -#include "lltoastpanel.h" - +#include "llpanelgenerictip.h"  #include "llnotifications.h" +#include "lltoastpanel.h"  //static  const S32 LLToastPanel::MIN_PANEL_HEIGHT = 40; // VPAD(4)*2 + ICON_HEIGHT(32) -LLToastPanel::LLToastPanel(LLNotificationPtr& notification)  +LLToastPanel::LLToastPanel(const LLNotificationPtr& notification)  {  	mNotification = notification;  } @@ -91,3 +91,20 @@ void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount)  	}  } +// static +LLToastPanel* LLToastPanel::buidPanelFromNotification( +		const LLNotificationPtr& notification) +{ +	LLToastPanel* res = NULL; + +	if (notification->getName() == "SystemMessageTip") +	{ +		res = new LLPanelGenericTip(notification); +	} +	/* +	 else if(...) +	 create all other specific non-public toast panel +	 */ + +	return res; +} diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h index f1dd7d7a86..54243e52fa 100644 --- a/indra/newview/lltoastpanel.h +++ b/indra/newview/lltoastpanel.h @@ -53,13 +53,21 @@ public:   */  class LLToastPanel: public LLPanel {  public: -	LLToastPanel(LLNotificationPtr&); +	LLToastPanel(const LLNotificationPtr&);  	virtual ~LLToastPanel() = 0;  	virtual std::string getTitle();  	virtual const LLUUID& getID();  	static const S32 MIN_PANEL_HEIGHT; + +	/** +	 * Builder method for constructing notification specific panels. +	 * Normally type of created panels shouldn't be publicated and should be hidden +	 * from other functionality. +	 */ +	static LLToastPanel* buidPanelFromNotification( +			const LLNotificationPtr& notification);  protected:  	LLNotificationPtr mNotification;  	void snapToMessageHeight(LLTextBase* message, S32 maxLineCount); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index c542459cdb..32df7d8410 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -71,7 +71,6 @@  #include "llnotifications.h"  #include "llnotificationsutil.h"  #include "llpanelgrouplandmoney.h" -#include "llpanelplaces.h"  #include "llrecentpeople.h"  #include "llscriptfloater.h"  #include "llselectmgr.h" @@ -692,6 +691,52 @@ bool join_group_response(const LLSD& notification, const LLSD& response)  	return false;  } + +static void highlight_inventory_items_in_panel(const std::vector<LLUUID>& items, LLInventoryPanel *inventory_panel) +{ +	if (NULL == inventory_panel) return; + +	for (std::vector<LLUUID>::const_iterator item_iter = items.begin(); +		item_iter != items.end(); +		++item_iter) +	{ +		const LLUUID& item_id = (*item_iter); +		if(!highlight_offered_item(item_id)) +		{ +			continue; +		} + +		LLInventoryItem* item = gInventory.getItem(item_id); +		llassert(item); +		if (!item) { +			continue; +		} + +		LL_DEBUGS("Inventory_Move") << "Highlighting inventory item: " << item->getName() << ", " << item_id  << LL_ENDL; +		LLFolderView* fv = inventory_panel->getRootFolder(); +		if (fv) +		{ +			LLFolderViewItem* fv_item = fv->getItemByID(item_id); +			if (fv_item) +			{ +				LLFolderViewItem* fv_folder = fv_item->getParentFolder(); +				if (fv_folder) +				{ +					// Parent folders can be different in case of 2 consecutive drag and drop +					// operations when the second one is started before the first one completes. +					LL_DEBUGS("Inventory_Move") << "Open folder: " << fv_folder->getName() << LL_ENDL; +					fv_folder->setOpen(TRUE); +					if (fv_folder->isSelected()) +					{ +						fv->changeSelection(fv_folder, FALSE); +					} +				} +				fv->changeSelection(fv_item, TRUE); +			} +		} +	} +} +  static LLNotificationFunctorRegistration jgr_1("JoinGroup", join_group_response);  static LLNotificationFunctorRegistration jgr_2("JoinedTooManyGroupsMember", join_group_response);  static LLNotificationFunctorRegistration jgr_3("JoinGroupCanAfford", join_group_response); @@ -714,6 +759,108 @@ private:  	std::string mFromName;  }; +/** + * Class to observe adding of new items moved from the world to user's inventory to select them in inventory. + * + * We can't create it each time items are moved because "drop" event is sent separately for each + * element even while multi-dragging. We have to have the only instance of the observer. See EXT-4347. + */ +class LLViewerInventoryMoveFromWorldObserver : public LLInventoryMoveFromWorldObserver +{ +public: +	LLViewerInventoryMoveFromWorldObserver() +		: LLInventoryMoveFromWorldObserver() +		, mActivePanel(NULL) +	{ + +	} + +	void setMoveIntoFolderID(const LLUUID& into_folder_uuid) {mMoveIntoFolderID = into_folder_uuid; } + +private: +	/*virtual */void onAssetAdded(const LLUUID& asset_id) +	{ +		// Store active Inventory panel. +		mActivePanel = LLInventoryPanel::getActiveInventoryPanel(); + +		// Store selected items (without destination folder) +		mSelectedItems.clear(); +		mActivePanel->getRootFolder()->getSelectionList(mSelectedItems); +		mSelectedItems.erase(mMoveIntoFolderID); +	} + +	/** +	 * Selects added inventory items watched by their Asset UUIDs if selection was not changed since +	 * all items were started to watch (dropped into a folder). +	 */ +	void done() +	{ +		// if selection is not changed since watch started lets hightlight new items. +		if (mActivePanel && !isSelectionChanged()) +		{ +			LL_DEBUGS("Inventory_Move") << "Selecting new items..." << LL_ENDL; +			mActivePanel->clearSelection(); +			highlight_inventory_items_in_panel(mAddedItems, mActivePanel); +		} +	} + +	/** +	 * Returns true if selected inventory items were changed since moved inventory items were started to watch. +	 */ +	bool isSelectionChanged() +	{ +		const LLInventoryPanel * const current_active_panel = LLInventoryPanel::getActiveInventoryPanel(); + +		if (NULL == mActivePanel || current_active_panel != mActivePanel) +		{ +			return true; +		} + +		// get selected items (without destination folder) +		selected_items_t selected_items; +		mActivePanel->getRootFolder()->getSelectionList(selected_items); +		selected_items.erase(mMoveIntoFolderID); + +		// compare stored & current sets of selected items +		selected_items_t different_items; +		std::set_symmetric_difference(mSelectedItems.begin(), mSelectedItems.end(), +			selected_items.begin(), selected_items.end(), std::inserter(different_items, different_items.begin())); + +		LL_DEBUGS("Inventory_Move") << "Selected firstly: " << mSelectedItems.size() +			<< ", now: " << selected_items.size() << ", difference: " << different_items.size() << LL_ENDL; + +		return different_items.size() > 0; +	} + +	LLInventoryPanel *mActivePanel; +	typedef std::set<LLUUID> selected_items_t; +	selected_items_t mSelectedItems; + +	/** +	 * UUID of FolderViewFolder into which watched items are moved. +	 * +	 * Destination FolderViewFolder becomes selected while mouse hovering (when dragged items are dropped). +	 *  +	 * If mouse is moved out it set unselected and number of selected items is changed  +	 * even if selected items in Inventory stay the same. +	 * So, it is used to update stored selection list. +	 * +	 * @see onAssetAdded() +	 * @see isSelectionChanged() +	 */ +	LLUUID mMoveIntoFolderID; +}; + +LLViewerInventoryMoveFromWorldObserver* gInventoryMoveObserver = NULL; + +void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder_uuid) +{ +	start_new_inventory_observer(); + +	gInventoryMoveObserver->setMoveIntoFolderID(into_folder_uuid); +	gInventoryMoveObserver->watchAsset(inv_item->getAssetUUID()); +} +  //unlike the FetchObserver for AgentOffer, we only make one   //instance of the AddedObserver for TaskOffers  //and it never dies.  We do this because we don't know the UUID of  @@ -724,6 +871,33 @@ class LLOpenTaskOffer : public LLInventoryAddedObserver  protected:  	/*virtual*/ void done()  	{ +		for (uuid_vec_t::iterator it = mAdded.begin(); it != mAdded.end();) +		{ +			const LLUUID& item_uuid = *it; +			bool was_moved = false; +			LLInventoryObject* added_object = gInventory.getObject(item_uuid); +			if (added_object) +			{ +				// cast to item to get Asset UUID +				LLInventoryItem* added_item = dynamic_cast<LLInventoryItem*>(added_object); +				if (added_item) +				{ +					const LLUUID& asset_uuid = added_item->getAssetUUID(); +					if (gInventoryMoveObserver->isAssetWatched(asset_uuid)) +					{ +						LL_DEBUGS("Inventory_Move") << "Found asset UUID: " << asset_uuid << LL_ENDL; +						was_moved = true; +					} +				} +			} + +			if (was_moved) +			{ +				it = mAdded.erase(it); +			} +			else ++it; +		} +  		open_inventory_offer(mAdded, "");  		mAdded.clear();  	} @@ -752,6 +926,13 @@ void start_new_inventory_observer()  		gNewInventoryObserver = new LLOpenTaskOffer;  		gInventory.addObserver(gNewInventoryObserver);  	} + +	if (!gInventoryMoveObserver) //inventory move from the world observer  +	{ +		// Observer is deleted by gInventory +		gInventoryMoveObserver = new LLViewerInventoryMoveFromWorldObserver; +		gInventory.addObserver(gInventoryMoveObserver); +	}  }  class LLDiscardAgentOffer : public LLInventoryFetchComboObserver @@ -916,9 +1097,12 @@ void open_inventory_offer(const uuid_vec_t& items, const std::string& from_name)  					}  					else if("group_offer" == from_name)  					{ -						// do not open inventory when we open group notice attachment because  -						// we already opened landmark info panel  						// "group_offer" is passed by LLOpenTaskGroupOffer +						// Notification about added landmark will be generated under the "from_name.empty()" called from LLOpenTaskOffer::done(). +						LLSD args; +						args["type"] = "landmark"; +						args["id"] = item_id; +						LLSideTray::getInstance()->showPanel("panel_places", args);  						continue;  					} @@ -929,28 +1113,6 @@ void open_inventory_offer(const uuid_vec_t& items, const std::string& from_name)  						args["LANDMARK_NAME"] = item->getName();  						args["FOLDER_NAME"] = std::string(parent_folder ? parent_folder->getName() : "unknown");  						LLNotificationsUtil::add("LandmarkCreated", args); -						// Created landmark is passed to Places panel to allow its editing. In fact panel should be already displayed. -						// If the panel is closed we don't reopen it until created landmark is loaded. -						//TODO*:: dserduk(7/12/09) remove LLPanelPlaces dependency from here -						LLPanelPlaces *places_panel = dynamic_cast<LLPanelPlaces*>(LLSideTray::getInstance()->getPanel("panel_places")); -						if (places_panel) -						{ -							// Landmark creation handling is moved to LLPanelPlaces::showAddedLandmarkInfo() -							// TODO* LLPanelPlaces dependency is going to be removed. See EXT-4347. -							//if("create_landmark" == places_panel->getPlaceInfoType() && !places_panel->getItem()) -							//{ -							//	places_panel->setItem(item); -							//} -							//else -							// we are opening a group notice attachment -							if("create_landmark" != places_panel->getPlaceInfoType()) -							{ -								LLSD args; -								args["type"] = "landmark"; -								args["id"] = item_id; -								LLSideTray::getInstance()->showPanel("panel_places", args); -							} -						}  					}  				}  				break; @@ -2230,10 +2392,13 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  				chat.mFromID = from_id ^ gAgent.getSessionID();  			} +			chat.mSourceType = CHAT_SOURCE_OBJECT; +  			if(SYSTEM_FROM == name)  			{  				// System's UUID is NULL (fixes EXT-4766)  				chat.mFromID = LLUUID::null; +				chat.mSourceType = CHAT_SOURCE_SYSTEM;  			}  			LLSD query_string; @@ -2250,7 +2415,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  			chat.mURL = link.str();  			chat.mText = message; -			chat.mSourceType = CHAT_SOURCE_OBJECT;  			// Note: lie to Nearby Chat, pretending that this is NOT an IM, because  			// IMs from obejcts don't open IM sessions. @@ -4552,11 +4716,12 @@ void process_money_balance_reply( LLMessageSystem* msg, void** )  				if(boost::regex_match(desc, matches, expr))  				{  					// Name of full localizable notification string -					// there are three types of this string- with name of receiver and reason of payment, -					// without name and without reason (but not simultaneously) +					// there are four types of this string- with name of receiver and reason of payment, +					// without name and without reason (both may also be absent simultaneously).  					// example of string without name - You paid L$100 to create a group.  					// example of string without reason - You paid Smdby Linden L$100.  					// example of string with reason and name - You paid Smbdy Linden L$100 for a land access pass. +					// example of string with no info - You paid L$50.  					std::string line = "you_paid_ldollars_no_name";  					// arguments of string which will be in notification @@ -4577,7 +4742,7 @@ void process_money_balance_reply( LLMessageSystem* msg, void** )  					std::string reason = std::string(matches[3]);  					if (reason.empty())  					{ -						line = "you_paid_ldollars_no_reason"; +						line = name.empty() ? "you_paid_ldollars_no_info" : "you_paid_ldollars_no_reason";  					}  					else  					{ @@ -4621,6 +4786,10 @@ bool handle_special_notification_callback(const LLSD& notification, const LLSD&  		gSavedSettings.setU32("PreferredMaturity", preferredMaturity);  		gAgent.sendMaturityPreferenceToServer(preferredMaturity); +		// notify user that the maturity preference has been changed +		LLSD args; +		args["RATING"] = LLViewerRegion::accessToString(preferredMaturity); +		LLNotificationsUtil::add("PreferredMaturityChanged", args);  	}  	return false; diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index 4015cca77b..7c021dc05f 100644 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -208,6 +208,8 @@ void open_inventory_offer(const uuid_vec_t& items, const std::string& from_name)  // Returns false if item is not found.  bool highlight_offered_item(const LLUUID& item_id); +void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder_uuid); +  struct LLOfferInfo  {          LLOfferInfo() diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 1f6bbcbae8..a591cc1e14 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -2185,7 +2185,8 @@ bool LLViewerParcelMgr::canAgentBuyParcel(LLParcel* parcel, bool forGroup) const  		return true;	// change this if want to make it gods only  	} -	LLViewerRegion* regionp = LLViewerParcelMgr::getInstance()->getSelectionRegion(); +	LLVector3 parcel_coord = parcel->getCenterpoint(); +	LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosAgent(parcel_coord);  	if (regionp)  	{  		U8 sim_access = regionp->getSimAccess(); diff --git a/indra/newview/skins/default/xui/en/floater_joystick.xml b/indra/newview/skins/default/xui/en/floater_joystick.xml index 4d67e4c343..b8156a174d 100644 --- a/indra/newview/skins/default/xui/en/floater_joystick.xml +++ b/indra/newview/skins/default/xui/en/floater_joystick.xml @@ -819,7 +819,7 @@       layout="topleft"       left="20"       name="ZoomDeadZone" -     width="94"> +     width="96">          Zoom Dead Zone      </text>      <spinner diff --git a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml index 2bafd1bdef..5ea207675b 100644 --- a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml +++ b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml @@ -100,7 +100,7 @@ No Answer.  Please try again later.     top="27"     width="315"     word_wrap="true"> -    [VOICE_CHANNEL_NAME] has ended the call.  [RECONNECT_NEARBY] +    Your call has ended.  [RECONNECT_NEARBY]    </text>    <text     font="SansSerifLarge" diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 2874151df5..5e1f6b58e8 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -5,6 +5,14 @@   name="Popup"   visible="false">      <menu_item_call +     label="Share" +     layout="topleft" +     name="Share" +     visible="true"> +        <menu_item_call.on_click +         function="Inventory.Share" /> +    </menu_item_call> +    <menu_item_call       label="Buy"       layout="topleft"       name="Task Buy"> diff --git a/indra/newview/skins/default/xui/en/menu_save_outfit.xml b/indra/newview/skins/default/xui/en/menu_save_outfit.xml new file mode 100644 index 0000000000..a8778df7f6 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_save_outfit.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + height="201" + layout="topleft" + mouse_opaque="false" + name="save_outfit_menu" + width="120"> +    <menu_item_call  +     name="save_outfit"  +     label="Save"> +        <menu_item_call.on_click  +         function="Outfit.Save.Action" +         userdata=""/> +        </menu_item_call> +    <menu_item_call  +     name="save_as_new_outfit"  +     label="Save As New"> +        <menu_item_call.on_click  +         function="Outfit.SaveAsNew.Action" +         userdata="" /> +    </menu_item_call> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index e8ba8c683d..9ee4e13f3c 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3380,6 +3380,13 @@ You can click 'Change Preference' to raise your maturity Rating prefer    </notification>    <notification +   icon="notifytip.tga" +   name="PreferredMaturityChanged" +   type="notifytip"> +Your maturity rating preference is now [RATING]. +  </notification> + +  <notification     icon="alertmodal.tga"     name="LandClaimAccessBlocked"     type="alertmodal"> @@ -4376,6 +4383,18 @@ Uploading in-world and web site snapshots...    </notification>    <notification +   icon="alertmodal.tga" +   name="UploadConfirmation" +   type="alertmodal"> +Uploading costs L$[AMOUNT]. +Do you wish to proceed? +    <usetemplate +     name="okcancelbuttons" +     notext="Cancel" +     yestext="Upload"/> +  </notification> + +  <notification     icon="notify.tga"     name="UploadPayment"     type="notify"> @@ -5942,6 +5961,13 @@ Selected button can not be shown right now.  The button will be shown when there is enough space for it.    </notification> +  <notification +   icon="notifytip.tga" +   name="ShareNotification" +   type="notifytip"> +Drag items from inventory onto a person in the resident picker +  </notification> +    <global name="UnsupportedCPU">  - Your CPU speed does not meet the minimum requirements. diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index c34a367c32..e412c491fd 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -127,6 +127,8 @@               <gesture_combo_list.combo_button                pad_right="10"                use_ellipses="true" /> +             <gesture_combo_list.combo_list +              page_lines="17" />           </gesture_combo_list>          </layout_panel>  		 <icon @@ -344,7 +346,6 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.           user_resize="false">              <chiclet_im_well               max_displayed_count="99" -             flash_period="0.3"               follows="right"               height="28"               layout="topleft" @@ -393,7 +394,6 @@ image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well           min_width="37"           user_resize="false">              <chiclet_notification -             flash_period="0.25"               follows="right"               height="23"               layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_generic_tip.xml b/indra/newview/skins/default/xui/en/panel_generic_tip.xml new file mode 100644 index 0000000000..453ed7c7a6 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_generic_tip.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + height="40" + layout="topleft" + left="0" + name="panel_system_tip" + top="0" + width="305"> +    <text +     follows="all" +     font="SansSerif" +     height="20" +     layout="topleft" +     left="10" +     max_length="350" +     name="message" +     text_color="white" +     top="10" +     use_ellipses="true" +     value="" +     width="285" +     wrap="true" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml index a314cedc21..7ec1ca2e2e 100644 --- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml @@ -66,6 +66,7 @@  	    <button  	     follows="left|top"  	     height="23" +	     image_bottom_pad="1"  	     image_overlay="Home_Off"  	     layout="topleft"  	     left_pad="7" 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 c1800384a3..a5e6506463 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -257,7 +257,7 @@               text_pad_left="25" />              <inventory_panel -             allow_multi_select="true" +             allow_multi_select="false"               border="false"               follows="left|top|right|bottom"               height="176" @@ -317,6 +317,19 @@                   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" />              </panel>          </layout_panel>      </layout_stack> @@ -338,6 +351,19 @@           name="save_btn"           width="145" />          <button +         follows="bottom|right" +         height="23" +         name="save_flyout_btn" +         label="" +         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"           left_pad="15" diff --git a/indra/newview/skins/default/xui/en/panel_scrolling_param.xml b/indra/newview/skins/default/xui/en/panel_scrolling_param.xml index f9c86fc75b..8042563900 100644 --- a/indra/newview/skins/default/xui/en/panel_scrolling_param.xml +++ b/indra/newview/skins/default/xui/en/panel_scrolling_param.xml @@ -1,6 +1,6 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <panel - height="152" + height="157"   layout="topleft"   left="0"   name="LLScrollingPanelParam" @@ -10,25 +10,25 @@       follows="left|top"       height="16"       layout="topleft" -     left="4" +     left="12"       name="min param text" -     top="116" -     width="128" /> +     top="120" +     width="120" />      <text       follows="left|top"       height="16"       layout="topleft" -     left_pad="6" +     left="155"       name="max param text"       top_delta="0" -     width="128" /> +     width="120" />      <text       type="string"       length="1"       follows="left|top"       height="16"       layout="topleft" -     left="8" +     left="12"       name="Loading..."       top="11"       width="128"> @@ -40,7 +40,7 @@       follows="left|top"       height="16"       layout="topleft" -     left_pad="6" +     left="155"       name="Loading...2"       top_delta="0"       width="128"> @@ -49,30 +49,30 @@      <view_border        layout="topleft"       follows="left|top" -     left="2" -     top="0" +     left="7" +     top="5"       width="132"       height="132"       thickness="2" -     shadow_light_color="LtGray_50" -     highlight_light_color="LtGray_50" -     highlight_dark_color="LtGray_50" -     shadow_dark_color="LtGray_50" +     shadow_light_color="0.3 0.3 0.3 1" +     highlight_light_color="0.3 0.3 0.3 1" +     highlight_dark_color="0.3 0.3 0.3 1" +     shadow_dark_color="0.3 0.3 0.3 1"       bevel_style="in"       name="left_border"      />      <view_border        layout="topleft"       follows="left|top" -     left_pad="2" +     left_pad="10"       top_delta="0"       width="132"       height="132"       thickness="2" -     shadow_light_color="LtGray_50" -     highlight_light_color="LtGray_50" -     highlight_dark_color="LtGray_50" -     shadow_dark_color="LtGray_50" +     shadow_light_color="0.3 0.3 0.3 1" +     highlight_light_color="0.3 0.3 0.3 1" +     highlight_dark_color="0.3 0.3 0.3 1" +     shadow_dark_color="0.3 0.3 0.3 1"       bevel_style="in"       name="right_border"      /> @@ -84,10 +84,10 @@       image_selected="PushButton_Selected"       image_unselected="PushButton_Off"       layout="topleft" -     left="2" +     left="7"       name="less"       tab_stop="false" -     top="0" +     top="5"       width="132" />      <button       enabled="false" @@ -97,7 +97,7 @@       image_selected="PushButton_Selected"       image_unselected="PushButton_Off"       layout="topleft" -     left_pad="2" +     left_pad="10"       name="more"       tab_stop="false"       top_delta="0" @@ -111,10 +111,11 @@       initial_value="0"       label="[DESC]"       label_width="100" -     layout="topleft" +     layout="bottom|left"       left="6"       max_val="100"       name="param slider" -     top="134" -     width="258" /> +     bottom="1" +     width="274"  +     slider_label.font.style="BOLD" />  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_toast.xml b/indra/newview/skins/default/xui/en/panel_toast.xml index e7384fa77f..92b4c17247 100644 --- a/indra/newview/skins/default/xui/en/panel_toast.xml +++ b/indra/newview/skins/default/xui/en/panel_toast.xml @@ -55,7 +55,7 @@      clip_partial="true"      visible="false"     follows="left|top|right|bottom" -   font="SansSerifBold" +   font="SansSerif"     height="20"     layout="topleft"     left="20" diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml index a233d42568..812d94c55f 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml @@ -46,17 +46,27 @@  				 left="0"  				 name="info_btn"  				 top="0" -				 width="153" /> +				 width="102" /> +			<button +				 enabled="true" +				 follows="bottom|left" +				 height="23" +				 label="Share" +				 layout="topleft" +				 left="105" +				 name="share_btn" +				 top="0" +				 width="102" />  			<button  				 enabled="false"  				 follows="bottom|left"  				 height="23"  				 label="Wear"  				 layout="topleft" -				 left="156" +				 left="210"  				 name="wear_btn"  				 top="0" -				 width="152" /> +				 width="102" />  			<button  				 enabled="false"  				 follows="bottom|left" @@ -64,19 +74,19 @@  				 label="Play"  				 layout="topleft"  				 name="play_btn" -				 left="156" +				 left="210"  				 top="0" -				 width="152" /> +				 width="102" />  			<button  				 enabled="false"  				 follows="bottom|left"  				 height="23"  				 label="Teleport"  				 layout="topleft" -				 left="156" +				 left="210"  				 name="teleport_btn"  				 top="0" -				 width="152" /> +				 width="102" />  		</panel>  	</panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 0c73b8d769..b0bf51c214 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2940,6 +2940,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].  	<string name="IM_moderator_label">(Moderator)</string>  	<!-- voice calls --> +	<string name="answered_call">Your call has been answered</string>  	<string name="started_call">Started a voice call</string>  	<string name="joined_call">Joined the voice call</string> @@ -3056,6 +3057,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].    <!-- Financial operations strings -->    <string name="paid_you_ldollars">[NAME] paid you L$[AMOUNT]</string>    <string name="you_paid_ldollars">You paid [NAME] L$[AMOUNT] [REASON].</string> +  <string name="you_paid_ldollars_no_info">You paid L$[AMOUNT].</string>    <string name="you_paid_ldollars_no_reason">You paid [NAME] L$[AMOUNT].</string>    <string name="you_paid_ldollars_no_name">You paid L$[AMOUNT] [REASON].</string>    <string name="for a parcel of land">for a parcel of land</string> | 
