diff options
Diffstat (limited to 'indra')
32 files changed, 625 insertions, 111 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 e672252a50..5fce1949a6 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1786,13 +1786,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/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/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index bed5c01d7a..1c6857b75c 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(); @@ -725,7 +725,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/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..943a851c13 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3167,6 +3167,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); 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..92f795462b 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -669,7 +669,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/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/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/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index c542459cdb..d8a3932a22 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  					{ 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/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_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/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index c34a367c32..c6ca814f58 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 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/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> | 
