diff options
47 files changed, 629 insertions, 351 deletions
| diff --git a/indra/llprimitive/tests/llmediaentry_test.cpp b/indra/llprimitive/tests/llmediaentry_test.cpp index 277e370ca4..88cd96ebe4 100644 --- a/indra/llprimitive/tests/llmediaentry_test.cpp +++ b/indra/llprimitive/tests/llmediaentry_test.cpp @@ -157,14 +157,9 @@ namespace  namespace tut  { -    bool llsd_equals(const LLSD& a, const LLSD& b) { -        // cheesy, brute force, but it works -        return std::string(ll_pretty_print_sd(a)) == std::string(ll_pretty_print_sd(b)); -    } -      void ensure_llsd_equals(const std::string& msg, const LLSD& expected, const LLSD& actual)      { -        if (!tut::llsd_equals(expected, actual)) +        if (!llsd_equals(expected, actual))          {              std::string message = msg;              message += ": actual: "; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 1de1d6ded4..b6a6b448ee 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -601,14 +601,20 @@ S32	LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_  	{  		llwchar wch = wchars[i]; -		F32 char_width = mFontFreetype->getXAdvance(wch); +		const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch); + +		// last character uses character width, since the whole character needs to be visible +		// other characters just use advance +		F32 width = (i == start)  +			? (F32)(fgi->mWidth + fgi->mXBearing)  	// use actual width for last character +			: fgi->mXAdvance;						// use advance for all other characters										 -		if( scaled_max_pixels < (total_width + char_width) ) +		if( scaled_max_pixels < (total_width + width) )  		{  			break;  		} -		total_width += char_width; +		total_width += width;  		drawable_chars++;  		if( max_chars >= 0 && drawable_chars >= max_chars ) @@ -626,7 +632,17 @@ S32	LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_  		total_width = llround(total_width);  	} -	return start_pos - drawable_chars; +	if (drawable_chars == 0) +	{ +		return start_pos; // just draw last character +	} +	else +	{ +		// if only 1 character is drawable, we want to return start_pos as the first character to draw +		// if 2 are drawable, return start_pos and character before start_pos, etc. +		return start_pos + 1 - drawable_chars; +	} +	  }  S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round) const diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 92993650a7..2481249f91 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -42,8 +42,6 @@ static const LLDefaultChildRegistry::Register<LLFlatListView> flat_list_view("fl  const LLSD SELECTED_EVENT	= LLSD().with("selected", true);  const LLSD UNSELECTED_EVENT	= LLSD().with("selected", false); -static const std::string COMMENT_TEXTBOX = "comment_text"; -  //forward declaration  bool llsds_are_equal(const LLSD& llsd_1, const LLSD& llsd_2); @@ -51,7 +49,8 @@ LLFlatListView::Params::Params()  :	item_pad("item_pad"),  	allow_select("allow_select"),  	multi_select("multi_select"), -	keep_one_selected("keep_one_selected") +	keep_one_selected("keep_one_selected"), +	no_items_text("no_items_text")  {};  void LLFlatListView::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */) @@ -295,19 +294,6 @@ void LLFlatListView::resetSelection(bool no_commit_on_deselection /*= false*/)  void LLFlatListView::setNoItemsCommentText(const std::string& comment_text)  { -	if (NULL == mNoItemsCommentTextbox) -	{ -		LLRect comment_rect = getRect(); -		comment_rect.setOriginAndSize(0, 0, comment_rect.getWidth(), comment_rect.getHeight()); -		comment_rect.stretch(-getBorderWidth()); -		LLTextBox::Params text_p; -		text_p.name(COMMENT_TEXTBOX); -		text_p.border_visible(false); -		text_p.rect(comment_rect); -		text_p.follows.flags(FOLLOWS_ALL); -		mNoItemsCommentTextbox = LLUICtrlFactory::create<LLTextBox>(text_p, this); -	} -  	mNoItemsCommentTextbox->setValue(comment_text);  } @@ -361,7 +347,6 @@ bool LLFlatListView::updateValue(const LLSD& old_value, const LLSD& new_value)  // PROTECTED STUFF  ////////////////////////////////////////////////////////////////////////// -  LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)  :	LLScrollContainer(p)    , mItemComparator(NULL) @@ -398,6 +383,25 @@ LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)  	params.bevel_style(LLViewBorder::BEVEL_IN);  	mSelectedItemsBorder = LLUICtrlFactory::create<LLViewBorder> (params);  	mItemsPanel->addChild( mSelectedItemsBorder ); + +	{ +		// create textbox for "No Items" comment text +		LLTextBox::Params text_p = p.no_items_text; +		if (!text_p.rect.isProvided()) +		{ +			LLRect comment_rect = getRect(); +			comment_rect.setOriginAndSize(0, 0, comment_rect.getWidth(), comment_rect.getHeight()); +			comment_rect.stretch(-getBorderWidth()); +			text_p.rect(comment_rect); +		} +		text_p.border_visible(false); + +		if (!text_p.follows.isProvided()) +		{ +			text_p.follows.flags(FOLLOWS_ALL); +		} +		mNoItemsCommentTextbox = LLUICtrlFactory::create<LLTextBox>(text_p, this); +	}  };  // virtual @@ -861,7 +865,11 @@ void LLFlatListView::notifyParentItemsRectChanged()  	// take into account comment text height if exists  	if (mNoItemsCommentTextbox && mNoItemsCommentTextbox->getVisible())  	{ +		// top text padding inside the textbox is included into the height  		comment_height = mNoItemsCommentTextbox->getTextPixelHeight(); + +		// take into account a distance from parent's top border to textbox's top +		comment_height += getRect().getHeight() - mNoItemsCommentTextbox->getRect().mTop;  	}  	LLRect req_rect =  getItemsRect(); @@ -892,6 +900,10 @@ void LLFlatListView::setNoItemsCommentVisible(bool visible) const  	{  		if (visible)  		{ +/* +// *NOTE: MA 2010-02-04 +// Deprecated after params of the comment text box were moved into widget (flat_list_view.xml) +// can be removed later if nothing happened.  			// We have to update child rect here because of issues with rect after reshaping while creating LLTextbox  			// It is possible to have invalid LLRect if Flat List is in LLAccordionTab  			LLRect comment_rect = getLocalRect(); @@ -903,6 +915,7 @@ void LLFlatListView::setNoItemsCommentVisible(bool visible) const  			LLViewBorder* scroll_border = getChild<LLViewBorder>("scroll border");  			comment_rect.stretch(-scroll_border->getBorderWidth());  			mNoItemsCommentTextbox->setRect(comment_rect); +*/  		}  		mNoItemsCommentTextbox->setVisible(visible);  	} diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index 949a731507..92cb40332e 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -35,8 +35,8 @@  #include "llpanel.h"  #include "llscrollcontainer.h" +#include "lltextbox.h" -class LLTextBox;  /**   * LLFlatListView represents a flat list ui control that operates on items in a form of LLPanel's. @@ -108,6 +108,9 @@ public:  		/** padding between items */  		Optional<U32> item_pad;  +		/** textbox with info message when list is empty*/ +		Optional<LLTextBox::Params> no_items_text; +  		Params();  	}; diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index eb2b4f7705..3e277f47b5 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -422,12 +422,16 @@ void LLLineEditor::setCursor( S32 pos )  	S32 old_cursor_pos = getCursor();  	mCursorPos = llclamp( pos, 0, mText.length()); +	// position of end of next character after cursor  	S32 pixels_after_scroll = findPixelNearestPos();  	if( pixels_after_scroll > mTextRightEdge )  	{  		S32 width_chars_to_left = mGLFont->getWidth(mText.getWString().c_str(), 0, mScrollHPos);  		S32 last_visible_char = mGLFont->maxDrawableChars(mText.getWString().c_str(), llmax(0.f, (F32)(mTextRightEdge - mTextLeftEdge + width_chars_to_left)));  -		S32 min_scroll = mGLFont->firstDrawableChar(mText.getWString().c_str(), (F32)(mTextRightEdge - mTextLeftEdge), mText.length(), getCursor()); +		// character immediately to left of cursor should be last one visible (SCROLL_INCREMENT_ADD will scroll in more characters) +		// or first character if cursor is at beginning +		S32 new_last_visible_char = llmax(0, getCursor() - 1); +		S32 min_scroll = mGLFont->firstDrawableChar(mText.getWString().c_str(), (F32)(mTextRightEdge - mTextLeftEdge), mText.length(), new_last_visible_char);  		if (old_cursor_pos == last_visible_char)  		{  			mScrollHPos = llmin(mText.length(), llmax(min_scroll, mScrollHPos + SCROLL_INCREMENT_ADD)); diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 62aeb50011..3fdb48b3ca 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -720,7 +720,10 @@ BOOL LLTextEditor::handleRightMouseDown(S32 x, S32 y, MASK mask)  	}  	if (!LLTextBase::handleRightMouseDown(x, y, mask))  	{ -		showContextMenu(x, y); +		if(getMouseOpaque()) +		{ +			showContextMenu(x, y); +		}  	}  	return TRUE;  } diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 41f2ff29e6..acbf02678c 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -927,13 +927,6 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs  	if (mInitialWearablesUpdateReceived)  		return;  	mInitialWearablesUpdateReceived = true; -	 -	// If this is the very first time the user has logged into viewer2+ (from a legacy viewer, or new account) -	// then auto-populate outfits from the library into the My Outfits folder. -	if (LLInventoryModel::getIsFirstTimeInViewer2() || gSavedSettings.getBOOL("MyOutfitsAutofill")) -	{ -		gAgentWearables.populateMyOutfitsFolder(); -	}  	LLUUID agent_id;  	gMessageSystem->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 585d42f66d..0fe236c056 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -321,7 +321,7 @@ public:  	~LLWearableHoldingPattern();  	bool pollCompletion(); -	bool isDone(); +	bool isFetchCompleted();  	bool isTimedOut();  	typedef std::list<LLFoundData> found_list_t; @@ -330,10 +330,12 @@ public:  	LLInventoryModel::item_array_t mGestItems;  	S32 mResolved;  	LLTimer mWaitTime; +	bool mFired;  };  LLWearableHoldingPattern::LLWearableHoldingPattern(): -	mResolved(0) +	mResolved(0), +	mFired(false)  {  } @@ -341,31 +343,34 @@ LLWearableHoldingPattern::~LLWearableHoldingPattern()  {  } -bool LLWearableHoldingPattern::isDone() +bool LLWearableHoldingPattern::isFetchCompleted()  { -	if (mResolved >= (S32)mFoundList.size()) -		return true; // have everything we were waiting for -	else if (isTimedOut()) -	{ -		llwarns << "Exceeded max wait time, updating appearance based on what has arrived" << llendl; -		return true; -	} -	return false; - +	return (mResolved >= (S32)mFoundList.size()); // have everything we were waiting for?  }  bool LLWearableHoldingPattern::isTimedOut()  { -	static F32 max_wait_time = 15.0;  // give up if wearable fetches haven't completed in max_wait_time seconds. +	static F32 max_wait_time = 20.0;  // give up if wearable fetches haven't completed in max_wait_time seconds.  	return mWaitTime.getElapsedTimeF32() > max_wait_time;   }  bool LLWearableHoldingPattern::pollCompletion()  { -	bool done = isDone(); -	llinfos << "polling, done status: " << done << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl; +	bool completed = isFetchCompleted(); +	bool timed_out = isTimedOut(); +	bool done = completed || timed_out; +	 +	llinfos << "polling, done status: " << completed << " timed out? " << timed_out << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl; +  	if (done)  	{ +		mFired = true; +		 +		if (timed_out) +		{ +			llwarns << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl; +		} +  		// Activate all gestures in this folder  		if (mGestItems.count() > 0)  		{ @@ -397,7 +402,11 @@ bool LLWearableHoldingPattern::pollCompletion()  			LLAgentWearables::userUpdateAttachments(mObjItems);  		} -		delete this; +		if (completed) +		{ +			// Only safe to delete if all wearable callbacks completed. +			delete this; +		}  	}  	return done;  } @@ -432,7 +441,11 @@ static void removeDuplicateItems(LLInventoryModel::item_array_t& items)  static void onWearableAssetFetch(LLWearable* wearable, void* data)  {  	LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data; -	 +	if (holder->mFired) +	{ +		llwarns << "called after holder fired" << llendl; +	} +  	if(wearable)  	{  		for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin(); diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 1dc0e8c0a7..f046e08827 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -585,9 +585,16 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  	bool irc_me = prefix == "/me " || prefix == "/me'";  	// Delimiter after a name in header copy/past and in plain text mode -	std::string delimiter = (chat.mChatType != CHAT_TYPE_SHOUT && chat.mChatType != CHAT_TYPE_WHISPER) -		? ": " -		: " "; +	std::string delimiter = ": "; +	std::string shout = LLTrans::getString("shout"); +	std::string whisper = LLTrans::getString("whisper"); +	if (chat.mChatType == CHAT_TYPE_SHOUT ||  +		chat.mChatType == CHAT_TYPE_WHISPER || +		chat.mText.compare(0, shout.length(), shout) == 0 || +		chat.mText.compare(0, whisper.length(), whisper) == 0) +	{ +		delimiter = " "; +	}  	// Don't add any delimiter after name in irc styled messages  	if (irc_me || chat.mChatStyle == CHAT_STYLE_IRC) diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index a5b62439f4..90f6438980 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -34,7 +34,6 @@  #include "llfavoritesbar.h" -#include "llbutton.h"  #include "llfloaterreg.h"  #include "llfocusmgr.h"  #include "llinventory.h" @@ -48,7 +47,6 @@  #include "llclipboard.h"  #include "llinventoryclipboard.h"  #include "llinventorybridge.h" -#include "llinventorymodel.h"  #include "llfloaterworldmap.h"  #include "lllandmarkactions.h"  #include "llnotificationsutil.h" @@ -674,7 +672,14 @@ void LLFavoritesBarCtrl::updateButtons()  	{  		return;  	} - +	if(mItems.empty()) +	{ +		mBarLabel->setVisible(TRUE); +	} +	else +	{ +		mBarLabel->setVisible(FALSE); +	}  	const child_list_t* childs = getChildList();  	child_list_const_iter_t child_it = childs->begin();  	int first_changed_item_index = 0; @@ -720,14 +725,22 @@ void LLFavoritesBarCtrl::updateButtons()  			}  		}  		// we have to remove ChevronButton to make sure that the last item will be LandmarkButton to get the right aligning +		// keep in mind that we are cutting all buttons in space between the last visible child of favbar and ChevronButton  		if (mChevronButton->getParent() == this)  		{  			removeChild(mChevronButton);  		}  		int last_right_edge = 0; +		//calculate new buttons offset  		if (getChildList()->size() > 0)  		{ -			last_right_edge = getChildList()->back()->getRect().mRight; +			//find last visible child to get the rightest button offset +			child_list_const_reverse_iter_t last_visible_it = std::find_if(childs->rbegin(), childs->rend(),  +					std::mem_fun(&LLView::getVisible)); +			if(last_visible_it != childs->rend()) +			{ +				last_right_edge = (*last_visible_it)->getRect().mRight; +			}  		}  		//last_right_edge is saving coordinates  		LLButton* last_new_button = NULL; diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp index 976af121ae..7388f7ea3f 100644 --- a/indra/newview/llfloatermediasettings.cpp +++ b/indra/newview/llfloatermediasettings.cpp @@ -149,13 +149,14 @@ void LLFloaterMediaSettings::apply()  	{  		LLSD settings;  		sInstance->mPanelMediaSettingsGeneral->preApply(); -		sInstance->mPanelMediaSettingsGeneral->getValues( settings ); +		sInstance->mPanelMediaSettingsGeneral->getValues( settings, false );  		sInstance->mPanelMediaSettingsSecurity->preApply(); -		sInstance->mPanelMediaSettingsSecurity->getValues( settings ); +		sInstance->mPanelMediaSettingsSecurity->getValues( settings, false );  		sInstance->mPanelMediaSettingsPermissions->preApply(); -		sInstance->mPanelMediaSettingsPermissions->getValues( settings ); -		LLSelectMgr::getInstance()->selectionSetMedia( LLTextureEntry::MF_HAS_MEDIA ); -		LLSelectMgr::getInstance()->selectionSetMediaData(settings); +		sInstance->mPanelMediaSettingsPermissions->getValues( settings, false ); +			 +		LLSelectMgr::getInstance()->selectionSetMedia( LLTextureEntry::MF_HAS_MEDIA, settings ); +  		sInstance->mPanelMediaSettingsGeneral->postApply();  		sInstance->mPanelMediaSettingsSecurity->postApply();  		sInstance->mPanelMediaSettingsPermissions->postApply(); @@ -176,6 +177,8 @@ void LLFloaterMediaSettings::onClose(bool app_quitting)  //static   void LLFloaterMediaSettings::initValues( const LLSD& media_settings, bool editable )  { +	if (sInstance->hasFocus()) return; +	  	sInstance->clearValues(editable);  	// update all panels with values from simulator  	sInstance->mPanelMediaSettingsGeneral-> diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index ef444c8ba4..9d9fbacee3 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -571,6 +571,16 @@ void LLFloaterPreference::setHardwareDefaults()  {  	LLFeatureManager::getInstance()->applyRecommendedSettings();  	refreshEnabledGraphics(); +	LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core"); +	child_list_t::const_iterator iter = tabcontainer->getChildList()->begin(); +	child_list_t::const_iterator end = tabcontainer->getChildList()->end(); +	for ( ; iter != end; ++iter) +	{ +		LLView* view = *iter; +		LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view); +		if (panel) +			panel->setHardwareDefaults(); +	}  }  //virtual @@ -1525,3 +1535,93 @@ void LLPanelPreference::setControlFalse(const LLSD& user_data)  	if (control)  		control->set(LLSD(FALSE));  } + +static LLRegisterPanelClassWrapper<LLPanelPreferenceGraphics> t_pref_graph("panel_preference_graphics"); + +BOOL LLPanelPreferenceGraphics::postBuild() +{ +	return LLPanelPreference::postBuild(); +} +void LLPanelPreferenceGraphics::draw() +{ +	LLPanelPreference::draw(); +	 +	LLButton* button_apply = findChild<LLButton>("Apply"); +	 +	if(button_apply && button_apply->getVisible()) +	{ +		bool enable = hasDirtyChilds(); + +		button_apply->setEnabled(enable); + +	} +} +bool LLPanelPreferenceGraphics::hasDirtyChilds() +{ +	std::list<LLView*> view_stack; +	view_stack.push_back(this); +	while(!view_stack.empty()) +	{ +		// Process view on top of the stack +		LLView* curview = view_stack.front(); +		view_stack.pop_front(); + +		LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview); +		if (ctrl) +		{ +			if(ctrl->isDirty()) +				return true; +		} +		// Push children onto the end of the work stack +		for (child_list_t::const_iterator iter = curview->getChildList()->begin(); +			 iter != curview->getChildList()->end(); ++iter) +		{ +			view_stack.push_back(*iter); +		} +	}	 +	return false; +} + +void LLPanelPreferenceGraphics::resetDirtyChilds() +{ +	std::list<LLView*> view_stack; +	view_stack.push_back(this); +	while(!view_stack.empty()) +	{ +		// Process view on top of the stack +		LLView* curview = view_stack.front(); +		view_stack.pop_front(); + +		LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview); +		if (ctrl) +		{ +			ctrl->resetDirty(); +		} +		// Push children onto the end of the work stack +		for (child_list_t::const_iterator iter = curview->getChildList()->begin(); +			 iter != curview->getChildList()->end(); ++iter) +		{ +			view_stack.push_back(*iter); +		} +	}	 +} +void LLPanelPreferenceGraphics::apply() +{ +	resetDirtyChilds(); +	LLPanelPreference::apply(); +} +void LLPanelPreferenceGraphics::cancel() +{ +	resetDirtyChilds(); +	LLPanelPreference::cancel(); +} +void LLPanelPreferenceGraphics::saveSettings() +{ +	resetDirtyChilds(); +	LLPanelPreference::saveSettings(); +} +void LLPanelPreferenceGraphics::setHardwareDefaults() +{ +	resetDirtyChilds(); +	LLPanelPreference::setHardwareDefaults(); +} diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 8778d76a5a..0827c7c2b2 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -161,6 +161,7 @@ public:  	virtual void apply();  	virtual void cancel();  	void setControlFalse(const LLSD& user_data); +	virtual void setHardwareDefaults(){};  	// This function squirrels away the current values of the controls so that  	// cancel() can restore them. @@ -177,4 +178,19 @@ private:  	string_color_map_t mSavedColors;  }; +class LLPanelPreferenceGraphics : public LLPanelPreference +{ +public: +	BOOL postBuild(); +	void draw(); +	void apply(); +	void cancel(); +	void saveSettings(); +	void setHardwareDefaults(); +protected: +	bool hasDirtyChilds(); +	void resetDirtyChilds(); +	 +}; +  #endif  // LL_LLPREFERENCEFLOATER_H diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index b6e9fb3f6c..a0031f0193 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -2084,10 +2084,6 @@ void LLFloaterSnapshot::draw()  			S32 offset_x = (getRect().getWidth() - previewp->getThumbnailWidth()) / 2 ;  			S32 offset_y = thumbnail_rect.mBottom + (thumbnail_rect.getHeight() - previewp->getThumbnailHeight()) / 2 ; -			if (! gSavedSettings.getBOOL("AdvanceSnapshot")) -			{ -				offset_y += getUIWinHeightShort() - getUIWinHeightLong(); -			}  			glMatrixMode(GL_MODELVIEW);  			gl_draw_scaled_image(offset_x, offset_y,  diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index c6135d3bc3..5c65b2c293 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -1272,8 +1272,7 @@ BOOL LLFolderView::canCut() const  		const LLFolderViewItem* item = *selected_it;  		const LLFolderViewEventListener* listener = item->getListener(); -		// *WARKAROUND: it is too many places where the "isItemRemovable" method should be changed with "const" modifier -		if (!listener || !(const_cast<LLFolderViewEventListener*>(listener))->isItemRemovable()) +		if (!listener || !listener->isItemRemovable())  		{  			return FALSE;  		} diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h index d6c4459e6f..12e100caf4 100644 --- a/indra/newview/llfoldervieweventlistener.h +++ b/indra/newview/llfoldervieweventlistener.h @@ -73,7 +73,8 @@ public:  	virtual BOOL isItemRenameable() const = 0;  	virtual BOOL renameItem(const std::string& new_name) = 0;  	virtual BOOL isItemMovable( void ) const = 0;		// Can be moved to another folder -	virtual BOOL isItemRemovable( void ) = 0;	// Can be destroyed +	virtual BOOL isItemRemovable( void ) const = 0;		// Can be destroyed +	virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual.  	virtual BOOL removeItem() = 0;  	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) = 0;  	virtual void move( LLFolderViewEventListener* parent_listener ) = 0; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index ab178b4007..1fd069f195 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -174,7 +174,7 @@ time_t LLInvFVBridge::getCreationDate() const  }  // Can be destroyed (or moved to trash) -BOOL LLInvFVBridge::isItemRemovable() +BOOL LLInvFVBridge::isItemRemovable() const  {  	const LLInventoryModel* model = getInventoryModel();  	if(!model)  @@ -605,7 +605,7 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	lldebugs << "LLInvFVBridge::buildContextMenu()" << llendl;  	std::vector<std::string> items;  	std::vector<std::string> disabled_items; -	if(isInTrash()) +	if(isItemInTrash())  	{  		items.push_back(std::string("Purge Item"));  		if (!isItemRemovable()) @@ -670,7 +670,7 @@ LLInventoryModel* LLInvFVBridge::getInventoryModel() const  	return panel ? panel->getModel() : NULL;  } -BOOL LLInvFVBridge::isInTrash() const +BOOL LLInvFVBridge::isItemInTrash() const  {  	LLInventoryModel* model = getInventoryModel();  	if(!model) return FALSE; @@ -680,7 +680,7 @@ BOOL LLInvFVBridge::isInTrash() const  BOOL LLInvFVBridge::isLinkedObjectInTrash() const  { -	if (isInTrash()) return TRUE; +	if (isItemInTrash()) return TRUE;  	const LLInventoryObject *obj = getInventoryObject();  	if (obj && obj->getIsLinkType()) @@ -1412,7 +1412,7 @@ public:  };  // Can be destroyed (or moved to trash) -BOOL LLFolderBridge::isItemRemovable() +BOOL LLFolderBridge::isItemRemovable() const  {  	LLInventoryModel* model = getInventoryModel();  	if(!model) @@ -3208,7 +3208,7 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	lldebugs << "LLTextureBridge::buildContextMenu()" << llendl;  	std::vector<std::string> items;  	std::vector<std::string> disabled_items; -	if(isInTrash()) +	if(isItemInTrash())  	{  		items.push_back(std::string("Purge Item"));  		if (!isItemRemovable()) @@ -3302,7 +3302,7 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	std::vector<std::string> items;  	std::vector<std::string> disabled_items; -	if(isInTrash()) +	if(isItemInTrash())  	{  		items.push_back(std::string("Purge Item"));  		if (!isItemRemovable()) @@ -3351,7 +3351,7 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	std::vector<std::string> disabled_items;  	lldebugs << "LLLandmarkBridge::buildContextMenu()" << llendl; -	if(isInTrash()) +	if(isItemInTrash())  	{  		items.push_back(std::string("Purge Item"));  		if (!isItemRemovable()) @@ -3576,7 +3576,7 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	std::vector<std::string> items;  	std::vector<std::string> disabled_items; -	if(isInTrash()) +	if(isItemInTrash())  	{  		items.push_back(std::string("Purge Item"));  		if (!isItemRemovable()) @@ -3841,7 +3841,7 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	lldebugs << "LLGestureBridge::buildContextMenu()" << llendl;  	std::vector<std::string> items;  	std::vector<std::string> disabled_items; -	if(isInTrash()) +	if(isItemInTrash())  	{  		items.push_back(std::string("Purge Item"));  		if (!isItemRemovable()) @@ -3905,7 +3905,7 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	std::vector<std::string> disabled_items;  	lldebugs << "LLAnimationBridge::buildContextMenu()" << llendl; -	if(isInTrash()) +	if(isItemInTrash())  	{  		items.push_back(std::string("Purge Item"));  		if (!isItemRemovable()) @@ -4184,7 +4184,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  {  	std::vector<std::string> items;  	std::vector<std::string> disabled_items; -	if(isInTrash()) +	if(isItemInTrash())  	{  		items.push_back(std::string("Purge Item"));  		if (!isItemRemovable()) @@ -4220,7 +4220,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  			{  				items.push_back(std::string("Detach From Yourself"));  			} -			else if (!isInTrash() && !isLinkedObjectInTrash() && !isLinkedObjectMissing()) +			else if (!isItemInTrash() && !isLinkedObjectInTrash() && !isLinkedObjectMissing())  			{  				items.push_back(std::string("Attach Separator"));  				items.push_back(std::string("Object Wear")); @@ -4558,7 +4558,7 @@ void LLWearableBridge::openItem()  		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());  	}  	/* -	if( isInTrash() ) +	if( isItemInTrash() )  	{  		LLNotificationsUtil::add("CannotWearTrash");  	} @@ -4600,7 +4600,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	lldebugs << "LLWearableBridge::buildContextMenu()" << llendl;  	std::vector<std::string> items;  	std::vector<std::string> disabled_items; -	if(isInTrash()) +	if(isItemInTrash())  	{  		items.push_back(std::string("Purge Item"));  		if (!isItemRemovable()) @@ -4916,8 +4916,12 @@ void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable,  	}  	// Find and remove this item from the COF. +	// FIXME 2.1 - call removeCOFItemLinks in llappearancemgr instead.  	LLInventoryModel::item_array_t items = gInventory.collectLinkedItems(item_id, LLAppearanceManager::instance().getCOF()); -	llassert(items.size() == 1); // Should always have one and only one item linked to this in the COF. +	if (items.size() != 1) +	{ +		llwarns << "Found " << items.size() << " COF links to " << item_id.asString() << ", expected 1" << llendl; +	}  	for (LLInventoryModel::item_array_t::const_iterator iter = items.begin();  		 iter != items.end();  		 ++iter) @@ -4953,7 +4957,10 @@ void LLWearableBridge::removeAllClothesFromAvatar()  		// Find and remove this item from the COF.  		LLInventoryModel::item_array_t items = gInventory.collectLinkedItems(  			item_id, LLAppearanceManager::instance().getCOF()); -		llassert(items.size() == 1); // Should always have one and only one item linked to this in the COF. +		if (items.size() != 1) +		{ +			llwarns << "Found " << items.size() << " COF links to " << item_id.asString() << ", expected 1" << llendl; +		}  		for (LLInventoryModel::item_array_t::const_iterator iter = items.begin();  			 iter != items.end();  			 ++iter) @@ -5195,7 +5202,7 @@ void	LLLSLTextBridgeAction::doIt()  } -BOOL LLWearableBridgeAction::isInTrash() const +BOOL LLWearableBridgeAction::isItemInTrash() const  {  	if(!mModel) return FALSE;  	const LLUUID trash_id = mModel->findCategoryUUIDForType(LLFolderType::FT_TRASH); @@ -5243,7 +5250,7 @@ void LLWearableBridgeAction::wearOnAvatar()  //virtual  void LLWearableBridgeAction::doIt()  { -	if(isInTrash()) +	if(isItemInTrash())  	{  		LLNotificationsUtil::add("CannotWearTrash");  	} @@ -5308,7 +5315,7 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	items.push_back(std::string("Find Original"));  	disabled_items.push_back(std::string("Find Original")); -	if(isInTrash()) +	if(isItemInTrash())  	{  		items.push_back(std::string("Purge Item"));  		if (!isItemRemovable()) @@ -5359,7 +5366,7 @@ void LLLinkFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	std::vector<std::string> items;  	std::vector<std::string> disabled_items; -	if(isInTrash()) +	if(isItemInTrash())  	{  		items.push_back(std::string("Purge Item"));  		if (!isItemRemovable()) diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 6fffec96a0..6e256edc05 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -158,8 +158,10 @@ public:  	virtual void showProperties();  	virtual BOOL isItemRenameable() const { return TRUE; }  	//virtual BOOL renameItem(const std::string& new_name) {} -	virtual BOOL isItemRemovable(); +	virtual BOOL isItemRemovable() const;  	virtual BOOL isItemMovable() const; +	virtual BOOL isItemInTrash() const; +  	//virtual BOOL removeItem() = 0;  	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);  	virtual void move(LLFolderViewEventListener* new_parent_bridge) {} @@ -185,13 +187,13 @@ public:  	// Allow context menus to be customized for side panel.  	bool isInOutfitsSidePanel() const; +  protected:  	LLInvFVBridge(LLInventoryPanel* inventory, const LLUUID& uuid);  	LLInventoryObject* getInventoryObject() const;  	LLInventoryModel* getInventoryModel() const; -	BOOL isInTrash() const;  	BOOL isLinkedObjectInTrash() const; // Is this obj or its baseobj in the trash?  	BOOL isLinkedObjectMissing() const; // Is this a linked obj whose baseobj is not in inventory? @@ -306,7 +308,7 @@ public:  							EDragAndDropType cargo_type,  							void* cargo_data); -	virtual BOOL isItemRemovable(); +	virtual BOOL isItemRemovable() const;  	virtual BOOL isItemMovable() const ;  	virtual BOOL isUpToDate() const;  	virtual BOOL isItemCopyable() const; @@ -786,7 +788,7 @@ protected:  	LLWearableBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){} -	BOOL isInTrash() const; +	BOOL isItemInTrash() const;  	// return true if the item is in agent inventory. if false, it  	// must be lost or in the inventory library.  	BOOL isAgentInventory() const; diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 8c875c9b63..d579058c32 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -152,6 +152,7 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)  		if (avatar_id.notNull())  		{  			// ...valid avatar id +  			LLScrollListCell* hit_cell = hit_item->getColumn(column_index);  			if (hit_cell)  			{ @@ -162,8 +163,8 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)  				localRectToScreen(cell_rect, &sticky_rect);  				// Spawn at right side of cell -				LLCoordGL pos( sticky_rect.mRight - 16, sticky_rect.mTop + (sticky_rect.getHeight()-16)/2 );  				LLPointer<LLUIImage> icon = LLUI::getUIImage("Info_Small"); +				LLCoordGL pos( sticky_rect.mRight - 16, sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight())/2 );  				// Should we show a group or an avatar inspector?  				bool is_group = hit_item->getValue()["is_group"].asBoolean(); diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 59708fcfb5..46cab0d868 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -185,43 +185,46 @@ void LLTeleportHistoryMenuItem::onMouseLeave(S32 x, S32 y, MASK mask)  static LLDefaultChildRegistry::Register<LLPullButton> menu_button("pull_button"); -LLPullButton::LLPullButton(const LLPullButton::Params& params): -		LLButton(params) -	,	mClickDraggingSignal(NULL) +LLPullButton::LLPullButton(const LLPullButton::Params& params) : +	LLButton(params)  {  	setDirectionFromName(params.direction);  } -boost::signals2::connection LLPullButton::setClickDraggingCallback( const commit_signal_t::slot_type& cb )  -{  -	if (!mClickDraggingSignal) mClickDraggingSignal = new commit_signal_t(); -	return mClickDraggingSignal->connect(cb);  +boost::signals2::connection LLPullButton::setClickDraggingCallback(const commit_signal_t::slot_type& cb) +{ +	return mClickDraggingSignal.connect(cb);  }  /*virtual*/  void LLPullButton::onMouseLeave(S32 x, S32 y, MASK mask)  {  	LLButton::onMouseLeave(x, y, mask); -	 -	if(mMouseDownTimer.getStarted() ) + +	if (mMouseDownTimer.getStarted()) //an user have done a mouse down, if the timer started. see LLButton::handleMouseDown for details  	{ -		const LLVector2 cursor_direction = LLVector2(F32(x),F32(y)) - mLastMouseDown; -		if( angle_between(mDraggingDirection, cursor_direction) < 0.5 * F_PI_BY_TWO)//call if angle < pi/4  -			{ -				if(mClickDraggingSignal) -				{ -					(*mClickDraggingSignal)(this, LLSD()); -				} -			} +		const LLVector2 cursor_direction = LLVector2(F32(x), F32(y)) - mLastMouseDown; +		/* For now cursor_direction points to the direction of mouse movement +		 * Need to decide whether should we fire a signal.  +		 * We fire if angle between mDraggingDirection and cursor_direction is less that 45 degree +		 * Note: +		 * 0.5 * F_PI_BY_TWO equals to PI/4 radian that equals to angle of 45 degrees +		 */ +		if (angle_between(mDraggingDirection, cursor_direction) < 0.5 * F_PI_BY_TWO)//call if angle < pi/4  +		{ +			mClickDraggingSignal(this, LLSD()); +		}  	}  }  /*virtual*/  BOOL LLPullButton::handleMouseDown(S32 x, S32 y, MASK mask) +{ +	BOOL handled = LLButton::handleMouseDown(x, y, mask); +	if (handled)  	{ -	BOOL handled = LLButton::handleMouseDown(x,y, mask); -	if(handled) -	{ +		//if mouse down was handled by button,  +		//capture mouse position to calculate the direction of  mouse move  after mouseLeave event   		mLastMouseDown.set(F32(x), F32(y));  	}  	return handled; @@ -230,27 +233,31 @@ BOOL LLPullButton::handleMouseDown(S32 x, S32 y, MASK mask)  /*virtual*/  BOOL LLPullButton::handleMouseUp(S32 x, S32 y, MASK mask)  { +	// reset data to get ready for next circle   	mLastMouseDown.clear();  	return LLButton::handleMouseUp(x, y, mask);  } - +/** + * this function is setting up dragging direction vector.  + * Last one is just unit vector. It points to direction of mouse drag that we need to handle    + */  void LLPullButton::setDirectionFromName(const std::string& name)  {  	if (name == "left")  	{ -		mDraggingDirection.set(F32(-1), F32(0));  +		mDraggingDirection.set(F32(-1), F32(0));  	}  	else if (name == "right")  	{ -		mDraggingDirection.set(F32(0), F32(1));  +		mDraggingDirection.set(F32(0), F32(1));  	}  	else if (name == "down")  	{ -		 mDraggingDirection.set(F32(0), F32(-1));  +		mDraggingDirection.set(F32(0), F32(-1));  	}  	else if (name == "up")  	{ -		 mDraggingDirection.set(F32(0), F32(1));  +		mDraggingDirection.set(F32(0), F32(1));  	}  } diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index 9d0abc7a3a..b512f2a79c 100644 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -44,46 +44,41 @@ class LLSearchComboBox;  /**   * This button is able to handle click-dragging mouse event.   * It has appropriated signal for this event. - * Dragging direction can be set from xml by attribute called 'direction' + * Dragging direction can be set from xml attribute called 'direction'   *    * *TODO: move to llui?     */ -class LLPullButton : public LLButton +class LLPullButton: public LLButton  {  	LOG_CLASS(LLPullButton); -	 +  public: -	 -	struct Params : public LLInitParam::Block<Params, LLButton::Params> +	struct Params: public LLInitParam::Block<Params, LLButton::Params>  	{ -		Optional<std::string>	direction; // left, right, down, up -		 -		Params() -		:	direction("direction","down") -		{} +		Optional<std::string> direction; // left, right, down, up + +		Params()  +		:	direction("direction", "down") +		{ +		}  	};  	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); -	 +  	/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); -	 +  	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); -	boost::signals2::connection setClickDraggingCallback( const commit_signal_t::slot_type& cb ); -	 -	/* virtual*/ ~LLPullButton() -	{ -		delete mClickDraggingSignal; -	} -	 +	boost::signals2::connection setClickDraggingCallback(const commit_signal_t::slot_type& cb); +  protected:  	friend class LLUICtrlFactory;  	// convert string name into direction vector  	void setDirectionFromName(const std::string& name);  	LLPullButton(const LLPullButton::Params& params); -	 -	commit_signal_t* mClickDraggingSignal;	 + +	commit_signal_t mClickDraggingSignal;  	LLVector2 mLastMouseDown;  	LLVector2 mDraggingDirection;  }; diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 6de47fccd2..8fc11d3929 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -200,18 +200,16 @@ void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)  		mMessageArchive.push_back(chat);  		if(mMessageArchive.size()>200)  			mMessageArchive.erase(mMessageArchive.begin()); +	} -		if (gSavedPerAccountSettings.getBOOL("LogChat"))  -		{ -			if (chat.mChatType != CHAT_TYPE_WHISPER && chat.mChatType != CHAT_TYPE_SHOUT) -			{ -				LLLogChat::saveHistory("chat", chat.mFromName, chat.mFromID, chat.mText); -			} -			else -			{ -				LLLogChat::saveHistory("chat", "", chat.mFromID, chat.mFromName + " " + chat.mText); -			} -		} +	if (args["do_not_log"].asBoolean())  +	{ +		return; +	} + +	if (gSavedPerAccountSettings.getBOOL("LogChat"))  +	{ +		LLLogChat::saveHistory("chat", chat.mFromName, chat.mFromID, chat.mText);  	}  } @@ -282,6 +280,9 @@ void LLNearbyChat::processChatHistoryStyleUpdate(const LLSD& newvalue)  void LLNearbyChat::loadHistory()  { +	LLSD do_not_log; +	do_not_log["do_not_log"] = true; +  	std::list<LLSD> history;  	LLLogChat::loadAllHistory("chat", history); @@ -302,7 +303,7 @@ void LLNearbyChat::loadHistory()  		chat.mFromID = from_id;  		chat.mText = msg[IM_TEXT].asString();  		chat.mTimeStr = msg[IM_TIME].asString(); -		addMessage(chat); +		addMessage(chat, true, do_not_log);  		it++;  	} diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index c08ca30bab..be48770567 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -274,6 +274,13 @@ void LLNearbyChatScreenChannel::showToastsBottom()  			toast->setRect(toast_rect);  			toast->setIsHidden(false);  			toast->setVisible(TRUE); + +			if(!toast->hasFocus()) +			{ +				// Fixing Z-order of toasts (EXT-4862) +				// Next toast will be positioned under this one. +				gFloaterView->sendChildToBack(toast); +			}  			bottom = toast->getRect().mTop;  		}		 diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 47feef496a..7c1b0f6234 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -171,8 +171,6 @@ BOOL LLLandmarksPanel::postBuild()  	initLandmarksInventoryPanel();  	initMyInventoryPanel();  	initLibraryInventoryPanel(); -	getChild<LLAccordionCtrlTab>("tab_favorites")->setDisplayChildren(true); -	getChild<LLAccordionCtrlTab>("tab_landmarks")->setDisplayChildren(true);  	return TRUE;  } @@ -462,7 +460,7 @@ void LLLandmarksPanel::initFavoritesInventoryPanel()  	initLandmarksPanel(mFavoritesInventoryPanel);  	mFavoritesInventoryPanel->getFilter()->setEmptyLookupMessage("FavoritesNoMatchingItems"); -	initAccordion("tab_favorites", mFavoritesInventoryPanel); +	initAccordion("tab_favorites", mFavoritesInventoryPanel, true);  }  void LLLandmarksPanel::initLandmarksInventoryPanel() @@ -481,7 +479,7 @@ void LLLandmarksPanel::initLandmarksInventoryPanel()  	// subscribe to have auto-rename functionality while creating New Folder  	mLandmarksInventoryPanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mLandmarksInventoryPanel, _1, _2)); -	initAccordion("tab_landmarks", mLandmarksInventoryPanel); +	initAccordion("tab_landmarks", mLandmarksInventoryPanel, true);  }  void LLLandmarksPanel::initMyInventoryPanel() @@ -490,7 +488,7 @@ void LLLandmarksPanel::initMyInventoryPanel()  	initLandmarksPanel(mMyInventoryPanel); -	initAccordion("tab_inventory", mMyInventoryPanel); +	initAccordion("tab_inventory", mMyInventoryPanel, false);  }  void LLLandmarksPanel::initLibraryInventoryPanel() @@ -499,7 +497,15 @@ void LLLandmarksPanel::initLibraryInventoryPanel()  	initLandmarksPanel(mLibraryInventoryPanel); -	initAccordion("tab_library", mLibraryInventoryPanel); +	// We want to fetch only "Landmarks" category from the library. +	const LLUUID &landmarks_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false, true); +	if (landmarks_cat.notNull()) +	{ +		gInventory.startBackgroundFetch(landmarks_cat); +	} + +	// Expanding "Library" tab for new users who have no landmarks in "My Inventory". +	initAccordion("tab_library", mLibraryInventoryPanel, true);  }  void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list) @@ -526,14 +532,14 @@ void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list  	inventory_list->saveFolderState();  } -void LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list) +void LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list,	bool expand_tab)  {  	LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>(accordion_tab_name);  	mAccordionTabs.push_back(accordion_tab);  	accordion_tab->setDropDownStateChangedCallback(  		boost::bind(&LLLandmarksPanel::onAccordionExpandedCollapsed, this, _2, inventory_list)); -	accordion_tab->setDisplayChildren(false); +	accordion_tab->setDisplayChildren(expand_tab);  }  void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list) diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 96b790844c..cbbd10ac26 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -110,7 +110,7 @@ private:  	void initMyInventoryPanel();  	void initLibraryInventoryPanel();  	void initLandmarksPanel(LLPlacesInventoryPanel* inventory_list); -	void initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list); +	void initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list, bool expand_tab);  	void onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list);  	void deselectOtherThan(const LLPlacesInventoryPanel* inventory_list); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index a5a61f0c7b..1895993a8e 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -1071,7 +1071,11 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)  			{  				const LLUUID &item_id = (*iter);  				LLFolderViewItem *item = folder->getItemByID(item_id); -				can_delete &= item->getListener()->isItemRemovable(); +				const LLFolderViewEventListener *listener = item->getListener(); +				llassert(listener); +				if (!listener) return FALSE; +				can_delete &= listener->isItemRemovable(); +				can_delete &= !listener->isItemInTrash();  			}  			return can_delete;  		} diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp index f574f55beb..f601a8d51c 100644 --- a/indra/newview/llpanelmediasettingsgeneral.cpp +++ b/indra/newview/llpanelmediasettingsgeneral.cpp @@ -250,18 +250,18 @@ bool LLPanelMediaSettingsGeneral::isMultiple()  ////////////////////////////////////////////////////////////////////////////////  // static  -void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_settings ,bool editable) +void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& _media_settings, bool editable)  {  	LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;  	self->mMediaEditable = editable; +	LLSD media_settings = _media_settings; +	  	if ( LLPanelMediaSettingsGeneral::isMultiple() )  	{ -		self->clearValues(self, self->mMediaEditable); -		// only show multiple  -		self->mHomeURL->setText(LLTrans::getString("Multiple Media")); -		self->mCurrentURL->setText(LLTrans::getString("Multiple Media")); -		return; +		// *HACK:  "edit" the incoming media_settings +		media_settings[LLMediaEntry::CURRENT_URL_KEY] = LLTrans::getString("Multiple Media"); +		media_settings[LLMediaEntry::HOME_URL_KEY] = LLTrans::getString("Multiple Media");  	}  	std::string base_key( "" ); @@ -286,7 +286,7 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_  		{ LLMediaEntry::WIDTH_PIXELS_KEY,			self->mWidthPixels,		"LLSpinCtrl" },  		{ "", NULL , "" }  	}; - +	  	for( int i = 0; data_set[ i ].key_name.length() > 0; ++i )  	{  		base_key = std::string( data_set[ i ].key_name ); @@ -405,20 +405,21 @@ void LLPanelMediaSettingsGeneral::preApply()  ////////////////////////////////////////////////////////////////////////////////  // -void LLPanelMediaSettingsGeneral::getValues( LLSD &fill_me_in ) +void LLPanelMediaSettingsGeneral::getValues( LLSD &fill_me_in, bool include_tentative )  { -	fill_me_in[LLMediaEntry::AUTO_LOOP_KEY] = (LLSD::Boolean)mAutoLoop->getValue(); -	fill_me_in[LLMediaEntry::AUTO_PLAY_KEY] = (LLSD::Boolean)mAutoPlay->getValue(); -	fill_me_in[LLMediaEntry::AUTO_SCALE_KEY] = (LLSD::Boolean)mAutoScale->getValue(); -	fill_me_in[LLMediaEntry::AUTO_ZOOM_KEY] = (LLSD::Boolean)mAutoZoom->getValue(); +	if (include_tentative || !mAutoLoop->getTentative()) fill_me_in[LLMediaEntry::AUTO_LOOP_KEY] = (LLSD::Boolean)mAutoLoop->getValue(); +	if (include_tentative || !mAutoPlay->getTentative()) fill_me_in[LLMediaEntry::AUTO_PLAY_KEY] = (LLSD::Boolean)mAutoPlay->getValue(); +	if (include_tentative || !mAutoScale->getTentative()) fill_me_in[LLMediaEntry::AUTO_SCALE_KEY] = (LLSD::Boolean)mAutoScale->getValue(); +	if (include_tentative || !mAutoZoom->getTentative()) fill_me_in[LLMediaEntry::AUTO_ZOOM_KEY] = (LLSD::Boolean)mAutoZoom->getValue();  	//Don't fill in current URL: this is only supposed to get changed via navigate -	// fill_me_in[LLMediaEntry::CURRENT_URL_KEY] = mCurrentURL->getValue(); -	fill_me_in[LLMediaEntry::HEIGHT_PIXELS_KEY] = (LLSD::Integer)mHeightPixels->getValue(); +	// if (include_tentative || !mCurrentURL->getTentative()) fill_me_in[LLMediaEntry::CURRENT_URL_KEY] = mCurrentURL->getValue(); +	if (include_tentative || !mHeightPixels->getTentative()) fill_me_in[LLMediaEntry::HEIGHT_PIXELS_KEY] = (LLSD::Integer)mHeightPixels->getValue();  	// Don't fill in the home URL if it is the special "Multiple Media" string! -	if (LLTrans::getString("Multiple Media") != mHomeURL->getValue()) -		fill_me_in[LLMediaEntry::HOME_URL_KEY] = (LLSD::String)mHomeURL->getValue(); -	fill_me_in[LLMediaEntry::FIRST_CLICK_INTERACT_KEY] = (LLSD::Boolean)mFirstClick->getValue(); -	fill_me_in[LLMediaEntry::WIDTH_PIXELS_KEY] = (LLSD::Integer)mWidthPixels->getValue(); +	if ((include_tentative || !mHomeURL->getTentative()) +		&& LLTrans::getString("Multiple Media") != mHomeURL->getValue()) +			fill_me_in[LLMediaEntry::HOME_URL_KEY] = (LLSD::String)mHomeURL->getValue(); +	if (include_tentative || !mFirstClick->getTentative()) fill_me_in[LLMediaEntry::FIRST_CLICK_INTERACT_KEY] = (LLSD::Boolean)mFirstClick->getValue(); +	if (include_tentative || !mWidthPixels->getTentative()) fill_me_in[LLMediaEntry::WIDTH_PIXELS_KEY] = (LLSD::Integer)mWidthPixels->getValue();  }  //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llpanelmediasettingsgeneral.h b/indra/newview/llpanelmediasettingsgeneral.h index 5f90321362..a3f0990f35 100644 --- a/indra/newview/llpanelmediasettingsgeneral.h +++ b/indra/newview/llpanelmediasettingsgeneral.h @@ -54,7 +54,8 @@ public:  	// Hook that the floater calls before applying changes from the panel  	void preApply();  	// Function that asks the panel to fill in values associated with the panel -    void getValues(LLSD &fill_me_in); +	// 'include_tentative' means fill in tentative values as well, otherwise do not +	void getValues(LLSD &fill_me_in, bool include_tentative = true);  	// Hook that the floater calls after applying changes to the panel  	void postApply(); diff --git a/indra/newview/llpanelmediasettingspermissions.cpp b/indra/newview/llpanelmediasettingspermissions.cpp index a23aed2e98..e5caaaaffc 100644 --- a/indra/newview/llpanelmediasettingspermissions.cpp +++ b/indra/newview/llpanelmediasettingspermissions.cpp @@ -149,27 +149,6 @@ void LLPanelMediaSettingsPermissions::clearValues( void* userdata, bool editable  void LLPanelMediaSettingsPermissions::initValues( void* userdata, const LLSD& media_settings ,  bool editable)  {      LLPanelMediaSettingsPermissions *self =(LLPanelMediaSettingsPermissions *)userdata; - -	if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo ) -	{ -		if(LLFloaterMediaSettings::getInstance()->mMultipleMedia)  -		{ -			self->clearValues(self, editable); -			// only show multiple  -			return; -		} -		 -	} -	else -	{ -		if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)  -		{ -			self->clearValues(self, editable); -			// only show multiple  -			return; -		}			 -		 -	}      std::string base_key( "" );      std::string tentative_key( "" ); @@ -215,7 +194,29 @@ void LLPanelMediaSettingsPermissions::initValues( void* userdata, const LLSD& me              data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );          };      }; - +	 +	// *NOTE: If any of a particular flavor is tentative, we have to disable  +	// them all because of an architectural issue: namely that we represent  +	// these as a bit field, and we can't selectively apply only one bit to all selected +	// faces if they don't match.  Also see the *NOTE below. +	if ( self->mPermsOwnerInteract->getTentative() || +		 self->mPermsGroupInteract->getTentative() || +		 self->mPermsWorldInteract->getTentative()) +	{ +		self->mPermsOwnerInteract->setEnabled(false); +		self->mPermsGroupInteract->setEnabled(false); +		self->mPermsWorldInteract->setEnabled(false); +	}	 +	if ( self->mPermsOwnerControl->getTentative() || +		 self->mPermsGroupControl->getTentative() || +		 self->mPermsWorldControl->getTentative()) +	{ +		self->mPermsOwnerControl->setEnabled(false); +		self->mPermsGroupControl->setEnabled(false); +		self->mPermsWorldControl->setEnabled(false); +	} +	 +	  	self->childSetEnabled("media_perms_label_owner", editable );  	self->childSetText("media_perms_label_owner",  LLTrans::getString("Media Perms Owner") );  	self->childSetEnabled("media_perms_label_group", editable ); @@ -233,29 +234,47 @@ void LLPanelMediaSettingsPermissions::preApply()  ////////////////////////////////////////////////////////////////////////////////  // -void LLPanelMediaSettingsPermissions::getValues( LLSD &fill_me_in ) +void LLPanelMediaSettingsPermissions::getValues( LLSD &fill_me_in, bool include_tentative )  {  	// moved over from the 'General settings' tab -	fill_me_in[LLMediaEntry::CONTROLS_KEY] = (LLSD::Integer)mControls->getCurrentIndex(); - -    // *NOTE: For some reason, gcc does not like these symbol references in the  -    // expressions below (inside the static_casts).  I have NO idea why :(. -    // For some reason, assigning them to const temp vars here fixes the link -    // error.  Bizarre. -    const U8 none = LLMediaEntry::PERM_NONE; -    const U8 owner = LLMediaEntry::PERM_OWNER; -    const U8 group = LLMediaEntry::PERM_GROUP; -    const U8 anyone = LLMediaEntry::PERM_ANYONE; -    const LLSD::Integer control = static_cast<LLSD::Integer>( +	if (include_tentative || !mControls->getTentative()) fill_me_in[LLMediaEntry::CONTROLS_KEY] = (LLSD::Integer)mControls->getCurrentIndex(); +	 +	// *NOTE: For some reason, gcc does not like these symbol references in the  +	// expressions below (inside the static_casts).	 I have NO idea why :(. +	// For some reason, assigning them to const temp vars here fixes the link +	// error.  Bizarre. +	const U8 none = LLMediaEntry::PERM_NONE; +	const U8 owner = LLMediaEntry::PERM_OWNER; +	const U8 group = LLMediaEntry::PERM_GROUP; +	const U8 anyone = LLMediaEntry::PERM_ANYONE;  +	const LLSD::Integer control = static_cast<LLSD::Integer>(  		(mPermsOwnerControl->getValue() ? owner : none ) |  		(mPermsGroupControl->getValue() ? group: none  ) |  		(mPermsWorldControl->getValue() ? anyone : none )); -    const LLSD::Integer interact = static_cast<LLSD::Integer>( -		(mPermsOwnerInteract->getValue() ? owner: none  ) | +	const LLSD::Integer interact = static_cast<LLSD::Integer>( +		(mPermsOwnerInteract->getValue() ? owner: none	) |  		(mPermsGroupInteract->getValue() ? group : none ) |  		(mPermsWorldInteract->getValue() ? anyone : none )); -    fill_me_in[LLMediaEntry::PERMS_CONTROL_KEY] = control; -    fill_me_in[LLMediaEntry::PERMS_INTERACT_KEY] = interact; +	 +	// *TODO: This will fill in the values of all permissions values, even if +	// one or more is tentative.  This is not quite the user expectation...what +	// it should do is only change the bit that was made "untentative", but in +	// a multiple-selection situation, this isn't possible given the architecture +	// for how settings are applied. +	if (include_tentative ||  +		!mPermsOwnerControl->getTentative() ||  +		!mPermsGroupControl->getTentative() ||  +		!mPermsWorldControl->getTentative()) +	{ +		fill_me_in[LLMediaEntry::PERMS_CONTROL_KEY] = control; +	} +	if (include_tentative ||  +		!mPermsOwnerInteract->getTentative() ||  +		!mPermsGroupInteract->getTentative() ||  +		!mPermsWorldInteract->getTentative()) +	{ +		fill_me_in[LLMediaEntry::PERMS_INTERACT_KEY] = interact; +	}  } diff --git a/indra/newview/llpanelmediasettingspermissions.h b/indra/newview/llpanelmediasettingspermissions.h index bd0c3b8ab5..858544605c 100644 --- a/indra/newview/llpanelmediasettingspermissions.h +++ b/indra/newview/llpanelmediasettingspermissions.h @@ -57,7 +57,8 @@ public:  	// Hook that the floater calls before applying changes from the panel  	void preApply();  	// Function that asks the panel to fill in values associated with the panel -    void getValues(LLSD &fill_me_in); +	// 'include_tentative' means fill in tentative values as well, otherwise do not +	void getValues(LLSD &fill_me_in, bool include_tentative = true);  	// Hook that the floater calls after applying changes to the panel  	void postApply(); diff --git a/indra/newview/llpanelmediasettingssecurity.cpp b/indra/newview/llpanelmediasettingssecurity.cpp index 81842e3851..1b1346c41a 100644 --- a/indra/newview/llpanelmediasettingssecurity.cpp +++ b/indra/newview/llpanelmediasettingssecurity.cpp @@ -94,27 +94,6 @@ void LLPanelMediaSettingsSecurity::draw()  void LLPanelMediaSettingsSecurity::initValues( void* userdata, const LLSD& media_settings , bool editable)  {  	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata; - -	if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo ) -	{ -		if(LLFloaterMediaSettings::getInstance()->mMultipleMedia)  -		{ -			self->clearValues(self, editable); -			// only show multiple  -			return; -		} -		 -	} -	else -	{ -		if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)  -		{ -			self->clearValues(self, editable); -			// only show multiple  -			return; -		}			 -		 -	}  	std::string base_key( "" );  	std::string tentative_key( "" ); @@ -136,6 +115,8 @@ void LLPanelMediaSettingsSecurity::initValues( void* userdata, const LLSD& media  		base_key = std::string( data_set[ i ].key_name );          tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ); +		bool enabled_overridden = false; +		  		// TODO: CP - I bet there is a better way to do this using Boost  		if ( media_settings[ base_key ].isDefined() )  		{ @@ -150,20 +131,31 @@ void LLPanelMediaSettingsSecurity::initValues( void* userdata, const LLSD& media  				// get control   				LLScrollListCtrl* list = static_cast< LLScrollListCtrl* >( data_set[ i ].ctrl_ptr );  				list->deleteAllItems(); - +				  				// points to list of white list URLs  				LLSD url_list = media_settings[ base_key ]; - -				// iterate over them and add to scroll list -				LLSD::array_iterator iter = url_list.beginArray(); -				while( iter != url_list.endArray() ) +				 +				// better be the whitelist +				llassert(data_set[ i ].ctrl_ptr == self->mWhiteListList); +				 +				// If tentative, don't add entries +				if (media_settings[ tentative_key ].asBoolean())  				{ -					std::string entry = *iter; -					self->addWhiteListEntry( entry ); -					++iter; -				}; +					self->mWhiteListList->setEnabled(false); +					enabled_overridden = true; +				} +				else { +					// iterate over them and add to scroll list +					LLSD::array_iterator iter = url_list.beginArray(); +					while( iter != url_list.endArray() ) +					{ +						std::string entry = *iter; +						self->addWhiteListEntry( entry ); +						++iter; +					} +				}  			}; -			data_set[ i ].ctrl_ptr->setEnabled(editable); +			if ( ! enabled_overridden) data_set[ i ].ctrl_ptr->setEnabled(editable);  			data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );  		};  	}; @@ -192,25 +184,29 @@ void LLPanelMediaSettingsSecurity::preApply()  ////////////////////////////////////////////////////////////////////////////////  // -void LLPanelMediaSettingsSecurity::getValues( LLSD &fill_me_in ) +void LLPanelMediaSettingsSecurity::getValues( LLSD &fill_me_in, bool include_tentative )  { -    fill_me_in[LLMediaEntry::WHITELIST_ENABLE_KEY] = (LLSD::Boolean)mEnableWhiteList->getValue(); - -    // iterate over white list and extract items -    std::vector< LLScrollListItem* > whitelist_items = mWhiteListList->getAllData(); -    std::vector< LLScrollListItem* >::iterator iter = whitelist_items.begin(); - -	// *NOTE: need actually set the key to be an emptyArray(), or the merge -	// we do with this LLSD will think there's nothing to change. -    fill_me_in[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray(); -    while( iter != whitelist_items.end() ) -    { -		LLScrollListCell* cell = (*iter)->getColumn( ENTRY_COLUMN ); -		std::string whitelist_url = cell->getValue().asString(); - -        fill_me_in[ LLMediaEntry::WHITELIST_KEY ].append( whitelist_url ); -        ++iter; -    }; +    if (include_tentative || !mEnableWhiteList->getTentative())  +		fill_me_in[LLMediaEntry::WHITELIST_ENABLE_KEY] = (LLSD::Boolean)mEnableWhiteList->getValue(); +	 +	if (include_tentative || !mWhiteListList->getTentative()) +	{ +		// iterate over white list and extract items +		std::vector< LLScrollListItem* > whitelist_items = mWhiteListList->getAllData(); +		std::vector< LLScrollListItem* >::iterator iter = whitelist_items.begin(); +		 +		// *NOTE: need actually set the key to be an emptyArray(), or the merge +		// we do with this LLSD will think there's nothing to change. +		fill_me_in[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray(); +		while( iter != whitelist_items.end() ) +		{ +			LLScrollListCell* cell = (*iter)->getColumn( ENTRY_COLUMN ); +			std::string whitelist_url = cell->getValue().asString(); +			 +			fill_me_in[ LLMediaEntry::WHITELIST_KEY ].append( whitelist_url ); +			++iter; +		}; +	}  }  //////////////////////////////////////////////////////////////////////////////// @@ -247,6 +243,10 @@ const std::string LLPanelMediaSettingsSecurity::makeValidUrl( const std::string&  // white list list box widget and build a list to test against.   bool LLPanelMediaSettingsSecurity::urlPassesWhiteList( const std::string& test_url )  { +	// If the whitlelist list is tentative, it means we have multiple settings. +	// In that case, we have no choice but to return true +	if ( mWhiteListList->getTentative() ) return true; +	  	// the checkUrlAgainstWhitelist(..) function works on a vector  	// of strings for the white list entries - in this panel, the white list  	// is stored in the widgets themselves so we need to build something compatible. @@ -330,7 +330,7 @@ void LLPanelMediaSettingsSecurity::addWhiteListEntry( const std::string& entry )  	// always add in the entry itself  	row[ "columns" ][ ENTRY_COLUMN ][ "type" ] = "text";  	row[ "columns" ][ ENTRY_COLUMN ][ "value" ] = entry; - +	  	// add to the white list scroll box  	mWhiteListList->addElement( row );  }; diff --git a/indra/newview/llpanelmediasettingssecurity.h b/indra/newview/llpanelmediasettingssecurity.h index 66ccb23f46..94f2fdc89c 100644 --- a/indra/newview/llpanelmediasettingssecurity.h +++ b/indra/newview/llpanelmediasettingssecurity.h @@ -53,11 +53,12 @@ public:  	// Hook that the floater calls before applying changes from the panel  	void preApply();  	// Function that asks the panel to fill in values associated with the panel -    void getValues(LLSD &fill_me_in); +	// 'include_tentative' means fill in tentative values as well, otherwise do not +	void getValues(LLSD &fill_me_in, bool include_tentative = true);  	// Hook that the floater calls after applying changes to the panel  	void postApply(); -	static void initValues( void* userdata, const LLSD& media_settings,bool editable ); +	static void initValues( void* userdata, const LLSD& media_settings, bool editable);  	static void clearValues( void* userdata, bool editable);  	void addWhiteListEntry( const std::string& url );  	void setParent( LLFloaterMediaSettings* parent ); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 5c5c35141e..e8ae006968 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -117,7 +117,7 @@ public:  	virtual BOOL isItemRenameable() const;  	virtual BOOL renameItem(const std::string& new_name);  	virtual BOOL isItemMovable() const; -	virtual BOOL isItemRemovable(); +	virtual BOOL isItemRemovable() const;  	virtual BOOL removeItem();  	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);  	virtual void move(LLFolderViewEventListener* parent_listener); @@ -412,9 +412,9 @@ BOOL LLTaskInvFVBridge::isItemMovable() const  	return TRUE;  } -BOOL LLTaskInvFVBridge::isItemRemovable() +BOOL LLTaskInvFVBridge::isItemRemovable() const  { -	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); +	const LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());  	if(object  	   && (object->permModify() || object->permYouOwner()))  	{ @@ -710,7 +710,7 @@ public:  	virtual BOOL isItemRenameable() const;  	// virtual BOOL isItemCopyable() const { return FALSE; }  	virtual BOOL renameItem(const std::string& new_name); -	virtual BOOL isItemRemovable(); +	virtual BOOL isItemRemovable() const;  	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);  	virtual BOOL hasChildren() const;  	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const; @@ -742,7 +742,7 @@ BOOL LLTaskCategoryBridge::renameItem(const std::string& new_name)  	return FALSE;  } -BOOL LLTaskCategoryBridge::isItemRemovable() +BOOL LLTaskCategoryBridge::isItemRemovable() const  {  	return FALSE;  } diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index cf903958ee..c2f2d32142 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -159,6 +159,27 @@ void LLPanelOutfitsInventory::onOpen(const LLSD& key)  	// Make sure we know which tab is selected, update the filter,  	// and update verbs.  	onTabChange(); +	 +	// Auto open the first outfit newly created so new users can see sample outfit contents +	static bool should_open_outfit = true; +	if (should_open_outfit && gAgent.isFirstLogin()) +	{ +		LLInventoryPanel* outfits_panel = getChild<LLInventoryPanel>(OUTFITS_TAB_NAME); +		if (outfits_panel) +		{ +			LLUUID my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); +			LLFolderViewFolder* my_outfits_folder = outfits_panel->getRootFolder()->getFolderByID(my_outfits_id); +			if (my_outfits_folder) +			{ +				LLFolderViewFolder* first_outfit = dynamic_cast<LLFolderViewFolder*>(my_outfits_folder->getFirstChild()); +				if (first_outfit) +				{ +					first_outfit->setOpen(TRUE); +				} +			} +		} +	} +	should_open_outfit = false;  }  void LLPanelOutfitsInventory::updateVerbs() diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index ad47e351ee..1c4004c37a 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -584,7 +584,7 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD&  {  	std::string item = userdata.asString();  	if (item == "can_mute_text" || "can_block" == item || "can_share" == item || "can_im" == item  -		|| "can_pay" == item || "can_add" == item) +		|| "can_pay" == item)  	{  		return mUUIDs.front() != gAgentID;  	} @@ -619,7 +619,7 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD&  		for (;id != uuids_end; ++id)  		{ -			if ( LLAvatarActions::isFriend(*id) ) +			if ( *id == gAgentID || LLAvatarActions::isFriend(*id) )  			{  				result = false;  				break; diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp index 83443687c9..4fe69f295c 100644 --- a/indra/newview/llplacesinventorybridge.cpp +++ b/indra/newview/llplacesinventorybridge.cpp @@ -66,7 +66,7 @@ void LLPlacesLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	std::vector<std::string> items;  	std::vector<std::string> disabled_items; -	if(isInTrash()) +	if(isItemInTrash())  	{  		items.push_back(std::string("Purge Item"));  		if (!isItemRemovable()) diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 8f36c0e88a..7c2e7e3319 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -533,9 +533,13 @@ void LLScreenChannel::showToastsBottom()  			// HACK  			// EXT-2653: it is necessary to prevent overlapping for secondary showed toasts  			(*it).toast->setVisible(TRUE); -			// Show toast behind floaters. (EXT-3089) -			gFloaterView->sendChildToBack((*it).toast);  		}		 +		if(!(*it).toast->hasFocus()) +		{ +			// Fixing Z-order of toasts (EXT-4862) +			// Next toast will be positioned under this one. +			gFloaterView->sendChildToBack((*it).toast); +		}  	}  	if(it != mToastList.rend()) diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index bf08756051..9540894646 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -41,6 +41,7 @@  #include "lldbstrings.h"  #include "lleconomy.h"  #include "llgl.h" +#include "llmediaentry.h"  #include "llrender.h"  #include "llnotifications.h"  #include "llpermissions.h" @@ -1739,70 +1740,70 @@ void LLSelectMgr::selectionSetFullbright(U8 fullbright)  	getSelection()->applyToObjects(&sendfunc);  } -void LLSelectMgr::selectionSetMedia(U8 media_type) -{ -	 -	struct f : public LLSelectedTEFunctor -	{ -		U8 mMediaFlags; -		f(const U8& t) : mMediaFlags(t) {} -		bool apply(LLViewerObject* object, S32 te) -		{ -			if (object->permModify()) -			{ -				// update viewer has media -				object->setTEMediaFlags(te, mMediaFlags); -			} -			return true; -		} -	} setfunc(media_type); -	getSelection()->applyToTEs(&setfunc); -	struct f2 : public LLSelectedObjectFunctor -	{ -		virtual bool apply(LLViewerObject* object) -		{ -			if (object->permModify()) -			{ -				object->sendTEUpdate(); -			} -			return true; -		} -	} func2; -	mSelectedObjects->applyToObjects( &func2 ); -} -  // This function expects media_data to be a map containing relevant  // media data name/value pairs (e.g. home_url, etc.) -void LLSelectMgr::selectionSetMediaData(const LLSD &media_data) -{ - +void LLSelectMgr::selectionSetMedia(U8 media_type, const LLSD &media_data) +{	  	struct f : public LLSelectedTEFunctor  	{ +		U8 mMediaFlags;  		const LLSD &mMediaData; -		f(const LLSD& t) : mMediaData(t) {} +		f(const U8& t, const LLSD& d) : mMediaFlags(t), mMediaData(d) {}  		bool apply(LLViewerObject* object, S32 te)  		{  			if (object->permModify())  			{ -                LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object); -                if (NULL != vo)  -                { -                    vo->syncMediaData(te, mMediaData, true/*merge*/, true/*ignore_agent*/); -                }                 +				// If we are adding media, then check the current state of the +				// media data on this face.   +				//  - If it does not have media, AND we are NOT setting the HOME URL, then do NOT add media to this +				// face. +				//  - If it does not have media, and we ARE setting the HOME URL, add media to this face. +				//  - If it does already have media, add/update media to/on this face +				// If we are removing media, just do it (ignore the passed-in LLSD). +				if (mMediaFlags & LLTextureEntry::MF_HAS_MEDIA) +				{ +					llassert(mMediaData.isMap()); +					const LLTextureEntry *texture_entry = object->getTE(te); +					if (!mMediaData.isMap() || +						(NULL != texture_entry) && !texture_entry->hasMedia() && !mMediaData.has(LLMediaEntry::HOME_URL_KEY)) +					{ +						// skip adding/updating media +					} +					else { +						// Add/update media +						object->setTEMediaFlags(te, mMediaFlags); +						LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object); +						llassert(NULL != vo); +						if (NULL != vo)  +						{ +							vo->syncMediaData(te, mMediaData, true/*merge*/, true/*ignore_agent*/); +						} +					} +				} +				else +				{ +					// delete media (or just set the flags) +					object->setTEMediaFlags(te, mMediaFlags); +				}  			}  			return true;  		} -	} setfunc(media_data); +	} setfunc(media_type, media_data);  	getSelection()->applyToTEs(&setfunc); - +	  	struct f2 : public LLSelectedObjectFunctor  	{  		virtual bool apply(LLViewerObject* object)  		{  			if (object->permModify())  			{ -                LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object); -                if (NULL != vo)  +				object->sendTEUpdate(); +				LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object); +				llassert(NULL != vo); +				// It's okay to skip this object if hasMedia() is false... +				// the sendTEUpdate() above would remove all media data if it were +				// there. +                if (NULL != vo && vo->hasMedia())                  {                      // Send updated media data FOR THE ENTIRE OBJECT                      vo->sendMediaDataUpdate(); @@ -1811,11 +1812,9 @@ void LLSelectMgr::selectionSetMediaData(const LLSD &media_data)  			return true;  		}  	} func2; -	getSelection()->applyToObjects(&func2); +	mSelectedObjects->applyToObjects( &func2 );  } - -  void LLSelectMgr::selectionSetGlow(F32 glow)  {  	struct f1 : public LLSelectedTEFunctor diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index f8ecfd0674..00474827ca 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -502,8 +502,7 @@ public:  	void selectionSetTexGen( U8 texgen );  	void selectionSetShiny( U8 shiny );  	void selectionSetFullbright( U8 fullbright ); -	void selectionSetMedia( U8 media_type ); -	void selectionSetMediaData(const LLSD &media_data); // NOTE: modifies media_data!!! +	void selectionSetMedia( U8 media_type, const LLSD &media_data );  	void selectionSetClickAction(U8 action);  	void selectionSetIncludeInSearch(bool include_in_search);  	void selectionSetGlow(const F32 glow); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 9fda77fe74..a402dfc3d1 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1876,6 +1876,17 @@ bool idle_startup()  				LLViewerShaderMgr::instance()->setShaders();  			}  		} +		 +		// If this is the very first time the user has logged into viewer2+ (from a legacy viewer, or new account) +		// then auto-populate outfits from the library into the My Outfits folder. +		static bool check_populate_my_outfits = true; +		if (check_populate_my_outfits &&  +			(LLInventoryModel::getIsFirstTimeInViewer2()  +			 || gSavedSettings.getBOOL("MyOutfitsAutofill"))) +		{ +			gAgentWearables.populateMyOutfitsFolder(); +		} +		check_populate_my_outfits = false;  		return TRUE;  	} diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index b6e7e73b9d..f3bfc2e86c 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -1107,16 +1107,17 @@ public:  	 * Sets internal voluem level for specified user.  	 *  	 * @param[in] speaker_id - LLUUID of user to store volume level for -	 * @param[in] volume - internal volume level to be stored for user. +	 * @param[in] volume - external (vivox) volume level to be stored for user.  	 */ -	void storeSpeakerVolume(const LLUUID& speaker_id, S32 volume); +	void storeSpeakerVolume(const LLUUID& speaker_id, F32 volume);  	/** -	 * Gets stored internal volume level for specified speaker. +	 * Gets stored external (vivox) volume level for specified speaker and +	 * transforms it into internal (viewer) level.  	 *  	 * If specified user is not found default level will be returned. It is equivalent of   	 * external level 0.5 from the 0.0..1.0 range. -	 * Default internal level is calculated as: internal = 400 * external^2 +	 * Internal level is calculated as: internal = 400 * external^2  	 * Maps 0.0 to 1.0 to internal values 0-400 with default 0.5 == 100  	 *  	 * @param[in] speaker_id - LLUUID of user to get his volume level @@ -1133,7 +1134,7 @@ private:  	void load();  	void save(); -	typedef std::map<LLUUID, S32> speaker_data_map_t; +	typedef std::map<LLUUID, F32> speaker_data_map_t;  	speaker_data_map_t mSpeakersData;  }; @@ -1149,7 +1150,7 @@ LLSpeakerVolumeStorage::~LLSpeakerVolumeStorage()  	save();  } -void LLSpeakerVolumeStorage::storeSpeakerVolume(const LLUUID& speaker_id, S32 volume) +void LLSpeakerVolumeStorage::storeSpeakerVolume(const LLUUID& speaker_id, F32 volume)  {  	mSpeakersData[speaker_id] = volume;  } @@ -1163,7 +1164,10 @@ S32 LLSpeakerVolumeStorage::getSpeakerVolume(const LLUUID& speaker_id)  	if (it != mSpeakersData.end())  	{ -		ret_val = it->second; +		F32 f_val = it->second; +		// volume can amplify by as much as 4x! +		S32 ivol = (S32)(400.f * f_val * f_val); +		ret_val = llclamp(ivol, 0, 400);  	}  	return ret_val;  } @@ -1184,7 +1188,7 @@ void LLSpeakerVolumeStorage::load()  	for (LLSD::map_const_iterator iter = settings_llsd.beginMap();  		iter != settings_llsd.endMap(); ++iter)  	{ -		mSpeakersData.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger())); +		mSpeakersData.insert(std::make_pair(LLUUID(iter->first), (F32)iter->second.asReal()));  	}  } @@ -6288,14 +6292,14 @@ void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume)  		participantState *participant = findParticipantByID(id);  		if (participant)  		{ +			// store this volume setting for future sessions +			LLSpeakerVolumeStorage::getInstance()->storeSpeakerVolume(id, volume); +  			// volume can amplify by as much as 4x!  			S32 ivol = (S32)(400.f * volume * volume);  			participant->mUserVolume = llclamp(ivol, 0, 400);  			participant->mVolumeDirty = TRUE;  			mAudioSession->mVolumeDirty = TRUE; - -			// store this volume setting for future sessions -			LLSpeakerVolumeStorage::getInstance()->storeSpeakerVolume(id, participant->mUserVolume);  		}  	}  } diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml index 15655a920e..05deca705a 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences.xml @@ -56,7 +56,7 @@           help_topic="preferences_general_tab"           name="general" />          <panel -	 class="panel_preference" +	 class="panel_preference_graphics"           filename="panel_preferences_graphics1.xml"           label="Graphics"           layout="topleft" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 5d78cfc9ef..d16474873f 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1532,7 +1532,7 @@ Your search terms were too short so no search was performed.     icon="alertmodal.tga"     name="CouldNotTeleportReason"     type="alertmodal"> -Could not teleport. +Teleport failed.  [REASON]    </notification> diff --git a/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml b/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml index b881719e3a..0c1418fc2d 100644 --- a/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml @@ -64,6 +64,7 @@       layout="topleft"       left="103"       name="description" +     textbox.mouse_opaque="false"        top_pad="0"       width="178"       word_wrap="true" /> diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 3b5add33a8..447ac1b123 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -137,6 +137,7 @@ background_visible="true"                          <avatar_list                           allow_select="true"                           follows="all" +                         height="235"                           layout="topleft"                           left="0"                           multi_select="true" @@ -152,6 +153,7 @@ background_visible="true"                          <avatar_list                           allow_select="true"                           follows="all" +                         height="235"                           layout="topleft"                           left="0"                           multi_select="true" diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml index 023b1fc81d..e62c1278f9 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml @@ -64,6 +64,7 @@       layout="topleft"       left="103"       name="picture_descr" +     textbox.mouse_opaque="false"        top_pad="0"       width="178"       word_wrap="true" /> diff --git a/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml b/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml index 888b4eaf7c..a71b293f31 100644 --- a/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml +++ b/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml @@ -5,4 +5,12 @@   item_pad="0"   keep_one_selected="true"   multi_select="false" - opaque="true" />
\ No newline at end of file + opaque="true"> +    <flat_list_view.no_items_text +     follows="all" +     name="no_items_msg" +     v_pad="10" +     h_pad="10" +     value="There are no any items in the list" +     wrap="true" /> +</flat_list_view>
\ No newline at end of file | 
