summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llprimitive/tests/llmediaentry_test.cpp7
-rw-r--r--indra/llrender/llfontgl.cpp24
-rw-r--r--indra/llui/llflatlistview.cpp47
-rw-r--r--indra/llui/llflatlistview.h5
-rw-r--r--indra/llui/lllineeditor.cpp6
-rw-r--r--indra/llui/lltexteditor.cpp5
-rw-r--r--indra/newview/llagentwearables.cpp7
-rw-r--r--indra/newview/llappearancemgr.cpp47
-rw-r--r--indra/newview/llchathistory.cpp13
-rw-r--r--indra/newview/llfavoritesbar.cpp21
-rw-r--r--indra/newview/llfloatermediasettings.cpp13
-rw-r--r--indra/newview/llfloaterpreference.cpp100
-rw-r--r--indra/newview/llfloaterpreference.h16
-rw-r--r--indra/newview/llfloatersnapshot.cpp4
-rw-r--r--indra/newview/llfolderview.cpp3
-rw-r--r--indra/newview/llfoldervieweventlistener.h3
-rw-r--r--indra/newview/llinventorybridge.cpp49
-rw-r--r--indra/newview/llinventorybridge.h10
-rw-r--r--indra/newview/llnamelistctrl.cpp3
-rw-r--r--indra/newview/llnavigationbar.cpp57
-rw-r--r--indra/newview/llnavigationbar.h37
-rw-r--r--indra/newview/llnearbychat.cpp25
-rw-r--r--indra/newview/llnearbychathandler.cpp7
-rw-r--r--indra/newview/llpanellandmarks.cpp22
-rw-r--r--indra/newview/llpanellandmarks.h2
-rw-r--r--indra/newview/llpanelmaininventory.cpp6
-rw-r--r--indra/newview/llpanelmediasettingsgeneral.cpp37
-rw-r--r--indra/newview/llpanelmediasettingsgeneral.h3
-rw-r--r--indra/newview/llpanelmediasettingspermissions.cpp95
-rw-r--r--indra/newview/llpanelmediasettingspermissions.h3
-rw-r--r--indra/newview/llpanelmediasettingssecurity.cpp100
-rw-r--r--indra/newview/llpanelmediasettingssecurity.h5
-rw-r--r--indra/newview/llpanelobjectinventory.cpp10
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp21
-rw-r--r--indra/newview/llparticipantlist.cpp4
-rw-r--r--indra/newview/llplacesinventorybridge.cpp2
-rw-r--r--indra/newview/llscreenchannel.cpp8
-rw-r--r--indra/newview/llselectmgr.cpp95
-rw-r--r--indra/newview/llselectmgr.h3
-rw-r--r--indra/newview/llstartup.cpp11
-rw-r--r--indra/newview/llvoiceclient.cpp26
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences.xml2
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/en/widgets/flat_list_view.xml10
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