diff options
author | Nyx (Neal Orman) <nyx@lindenlab.com> | 2012-01-25 15:59:37 -0500 |
---|---|---|
committer | Nyx (Neal Orman) <nyx@lindenlab.com> | 2012-01-25 15:59:37 -0500 |
commit | 50b67f052a440fba54a05fe32320f6bb84ea43cc (patch) | |
tree | e9716527ab736c1d5c92e0d1a4ee11cb071c522f /indra | |
parent | c4e0c20cdccc0604a1688ab3664295c1944321e8 (diff) | |
parent | 4ef9277761b5faee2825177112939b72c563a4ea (diff) |
MERGE - pulling latest viewer-development into pathfinding branch
Diffstat (limited to 'indra')
114 files changed, 4077 insertions, 3111 deletions
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 0e7060e22c..2f1c2a47c9 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -34,6 +34,10 @@ #include "llpanel.h" #include "llresizebar.h" #include "llcriticaldamp.h" +#include "boost/foreach.hpp" + +static const F32 MIN_FRACTIONAL_SIZE = 0.0001f; +static const F32 MAX_FRACTIONAL_SIZE = 1.f; static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack"); static LLLayoutStack::LayoutStackRegistry::Register<LLLayoutPanel> register_layout_panel("layout_panel"); @@ -49,39 +53,29 @@ void LLLayoutStack::OrientationNames::declareValues() // LLLayoutPanel::Params::Params() : expanded_min_dim("expanded_min_dim", 0), - min_dim("min_dim", 0), - max_dim("max_dim", S32_MAX), - user_resize("user_resize", true), + min_dim("min_dim", -1), + user_resize("user_resize", false), auto_resize("auto_resize", true) { addSynonym(min_dim, "min_width"); addSynonym(min_dim, "min_height"); - addSynonym(max_dim, "max_width"); - addSynonym(max_dim, "max_height"); } LLLayoutPanel::LLLayoutPanel(const Params& p) : LLPanel(p), - mExpandedMinDimSpecified(false), - mExpandedMinDim(p.min_dim), + mExpandedMinDim(p.expanded_min_dim.isProvided() ? p.expanded_min_dim : p.min_dim), mMinDim(p.min_dim), - mMaxDim(p.max_dim), mAutoResize(p.auto_resize), mUserResize(p.user_resize), mCollapsed(FALSE), mCollapseAmt(0.f), mVisibleAmt(1.f), // default to fully visible mResizeBar(NULL), - mFractionalSize(0.f), + mFractionalSize(MIN_FRACTIONAL_SIZE), + mTargetDim(0), + mIgnoreReshape(false), mOrientation(LLLayoutStack::HORIZONTAL) { - // Set the expanded min dim if it is provided, otherwise it gets the p.min_dim value - if (p.expanded_min_dim.isProvided()) - { - mExpandedMinDimSpecified = true; - mExpandedMinDim = p.expanded_min_dim(); - } - // panels initialized as hidden should not start out partially visible if (!getVisible()) { @@ -103,33 +97,83 @@ LLLayoutPanel::~LLLayoutPanel() mResizeBar = NULL; } -void LLLayoutPanel::reshape(S32 width, S32 height, BOOL called_from_parent) +F32 LLLayoutPanel::getAutoResizeFactor() const +{ + return mVisibleAmt * (1.f - mCollapseAmt); +} + +F32 LLLayoutPanel::getVisibleAmount() const +{ + return mVisibleAmt; +} + +S32 LLLayoutPanel::getLayoutDim() const +{ + return llround((F32)((mOrientation == LLLayoutStack::HORIZONTAL) + ? getRect().getWidth() + : getRect().getHeight())); +} + +S32 LLLayoutPanel::getVisibleDim() const +{ + F32 min_dim = getRelevantMinDim(); + return llround(mVisibleAmt + * (min_dim + + (((F32)mTargetDim - min_dim) * (1.f - mCollapseAmt)))); +} + +void LLLayoutPanel::setOrientation( LLLayoutStack::ELayoutOrientation orientation ) +{ + mOrientation = orientation; + S32 layout_dim = llround((F32)((mOrientation == LLLayoutStack::HORIZONTAL) + ? getRect().getWidth() + : getRect().getHeight())); + + mTargetDim = llmax(layout_dim, getMinDim()); +} + +void LLLayoutPanel::setVisible( BOOL visible ) { - if (mOrientation == LLLayoutStack::HORIZONTAL) + if (visible != getVisible()) { - mFractionalSize += width - llround(mFractionalSize); + LLLayoutStack* stackp = dynamic_cast<LLLayoutStack*>(getParent()); + if (stackp) + { + stackp->mNeedsLayout = true; + } } - else + LLPanel::setVisible(visible); +} + +void LLLayoutPanel::reshape( S32 width, S32 height, BOOL called_from_parent /*= TRUE*/ ) +{ + if (width == getRect().getWidth() && height == getRect().getHeight()) return; + + if (!mIgnoreReshape && mAutoResize == false) { - mFractionalSize += height - llround(mFractionalSize); + mTargetDim = (mOrientation == LLLayoutStack::HORIZONTAL) ? width : height; + LLLayoutStack* stackp = dynamic_cast<LLLayoutStack*>(getParent()); + if (stackp) + { + stackp->mNeedsLayout = true; + } } LLPanel::reshape(width, height, called_from_parent); } -F32 LLLayoutPanel::getCollapseFactor() +void LLLayoutPanel::handleReshape(const LLRect& new_rect, bool by_user) { - if (mOrientation == LLLayoutStack::HORIZONTAL) + LLLayoutStack* stackp = dynamic_cast<LLLayoutStack*>(getParent()); + if (stackp) { - F32 collapse_amt = - clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)getRelevantMinDim() / (F32)llmax(1, getRect().getWidth())); - return mVisibleAmt * collapse_amt; - } - else - { - F32 collapse_amt = - clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)getRelevantMinDim() / (F32)llmax(1, getRect().getHeight()))); - return mVisibleAmt * collapse_amt; + stackp->mNeedsLayout = true; + if (by_user) + { + // tell layout stack to account for new shape + stackp->updatePanelRect(this, new_rect); + } } + LLPanel::handleReshape(new_rect, by_user); } // @@ -142,20 +186,21 @@ LLLayoutStack::Params::Params() clip("clip", true), open_time_constant("open_time_constant", 0.02f), close_time_constant("close_time_constant", 0.03f), + resize_bar_overlap("resize_bar_overlap", 1), border_size("border_size", LLCachedControl<S32>(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0)) {} LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p) : LLView(p), - mMinWidth(0), - mMinHeight(0), mPanelSpacing(p.border_size), mOrientation(p.orientation), mAnimate(p.animate), mAnimatedThisFrame(false), + mNeedsLayout(true), mClip(p.clip), mOpenTimeConstant(p.open_time_constant), - mCloseTimeConstant(p.close_time_constant) + mCloseTimeConstant(p.close_time_constant), + mResizeBarOverlap(p.resize_bar_overlap) {} LLLayoutStack::~LLLayoutStack() @@ -169,26 +214,26 @@ void LLLayoutStack::draw() { updateLayout(); - e_panel_list_t::iterator panel_it; - for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) + // always clip to stack itself + LLLocalClipRect clip(getLocalRect()); + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) { // clip to layout rectangle, not bounding rectangle - LLRect clip_rect = (*panel_it)->getRect(); + LLRect clip_rect = panelp->getRect(); // scale clipping rectangle by visible amount if (mOrientation == HORIZONTAL) { - clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor()); + clip_rect.mRight = clip_rect.mLeft + panelp->getVisibleDim(); } else { - clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor()); + clip_rect.mBottom = clip_rect.mTop - panelp->getVisibleDim(); } - LLPanel* panelp = (*panel_it); - - LLLocalClipRect clip(clip_rect, mClip); - // only force drawing invisible children if visible amount is non-zero - drawChild(panelp, 0, 0, !clip_rect.isEmpty()); + {LLLocalClipRect clip(clip_rect, mClip); + // only force drawing invisible children if visible amount is non-zero + drawChild(panelp, 0, 0, !clip_rect.isEmpty()); + } } mAnimatedThisFrame = false; } @@ -201,12 +246,10 @@ void LLLayoutStack::removeChild(LLView* view) { mPanels.erase(std::find(mPanels.begin(), mPanels.end(), embedded_panelp)); delete embedded_panelp; + updateFractionalSizes(); + mNeedsLayout = true; } - // need to update resizebars - - calcMinExtents(); - LLView::removeChild(view); } @@ -221,29 +264,15 @@ bool LLLayoutStack::addChild(LLView* child, S32 tab_group) LLLayoutPanel* panelp = dynamic_cast<LLLayoutPanel*>(child); if (panelp) { - panelp->mFractionalSize = (mOrientation == HORIZONTAL) - ? panelp->getRect().getWidth() - : panelp->getRect().getHeight(); panelp->setOrientation(mOrientation); mPanels.push_back(panelp); + createResizeBar(panelp); + mNeedsLayout = true; } - return LLView::addChild(child, tab_group); -} + BOOL result = LLView::addChild(child, tab_group); -void LLLayoutStack::movePanel(LLPanel* panel_to_move, LLPanel* target_panel, bool move_to_front) -{ - LLLayoutPanel* embedded_panel_to_move = findEmbeddedPanel(panel_to_move); - LLLayoutPanel* embedded_target_panel = move_to_front ? *mPanels.begin() : findEmbeddedPanel(target_panel); - - if (!embedded_panel_to_move || !embedded_target_panel || embedded_panel_to_move == embedded_target_panel) - { - llwarns << "One of the panels was not found in stack or NULL was passed instead of valid panel" << llendl; - return; - } - e_panel_list_t::iterator it = std::find(mPanels.begin(), mPanels.end(), embedded_panel_to_move); - mPanels.erase(it); - it = move_to_front ? mPanels.begin() : std::find(mPanels.begin(), mPanels.end(), embedded_target_panel); - mPanels.insert(it, embedded_panel_to_move); + updateFractionalSizes(); + return result; } void LLLayoutStack::addPanel(LLLayoutPanel* panel, EAnimate animate) @@ -258,84 +287,274 @@ void LLLayoutStack::addPanel(LLLayoutPanel* panel, EAnimate animate) } } -void LLLayoutStack::removePanel(LLPanel* panel) -{ - removeChild(panel); -} - void LLLayoutStack::collapsePanel(LLPanel* panel, BOOL collapsed) { LLLayoutPanel* panel_container = findEmbeddedPanel(panel); if (!panel_container) return; panel_container->mCollapsed = collapsed; + mNeedsLayout = true; } -void LLLayoutStack::updatePanelAutoResize(const std::string& panel_name, BOOL auto_resize) -{ - LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name); +static LLFastTimer::DeclareTimer FTM_UPDATE_LAYOUT("Update LayoutStacks"); - if (panel) +void LLLayoutStack::updateLayout() +{ + LLFastTimer ft(FTM_UPDATE_LAYOUT); + + if (!mNeedsLayout) return; + + bool animation_in_progress = animatePanels(); + F32 total_visible_fraction = 0.f; + F32 total_open_fraction = 0.f; + S32 space_to_distribute = (mOrientation == HORIZONTAL) + ? getRect().getWidth() + : getRect().getHeight(); + + // first, assign minimum dimensions + LLLayoutPanel* panelp = NULL; + BOOST_FOREACH(panelp, mPanels) { - panel->mAutoResize = auto_resize; + if (panelp->mAutoResize) + { + panelp->mTargetDim = panelp->getRelevantMinDim(); + if (!panelp->mCollapsed && panelp->getVisible()) + { + total_open_fraction += panelp->mFractionalSize; + } + } + space_to_distribute -= panelp->getVisibleDim() + llround((F32)mPanelSpacing * panelp->getVisibleAmount()); + total_visible_fraction += panelp->mFractionalSize; } -} -void LLLayoutStack::setPanelUserResize(const std::string& panel_name, BOOL user_resize) + llassert(total_visible_fraction < 1.01f); + + // don't need spacing after last panel + space_to_distribute += panelp ? llround((F32)mPanelSpacing * panelp->getVisibleAmount()) : 0; + + F32 fraction_distributed = 0.f; + if (space_to_distribute > 0 && total_visible_fraction > 0.f) + { // give space proportionally to visible auto resize panels + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) + { + if (panelp->mAutoResize) + { + F32 fraction_to_distribute = (panelp->mFractionalSize * panelp->getAutoResizeFactor()) / (total_visible_fraction); + S32 delta = llround((F32)space_to_distribute * fraction_to_distribute); + fraction_distributed += fraction_to_distribute; + panelp->mTargetDim += delta; + } + } + } + + if (fraction_distributed < total_visible_fraction) + { // distribute any left over pixels to non-collapsed, visible panels + F32 fraction_left = total_visible_fraction - fraction_distributed; + S32 space_left = llround((F32)space_to_distribute * (fraction_left / total_visible_fraction)); + + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) + { + if (panelp->mAutoResize + && !panelp->mCollapsed + && panelp->getVisible()) + { + S32 space_for_panel = llmax(0, llround((F32)space_left * (panelp->mFractionalSize / total_open_fraction))); + panelp->mTargetDim += space_for_panel; + space_left -= space_for_panel; + total_open_fraction -= panelp->mFractionalSize; + } + } + } + + F32 cur_pos = (mOrientation == HORIZONTAL) ? 0.f : (F32)getRect().getHeight(); + + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) + { + F32 panel_dim = llmax(panelp->getExpandedMinDim(), panelp->mTargetDim); + F32 panel_visible_dim = panelp->getVisibleDim(); + + LLRect panel_rect; + if (mOrientation == HORIZONTAL) + { + panel_rect.setLeftTopAndSize(llround(cur_pos), + getRect().getHeight(), + llround(panel_dim), + getRect().getHeight()); + } + else + { + panel_rect.setLeftTopAndSize(0, + llround(cur_pos), + getRect().getWidth(), + llround(panel_dim)); + } + panelp->setIgnoreReshape(true); + panelp->setShape(panel_rect); + panelp->setIgnoreReshape(false); + + LLRect resize_bar_rect(panel_rect); + + F32 panel_spacing = (F32)mPanelSpacing * panelp->getVisibleAmount(); + if (mOrientation == HORIZONTAL) + { + resize_bar_rect.mLeft = panel_rect.mRight - mResizeBarOverlap; + resize_bar_rect.mRight = panel_rect.mRight + (S32)(llround(panel_spacing)) + mResizeBarOverlap; + + cur_pos += panel_visible_dim + panel_spacing; + } + else //VERTICAL + { + resize_bar_rect.mTop = panel_rect.mBottom + mResizeBarOverlap; + resize_bar_rect.mBottom = panel_rect.mBottom - (S32)(llround(panel_spacing)) - mResizeBarOverlap; + + cur_pos -= panel_visible_dim + panel_spacing; + } + panelp->mResizeBar->setShape(resize_bar_rect); + } + + updateResizeBarLimits(); + + // clear animation flag at end, since panel resizes will set it + // and leave it set if there is any animation in progress + mNeedsLayout = animation_in_progress; +} // end LLLayoutStack::updateLayout + +LLLayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const { - LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name); + if (!panelp) return NULL; - if (panel) + e_panel_list_t::const_iterator panel_it; + BOOST_FOREACH(LLLayoutPanel* p, mPanels) { - panel->mUserResize = user_resize; + if (p == panelp) + { + return p; + } } + return NULL; } -bool LLLayoutStack::getPanelMinSize(const std::string& panel_name, S32* min_dimp) +LLLayoutPanel* LLLayoutStack::findEmbeddedPanelByName(const std::string& name) const { - LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name); + LLLayoutPanel* result = NULL; - if (panel && min_dimp) + BOOST_FOREACH(LLLayoutPanel* p, mPanels) { - *min_dimp = panel->getRelevantMinDim(); + if (p->getName() == name) + { + result = p; + break; + } } - return NULL != panel; + return result; } -bool LLLayoutStack::getPanelMaxSize(const std::string& panel_name, S32* max_dimp) +void LLLayoutStack::createResizeBar(LLLayoutPanel* panelp) { - LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name); + BOOST_FOREACH(LLLayoutPanel* lp, mPanels) + { + if (lp->mResizeBar == NULL) + { + LLResizeBar::Side side = (mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM; + LLRect resize_bar_rect = getRect(); - if (panel) + LLResizeBar::Params resize_params; + resize_params.name("resize"); + resize_params.resizing_view(lp); + resize_params.min_size(lp->getRelevantMinDim()); + resize_params.side(side); + resize_params.snapping_enabled(false); + LLResizeBar* resize_bar = LLUICtrlFactory::create<LLResizeBar>(resize_params); + lp->mResizeBar = resize_bar; + LLView::addChild(resize_bar, 0); + } + } + // bring all resize bars to the front so that they are clickable even over the panels + // with a bit of overlap + for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { - if (max_dimp) *max_dimp = panel->mMaxDim; + LLResizeBar* resize_barp = (*panel_it)->mResizeBar; + sendChildToFront(resize_barp); } +} - return NULL != panel; +// update layout stack animations, etc. once per frame +// NOTE: we use this to size world view based on animating UI, *before* we draw the UI +// we might still need to call updateLayout during UI draw phase, in case UI elements +// are resizing themselves dynamically +//static +void LLLayoutStack::updateClass() +{ + for (instance_iter it = beginInstances(); it != endInstances(); ++it) + { + it->updateLayout(); + } } -static LLFastTimer::DeclareTimer FTM_UPDATE_LAYOUT("Update LayoutStacks"); -void LLLayoutStack::updateLayout(BOOL force_resize) +void LLLayoutStack::updateFractionalSizes() { - LLFastTimer ft(FTM_UPDATE_LAYOUT); - static LLUICachedControl<S32> resize_bar_overlap ("UIResizeBarOverlap", 0); - calcMinExtents(); - createResizeBars(); + F32 total_resizable_dim = 0; + S32 num_auto_resize_panels = 0; - // calculate current extents - F32 total_size = 0.f; + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) + { + if (panelp->mAutoResize) + { + total_resizable_dim += llmax(0, panelp->getLayoutDim() - panelp->getRelevantMinDim()); + num_auto_resize_panels++; + } + } + F32 total_fractional_size = 0.f; + + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) + { + if (panelp->mAutoResize) + { + F32 panel_resizable_dim = llmax(MIN_FRACTIONAL_SIZE, (F32)(panelp->getLayoutDim() - panelp->getRelevantMinDim())); + panelp->mFractionalSize = panel_resizable_dim > 0.f + ? llclamp(panel_resizable_dim / total_resizable_dim, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE) + : MIN_FRACTIONAL_SIZE; + total_fractional_size += panelp->mFractionalSize; + llassert(!llisnan(panelp->mFractionalSize)); + } + } + + if (total_fractional_size == 0.f) + { // equal distribution + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) + { + if (panelp->mAutoResize) + { + panelp->mFractionalSize = MAX_FRACTIONAL_SIZE / (F32)num_auto_resize_panels; + } + } + } + else + { // renormalize + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) + { + if (panelp->mAutoResize) + { + panelp->mFractionalSize /= total_fractional_size; + } + } + } +} + +bool LLLayoutStack::animatePanels() +{ + bool animation_in_progress = false; + // // animate visibility // - e_panel_list_t::iterator panel_it; - for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) { - LLLayoutPanel* panelp = (*panel_it); - if (panelp->getVisible()) + if (panelp->getVisible()) { - if (mAnimate) + if (mAnimate && panelp->mVisibleAmt < 1.f) { if (!mAnimatedThisFrame) { @@ -345,15 +564,21 @@ void LLLayoutStack::updateLayout(BOOL force_resize) panelp->mVisibleAmt = 1.f; } } + + animation_in_progress = true; } else { - panelp->mVisibleAmt = 1.f; + if (panelp->mVisibleAmt != 1.f) + { + panelp->mVisibleAmt = 1.f; + animation_in_progress = true; + } } } else // not visible { - if (mAnimate) + if (mAnimate && panelp->mVisibleAmt > 0.f) { if (!mAnimatedThisFrame) { @@ -363,297 +588,213 @@ void LLLayoutStack::updateLayout(BOOL force_resize) panelp->mVisibleAmt = 0.f; } } + + animation_in_progress = true; } else { - panelp->mVisibleAmt = 0.f; + if (panelp->mVisibleAmt != 0.f) + { + panelp->mVisibleAmt = 0.f; + animation_in_progress = true; + } } } F32 collapse_state = panelp->mCollapsed ? 1.f : 0.f; - panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); - - total_size += panelp->mFractionalSize * panelp->getCollapseFactor(); - // want n-1 panel gaps for n panels - if (panel_it != mPanels.begin()) - { - total_size += mPanelSpacing; - } - } - - S32 num_resizable_panels = 0; - F32 shrink_headroom_available = 0.f; - F32 shrink_headroom_total = 0.f; - for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) - { - LLLayoutPanel* panelp = (*panel_it); - - // panels that are not fully visible do not count towards shrink headroom - if (panelp->getCollapseFactor() < 1.f) - { - continue; - } - - F32 cur_size = panelp->mFractionalSize; - F32 min_size = (F32)panelp->getRelevantMinDim(); - - // if currently resizing a panel or the panel is flagged as not automatically resizing - // only track total available headroom, but don't use it for automatic resize logic - if (panelp->mResizeBar->hasMouseCapture() - || (!panelp->mAutoResize - && !force_resize)) - { - shrink_headroom_total += cur_size - min_size; - } - else - { - num_resizable_panels++; - - shrink_headroom_available += cur_size - min_size; - shrink_headroom_total += cur_size - min_size; - } - } - - // calculate how many pixels need to be distributed among layout panels - // positive means panels need to grow, negative means shrink - F32 pixels_to_distribute = (mOrientation == HORIZONTAL) - ? getRect().getWidth() - total_size - : getRect().getHeight() - total_size; - - // now we distribute the pixels... - F32 cur_x = 0.f; - F32 cur_y = (F32)getRect().getHeight(); - - for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) - { - LLLayoutPanel* panelp = (*panel_it); - - F32 min_size = panelp->getRelevantMinDim(); - F32 delta_size = 0.f; - - // if panel can automatically resize (not animating, and resize flag set)... - if (panelp->getCollapseFactor() == 1.f - && (force_resize || panelp->mAutoResize) - && !panelp->mResizeBar->hasMouseCapture()) + if (panelp->mCollapseAmt != collapse_state) { - if (pixels_to_distribute < 0.f) + if (!mAnimatedThisFrame) { - // shrink proportionally to amount over minimum - // so we can do this in one pass - delta_size = (shrink_headroom_available > 0.f) - ? pixels_to_distribute * ((F32)(panelp->mFractionalSize - min_size) / shrink_headroom_available) - : 0.f; - shrink_headroom_available -= (panelp->mFractionalSize - min_size); + panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); } - else + animation_in_progress = true; + + if (llabs(panelp->mCollapseAmt - collapse_state) < 0.001f) { - // grow all elements equally - delta_size = pixels_to_distribute / (F32)num_resizable_panels; - num_resizable_panels--; + panelp->mCollapseAmt = collapse_state; } - - panelp->mFractionalSize = llmax(min_size, panelp->mFractionalSize + delta_size); - pixels_to_distribute -= delta_size; } + } - // adjust running headroom count based on new sizes - shrink_headroom_total += delta_size; + mAnimatedThisFrame = true; - LLRect panel_rect; - if (mOrientation == HORIZONTAL) - { - panel_rect.setLeftTopAndSize(llround(cur_x), - llround(cur_y), - llround(panelp->mFractionalSize), - getRect().getHeight()); - } - else - { - panel_rect.setLeftTopAndSize(llround(cur_x), - llround(cur_y), - getRect().getWidth(), - llround(panelp->mFractionalSize)); - } - panelp->setShape(panel_rect); + return animation_in_progress; +} - LLRect resize_bar_rect = panel_rect; - if (mOrientation == HORIZONTAL) - { - resize_bar_rect.mLeft = panel_rect.mRight - resize_bar_overlap; - resize_bar_rect.mRight = panel_rect.mRight + mPanelSpacing + resize_bar_overlap; - } - else - { - resize_bar_rect.mTop = panel_rect.mBottom + resize_bar_overlap; - resize_bar_rect.mBottom = panel_rect.mBottom - mPanelSpacing - resize_bar_overlap; - } - (*panel_it)->mResizeBar->setRect(resize_bar_rect); +void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& new_rect ) +{ + S32 new_dim = (mOrientation == HORIZONTAL) + ? new_rect.getWidth() + : new_rect.getHeight(); + S32 delta_dim = new_dim - resized_panel->getVisibleDim(); + if (delta_dim == 0) return; - F32 size = ((*panel_it)->mFractionalSize * (*panel_it)->getCollapseFactor()) + (F32)mPanelSpacing; - if (mOrientation == HORIZONTAL) - { - cur_x += size; - } - else //VERTICAL - { - cur_y -= size; - } - } + F32 total_visible_fraction = 0.f; + F32 delta_auto_resize_headroom = 0.f; + F32 total_auto_resize_headroom = 0.f; - // update resize bars with new limits - LLLayoutPanel* last_resizeable_panel = NULL; - for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) - { - LLLayoutPanel* panelp = (*panel_it); - S32 relevant_min = panelp->getRelevantMinDim(); + LLLayoutPanel* other_resize_panel = NULL; + LLLayoutPanel* following_panel = NULL; - if (mOrientation == HORIZONTAL) + BOOST_REVERSE_FOREACH(LLLayoutPanel* panelp, mPanels) + { + if (panelp->mAutoResize) { - (*panel_it)->mResizeBar->setResizeLimits( - relevant_min, - relevant_min + llround(shrink_headroom_total)); + total_auto_resize_headroom += (F32)(panelp->mTargetDim - panelp->getRelevantMinDim()); + total_visible_fraction += panelp->mFractionalSize * panelp->getAutoResizeFactor(); } - else //VERTICAL + + if (panelp == resized_panel) { - (*panel_it)->mResizeBar->setResizeLimits( - relevant_min, - relevant_min + llround(shrink_headroom_total)); + other_resize_panel = following_panel; } - // toggle resize bars based on panel visibility, resizability, etc - BOOL resize_bar_enabled = panelp->getVisible() && (*panel_it)->mUserResize; - (*panel_it)->mResizeBar->setVisible(resize_bar_enabled); - - if ((*panel_it)->mUserResize || (*panel_it)->mAutoResize) + if (panelp->getVisible() && !panelp->mCollapsed) { - last_resizeable_panel = (*panel_it); + following_panel = panelp; } } - // hide last resize bar as there is nothing past it - // resize bars need to be in between two resizable panels - if (last_resizeable_panel) + if (resized_panel->mAutoResize == FALSE) { - last_resizeable_panel->mResizeBar->setVisible(FALSE); + delta_auto_resize_headroom += -delta_dim; } - - // not enough room to fit existing contents - if (force_resize == FALSE - // layout did not complete by reaching target position - && ((mOrientation == VERTICAL && llround(cur_y) != -mPanelSpacing) - || (mOrientation == HORIZONTAL && llround(cur_x) != getRect().getWidth() + mPanelSpacing))) + if (other_resize_panel && other_resize_panel->mAutoResize == FALSE) { - // do another layout pass with all stacked elements contributing - // even those that don't usually resize - llassert_always(force_resize == FALSE); - updateLayout(TRUE); + delta_auto_resize_headroom += delta_dim; } - mAnimatedThisFrame = true; -} // end LLLayoutStack::updateLayout + F32 fraction_given_up = 0.f; + F32 fraction_remaining = 1.f; + F32 updated_auto_resize_headroom = total_auto_resize_headroom + delta_auto_resize_headroom; - -LLLayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const -{ - if (!panelp) return NULL; - - e_panel_list_t::const_iterator panel_it; - for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) + enum { - if ((*panel_it) == panelp) - { - return *panel_it; - } - } - return NULL; -} + BEFORE_RESIZED_PANEL, + RESIZED_PANEL, + NEXT_PANEL, + AFTER_RESIZED_PANEL + } which_panel = BEFORE_RESIZED_PANEL; -LLLayoutPanel* LLLayoutStack::findEmbeddedPanelByName(const std::string& name) const -{ - LLLayoutPanel* result = NULL; - - for (e_panel_list_t::const_iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) + BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) { - LLLayoutPanel* p = *panel_it; + if (!panelp->getVisible() || panelp->mCollapsed) continue; - if (p->getName() == name) + if (panelp == resized_panel) { - result = p; - break; + which_panel = RESIZED_PANEL; } - } - - return result; -} - -// Compute sum of min_width or min_height of children -void LLLayoutStack::calcMinExtents() -{ - mMinWidth = 0; - mMinHeight = 0; - e_panel_list_t::iterator panel_it; - for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) - { - if (mOrientation == HORIZONTAL) + switch(which_panel) { - mMinWidth += (*panel_it)->getRelevantMinDim(); - if (panel_it != mPanels.begin()) + case BEFORE_RESIZED_PANEL: + if (panelp->mAutoResize) + { // freeze current size as fraction of overall auto_resize space + F32 fractional_adjustment_factor = total_auto_resize_headroom / updated_auto_resize_headroom; + F32 new_fractional_size = llclamp(panelp->mFractionalSize * fractional_adjustment_factor, + MIN_FRACTIONAL_SIZE, + MAX_FRACTIONAL_SIZE); + F32 fraction_delta = (new_fractional_size - panelp->mFractionalSize); + fraction_given_up -= fraction_delta; + fraction_remaining -= panelp->mFractionalSize; + panelp->mFractionalSize += fraction_delta; + llassert(!llisnan(panelp->mFractionalSize)); + } + else { - mMinWidth += mPanelSpacing; + // leave non auto-resize panels alone } - } - else //VERTICAL - { - mMinHeight += (*panel_it)->getRelevantMinDim(); - if (panel_it != mPanels.begin()) + break; + case RESIZED_PANEL: + if (panelp->mAutoResize) + { // freeze new size as fraction + F32 new_fractional_size = (updated_auto_resize_headroom == 0.f) + ? MAX_FRACTIONAL_SIZE + : llclamp((F32)(new_dim - panelp->getRelevantMinDim()) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE); + fraction_given_up -= new_fractional_size - panelp->mFractionalSize; + fraction_remaining -= panelp->mFractionalSize; + panelp->mFractionalSize = new_fractional_size; + llassert(!llisnan(panelp->mFractionalSize)); + } + else + { // freeze new size as original size + panelp->mTargetDim = new_dim; + fraction_remaining -= fraction_given_up; + } + which_panel = NEXT_PANEL; + break; + case NEXT_PANEL: + if (panelp->mAutoResize) + { + fraction_remaining -= panelp->mFractionalSize; + if (fraction_given_up != 0.f) + { + panelp->mFractionalSize = llclamp(panelp->mFractionalSize + fraction_given_up, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE); + fraction_given_up = 0.f; + } + else + { + F32 new_fractional_size = llclamp((F32)(panelp->mTargetDim - panelp->getRelevantMinDim() + delta_auto_resize_headroom) + / updated_auto_resize_headroom, + MIN_FRACTIONAL_SIZE, + MAX_FRACTIONAL_SIZE); + fraction_given_up -= new_fractional_size - panelp->mFractionalSize; + panelp->mFractionalSize = new_fractional_size; + } + } + else + { + panelp->mTargetDim -= delta_dim; + } + which_panel = AFTER_RESIZED_PANEL; + break; + case AFTER_RESIZED_PANEL: + if (panelp->mAutoResize) { - mMinHeight += mPanelSpacing; + panelp->mFractionalSize = llclamp(panelp->mFractionalSize + (panelp->mFractionalSize / fraction_remaining) * fraction_given_up, + MIN_FRACTIONAL_SIZE, + MAX_FRACTIONAL_SIZE); } + default: + break; } } } -void LLLayoutStack::createResizeBars() +void LLLayoutStack::reshape(S32 width, S32 height, BOOL called_from_parent) { - for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) + mNeedsLayout = true; + LLView::reshape(width, height, called_from_parent); +} + +void LLLayoutStack::updateResizeBarLimits() +{ + LLLayoutPanel* previous_visible_panelp = NULL; + BOOST_REVERSE_FOREACH(LLLayoutPanel* visible_panelp, mPanels) { - LLLayoutPanel* lp = (*panel_it); - if (lp->mResizeBar == NULL) + if (!visible_panelp->getVisible() || visible_panelp->mCollapsed) { - LLResizeBar::Side side = (mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM; - LLRect resize_bar_rect = getRect(); - - LLResizeBar::Params resize_params; - resize_params.name("resize"); - resize_params.resizing_view(lp); - resize_params.min_size(lp->getRelevantMinDim()); - resize_params.side(side); - resize_params.snapping_enabled(false); - LLResizeBar* resize_bar = LLUICtrlFactory::create<LLResizeBar>(resize_params); - lp->mResizeBar = resize_bar; - LLView::addChild(resize_bar, 0); + visible_panelp->mResizeBar->setVisible(FALSE); + continue; + } - // bring all resize bars to the front so that they are clickable even over the panels - // with a bit of overlap - for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) - { - LLResizeBar* resize_barp = (*panel_it)->mResizeBar; - sendChildToFront(resize_barp); - } + // toggle resize bars based on panel visibility, resizability, etc + if (previous_visible_panelp + && (visible_panelp->mUserResize || previous_visible_panelp->mUserResize) // one of the pair is user resizable + && (visible_panelp->mAutoResize || visible_panelp->mUserResize) // current panel is resizable + && (previous_visible_panelp->mAutoResize || previous_visible_panelp->mUserResize)) // previous panel is resizable + { + visible_panelp->mResizeBar->setVisible(TRUE); + S32 previous_panel_headroom = previous_visible_panelp->getVisibleDim() - previous_visible_panelp->getRelevantMinDim(); + visible_panelp->mResizeBar->setResizeLimits(visible_panelp->getRelevantMinDim(), + visible_panelp->getVisibleDim() + previous_panel_headroom); + } + else + { + visible_panelp->mResizeBar->setVisible(FALSE); } - } -} -// update layout stack animations, etc. once per frame -// NOTE: we use this to size world view based on animating UI, *before* we draw the UI -// we might still need to call updateLayout during UI draw phase, in case UI elements -// are resizing themselves dynamically -//static -void LLLayoutStack::updateClass() -{ - for (instance_iter it = beginInstances(); it != endInstances(); ++it) - { - it->updateLayout(); + previous_visible_panelp = visible_panelp; } } diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index 3b308a359d..efe93f6def 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2010, Linden Reshasearch, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -60,6 +60,7 @@ public: clip; Optional<F32> open_time_constant, close_time_constant; + Optional<S32> resize_bar_overlap; Params(); }; @@ -72,12 +73,11 @@ public: /*virtual*/ void removeChild(LLView*); /*virtual*/ BOOL postBuild(); /*virtual*/ bool addChild(LLView* child, S32 tab_group = 0); + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL); - S32 getMinWidth() const { return mMinWidth; } - S32 getMinHeight() const { return mMinHeight; } - typedef enum e_animate { NO_ANIMATE, @@ -85,47 +85,24 @@ public: } EAnimate; void addPanel(LLLayoutPanel* panel, EAnimate animate = NO_ANIMATE); - void removePanel(LLPanel* panel); void collapsePanel(LLPanel* panel, BOOL collapsed = TRUE); S32 getNumPanels() { return mPanels.size(); } - /** - * Moves panel_to_move before target_panel inside layout stack (both panels should already be there). - * If move_to_front is true target_panel is ignored and panel_to_move is moved to the beginning of mPanels - */ - void movePanel(LLPanel* panel_to_move, LLPanel* target_panel, bool move_to_front = false); - - void updatePanelAutoResize(const std::string& panel_name, BOOL auto_resize); - void setPanelUserResize(const std::string& panel_name, BOOL user_resize); - - /** - * Gets minimal dimension along layout_stack axis of the specified by name panel. - * - * @returns true if specified by panel_name internal panel exists, false otherwise. - */ - bool getPanelMinSize(const std::string& panel_name, S32* min_dimp); - - /** - * Gets maximal dimension along layout_stack axis of the specified by name panel. - * - * @returns true if specified by panel_name internal panel exists, false otherwise. - */ - bool getPanelMaxSize(const std::string& panel_name, S32* max_dim); - - void updateLayout(BOOL force_resize = FALSE); - + + void updateLayout(); + S32 getPanelSpacing() const { return mPanelSpacing; } - BOOL getAnimate () const { return mAnimate; } - void setAnimate (BOOL animate) { mAnimate = animate; } static void updateClass(); protected: LLLayoutStack(const Params&); friend class LLUICtrlFactory; + friend class LLLayoutPanel; private: - void createResizeBars(); - void calcMinExtents(); + void updateResizeBarLimits(); + bool animatePanels(); + void createResizeBar(LLLayoutPanel* panel); const ELayoutOrientation mOrientation; @@ -134,17 +111,19 @@ private: LLLayoutPanel* findEmbeddedPanel(LLPanel* panelp) const; LLLayoutPanel* findEmbeddedPanelByName(const std::string& name) const; + void updateFractionalSizes(); + void updatePanelRect( LLLayoutPanel* param1, const LLRect& new_rect ); - S32 mMinWidth; // calculated by calcMinExtents - S32 mMinHeight; // calculated by calcMinExtents S32 mPanelSpacing; // true if we already applied animation this frame bool mAnimatedThisFrame; bool mAnimate; bool mClip; - F32 mOpenTimeConstant; - F32 mCloseTimeConstant; + F32 mOpenTimeConstant; + F32 mCloseTimeConstant; + bool mNeedsLayout; + S32 mResizeBarOverlap; }; // end class LLLayoutStack @@ -156,8 +135,7 @@ public: struct Params : public LLInitParam::Block<Params, LLPanel::Params> { Optional<S32> expanded_min_dim, - min_dim, - max_dim; + min_dim; Optional<bool> user_resize, auto_resize; @@ -168,16 +146,19 @@ public: void initFromParams(const Params& p); + void handleReshape(const LLRect& new_rect, bool by_user); + void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + - S32 getMinDim() const { return mMinDim; } - void setMinDim(S32 value) { mMinDim = value; if (!mExpandedMinDimSpecified) mExpandedMinDim = value; } + void setVisible(BOOL visible); - S32 getMaxDim() const { return mMaxDim; } - void setMaxDim(S32 value) { mMaxDim = value; } + S32 getLayoutDim() const; + S32 getMinDim() const { return (mMinDim >= 0 || mAutoResize) ? llmax(0, mMinDim) : getLayoutDim(); } + void setMinDim(S32 value) { mMinDim = value; } - S32 getExpandedMinDim() const { return mExpandedMinDim; } - void setExpandedMinDim(S32 value) { mExpandedMinDim = value; mExpandedMinDimSpecified = true; } + S32 getExpandedMinDim() const { return mExpandedMinDim >= 0 ? mExpandedMinDim : mMinDim; } + void setExpandedMinDim(S32 value) { mExpandedMinDim = value; } S32 getRelevantMinDim() const { @@ -185,29 +166,35 @@ public: if (!mCollapsed) { - min_dim = mExpandedMinDim; + min_dim = getExpandedMinDim(); } return min_dim; } - F32 getCollapseFactor(); - void setOrientation(LLLayoutStack::ELayoutOrientation orientation) { mOrientation = orientation; } + F32 getAutoResizeFactor() const; + F32 getVisibleAmount() const; + S32 getVisibleDim() const; + + void setOrientation(LLLayoutStack::ELayoutOrientation orientation); + void storeOriginalDim(); + + void setIgnoreReshape(bool ignore) { mIgnoreReshape = ignore; } protected: LLLayoutPanel(const Params& p); - bool mExpandedMinDimSpecified; + const bool mAutoResize; + const bool mUserResize; + S32 mExpandedMinDim; - S32 mMinDim; - S32 mMaxDim; - bool mAutoResize; - bool mUserResize; bool mCollapsed; F32 mVisibleAmt; F32 mCollapseAmt; F32 mFractionalSize; + S32 mTargetDim; + bool mIgnoreReshape; LLLayoutStack::ELayoutOrientation mOrientation; class LLResizeBar* mResizeBar; }; diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp index 02f60c76fa..87aeb4d7a7 100644 --- a/indra/llui/llresizebar.cpp +++ b/indra/llui/llresizebar.cpp @@ -79,6 +79,8 @@ LLResizeBar::LLResizeBar(const LLResizeBar::Params& p) BOOL LLResizeBar::handleMouseDown(S32 x, S32 y, MASK mask) { + if (!canResize()) return FALSE; + // Route future Mouse messages here preemptively. (Release on mouse up.) // No handler needed for focus lost since this clas has no state that depends on it. gFocusMgr.setMouseCapture( this ); @@ -243,7 +245,7 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask) handled = TRUE; } - if( handled ) + if( handled && canResize() ) { switch( mSide ) { diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h index 0725fbd846..6daf191918 100644 --- a/indra/llui/llresizebar.h +++ b/indra/llui/llresizebar.h @@ -70,6 +70,7 @@ public: void setResizeLimits( S32 min_size, S32 max_size ) { mMinSize = min_size; mMaxSize = max_size; } void setEnableSnapping(BOOL enable) { mSnappingEnabled = enable; } void setAllowDoubleClickSnapping(BOOL allow) { mAllowDoubleClickSnapping = allow; } + bool canResize() { return getEnabled() && mMaxSize > mMinSize; } private: S32 mDragLastScreenX; diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index fe3f688fc5..ad4cc20d9a 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -424,63 +424,66 @@ void LLScrollContainer::draw() focusFirstItem(); } - // Draw background - if( mIsOpaque ) + if (getRect().isValid()) { - F32 alpha = getCurrentTransparency(); + // Draw background + if( mIsOpaque ) + { + F32 alpha = getCurrentTransparency(); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gl_rect_2d(mInnerRect, mBackgroundColor.get() % alpha); - } + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gl_rect_2d(mInnerRect, mBackgroundColor.get() % alpha); + } - // Draw mScrolledViews and update scroll bars. - // get a scissor region ready, and draw the scrolling view. The - // scissor region ensures that we don't draw outside of the bounds - // of the rectangle. - if( mScrolledView ) - { - updateScroll(); - - // Draw the scrolled area. + // Draw mScrolledViews and update scroll bars. + // get a scissor region ready, and draw the scrolling view. The + // scissor region ensures that we don't draw outside of the bounds + // of the rectangle. + if( mScrolledView ) { - S32 visible_width = 0; - S32 visible_height = 0; - BOOL show_v_scrollbar = FALSE; - BOOL show_h_scrollbar = FALSE; - calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); - - LLLocalClipRect clip(LLRect(mInnerRect.mLeft, - mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) + visible_height, - mInnerRect.mRight - (show_v_scrollbar ? scrollbar_size: 0), - mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) - )); - drawChild(mScrolledView); - } - } - - // Highlight border if a child of this container has keyboard focus - if( mBorder->getVisible() ) - { - mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) ); - } + updateScroll(); - // Draw all children except mScrolledView - // Note: scrollbars have been adjusted by above drawing code - for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin(); - child_iter != getChildList()->rend(); ++child_iter) - { - LLView *viewp = *child_iter; - if( sDebugRects ) - { - sDepth++; + // Draw the scrolled area. + { + S32 visible_width = 0; + S32 visible_height = 0; + BOOL show_v_scrollbar = FALSE; + BOOL show_h_scrollbar = FALSE; + calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); + + LLLocalClipRect clip(LLRect(mInnerRect.mLeft, + mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) + visible_height, + mInnerRect.mRight - (show_v_scrollbar ? scrollbar_size: 0), + mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) + )); + drawChild(mScrolledView); + } } - if( (viewp != mScrolledView) && viewp->getVisible() ) + + // Highlight border if a child of this container has keyboard focus + if( mBorder->getVisible() ) { - drawChild(viewp); + mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) ); } - if( sDebugRects ) + + // Draw all children except mScrolledView + // Note: scrollbars have been adjusted by above drawing code + for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin(); + child_iter != getChildList()->rend(); ++child_iter) { - sDepth--; + LLView *viewp = *child_iter; + if( sDebugRects ) + { + sDepth++; + } + if( (viewp != mScrolledView) && viewp->getVisible() ) + { + drawChild(viewp); + } + if( sDebugRects ) + { + sDepth--; + } } } } // end draw diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 004681325f..e1ee0a5b14 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1093,6 +1093,11 @@ void LLView::drawChildren() { child_list_reverse_iter_t child = child_iter++; LLView *viewp = *child; + + if (viewp == NULL) + { + continue; + } if (viewp->getVisible() && viewp->getRect().isValid()) { diff --git a/indra/llui/llwindowshade.cpp b/indra/llui/llwindowshade.cpp index ae8b30b1ba..f5c463c961 100644 --- a/indra/llui/llwindowshade.cpp +++ b/indra/llui/llwindowshade.cpp @@ -160,7 +160,7 @@ void LLWindowShade::draw() notification_area->reshape(notification_area->getRect().getWidth(), llclamp(message_rect.getHeight() + 15, - llmin(mFormHeight, MAX_NOTIFICATION_AREA_HEIGHT), + llmax(mFormHeight, MIN_NOTIFICATION_AREA_HEIGHT), MAX_NOTIFICATION_AREA_HEIGHT)); LLUICtrl::draw(); @@ -176,12 +176,12 @@ void LLWindowShade::draw() { hide(); } - else if (notification_area->getCollapseFactor() < 0.01f) + else if (notification_area->getVisibleAmount() < 0.01f) { displayLatestNotification(); } - if (!notification_area->getVisible() && (notification_area->getCollapseFactor() < 0.001f)) + if (!notification_area->getVisible() && (notification_area->getVisibleAmount() < 0.001f)) { getChildRef<LLLayoutPanel>("background_area").setBackgroundVisible(false); setMouseOpaque(false); @@ -371,6 +371,11 @@ void LLWindowShade::setTextColor(LLColor4 color) getChild<LLTextBox>("notification_text")->setColor(color); } +bool LLWindowShade::isShown() const +{ + return getChildRef<LLLayoutPanel>("notification_area").getVisible(); +} + void LLWindowShade::setCanClose(bool can_close) { getChildView("close_panel")->setVisible(can_close); diff --git a/indra/llui/llwindowshade.h b/indra/llui/llwindowshade.h index 1ae84028dd..6d753d1161 100644 --- a/indra/llui/llwindowshade.h +++ b/indra/llui/llwindowshade.h @@ -48,6 +48,9 @@ public: void show(LLNotificationPtr); /*virtual*/ void draw(); void hide(); + + bool isShown() const; + void setBackgroundImage(LLUIImage* image); void setTextColor(LLColor4 color); void setCanClose(bool can_close); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 954b9f2b15..228fbefd19 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1747,7 +1747,7 @@ void LLWindowWin32::gatherInput() LLMemType m1(LLMemType::MTYPE_GATHER_INPUT); - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) && msg_count < MAX_MESSAGE_PER_UPDATE) + while ((msg_count < MAX_MESSAGE_PER_UPDATE) && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { mCallbacks->handlePingWatchdog(this, "Main:TranslateGatherInput"); TranslateMessage(&msg); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index bff87cea95..81ab4116b0 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -218,6 +218,7 @@ set(viewer_SOURCE_FILES llfloaternotificationsconsole.cpp llfloaterobjectweights.cpp llfloateropenobject.cpp + llfloateroutbox.cpp llfloaterpathfindingconsole.cpp llfloaterpathfindinglinksets.cpp llfloaterpay.cpp @@ -318,6 +319,8 @@ set(viewer_SOURCE_FILES llmaniprotate.cpp llmanipscale.cpp llmaniptranslate.cpp + llmarketplacefunctions.cpp + llmarketplacenotifications.cpp llmediactrl.cpp llmediadataclient.cpp llmemoryview.cpp @@ -375,7 +378,6 @@ set(viewer_SOURCE_FILES llpanelmaininventory.cpp llpanelmarketplaceinbox.cpp llpanelmarketplaceinboxinventory.cpp - llpanelmarketplaceoutbox.cpp llpanelmarketplaceoutboxinventory.cpp llpanelmediasettingsgeneral.cpp llpanelmediasettingspermissions.cpp @@ -775,6 +777,7 @@ set(viewer_HEADER_FILES llfloaternotificationsconsole.h llfloaterobjectweights.h llfloateropenobject.h + llfloateroutbox.h llfloaterpathfindingconsole.h llfloaterpathfindinglinksets.h llfloaterpay.h @@ -875,6 +878,8 @@ set(viewer_HEADER_FILES llmaniprotate.h llmanipscale.h llmaniptranslate.h + llmarketplacefunctions.h + llmarketplacenotifications.h llmediactrl.h llmediadataclient.h llmemoryview.h @@ -926,7 +931,6 @@ set(viewer_HEADER_FILES llpanelmaininventory.h llpanelmarketplaceinbox.h llpanelmarketplaceinboxinventory.h - llpanelmarketplaceoutbox.h llpanelmarketplaceoutboxinventory.h llpanelmediasettingsgeneral.h llpanelmediasettingspermissions.h @@ -1518,8 +1522,8 @@ if (WINDOWS) # *TODO -reenable this once we get server usage sorted out #LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:\"__tcmalloc\"" LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:__tcmalloc " - LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO" - LINK_FLAGS_RELEASE "/FORCE:MULTIPLE" + LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO" + LINK_FLAGS_RELEASE "/FORCE:MULTIPLE" ) if(USE_PRECOMPILED_HEADERS) set_target_properties( diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index b373ec0807..22dc336399 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -135,6 +135,16 @@ is_running_function="Floater.IsOpen" is_running_parameters="moveview" /> + <command name="outbox" + available_in_toybox="false" + icon="Command_Outbox_Icon" + label_ref="Command_Outbox_Label" + tooltip_ref="Command_Outbox_Tooltip" + execute_function="Floater.ToggleOrBringToFront" + execute_parameters="outbox" + is_running_function="Floater.IsOpen" + is_running_parameters="outbox" + /> <command name="people" available_in_toybox="true" icon="Command_People_Icon" diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 1ea623791d..28ba9fd704 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4271,16 +4271,49 @@ <key>Value</key> <integer>0</integer> </map> - <key>InventoryMarketplaceUserStatus</key> + <key>InventoryOutboxLogging</key> + <map> + <key>Comment</key> + <string>Enable debug output associated with the Merchant Outbox.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>InventoryOutboxMaxFolderCount</key> <map> <key>Comment</key> - <string>Marketplace user status.</string> + <string>Maximum number of subfolders allowed in a listing in the merchant outbox.</string> <key>Persist</key> - <integer>1</integer> + <integer>0</integer> <key>Type</key> - <string>String</string> + <string>U32</string> <key>Value</key> - <string /> + <integer>21</integer> + </map> + <key>InventoryOutboxMaxFolderDepth</key> + <map> + <key>Comment</key> + <string>Maximum number of nested levels of subfolders allowed in a listing in the merchant outbox.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>4</integer> + </map> + <key>InventoryOutboxMaxItemCount</key> + <map> + <key>Comment</key> + <string>Maximum number of items allowed in a listing in the merchant outbox.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>200</integer> </map> <key>InventorySortOrder</key> <map> @@ -11345,17 +11378,6 @@ <key>Value</key> <real>3</real> </map> - <key>UIResizeBarOverlap</key> - <map> - <key>Comment</key> - <string>Size of UI resize bar overlap</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <real>1</real> - </map> <key>UIScaleFactor</key> <map> <key>Comment</key> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 40136adbc9..a455d359bf 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -45,6 +45,8 @@ #include "llwindow.h" #include "llviewerstats.h" #include "llviewerstatsrecorder.h" +#include "llmarketplacefunctions.h" +#include "llmarketplacenotifications.h" #include "llmd5.h" #include "llmeshrepository.h" #include "llpumpio.h" @@ -4404,6 +4406,10 @@ void LLAppViewer::idle() // update media focus LLViewerMediaFocus::getInstance()->update(); + + // Update marketplace + LLMarketplaceInventoryImporter::update(); + LLMarketplaceInventoryNotifications::update(); // objects and camera should be in sync, do LOD calculations now { diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 7abecc643b..9a7cdcfa21 100755 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -724,7 +724,7 @@ std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs() LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); if (sidepanel_inventory) { - inventory_selected_uuids = sidepanel_inventory->getInboxOrOutboxSelectionList(); + inventory_selected_uuids = sidepanel_inventory->getInboxSelectionList(); } } diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 42de47e777..f530d10ddc 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -621,7 +621,6 @@ void LLChatHistory::initFromParams(const LLChatHistory::Params& p) panel_p.has_border = false; panel_p.mouse_opaque = false; panel_p.min_dim = 30; - panel_p.max_dim = S32_MAX; panel_p.auto_resize = true; panel_p.user_resize = false; diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp index a879651060..f1bc51fbe7 100644 --- a/indra/newview/llchicletbar.cpp +++ b/indra/newview/llchicletbar.cpp @@ -42,28 +42,6 @@ namespace { const std::string& PANEL_CHICLET_NAME = "chiclet_list_panel"; - S32 get_panel_min_width(LLLayoutStack* stack, LLView* panel) - { - S32 minimal_width = 0; - llassert(stack); - if ( stack && panel && panel->getVisible() ) - { - stack->getPanelMinSize(panel->getName(), &minimal_width); - } - return minimal_width; - } - - S32 get_panel_max_width(LLLayoutStack* stack, LLPanel* panel) - { - S32 max_width = 0; - llassert(stack); - if ( stack && panel && panel->getVisible() ) - { - stack->getPanelMaxSize(panel->getName(), &max_width); - } - return max_width; - } - S32 get_curr_width(LLUICtrl* ctrl) { S32 cur_width = 0; @@ -234,15 +212,8 @@ void LLChicletBar::reshape(S32 width, S32 height, BOOL called_from_parent) { // Firstly, update layout stack to ensure we deal with correct panel sizes. { - BOOL saved_anim = mToolbarStack->getAnimate(); - // Set chiclet panel to be autoresized by default. - mToolbarStack->updatePanelAutoResize(PANEL_CHICLET_NAME, TRUE); - // Disable animation to prevent layout updating in several frames. - mToolbarStack->setAnimate(FALSE); // Force the updating of layout to reset panels collapse factor. mToolbarStack->updateLayout(); - // Restore animate state. - mToolbarStack->setAnimate(saved_anim); } // chiclet bar is narrowed diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index b13a9aab88..95da8ff948 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -2025,7 +2025,6 @@ void LLPanelLandOptions::refresh() } mSeeAvatarsCtrl->set(parcel->getSeeAVs()); - mSeeAvatarsCtrl->setLabel(getString("see_avs_text")); mSeeAvatarsCtrl->setEnabled(can_change_options && parcel->getHaveNewParcelLimitData()); BOOL can_change_landing_point = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, @@ -2475,27 +2474,6 @@ void LLPanelLandAccess::refresh() mListBanned->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix); } } - - LLCheckBoxWithTBAcess* maturity_checkbox = (LLCheckBoxWithTBAcess*) getChild<LLCheckBoxCtrl>( "public_access"); - LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); - if(region) - { - LLTextBox* maturity_textbox = maturity_checkbox->getTextBox(); - insert_maturity_into_textbox(maturity_textbox, gFloaterView->getParentFloater(this), getString("allow_public_access")); - maturity_checkbox->reshape(maturity_checkbox->getRect().getWidth(), maturity_checkbox->getRect().getHeight(), FALSE); - } - else - { - std::string maturity_string = getString("allow_public_access"); - size_t maturity_pos = maturity_string.find(MATURITY); - - if (maturity_pos != std::string::npos) - { - maturity_string.replace(maturity_pos, MATURITY.length(), std::string("")); - } - - maturity_checkbox->setLabel(maturity_string); - } if(parcel->getRegionDenyAnonymousOverride()) { diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp index 29af81d64c..2681d4b34d 100644 --- a/indra/newview/llfloaternotificationsconsole.cpp +++ b/indra/newview/llfloaternotificationsconsole.cpp @@ -220,7 +220,7 @@ void LLFloaterNotificationConsole::addChannel(const std::string& name, bool open void LLFloaterNotificationConsole::removeChannel(const std::string& name) { LLPanel* panelp = getChild<LLPanel>(name); - getChildRef<LLLayoutStack>("notification_channels").removePanel(panelp); + getChildRef<LLView>("notification_channels").removeChild(panelp); delete panelp; updateResizeLimits(); diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp new file mode 100644 index 0000000000..540f977305 --- /dev/null +++ b/indra/newview/llfloateroutbox.cpp @@ -0,0 +1,567 @@ +/** + * @file llfloateroutbox.cpp + * @brief Implementation of the merchant outbox window + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloateroutbox.h" + +#include "llfloaterreg.h" +#include "llfolderview.h" +#include "llinventorybridge.h" +#include "llinventorymodelbackgroundfetch.h" +#include "llinventoryobserver.h" +#include "llinventorypanel.h" +#include "llmarketplacefunctions.h" +#include "llnotificationhandler.h" +#include "llnotificationmanager.h" +#include "llnotificationsutil.h" +#include "lltextbox.h" +#include "lltransientfloatermgr.h" +#include "lltrans.h" +#include "llviewernetwork.h" +#include "llwindowshade.h" + +#define USE_WINDOWSHADE_DIALOGS 0 + + +///---------------------------------------------------------------------------- +/// LLOutboxNotification class +///---------------------------------------------------------------------------- + +bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLSD& notify) +{ + LLFloaterOutbox* outbox_floater = LLFloaterReg::getTypedInstance<LLFloaterOutbox>("outbox"); + + outbox_floater->showNotification(notify); + + return false; +} + + +///---------------------------------------------------------------------------- +/// LLOutboxAddedObserver helper class +///---------------------------------------------------------------------------- + +class LLOutboxAddedObserver : public LLInventoryCategoryAddedObserver +{ +public: + LLOutboxAddedObserver(LLFloaterOutbox * outboxFloater) + : LLInventoryCategoryAddedObserver() + , mOutboxFloater(outboxFloater) + { + } + + void done() + { + for (cat_vec_t::iterator it = mAddedCategories.begin(); it != mAddedCategories.end(); ++it) + { + LLViewerInventoryCategory* added_category = *it; + + LLFolderType::EType added_category_type = added_category->getPreferredType(); + + if (added_category_type == LLFolderType::FT_OUTBOX) + { + mOutboxFloater->setupOutbox(added_category->getUUID()); + } + } + } + +private: + LLFloaterOutbox * mOutboxFloater; +}; + +///---------------------------------------------------------------------------- +/// LLFloaterOutbox +///---------------------------------------------------------------------------- + +LLFloaterOutbox::LLFloaterOutbox(const LLSD& key) + : LLFloater(key) + , mCategoriesObserver(NULL) + , mCategoryAddedObserver(NULL) + , mImportBusy(false) + , mImportButton(NULL) + , mInventoryFolderCountText(NULL) + , mInventoryImportInProgress(NULL) + , mInventoryPlaceholder(NULL) + , mInventoryText(NULL) + , mInventoryTitle(NULL) + , mOutboxId(LLUUID::null) + , mOutboxInventoryPanel(NULL) + , mOutboxItemCount(0) + , mOutboxTopLevelDropZone(NULL) + , mWindowShade(NULL) +{ +} + +LLFloaterOutbox::~LLFloaterOutbox() +{ + if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver)) + { + gInventory.removeObserver(mCategoriesObserver); + } + delete mCategoriesObserver; + + if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver)) + { + gInventory.removeObserver(mCategoryAddedObserver); + } + delete mCategoryAddedObserver; +} + +BOOL LLFloaterOutbox::postBuild() +{ + mInventoryFolderCountText = getChild<LLTextBox>("outbox_folder_count"); + mInventoryImportInProgress = getChild<LLView>("import_progress_indicator"); + mInventoryPlaceholder = getChild<LLView>("outbox_inventory_placeholder_panel"); + mInventoryText = mInventoryPlaceholder->getChild<LLTextBox>("outbox_inventory_placeholder_text"); + mInventoryTitle = mInventoryPlaceholder->getChild<LLTextBox>("outbox_inventory_placeholder_title"); + + mImportButton = getChild<LLButton>("outbox_import_btn"); + mImportButton->setCommitCallback(boost::bind(&LLFloaterOutbox::onImportButtonClicked, this)); + + mOutboxTopLevelDropZone = getChild<LLPanel>("outbox_generic_drag_target"); + + LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLFloaterOutbox::onFocusReceived, this)); + + return TRUE; +} + +void LLFloaterOutbox::onClose(bool app_quitting) +{ + if (mWindowShade) + { + delete mWindowShade; + + mWindowShade = NULL; + } +} + +void LLFloaterOutbox::onOpen(const LLSD& key) +{ + // + // Look for an outbox and set up the inventory API + // + + if (mOutboxId.isNull()) + { + const bool do_not_create_folder = false; + const bool do_not_find_in_library = false; + + const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder, do_not_find_in_library); + + if (outbox_id.isNull()) + { + // Observe category creation to catch outbox creation + mCategoryAddedObserver = new LLOutboxAddedObserver(this); + gInventory.addObserver(mCategoryAddedObserver); + } + else + { + setupOutbox(outbox_id); + } + } + + updateView(); + + // + // Trigger fetch of outbox contents + // + + fetchOutboxContents(); +} + +void LLFloaterOutbox::onFocusReceived() +{ + fetchOutboxContents(); +} + +void LLFloaterOutbox::fetchOutboxContents() +{ + if (mOutboxId.notNull()) + { + LLInventoryModelBackgroundFetch::instance().start(mOutboxId); + } +} + +void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId) +{ + llassert(outboxId.notNull()); + llassert(mOutboxId.isNull()); + llassert(mCategoriesObserver == NULL); + + mOutboxId = outboxId; + + // No longer need to observe new category creation + if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver)) + { + gInventory.removeObserver(mCategoryAddedObserver); + delete mCategoryAddedObserver; + mCategoryAddedObserver = NULL; + } + + // Create observer for outbox modifications + mCategoriesObserver = new LLInventoryCategoriesObserver(); + gInventory.addObserver(mCategoriesObserver); + + mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this)); + + // + // Set up the outbox inventory view + // + + mOutboxInventoryPanel = + LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml", + mInventoryPlaceholder->getParent(), + LLInventoryPanel::child_registry_t::instance()); + + llassert(mOutboxInventoryPanel); + + // Reshape the inventory to the proper size + LLRect inventory_placeholder_rect = mInventoryPlaceholder->getRect(); + mOutboxInventoryPanel->setShape(inventory_placeholder_rect); + + // Set the sort order newest to oldest + mOutboxInventoryPanel->setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME); + mOutboxInventoryPanel->getFilter()->markDefault(); + + fetchOutboxContents(); + + // + // Initialize the marketplace import API + // + + LLMarketplaceInventoryImporter& importer = LLMarketplaceInventoryImporter::instance(); + + importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2)); + importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1)); + importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2)); + importer.initialize(); +} + +void LLFloaterOutbox::setStatusString(const std::string& statusString) +{ + llassert(mInventoryFolderCountText != NULL); + + mInventoryFolderCountText->setText(statusString); +} + +void LLFloaterOutbox::updateFolderCount() +{ + S32 item_count = 0; + + if (mOutboxId.notNull()) + { + LLInventoryModel::cat_array_t * cats; + LLInventoryModel::item_array_t * items; + gInventory.getDirectDescendentsOf(mOutboxId, cats, items); + + item_count = cats->count() + items->count(); + } + + mOutboxItemCount = item_count; + + if (!mImportBusy) + { + updateFolderCountStatus(); + } +} + +void LLFloaterOutbox::updateFolderCountStatus() +{ + if (mOutboxInventoryPanel) + { + switch (mOutboxItemCount) + { + case 0: setStatusString(getString("OutboxFolderCount0")); break; + case 1: setStatusString(getString("OutboxFolderCount1")); break; + default: + { + std::string item_count_str = llformat("%d", mOutboxItemCount); + + LLStringUtil::format_map_t args; + args["[NUM]"] = item_count_str; + + setStatusString(getString("OutboxFolderCountN", args)); + break; + } + } + } + + mImportButton->setEnabled(mOutboxItemCount > 0); +} + +void LLFloaterOutbox::updateView() +{ + updateFolderCount(); + + if (mOutboxItemCount > 0) + { + mOutboxInventoryPanel->setVisible(TRUE); + mInventoryPlaceholder->setVisible(FALSE); + } + else + { + if (mOutboxInventoryPanel) + { + mOutboxInventoryPanel->setVisible(FALSE); + } + + mInventoryPlaceholder->setVisible(TRUE); + + std::string outbox_text; + std::string outbox_title; + std::string outbox_tooltip; + + const LLSD& subs = getMarketplaceStringSubstitutions(); + + if (mOutboxId.notNull()) + { + outbox_text = LLTrans::getString("InventoryOutboxNoItems", subs); + outbox_title = LLTrans::getString("InventoryOutboxNoItemsTitle"); + outbox_tooltip = LLTrans::getString("InventoryOutboxNoItemsTooltip"); + } + else + { + outbox_text = LLTrans::getString("InventoryOutboxNotMerchant", subs); + outbox_title = LLTrans::getString("InventoryOutboxNotMerchantTitle"); + outbox_tooltip = LLTrans::getString("InventoryOutboxNotMerchantTooltip"); + } + + mInventoryText->setValue(outbox_text); + mInventoryTitle->setValue(outbox_title); + mInventoryPlaceholder->getParent()->setToolTip(outbox_tooltip); + } +} + +bool isAccepted(EAcceptance accept) +{ + return (accept >= ACCEPT_YES_COPY_SINGLE); +} + +BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + if ((mOutboxInventoryPanel == NULL) || + (mWindowShade && mWindowShade->isShown()) || + LLMarketplaceInventoryImporter::getInstance()->isImportInProgress()) + { + return FALSE; + } + + LLView * handled_view = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + BOOL handled = (handled_view != NULL); + + // Determine if the mouse is inside the inventory panel itself or just within the floater + bool pointInInventoryPanel = false; + bool pointInInventoryPanelChild = false; + LLFolderView * root_folder = mOutboxInventoryPanel->getRootFolder(); + if (mOutboxInventoryPanel->getVisible()) + { + S32 inv_x, inv_y; + localPointToOtherView(x, y, &inv_x, &inv_y, mOutboxInventoryPanel); + + pointInInventoryPanel = mOutboxInventoryPanel->getRect().pointInRect(inv_x, inv_y); + + LLView * inventory_panel_child_at_point = mOutboxInventoryPanel->childFromPoint(inv_x, inv_y, true); + pointInInventoryPanelChild = (inventory_panel_child_at_point != root_folder); + } + + // Pass all drag and drop for this floater to the outbox inventory control + if (!handled || !isAccepted(*accept)) + { + // Handle the drag and drop directly to the root of the outbox if we're not in the inventory panel + // (otherwise the inventory panel itself will handle the drag and drop operation, without any override) + if (!pointInInventoryPanel) + { + handled = root_folder->handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + } + + mOutboxTopLevelDropZone->setBackgroundVisible(handled && !drop && isAccepted(*accept)); + } + else + { + mOutboxTopLevelDropZone->setBackgroundVisible(!pointInInventoryPanelChild); + } + + return handled; +} + +BOOL LLFloaterOutbox::handleHover(S32 x, S32 y, MASK mask) +{ + mOutboxTopLevelDropZone->setBackgroundVisible(FALSE); + + return LLFloater::handleHover(x, y, mask); +} + +void LLFloaterOutbox::onMouseLeave(S32 x, S32 y, MASK mask) +{ + mOutboxTopLevelDropZone->setBackgroundVisible(FALSE); + + LLFloater::onMouseLeave(x, y, mask); +} + +void LLFloaterOutbox::onImportButtonClicked() +{ + mOutboxInventoryPanel->clearSelection(); + + mImportBusy = LLMarketplaceInventoryImporter::instance().triggerImport(); +} + +void LLFloaterOutbox::onOutboxChanged() +{ + llassert(!mOutboxId.isNull()); + + if (mOutboxInventoryPanel) + { + mOutboxInventoryPanel->requestSort(); + } + + fetchOutboxContents(); + + updateView(); +} + +void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content) +{ + if (status == MarketplaceErrorCodes::IMPORT_DONE) + { + LLNotificationsUtil::add("OutboxImportComplete"); + } + else if (status == MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS) + { + const LLSD& subs = getMarketplaceStringSubstitutions(); + + LLNotificationsUtil::add("OutboxImportHadErrors", subs); + } + else + { + char status_string[16]; + sprintf(status_string, "%d", status); + + LLSD subs; + subs["[ERROR_CODE]"] = status_string; + + LLNotificationsUtil::add("OutboxImportFailed", subs); + } + + updateView(); +} + +void LLFloaterOutbox::importStatusChanged(bool inProgress) +{ + if (inProgress) + { + if (mImportBusy) + { + setStatusString(getString("OutboxImporting")); + } + else + { + setStatusString(getString("OutboxInitializing")); + } + + mImportBusy = true; + mImportButton->setEnabled(false); + mInventoryImportInProgress->setVisible(true); + } + else + { + mImportBusy = false; + mImportButton->setEnabled(mOutboxItemCount > 0); + mInventoryImportInProgress->setVisible(false); + } + + updateView(); +} + +void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content) +{ + if (status != MarketplaceErrorCodes::IMPORT_DONE) + { + char status_string[16]; + sprintf(status_string, "%d", status); + + LLSD subs; + subs["[ERROR_CODE]"] = status_string; + + LLNotificationsUtil::add("OutboxInitFailed", subs); + } + + updateView(); +} + +void LLFloaterOutbox::showNotification(const LLSD& notify) +{ + LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); + + if (!notification) + { + llerrs << "Unable to find outbox notification!" << notify.asString() << llendl; + + return; + } + +#if USE_WINDOWSHADE_DIALOGS + + if (mWindowShade) + { + delete mWindowShade; + } + + LLRect floater_rect = getLocalRect(); + floater_rect.mTop -= getHeaderHeight(); + floater_rect.stretch(-5, 0); + + LLWindowShade::Params params; + params.name = "notification_shade"; + params.rect = floater_rect; + params.follows.flags = FOLLOWS_ALL; + params.modal = true; + params.can_close = false; + params.shade_color = LLColor4::white % 0.25f; + params.text_color = LLColor4::white; + + mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params); + + addChild(mWindowShade); + mWindowShade->show(notification); + +#else + + LLNotificationsUI::LLEventHandler * handler = + LLNotificationsUI::LLNotificationManager::instance().getHandlerForNotification("alertmodal"); + + LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler *>(handler); + llassert(sys_handler); + + sys_handler->processNotification(notify); + +#endif +} + diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h new file mode 100644 index 0000000000..18baccf1c9 --- /dev/null +++ b/indra/newview/llfloateroutbox.h @@ -0,0 +1,114 @@ +/** + * @file llfloateroutbox.h + * @brief LLFloaterOutbox + * class definition + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * ABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATEROUTBOX_H +#define LL_LLFLOATEROUTBOX_H + +#include "llfloater.h" +#include "llfoldertype.h" +#include "llnotificationptr.h" + + +class LLButton; +class LLInventoryCategoriesObserver; +class LLInventoryCategoryAddedObserver; +class LLInventoryPanel; +class LLLoadingIndicator; +class LLNotification; +class LLTextBox; +class LLView; +class LLWindowShade; + + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFloaterOutbox +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLFloaterOutbox : public LLFloater +{ +public: + LLFloaterOutbox(const LLSD& key); + ~LLFloaterOutbox(); + + void setupOutbox(const LLUUID& outboxId); + + // virtuals + BOOL postBuild(); + BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); + + void showNotification(const LLSD& notify); + + BOOL handleHover(S32 x, S32 y, MASK mask); + void onMouseLeave(S32 x, S32 y, MASK mask); + +protected: + void fetchOutboxContents(); + + void importReportResults(U32 status, const LLSD& content); + void importStatusChanged(bool inProgress); + void initializationReportError(U32 status, const LLSD& content); + + void onClose(bool app_quitting); + void onOpen(const LLSD& key); + + void onFocusReceived(); + + void onImportButtonClicked(); + void onOutboxChanged(); + + void setStatusString(const std::string& statusString); + + void updateFolderCount(); + void updateFolderCountStatus(); + void updateView(); + +private: + LLInventoryCategoriesObserver * mCategoriesObserver; + LLInventoryCategoryAddedObserver * mCategoryAddedObserver; + + bool mImportBusy; + LLButton * mImportButton; + + LLTextBox * mInventoryFolderCountText; + LLView * mInventoryImportInProgress; + LLView * mInventoryPlaceholder; + LLTextBox * mInventoryText; + LLTextBox * mInventoryTitle; + + LLUUID mOutboxId; + LLInventoryPanel * mOutboxInventoryPanel; + U32 mOutboxItemCount; + LLPanel * mOutboxTopLevelDropZone; + + LLWindowShade * mWindowShade; +}; + +#endif // LL_LLFLOATEROUTBOX_H diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index 4c9c4cb154..d741b5b133 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -915,14 +915,16 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) { panel->buildFromFile(path); // build it LLRect new_size = panel->getRect(); // get its rectangle - panel->setOrigin(0,0); // reset its origin point so it's not offset by -left or other XUI attributes + panel->setOrigin(2,2); // reset its origin point so it's not offset by -left or other XUI attributes (*floaterp)->setTitle(path); // use the file name as its title, since panels have no guaranteed meaningful name attribute panel->setUseBoundingRect(TRUE); // enable the use of its outer bounding rect (normally disabled because it's O(n) on the number of sub-elements) panel->updateBoundingRect(); // update bounding rect LLRect bounding_rect = panel->getBoundingRect(); // get the bounding rect LLRect new_rect = panel->getRect(); // get the panel's rect new_rect.unionWith(bounding_rect); // union them to make sure we get the biggest one possible - (*floaterp)->reshape(new_rect.getWidth(), new_rect.getHeight() + floater_header_size); // reshape floater to match the union rect's dimensions + LLRect floater_rect = new_rect; + floater_rect.stretch(4, 4); + (*floaterp)->reshape(floater_rect.getWidth(), floater_rect.getHeight() + floater_header_size); // reshape floater to match the union rect's dimensions panel->reshape(new_rect.getWidth(), new_rect.getHeight()); // reshape panel to match the union rect's dimensions as well (both are needed) (*floaterp)->addChild(panel); // add panel as child (*floaterp)->openFloater(); // open floater (needed?) diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index ecd4c2c3de..e0d7d67f7d 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -172,6 +172,7 @@ LLFolderView::Params::Params() title("title"), use_label_suffix("use_label_suffix"), allow_multiselect("allow_multiselect", true), + show_empty_message("show_empty_message", true), show_load_status("show_load_status", true), use_ellipses("use_ellipses", false) { @@ -185,6 +186,7 @@ LLFolderView::LLFolderView(const Params& p) mScrollContainer( NULL ), mPopupMenuHandle(), mAllowMultiSelect(p.allow_multiselect), + mShowEmptyMessage(p.show_empty_message), mShowFolderHierarchy(FALSE), mSourceID(p.task_id), mRenameItem( NULL ), @@ -349,10 +351,6 @@ BOOL LLFolderView::addFolder( LLFolderViewFolder* folder) { mFolders.insert(mFolders.begin(), folder); } - if (folder->numSelected()) - { - recursiveIncrementNumDescendantsSelected(folder->numSelected()); - } folder->setShowLoadStatus(mShowLoadStatus); folder->setOrigin(0, 0); folder->reshape(getRect().getWidth(), 0); @@ -694,26 +692,6 @@ BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected) return rv; } -void LLFolderView::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items) -{ - // now store resulting selection - if (mAllowMultiSelect) - { - LLFolderViewItem *cur_selection = getCurSelectedItem(); - LLFolderViewFolder::extendSelection(selection, cur_selection, items); - for (S32 i = 0; i < items.count(); i++) - { - addToSelectionList(items[i]); - } - } - else - { - setSelection(selection, FALSE, FALSE); - } - - mSignalSelectCallback = SIGNAL_KEYBOARD_FOCUS; -} - static LLFastTimer::DeclareTimer FTM_SANITIZE_SELECTION("Sanitize Selection"); void LLFolderView::sanitizeSelection() { @@ -932,7 +910,7 @@ void LLFolderView::draw() mStatusText.clear(); mStatusTextBox->setVisible( FALSE ); } - else + else if (mShowEmptyMessage) { if (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration()) { @@ -966,7 +944,6 @@ void LLFolderView::draw() // See EXT-7564, EXT-7047. arrangeFromRoot(); } - } // skip over LLFolderViewFolder::draw since we don't want the folder icon, label, @@ -1222,7 +1199,9 @@ void LLFolderView::changeType(LLInventoryModel *model, LLFolderType::EType new_f void LLFolderView::autoOpenItem( LLFolderViewFolder* item ) { - if (mAutoOpenItems.check() == item || mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH) + if ((mAutoOpenItems.check() == item) || + (mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH) || + item->isOpen()) { return; } @@ -1945,9 +1924,9 @@ BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, if (!handled) { if (getListener()->getUUID().notNull()) - { - handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); - } + { + handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + } else { if (!mFolders.empty()) diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 8af01e9102..1d018b5e6a 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -75,6 +75,7 @@ public: Optional<std::string> title; Optional<bool> use_label_suffix, allow_multiselect, + show_empty_message, show_load_status, use_ellipses; @@ -106,6 +107,8 @@ public: U32 getSortOrder() const; BOOL isFilterModified(); + bool getAllowMultiSelect() { return mAllowMultiSelect; } + // Close all folders in the view void closeAllFolders(); void openTopLevelFolders(); @@ -141,8 +144,6 @@ public: // children, and keeps track of selected objects. virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); - virtual void extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items); - virtual std::set<LLUUID> getSelectionList() const; // make sure if ancestor is selected, descendents are not @@ -156,7 +157,6 @@ public: void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; } LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; } - // deletion functionality void removeSelectedItems(); @@ -282,6 +282,7 @@ protected: selected_items_t mSelectedItems; BOOL mKeyboardSelection; BOOL mAllowMultiSelect; + BOOL mShowEmptyMessage; BOOL mShowFolderHierarchy; LLUUID mSourceID; diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index f27fd035db..8d6114c887 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -386,13 +386,6 @@ void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL getRoot()->changeSelection(selection, selected); } -void LLFolderViewItem::extendSelectionFromRoot(LLFolderViewItem* selection) -{ - LLDynamicArray<LLFolderViewItem*> selected_items; - - getRoot()->extendSelection(selection, NULL, selected_items); -} - std::set<LLUUID> LLFolderViewItem::getSelectionList() const { std::set<LLUUID> selection; @@ -496,10 +489,6 @@ BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, if (selection == this && !mIsSelected) { selectItem(); - if (mListener) - { - mListener->selectItem(); - } } else if (mIsSelected) // Deselect everything else. { @@ -510,7 +499,7 @@ BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected) { - if (selection == this && mIsSelected != selected) + if (selection == this) { if (mIsSelected) { @@ -520,10 +509,6 @@ BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selecte { selectItem(); } - if (mListener) - { - mListener->selectItem(); - } return TRUE; } return FALSE; @@ -531,29 +516,18 @@ BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selecte void LLFolderViewItem::deselectItem(void) { - llassert(mIsSelected); - mIsSelected = FALSE; - - // Update ancestors' count of selected descendents. - LLFolderViewFolder* parent_folder = getParentFolder(); - if (parent_folder) - { - parent_folder->recursiveIncrementNumDescendantsSelected(-1); - } } void LLFolderViewItem::selectItem(void) { - llassert(!mIsSelected); - - mIsSelected = TRUE; - - // Update ancestors' count of selected descendents. - LLFolderViewFolder* parent_folder = getParentFolder(); - if (parent_folder) + if (mIsSelected == FALSE) { - parent_folder->recursiveIncrementNumDescendantsSelected(1); + if (mListener) + { + mListener->selectItem(); + } + mIsSelected = TRUE; } } @@ -697,7 +671,7 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask ) } else if (mask & MASK_SHIFT) { - extendSelectionFromRoot(this); + getParentFolder()->extendSelectionTo(this); } else { @@ -812,7 +786,7 @@ BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask ) } else if (mask & MASK_SHIFT) { - extendSelectionFromRoot(this); + getParentFolder()->extendSelectionTo(this); } else { @@ -1125,7 +1099,6 @@ void LLFolderViewItem::draw() LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ): LLFolderViewItem( p ), // 0 = no create time - mNumDescendantsSelected(0), mIsOpen(FALSE), mExpanderHighlighted(FALSE), mCurHeight(0.f), @@ -1572,21 +1545,6 @@ BOOL LLFolderViewFolder::hasFilteredDescendants() return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration(); } -void LLFolderViewFolder::recursiveIncrementNumDescendantsSelected(S32 increment) -{ - LLFolderViewFolder* parent_folder = this; - do - { - parent_folder->mNumDescendantsSelected += increment; - - // Make sure we don't have negative values. - llassert(parent_folder->mNumDescendantsSelected >= 0); - - parent_folder = parent_folder->getParentFolder(); - } - while(parent_folder); -} - // Passes selection information on to children and record selection // information if necessary. BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem, @@ -1599,10 +1557,6 @@ BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem { selectItem(); } - if (mListener) - { - mListener->selectItem(); - } rv = TRUE; } else @@ -1663,10 +1617,6 @@ BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, BOOL selec deselectItem(); } } - if (mListener && selected) - { - mListener->selectItem(); - } } for (folders_t::iterator iter = mFolders.begin(); @@ -1690,119 +1640,261 @@ BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, BOOL selec return rv; } -void LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& selected_items) +LLFolderViewFolder* LLFolderViewFolder::getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse) { - // pass on to child folders first - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) + if (!item_a->getParentFolder() || !item_b->getParentFolder()) return NULL; + + std::deque<LLFolderViewFolder*> item_a_ancestors; + + LLFolderViewFolder* parent = item_a->getParentFolder(); + while(parent) { - folders_t::iterator fit = iter++; - (*fit)->extendSelection(selection, last_selected, selected_items); + item_a_ancestors.push_back(parent); + parent = parent->getParentFolder(); } - // handle selection of our immediate children... - BOOL reverse_select = FALSE; - BOOL found_last_selected = FALSE; - BOOL found_selection = FALSE; - LLDynamicArray<LLFolderViewItem*> items_to_select; - LLFolderViewItem* item; + std::deque<LLFolderViewFolder*> item_b_ancestors; + + parent = item_b->getParentFolder(); + while(parent) + { + item_b_ancestors.push_back(parent); + parent = parent->getParentFolder(); + } - //...folders first... - for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) + LLFolderViewFolder* common_ancestor = item_a->getRoot(); + + while(item_a_ancestors.size() > item_b_ancestors.size()) { - folders_t::iterator fit = iter++; - item = (*fit); - if(item == selection) - { - found_selection = TRUE; - } - else if (item == last_selected) + item_a = item_a_ancestors.front(); + item_a_ancestors.pop_front(); + } + + while(item_b_ancestors.size() > item_a_ancestors.size()) + { + item_b = item_b_ancestors.front(); + item_b_ancestors.pop_front(); + } + + while(item_a_ancestors.size()) + { + common_ancestor = item_a_ancestors.front(); + + if (item_a_ancestors.front() == item_b_ancestors.front()) { - found_last_selected = TRUE; - if (found_selection) + // which came first, sibling a or sibling b? + for (folders_t::iterator it = common_ancestor->mFolders.begin(), end_it = common_ancestor->mFolders.end(); + it != end_it; + ++it) { - reverse_select = TRUE; + LLFolderViewItem* item = *it; + + if (item == item_a) + { + reverse = false; + return common_ancestor; + } + if (item == item_b) + { + reverse = true; + return common_ancestor; + } } - } - if (found_selection || found_last_selected) - { - // deselect currently selected items so they can be pushed back on queue - if (item->isSelected()) + for (items_t::iterator it = common_ancestor->mItems.begin(), end_it = common_ancestor->mItems.end(); + it != end_it; + ++it) { - item->changeSelection(item, FALSE); + LLFolderViewItem* item = *it; + + if (item == item_a) + { + reverse = false; + return common_ancestor; + } + if (item == item_b) + { + reverse = true; + return common_ancestor; + } } - items_to_select.put(item); + break; } - if (found_selection && found_last_selected) - { - break; - } + item_a = item_a_ancestors.front(); + item_a_ancestors.pop_front(); + item_b = item_b_ancestors.front(); + item_b_ancestors.pop_front(); } - if (!(found_selection && found_last_selected)) + return NULL; +} + +void LLFolderViewFolder::gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items) +{ + bool selecting = start == NULL; + if (reverse) { - //,,,then items - for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) + for (items_t::reverse_iterator it = mItems.rbegin(), end_it = mItems.rend(); + it != end_it; + ++it) { - items_t::iterator iit = iter++; - item = (*iit); - if(item == selection) + if (*it == end) { - found_selection = TRUE; + return; } - else if (item == last_selected) + if (selecting) { - found_last_selected = TRUE; - if (found_selection) - { - reverse_select = TRUE; - } + items.push_back(*it); } - if (found_selection || found_last_selected) + if (*it == start) { - // deselect currently selected items so they can be pushed back on queue - if (item->isSelected()) - { - item->changeSelection(item, FALSE); - } - items_to_select.put(item); + selecting = true; + } + } + for (folders_t::reverse_iterator it = mFolders.rbegin(), end_it = mFolders.rend(); + it != end_it; + ++it) + { + if (*it == end) + { + return; } - if (found_selection && found_last_selected) + if (selecting) { - break; + items.push_back(*it); + } + + if (*it == start) + { + selecting = true; } } } - - if (found_last_selected && found_selection) + else { - // we have a complete selection inside this folder - for (S32 index = reverse_select ? items_to_select.getLength() - 1 : 0; - reverse_select ? index >= 0 : index < items_to_select.getLength(); reverse_select ? index-- : index++) + for (folders_t::iterator it = mFolders.begin(), end_it = mFolders.end(); + it != end_it; + ++it) { - LLFolderViewItem* item = items_to_select[index]; - if (item->changeSelection(item, TRUE)) + if (*it == end) { - selected_items.put(item); + return; + } + + if (selecting) + { + items.push_back(*it); + } + + if (*it == start) + { + selecting = true; + } + } + for (items_t::iterator it = mItems.begin(), end_it = mItems.end(); + it != end_it; + ++it) + { + if (*it == end) + { + return; + } + + if (selecting) + { + items.push_back(*it); + } + + if (*it == start) + { + selecting = true; } } } - else if (found_selection) +} + +void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection) +{ + if (getRoot()->getAllowMultiSelect() == FALSE) return; + + LLFolderViewItem* cur_selected_item = getRoot()->getCurSelectedItem(); + if (cur_selected_item == NULL) { - // last selection was not in this folder....go ahead and select just the new item - if (selection->changeSelection(selection, TRUE)) + cur_selected_item = new_selection; + } + + + bool reverse = false; + LLFolderViewFolder* common_ancestor = getCommonAncestor(cur_selected_item, new_selection, reverse); + if (!common_ancestor) return; + + LLFolderViewItem* last_selected_item_from_cur = cur_selected_item; + LLFolderViewFolder* cur_folder = cur_selected_item->getParentFolder(); + + std::vector<LLFolderViewItem*> items_to_select_forward; + + while(cur_folder != common_ancestor) + { + cur_folder->gatherChildRangeExclusive(last_selected_item_from_cur, NULL, reverse, items_to_select_forward); + + last_selected_item_from_cur = cur_folder; + cur_folder = cur_folder->getParentFolder(); + } + + std::vector<LLFolderViewItem*> items_to_select_reverse; + + LLFolderViewItem* last_selected_item_from_new = new_selection; + cur_folder = new_selection->getParentFolder(); + while(cur_folder != common_ancestor) + { + cur_folder->gatherChildRangeExclusive(last_selected_item_from_new, NULL, !reverse, items_to_select_reverse); + + last_selected_item_from_new = cur_folder; + cur_folder = cur_folder->getParentFolder(); + } + + common_ancestor->gatherChildRangeExclusive(last_selected_item_from_cur, last_selected_item_from_new, reverse, items_to_select_forward); + + for (std::vector<LLFolderViewItem*>::reverse_iterator it = items_to_select_reverse.rbegin(), end_it = items_to_select_reverse.rend(); + it != end_it; + ++it) + { + items_to_select_forward.push_back(*it); + } + + LLFolderView* root = getRoot(); + + for (std::vector<LLFolderViewItem*>::iterator it = items_to_select_forward.begin(), end_it = items_to_select_forward.end(); + it != end_it; + ++it) + { + LLFolderViewItem* item = *it; + if (item->isSelected()) + { + root->removeFromSelectionList(item); + } + else { - selected_items.put(selection); + item->selectItem(); } + root->addToSelectionList(item); + } + + if (new_selection->isSelected()) + { + root->removeFromSelectionList(new_selection); + } + else + { + new_selection->selectItem(); } + root->addToSelectionList(new_selection); } + void LLFolderViewFolder::destroyView() { for (items_t::iterator iter = mItems.begin(); @@ -1874,19 +1966,11 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item ) ft = std::find(mFolders.begin(), mFolders.end(), f); if (ft != mFolders.end()) { - if ((*ft)->numSelected()) - { - recursiveIncrementNumDescendantsSelected(-(*ft)->numSelected()); - } mFolders.erase(ft); } } else { - if ((*it)->isSelected()) - { - recursiveIncrementNumDescendantsSelected(-1); - } mItems.erase(it); } //item has been removed, need to update filter @@ -2055,11 +2139,6 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item) { mItems.push_back(item); - if (item->isSelected()) - { - recursiveIncrementNumDescendantsSelected(1); - } - item->setRect(LLRect(0, 0, getRect().getWidth(), 0)); item->setVisible(FALSE); @@ -2067,8 +2146,14 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item) item->dirtyFilter(); - // Update the folder creation date if the child is newer than our current date - setCreationDate(llmax<time_t>(mCreationDate, item->getCreationDate())); + // Update the folder creation date if the folder has no creation date + bool setting_date = false; + const time_t item_creation_date = item->getCreationDate(); + if ((item_creation_date > 0) && (mCreationDate == 0)) + { + setCreationDate(item_creation_date); + setting_date = true; + } // Handle sorting requestArrange(); @@ -2078,8 +2163,11 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item) LLFolderViewFolder* parentp = getParentFolder(); while (parentp) { - // Update the folder creation date if the child is newer than our current date - parentp->setCreationDate(llmax<time_t>(parentp->mCreationDate, item->getCreationDate())); + // Update the parent folder creation date + if (setting_date && (parentp->mCreationDate == 0)) + { + parentp->setCreationDate(item_creation_date); + } if (parentp->mSortFunction.isByDate()) { @@ -2097,10 +2185,6 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item) BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder) { mFolders.push_back(folder); - if (folder->numSelected()) - { - recursiveIncrementNumDescendantsSelected(folder->numSelected()); - } folder->setOrigin(0, 0); folder->reshape(getRect().getWidth(), 0); folder->setVisible(FALSE); @@ -2276,33 +2360,16 @@ BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask, EAcceptance* accept, std::string& tooltip_msg) { - LLFolderView* root_view = getRoot(); - BOOL handled = FALSE; - if(mIsOpen) + + if (mIsOpen) { - handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, - cargo_data, accept, tooltip_msg) != NULL; + handled = (childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg) != NULL); } if (!handled) { - BOOL accepted = mListener && mListener->dragOrDrop(mask, drop,cargo_type,cargo_data, tooltip_msg); - - if (accepted) - { - mDragAndDropTarget = TRUE; - *accept = ACCEPT_YES_MULTI; - } - else - { - *accept = ACCEPT_NO; - } - - if (!drop && accepted) - { - root_view->autoOpenTest(this); - } + handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg); lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl; } @@ -2310,6 +2377,33 @@ BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask, return TRUE; } +BOOL LLFolderViewFolder::handleDragAndDropToThisFolder(MASK mask, + BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + BOOL accepted = mListener && mListener->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg); + + if (accepted) + { + mDragAndDropTarget = TRUE; + *accept = ACCEPT_YES_MULTI; + } + else + { + *accept = ACCEPT_NO; + } + + if (!drop && accepted) + { + getRoot()->autoOpenTest(this); + } + + return TRUE; +} + BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask ) { diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index 3433e3f7f3..2fc79f5765 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -122,6 +122,8 @@ public: // Mostly for debugging printout purposes. const std::string& getSearchableLabel() { return mSearchableLabel; } + + BOOL isLoading() const { return mIsLoading; } private: BOOL mIsSelected; @@ -164,9 +166,6 @@ protected: // helper function to change the selection from the root. void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected); - // helper function to change the selection from the root. - void extendSelectionFromRoot(LLFolderViewItem* selection); - // this is an internal method used for adding items to folders. A // no-op at this level, but reimplemented in derived classes. virtual BOOL addItem(LLFolderViewItem*) { return FALSE; } @@ -224,9 +223,6 @@ public: // Returns TRUE if the selection state of this item was changed. virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); - // this method is used to group select items - virtual void extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items) { } - // this method is used to deselect this element void deselectItem(); @@ -373,13 +369,6 @@ public: typedef std::list<LLFolderViewItem*> items_t; typedef std::list<LLFolderViewFolder*> folders_t; -private: - S32 mNumDescendantsSelected; - -public: // Accessed needed by LLFolderViewItem - void recursiveIncrementNumDescendantsSelected(S32 increment); - S32 numSelected(void) const { return mNumDescendantsSelected + (isSelected() ? 1 : 0); } - protected: items_t mItems; folders_t mFolders; @@ -461,7 +450,7 @@ public: virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); // this method is used to group select items - virtual void extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items); + void extendSelectionTo(LLFolderViewItem* selection); // Returns true is this object and all of its children can be removed. virtual BOOL isRemovable(); @@ -547,11 +536,15 @@ public: void* cargo_data, EAcceptance* accept, std::string& tooltip_msg); + BOOL handleDragAndDropToThisFolder(MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); virtual void draw(); time_t getCreationDate() const; bool isTrash() const; - S32 getNumSelectedDescendants(void) const { return mNumDescendantsSelected; } folders_t::const_iterator getFoldersBegin() const { return mFolders.begin(); } folders_t::const_iterator getFoldersEnd() const { return mFolders.end(); } @@ -560,6 +553,8 @@ public: items_t::const_iterator getItemsBegin() const { return mItems.begin(); } items_t::const_iterator getItemsEnd() const { return mItems.end(); } items_t::size_type getItemsCount() const { return mItems.size(); } + LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse); + void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items); }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index f5cda52d44..f67464078b 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -234,12 +234,6 @@ LLIMFloater::~LLIMFloater() //virtual BOOL LLIMFloater::postBuild() { - // User-resizable control panels in P2P sessions look ugly (EXT-3470). - if (mDialog == IM_NOTHING_SPECIAL || mDialog == IM_SESSION_P2P_INVITE) - { - getChild<LLLayoutStack>("im_panels")->setPanelUserResize("panel_im_control_panel", FALSE); - } - const LLUUID& other_party_id = LLIMModel::getInstance()->getOtherParticipantID(mSessionID); if (other_party_id.notNull()) { @@ -385,9 +379,6 @@ void LLIMFloater::onSlide() getChild<LLButton>("slide_left_btn")->setVisible(mControlPanel->getParent()->getVisible()); getChild<LLButton>("slide_right_btn")->setVisible(!mControlPanel->getParent()->getVisible()); - - LLLayoutStack* stack = getChild<LLLayoutStack>("im_panels"); - if (stack) stack->setAnimate(true); } //static diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp index bf6cf52298..a12ec390af 100644 --- a/indra/newview/llinspectremoteobject.cpp +++ b/indra/newview/llinspectremoteobject.cpp @@ -60,12 +60,10 @@ public: private: void update(); - void onNameCache(const LLUUID& id, const std::string& name, bool is_group); private: LLUUID mObjectID; LLUUID mOwnerID; - std::string mOwnerLegacyName; std::string mSLurl; std::string mName; bool mGroupOwned; @@ -75,7 +73,6 @@ LLInspectRemoteObject::LLInspectRemoteObject(const LLSD& sd) : LLInspect(LLSD()), mObjectID(NULL), mOwnerID(NULL), - mOwnerLegacyName(), mSLurl(""), mName(""), mGroupOwned(false) @@ -111,14 +108,6 @@ void LLInspectRemoteObject::onOpen(const LLSD& data) mGroupOwned = data["group_owned"].asBoolean(); mSLurl = data["slurl"].asString(); - // work out the owner's name - mOwnerLegacyName = ""; - if (gCacheName) - { - gCacheName->get(mOwnerID, mGroupOwned, // muting - boost::bind(&LLInspectRemoteObject::onNameCache, this, _1, _2, _3)); - } - // update the inspector with the current object state update(); @@ -144,8 +133,7 @@ void LLInspectRemoteObject::onClickMap() void LLInspectRemoteObject::onClickBlock() { - LLMute::EType mute_type = mGroupOwned ? LLMute::GROUP : LLMute::AGENT; - LLMute mute(mOwnerID, mOwnerLegacyName, mute_type); + LLMute mute(mObjectID, mName, LLMute::OBJECT); LLMuteList::getInstance()->add(mute); LLPanelBlockedList::showPanelAndSelect(mute.mID); closeFloater(); @@ -156,12 +144,6 @@ void LLInspectRemoteObject::onClickClose() closeFloater(); } -void LLInspectRemoteObject::onNameCache(const LLUUID& id, const std::string& name, bool is_group) -{ - mOwnerLegacyName = name; - update(); -} - void LLInspectRemoteObject::update() { // show the object name as the inspector's title @@ -198,8 +180,8 @@ void LLInspectRemoteObject::update() // disable the Map button if we don't have a SLurl getChild<LLUICtrl>("map_btn")->setEnabled(! mSLurl.empty()); - // disable the Block button if we don't have the owner ID - getChild<LLUICtrl>("block_btn")->setEnabled(! mOwnerID.isNull()); + // disable the Block button if we don't have the object ID (will this ever happen?) + getChild<LLUICtrl>("block_btn")->setEnabled(! mObjectID.isNull()); } ////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index eaf9b53eb9..c0065a94e6 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -53,6 +53,7 @@ #include "llinventorymodel.h" #include "llinventorymodelbackgroundfetch.h" #include "llinventorypanel.h" +#include "llmarketplacefunctions.h" #include "llnotifications.h" #include "llnotificationsutil.h" #include "llpreviewanim.h" @@ -60,6 +61,7 @@ #include "llpreviewtexture.h" #include "llselectmgr.h" #include "llsidepanelappearance.h" +#include "lltooldraganddrop.h" #include "lltrans.h" #include "llviewerassettype.h" #include "llviewerfoldertype.h" @@ -71,7 +73,9 @@ #include "llwearablelist.h" // Marketplace outbox current disabled -#define ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU 0 // keep in sync with ENABLE_INVENTORY_DISPLAY_OUTBOX, ENABLE_MERCHANT_OUTBOX_PANEL +#define ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU 1 +#define ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU 0 +#define BLOCK_WORN_ITEMS_IN_OUTBOX 1 typedef std::pair<LLUUID, LLUUID> two_uuids_t; typedef std::list<two_uuids_t> two_uuids_list_t; @@ -127,6 +131,11 @@ bool isMarketplaceCopyAction(const std::string& action) return (("copy_to_outbox" == action) || ("move_to_outbox" == action)); } +bool isMarketplaceSendAction(const std::string& action) +{ + return ("send_to_marketplace" == action); +} + // +=================================================+ // | LLInvFVBridge | // +=================================================+ @@ -462,14 +471,13 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const void hide_context_entries(LLMenuGL& menu, const menuentry_vec_t &entries_to_show, - const menuentry_vec_t &disabled_entries, - BOOL append) // If append is TRUE, then new enabled entries + const menuentry_vec_t &disabled_entries) { const LLView::child_list_t *list = menu.getChildList(); // For removing double separators or leading separator. Start at true so that // if the first element is a separator, it will not be shown. - BOOL is_previous_entry_separator = TRUE; + bool is_previous_entry_separator = true; for (LLView::child_list_t::const_iterator itor = list->begin(); itor != list->end(); @@ -485,7 +493,6 @@ void hide_context_entries(LLMenuGL& menu, hide_context_entries(*branchp->getBranch(), entries_to_show, disabled_entries); } - bool found = false; menuentry_vec_t::const_iterator itor2; for (itor2 = entries_to_show.begin(); itor2 != entries_to_show.end(); ++itor2) @@ -493,6 +500,7 @@ void hide_context_entries(LLMenuGL& menu, if (*itor2 == name) { found = true; + break; } } @@ -500,9 +508,8 @@ void hide_context_entries(LLMenuGL& menu, // between two separators). if (found) { - const BOOL is_entry_separator = (dynamic_cast<LLMenuItemSeparatorGL *>(menu_item) != NULL); - if (is_entry_separator && is_previous_entry_separator) - found = false; + const bool is_entry_separator = (dynamic_cast<LLMenuItemSeparatorGL *>(menu_item) != NULL); + found = !(is_entry_separator && is_previous_entry_separator); is_previous_entry_separator = is_entry_separator; } @@ -512,6 +519,7 @@ void hide_context_entries(LLMenuGL& menu, { menu_item->setVisible(FALSE); } + menu_item->setEnabled(FALSE); } else @@ -520,17 +528,14 @@ void hide_context_entries(LLMenuGL& menu, // A bit of a hack so we can remember that some UI element explicitly set this to be visible // so that some other UI element from multi-select doesn't later set this invisible. menu_item->pushVisible(TRUE); - if (append) - { - menu_item->setEnabled(TRUE); - } - for (itor2 = disabled_entries.begin(); itor2 != disabled_entries.end(); ++itor2) + + bool enabled = (menu_item->getEnabled() == TRUE); + for (itor2 = disabled_entries.begin(); enabled && (itor2 != disabled_entries.end()); ++itor2) { - if (*itor2 == name) - { - menu_item->setEnabled(FALSE); - } + enabled &= (*itor2 != name); } + + menu_item->setEnabled(enabled); } } } @@ -598,25 +603,16 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, { items.push_back(std::string("Marketplace Separator")); - bool copyable = true; - LLViewerInventoryItem* inv_item = gInventory.getItem(mUUID); - if (inv_item) - { - copyable = inv_item->getPermissions().allowCopyBy(gAgent.getID()); - } - - const std::string merchant_action = ((copyable == true) ? "Merchant Copy" : "Merchant Move"); - items.push_back(merchant_action); - + items.push_back(std::string("Merchant Copy")); if (!canListOnMarketplaceNow()) { - disabled_items.push_back(merchant_action); + disabled_items.push_back(std::string("Merchant Copy")); } } } } - // Don't allow items to be pasted directly into the COF or the inbox + // Don't allow items to be pasted directly into the COF or the inbox/outbox if (!isCOFFolder() && !isInboxFolder() && !isOutboxFolder()) { items.push_back(std::string("Paste")); @@ -657,7 +653,7 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else if(isOutboxFolder()) { - items.push_back(std::string("Delete")); + addOutboxContextMenuOptions(flags, items, disabled_items); } else { @@ -734,6 +730,32 @@ void LLInvFVBridge::addOpenRightClickMenuOption(menuentry_vec_t &items) items.push_back(std::string("Open")); } +void LLInvFVBridge::addOutboxContextMenuOptions(U32 flags, + menuentry_vec_t &items, + menuentry_vec_t &disabled_items) +{ + items.push_back(std::string("Rename")); + items.push_back(std::string("Delete")); + + if ((flags & FIRST_SELECTED_ITEM) == 0) + { + disabled_items.push_back(std::string("Rename")); + } + +#if ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU + if (isOutboxFolderDirectParent()) + { + items.push_back(std::string("Marketplace Separator")); + items.push_back(std::string("Marketplace Send")); + + if ((flags & FIRST_SELECTED_ITEM) == 0) + { + disabled_items.push_back(std::string("Marketplace Send")); + } + } +#endif // ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU +} + // *TODO: remove this BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const { @@ -854,6 +876,22 @@ BOOL LLInvFVBridge::isOutboxFolder() const return gInventory.isObjectDescendentOf(mUUID, outbox_id); } +BOOL LLInvFVBridge::isOutboxFolderDirectParent() const +{ + BOOL outbox_is_parent = FALSE; + + const LLInventoryCategory *cat = gInventory.getCategory(mUUID); + + if (cat) + { + const LLUUID outbox_id = getOutboxFolder(); + + outbox_is_parent = (outbox_id.notNull() && (outbox_id == cat->getParentUUID())); + } + + return outbox_is_parent; +} + const LLUUID LLInvFVBridge::getOutboxFolder() const { const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); @@ -1040,82 +1078,134 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid) } } -BOOL LLInvFVBridge::canShare() const +bool LLInvFVBridge::canShare() const { - if (!isAgentInventory()) return FALSE; + bool can_share = false; - const LLInventoryModel* model = getInventoryModel(); - if (!model) return FALSE; - - const LLViewerInventoryItem *item = model->getItem(mUUID); - if (item) + if (isAgentInventory()) { - if (!LLInventoryCollectFunctor::itemTransferCommonlyAllowed(item)) - return FALSE; - return (BOOL)LLGiveInventory::isInventoryGiveAcceptable(item); + const LLInventoryModel* model = getInventoryModel(); + if (model) + { + const LLViewerInventoryItem *item = model->getItem(mUUID); + if (item) + { + if (LLInventoryCollectFunctor::itemTransferCommonlyAllowed(item)) + { + can_share = LLGiveInventory::isInventoryGiveAcceptable(item); + } + } + else + { + // Categories can be given. + can_share = (model->getCategory(mUUID) != NULL); + } + } } - // Categories can be given. - if (model->getCategory(mUUID)) return TRUE; - - return FALSE; + return can_share; } -BOOL LLInvFVBridge::canListOnMarketplace() const +bool LLInvFVBridge::canListOnMarketplace() const { #if ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU + LLInventoryModel * model = getInventoryModel(); + const LLViewerInventoryCategory * cat = model->getCategory(mUUID); if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType())) { - return FALSE; + return false; } if (!isAgentInventory()) { - return FALSE; + return false; } if (getOutboxFolder().isNull()) { - return FALSE; + return false; } if (isInboxFolder() || isOutboxFolder()) { - return FALSE; + return false; } - + LLViewerInventoryItem * item = model->getItem(mUUID); - if (item && !item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) + if (item) { - return FALSE; + if (!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) + { + return false; + } + + if (LLAssetType::AT_CALLINGCARD == item->getType()) + { + return false; + } } - return TRUE; + return true; + #else - return FALSE; + return false; #endif } -BOOL LLInvFVBridge::canListOnMarketplaceNow() const +bool LLInvFVBridge::canListOnMarketplaceNow() const { #if ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU - if (get_is_item_worn(mUUID)) + + bool can_list = true; + + // Do not allow listing while import is in progress + if (LLMarketplaceInventoryImporter::instanceExists()) { - return FALSE; + can_list = !LLMarketplaceInventoryImporter::instance().isImportInProgress(); } + + const LLInventoryObject* obj = getInventoryObject(); + can_list &= (obj != NULL); - // Loop through all items worn by avatar and check to see if they are descendants - // of the item we are trying to list on the marketplace - if (get_is_parent_to_worn_item(mUUID)) + if (can_list) { - return FALSE; + const LLUUID& object_id = obj->getLinkedUUID(); + can_list = object_id.notNull(); + + if (can_list) + { + LLFolderViewFolder * object_folderp = mRoot->getFolderByID(object_id); + if (object_folderp) + { + can_list = !object_folderp->isLoading(); + } + } + + if (can_list) + { + // Get outbox id + const LLUUID & outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + LLFolderViewItem * outbox_itemp = mRoot->getItemByID(outbox_id); + + if (outbox_itemp) + { + MASK mask = 0x0; + BOOL drop = FALSE; + EDragAndDropType cargo_type = LLViewerAssetType::lookupDragAndDropType(obj->getActualType()); + void * cargo_data = (void *) obj; + std::string tooltip_msg; + + can_list = outbox_itemp->getListener()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg); + } + } } + + return can_list; - return TRUE; #else - return FALSE; + return false; #endif } @@ -1225,7 +1315,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action) if (!itemp) return; const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); - copy_item_to_outbox(itemp, outbox_id, LLUUID::null); + copy_item_to_outbox(itemp, outbox_id, LLUUID::null, LLToolDragAndDrop::getOperationId()); } } @@ -1235,6 +1325,7 @@ void LLItemBridge::selectItem() if(item && !item->isFinished()) { item->fetchFromServer(); + //LLInventoryModelBackgroundFetch::instance().start(item->getUUID(), false); } } @@ -1564,11 +1655,7 @@ BOOL LLItemBridge::isItemCopyable() const return FALSE; } - // All items can be copied in god mode since you can - // at least paste-as-link the item, though you - // still may not be able paste the item. - return TRUE; - // return (item->getPermissions().allowCopyBy(gAgent.getID())); + return item->getPermissions().allowCopyBy(gAgent.getID()) || gSavedSettings.getBOOL("InventoryLinking"); } return FALSE; } @@ -1681,12 +1768,8 @@ BOOL LLFolderBridge::isUpToDate() const BOOL LLFolderBridge::isItemCopyable() const { - if (gSavedSettings.getBOOL("InventoryLinking")) - { - // Can copy folders to paste-as-link, but not for straight paste. - return TRUE; - } - return FALSE; + // Can copy folders to paste-as-link, but not for straight paste. + return gSavedSettings.getBOOL("InventoryLinking"); } BOOL LLFolderBridge::copyToClipboard() const @@ -1787,30 +1870,41 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const static BOOL can_move_to_outbox(LLInventoryItem* inv_item, std::string& tooltip_msg) { - bool worn = get_is_item_worn(inv_item->getUUID()); + // Collapse links directly to items/folders + LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item; + LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem(); + if (linked_item != NULL) + { + inv_item = linked_item; + } + bool allow_transfer = inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); - if (!allow_transfer) { tooltip_msg = LLTrans::getString("TooltipOutboxNoTransfer"); + return false; } - else if(worn) + +#if BLOCK_WORN_ITEMS_IN_OUTBOX + bool worn = get_is_item_worn(inv_item->getUUID()); + if (worn) { tooltip_msg = LLTrans::getString("TooltipOutboxWorn"); + return false; } +#endif - return !worn && allow_transfer; -} - - - -void LLFolderBridge::dropFolderToOutbox(LLInventoryCategory* inv_cat) -{ - copy_folder_to_outbox(inv_cat, getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false), inv_cat->getUUID()); + bool calling_card = (LLAssetType::AT_CALLINGCARD == inv_item->getType()); + if (calling_card) + { + tooltip_msg = LLTrans::getString("TooltipOutboxCallingCard"); + return false; + } + + return true; } - int get_folder_levels(LLInventoryCategory* inv_cat) { LLInventoryModel::cat_array_t* cats; @@ -1865,54 +1959,78 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, if (!isAgentAvatarValid()) return FALSE; if (!isAgentInventory()) return FALSE; // cannot drag categories into library + const LLUUID &cat_id = inv_cat->getUUID(); + const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); + const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + + const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); + const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); + const BOOL move_is_from_outbox = model->isObjectDescendentOf(cat_id, outbox_id); // check to make sure source is agent inventory, and is represented there. LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); - const BOOL is_agent_inventory = (model->getCategory(inv_cat->getUUID()) != NULL) + const BOOL is_agent_inventory = (model->getCategory(cat_id) != NULL) && (LLToolDragAndDrop::SOURCE_AGENT == source); - const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); - const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); - BOOL accept = FALSE; if (is_agent_inventory) { - const LLUUID &cat_id = inv_cat->getUUID(); const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH, false); const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); - const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id); const BOOL move_is_into_outfit = getCategory() && (getCategory()->getPreferredType() == LLFolderType::FT_OUTFIT); const BOOL move_is_into_landmarks = (mUUID == landmarks_id) || model->isObjectDescendentOf(mUUID, landmarks_id); - const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); - const BOOL move_is_from_outbox = model->isObjectDescendentOf(inv_cat->getUUID(), outbox_id); //-------------------------------------------------------------------------------- // Determine if folder can be moved. // BOOL is_movable = TRUE; - if (LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType())) + + if (is_movable && (mUUID == cat_id)) + { + is_movable = FALSE; + tooltip_msg = LLTrans::getString("TooltipDragOntoSelf"); + } + if (is_movable && (model->isObjectDescendentOf(mUUID, cat_id))) + { + is_movable = FALSE; + tooltip_msg = LLTrans::getString("TooltipDragOntoOwnChild"); + } + if (is_movable && LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType())) + { is_movable = FALSE; - if (move_is_into_outfit) + // tooltip? + } + if (is_movable && move_is_into_outfit) + { is_movable = FALSE; - if (mUUID == gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE)) + // tooltip? + } + if (is_movable && (mUUID == model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE))) + { is_movable = FALSE; + // tooltip? + } + LLInventoryModel::cat_array_t descendent_categories; LLInventoryModel::item_array_t descendent_items; - gInventory.collectDescendents(cat_id, descendent_categories, descendent_items, FALSE); - for (S32 i=0; i < descendent_categories.count(); ++i) + if (is_movable) { - LLInventoryCategory* category = descendent_categories[i]; - if(LLFolderType::lookupIsProtectedType(category->getPreferredType())) + model->collectDescendents(cat_id, descendent_categories, descendent_items, FALSE); + for (S32 i=0; i < descendent_categories.count(); ++i) { - // Can't move "special folders" (e.g. Textures Folder). - is_movable = FALSE; - break; + LLInventoryCategory* category = descendent_categories[i]; + if(LLFolderType::lookupIsProtectedType(category->getPreferredType())) + { + // Can't move "special folders" (e.g. Textures Folder). + is_movable = FALSE; + break; + } } } - if (move_is_into_trash) + if (is_movable && move_is_into_trash) { for (S32 i=0; i < descendent_items.count(); ++i) { @@ -1924,7 +2042,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } } } - if (move_is_into_landmarks) + if (is_movable && move_is_into_landmarks) { for (S32 i=0; i < descendent_items.count(); ++i) { @@ -1939,35 +2057,100 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } } } - if (move_is_into_outbox) + if (is_movable && move_is_into_outbox) { - for (S32 i=0; i < descendent_items.count(); ++i) + const int nested_folder_levels = get_folder_path_length(outbox_id, mUUID) + get_folder_levels(inv_cat); + + if (nested_folder_levels > gSavedSettings.getU32("InventoryOutboxMaxFolderDepth")) { - LLInventoryItem* item = descendent_items[i]; - if (!can_move_to_outbox(item, tooltip_msg)) - { - is_movable = FALSE; - break; - } + tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels"); + is_movable = FALSE; } + else + { + int dragged_folder_count = descendent_categories.count(); + int existing_item_count = 0; + int existing_folder_count = 0; + + const LLViewerInventoryCategory * master_folder = model->getFirstDescendantOf(outbox_id, mUUID); + + if (master_folder != NULL) + { + if (model->isObjectDescendentOf(cat_id, master_folder->getUUID())) + { + // Don't use count because we're already inside the same category anyway + dragged_folder_count = 0; + } + else + { + existing_folder_count = 1; // Include the master folder in the count! + + // If we're in the drop operation as opposed to the drag without drop, we are doing a + // single category at a time so don't block based on the total amount of cargo data items + if (drop) + { + dragged_folder_count += 1; + } + else + { + // NOTE: The cargo id's count is a total of categories AND items but we err on the side of + // prevention rather than letting too many folders into the hierarchy of the outbox, + // when we're dragging the item to a new parent + dragged_folder_count += LLToolDragAndDrop::instance().getCargoIDsCount(); + } + } + + // Tally the total number of categories and items inside the master folder - int nested_folder_levels = get_folder_path_length(outbox_id, mUUID) + get_folder_levels(inv_cat); + LLInventoryModel::cat_array_t existing_categories; + LLInventoryModel::item_array_t existing_items; - if (nested_folder_levels > 4) - { - tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels"); - is_movable = FALSE; + model->collectDescendents(master_folder->getUUID(), existing_categories, existing_items, FALSE); + + existing_folder_count += existing_categories.count(); + existing_item_count += existing_items.count(); + } + else + { + // Assume a single category is being dragged to the outbox since we evaluate one at a time + // when not putting them under a parent item. + dragged_folder_count += 1; + } + + const int nested_folder_count = existing_folder_count + dragged_folder_count; + const int nested_item_count = existing_item_count + descendent_items.count(); + + if (nested_folder_count > gSavedSettings.getU32("InventoryOutboxMaxFolderCount")) + { + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyFolders"); + is_movable = FALSE; + } + else if (nested_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount")) + { + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects"); + is_movable = FALSE; + } + + if (is_movable == TRUE) + { + for (S32 i=0; i < descendent_items.count(); ++i) + { + LLInventoryItem* item = descendent_items[i]; + if (!can_move_to_outbox(item, tooltip_msg)) + { + is_movable = FALSE; + break; + } + } + } } - } // //-------------------------------------------------------------------------------- - accept = is_movable - && (mUUID != cat_id) // Can't move a folder into itself - && (mUUID != inv_cat->getParentUUID()) // Avoid moves that would change nothing - && !(model->isObjectDescendentOf(mUUID, cat_id)); // Avoid circularity + accept = is_movable; + if (accept && drop) { // Look for any gestures and deactivate them @@ -1999,7 +2182,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, // Recursively create links in target outfit. LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; - gInventory.collectDescendents(inv_cat->getUUID(), cats, items, LLInventoryModel::EXCLUDE_TRASH); + model->collectDescendents(cat_id, cats, items, LLInventoryModel::EXCLUDE_TRASH); LLAppearanceMgr::instance().linkAll(mUUID,items,NULL); } } @@ -2017,7 +2200,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, const std::string empty_description = ""; link_inventory_item( gAgent.getID(), - inv_cat->getUUID(), + cat_id, mUUID, inv_cat->getName(), empty_description, @@ -2029,13 +2212,13 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } else if (move_is_into_outbox && !move_is_from_outbox) { - dropFolderToOutbox(inv_cat); + copy_folder_to_outbox(inv_cat, mUUID, cat_id, LLToolDragAndDrop::getOperationId()); } else { - if (gInventory.isObjectDescendentOf(inv_cat->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false))) + if (model->isObjectDescendentOf(cat_id, model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false))) { - set_dad_inbox_object(inv_cat->getUUID()); + set_dad_inbox_object(cat_id); } // Reparent the folder and restamp children if it's moving @@ -2050,15 +2233,28 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } else if (LLToolDragAndDrop::SOURCE_WORLD == source) { - // content category has same ID as object itself - LLUUID object_id = inv_cat->getUUID(); - LLUUID category_id = mUUID; - accept = move_inv_category_world_to_agent(object_id, category_id, drop); + if (move_is_into_outbox) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + accept = FALSE; + } + else + { + accept = move_inv_category_world_to_agent(cat_id, mUUID, drop); + } } else if (LLToolDragAndDrop::SOURCE_LIBRARY == source) { - // Accept folders that contain complete outfits. - accept = move_is_into_current_outfit && LLAppearanceMgr::instance().getCanMakeFolderIntoOutfit(inv_cat->getUUID()); + if (move_is_into_outbox) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + accept = FALSE; + } + else + { + // Accept folders that contain complete outfits. + accept = move_is_into_current_outfit && LLAppearanceMgr::instance().getCanMakeFolderIntoOutfit(cat_id); + } if (accept && drop) { @@ -2201,7 +2397,6 @@ public: delete this; } - protected: LLUUID mCatID; bool mCopyItems; @@ -2450,8 +2645,19 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) if (!cat) return; const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); - copy_folder_to_outbox(cat, outbox_id, cat->getUUID()); + copy_folder_to_outbox(cat, outbox_id, cat->getUUID(), LLToolDragAndDrop::getOperationId()); } +#if ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU + else if (isMarketplaceSendAction(action)) + { + llinfos << "Send to marketplace action!" << llendl; + + LLInventoryCategory * cat = gInventory.getCategory(mUUID); + if (!cat) return; + + send_to_marketplace(cat); + } +#endif // ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU } void LLFolderBridge::openItem() @@ -2718,103 +2924,10 @@ void LLFolderBridge::pasteLinkFromClipboard() void LLFolderBridge::staticFolderOptionsMenu() { LLFolderBridge* selfp = sSelf.get(); - if (selfp) - { - selfp->folderOptionsMenu(); - } -} -void LLFolderBridge::folderOptionsMenu() -{ - LLInventoryModel* model = getInventoryModel(); - if(!model) return; - - const LLInventoryCategory* category = model->getCategory(mUUID); - if(!category) return; - - const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); - if (trash_id == mUUID) return; - if (isItemInTrash()) return; - if (!isAgentInventory()) return; - if (isOutboxFolder()) return; - - LLFolderType::EType type = category->getPreferredType(); - const bool is_system_folder = LLFolderType::lookupIsProtectedType(type); - // BAP change once we're no longer treating regular categories as ensembles. - const bool is_ensemble = (type == LLFolderType::FT_NONE || - LLFolderType::lookupIsEnsembleType(type)); - - // Only enable calling-card related options for non-system folders. - if (!is_system_folder) - { - LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD); - if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard)) - { - mItems.push_back(std::string("Calling Card Separator")); - mItems.push_back(std::string("Conference Chat Folder")); - mItems.push_back(std::string("IM All Contacts In Folder")); - } - } - - if (!isItemRemovable()) + if (selfp && selfp->mRoot) { - mDisabledItems.push_back(std::string("Delete")); - } - -#ifndef LL_RELEASE_FOR_DOWNLOAD - if (LLFolderType::lookupIsProtectedType(type)) - { - mItems.push_back(std::string("Delete System Folder")); - } -#endif - - // wearables related functionality for folders. - //is_wearable - LLFindWearables is_wearable; - LLIsType is_object( LLAssetType::AT_OBJECT ); - LLIsType is_gesture( LLAssetType::AT_GESTURE ); - - if (mWearables || - checkFolderForContentsOfType(model, is_wearable) || - checkFolderForContentsOfType(model, is_object) || - checkFolderForContentsOfType(model, is_gesture) ) - { - mItems.push_back(std::string("Folder Wearables Separator")); - - // Only enable add/replace outfit for non-system folders. - if (!is_system_folder) - { - // Adding an outfit onto another (versus replacing) doesn't make sense. - if (type != LLFolderType::FT_OUTFIT) - { - mItems.push_back(std::string("Add To Outfit")); - } - - mItems.push_back(std::string("Replace Outfit")); - } - if (is_ensemble) - { - mItems.push_back(std::string("Wear As Ensemble")); - } - mItems.push_back(std::string("Remove From Outfit")); - if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID)) - { - mDisabledItems.push_back(std::string("Remove From Outfit")); - } - if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID)) - { - mDisabledItems.push_back(std::string("Replace Outfit")); - } - mItems.push_back(std::string("Outfit Separator")); - } - LLMenuGL* menup = dynamic_cast<LLMenuGL*>(mMenu.get()); - if (menup) - { - hide_context_entries(*menup, mItems, mDisabledItems, TRUE); - - // Reposition the menu, in case we're adding items to an existing menu. - menup->needsArrange(); - menup->arrangeAndClear(); + selfp->mRoot->updateMenu(); } } @@ -2830,17 +2943,11 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv return ((item_array.count() > 0) ? TRUE : FALSE ); } -// Flags unused -void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +void LLFolderBridge::buildContextMenuBaseOptions(U32 flags) { - mItems.clear(); - mDisabledItems.clear(); - - lldebugs << "LLFolderBridge::buildContextMenu()" << llendl; - -// menuentry_vec_t disabled_items; LLInventoryModel* model = getInventoryModel(); - if(!model) return; + llassert(model != NULL); + const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); const LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); @@ -2857,10 +2964,6 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) mDisabledItems.push_back(std::string("New Body Parts")); } - // clear out old menu and folder pointers - mMenu.markDead(); - sSelf.markDead(); - if(trash_id == mUUID) { // This is the trash. @@ -2874,20 +2977,23 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else if(isOutboxFolder()) { - mItems.push_back(std::string("Delete")); + addOutboxContextMenuOptions(flags, mItems, mDisabledItems); } else if(isAgentInventory()) // do not allow creating in library { - LLViewerInventoryCategory *cat = getCategory(); + LLViewerInventoryCategory *cat = getCategory(); // BAP removed protected check to re-enable standard ops in untyped folders. // Not sure what the right thing is to do here. if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT)) { - if (!isInboxFolder() && !isOutboxFolder()) // don't allow creation in inbox + if (!isInboxFolder() && !isOutboxFolder()) // don't allow creation in inbox or outbox { // Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694. if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat)) + { mItems.push_back(std::string("New Folder")); + } + mItems.push_back(std::string("New Script")); mItems.push_back(std::string("New Note")); mItems.push_back(std::string("New Gesture")); @@ -2958,34 +3064,138 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) mDisabledItems.push_back(std::string("Share")); } } +} - hide_context_entries(menu, mItems, mDisabledItems); +void LLFolderBridge::buildContextMenuFolderOptions(U32 flags) +{ + // Build folder specific options back up + LLInventoryModel* model = getInventoryModel(); + if(!model) return; - // Add menu items that are dependent on the contents of the folder. - uuid_vec_t folders; - LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID); - if (category) + const LLInventoryCategory* category = model->getCategory(mUUID); + if(!category) return; + + const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); + if (trash_id == mUUID) return; + if (isItemInTrash()) return; + if (!isAgentInventory()) return; + if (isOutboxFolder()) return; + + LLFolderType::EType type = category->getPreferredType(); + const bool is_system_folder = LLFolderType::lookupIsProtectedType(type); + // BAP change once we're no longer treating regular categories as ensembles. + const bool is_ensemble = (type == LLFolderType::FT_NONE || + LLFolderType::lookupIsEnsembleType(type)); + + // Only enable calling-card related options for non-system folders. + if (!is_system_folder) { - folders.push_back(category->getUUID()); + LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD); + if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard)) + { + mItems.push_back(std::string("Calling Card Separator")); + mItems.push_back(std::string("Conference Chat Folder")); + mItems.push_back(std::string("IM All Contacts In Folder")); + } } - mMenu = menu.getHandle(); - sSelf = getHandle(); - LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders, FALSE); - fetch->startFetch(); - inc_busy_count(); - if(fetch->isFinished()) + if (!isItemRemovable()) { - // everything is already here - call done. - fetch->done(); + mDisabledItems.push_back(std::string("Delete")); } - else + +#ifndef LL_RELEASE_FOR_DOWNLOAD + if (LLFolderType::lookupIsProtectedType(type)) { - // it's all on its way - add an observer, and the inventory will call done for us when everything is here. - gInventory.addObserver(fetch); + mItems.push_back(std::string("Delete System Folder")); + } +#endif + + // wearables related functionality for folders. + //is_wearable + LLFindWearables is_wearable; + LLIsType is_object( LLAssetType::AT_OBJECT ); + LLIsType is_gesture( LLAssetType::AT_GESTURE ); + + if (mWearables || + checkFolderForContentsOfType(model, is_wearable) || + checkFolderForContentsOfType(model, is_object) || + checkFolderForContentsOfType(model, is_gesture) ) + { + mItems.push_back(std::string("Folder Wearables Separator")); + + // Only enable add/replace outfit for non-system folders. + if (!is_system_folder) + { + // Adding an outfit onto another (versus replacing) doesn't make sense. + if (type != LLFolderType::FT_OUTFIT) + { + mItems.push_back(std::string("Add To Outfit")); + } + + mItems.push_back(std::string("Replace Outfit")); + } + if (is_ensemble) + { + mItems.push_back(std::string("Wear As Ensemble")); + } + mItems.push_back(std::string("Remove From Outfit")); + if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID)) + { + mDisabledItems.push_back(std::string("Remove From Outfit")); + } + if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID)) + { + mDisabledItems.push_back(std::string("Replace Outfit")); + } + mItems.push_back(std::string("Outfit Separator")); } } +// Flags unused +void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + sSelf.markDead(); + + mItems.clear(); + mDisabledItems.clear(); + + lldebugs << "LLFolderBridge::buildContextMenu()" << llendl; + + LLInventoryModel* model = getInventoryModel(); + if(!model) return; + + buildContextMenuBaseOptions(flags); + + // Add menu items that are dependent on the contents of the folder. + LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID); + if (category) + { + uuid_vec_t folders; + folders.push_back(category->getUUID()); + + sSelf = getHandle(); + LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders, FALSE); + fetch->startFetch(); + inc_busy_count(); + if (fetch->isFinished()) + { + buildContextMenuFolderOptions(flags); + } + else + { + // it's all on its way - add an observer, and the inventory will call done for us when everything is here. + gInventory.addObserver(fetch); + } + } + + hide_context_entries(menu, mItems, mDisabledItems); + + // Reposition the menu, in case we're adding items to an existing menu. + menu.needsArrange(); + menu.arrangeAndClear(); +} + BOOL LLFolderBridge::hasChildren() const { LLInventoryModel* model = getInventoryModel(); @@ -3306,8 +3516,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { LLInventoryModel* model = getInventoryModel(); - if(!model || !inv_item) return FALSE; - if(!isAgentInventory()) return FALSE; // cannot drag into library + if (!model || !inv_item) return FALSE; + if (!isAgentInventory()) return FALSE; // cannot drag into library if (!isAgentAvatarValid()) return FALSE; const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); @@ -3375,10 +3585,14 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, accept = TRUE; if (!is_movable) + { accept = FALSE; - if ((mUUID == inv_item->getParentUUID()) && !move_is_into_favorites) + } + else if ((mUUID == inv_item->getParentUUID()) && !move_is_into_favorites) + { accept = FALSE; - if (move_is_into_current_outfit || move_is_into_outfit) + } + else if (move_is_into_current_outfit || move_is_into_outfit) { accept = can_move_to_outfit(inv_item, move_is_into_current_outfit); } @@ -3389,9 +3603,32 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, else if (move_is_into_outbox) { accept = can_move_to_outbox(inv_item, tooltip_msg); + + if (accept) + { + const LLViewerInventoryCategory * master_folder = model->getFirstDescendantOf(outbox_id, mUUID); + + int existing_item_count = LLToolDragAndDrop::instance().getCargoIDsCount(); + + if (master_folder != NULL) + { + LLInventoryModel::cat_array_t existing_categories; + LLInventoryModel::item_array_t existing_items; + + gInventory.collectDescendents(master_folder->getUUID(), existing_categories, existing_items, FALSE); + + existing_item_count += existing_items.count(); + } + + if (existing_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount")) + { + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects"); + accept = FALSE; + } + } } - if(accept && drop) + if (accept && drop) { if (inv_item->getType() == LLAssetType::AT_GESTURE && LLGestureMgr::instance().isGestureActive(inv_item->getUUID()) && move_is_into_trash) @@ -3440,9 +3677,16 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { dropToOutfit(inv_item, move_is_into_current_outfit); } - else if (move_is_into_outbox && !move_is_from_outbox) + else if (move_is_into_outbox) { - copy_item_to_outbox(inv_item, outbox_id, LLUUID::null); + if (move_is_from_outbox) + { + move_item_within_outbox(inv_item, mUUID, LLToolDragAndDrop::getOperationId()); + } + else + { + copy_item_to_outbox(inv_item, mUUID, LLUUID::null, LLToolDragAndDrop::getOperationId()); + } } // NORMAL or TRASH folder // (move the item, restamp if into trash) @@ -3463,7 +3707,6 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // //-------------------------------------------------------------------------------- - } } else if (LLToolDragAndDrop::SOURCE_WORLD == source) @@ -3472,7 +3715,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // anonymous objects, it would be possible to bypass // permissions. object = gObjectList.findObject(inv_item->getParentUUID()); - if(!object) + if (!object) { llinfos << "Object not found for drop." << llendl; return FALSE; @@ -3482,10 +3725,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // move/copy this item. LLPermissions perm(inv_item->getPermissions()); BOOL is_move = FALSE; - if((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID()) + if ((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID()) && perm.allowTransferTo(gAgent.getID()))) // || gAgent.isGodlike()) - { accept = TRUE; } @@ -3501,7 +3743,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // Don't allow placing an original item into Current Outfit or an outfit folder // because they must contain only links to wearable items. // *TODO: Probably we should create a link to an item if it was dragged to outfit or COF. - if(move_is_into_current_outfit || move_is_into_outfit) + if (move_is_into_current_outfit || move_is_into_outfit) { accept = FALSE; } @@ -3512,8 +3754,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { accept = FALSE; } - - if(drop && accept) + else if (move_is_into_outbox) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + accept = FALSE; + } + + if (accept && drop) { LLMoveInv* move_inv = new LLMoveInv; move_inv->mObjectID = inv_item->getParentUUID(); @@ -3535,15 +3782,22 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, LLNotifications::instance().forceResponse(params, 0); } } - } else if(LLToolDragAndDrop::SOURCE_NOTECARD == source) { - // Don't allow placing an original item from a notecard to Current Outfit or an outfit folder - // because they must contain only links to wearable items. - accept = !(move_is_into_current_outfit || move_is_into_outfit); - - if(accept && drop) + if (move_is_into_outbox) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + accept = FALSE; + } + else + { + // Don't allow placing an original item from a notecard to Current Outfit or an outfit folder + // because they must contain only links to wearable items. + accept = !(move_is_into_current_outfit || move_is_into_outfit); + } + + if (accept && drop) { copy_inventory_from_notecard(mUUID, // Drop to the chosen destination folder LLToolDragAndDrop::getInstance()->getObjectID(), @@ -3558,7 +3812,12 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { accept = TRUE; - if (move_is_into_current_outfit || move_is_into_outfit) + if (move_is_into_outbox) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + accept = FALSE; + } + else if (move_is_into_current_outfit || move_is_into_outfit) { accept = can_move_to_outfit(inv_item, move_is_into_current_outfit); } @@ -3649,7 +3908,7 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else if(isOutboxFolder()) { - items.push_back(std::string("Delete")); + addOutboxContextMenuOptions(flags, items, disabled_items); } else { @@ -3723,29 +3982,29 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) menuentry_vec_t items; menuentry_vec_t disabled_items; - if(isItemInTrash()) - { - addTrashContextMenuOptions(items, disabled_items); - } - else if(isOutboxFolder()) + if (isOutboxFolder()) { - items.push_back(std::string("Delete")); + addOutboxContextMenuOptions(flags, items, disabled_items); } else { - items.push_back(std::string("Share")); - if (!canShare()) + if (isItemInTrash()) { - disabled_items.push_back(std::string("Share")); - } - items.push_back(std::string("Sound Open")); - items.push_back(std::string("Properties")); + addTrashContextMenuOptions(items, disabled_items); + } + else + { + items.push_back(std::string("Share")); + if (!canShare()) + { + disabled_items.push_back(std::string("Share")); + } + items.push_back(std::string("Sound Open")); + items.push_back(std::string("Properties")); - getClipboardEntries(true, items, disabled_items, flags); - } + getClipboardEntries(true, items, disabled_items, flags); + } - if (!isOutboxFolder()) - { items.push_back(std::string("Sound Separator")); items.push_back(std::string("Sound Play")); } @@ -3781,29 +4040,29 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) menuentry_vec_t disabled_items; lldebugs << "LLLandmarkBridge::buildContextMenu()" << llendl; - if(isItemInTrash()) - { - addTrashContextMenuOptions(items, disabled_items); - } - else if(isOutboxFolder()) + if(isOutboxFolder()) { - items.push_back(std::string("Delete")); + addOutboxContextMenuOptions(flags, items, disabled_items); } else { - items.push_back(std::string("Share")); - if (!canShare()) + if(isItemInTrash()) { - disabled_items.push_back(std::string("Share")); - } - items.push_back(std::string("Landmark Open")); - items.push_back(std::string("Properties")); + addTrashContextMenuOptions(items, disabled_items); + } + else + { + items.push_back(std::string("Share")); + if (!canShare()) + { + disabled_items.push_back(std::string("Share")); + } + items.push_back(std::string("Landmark Open")); + items.push_back(std::string("Properties")); - getClipboardEntries(true, items, disabled_items, flags); - } + getClipboardEntries(true, items, disabled_items, flags); + } - if (!isOutboxFolder()) - { items.push_back(std::string("Landmark Separator")); items.push_back(std::string("About Landmark")); } @@ -4336,36 +4595,35 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags) menuentry_vec_t disabled_items; lldebugs << "LLAnimationBridge::buildContextMenu()" << llendl; - if(isItemInTrash()) - { - addTrashContextMenuOptions(items, disabled_items); - } - else if(isOutboxFolder()) + if(isOutboxFolder()) { items.push_back(std::string("Delete")); } else { - items.push_back(std::string("Share")); - if (!canShare()) + if(isItemInTrash()) { - disabled_items.push_back(std::string("Share")); - } - items.push_back(std::string("Animation Open")); - items.push_back(std::string("Properties")); + addTrashContextMenuOptions(items, disabled_items); + } + else + { + items.push_back(std::string("Share")); + if (!canShare()) + { + disabled_items.push_back(std::string("Share")); + } + items.push_back(std::string("Animation Open")); + items.push_back(std::string("Properties")); - getClipboardEntries(true, items, disabled_items, flags); - } + getClipboardEntries(true, items, disabled_items, flags); + } - if (!isOutboxFolder()) - { items.push_back(std::string("Animation Separator")); items.push_back(std::string("Animation Play")); items.push_back(std::string("Animation Audition")); } hide_context_entries(menu, items, disabled_items); - } // virtual @@ -5350,7 +5608,7 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else if(isOutboxFolder()) { - items.push_back(std::string("Delete")); + addOutboxContextMenuOptions(flags, items, disabled_items); } else { @@ -5359,7 +5617,6 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) getClipboardEntries(true, items, disabled_items, flags); } - hide_context_entries(menu, items, disabled_items); } diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 2d625befb4..871657a58a 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -69,9 +69,9 @@ public: U32 flags = 0x00); virtual ~LLInvFVBridge() {} - BOOL canShare() const; - BOOL canListOnMarketplace() const; - BOOL canListOnMarketplaceNow() const; + bool canShare() const; + bool canListOnMarketplace() const; + bool canListOnMarketplaceNow() const; //-------------------------------------------------------------------- // LLInvFVBridge functionality @@ -131,6 +131,9 @@ protected: virtual void addDeleteContextMenuOptions(menuentry_vec_t &items, menuentry_vec_t &disabled_items); virtual void addOpenRightClickMenuOption(menuentry_vec_t &items); + virtual void addOutboxContextMenuOptions(U32 flags, + menuentry_vec_t &items, + menuentry_vec_t &disabled_items); protected: LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid); @@ -144,6 +147,7 @@ protected: BOOL isCOFFolder() const; // true if COF or descendent of BOOL isInboxFolder() const; // true if COF or descendent of marketplace inbox BOOL isOutboxFolder() const; // true if COF or descendent of marketplace outbox + BOOL isOutboxFolderDirectParent() const; const LLUUID getOutboxFolder() const; virtual BOOL isItemPermissive() const; @@ -278,6 +282,9 @@ public: LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; } protected: + void buildContextMenuBaseOptions(U32 flags); + void buildContextMenuFolderOptions(U32 flags); + //-------------------------------------------------------------------- // Menu callbacks //-------------------------------------------------------------------- @@ -306,8 +313,6 @@ protected: void dropToFavorites(LLInventoryItem* inv_item); void dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit); - void dropToOutbox(LLInventoryItem* inv_item); - void dropFolderToOutbox(LLInventoryCategory* inv_cat); //-------------------------------------------------------------------- // Messy hacks for handling folder options @@ -315,12 +320,10 @@ protected: public: static LLHandle<LLFolderBridge> sSelf; static void staticFolderOptionsMenu(); - void folderOptionsMenu(); private: BOOL mCallingCards; BOOL mWearables; - LLHandle<LLView> mMenu; menuentry_vec_t mItems; menuentry_vec_t mDisabledItems; LLRootHandle<LLFolderBridge> mHandle; @@ -650,7 +653,6 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, // are set as enabled. void hide_context_entries(LLMenuGL& menu, const menuentry_vec_t &entries_to_show, - const menuentry_vec_t &disabled_entries, - BOOL append = FALSE); + const menuentry_vec_t &disabled_entries); #endif // LL_LLINVENTORYBRIDGE_H diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 5fb3f15cd5..dd92188e9d 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -58,6 +58,7 @@ #include "llinventorymodel.h" #include "llinventorypanel.h" #include "lllineeditor.h" +#include "llmarketplacenotifications.h" #include "llmenugl.h" #include "llnotificationsutil.h" #include "llpanelmaininventory.h" @@ -82,6 +83,8 @@ #include "llvoavatarself.h" #include "llwearablelist.h" +#include <boost/foreach.hpp> + BOOL LLInventoryState::sWearNewClothing = FALSE; LLUUID LLInventoryState::sWearNewClothingTransactionID; @@ -530,21 +533,37 @@ void show_item_original(const LLUUID& item_uuid) } } -void move_to_outbox_cb(const LLSD& notification, const LLSD& response) + +void open_outbox() +{ + LLFloaterReg::showInstance("outbox"); +} + +LLUUID create_folder_in_outbox_for_item(LLInventoryItem* item, const LLUUID& destFolderId, S32 operation_id) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) return; // canceled + llassert(item); + llassert(destFolderId.notNull()); + + LLUUID created_folder_id = gInventory.createNewCategory(destFolderId, LLFolderType::FT_NONE, item->getName()); + gInventory.notifyObservers(); + + LLNotificationsUtil::add("OutboxFolderCreated"); + + return created_folder_id; +} - LLViewerInventoryItem * viitem = gInventory.getItem(notification["payload"]["item_id"].asUUID()); - LLUUID dest_folder_id = notification["payload"]["dest_folder_id"].asUUID(); +void move_to_outbox_cb_action(const LLSD& payload) +{ + LLViewerInventoryItem * viitem = gInventory.getItem(payload["item_id"].asUUID()); + LLUUID dest_folder_id = payload["dest_folder_id"].asUUID(); if (viitem) { // when moving item directly into outbox create folder with that name if (dest_folder_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false)) { - dest_folder_id = gInventory.createNewCategory(dest_folder_id, LLFolderType::FT_NONE, viitem->getName()); - gInventory.notifyObservers(); + S32 operation_id = payload["operation_id"].asInteger(); + dest_folder_id = create_folder_in_outbox_for_item(viitem, dest_folder_id, operation_id); } LLUUID parent = viitem->getParentUUID(); @@ -555,12 +574,12 @@ void move_to_outbox_cb(const LLSD& notification, const LLSD& response) dest_folder_id, false); - LLUUID top_level_folder = notification["payload"]["top_level_folder"].asUUID(); + LLUUID top_level_folder = payload["top_level_folder"].asUUID(); if (top_level_folder != LLUUID::null) { LLViewerInventoryCategory* category; - + while (parent.notNull()) { LLInventoryModel::cat_array_t* cat_array; @@ -589,42 +608,75 @@ void move_to_outbox_cb(const LLSD& notification, const LLSD& response) } } + open_outbox(); } } - -void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LLUUID& top_level_folder) +void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LLUUID& top_level_folder, S32 operation_id) { - if (inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + // Collapse links directly to items/folders + LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item; + LLViewerInventoryCategory * linked_category = viewer_inv_item->getLinkedCategory(); + if (linked_category != NULL) { - // when moving item directly into outbox create folder with that name - if (dest_folder == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false)) + copy_folder_to_outbox(linked_category, dest_folder, top_level_folder, operation_id); + } + else + { + LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem(); + if (linked_item != NULL) { - dest_folder = gInventory.createNewCategory(dest_folder, LLFolderType::FT_NONE, inv_item->getName()); - gInventory.notifyObservers(); + inv_item = (LLInventoryItem *) linked_item; + } + + // Check for copy permissions + if (inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + // when moving item directly into outbox create folder with that name + if (dest_folder == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false)) + { + dest_folder = create_folder_in_outbox_for_item(inv_item, dest_folder, operation_id); + } + + copy_inventory_item(gAgent.getID(), + inv_item->getPermissions().getOwner(), + inv_item->getUUID(), + dest_folder, + inv_item->getName(), + LLPointer<LLInventoryCallback>(NULL)); + + open_outbox(); + } + else + { + LLSD payload; + payload["item_id"] = inv_item->getUUID(); + payload["dest_folder_id"] = dest_folder; + payload["top_level_folder"] = top_level_folder; + payload["operation_id"] = operation_id; + + LLMarketplaceInventoryNotifications::addNoCopyNotification(payload, move_to_outbox_cb_action); } - - copy_inventory_item( - gAgent.getID(), - inv_item->getPermissions().getOwner(), - inv_item->getUUID(), - dest_folder, - inv_item->getName(), - LLPointer<LLInventoryCallback>(NULL)); } - else - { - LLSD args; - args["ITEM_NAME"] = inv_item->getName(); - LLSD payload; - payload["item_id"] = inv_item->getUUID(); - payload["dest_folder_id"] = dest_folder; - payload["top_level_folder"] = top_level_folder; - LLNotificationsUtil::add("ConfirmNoCopyToOutbox", args, payload, boost::bind(&move_to_outbox_cb, _1, _2)); +} + +void move_item_within_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, S32 operation_id) +{ + // when moving item directly into outbox create folder with that name + if (dest_folder == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false)) + { + dest_folder = create_folder_in_outbox_for_item(inv_item, dest_folder, operation_id); } + + LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item; + + change_item_parent(&gInventory, + viewer_inv_item, + dest_folder, + false); } -void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder) +void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder, S32 operation_id) { LLUUID new_folder_id = gInventory.createNewCategory(dest_folder, LLFolderType::FT_NONE, inv_cat->getName()); gInventory.notifyObservers(); @@ -639,7 +691,7 @@ void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_fold for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++) { LLInventoryItem* item = *iter; - copy_item_to_outbox(item, new_folder_id, top_level_folder); + copy_item_to_outbox(item, new_folder_id, top_level_folder, operation_id); } LLInventoryModel::cat_array_t cat_array_copy = *cat_array; @@ -647,14 +699,10 @@ void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_fold for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) { LLViewerInventoryCategory* category = *iter; - copy_folder_to_outbox(category, new_folder_id, top_level_folder); + copy_folder_to_outbox(category, new_folder_id, top_level_folder, operation_id); } - // delete the folder if we have emptied it - //if (cat_array->empty() && item_array->empty()) - //{ - // remove_category(inventory_model, inv_cat->getUUID()); - //} + open_outbox(); } ///---------------------------------------------------------------------------- diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 7b452537f8..ce2b89b22e 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -74,9 +74,10 @@ void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::s // Generates a string containing the path to the item specified by item_id. void append_path(const LLUUID& id, std::string& path); -void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LLUUID& top_level_folder); +void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LLUUID& top_level_folder, S32 operation_id); +void move_item_within_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, S32 operation_id); -void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder); +void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder, S32 operation_id); /** Miscellaneous global functions ** ** diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 568ec4c5e2..a71b699fdd 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -217,6 +217,38 @@ const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(cons return NULL; } +// +// Search up the parent chain until we get to the specified parent, then return the first child category under it +// +const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LLUUID& master_parent_id, const LLUUID& obj_id) const +{ + if (master_parent_id == obj_id) + { + return NULL; + } + + const LLViewerInventoryCategory* current_cat = getCategory(obj_id); + + if (current_cat == NULL) + { + current_cat = getCategory(getObject(obj_id)->getParentUUID()); + } + + while (current_cat != NULL) + { + const LLUUID& current_parent_id = current_cat->getParentUUID(); + + if (current_parent_id == master_parent_id) + { + return current_cat; + } + + current_cat = getCategory(current_parent_id); + } + + return NULL; +} + // Get the object by id. Returns NULL if not found. LLInventoryObject* LLInventoryModel::getObject(const LLUUID& id) const { diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 19d1e4e01f..7cd85c4ab7 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -239,6 +239,9 @@ public: // Get whatever special folder this object is a child of, if any. const LLViewerInventoryCategory *getFirstNondefaultParent(const LLUUID& obj_id) const; + + // Get first descendant of the child object under the specified parent + const LLViewerInventoryCategory *getFirstDescendantOf(const LLUUID& master_parent_id, const LLUUID& obj_id) const; // Get the object by id. Returns NULL if not found. // NOTE: Use the pointer returned for read operations - do diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 80b53d5702..382569fa3a 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -132,6 +132,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) : mAcceptsDragAndDrop(p.accepts_drag_and_drop), mAllowMultiSelect(p.allow_multi_select), mShowItemLinkOverlays(p.show_item_link_overlays), + mShowEmptyMessage(p.show_empty_message), mShowLoadStatus(p.show_load_status), mViewsInitialized(false), mInvFVBridgeBuilder(NULL) @@ -617,6 +618,7 @@ LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool u p.listener = bridge; p.use_label_suffix = useLabelSuffix; p.allow_multiselect = mAllowMultiSelect; + p.show_empty_message = mShowEmptyMessage; p.show_load_status = mShowLoadStatus; return LLUICtrlFactory::create<LLFolderView>(p); @@ -1157,7 +1159,6 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L LLViewerInventoryCategory * cat = gInventory.getCategory(obj_id); bool in_inbox = false; - bool in_outbox = false; LLViewerInventoryCategory * parent_cat = NULL; @@ -1173,10 +1174,9 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L if (parent_cat) { in_inbox = (LLFolderType::FT_INBOX == parent_cat->getPreferredType()); - in_outbox = (LLFolderType::FT_OUTBOX == parent_cat->getPreferredType()); } - if (in_inbox || in_outbox) + if (in_inbox) { LLSidepanelInventory * sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); LLInventoryPanel * inventory_panel = NULL; @@ -1186,11 +1186,6 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L sidepanel_inventory->openInbox(); inventory_panel = sidepanel_inventory->getInboxPanel(); } - else - { - sidepanel_inventory->openOutbox(); - inventory_panel = sidepanel_inventory->getOutboxPanel(); - } if (inventory_panel) { diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 2a24327115..8279163762 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -84,6 +84,7 @@ public: Optional<Filter> filter; Optional<std::string> start_folder; Optional<bool> use_label_suffix; + Optional<bool> show_empty_message; Optional<bool> show_load_status; Optional<LLScrollContainer::Params> scroll; Optional<bool> accepts_drag_and_drop; @@ -96,6 +97,7 @@ public: filter("filter"), start_folder("start_folder"), use_label_suffix("use_label_suffix", true), + show_empty_message("show_empty_message", true), show_load_status("show_load_status"), scroll("scroll"), accepts_drag_and_drop("accepts_drag_and_drop") @@ -188,6 +190,7 @@ protected: BOOL mAcceptsDragAndDrop; BOOL mAllowMultiSelect; BOOL mShowItemLinkOverlays; // Shows link graphic over inventory item icons + BOOL mShowEmptyMessage; BOOL mShowLoadStatus; LLFolderView* mFolderRoot; diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp new file mode 100644 index 0000000000..a3f0a6062c --- /dev/null +++ b/indra/newview/llmarketplacefunctions.cpp @@ -0,0 +1,463 @@ +/** + * @file llmarketplacefunctions.cpp + * @brief Implementation of assorted functions related to the marketplace + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llmarketplacefunctions.h" + +#include "llagent.h" +#include "llhttpclient.h" +#include "lltrans.h" +#include "llviewercontrol.h" +#include "llviewermedia.h" +#include "llviewernetwork.h" + + +// +// Helpers +// + +static std::string getMarketplaceDomain() +{ + std::string domain = "secondlife.com"; + + if (!LLGridManager::getInstance()->isInProductionGrid()) + { + const std::string& grid_label = LLGridManager::getInstance()->getGridLabel(); + const std::string& grid_label_lower = utf8str_tolower(grid_label); + + if (grid_label_lower == "damballah") + { + domain = "secondlife-staging.com"; + } + else + { + domain = llformat("%s.lindenlab.com", grid_label_lower.c_str()); + } + } + + return domain; +} + +static std::string getMarketplaceURL(const std::string& urlStringName) +{ + LLStringUtil::format_map_t domain_arg; + domain_arg["[MARKETPLACE_DOMAIN_NAME]"] = getMarketplaceDomain(); + + std::string marketplace_url = LLTrans::getString(urlStringName, domain_arg); + + return marketplace_url; +} + +LLSD getMarketplaceStringSubstitutions() +{ + std::string marketplace_url = getMarketplaceURL("MarketplaceURL"); + std::string marketplace_url_create = getMarketplaceURL("MarketplaceURL_CreateStore"); + std::string marketplace_url_dashboard = getMarketplaceURL("MarketplaceURL_Dashboard"); + std::string marketplace_url_imports = getMarketplaceURL("MarketplaceURL_Imports"); + std::string marketplace_url_info = getMarketplaceURL("MarketplaceURL_LearnMore"); + + LLSD marketplace_sub_map; + + marketplace_sub_map["[MARKETPLACE_URL]"] = marketplace_url; + marketplace_sub_map["[MARKETPLACE_CREATE_STORE_URL]"] = marketplace_url_create; + marketplace_sub_map["[MARKETPLACE_LEARN_MORE_URL]"] = marketplace_url_info; + marketplace_sub_map["[MARKETPLACE_DASHBOARD_URL]"] = marketplace_url_dashboard; + marketplace_sub_map["[MARKETPLACE_IMPORTS_URL]"] = marketplace_url_imports; + + return marketplace_sub_map; +} + +namespace LLMarketplaceImport +{ + // Basic interface for this namespace + + bool hasSessionCookie(); + bool inProgress(); + bool resultPending(); + U32 getResultStatus(); + const LLSD& getResults(); + + bool establishMarketplaceSessionCookie(); + bool pollStatus(); + bool triggerImport(); + + // Internal state variables + + static std::string sMarketplaceCookie = ""; + static LLSD sImportId = LLSD::emptyMap(); + static bool sImportInProgress = false; + static bool sImportPostPending = false; + static bool sImportGetPending = false; + static U32 sImportResultStatus = 0; + static LLSD sImportResults = LLSD::emptyMap(); + + // Responders + + class LLImportPostResponder : public LLHTTPClient::Responder + { + public: + LLImportPostResponder() : LLCurl::Responder() {} + + void completed(U32 status, const std::string& reason, const LLSD& content) + { + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM POST status: " << status << llendl; + llinfos << " SLM POST reason: " << reason << llendl; + llinfos << " SLM POST content: " << content.asString() << llendl; + } + + if ((status == MarketplaceErrorCodes::IMPORT_REDIRECT) || + (status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) || + (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT)) + { + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM POST clearing marketplace cookie due to authentication failure or timeout" << llendl; + } + + sMarketplaceCookie.clear(); + } + + sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_DONE); + sImportPostPending = false; + sImportResultStatus = status; + sImportId = content; + } + }; + + class LLImportGetResponder : public LLHTTPClient::Responder + { + public: + LLImportGetResponder() : LLCurl::Responder() {} + + void completedHeader(U32 status, const std::string& reason, const LLSD& content) + { + const std::string& set_cookie_string = content["set-cookie"].asString(); + + if (!set_cookie_string.empty()) + { + sMarketplaceCookie = set_cookie_string; + } + } + + void completed(U32 status, const std::string& reason, const LLSD& content) + { + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM GET status: " << status << llendl; + llinfos << " SLM GET reason: " << reason << llendl; + llinfos << " SLM GET content: " << content.asString() << llendl; + } + + if ((status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) || + (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT)) + { + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM GET clearing marketplace cookie due to authentication failure or timeout" << llendl; + } + + sMarketplaceCookie.clear(); + } + + sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING); + sImportGetPending = false; + sImportResultStatus = status; + sImportResults = content; + } + }; + + // Basic API + + bool hasSessionCookie() + { + return !sMarketplaceCookie.empty(); + } + + bool inProgress() + { + return sImportInProgress; + } + + bool resultPending() + { + return (sImportPostPending || sImportGetPending); + } + + U32 getResultStatus() + { + return sImportResultStatus; + } + + const LLSD& getResults() + { + return sImportResults; + } + + static std::string getInventoryImportURL() + { + std::string url = getMarketplaceURL("MarketplaceURL"); + + url += "api/1/"; + url += gAgent.getID().getString(); + url += "/inventory/import/"; + + return url; + } + + bool establishMarketplaceSessionCookie() + { + if (hasSessionCookie()) + { + return false; + } + + sImportInProgress = true; + sImportGetPending = true; + + std::string url = getInventoryImportURL(); + + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM GET: " << url << llendl; + } + + LLHTTPClient::get(url, new LLImportGetResponder(), LLViewerMedia::getHeaders()); + + return true; + } + + bool pollStatus() + { + if (!hasSessionCookie()) + { + return false; + } + + sImportGetPending = true; + + std::string url = getInventoryImportURL(); + + url += sImportId.asString(); + + // Make the headers for the post + LLSD headers = LLSD::emptyMap(); + headers["Accept"] = "*/*"; + headers["Cookie"] = sMarketplaceCookie; + headers["Content-Type"] = "application/llsd+xml"; + headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent(); + + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM GET: " << url << llendl; + } + + LLHTTPClient::get(url, new LLImportGetResponder(), headers); + + return true; + } + + bool triggerImport() + { + if (!hasSessionCookie()) + { + return false; + } + + sImportId = LLSD::emptyMap(); + sImportInProgress = true; + sImportPostPending = true; + sImportResultStatus = MarketplaceErrorCodes::IMPORT_PROCESSING; + sImportResults = LLSD::emptyMap(); + + std::string url = getInventoryImportURL(); + + // Make the headers for the post + LLSD headers = LLSD::emptyMap(); + headers["Accept"] = "*/*"; + headers["Connection"] = "Keep-Alive"; + headers["Cookie"] = sMarketplaceCookie; + headers["Content-Type"] = "application/xml"; + headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent(); + + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM POST: " << url << llendl; + } + + LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers); + + return true; + } +} + + +// +// Interface class +// + + +//static +void LLMarketplaceInventoryImporter::update() +{ + if (instanceExists()) + { + LLMarketplaceInventoryImporter::instance().updateImport(); + } +} + +LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter() + : mAutoTriggerImport(false) + , mImportInProgress(false) + , mInitialized(false) + , mErrorInitSignal(NULL) + , mStatusChangedSignal(NULL) + , mStatusReportSignal(NULL) +{ +} + +boost::signals2::connection LLMarketplaceInventoryImporter::setInitializationErrorCallback(const status_report_signal_t::slot_type& cb) +{ + if (mErrorInitSignal == NULL) + { + mErrorInitSignal = new status_report_signal_t(); + } + + return mErrorInitSignal->connect(cb); +} + +boost::signals2::connection LLMarketplaceInventoryImporter::setStatusChangedCallback(const status_changed_signal_t::slot_type& cb) +{ + if (mStatusChangedSignal == NULL) + { + mStatusChangedSignal = new status_changed_signal_t(); + } + + return mStatusChangedSignal->connect(cb); +} + +boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallback(const status_report_signal_t::slot_type& cb) +{ + if (mStatusReportSignal == NULL) + { + mStatusReportSignal = new status_report_signal_t(); + } + + return mStatusReportSignal->connect(cb); +} + +void LLMarketplaceInventoryImporter::initialize() +{ + llassert(!mInitialized); + + if (!LLMarketplaceImport::hasSessionCookie()) + { + LLMarketplaceImport::establishMarketplaceSessionCookie(); + } +} + +void LLMarketplaceInventoryImporter::reinitializeAndTriggerImport() +{ + mInitialized = false; + + initialize(); + + mAutoTriggerImport = true; +} + +bool LLMarketplaceInventoryImporter::triggerImport() +{ + const bool import_triggered = LLMarketplaceImport::triggerImport(); + + if (!import_triggered) + { + reinitializeAndTriggerImport(); + } + + return import_triggered; +} + +void LLMarketplaceInventoryImporter::updateImport() +{ + const bool in_progress = LLMarketplaceImport::inProgress(); + + if (in_progress && !LLMarketplaceImport::resultPending()) + { + const bool polling_status = LLMarketplaceImport::pollStatus(); + + if (!polling_status) + { + reinitializeAndTriggerImport(); + } + } + + if (mImportInProgress != in_progress) + { + mImportInProgress = in_progress; + + // If we are no longer in progress + if (!mImportInProgress) + { + if (mInitialized) + { + // Report results + if (mStatusReportSignal) + { + (*mStatusReportSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults()); + } + } + else + { + // Look for results success + mInitialized = LLMarketplaceImport::hasSessionCookie(); + + if (mInitialized) + { + // Follow up with auto trigger of import + if (mAutoTriggerImport) + { + mAutoTriggerImport = false; + + mImportInProgress = triggerImport(); + } + } + else if (mErrorInitSignal) + { + (*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults()); + } + } + } + + // Make sure we trigger the status change with the final state (in case of auto trigger after initialize) + if (mStatusChangedSignal) + { + (*mStatusChangedSignal)(mImportInProgress); + } + } +} + diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h new file mode 100644 index 0000000000..4b8f7a1ac7 --- /dev/null +++ b/indra/newview/llmarketplacefunctions.h @@ -0,0 +1,94 @@ +/** + * @file llmarketplacefunctions.h + * @brief Miscellaneous marketplace-related functions and classes + * class definition + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLMARKETPLACEFUNCTIONS_H +#define LL_LLMARKETPLACEFUNCTIONS_H + + +#include <llsd.h> +#include <boost/function.hpp> +#include <boost/signals2.hpp> + +#include "llsingleton.h" +#include "llstring.h" + + +LLSD getMarketplaceStringSubstitutions(); + + +namespace MarketplaceErrorCodes +{ + enum eCode + { + IMPORT_DONE = 200, + IMPORT_PROCESSING = 202, + IMPORT_REDIRECT = 302, + IMPORT_AUTHENTICATION_ERROR = 401, + IMPORT_DONE_WITH_ERRORS = 409, + IMPORT_JOB_FAILED = 410, + IMPORT_JOB_TIMEOUT = 499, + }; +} + + +class LLMarketplaceInventoryImporter + : public LLSingleton<LLMarketplaceInventoryImporter> +{ +public: + static void update(); + + LLMarketplaceInventoryImporter(); + + typedef boost::signals2::signal<void (bool)> status_changed_signal_t; + typedef boost::signals2::signal<void (U32, const LLSD&)> status_report_signal_t; + + boost::signals2::connection setInitializationErrorCallback(const status_report_signal_t::slot_type& cb); + boost::signals2::connection setStatusChangedCallback(const status_changed_signal_t::slot_type& cb); + boost::signals2::connection setStatusReportCallback(const status_report_signal_t::slot_type& cb); + + void initialize(); + bool triggerImport(); + bool isImportInProgress() const { return mImportInProgress; } + +protected: + void reinitializeAndTriggerImport(); + void updateImport(); + +private: + bool mAutoTriggerImport; + bool mImportInProgress; + bool mInitialized; + + status_report_signal_t * mErrorInitSignal; + status_changed_signal_t * mStatusChangedSignal; + status_report_signal_t * mStatusReportSignal; +}; + + + +#endif // LL_LLMARKETPLACEFUNCTIONS_H + diff --git a/indra/newview/llmarketplacenotifications.cpp b/indra/newview/llmarketplacenotifications.cpp new file mode 100644 index 0000000000..0886f9a990 --- /dev/null +++ b/indra/newview/llmarketplacenotifications.cpp @@ -0,0 +1,90 @@ +/** + * @file llmarketplacenotifications.cpp + * @brief Handler for notifications related to marketplace file I/O + * class definition + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Precompiled header +#include "llviewerprecompiledheaders.h" + +#include "llmarketplacenotifications.h" +#include "llnotificationsutil.h" + +#include "llerror.h" + +#include <boost/foreach.hpp> +#include <boost/signals2.hpp> + + +namespace LLMarketplaceInventoryNotifications +{ + typedef boost::signals2::signal<void (const LLSD& param)> no_copy_payload_cb_signal_t; + + static no_copy_payload_cb_signal_t* no_copy_cb_action = NULL; + static bool no_copy_notify_active = false; + static std::list<LLSD> no_copy_payloads; + + void notifyNoCopyCallback(const LLSD& notification, const LLSD& response) + { + const S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + + if (option == 0) + { + llassert(!no_copy_payloads.empty()); + llassert(no_copy_cb_action != NULL); + + BOOST_FOREACH(const LLSD& payload, no_copy_payloads) + { + (*no_copy_cb_action)(payload); + } + } + + delete no_copy_cb_action; + no_copy_cb_action = NULL; + + no_copy_notify_active = false; + no_copy_payloads.clear(); + } + + void update() + { + if (!no_copy_notify_active && !no_copy_payloads.empty()) + { + no_copy_notify_active = true; + + LLNotificationsUtil::add("ConfirmNoCopyToOutbox", LLSD(), LLSD(), boost::bind(¬ifyNoCopyCallback, _1, _2)); + } + } + + void addNoCopyNotification(const LLSD& payload, const NoCopyCallbackFunction& cb) + { + if (no_copy_cb_action == NULL) + { + no_copy_cb_action = new no_copy_payload_cb_signal_t; + no_copy_cb_action->connect(boost::bind(cb, _1)); + } + + no_copy_payloads.push_back(payload); + } +} diff --git a/indra/newview/llmarketplacenotifications.h b/indra/newview/llmarketplacenotifications.h new file mode 100644 index 0000000000..83a4e163c7 --- /dev/null +++ b/indra/newview/llmarketplacenotifications.h @@ -0,0 +1,57 @@ +/** + * @file llmarketplacenotifications.h + * @brief Handler for notifications related to marketplace file I/O + * class definition + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLMARKETPLACENOTIFICATIONS_H +#define LL_LLMARKETPLACENOTIFICATIONS_H + + +#include <llsd.h> +#include <boost/function.hpp> + + +// +// This is a set of helper functions to handle a unique notification with multiple +// payloads, helpful when dragging and dropping items to the merchant outbox that +// trigger notifications that can potentially interfere with the current drag and +// drop operation. +// +// Notification payloads are cached locally when initiated, the notification itself +// is triggered on the following frame during the call to "update" and then the +// response is triggered once per payload. +// + +namespace LLMarketplaceInventoryNotifications +{ + void update(); + + typedef boost::function<void (const LLSD&)> NoCopyCallbackFunction; + + void addNoCopyNotification(const LLSD& payload, const NoCopyCallbackFunction& cb); +}; + + +#endif // LL_LLMARKETPLACENOTIFICATIONS_H diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index 28a69f2373..23dbb6b047 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -283,9 +283,17 @@ class LLBrowserNotification : public LLSingleton<LLBrowserNotification> { public: virtual bool processNotification(const LLSD& notify); +}; +/** + * Handler for outbox notifications + */ +class LLOutboxNotification : public LLSingleton<LLOutboxNotification> +{ +public: + virtual bool processNotification(const LLSD& notify); }; - + class LLHandlerUtil { public: diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp index 6988227128..6105eff8ea 100644 --- a/indra/newview/llnotificationmanager.cpp +++ b/indra/newview/llnotificationmanager.cpp @@ -62,6 +62,7 @@ void LLNotificationManager::init() LLNotificationChannel::buildChannel("Offer", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "offer")); LLNotificationChannel::buildChannel("Hints", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "hint")); LLNotificationChannel::buildChannel("Browser", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "browser")); + LLNotificationChannel::buildChannel("Outbox", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "outbox")); LLNotifications::instance().getChannel("Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); LLNotifications::instance().getChannel("NotificationTips")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); @@ -72,6 +73,7 @@ void LLNotificationManager::init() LLNotifications::instance().getChannel("Offer")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); LLNotifications::instance().getChannel("Hints")->connectChanged(boost::bind(&LLHintHandler::processNotification, LLHintHandler::getInstance(), _1)); LLNotifications::instance().getChannel("Browser")->connectChanged(boost::bind(&LLBrowserNotification::processNotification, LLBrowserNotification::getInstance(), _1)); + LLNotifications::instance().getChannel("Outbox")->connectChanged(boost::bind(&LLOutboxNotification::processNotification, LLOutboxNotification::getInstance(), _1)); mNotifyHandlers["notify"] = boost::shared_ptr<LLEventHandler>(new LLScriptHandler(NT_NOTIFY, LLSD())); mNotifyHandlers["notifytip"] = boost::shared_ptr<LLEventHandler>(new LLTipHandler(NT_NOTIFY, LLSD())); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 68ef13cd68..374afb90be 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -593,7 +593,7 @@ void LLPanelMainInventory::onFocusReceived() return; } - sidepanel_inventory->clearSelections(false, true, true); + sidepanel_inventory->clearSelections(false, true); } void LLPanelMainInventory::setFilterTextFromFilter() diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp index 7cb4bbf891..66c9c323cb 100644 --- a/indra/newview/llpanelmarketplaceinbox.cpp +++ b/indra/newview/llpanelmarketplaceinbox.cpp @@ -48,6 +48,8 @@ const LLPanelMarketplaceInbox::Params& LLPanelMarketplaceInbox::getDefaultParams // protected LLPanelMarketplaceInbox::LLPanelMarketplaceInbox(const Params& p) : LLPanel(p) + , mFreshCountCtrl(NULL) + , mInboxButton(NULL) , mInventoryPanel(NULL) { } @@ -60,6 +62,9 @@ LLPanelMarketplaceInbox::~LLPanelMarketplaceInbox() BOOL LLPanelMarketplaceInbox::postBuild() { LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceInbox::onFocusReceived, this)); + + mFreshCountCtrl = getChild<LLUICtrl>("inbox_fresh_new_count"); + mInboxButton = getChild<LLButton>("inbox_btn"); return TRUE; } @@ -109,7 +114,7 @@ void LLPanelMarketplaceInbox::onFocusReceived() LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); if (sidepanel_inventory) { - sidepanel_inventory->clearSelections(true, false, true); + sidepanel_inventory->clearSelections(true, false); } gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected()); @@ -216,7 +221,7 @@ void LLPanelMarketplaceInbox::draw() { U32 item_count = getTotalItemCount(); - LLView * fresh_new_count_view = getChildView("inbox_fresh_new_count"); + llassert(mFreshCountCtrl != NULL); if (item_count > 0) { @@ -224,26 +229,26 @@ void LLPanelMarketplaceInbox::draw() LLStringUtil::format_map_t args; args["[NUM]"] = item_count_str; - getChild<LLButton>("inbox_btn")->setLabel(getString("InboxLabelWithArg", args)); + mInboxButton->setLabel(getString("InboxLabelWithArg", args)); #if SUPPORTING_FRESH_ITEM_COUNT // set green text to fresh item count U32 fresh_item_count = getFreshItemCount(); - fresh_new_count_view->setVisible((fresh_item_count > 0)); + mFreshCountCtrl->setVisible((fresh_item_count > 0)); if (fresh_item_count > 0) { - getChild<LLUICtrl>("inbox_fresh_new_count")->setTextArg("[NUM]", llformat("%d", fresh_item_count)); + mFreshCountCtrl->setTextArg("[NUM]", llformat("%d", fresh_item_count)); } #else - fresh_new_count_view->setVisible(FALSE); + mFreshCountCtrl->setVisible(FALSE); #endif } else { - getChild<LLButton>("inbox_btn")->setLabel(getString("InboxLabelNoArg")); + mInboxButton->setLabel(getString("InboxLabelNoArg")); - fresh_new_count_view->setVisible(FALSE); + mFreshCountCtrl->setVisible(FALSE); } LLPanel::draw(); diff --git a/indra/newview/llpanelmarketplaceinbox.h b/indra/newview/llpanelmarketplaceinbox.h index 3531518e51..9eb74581a2 100644 --- a/indra/newview/llpanelmarketplaceinbox.h +++ b/indra/newview/llpanelmarketplaceinbox.h @@ -29,7 +29,9 @@ #include "llpanel.h" +class LLButton; class LLInventoryPanel; +class LLUICtrl; class LLPanelMarketplaceInbox : public LLPanel { @@ -66,9 +68,10 @@ private: void onFocusReceived(); private: - LLInventoryPanel* mInventoryPanel; + LLUICtrl * mFreshCountCtrl; + LLButton * mInboxButton; + LLInventoryPanel * mInventoryPanel; }; #endif //LL_LLPANELMARKETPLACEINBOX_H - diff --git a/indra/newview/llpanelmarketplaceoutbox.cpp b/indra/newview/llpanelmarketplaceoutbox.cpp deleted file mode 100644 index 12960fd0d6..0000000000 --- a/indra/newview/llpanelmarketplaceoutbox.cpp +++ /dev/null @@ -1,363 +0,0 @@ -/** - * @file llpanelmarketplaceoutbox.cpp - * @brief Panel for marketplace outbox - * -* $LicenseInfo:firstyear=2011&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llpanelmarketplaceoutbox.h" -#include "llpanelmarketplaceoutboxinventory.h" - -#include "llappviewer.h" -#include "llbutton.h" -#include "llcoros.h" -#include "lleventcoro.h" -#include "llfloatersidepanelcontainer.h" -#include "llinventorypanel.h" -#include "llloadingindicator.h" -#include "llnotificationsutil.h" -#include "llpanelmarketplaceinbox.h" -#include "llsdutil.h" -#include "llsidepanelinventory.h" -#include "lltimer.h" -#include "llviewernetwork.h" -#include "llagent.h" -#include "llviewermedia.h" -#include "llfolderview.h" -#include "llinventoryfunctions.h" - -static LLRegisterPanelClassWrapper<LLPanelMarketplaceOutbox> t_panel_marketplace_outbox("panel_marketplace_outbox"); - -const LLPanelMarketplaceOutbox::Params& LLPanelMarketplaceOutbox::getDefaultParams() -{ - return LLUICtrlFactory::getDefaultParams<LLPanelMarketplaceOutbox>(); -} - -// protected -LLPanelMarketplaceOutbox::LLPanelMarketplaceOutbox(const Params& p) - : LLPanel(p) - , mInventoryPanel(NULL) - , mSyncButton(NULL) - , mSyncIndicator(NULL) - , mSyncInProgress(false) -{ -} - -LLPanelMarketplaceOutbox::~LLPanelMarketplaceOutbox() -{ -} - -// virtual -BOOL LLPanelMarketplaceOutbox::postBuild() -{ - LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLPanelMarketplaceOutbox::handleLoginComplete, this)); - - LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceOutbox::onFocusReceived, this)); - - return TRUE; -} - -void LLPanelMarketplaceOutbox::handleLoginComplete() -{ - mSyncButton = getChild<LLButton>("outbox_sync_btn"); - mSyncButton->setCommitCallback(boost::bind(&LLPanelMarketplaceOutbox::onSyncButtonClicked, this)); - mSyncButton->setEnabled(!isOutboxEmpty()); - - mSyncIndicator = getChild<LLLoadingIndicator>("outbox_sync_indicator"); -} - -void LLPanelMarketplaceOutbox::onFocusReceived() -{ - LLSidepanelInventory * sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); - if (sidepanel_inventory) - { - sidepanel_inventory->clearSelections(true, true, false); - } -} - -void LLPanelMarketplaceOutbox::onSelectionChange() -{ - LLSidepanelInventory* sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); - if (sidepanel_inventory) - { - sidepanel_inventory->updateVerbs(); - } -} - -LLInventoryPanel * LLPanelMarketplaceOutbox::setupInventoryPanel() -{ - LLView * outbox_inventory_placeholder = getChild<LLView>("outbox_inventory_placeholder_panel"); - LLView * outbox_inventory_parent = outbox_inventory_placeholder->getParent(); - - mInventoryPanel = - LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml", - outbox_inventory_parent, - LLInventoryPanel::child_registry_t::instance()); - - llassert(mInventoryPanel); - - // Reshape the inventory to the proper size - LLRect inventory_placeholder_rect = outbox_inventory_placeholder->getRect(); - mInventoryPanel->setShape(inventory_placeholder_rect); - - // Set the sort order newest to oldest - mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE); - mInventoryPanel->getFilter()->markDefault(); - - // Set selection callback for proper update of inventory status buttons - mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceOutbox::onSelectionChange, this)); - - // Set up the note to display when the outbox is empty - mInventoryPanel->getFilter()->setEmptyLookupMessage("InventoryOutboxNoItems"); - - // Hide the placeholder text - outbox_inventory_placeholder->setVisible(FALSE); - - return mInventoryPanel; -} - -BOOL LLPanelMarketplaceOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); - - if (!handled && mInventoryPanel && mInventoryPanel->getRootFolder()) - { - handled = mInventoryPanel->getRootFolder()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg); - - if (handled) - { - mInventoryPanel->getRootFolder()->setDragAndDropThisFrame(); - } - } - - return handled; -} - -bool LLPanelMarketplaceOutbox::isOutboxEmpty() const -{ - return (getTotalItemCount() == 0); -} - -bool LLPanelMarketplaceOutbox::isSyncInProgress() const -{ - return mSyncInProgress; -} - - -std::string gTimeDelayDebugFunc = ""; - -void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel) -{ - waitForEventOn(self, "mainloop"); - - LLTimer delayTimer; - delayTimer.reset(); - delayTimer.setTimerExpirySec(5.0f); - - while (!delayTimer.hasExpired()) - { - waitForEventOn(self, "mainloop"); - } - - outboxPanel->onSyncComplete(true, LLSD::emptyMap()); - - gTimeDelayDebugFunc = ""; -} - - -class LLInventorySyncResponder : public LLHTTPClient::Responder -{ -public: - LLInventorySyncResponder(LLPanelMarketplaceOutbox * outboxPanel) - : LLCurl::Responder() - , mOutboxPanel(outboxPanel) - { - } - - void completed(U32 status, const std::string& reason, const LLSD& content) - { - llinfos << "inventory_import complete status: " << status << ", reason: " << reason << llendl; - - if (isGoodStatus(status)) - { - // Complete success - llinfos << "success" << llendl; - } - else - { - llwarns << "failed" << llendl; - } - - mOutboxPanel->onSyncComplete(isGoodStatus(status), content); - } - -private: - LLPanelMarketplaceOutbox * mOutboxPanel; -}; - -void LLPanelMarketplaceOutbox::onSyncButtonClicked() -{ - // Get the sync animation going - mSyncInProgress = true; - updateSyncButtonStatus(); - - // Make the url for the inventory import request - std::string url = "https://marketplace.secondlife.com/"; - - if (!LLGridManager::getInstance()->isInProductionGrid()) - { - std::string gridLabel = LLGridManager::getInstance()->getGridLabel(); - url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str()); - - // TEMP for Jim's pdp - //url = "http://pdp24.lindenlab.com:3000/"; - } - - url += "api/1/users/"; - url += gAgent.getID().getString(); - url += "/inventory_import"; - - llinfos << "http get: " << url << llendl; - LLHTTPClient::get(url, new LLInventorySyncResponder(this), LLViewerMedia::getHeaders()); - - // Set a timer (for testing only) - //gTimeDelayDebugFunc = LLCoros::instance().launch("LLPanelMarketplaceOutbox timeDelay", boost::bind(&timeDelay, _1, this)); -} - -void LLPanelMarketplaceOutbox::onSyncComplete(bool goodStatus, const LLSD& content) -{ - mSyncInProgress = false; - updateSyncButtonStatus(); - - const LLSD& errors_list = content["errors"]; - - if (goodStatus && (errors_list.size() == 0)) - { - LLNotificationsUtil::add("OutboxUploadComplete", LLSD::emptyMap(), LLSD::emptyMap()); - } - else - { - LLNotificationsUtil::add("OutboxUploadHadErrors", LLSD::emptyMap(), LLSD::emptyMap()); - } - - llinfos << "Marketplace upload llsd:" << llendl; - llinfos << ll_pretty_print_sd(content) << llendl; - llinfos << llendl; - - const LLSD& imported_list = content["imported"]; - LLSD::array_const_iterator it = imported_list.beginArray(); - for ( ; it != imported_list.endArray(); ++it) - { - LLUUID imported_folder = (*it).asUUID(); - llinfos << "Successfully uploaded folder " << imported_folder.asString() << " to marketplace." << llendl; - } - - for (it = errors_list.beginArray(); it != errors_list.endArray(); ++it) - { - const LLSD& item_error_map = (*it); - - LLUUID error_folder = item_error_map["folder_id"].asUUID(); - const std::string& error_string = item_error_map["identifier"].asString(); - LLUUID error_item = item_error_map["item_id"].asUUID(); - const std::string& error_item_name = item_error_map["item_name"].asString(); - const std::string& error_message = item_error_map["message"].asString(); - - llinfos << "Error item " << error_folder.asString() << ", " << error_string << ", " - << error_item.asString() << ", " << error_item_name << ", " << error_message << llendl; - - LLFolderViewFolder * item_folder = mInventoryPanel->getRootFolder()->getFolderByID(error_folder); - LLOutboxFolderViewFolder * outbox_item_folder = dynamic_cast<LLOutboxFolderViewFolder *>(item_folder); - - llassert(outbox_item_folder); - - outbox_item_folder->setErrorString(error_string); - } -} - -void LLPanelMarketplaceOutbox::updateSyncButtonStatus() -{ - if (isSyncInProgress()) - { - mSyncButton->setVisible(false); - - mSyncIndicator->setVisible(true); - mSyncIndicator->reset(); - mSyncIndicator->start(); - } - else - { - mSyncIndicator->stop(); - mSyncIndicator->setVisible(false); - - mSyncButton->setVisible(true); - mSyncButton->setEnabled(!isOutboxEmpty()); - } -} - -U32 LLPanelMarketplaceOutbox::getTotalItemCount() const -{ - U32 item_count = 0; - - if (mInventoryPanel) - { - const LLFolderViewFolder * outbox_folder = mInventoryPanel->getRootFolder(); - - if (outbox_folder) - { - item_count += outbox_folder->getFoldersCount(); - } - } - - return item_count; -} - -void LLPanelMarketplaceOutbox::draw() -{ - const U32 item_count = getTotalItemCount(); - const bool not_empty = (item_count > 0); - - if (not_empty) - { - std::string item_count_str = llformat("%d", item_count); - - LLStringUtil::format_map_t args; - args["[NUM]"] = item_count_str; - getChild<LLButton>("outbox_btn")->setLabel(getString("OutboxLabelWithArg", args)); - } - else - { - getChild<LLButton>("outbox_btn")->setLabel(getString("OutboxLabelNoArg")); - } - - if (!isSyncInProgress()) - { - mSyncButton->setEnabled(not_empty); - } - - LLPanel::draw(); -} diff --git a/indra/newview/llpanelmarketplaceoutbox.h b/indra/newview/llpanelmarketplaceoutbox.h deleted file mode 100644 index c6b4a5abe2..0000000000 --- a/indra/newview/llpanelmarketplaceoutbox.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file llpanelmarketplaceoutbox.h - * @brief Panel for marketplace outbox - * -* $LicenseInfo:firstyear=2011&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLPANELMARKETPLACEOUTBOX_H -#define LL_LLPANELMARKETPLACEOUTBOX_H - -#include "llpanel.h" - - -class LLButton; -class LLInventoryPanel; -class LLLoadingIndicator; - - -class LLPanelMarketplaceOutbox : public LLPanel -{ -public: - - struct Params : public LLInitParam::Block<Params, LLPanel::Params> - {}; - - LOG_CLASS(LLPanelMarketplaceOutbox); - - // RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8 - static const LLPanelMarketplaceOutbox::Params& getDefaultParams(); - - LLPanelMarketplaceOutbox(const Params& p = getDefaultParams()); - ~LLPanelMarketplaceOutbox(); - - /*virtual*/ BOOL postBuild(); - - /*virtual*/ void draw(); - - LLInventoryPanel * setupInventoryPanel(); - - U32 getTotalItemCount() const; - - bool isOutboxEmpty() const; - bool isSyncInProgress() const; - - void onSyncComplete(bool goodStatus, const LLSD& content); - - /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg); - -protected: - void onSyncButtonClicked(); - void updateSyncButtonStatus(); - - void handleLoginComplete(); - void onFocusReceived(); - void onSelectionChange(); - -private: - LLInventoryPanel * mInventoryPanel; - - LLButton * mSyncButton; - LLLoadingIndicator * mSyncIndicator; - bool mSyncInProgress; -}; - - -#endif //LL_LLPANELMARKETPLACEOUTBOX_H - diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.cpp b/indra/newview/llpanelmarketplaceoutboxinventory.cpp index ed1206aec8..ff62cb23db 100644 --- a/indra/newview/llpanelmarketplaceoutboxinventory.cpp +++ b/indra/newview/llpanelmarketplaceoutboxinventory.cpp @@ -47,50 +47,6 @@ static LLDefaultChildRegistry::Register<LLOutboxFolderViewFolder> r2("outbox_fol // -// Marketplace errors -// - -enum -{ - MKTERR_NONE = 0, - - MKTERR_NOT_MERCHANT, - MKTERR_FOLDER_EMPTY, - MKTERR_UNASSOCIATED_PRODUCTS, - MKTERR_OBJECT_LIMIT, - MKTERR_FOLDER_DEPTH, - MKTERR_UNSELLABLE_ITEM, - MKTERR_INTERNAL_IMPORT, - - MKTERR_COUNT -}; - -static const std::string MARKETPLACE_ERROR_STRINGS[MKTERR_COUNT] = -{ - "NO_ERROR", - "NOT_MERCHANT_ERROR", - "FOLDER_EMPTY_ERROR", - "UNASSOCIATED_PRODUCTS_ERROR", - "OBJECT_LIMIT_ERROR", - "FOLDER_DEPTH_ERROR", - "UNSELLABLE_ITEM_FOUND", - "INTERNAL_IMPORT_ERROR", -}; - -static const std::string MARKETPLACE_ERROR_NAMES[MKTERR_COUNT] = -{ - "Marketplace Error None", - "Marketplace Error Not Merchant", - "Marketplace Error Empty Folder", - "Marketplace Error Unassociated Products", - "Marketplace Error Object Limit", - "Marketplace Error Folder Depth", - "Marketplace Error Unsellable Item", - "Marketplace Error Internal Import", -}; - - -// // LLOutboxInventoryPanel Implementation // @@ -111,37 +67,6 @@ void LLOutboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& par LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); - // leslie -- temporary HACK to work around sim not creating outbox with proper system folder type - if (root_id.isNull()) - { - std::string start_folder_name(params.start_folder()); - - LLInventoryModel::cat_array_t* cats; - LLInventoryModel::item_array_t* items; - - gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), cats, items); - - if (cats) - { - for (LLInventoryModel::cat_array_t::const_iterator cat_it = cats->begin(); cat_it != cats->end(); ++cat_it) - { - LLInventoryCategory* cat = *cat_it; - - if (cat->getName() == start_folder_name) - { - root_id = cat->getUUID(); - break; - } - } - } - - if (root_id == LLUUID::null) - { - llwarns << "No category found that matches outbox inventory panel start_folder: " << start_folder_name << llendl; - } - } - // leslie -- end temporary HACK - if (root_id == LLUUID::null) { llwarns << "Outbox inventory panel has no root folder!" << llendl; @@ -206,66 +131,26 @@ LLFolderViewItem * LLOutboxInventoryPanel::createFolderViewItem(LLInvFVBridge * LLOutboxFolderViewFolder::LLOutboxFolderViewFolder(const Params& p) : LLFolderViewFolder(p) - , LLBadgeOwner(getHandle()) - , mError(0) -{ - initBadgeParams(p.error_badge()); -} - -LLOutboxFolderViewFolder::~LLOutboxFolderViewFolder() { } -// virtual -void LLOutboxFolderViewFolder::draw() -{ - if (!badgeHasParent()) - { - addBadgeToParentPanel(); - } - - setBadgeVisibility(hasError()); - - LLFolderViewFolder::draw(); -} +// +// LLOutboxFolderViewItem Implementation +// -void LLOutboxFolderViewFolder::setErrorString(const std::string& errorString) +LLOutboxFolderViewItem::LLOutboxFolderViewItem(const Params& p) + : LLFolderViewItem(p) { - S32 error_code = MKTERR_NONE; - - for (S32 i = 1; i < MKTERR_COUNT; ++i) - { - if (MARKETPLACE_ERROR_STRINGS[i] == errorString) - { - error_code = i; - break; - } - } - - setError(error_code); } -void LLOutboxFolderViewFolder::setError(S32 errorCode) +BOOL LLOutboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask) { - mError = errorCode; - - if (hasError()) - { - setToolTip(LLTrans::getString(MARKETPLACE_ERROR_NAMES[mError])); - } - else - { - setToolTip(LLStringExplicit("")); - } + return TRUE; } -// -// LLOutboxFolderViewItem Implementation -// - -BOOL LLOutboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask) +void LLOutboxFolderViewItem::openItem() { - return TRUE; + // Intentionally do nothing to block attaching items from the outbox } // eof diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.h b/indra/newview/llpanelmarketplaceoutboxinventory.h index 346680a79d..a6c522b7c2 100644 --- a/indra/newview/llpanelmarketplaceoutboxinventory.h +++ b/indra/newview/llpanelmarketplaceoutboxinventory.h @@ -28,7 +28,6 @@ #define LL_OUTBOXINVENTORYPANEL_H -#include "llbadgeowner.h" #include "llinventorypanel.h" #include "llfolderviewitem.h" @@ -53,44 +52,26 @@ public: }; -class LLOutboxFolderViewFolder : public LLFolderViewFolder, public LLBadgeOwner +class LLOutboxFolderViewFolder : public LLFolderViewFolder { public: struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params> { - Optional<LLBadge::Params> error_badge; - - Params() - : error_badge("error_badge") - { - } + Params() {} }; LLOutboxFolderViewFolder(const Params& p); - ~LLOutboxFolderViewFolder(); - - void draw(); - - void setErrorString(const std::string& errorString); - void setError(S32 errorCode); - - bool hasError() const { return (mError != 0); } - -protected: - S32 mError; }; class LLOutboxFolderViewItem : public LLFolderViewItem { public: - LLOutboxFolderViewItem(const Params& p) - : LLFolderViewItem(p) - { - } + LLOutboxFolderViewItem(const Params& p); // virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + void openItem(); }; diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 9d069c3996..038b18afbd 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -47,7 +47,6 @@ #include "lloutfitobserver.h" #include "llpanelmaininventory.h" #include "llpanelmarketplaceinbox.h" -#include "llpanelmarketplaceoutbox.h" #include "llselectmgr.h" #include "llsidepaneliteminfo.h" #include "llsidepaneltaskinfo.h" @@ -68,35 +67,22 @@ static LLRegisterPanelClassWrapper<LLSidepanelInventory> t_inventory("sidepanel_ // No longer want the inbox panel to auto-expand since it creates issues with the "new" tag time stamp #define AUTO_EXPAND_INBOX 0 -// Temporarily disabling the outbox until we straighten out the API -#define ENABLE_MERCHANT_OUTBOX_PANEL 0 // keep in sync with ENABLE_INVENTORY_DISPLAY_OUTBOX, ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU - static const char * const INBOX_BUTTON_NAME = "inbox_btn"; -static const char * const OUTBOX_BUTTON_NAME = "outbox_btn"; - static const char * const INBOX_LAYOUT_PANEL_NAME = "inbox_layout_panel"; -static const char * const OUTBOX_LAYOUT_PANEL_NAME = "outbox_layout_panel"; - -static const char * const INBOX_OUTBOX_LAYOUT_PANEL_NAME = "inbox_outbox_layout_panel"; static const char * const MAIN_INVENTORY_LAYOUT_PANEL_NAME = "main_inventory_layout_panel"; -static const char * const INBOX_INVENTORY_PANEL = "inventory_inbox"; -static const char * const OUTBOX_INVENTORY_PANEL = "inventory_outbox"; - -static const char * const INBOX_OUTBOX_LAYOUT_STACK_NAME = "inbox_outbox_layout_stack"; static const char * const INVENTORY_LAYOUT_STACK_NAME = "inventory_layout_stack"; static const char * const MARKETPLACE_INBOX_PANEL = "marketplace_inbox"; -static const char * const MARKETPLACE_OUTBOX_PANEL = "marketplace_outbox"; // // Helpers // -class LLInboxOutboxAddedObserver : public LLInventoryCategoryAddedObserver +class LLInboxAddedObserver : public LLInventoryCategoryAddedObserver { public: - LLInboxOutboxAddedObserver(LLSidepanelInventory * sidepanelInventory) + LLInboxAddedObserver(LLSidepanelInventory * sidepanelInventory) : LLInventoryCategoryAddedObserver() , mSidepanelInventory(sidepanelInventory) { @@ -116,10 +102,6 @@ public: mSidepanelInventory->enableInbox(true); mSidepanelInventory->observeInboxModifications(added_category->getUUID()); break; - case LLFolderType::FT_OUTBOX: - mSidepanelInventory->enableOutbox(true); - mSidepanelInventory->observeOutboxModifications(added_category->getUUID()); - break; default: break; } @@ -138,12 +120,10 @@ LLSidepanelInventory::LLSidepanelInventory() : LLPanel() , mItemPanel(NULL) , mInventoryPanelInbox(NULL) - , mInventoryPanelOutbox(NULL) , mPanelMainInventory(NULL) , mInboxEnabled(false) - , mOutboxEnabled(false) , mCategoriesObserver(NULL) - , mInboxOutboxAddedObserver(NULL) + , mInboxAddedObserver(NULL) { //buildFromFile( "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() } @@ -156,11 +136,11 @@ LLSidepanelInventory::~LLSidepanelInventory() } delete mCategoriesObserver; - if (mInboxOutboxAddedObserver && gInventory.containsObserver(mInboxOutboxAddedObserver)) + if (mInboxAddedObserver && gInventory.containsObserver(mInboxAddedObserver)) { - gInventory.removeObserver(mInboxOutboxAddedObserver); + gInventory.removeObserver(mInboxAddedObserver); } - delete mInboxOutboxAddedObserver; + delete mInboxAddedObserver; } void handleInventoryDisplayInboxChanged() @@ -172,15 +152,6 @@ void handleInventoryDisplayInboxChanged() } } -void handleInventoryDisplayOutboxChanged() -{ - LLSidepanelInventory* sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); - if (sidepanel_inventory) - { - sidepanel_inventory->enableOutbox(gSavedSettings.getBOOL("InventoryDisplayOutbox")); - } -} - BOOL LLSidepanelInventory::postBuild() { // UI elements from inventory panel @@ -242,43 +213,27 @@ BOOL LLSidepanelInventory::postBuild() } } - // Marketplace inbox/outbox setup + // Received items inbox setup { LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME); - // Disable user_resize on main inventory panel by default - inv_stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL_NAME, false); - inv_stack->setPanelUserResize(INBOX_OUTBOX_LAYOUT_PANEL_NAME, false); - - // Collapse marketplace panel by default - inv_stack->collapsePanel(getChild<LLLayoutPanel>(INBOX_OUTBOX_LAYOUT_PANEL_NAME), true); - - LLLayoutStack* inout_stack = getChild<LLLayoutStack>(INBOX_OUTBOX_LAYOUT_STACK_NAME); - - // Collapse both inbox and outbox panels - inout_stack->collapsePanel(getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME), true); - inout_stack->collapsePanel(getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME), true); + // Collapse inbox panel + inv_stack->collapsePanel(getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME), true); // Set up button states and callbacks LLButton * inbox_button = getChild<LLButton>(INBOX_BUTTON_NAME); - LLButton * outbox_button = getChild<LLButton>(OUTBOX_BUTTON_NAME); inbox_button->setToggleState(false); - outbox_button->setToggleState(false); - inbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleInboxBtn, this)); - outbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleOutboxBtn, this)); - // Set the inbox and outbox visible based on debug settings (final setting comes from http request below) + // Set the inbox visible based on debug settings (final setting comes from http request below) enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox")); - enableOutbox(gSavedSettings.getBOOL("InventoryDisplayOutbox")); - // Trigger callback for after login so we can setup to track inbox and outbox changes after initial inventory load - LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLSidepanelInventory::updateInboxOutbox, this)); + // Trigger callback for after login so we can setup to track inbox changes after initial inventory load + LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLSidepanelInventory::updateInbox, this)); } gSavedSettings.getControl("InventoryDisplayInbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayInboxChanged)); - gSavedSettings.getControl("InventoryDisplayOutbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayOutboxChanged)); // Update the verbs buttons state. updateVerbs(); @@ -286,168 +241,96 @@ BOOL LLSidepanelInventory::postBuild() return TRUE; } -void LLSidepanelInventory::updateInboxOutbox() +void LLSidepanelInventory::updateInbox() { // - // Track inbox and outbox folder changes + // Track inbox folder changes // const bool do_not_create_folder = false; const bool do_not_find_in_library = false; const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, do_not_create_folder, do_not_find_in_library); - const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder, do_not_find_in_library); - // Set up observer to listen for creation of inbox and outbox if at least one of them doesn't exist - if (inbox_id.isNull() || outbox_id.isNull()) + // Set up observer to listen for creation of inbox if at least one of them doesn't exist + if (inbox_id.isNull()) { - observeInboxOutboxCreation(); + observeInboxCreation(); } - // Set up observer for inbox changes, if we have an inbox already - if (!inbox_id.isNull()) + else { // Enable the display of the inbox if it exists enableInbox(true); observeInboxModifications(inbox_id); } - -#if ENABLE_MERCHANT_OUTBOX_PANEL - // Set up observer for outbox changes, if we have an outbox already - if (!outbox_id.isNull()) - { - // Enable the display of the outbox if it exists - enableOutbox(true); - - observeOutboxModifications(outbox_id); - } -#endif } -void LLSidepanelInventory::observeInboxOutboxCreation() +void LLSidepanelInventory::observeInboxCreation() { // - // Set up observer to track inbox and outbox folder creation + // Set up observer to track inbox folder creation // - if (mInboxOutboxAddedObserver == NULL) + if (mInboxAddedObserver == NULL) { - mInboxOutboxAddedObserver = new LLInboxOutboxAddedObserver(this); + mInboxAddedObserver = new LLInboxAddedObserver(this); - gInventory.addObserver(mInboxOutboxAddedObserver); + gInventory.addObserver(mInboxAddedObserver); } } void LLSidepanelInventory::observeInboxModifications(const LLUUID& inboxID) { // - // Track inbox and outbox folder changes + // Silently do nothing if we already have an inbox inventory panel set up + // (this can happen multiple times on the initial session that creates the inbox) // - + + if (mInventoryPanelInbox != NULL) + { + return; + } + + // + // Track inbox folder changes + // + if (inboxID.isNull()) { - llwarns << "Attempting to track modifications to non-existant inbox" << llendl; + llwarns << "Attempting to track modifications to non-existent inbox" << llendl; return; } - + if (mCategoriesObserver == NULL) { mCategoriesObserver = new LLInventoryCategoriesObserver(); gInventory.addObserver(mCategoriesObserver); } - + mCategoriesObserver->addCategory(inboxID, boost::bind(&LLSidepanelInventory::onInboxChanged, this, inboxID)); - + // // Trigger a load for the entire contents of the Inbox // - + LLInventoryModelBackgroundFetch::instance().start(inboxID); - + // // Set up the inbox inventory view // - + LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL); mInventoryPanelInbox = inbox->setupInventoryPanel(); } - -void LLSidepanelInventory::observeOutboxModifications(const LLUUID& outboxID) -{ - // - // Track outbox folder changes - // - - if (outboxID.isNull()) - { - llwarns << "Attempting to track modifications to non-existant outbox" << llendl; - return; - } - - if (mCategoriesObserver == NULL) - { - mCategoriesObserver = new LLInventoryCategoriesObserver(); - gInventory.addObserver(mCategoriesObserver); - } - - mCategoriesObserver->addCategory(outboxID, boost::bind(&LLSidepanelInventory::onOutboxChanged, this, outboxID)); - - // - // Set up the outbox inventory view - // - - LLPanelMarketplaceOutbox * outbox = getChild<LLPanelMarketplaceOutbox>(MARKETPLACE_OUTBOX_PANEL); - mInventoryPanelOutbox = outbox->setupInventoryPanel(); -} - void LLSidepanelInventory::enableInbox(bool enabled) { mInboxEnabled = enabled; LLLayoutPanel * inbox_layout_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); inbox_layout_panel->setVisible(enabled); - - if (mInboxEnabled) - { - LLLayoutPanel * inout_layout_panel = getChild<LLLayoutPanel>(INBOX_OUTBOX_LAYOUT_PANEL_NAME); - - inout_layout_panel->setVisible(TRUE); - - if (mOutboxEnabled) - { - S32 inbox_min_dim = inbox_layout_panel->getMinDim(); - S32 outbox_min_dim = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME)->getMinDim(); - - inout_layout_panel->setMinDim(inbox_min_dim + outbox_min_dim); - } - } -} - -void LLSidepanelInventory::enableOutbox(bool enabled) -{ - mOutboxEnabled = enabled; - - LLLayoutPanel * outbox_layout_panel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME); - outbox_layout_panel->setVisible(enabled); - - if (mOutboxEnabled) - { - LLLayoutPanel * inout_layout_panel = getChild<LLLayoutPanel>(INBOX_OUTBOX_LAYOUT_PANEL_NAME); - - inout_layout_panel->setVisible(TRUE); - - if (mInboxEnabled) - { - S32 inbox_min_dim = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME)->getMinDim(); - S32 outbox_min_dim = outbox_layout_panel->getMinDim(); - - inout_layout_panel->setMinDim(inbox_min_dim + outbox_min_dim); - } - - updateOutboxUserStatus(); - } } void LLSidepanelInventory::openInbox() @@ -459,31 +342,13 @@ void LLSidepanelInventory::openInbox() } } -void LLSidepanelInventory::openOutbox() -{ - if (mOutboxEnabled) - { - getChild<LLButton>(OUTBOX_BUTTON_NAME)->setToggleState(true); - onToggleOutboxBtn(); - } -} - void LLSidepanelInventory::onInboxChanged(const LLUUID& inbox_id) { // Trigger a load of the entire inbox so we always know the contents and their creation dates for sorting LLInventoryModelBackgroundFetch::instance().start(inbox_id); #if AUTO_EXPAND_INBOX - // If the outbox is expanded, don't auto-expand the inbox - if (mOutboxEnabled) - { - if (getChild<LLButton>(OUTBOX_BUTTON_NAME)->getToggleState()) - { - return; - } - } - - // Expand the inbox since we have fresh items and the outbox is not expanded + // Expand the inbox since we have fresh items if (mInboxEnabled) { getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true); @@ -492,68 +357,16 @@ void LLSidepanelInventory::onInboxChanged(const LLUUID& inbox_id) #endif } -void LLSidepanelInventory::onOutboxChanged(const LLUUID& outbox_id) -{ - // Expand the outbox since we have new items in it - if (mOutboxEnabled) - { - getChild<LLButton>(OUTBOX_BUTTON_NAME)->setToggleState(true); - onToggleOutboxBtn(); - } -} - -bool LLSidepanelInventory::manageInboxOutboxPanels(LLButton * pressedButton, LLLayoutPanel * pressedPanel, - LLButton * otherButton, LLLayoutPanel * otherPanel) -{ - bool expand = pressedButton->getToggleState(); - bool otherExpanded = otherButton->getToggleState(); - - LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME); - LLLayoutStack* inout_stack = getChild<LLLayoutStack>(INBOX_OUTBOX_LAYOUT_STACK_NAME); - LLLayoutPanel* inout_panel = getChild<LLLayoutPanel>(INBOX_OUTBOX_LAYOUT_PANEL_NAME); - - // Enable user_resize on main inventory panel only when a marketplace box is expanded - inv_stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL_NAME, expand); - inv_stack->collapsePanel(inout_panel, !expand); - - // Collapse other marketplace panel if it is expanded - if (expand && otherExpanded) - { - // Reshape pressedPanel to the otherPanel's height so we preserve the marketplace panel size - pressedPanel->reshape(pressedPanel->getRect().getWidth(), otherPanel->getRect().getHeight()); - - inout_stack->collapsePanel(otherPanel, true); - otherButton->setToggleState(false); - } - else - { - // NOTE: This is an attempt to reshape the inventory panel to the proper size but it doesn't seem to propagate - // properly to the child panels. - - S32 new_height = inout_panel->getRect().getHeight(); - - if (otherPanel->getVisible()) - { - new_height -= otherPanel->getMinDim(); - } - - pressedPanel->reshape(pressedPanel->getRect().getWidth(), new_height); - } - - // Expand/collapse the indicated panel - inout_stack->collapsePanel(pressedPanel, !expand); - - return expand; -} - void LLSidepanelInventory::onToggleInboxBtn() { LLButton* inboxButton = getChild<LLButton>(INBOX_BUTTON_NAME); LLLayoutPanel* inboxPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); - LLButton* outboxButton = getChild<LLButton>(OUTBOX_BUTTON_NAME); - LLLayoutPanel* outboxPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME); - - const bool inbox_expanded = manageInboxOutboxPanels(inboxButton, inboxPanel, outboxButton, outboxPanel); + LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME); + + const bool inbox_expanded = inboxButton->getToggleState(); + + // Expand/collapse the indicated panel + inv_stack->collapsePanel(inboxPanel, !inbox_expanded); if (inbox_expanded && inboxPanel->isInVisibleChain()) { @@ -561,16 +374,6 @@ void LLSidepanelInventory::onToggleInboxBtn() } } -void LLSidepanelInventory::onToggleOutboxBtn() -{ - LLButton* inboxButton = getChild<LLButton>(INBOX_BUTTON_NAME); - LLLayoutPanel* inboxPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); - LLButton* outboxButton = getChild<LLButton>(OUTBOX_BUTTON_NAME); - LLLayoutPanel* outboxPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME); - - manageInboxOutboxPanels(outboxButton, outboxPanel, inboxButton, inboxPanel); -} - void LLSidepanelInventory::onOpen(const LLSD& key) { LLFirstUse::newInventory(false); @@ -740,77 +543,6 @@ void LLSidepanelInventory::showInventoryPanel() updateVerbs(); } -void LLSidepanelInventory::updateOutboxUserStatus() -{ - const bool isMerchant = (gSavedSettings.getString("InventoryMarketplaceUserStatus") == "merchant"); - const bool hasOutbox = !gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false).isNull(); - - LLView * outbox_placeholder = getChild<LLView>("outbox_inventory_placeholder_panel"); - LLView * outbox_placeholder_parent = outbox_placeholder->getParent(); - - LLTextBox * outbox_title_box = outbox_placeholder->getChild<LLTextBox>("outbox_inventory_placeholder_title"); - LLTextBox * outbox_text_box = outbox_placeholder->getChild<LLTextBox>("outbox_inventory_placeholder_text"); - - std::string outbox_text; - std::string outbox_title; - std::string outbox_tooltip; - - if (isMerchant) - { - if (hasOutbox) - { - outbox_text = LLTrans::getString("InventoryOutboxNoItems"); - outbox_title = LLTrans::getString("InventoryOutboxNoItemsTitle"); - outbox_tooltip = LLTrans::getString("InventoryOutboxNoItemsTooltip"); - } - else - { - outbox_text = LLTrans::getString("InventoryOutboxCreationError"); - outbox_title = LLTrans::getString("InventoryOutboxCreationErrorTitle"); - outbox_tooltip = LLTrans::getString("InventoryOutboxCreationErrorTooltip"); - } - } - else - { - // - // The string to become a merchant contains 3 URL's which need the domain name patched in. - // - - std::string domain = "secondlife.com"; - - if (!LLGridManager::getInstance()->isInProductionGrid()) - { - std::string gridLabel = LLGridManager::getInstance()->getGridLabel(); - domain = llformat("%s.lindenlab.com", utf8str_tolower(gridLabel).c_str()); - } - - LLStringUtil::format_map_t domain_arg; - domain_arg["[DOMAIN_NAME]"] = domain; - - std::string marketplace_url = LLTrans::getString("MarketplaceURL", domain_arg); - std::string marketplace_url_create = LLTrans::getString("MarketplaceURL_CreateStore", domain_arg); - std::string marketplace_url_info = LLTrans::getString("MarketplaceURL_LearnMore", domain_arg); - - LLStringUtil::format_map_t args1, args2, args3; - args1["[MARKETPLACE_URL]"] = marketplace_url; - args2["[LEARN_MORE_URL]"] = marketplace_url_info; - args3["[CREATE_STORE_URL]"] = marketplace_url_create; - - // NOTE: This is dumb, ridiculous and very finicky. The order of these is very important - // to have these three string substitutions work properly. - outbox_text = LLTrans::getString("InventoryOutboxNotMerchant", args1); - LLStringUtil::format(outbox_text, args2); - LLStringUtil::format(outbox_text, args3); - - outbox_title = LLTrans::getString("InventoryOutboxNotMerchantTitle"); - outbox_tooltip = LLTrans::getString("InventoryOutboxNotMerchantTooltip"); - } - - outbox_text_box->setValue(outbox_text); - outbox_title_box->setValue(outbox_title); - outbox_placeholder_parent->setToolTip(outbox_tooltip); -} - void LLSidepanelInventory::updateVerbs() { mInfoBtn->setEnabled(FALSE); @@ -926,13 +658,6 @@ U32 LLSidepanelInventory::getSelectedCount() { selection_list = mInventoryPanelInbox->getRootFolder()->getSelectionList(); - count += selection_list.size(); - } - - if ((count == 0) && mOutboxEnabled && (mInventoryPanelOutbox != NULL)) - { - selection_list = mInventoryPanelOutbox->getRootFolder()->getSelectionList(); - count += selection_list.size(); } @@ -957,7 +682,7 @@ BOOL LLSidepanelInventory::isMainInventoryPanelActive() const return mInventoryPanel->getVisible(); } -void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox, bool clearOutbox) +void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox) { if (clearMain) { @@ -974,15 +699,10 @@ void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox, bool mInventoryPanelInbox->clearSelection(); } - if (clearOutbox && mOutboxEnabled && (mInventoryPanelOutbox != NULL)) - { - mInventoryPanelOutbox->clearSelection(); - } - updateVerbs(); } -std::set<LLUUID> LLSidepanelInventory::getInboxOrOutboxSelectionList() +std::set<LLUUID> LLSidepanelInventory::getInboxSelectionList() { std::set<LLUUID> inventory_selected_uuids; @@ -991,10 +711,5 @@ std::set<LLUUID> LLSidepanelInventory::getInboxOrOutboxSelectionList() inventory_selected_uuids = mInventoryPanelInbox->getRootFolder()->getSelectionList(); } - if (inventory_selected_uuids.empty() && mOutboxEnabled && (mInventoryPanelOutbox != NULL)) - { - inventory_selected_uuids = mInventoryPanelOutbox->getRootFolder()->getSelectionList(); - } - return inventory_selected_uuids; } diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index 2c6f807013..a33607f50d 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -31,7 +31,7 @@ class LLButton; class LLFolderViewItem; -class LLInboxOutboxAddedObserver; +class LLInboxAddedObserver; class LLInventoryCategoriesObserver; class LLInventoryItem; class LLInventoryPanel; @@ -47,25 +47,23 @@ public: virtual ~LLSidepanelInventory(); private: - void updateInboxOutbox(); + void updateInbox(); public: - void observeInboxOutboxCreation(); + void observeInboxCreation(); void observeInboxModifications(const LLUUID& inboxID); - void observeOutboxModifications(const LLUUID& outboxID); /*virtual*/ BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); LLInventoryPanel* getActivePanel(); // Returns an active inventory panel, if any. LLInventoryPanel* getInboxPanel() const { return mInventoryPanelInbox; } - LLInventoryPanel* getOutboxPanel() const { return mInventoryPanelOutbox; } LLPanelMainInventory* getMainInventoryPanel() const { return mPanelMainInventory; } BOOL isMainInventoryPanelActive() const; - void clearSelections(bool clearMain, bool clearInbox, bool clearOutbox); - std::set<LLUUID> getInboxOrOutboxSelectionList(); + void clearSelections(bool clearMain, bool clearInbox); + std::set<LLUUID> getInboxSelectionList(); void showItemInfoPanel(); void showTaskInfoPanel(); @@ -75,18 +73,13 @@ public: bool canShare(); void onToggleInboxBtn(); - void onToggleOutboxBtn(); void enableInbox(bool enabled); - void enableOutbox(bool enabled); void openInbox(); - void openOutbox(); bool isInboxEnabled() const { return mInboxEnabled; } - bool isOutboxEnabled() const { return mOutboxEnabled; } - void updateOutboxUserStatus(); void updateVerbs(); protected: @@ -100,9 +93,6 @@ protected: bool canWearSelected(); // check whether selected items can be worn void onInboxChanged(const LLUUID& inbox_id); - void onOutboxChanged(const LLUUID& outbox_id); - - bool manageInboxOutboxPanels(LLButton * pressedButton, LLLayoutPanel * pressedPanel, LLButton * otherButton, LLLayoutPanel * otherPanel); // // UI Elements @@ -110,7 +100,6 @@ protected: private: LLPanel* mInventoryPanel; // Main inventory view LLInventoryPanel* mInventoryPanelInbox; - LLInventoryPanel* mInventoryPanelOutbox; LLSidepanelItemInfo* mItemPanel; // Individual item view LLSidepanelTaskInfo* mTaskPanel; // Individual in-world object view LLPanelMainInventory* mPanelMainInventory; @@ -135,10 +124,9 @@ private: LLButton* mShopBtn; bool mInboxEnabled; - bool mOutboxEnabled; - LLInventoryCategoriesObserver* mCategoriesObserver; - LLInboxOutboxAddedObserver* mInboxOutboxAddedObserver; + LLInventoryCategoriesObserver* mCategoriesObserver; + LLInboxAddedObserver* mInboxAddedObserver; }; #endif //LL_LLSIDEPANELINVENTORY_H diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 7e02a41e7e..3923b4510a 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -804,9 +804,8 @@ bool idle_startup() #ifdef _WIN32 MSG msg; while( PeekMessage( &msg, /*All hWnds owned by this thread */ NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) ) - { - display_startup(); - } + { } + display_startup(); #endif timeout.reset(); return FALSE; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 6910b8eced..8c32dfcb4d 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -282,6 +282,8 @@ void LLCategoryDropDescendentsObserver::done() } */ +S32 LLToolDragAndDrop::sOperationId = 0; + LLToolDragAndDrop::DragAndDropEntry::DragAndDropEntry(dragOrDrop3dImpl f_none, dragOrDrop3dImpl f_self, dragOrDrop3dImpl f_avatar, @@ -626,6 +628,8 @@ BOOL LLToolDragAndDrop::handleToolTip(S32 x, S32 y, MASK mask) void LLToolDragAndDrop::handleDeselect() { mToolTipMsg.clear(); + + LLToolTipMgr::instance().blockToolTips(); } // protected @@ -642,6 +646,12 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop, mToolTipMsg.clear(); + // Increment the operation id for every drop + if (drop) + { + sOperationId++; + } + if (top_view) { handled = TRUE; @@ -767,6 +777,21 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop, if (!handled) { + // Disallow drag and drop to 3D from the outbox + const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); + if (outbox_id.notNull()) + { + for (S32 item_index = 0; item_index < (S32)mCargoIDs.size(); item_index++) + { + if (gInventory.isObjectDescendentOf(mCargoIDs[item_index], outbox_id)) + { + *acceptance = ACCEPT_NO; + mToolTipMsg = LLTrans::getString("TooltipOutboxDragToWorld"); + return; + } + } + } + dragOrDrop3D( x, y, mask, drop, acceptance ); } } @@ -865,7 +890,7 @@ void LLToolDragAndDrop::pick(const LLPickInfo& pick_info) (U32)mLastAccept, (U32)callMemberFunction(*this, LLDragAndDropDictionary::instance().get(dad_type, target)) - (hit_obj, hit_face, pick_info.mKeyMask, FALSE)); + (hit_obj, hit_face, pick_info.mKeyMask, FALSE)); } if (mDrop && ((U32)mLastAccept >= ACCEPT_YES_COPY_SINGLE)) diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 92f007a251..188d36cd1b 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -86,6 +86,9 @@ public: EAcceptance getLastAccept() { return mLastAccept; } boost::signals2::connection setEndDragCallback( const enddrag_signal_t::slot_type& cb ) { return mEndDragSignal.connect(cb); } + + uuid_vec_t::size_type getCargoIDsCount() const { return mCargoIDs.size(); } + static S32 getOperationId() { return sOperationId; } protected: enum EDropTarget @@ -125,6 +128,8 @@ protected: LLUUID mSourceID; LLUUID mObjectID; + static S32 sOperationId; + LLVector3d mLastCameraPos; LLVector3d mLastHitPos; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 16edec606c..0a3bb2f4ba 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -83,6 +83,7 @@ #include "llfloaternotificationsconsole.h" #include "llfloaterobjectweights.h" #include "llfloateropenobject.h" +#include "llfloateroutbox.h" #include "llfloaterpathfindingconsole.h" #include "llfloaterpathfindinglinksets.h" #include "llfloaterpay.h" @@ -240,6 +241,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("object_weights", "floater_object_weights.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterObjectWeights>); LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>); + LLFloaterReg::add("outbox", "floater_merchant_outbox.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutbox>); LLFloaterReg::add("outgoing_call", "floater_outgoing_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLOutgoingCallDialog>); LLFloaterPayUtil::registerFloater(); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 09cce39c3d..046360e9e9 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -26,46 +26,48 @@ #include "llviewerprecompiledheaders.h" +#include "llviewermedia.h" + #include "llagent.h" #include "llagentcamera.h" -#include "llviewermedia.h" -#include "llviewermediafocus.h" -#include "llmimetypes.h" +#include "llappviewer.h" +#include "llaudioengine.h" // for gAudiop +#include "llcallbacklist.h" +#include "lldir.h" +#include "lldiriterator.h" +#include "llevent.h" // LLSimpleListener +#include "llfilepicker.h" +#include "llfloaterwebcontent.h" // for handling window close requests and geometry change requests in media browser windows. +#include "llfocusmgr.h" +#include "llkeyboard.h" +#include "lllogininstance.h" +#include "llmarketplacefunctions.h" #include "llmediaentry.h" +#include "llmimetypes.h" +#include "llmutelist.h" +#include "llnotifications.h" +#include "llnotificationsutil.h" +#include "llpanelprofile.h" +#include "llparcel.h" +#include "llpluginclassmedia.h" +#include "llplugincookiestore.h" +#include "llurldispatcher.h" +#include "lluuid.h" #include "llversioninfo.h" +#include "llviewermediafocus.h" #include "llviewercontrol.h" -#include "llviewertexture.h" +#include "llviewernetwork.h" #include "llviewerparcelmedia.h" #include "llviewerparcelmgr.h" +#include "llviewerregion.h" +#include "llviewertexture.h" #include "llviewertexturelist.h" -#include "llvovolume.h" -#include "llpluginclassmedia.h" -#include "llplugincookiestore.h" #include "llviewerwindow.h" -#include "llfocusmgr.h" -#include "llcallbacklist.h" -#include "llparcel.h" -#include "llaudioengine.h" // for gAudiop -#include "llurldispatcher.h" #include "llvoavatar.h" #include "llvoavatarself.h" -#include "llviewerregion.h" +#include "llvovolume.h" #include "llwebprofile.h" #include "llwebsharing.h" // For LLWebSharing::setOpenIDCookie(), *TODO: find a better way to do this! -#include "llfilepicker.h" -#include "llnotifications.h" -#include "lldir.h" -#include "lldiriterator.h" -#include "llevent.h" // LLSimpleListener -#include "llnotificationsutil.h" -#include "lluuid.h" -#include "llkeyboard.h" -#include "llmutelist.h" -#include "llpanelprofile.h" -#include "llappviewer.h" -#include "lllogininstance.h" -//#include "llfirstuse.h" -#include "llviewernetwork.h" #include "llwindow.h" #include "llvieweraudio.h" @@ -1398,75 +1400,11 @@ void LLViewerMedia::removeCookie(const std::string &name, const std::string &dom } -// This is defined in two files but I don't want to create a dependence between this and llsidepanelinventory -// just to be able to temporarily disable the outbox. -#define ENABLE_INVENTORY_DISPLAY_OUTBOX 0 // keep in sync with ENABLE_MERCHANT_OUTBOX_PANEL, ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU - -class LLInventoryUserStatusResponder : public LLHTTPClient::Responder -{ -public: - LLInventoryUserStatusResponder() - : LLCurl::Responder() - { - } - - void completed(U32 status, const std::string& reason, const LLSD& content) - { - if (isGoodStatus(status)) - { - std::string merchantStatus = content[gAgent.getID().getString()].asString(); - llinfos << "Marketplace merchant status: " << merchantStatus << llendl; - - // Save the merchant status before turning on the display - gSavedSettings.setString("InventoryMarketplaceUserStatus", merchantStatus); - - // Complete success - gSavedSettings.setBOOL("InventoryDisplayInbox", true); - -#if ENABLE_INVENTORY_DISPLAY_OUTBOX - gSavedSettings.setBOOL("InventoryDisplayOutbox", true); -#endif - } - else if (status == 401) - { - // API is available for use but OpenID authorization failed - gSavedSettings.setBOOL("InventoryDisplayInbox", true); - } - else - { - // API in unavailable - llinfos << "Marketplace API is unavailable -- Inbox may be disabled, status = " << status << ", reason = " << reason << llendl; - } - } -}; - - -void doOnetimeEarlyHTTPRequests() -{ - std::string url = "https://marketplace.secondlife.com/"; - - if (!LLGridManager::getInstance()->isInProductionGrid()) - { - std::string gridLabel = LLGridManager::getInstance()->getGridLabel(); - url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str()); - - // TEMP for Jim's pdp - //url = "http://pdp24.lindenlab.com:3000/"; - } - - url += "api/1/users/"; - url += gAgent.getID().getString(); - url += "/user_status"; - - llinfos << "http get: " << url << llendl; - LLHTTPClient::get(url, new LLInventoryUserStatusResponder(), LLViewerMedia::getHeaders()); -} - - LLSD LLViewerMedia::getHeaders() { LLSD headers = LLSD::emptyMap(); headers["Accept"] = "*/*"; + headers["Content-Type"] = "application/xml"; headers["Cookie"] = sOpenIDCookie; headers["User-Agent"] = getCurrentUserAgent(); @@ -1521,9 +1459,6 @@ void LLViewerMedia::setOpenIDCookie() LLHTTPClient::get(profile_url, new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()), headers); - - // FUI: No longer perform the user_status query - //doOnetimeEarlyHTTPRequests(); } } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 0104d35e53..67f6150dbe 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2786,8 +2786,31 @@ bool enable_object_mute() else { // Just a regular object - return LLSelectMgr::getInstance()->getSelection()-> - contains( object, SELECT_ALL_TES ); + return LLSelectMgr::getInstance()->getSelection()->contains( object, SELECT_ALL_TES ) && + !LLMuteList::getInstance()->isMuted(object->getID()); + } +} + +bool enable_object_unmute() +{ + LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (!object) return false; + + LLVOAvatar* avatar = find_avatar_from_object(object); + if (avatar) + { + // It's an avatar + LLNameValue *lastname = avatar->getNVPair("LastName"); + bool is_linden = + lastname && !LLStringUtil::compareStrings(lastname->getString(), "Linden"); + bool is_self = avatar->isSelf(); + return !is_linden && !is_self; + } + else + { + // Just a regular object + return LLSelectMgr::getInstance()->getSelection()->contains( object, SELECT_ALL_TES ) && + LLMuteList::getInstance()->isMuted(object->getID());; } } @@ -8308,6 +8331,7 @@ void initialize_menus() enable.add("Avatar.EnableMute", boost::bind(&enable_object_mute)); enable.add("Object.EnableMute", boost::bind(&enable_object_mute)); + enable.add("Object.EnableUnmute", boost::bind(&enable_object_unmute)); enable.add("Object.EnableBuy", boost::bind(&enable_buy_object)); commit.add("Object.ZoomIn", boost::bind(&handle_look_at_selection, "zoom")); diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index ddbcdfc3f7..6f6411ce3c 100644 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -63,7 +63,7 @@ struct LLWearableArrivedData LLWearableList::~LLWearableList() { - llassert_always(mList.empty()) ; + cleanup(); } void LLWearableList::cleanup() diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index ee854d96e5..9f14caa142 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -137,6 +137,7 @@ with the same filename but different name <texture name="Command_MiniCart_Icon" file_name="toolbar_icons/mini_cart.png" preload="true" /> <texture name="Command_MiniMap_Icon" file_name="toolbar_icons/mini_map.png" preload="true" /> <texture name="Command_Move_Icon" file_name="toolbar_icons/move.png" preload="true" /> + <texture name="Command_Outbox_Icon" file_name="toolbar_icons/outbox.png" preload="true" /> <texture name="Command_Pathfinding_Icon" file_name="toolbar_icons/land.png" preload="true" /> <texture name="Command_People_Icon" file_name="toolbar_icons/people.png" preload="true" /> <texture name="Command_PF_Linksets_Icon" file_name="toolbar_icons/land.png" preload="true" /> @@ -388,22 +389,9 @@ with the same filename but different name <texture name="OptionsMenu_Off" file_name="icons/OptionsMenu_Off.png" preload="false" /> <texture name="OptionsMenu_Press" file_name="icons/OptionsMenu_Press.png" preload="false" /> - <texture name="OutboxPush_Disabled" file_name="icons/OutboxPush_Disabled.png" preload="true" /> - <texture name="OutboxPush_Off" file_name="icons/OutboxPush_Off.png" preload="true" /> - <texture name="OutboxPush_On" file_name="icons/OutboxPush_On.png" preload="true" /> - <texture name="OutboxPush_On_Over" file_name="icons/OutboxPush_On_Over.png" preload="true" /> - <texture name="OutboxPush_Over" file_name="icons/OutboxPush_Over.png" preload="true" /> - <texture name="OutboxPush_Press" file_name="icons/OutboxPush_Press.png" preload="true" /> - <texture name="OutboxPush_Progress_1" file_name="icons/OutboxPush_Progress_1.png" preload="true" /> - <texture name="OutboxPush_Progress_2" file_name="icons/OutboxPush_Progress_2.png" preload="true" /> - <texture name="OutboxPush_Progress_3" file_name="icons/OutboxPush_Progress_3.png" preload="true" /> - <texture name="OutboxPush_Progress_4" file_name="icons/OutboxPush_Progress_4.png" preload="true" /> - <texture name="OutboxPush_Progress_5" file_name="icons/OutboxPush_Progress_5.png" preload="true" /> - <texture name="OutboxPush_Progress_6" file_name="icons/OutboxPush_Progress_6.png" preload="true" /> - <texture name="OutboxPush_Selected" file_name="icons/OutboxPush_Selected.png" preload="true" /> - <texture name="OutboxPush_Selected_Disabled" file_name="icons/OutboxPush_Selected_Disabled.png" preload="true" /> - <texture name="OutboxPush_Selected_Over" file_name="icons/OutboxPush_Selected_Over.png" preload="true" /> - <texture name="OutboxPush_Selected_Press" file_name="icons/OutboxPush_Selected_Press.png" preload="true" /> + <texture name="OutboxStatus_Success" file_name="green_checkmark.png" preload="false" /> + <texture name="OutboxStatus_Warning" file_name="icons/pop_up_caution.png" preload="false" /> + <texture name="OutboxStatus_Error" file_name="red_x.png" preload="false" /> <texture name="PanOrbit_Off" file_name="bottomtray/PanOrbit_Off.png" preload="false" /> diff --git a/indra/newview/skins/default/textures/toolbar_icons/outbox.png b/indra/newview/skins/default/textures/toolbar_icons/outbox.png Binary files differnew file mode 100644 index 0000000000..0f3db1c47c --- /dev/null +++ b/indra/newview/skins/default/textures/toolbar_icons/outbox.png diff --git a/indra/newview/skins/default/xui/da/menu_viewer.xml b/indra/newview/skins/default/xui/da/menu_viewer.xml index ba18306686..d695cd1f89 100644 --- a/indra/newview/skins/default/xui/da/menu_viewer.xml +++ b/indra/newview/skins/default/xui/da/menu_viewer.xml @@ -20,8 +20,6 @@ <menu_item_call label="Væk" name="Set Away"/> <menu_item_call label="Optaget" name="Set Busy"/> </menu> - <menu_item_call label="Anmod om administrator status" name="Request Admin Options"/> - <menu_item_call label="Stop administrator status" name="Leave Admin Options"/> <menu_item_call label="Afslut [APP_NAME]" name="Quit"/> </menu> <menu label="Kommunikér" name="Communicate"> @@ -36,11 +34,10 @@ <menu_item_check label="Søg" name="Search"/> <menu_item_call label="Foto" name="Take Snapshot"/> <menu_item_call label="Opret landemærke for dette sted" name="Create Landmark Here"/> - <menu label="Profil for sted" name="Land"> - <menu_item_call label="Profil for sted" name="Place Profile"/> - <menu_item_call label="Om land" name="About Land"/> - <menu_item_call label="Region/Estate" name="Region/Estate"/> - </menu> + <menu_item_separator/> + <menu_item_call label="Profil for sted" name="Place Profile"/> + <menu_item_call label="Om land" name="About Land"/> + <menu_item_call label="Region/Estate" name="Region/Estate"/> <menu_item_call label="Køb dette land" name="Buy Land"/> <menu_item_call label="Mit land" name="My Land"/> <menu label="Vis" name="LandShow"> @@ -56,7 +53,7 @@ </menu> <menu_item_call label="Teleport hjem" name="Teleport Home"/> <menu_item_call label="Sæt dette sted som 'Hjem'" name="Set Home to Here"/> - <menu label="Sol" name="Environment Settings"> + <menu label="Sol" name="Sun"> <menu_item_call label="Solopgang" name="Sunrise"/> <menu_item_call label="Middag" name="Noon"/> <menu_item_call label="Solnedgang" name="Sunset"/> @@ -155,22 +152,22 @@ <menu_item_check label="Vis muse-sigte" name="ShowCrosshairs"/> </menu> <menu label="Gengivelsestyper" name="Rendering Types"> - <menu_item_check label="Simpel" name="Simple"/> - <menu_item_check label="Alpha" name="Alpha"/> - <menu_item_check label="Træer" name="Tree"/> - <menu_item_check label="Avatarer" name="Character"/> - <menu_item_check label="Surface Patch" name="Surface Patch"/> - <menu_item_check label="Himmel" name="Sky"/> - <menu_item_check label="Vand" name="Water"/> - <menu_item_check label="Jord" name="Ground"/> - <menu_item_check label="Volume" name="Volume"/> - <menu_item_check label="Græs" name="Grass"/> - <menu_item_check label="Skyer" name="Clouds"/> - <menu_item_check label="Partikler" name="Particles"/> - <menu_item_check label="Bump" name="Bump"/> + <menu_item_check label="Simpel" name="Rendering Type Simple"/> + <menu_item_check label="Alpha" name="Rendering Type Alpha"/> + <menu_item_check label="Træer" name="Rendering Type Tree"/> + <menu_item_check label="Avatarer" name="Rendering Type Character"/> + <menu_item_check label="Surface Patch" name="Rendering Type Surface Patch"/> + <menu_item_check label="Himmel" name="Rendering Type Sky"/> + <menu_item_check label="Vand" name="Rendering Type Water"/> + <menu_item_check label="Jord" name="Rendering Type Ground"/> + <menu_item_check label="Volume" name="Rendering Type Volume"/> + <menu_item_check label="Græs" name="Rendering Type Grass"/> + <menu_item_check label="Skyer" name="Rendering Type Clouds"/> + <menu_item_check label="Partikler" name="Rendering Type Particles"/> + <menu_item_check label="Bump" name="Rendering Type Bump"/> </menu> <menu label="Gengivelsesegenskaber" name="Rendering Features"> - <menu_item_check label="UI" name="UI"/> + <menu_item_check label="UI" name="ToggleUI"/> <menu_item_check label="Valgte" name="Selected"/> <menu_item_check label="Fremhævede" name="Highlighted"/> <menu_item_check label="Dynamiske teksturer" name="Dynamic Textures"/> @@ -182,10 +179,7 @@ <menu_item_call label="Tøm gruppe cache" name="ClearGroupCache"/> <menu_item_check label="Muse udjævning" name="Mouse Smoothing"/> <menu label="Shortcuts" name="Shortcuts"> - <menu_item_call label="Billede (L$[COST])..." name="Upload Image"/> - <menu_item_check label="Søg" name="Search"/> <menu_item_call label="Frigør taster" name="Release Keys"/> - <menu_item_call label="Sæt UI størrelse til standard" name="Set UI Size to Default"/> <menu_item_check label="Vis avanceret menu (gammel genvej)" name="Show Advanced Menu - legacy shortcut"/> <menu_item_call label="Luk vindue" name="Close Window"/> <menu_item_call label="Luk alle vinduer" name="Close All Windows"/> @@ -194,13 +188,6 @@ <menu_item_check label=""Joystick Flycam"" name="Joystick Flycam"/> <menu_item_call label="Nulstil udsyn" name="Reset View"/> <menu_item_call label="Se på den sidste der chattede" name="Look at Last Chatter"/> - <menu label="Vælg byggeværktøj" name="Select Tool"> - <menu_item_call label="Fokuseringsværktøj" name="Focus"/> - <menu_item_call label="Flyt værktøj" name="Move"/> - <menu_item_call label="Redigeringsværktøj" name="Edit"/> - <menu_item_call label="Opret værktøj" name="Create"/> - <menu_item_call label="Land værktøj" name="Land"/> - </menu> <menu_item_call label="Zoom ind" name="Zoom In"/> <menu_item_call label="Zoom standard" name="Zoom Default"/> <menu_item_call label="Zoom ud" name="Zoom Out"/> @@ -276,9 +263,8 @@ <menu_item_call label="Mist en netværkspakke" name="Drop a Packet"/> </menu> <menu_item_call label="Stød, skub & slag" name="Bumps, Pushes &amp; Hits"/> - <menu label="Verden" name="World"> + <menu label="Verden" name="DevelopWorld"> <menu_item_check label="Vælg anden sol end region" name="Sim Sun Override"/> - <menu_item_check label="Pejlelys blink effekt" name="Cheesy Beacon"/> <menu_item_check label="Fast vejr" name="Fixed Weather"/> <menu_item_call label="Dump Region Object Cache" name="Dump Region Object Cache"/> </menu> @@ -300,11 +286,11 @@ </menu> <menu label="Avatar" name="Character"> <menu label="Grab Baked Texture" name="Grab Baked Texture"> - <menu_item_call label="Iris" name="Iris"/> - <menu_item_call label="Hovede" name="Head"/> - <menu_item_call label="Overkrop" name="Upper Body"/> - <menu_item_call label="Underkrop" name="Lower Body"/> - <menu_item_call label="Nederdel" name="Skirt"/> + <menu_item_call label="Iris" name="Grab Iris"/> + <menu_item_call label="Hovede" name="Grab Head"/> + <menu_item_call label="Overkrop" name="Grab Upper Body"/> + <menu_item_call label="Underkrop" name="Grab Lower Body"/> + <menu_item_call label="Nederdel" name="Grab Skirt"/> </menu> <menu label="Avatar tests" name="Character Tests"> <menu_item_call label="Skift avatar geometri" name="Toggle Character Geometry"/> @@ -326,8 +312,8 @@ <menu_item_check label="Vis administrationsmenu" name="View Admin Options"/> </menu> <menu label="Administrér" name="Admin"> - <menu label="Object"> - <menu_item_call label="Tag kopi" name="Take Copy"/> + <menu label="Object" name="AdminObject"> + <menu_item_call label="Tag kopi" name="Admin Take Copy"/> <menu_item_call label="Gennemtving ejer til mig" name="Force Owner To Me"/> <menu_item_call label="Gennemtving ejer tolerance" name="Force Owner Permissive"/> <menu_item_call label="Slet" name="Delete"/> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 4772f744ea..1d5a6740b7 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1206,10 +1206,6 @@ Only large parcels can be listed in search. name="push_restrict_region_text"> No Pushing (Region Override) </panel.string> - <panel.string - name="see_avs_text"> - Avatars on other parcels can see - </panel.string> <text type="string" length="1" @@ -1524,24 +1520,24 @@ Only large parcels can be listed in search. length="1" follows="left|top" text_color="LtGray" - height="16" + height="32" layout="topleft" left="274" - top="166" + top="150" name="allow_label5" - width="278"> - and chat with avatars on this parcel + width="205" + wrap="true"> + Avatars on other parcels can see and chat with avatars on this parcel </text> <check_box height="16" - label="See Avatars" follows="top" layout="topleft" left="253" top="150" name="SeeAvatarsCheck" tool_tip="Allows avatars on other parcels to see and chat with avatars on this parcel, and you to see and chat with them." - width="120" /> + width="10" /> <text type="string" length="1" @@ -1955,36 +1951,18 @@ Only large parcels can be listed in search. name="access_estate_defined"> (Defined by the Estate) </panel.string> - <panel.string - name="allow_public_access"> - Allow Public Access ([MATURITY]) (Note: Unchecking this will create ban lines) - </panel.string> <panel.string name="estate_override"> One or more of these options is set at the estate level </panel.string> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="10" - name="Limit access to this parcel to:" - text_color="White" - top="10" - width="400"> - Access To This Parcel - </text> <check_box follows="top|left" height="16" layout="topleft" - left_delta="0" + left="8" name="public_access" - top_pad="5" - label_text.valign="center" - label_text.v_pad="-2" + label="Allow Public Access (Unchecking this will create ban lines)" + top_pad="10" width="278" /> <text type="string" @@ -1994,28 +1972,28 @@ Only large parcels can be listed in search. layout="topleft" left_delta="20" name="Only Allow" - top="49" + top="30" width="325"> - Restrict Access to Residents verified by: + Allow access only to Residents who: </text> <check_box follows="top|left" height="16" - label="Payment Information on File [ESTATE_PAYMENT_LIMIT]" + label="Have payment Information on File [ESTATE_PAYMENT_LIMIT]" layout="topleft" left_delta="0" name="limit_payment" - tool_tip="Ban unidentified Residents." + tool_tip="Residents must have payment information on file to access this parcel. See the [SUPPORT_SITE] for more information." top_pad="4" width="278" /> <check_box follows="top|left" height="16" - label="Age Verification [ESTATE_AGE_LIMIT]" + label="Have been age-verified [ESTATE_AGE_LIMIT]" layout="topleft" left_delta="0" name="limit_age_verified" - tool_tip="Ban Residents who have not verified their age. See the [SUPPORT_SITE] for more information." + tool_tip="Residents must be age verified to access this parcel. See the [SUPPORT_SITE] for more information." top_pad="4" width="278" /> <check_box @@ -2025,7 +2003,7 @@ Only large parcels can be listed in search. left="8" name="GroupCheck" tool_tip="Set group in the General tab." - top="109" + top="89" width="278" /> <check_box enabled="false" diff --git a/indra/newview/skins/default/xui/en/floater_help_browser.xml b/indra/newview/skins/default/xui/en/floater_help_browser.xml index d101bca694..cd075abc41 100644 --- a/indra/newview/skins/default/xui/en/floater_help_browser.xml +++ b/indra/newview/skins/default/xui/en/floater_help_browser.xml @@ -34,7 +34,6 @@ left_delta="0" top_delta="0" name="external_controls" - user_resize="false" width="620"> <web_browser trusted_content="true" diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index a2739a8339..ca73883e53 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -16,7 +16,7 @@ min_width="250" min_height="190"> <layout_stack - animate="false" + animate="true" default_tab_group="2" follows="all" height="320" @@ -32,8 +32,7 @@ min_width="115" width="150" height="320" - auto_resize="false" - user_resize="false"> + auto_resize="false"> <panel name="panel_im_control_panel" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_media_browser.xml b/indra/newview/skins/default/xui/en/floater_media_browser.xml index c3324a6aa4..ce788654aa 100644 --- a/indra/newview/skins/default/xui/en/floater_media_browser.xml +++ b/indra/newview/skins/default/xui/en/floater_media_browser.xml @@ -37,7 +37,6 @@ min_height="20" name="nav_controls" top="400" - user_resize="false" width="800"> <button follows="left|top" @@ -113,7 +112,6 @@ min_height="20" name="time_controls" top_delta="0" - user_resize="false" width="800"> <button follows="left|top" @@ -171,7 +169,6 @@ min_height="20" name="parcel_owner_controls" top_delta="0" - user_resize="false" width="540"> <button enabled="false" @@ -193,7 +190,6 @@ left_delta="0" name="external_controls" top_delta="0" - user_resize="false" width="540"> <web_browser bottom="-30" diff --git a/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml new file mode 100644 index 0000000000..498a9b6ce0 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml @@ -0,0 +1,152 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<floater + open_positioning="cascading" + can_close="true" + can_resize="true" + height="440" + help_topic="floater_merchant_outbox" + min_width="300" + min_height="200" + name="floater_merchant_outbox" + save_rect="true" + save_visibility="false" + reuse_instance="true" + title="MERCHANT OUTBOX" + width="333"> + <string name="OutboxFolderCount0"></string> + <string name="OutboxFolderCount1">1 folder</string> + <string name="OutboxFolderCountN">[NUM] folders</string> + <string name="OutboxImporting">Sending folders...</string> + <string name="OutboxInitializing">Initializing...</string> + <panel + follows="all" + layout="topleft" + left="0" + top="0" + label="" + height="440" + width="333"> + <panel + follows="all" + left="10" + bottom="370" + width="313" + top="0" + bg_opaque_color="InventoryBackgroundColor"> + <panel + name="outbox_inventory_placeholder_panel" + follows="all" + layout="topleft" + top="0" + left="0" + width="308" + height="370" + bg_opaque_color="InventoryBackgroundColor"> + <text + name="outbox_inventory_placeholder_title" + type="string" + follows="top|left|right" + layout="topleft" + top="10" + left="0" + width="308" + height="25" + wrap="true" + halign="center" + font="SansSerifBold"> + Loading... + </text> + <text + name="outbox_inventory_placeholder_text" + type="string" + follows="top|left|right" + layout="topleft" + top="35" + left="0" + width="308" + height="130" + wrap="true" + halign="left" /> + </panel> + </panel> + <panel + follows="bottom|left|right" + left="10" + bottom="435" + width="313" + top="370"> + <panel + name="outbox_generic_drag_target" + mouse_opaque="false" + follows="all" + top="5" + left="5" + width="303" + height="25" + background_visible="false" + bg_alpha_color="EmphasisColor_35" + border="true" + bevel_style="in" + visible="true"> + <text + type="string" + follows="all" + layout="topleft" + top="6" + height="20" + left="5" + width="293" + halign="center" + font="SansSerifMedium" + font_shadow="hard" + valign="bottom"> + Drag items here to create folders + </text> + </panel> + <text + name="outbox_folder_count" + type="string" + follows="all" + layout="topleft" + top="40" + left="5" + width="150" + height="20" + wrap="true" + halign="left" + valign="bottom" + font="SansSerif" /> + <button + label="Send to Marketplace" + tool_tip="Push to my Marketplace Storefront" + is_toggle="false" + name="outbox_import_btn" + follows="bottom|right" + tab_stop="false" + halign="center" + top="37" + left="160" + height="25" + width="150" + enabled="false" /> + </panel> + <layout_stack name="import_progress_indicator" orientation="vertical" left="0" height="440" top="0" width="333" follows="all" visible="false"> + <layout_panel /> + <layout_panel height="45" auto_resize="false"> + <layout_stack orientation="horizontal" left="0" height="45" top="0" width="333" follows="all"> + <layout_panel width="0" /> + <layout_panel width="45" auto_resize="false"> + <loading_indicator + height="45" + layout="topleft" + left="0" + top="0" + width="45" /> + </layout_panel> + <layout_panel width="0" /> + </layout_stack> + </layout_panel> + <layout_panel /> + </layout_stack> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml new file mode 100644 index 0000000000..f95f21e63a --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml @@ -0,0 +1,206 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_resize="true" + can_close="true" + bevel_style="in" + height="300" + layout="topleft" + min_height="40" + min_width="420" + name="Test Floater" + title="LAYOUTSTACK TESTS" + width="420"> + <layout_stack name="test_stack" + left="0" + top="0" + width="100" + height="250" + follows="left|top|bottom" + orientation="vertical"> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="11" + min_height="0" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="11" + min_height="0" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + </layout_stack> + <layout_stack name="test_stack" + left_pad="5" + top="0" + width="100" + height="250" + follows="left|top|bottom" + orientation="vertical"> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="100" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + visible="false" + bg_alpha_color="blue" + height="100" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="fixed" + auto_resize="false" + user_resize="true" + height="50" + min_height="10" + bg_alpha_color="green" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="black">fixed</text> + </layout_panel> + <layout_panel name="fixed" + auto_resize="false" + user_resize="true" + height="50" + min_height="10" + bg_alpha_color="green" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="black">fixed</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="100" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="100" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="100" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="100" + visible="true" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + </layout_stack> + <layout_stack name="test_stack" + left_pad="5" + top="0" + width="100" + height="250" + follows="left|top|bottom" + orientation="vertical"> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + height="11" + bg_alpha_color="blue" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="fixed" + auto_resize="false" + user_resize="true" + height="50" + bg_alpha_color="green" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="black">fixed</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="11" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + </layout_stack> + <layout_stack name="test_stack" + left_pad="5" + top="0" + width="100" + height="250" + follows="left|top|bottom" + orientation="vertical"> + <layout_panel name="fixed" + auto_resize="false" + user_resize="true" + height="50" + bg_alpha_color="green" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="black">fixed</text> + </layout_panel> + <layout_panel name="fixed" + auto_resize="false" + user_resize="true" + height="50" + bg_alpha_color="green" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="black">fixed</text> + </layout_panel> + <layout_panel name="fixed" + auto_resize="false" + user_resize="true" + height="50" + bg_alpha_color="green" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="black">fixed</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="11" + min_height="0" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="11" + min_height="0" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + <layout_panel name="flex" + auto_resize="true" + user_resize="true" + bg_alpha_color="blue" + height="11" + min_height="0" + background_visible="true"> + <text follows="top|left|right" halign="center" text_color="white">flex</text> + </layout_panel> + </layout_stack> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_toybox.xml b/indra/newview/skins/default/xui/en/floater_toybox.xml index 493d44a9cf..72e6187a14 100644 --- a/indra/newview/skins/default/xui/en/floater_toybox.xml +++ b/indra/newview/skins/default/xui/en/floater_toybox.xml @@ -5,7 +5,7 @@ can_minimize="false" can_resize="false" default_tab_group="1" - height="330" + height="375" help_topic="toybox" layout="topleft" legacy_header_height="18" @@ -46,7 +46,7 @@ Buttons will appear as shown or as icon-only depending on each toolbar's settings. </text> <toolbar - bottom="265" + bottom="310" button_display_mode="icons_with_text" follows="all" left="20" @@ -82,11 +82,11 @@ <panel bevel_style="none" border="true" - bottom="266" + bottom="311" follows="left|bottom|right" left="20" right="-20" - top="266" /> + top="311" /> <button follows="left|bottom|right" height="23" @@ -95,7 +95,7 @@ layout="topleft" left="185" name="btn_clear_all" - top="285" + top="330" width="130"> <button.commit_callback function="Toybox.ClearAll" /> </button> @@ -107,7 +107,7 @@ layout="topleft" left="335" name="btn_restore_defaults" - top="285" + top="330" width="130"> <button.commit_callback function="Toybox.RestoreDefaults" /> </button> diff --git a/indra/newview/skins/default/xui/en/floater_ui_preview.xml b/indra/newview/skins/default/xui/en/floater_ui_preview.xml index 3921cfcd2c..06d4327293 100644 --- a/indra/newview/skins/default/xui/en/floater_ui_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_ui_preview.xml @@ -22,6 +22,7 @@ or specifying its path in the "Editor Path" field.</string> layout="topleft" left="0" mouse_opaque="false" + default_tab_group="1" name="main_panel" right="750" top="0"> @@ -196,6 +197,7 @@ or specifying its path in the "Editor Path" field.</string> left="10" name="name_list" right="-10" + tab_group="1" search_column="1" top="80"> <scroll_list.columns diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml index 6807b01fa3..cea19ec75c 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml @@ -49,7 +49,6 @@ width="263"> <layout_panel follows="top|left|right" - user_resize="false" auto_resize="false" layout="topleft" min_height="20" @@ -89,7 +88,7 @@ visible="true" width="20" /> </layout_panel> - <layout_panel name="leave_call_panel" height="26" min_height="26" user_resize="false" auto_resize="false"> + <layout_panel name="leave_call_panel" height="26" min_height="26" auto_resize="false"> <layout_stack clip="true" follows="left|top|right" @@ -110,7 +109,6 @@ </layout_panel> <layout_panel auto_resize="false" - user_resize="false" follows="top|right" height="23" visible="true" @@ -133,7 +131,6 @@ top_pad="0" height="132" name="callers_panel" - user_resize="false" auto_resize="true" width="280"> <avatar_list diff --git a/indra/newview/skins/default/xui/en/floater_web_content.xml b/indra/newview/skins/default/xui/en/floater_web_content.xml index 57d1c92acb..cea10adca8 100644 --- a/indra/newview/skins/default/xui/en/floater_web_content.xml +++ b/indra/newview/skins/default/xui/en/floater_web_content.xml @@ -31,7 +31,6 @@ min_height="20" name="nav_controls" top="400" - user_resize="false" width="770"> <button image_overlay="Arrow_Left_Off" @@ -160,7 +159,6 @@ left_delta="0" name="external_controls" top_delta="0" - user_resize="false" auto_resize="true" width="585"> <web_browser @@ -173,8 +171,7 @@ </layout_panel> <layout_panel name="status_bar" height="23" - auto_resize="false" - user_resize="false"> + auto_resize="false"> <text type="string" length="200" diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml index b4be17e677..a87027a113 100644 --- a/indra/newview/skins/default/xui/en/main_view.xml +++ b/indra/newview/skins/default/xui/en/main_view.xml @@ -23,7 +23,6 @@ left="0" top="0" width="1024" - user_resize="false" auto_resize="false" visible="true"> <view mouse_opaque="false" @@ -40,7 +39,6 @@ name="nav_bar_container" tab_stop="false" width="1024" - user_resize="false" visible="false"/> <layout_panel auto_resize="true" follows="all" diff --git a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml index f818ebe2d7..63e154697b 100644 --- a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml @@ -114,6 +114,15 @@ function="Object.EnableMute" /> </menu_item_call> <menu_item_call + label="Unblock" + layout="topleft" + name="unblock"> + <menu_item_call.on_click + function="Object.Mute" /> + <menu_item_call.on_visible + function="Object.EnableUnmute" /> + </menu_item_call> + <menu_item_call label="Zoom In" layout="topleft" name="zoom_in"> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index fb85e5278a..ef4a1bc061 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -686,12 +686,12 @@ parameter="copy_to_outbox" /> </menu_item_call> <menu_item_call - label="Move to Merchant Outbox" + label="Send to Marketplace" layout="topleft" - name="Merchant Move"> + name="Marketplace Send"> <menu_item_call.on_click function="Inventory.DoToSelected" - parameter="move_to_outbox" /> + parameter="send_to_marketplace" /> </menu_item_call> <menu_item_call label="--no options--" diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml index 0f42000ae7..e91f5af3d5 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml @@ -3,6 +3,7 @@ layout="topleft" left="0" mouse_opaque="false" + can_tear_off="true" name="menu_inventory_add" visible="false"> <menu diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index a95ed572f9..54477f2cb7 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -118,7 +118,7 @@ </menu_item_call> <menu_item_call label="Walk / run / fly..." - name="Stop Animating My Avatar"> + name="Walk / run / fly"> <menu_item_call.on_click function="Floater.ToggleOrBringToFront" parameter="moveview" /> @@ -144,32 +144,22 @@ </menu_item_call> </menu> - <menu_item_call - label="Request Admin Status" - name="Request Admin Options" - shortcut="control|alt|G" - visible="false"> - <menu_item_call.on_click - function="Advanced.RequestAdminStatus" /> - </menu_item_call> - <menu_item_call - label="Leave Admin Status" - name="Leave Admin Options" - shortcut="control|alt|shift|G" - visible="false"> - <menu_item_call.on_click - function="Advanced.LeaveAdminStatus" /> - </menu_item_call> - <menu_item_separator/> <menu_item_call - label="Buy L$" + label="Buy L$..." name="Buy and Sell L$"> <menu_item_call.on_click function="BuyCurrency" /> </menu_item_call> <menu_item_call + label="Merchant Outbox..." + name="MerchantOutbox"> + <menu_item_call.on_click + function="Floater.ToggleOrBringToFront" + parameter="outbox" /> + </menu_item_call> + <menu_item_call label="Account dashboard..." name="Manage My Account"> <menu_item_call.on_click @@ -525,7 +515,7 @@ <menu create_jump_keys="true" label="Sun" - name="Environment Settings" + name="Sun" tear_off="true"> <menu_item_call label="Sunrise" @@ -1469,7 +1459,7 @@ tear_off="true"> <menu_item_check label="Simple" - name="Simple" + name="Rendering Type Simple" shortcut="control|alt|shift|1"> <menu_item_check.on_check function="Advanced.CheckRenderType" @@ -1480,7 +1470,7 @@ </menu_item_check> <menu_item_check label="Alpha" - name="Alpha" + name="Rendering Type Alpha" shortcut="control|alt|shift|2"> <menu_item_check.on_check function="Advanced.CheckRenderType" @@ -1491,7 +1481,7 @@ </menu_item_check> <menu_item_check label="Tree" - name="Tree" + name="Rendering Type Tree" shortcut="control|alt|shift|3"> <menu_item_check.on_check function="Advanced.CheckRenderType" @@ -1502,7 +1492,7 @@ </menu_item_check> <menu_item_check label="Avatars" - name="Character" + name="Rendering Type Character" shortcut="control|alt|shift|4"> <menu_item_check.on_check function="Advanced.CheckRenderType" @@ -1513,7 +1503,7 @@ </menu_item_check> <menu_item_check label="Surface Patch" - name="Surface Patch" + name="Rendering Type Surface Patch" shortcut="control|alt|shift|5"> <menu_item_check.on_check function="Advanced.CheckRenderType" @@ -1524,7 +1514,7 @@ </menu_item_check> <menu_item_check label="Sky" - name="Sky" + name="Rendering Type Sky" shortcut="control|alt|shift|6"> <menu_item_check.on_check function="Advanced.CheckRenderType" @@ -1535,7 +1525,7 @@ </menu_item_check> <menu_item_check label="Water" - name="Water" + name="Rendering Type Water" shortcut="control|alt|shift|7"> <menu_item_check.on_check function="Advanced.CheckRenderType" @@ -1546,7 +1536,7 @@ </menu_item_check> <menu_item_check label="Ground" - name="Ground" + name="Rendering Type Ground" shortcut="control|alt|shift|8"> <menu_item_check.on_check function="Advanced.CheckRenderType" @@ -1557,7 +1547,7 @@ </menu_item_check> <menu_item_check label="Volume" - name="Volume" + name="Rendering Type Volume" shortcut="control|alt|shift|9"> <menu_item_check.on_check function="Advanced.CheckRenderType" @@ -1568,7 +1558,7 @@ </menu_item_check> <menu_item_check label="Grass" - name="Grass" + name="Rendering Type Grass" shortcut="control|alt|shift|0"> <menu_item_check.on_check function="Advanced.CheckRenderType" @@ -1579,7 +1569,7 @@ </menu_item_check> <menu_item_check label="Clouds" - name="Clouds" + name="Rendering Type Clouds" shortcut="control|alt|shift|-"> <menu_item_check.on_check function="Advanced.CheckRenderType" @@ -1590,7 +1580,7 @@ </menu_item_check> <menu_item_check label="Particles" - name="Particles" + name="Rendering Type Particles" shortcut="control|alt|shift|="> <menu_item_check.on_check function="Advanced.CheckRenderType" @@ -1601,7 +1591,7 @@ </menu_item_check> <menu_item_check label="Bump" - name="Bump" + name="Rendering Type Bump" shortcut="control|alt|shift|\"> <menu_item_check.on_check function="Advanced.CheckRenderType" @@ -1618,7 +1608,7 @@ tear_off="true"> <menu_item_check label="UI" - name="UI" + name="ToggleUI" shortcut="control|alt|F1"> <menu_item_check.on_check function="Advanced.CheckFeature" @@ -1751,28 +1741,6 @@ name="Shortcuts" tear_off="true" visible="false"> - <menu_item_call - label="Image (L$[COST])..." - name="Upload Image" - shortcut="control|U"> - <menu_item_call.on_click - function="File.UploadImage" - parameter="" /> - <menu_item_call.on_enable - function="File.EnableUpload" /> - </menu_item_call> - <menu_item_check - label="Search" - name="Search" - shortcut="control|F"> - <menu_item_check.on_check - function="Floater.Visible" - parameter="search" /> - <menu_item_check.on_click - function="Floater.Toggle" - parameter="search" /> - </menu_item_check> - <!-- This second, alternative shortcut for Show Advanced Menu is for backward compatibility. The main shortcut has been changed so it's Linux-friendly, where the old shortcut is typically eaten by the window manager. --> <menu_item_check label="Show Advanced Menu - legacy shortcut" @@ -1859,55 +1827,6 @@ <menu_item_separator/> - <menu - create_jump_keys="true" - label="Select Build Tool" - name="Select Tool" - tear_off="true"> - <menu_item_call - label="Focus Tool" - name="Focus" - shortcut="control|1"> - <menu_item_call.on_click - function="Tools.SelectTool" - parameter="focus" /> - </menu_item_call> - <menu_item_call - label="Move Tool" - name="Move" - shortcut="control|2"> - <menu_item_call.on_click - function="Tools.SelectTool" - parameter="move" /> - </menu_item_call> - <menu_item_call - label="Edit Tool" - name="Edit" - shortcut="control|3"> - <menu_item_call.on_click - function="Tools.SelectTool" - parameter="edit" /> - </menu_item_call> - <menu_item_call - label="Create Tool" - name="Create" - shortcut="control|4"> - <menu_item_call.on_click - function="Tools.SelectTool" - parameter="create" /> - </menu_item_call> - <menu_item_call - label="Land Tool" - name="Land" - shortcut="control|5"> - <menu_item_call.on_click - function="Tools.SelectTool" - parameter="land" /> - </menu_item_call> - </menu> - - <menu_item_separator/> - <menu_item_call label="Zoom In" name="Zoom In" @@ -2870,7 +2789,7 @@ <menu create_jump_keys="true" label="World" - name="World" + name="DevelopWorld" tear_off="true"> <menu_item_check label="Sim Sun Override" @@ -2883,16 +2802,6 @@ parameter="SkyOverrideSimSunPosition" /> </menu_item_check> <menu_item_check - label="Cheesy Beacon" - name="Cheesy Beacon"> - <menu_item_check.on_check - function="CheckControl" - parameter="CheesyBeacon" /> - <menu_item_check.on_click - function="ToggleControl" - parameter="CheesyBeacon" /> - </menu_item_check> - <menu_item_check label="Fixed Weather" name="Fixed Weather"> <menu_item_check.on_check @@ -3116,7 +3025,7 @@ tear_off="true"> <menu_item_call label="Iris" - name="Iris"> + name="Grab Iris"> <menu_item_call.on_click function="Advanced.GrabBakedTexture" parameter="iris" /> @@ -3126,7 +3035,7 @@ </menu_item_call> <menu_item_call label="Head" - name="Head"> + name="Grab Head"> <menu_item_call.on_click function="Advanced.GrabBakedTexture" parameter="head" /> @@ -3136,7 +3045,7 @@ </menu_item_call> <menu_item_call label="Upper Body" - name="Upper Body"> + name="Grab Upper Body"> <menu_item_call.on_click function="Advanced.GrabBakedTexture" parameter="upper" /> @@ -3146,7 +3055,7 @@ </menu_item_call> <menu_item_call label="Lower Body" - name="Lower Body"> + name="Grab Lower Body"> <menu_item_call.on_click function="Advanced.GrabBakedTexture" parameter="lower" /> @@ -3156,7 +3065,7 @@ </menu_item_call> <menu_item_call label="Skirt" - name="Skirt"> + name="Grab Skirt"> <menu_item_call.on_click function="Advanced.GrabBakedTexture" parameter="skirt" /> @@ -3475,10 +3384,11 @@ <menu create_jump_keys="true" label="Object" + name="AdminObject" tear_off="true"> <menu_item_call label="Take Copy" - name="Take Copy" + name="Admin Take Copy" shortcut="control|alt|shift|O"> <menu_item_call.on_click function="Admin.ForceTakeCopy" /> @@ -3747,7 +3657,7 @@ <menu create_jump_keys="true" label="Help" - name="Help" + name="DeprecatedHelp" tear_off="true"> <menu_item_call label="Official Linden Blog" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 1daf2e6948..af75d49353 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -203,34 +203,80 @@ Save changes to current clothing/body part? icon="alertmodal.tga" name="ConfirmNoCopyToOutbox" type="alertmodal"> - You don't have permission to copy this item to the Marketplace Outbox. Are you sure you want to move the following item? - [ITEM_NAME] +You don't have permission to copy one or more of these items to the Merchant Outbox. You can move them or leave them behind. + <usetemplate + name="okcancelbuttons" + notext="Don't move item(s)" + yestext="Move item(s)"/> + </notification> + + <notification + icon="OutboxStatus_Success" + name="OutboxFolderCreated" + type="outbox"> + <unique/> +A new folder has been created for each item you have transferred into the top level of your Merchant Outbox. + + <usetemplate + ignoretext="A new folder was created in the Merchant Outbox" + name="okignore" + yestext="OK"/> + </notification> + + <notification + icon="OutboxStatus_Success" + name="OutboxImportComplete" + type="outbox"> +Success + +All folders were successfully sent to the Marketplace. + <usetemplate - name="okcancelbuttons" - notext="No" - yestext="Yes"/> - </notification> + ignoretext="All folders sent to the Marketplace" + name="okignore" + yestext="OK"/> + </notification> <notification - icon="alertmodal.tga" - name="OutboxUploadComplete" - type="alertmodal"> -Marketplace upload complete. + icon="OutboxStatus_Warning" + name="OutboxImportHadErrors" + type="outbox"> +Some folders did not transfer + +Errors occurred when some folders were sent to the Marketplace. Those folders are still in your Merchant Outbox. + +See the [[MARKETPLACE_IMPORTS_URL] error log] for more information. + <usetemplate name="okbutton" - yestext="Hooray!"/> + yestext="OK"/> </notification> <notification - icon="alertmodal.tga" - name="OutboxUploadHadErrors" - type="alertmodal"> -Marketplace upload completed with errors! Please correct the problems in your outbox and retry. Thanks. + icon="OutboxStatus_Error" + name="OutboxImportFailed" + type="outbox"> +Transfer failed + +No folders were sent to the Marketplace because of a system or network error. Try again later. + <usetemplate name="okbutton" - yestext="Boo!"/> + yestext="OK"/> </notification> + <notification + icon="OutboxStatus_Error" + name="OutboxInitFailed" + type="outbox"> +Marketplace initialization failed + +Initialization with the Marketplace failed because of a system or network error. Try again later. + + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> <notification diff --git a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml index 93cafd4a53..d68fa6ca6c 100644 --- a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml +++ b/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml @@ -27,8 +27,7 @@ mouse_opaque="false" width="147" top="0" - name="speakers_list_panel" - user_resize="false"> + name="speakers_list_panel"> <avatar_list color="DkGray2" follows="all" @@ -50,7 +49,6 @@ min_height="25" width="130" name="call_btn_panel" - user_resize="false" visible="false"> <button follows="all" @@ -68,7 +66,6 @@ min_height="25" width="130" name="end_call_btn_panel" - user_resize="false" visible="false"> <button follows="all" @@ -85,7 +82,6 @@ min_height="25" width="130" name="voice_ctrls_btn_panel" - user_resize="false" visible="false"> <button follows="all" diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml index b5e1a5f16d..f4722b05d6 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml @@ -31,7 +31,6 @@ width="1000"> <layout_panel auto_resize="false" - user_resize="false" min_width="2" width="2" /> <layout_panel @@ -40,8 +39,7 @@ height="28" layout="topleft" width="310" - min_width="188" - user_resize="false"> + min_width="188"> <panel left="0" filename="panel_nearby_chat_bar.xml" @@ -61,8 +59,7 @@ width="82" top_delta="0" min_width="52" - name="gesture_panel" - user_resize="false"> + name="gesture_panel"> <gesture_combo_list follows="left|right" height="23" @@ -80,7 +77,6 @@ </layout_panel> <layout_panel auto_resize="false" - user_resize="false" min_width="3" name="after_gesture_panel" width="3"/> diff --git a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml index 41d1036a4d..ff0146490b 100644 --- a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml @@ -27,8 +27,8 @@ min_width="95" mouse_opaque="false" name="chiclet_list_panel" + auto_resize="true" top="0" - user_resize="false" width="189"> <chiclet_panel chiclet_padding="4" @@ -78,7 +78,6 @@ </chiclet_panel> </layout_panel> <layout_panel auto_resize="false" - user_resize="false" width="4" min_width="4"/> <layout_panel @@ -90,7 +89,6 @@ min_width="37" name="im_well_panel" top="0" - user_resize="false" width="37"> <chiclet_im_well follows="right" @@ -139,7 +137,6 @@ image_pressed_selected "Lit" + "Selected" - there are new messages and the Well min_width="37" name="notification_well_panel" top="0" - user_resize="false" width="37"> <chiclet_notification follows="right" diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml index 6c8d994bc6..d4a2745d1d 100644 --- a/indra/newview/skins/default/xui/en/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml @@ -289,8 +289,7 @@ left="0" top="0" width="290" - height="16" - user_resize="false"> + height="16"> <text follows="left|top" font.style="BOLD" @@ -327,8 +326,7 @@ left="0" top="0" width="290" - height="16" - user_resize="false"> + height="16"> <text follows="left|top" font.style="BOLD" @@ -357,8 +355,7 @@ left="0" top="0" width="290" - height="215" - user_resize="false"> + height="215"> <text auto_resize="false" follows="left|top" @@ -416,7 +413,6 @@ layout="bottomleft" left="0" name="layout_panel1" - user_resize="false" auto_resize="true" width="101"> <button @@ -436,7 +432,6 @@ layout="bottomleft" left_pad="3" name="show_on_map_btn_lp" - user_resize="false" auto_resize="true" width="100"> <button @@ -455,7 +450,6 @@ layout="bottomleft" left_pad="3" name="edit_btn_lp" - user_resize="false" auto_resize="true" width="101"> <button diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml index e512d63f9e..3509eaa285 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml @@ -319,7 +319,6 @@ layout="bottomleft" left="0" name="save_changes_btn_lp" - user_resize="false" auto_resize="true" width="156"> <button @@ -339,7 +338,6 @@ layout="bottomleft" left_pad="3" name="show_on_map_btn_lp" - user_resize="false" auto_resize="true" width="157"> <button diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml index 2ec2e03e8c..0faa1598b1 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml @@ -201,7 +201,6 @@ layout="topleft" left="0" name="layout_panel1" - user_resize="false" auto_resize="true" width="150"> <button @@ -221,7 +220,6 @@ layout="topleft" left_pad="4" name="layout_panel2" - user_resize="false" auto_resize="true" width="146"> <button diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml index 442eb8c28d..2c7c8133d1 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml @@ -435,7 +435,6 @@ layout="bottomleft" name="save_changes_btn_lp" top="0" - user_resize="false" auto_resize="true" width="153"> <button @@ -456,7 +455,6 @@ left_pad="3" name="show_on_map_btn_lp" top="0" - user_resize="false" auto_resize="true" width="154"> <button diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml index c8764a6a84..69a692e2c4 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -454,7 +454,6 @@ left="0" mouse_opaque="false" name="save_as_btn_lp" - user_resize="false" auto_resize="true" width="154"> <button @@ -474,7 +473,6 @@ left_pad="3" mouse_opaque="false" name="revert_btn_lp" - user_resize="false" auto_resize="true" width="152"> <button diff --git a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml index c1dc2aaaf7..ad10e53a4e 100644 --- a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml +++ b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml @@ -26,8 +26,7 @@ mouse_opaque="false" width="145" top="0" - name="speakers_list_panel" - user_resize="false"> + name="speakers_list_panel"> <avatar_list color="DkGray2" follows="all" @@ -48,8 +47,7 @@ layout="topleft" min_height="28" width="130" - name="group_info_btn_panel" - user_resize="false"> + name="group_info_btn_panel"> <button follows="left|right|bottom" height="23" @@ -66,8 +64,7 @@ layout="topleft" min_height="28" width="130" - name="call_btn_panel" - user_resize="false"> + name="call_btn_panel"> <button follows="all" height="23" @@ -84,7 +81,6 @@ min_height="28" width="130" name="end_call_btn_panel" - user_resize="false" visible="false"> <button follows="all" @@ -101,7 +97,6 @@ min_height="28" width="130" name="voice_ctrls_btn_panel" - user_resize="false" visible="false"> <button follows="all" diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml index ec3f3b48bc..206496cc0e 100644 --- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml @@ -97,6 +97,7 @@ background_visible="true" follows="all" layout="topleft" auto_resize="true" + user_resize="true" height="513" width="313"> <accordion @@ -195,7 +196,6 @@ background_visible="true" layout="bottomleft" left="0" name="btn_refresh_lp" - user_resize="false" auto_resize="false" width="24"> <button @@ -215,7 +215,6 @@ background_visible="true" layout="bottomleft" left_pad="3" name="btn_chat_lp" - user_resize="false" auto_resize="true" width="91"> <button @@ -234,7 +233,6 @@ background_visible="true" layout="bottomleft" left_pad="3" name="call_btn_lp" - user_resize="false" auto_resize="true" width="91"> <button @@ -255,7 +253,6 @@ background_visible="true" layout="bottomleft" left_pad="3" name="btn_apply_lp" - user_resize="false" auto_resize="true" width="91"> <button diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml index 9f73b7c540..8fcd6ccbaf 100644 --- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml +++ b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml @@ -32,8 +32,7 @@ min_height="20" width="140" name="view_profile_btn_panel" - top="0" - user_resize="false"> + top="0" > <button follows="left|top|right" height="23" @@ -49,8 +48,7 @@ layout="topleft" min_height="25" width="140" - name="add_friend_btn_panel" - user_resize="false"> + name="add_friend_btn_panel"> <button follows="left|top|right" height="23" @@ -66,8 +64,7 @@ layout="topleft" min_height="25" width="140" - name="teleport_btn_panel" - user_resize="false"> + name="teleport_btn_panel"> <button auto_resize="false" follows="left|top|right" @@ -84,8 +81,7 @@ layout="topleft" min_height="25" width="140" - name="share_btn_panel" - user_resize="false"> + name="share_btn_panel"> <button auto_resize="true" follows="left|top|right" @@ -101,8 +97,7 @@ layout="topleft" min_height="25" width="140" - name="pay_btn_panel" - user_resize="false"> + name="pay_btn_panel"> <button auto_resize="true" follows="left|top|right" @@ -118,8 +113,7 @@ layout="topleft" min_height="25" width="140" - name="call_btn_panel" - user_resize="false"> + name="call_btn_panel"> <button follows="left|top|right" height="23" @@ -135,7 +129,6 @@ min_height="25" width="140" name="end_call_btn_panel" - user_resize="false" visible="false"> <button follows="left|top|right" @@ -152,7 +145,6 @@ min_height="25" width="140" name="voice_ctrls_btn_panel" - user_resize="false" visible="false"> <button follows="left|top|right" @@ -169,7 +161,6 @@ layout="topleft" min_height="0" width="140" - name="spacer" - user_resize="false" /> + name="spacer"/> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml index 23d8cb11ca..2a5933e3e9 100644 --- a/indra/newview/skins/default/xui/en/panel_landmarks.xml +++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml @@ -114,7 +114,6 @@ height="25" layout="topleft" name="options_gear_btn_panel" - user_resize="false" width="32"> <menu_button follows="bottom|left" @@ -135,7 +134,6 @@ height="25" layout="topleft" name="add_btn_panel" - user_resize="false" width="32"> <button follows="bottom|left" @@ -156,7 +154,6 @@ height="25" layout="topleft" name="dummy_panel" - user_resize="false" width="212"> <icon follows="bottom|left|right" @@ -173,7 +170,6 @@ height="25" layout="topleft" name="trash_btn_panel" - user_resize="false" width="31"> <dnd_button follows="bottom|left" diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index 6521bf2a4e..223326dd06 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -48,7 +48,6 @@ name="login" layout="topleft" width="705" min_width="705" -user_resize="false" height="80"> <text follows="left|bottom" @@ -165,7 +164,6 @@ follows="right|bottom" name="links" width="205" min_width="205" -user_resize="false" height="80"> <text follows="right|bottom" diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml index e6c5110999..d6d8b2a83e 100644 --- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - background_visible="true" default_tab_group="1" follows="all" height="423" @@ -51,10 +50,6 @@ top="18" width="303" /> <tab_container - bg_alpha_color="DkGray" - bg_opaque_color="DkGray" - background_visible="true" - background_opaque="true" follows="all" halign="center" height="339" @@ -71,7 +66,6 @@ bg_opaque_color="DkGray2" bg_alpha_color="DkGray2" background_visible="true" - background_opaque="true" border="false" bevel_style="none" follows="all" @@ -90,7 +84,6 @@ bg_opaque_color="DkGray2" bg_alpha_color="DkGray2" background_visible="true" - background_opaque="true" border="false" bevel_style="none" follows="all" @@ -119,7 +112,6 @@ height="25" layout="topleft" name="options_gear_btn_panel" - user_resize="false" width="32"> <menu_button follows="bottom|left" @@ -140,7 +132,6 @@ height="25" layout="topleft" name="add_btn_panel" - user_resize="false" width="32"> <button follows="bottom|left" @@ -161,7 +152,6 @@ height="25" layout="topleft" name="dummy_panel" - user_resize="false" width="212"> <icon follows="bottom|left|right" @@ -178,7 +168,6 @@ height="25" layout="topleft" name="trash_btn_panel" - user_resize="false" width="31"> <dnd_button follows="bottom|left" diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml index 7a8e872dc9..4bf420b79f 100644 --- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml @@ -54,11 +54,11 @@ width="800" height="2"/> <layout_stack - use_border="true" - bevel_style="none" follows="all" height="34" layout="topleft" + border_size="0" + resize_bar_overlap="3" left="0" mouse_opaque="false" name="nvp_stack" @@ -73,130 +73,130 @@ min_width="480" name="navigation_layout_panel" width="480"> - <panel - background_visible="false" - follows="left|top|right" - top="3" - height="23" - layout="topleft" - left="0" - name="navigation_panel" - width="480"> - <pull_button - follows="left|top" - direction="down" - height="23" - image_overlay="Arrow_Left_Off" - image_bottom_pad="1" - layout="topleft" - left="10" - name="back_btn" - tool_tip="Go back to previous location" - top="2" - width="31" /> - <pull_button - follows="left|top" - direction="down" - height="23" - image_overlay="Arrow_Right_Off" - image_bottom_pad="1" - layout="topleft" - left_pad="0" - name="forward_btn" - tool_tip="Go forward one location" - top_delta="0" - width="31" /> - <button - follows="left|top" - height="23" - image_bottom_pad="1" - image_overlay="Home_Off" - layout="topleft" - left_pad="7" - name="home_btn" - tool_tip="Teleport to my home location" - top_delta="0" - width="32" /> - <location_input - follows="all" - halign="right" - height="23" - label="Location" - layout="topleft" - left_pad="7" - max_chars="254" - mouse_opaque="false" - name="location_combo" - top_delta="0" - width="355"> - <combo_list - mouse_wheel_opaque="true"/> - </location_input> - </panel> - </layout_panel> - - <layout_panel - auto_resize="false" - layout="topleft" - max_width="5" - min_width="5" - name="nav_bar_resize_handle_panel" - user_resize="false" - width="5"> - <icon - follows="top|right" - height="25" - image_name="ChatBarHandle" - layout="topleft" - left="-6" - name="resize_handle" - top="4" - width="5" /> - </layout_panel> - + <panel + background_visible="false" + follows="left|top|right" + top="3" + height="23" + layout="topleft" + left="0" + name="navigation_panel" + width="480"> + <pull_button + follows="left|top" + direction="down" + height="23" + image_overlay="Arrow_Left_Off" + image_bottom_pad="1" + layout="topleft" + left="10" + name="back_btn" + tool_tip="Go back to previous location" + top="2" + width="31" /> + <pull_button + follows="left|top" + direction="down" + height="23" + image_overlay="Arrow_Right_Off" + image_bottom_pad="1" + layout="topleft" + left_pad="0" + name="forward_btn" + tool_tip="Go forward one location" + top_delta="0" + width="31" /> + <button + follows="left|top" + height="23" + image_bottom_pad="1" + image_overlay="Home_Off" + layout="topleft" + left_pad="7" + name="home_btn" + tool_tip="Teleport to my home location" + top_delta="0" + width="32" /> + <location_input + follows="all" + halign="right" + height="23" + label="Location" + layout="topleft" + left_pad="7" + max_chars="254" + mouse_opaque="false" + name="location_combo" + top_delta="0" + width="355"> + <combo_list + mouse_wheel_opaque="true"/> + </location_input> + </panel> + <icon + follows="top|right" + height="25" + image_name="ChatBarHandle" + layout="topleft" + left="-3" + name="resize_handle" + top="4" + width="5" /> + </layout_panel> <layout_panel follows="top|left" - layout="topleft" + layout="topleft" auto_resize="true" user_resize="true" min_width="315" name="favorites_layout_panel" width="315"> - <favorites_bar - follows="left|right|top" - font="SansSerifSmall" - height="20" - layout="topleft" - left="0" - name="favorite" - image_drag_indication="Accordion_ArrowOpened_Off" - tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!" - width="311"> - <label - follows="left|top" - height="15" - layout="topleft" - left="10" - name="favorites_bar_label" - text_color="LtGray" - tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!" - top="12" - width="102"> - Favorites Bar - </label> - <!-- More button actually is a text box. --> - <more_button - follows="left|bottom" - name=">>" - tab_stop="false" - tool_tip="Show more of My Favorites" - top="13" - width="50" - bottom="0" - valign="bottom"> - More ▼ - </more_button> - </favorites_bar> + <icon + follows="top|left" + height="25" + image_name="ChatBarHandle" + layout="topleft" + left="-318" + name="resize_handle" + top="4" + width="5" /> + + <favorites_bar + follows="left|right|top" + font="SansSerifSmall" + height="20" + layout="topleft" + left="0" + top="4" + name="favorite" + image_drag_indication="Accordion_ArrowOpened_Off" + tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!" + width="311"> + <label + follows="left|top" + height="15" + layout="topleft" + left="10" + name="favorites_bar_label" + text_color="LtGray" + tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!" + top="12" + width="102"> + Favorites Bar + </label> + <!-- More button actually is a text box. --> + <more_button + follows="left|bottom" + name=">>" + tab_stop="false" + tool_tip="Show more of My Favorites" + top="13" + width="50" + bottom="0" + valign="bottom"> + More ▼ + </more_button> + </favorites_bar> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/en/panel_nearby_media.xml b/indra/newview/skins/default/xui/en/panel_nearby_media.xml index bfc503f05b..d1cb64f7ad 100644 --- a/indra/newview/skins/default/xui/en/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/en/panel_nearby_media.xml @@ -196,7 +196,6 @@ name="stop" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" height="22" @@ -224,7 +223,6 @@ name="play" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" height="22" @@ -252,7 +250,6 @@ name="pause" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" min_width="22" @@ -279,7 +276,6 @@ name="volume_slider_ctrl" mouse_opaque="false" auto_resize="true" - user_resize="false" follows="left|right" layout="topleft" top="0" @@ -304,7 +300,6 @@ name="mute" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" height="72" @@ -333,7 +328,6 @@ name="zoom" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" height="28" @@ -361,7 +355,6 @@ name="unzoom" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" min_width="21" @@ -388,8 +381,7 @@ <layout_panel name="right_bookend" width="0" - mouse_opaque="false" - user_resize="false" /> + mouse_opaque="false"/> </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml index 66117615e4..a3d39e55af 100644 --- a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml @@ -8,7 +8,6 @@ bg_opaque_color="DkGray2" bg_alpha_color="DkGray2" background_visible="true" - background_opaque="true" border="false" bevel_style="none" show_item_link_overlays="true" diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index e1cd78bad8..b61f110e32 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -198,7 +198,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap height="154" name="add_button_and_combobox" width="311" - user_resize="false" visible="true"> <!-- List containing items from the COF and Base outfit --> @@ -271,8 +270,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap height="30" name="filter_panel" width="311" - visible="false" - user_resize="false"> + visible="false"> <filter_editor background_image="TextField_Search_Off" @@ -515,7 +513,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap left="0" mouse_opaque="false" name="save_btn_lp" - user_resize="false" auto_resize="true" width="156"> <button @@ -550,7 +547,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap left_pad="3" mouse_opaque="false" name="revert_btn_lp" - user_resize="false" auto_resize="true" width="147"> <button diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml index 2ad2416179..405d9513db 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml @@ -84,7 +84,6 @@ left="0" mouse_opaque="false" name="save_btn_lp" - user_resize="false" auto_resize="true" width="156"> <button @@ -118,7 +117,6 @@ left_pad="3" mouse_opaque="false" name="wear_btn_lp" - user_resize="false" auto_resize="true" width="147"> <button diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 0ebfd9c037..98c7c49ff4 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -284,7 +284,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M height="25" layout="topleft" name="options_gear_btn_panel" - user_resize="false" width="32"> <menu_button follows="bottom|left" @@ -305,7 +304,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M height="25" layout="topleft" name="add_btn_panel" - user_resize="false" width="32"> <button follows="bottom|left" @@ -326,7 +324,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M height="25" layout="topleft" name="dummy_panel" - user_resize="false" width="210"> <icon follows="bottom|left|right" @@ -343,7 +340,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M height="25" layout="topleft" name="trash_btn_panel" - user_resize="false" width="31"> <dnd_button follows="bottom|left" @@ -602,7 +598,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M layout="bottomleft" left="0" name="view_profile_btn_lp" - user_resize="false" auto_resize="true" width="68"> <button @@ -623,7 +618,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M layout="bottomleft" left_pad="3" name="im_btn_lp" - user_resize="false" auto_resize="true" width="41"> <button @@ -644,7 +638,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M layout="bottomleft" left_pad="3" name="call_btn_lp" - user_resize="false" auto_resize="true" width="52"> <button @@ -665,7 +658,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M layout="bottomleft" left_pad="3" name="share_btn_lp" - user_resize="false" auto_resize="true" width="66"> <button @@ -686,7 +678,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M layout="bottomleft" left_pad="3" name="teleport_btn_lp" - user_resize="false" auto_resize="true" width="77"> <button @@ -720,7 +711,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M left="0" mouse_opaque="false" name="group_info_btn_lp" - user_resize="false" auto_resize="true" width="108"> <button @@ -743,7 +733,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M left_pad="3" mouse_opaque="false" name="chat_btn_lp" - user_resize="false" auto_resize="true" width="101"> <button @@ -766,7 +755,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M left_pad="3" mouse_opaque="false" name="group_call_btn_lp" - user_resize="false" auto_resize="true" width="96"> <button diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml index 24046d5cca..79d190e1e0 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml @@ -139,7 +139,6 @@ layout="bottomleft" left="0" name="layout_panel1" - user_resize="false" auto_resize="true" width="101"> <button @@ -158,7 +157,6 @@ layout="bottomleft" left_pad="3" name="show_on_map_btn_lp" - user_resize="false" auto_resize="true" width="100"> <button @@ -177,7 +175,6 @@ layout="bottomleft" left_pad="3" name="edit_btn_lp" - user_resize="false" auto_resize="true" width="101"> <button diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml index 85f402dfa2..8def96cada 100644 --- a/indra/newview/skins/default/xui/en/panel_picks.xml +++ b/indra/newview/skins/default/xui/en/panel_picks.xml @@ -102,7 +102,6 @@ bg_opaque_color="DkGray2" layout="bottomleft" left="0" name="gear_menu_btn" - user_resize="false" auto_resize="true" width="51"> <button @@ -124,7 +123,6 @@ bg_opaque_color="DkGray2" height="18" layout="bottomleft" name="trash_btn_lp" - user_resize="false" auto_resize="true" width="18"> <button @@ -170,7 +168,6 @@ bg_opaque_color="DkGray2" layout="topleft" left="0" name="info_btn_lp" - user_resize="false" auto_resize="true" top="0" width="95"> @@ -192,7 +189,6 @@ bg_opaque_color="DkGray2" layout="bottomleft" left_pad="2" name="teleport_btn_lp" - user_resize="false" auto_resize="true" width="117"> <button @@ -212,7 +208,6 @@ bg_opaque_color="DkGray2" height="28" layout="bottomleft" name="show_on_map_btn_lp" - user_resize="false" auto_resize="true" left_pad="2" width="90"> diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml index e280115bda..308acf0c0c 100644 --- a/indra/newview/skins/default/xui/en/panel_place_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml @@ -238,7 +238,6 @@ mouse_opaque="false" name="here_panel" top="0" - user_resize="false" width="60"> <icon follows="top|left" @@ -259,7 +258,6 @@ mouse_opaque="false" name="for_sale_panel" top="0" - user_resize="false" width="60"> <icon follows="top|left" diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index 670aa47313..f169dbb702 100644 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -92,7 +92,6 @@ background_visible="true" left="0" mouse_opaque="false" name="lp1" - user_resize="false" auto_resize="true" width="193"> @@ -115,7 +114,6 @@ background_visible="true" left="0" mouse_opaque="false" name="teleport_btn_lp" - user_resize="false" auto_resize="true" width="109"> <button @@ -137,7 +135,6 @@ background_visible="true" left_pad="3" mouse_opaque="false" name="chat_btn_lp" - user_resize="false" auto_resize="true" width="86"> <button @@ -161,7 +158,6 @@ background_visible="true" left_pad="0" mouse_opaque="false" name="lp2" - user_resize="false" auto_resize="true" width="116"> @@ -185,7 +181,6 @@ background_visible="true" left_pad="0" mouse_opaque="false" name="edit_btn_lp" - user_resize="false" auto_resize="true" width="84"> <button @@ -208,7 +203,6 @@ background_visible="true" left_pad="0" mouse_opaque="false" name="overflow_btn_lp" - user_resize="false" auto_resize="true" width="24"> <menu_button @@ -246,7 +240,6 @@ background_visible="true" left_pad="3" mouse_opaque="false" name="profile_btn_lp" - user_resize="false" auto_resize="true" width="102"> <button @@ -283,7 +276,6 @@ background_visible="true" mouse_opaque="false" name="close_btn_lp" top="0" - user_resize="false" auto_resize="true" width="51"> <button @@ -324,7 +316,6 @@ background_visible="true" mouse_opaque="false" name="save_btn_lp" top="0" - user_resize="false" auto_resize="true" width="153"> <button @@ -347,7 +338,6 @@ background_visible="true" mouse_opaque="false" name="cancel_btn_lp" top="0" - user_resize="false" auto_resize="true" width="154"> <button diff --git a/indra/newview/skins/default/xui/en/panel_postcard_settings.xml b/indra/newview/skins/default/xui/en/panel_postcard_settings.xml index 2e0bb88f53..e9427a2388 100644 --- a/indra/newview/skins/default/xui/en/panel_postcard_settings.xml +++ b/indra/newview/skins/default/xui/en/panel_postcard_settings.xml @@ -50,7 +50,6 @@ layout="topleft" left="0" name="postcard_image_size_lp" - user_resize="false" auto_resize="false" top="0" right="-1" @@ -99,7 +98,6 @@ layout="topleft" left="0" name="postcard_image_format_quality_lp" - user_resize="false" auto_resize="true" top="0" right="-1" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml index 47236c1a48..587c461bee 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml @@ -59,7 +59,6 @@ top_pad="30" width="350" /> <check_box - enabled_control="EnableVoiceChat" control_name="VoiceCallsFriendsOnly" height="16" label="Only friends and groups can call or IM me" diff --git a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml index 273c252474..198ccd6e2f 100644 --- a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml +++ b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml @@ -31,8 +31,7 @@ width="0" name="left_bookend_bottom" mouse_opaque="false" - layout="topleft" - user_resize="false" /> + layout="topleft"/> <layout_panel name="media_progress_indicator" mouse_opaque="false" @@ -41,7 +40,6 @@ left="0" top="0" auto_resize="false" - user_resize="false" min_width="100" width="200"> <progress_bar @@ -59,8 +57,7 @@ name="right_bookend_bottom" width="0" mouse_opaque="false" - layout="topleft" - user_resize="false" /> + layout="topleft"/> </layout_stack> <layout_stack name="media_controls" @@ -79,13 +76,11 @@ top="0" width="0" mouse_opaque="false" - layout="topleft" - user_resize="false" /> + layout="topleft"/> <layout_panel name="back" top="0" auto_resize="false" - user_resize="false" layout="topleft" mouse_opaque="false" min_width="22" @@ -114,7 +109,6 @@ name="fwd" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" min_width="22" top="0" @@ -142,7 +136,6 @@ name="home" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" height="22" @@ -170,7 +163,6 @@ name="media_stop" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" height="22" @@ -198,7 +190,6 @@ name="reload" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" height="22" @@ -226,7 +217,6 @@ name="stop" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" height="22" @@ -254,7 +244,6 @@ name="play" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" height="22" @@ -282,7 +271,6 @@ name="pause" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" min_width="22" @@ -310,7 +298,6 @@ name="media_address" mouse_opaque="false" auto_resize="true" - user_resize="false" height="24" follows="left|right|bottom" layout="topleft" @@ -343,8 +330,7 @@ layout="topleft" width="16" mouse_opaque="false" - auto_resize="false" - user_resize="false"> + auto_resize="false"> <icon name="media_whitelist_flag" follows="top|right" @@ -358,8 +344,7 @@ layout="topleft" width="16" mouse_opaque="false" - auto_resize="false" - user_resize="false"> + auto_resize="false"> <icon name="media_secure_lock_flag" height="16" @@ -374,7 +359,6 @@ name="media_play_position" mouse_opaque="false" auto_resize="true" - user_resize="false" follows="left|right" layout="topleft" top="0" @@ -399,7 +383,6 @@ name="skip_back" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" min_width="22" @@ -428,7 +411,6 @@ name="skip_forward" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" min_width="22" @@ -455,7 +437,6 @@ name="media_volume" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" height="72" @@ -511,7 +492,6 @@ name="zoom_frame" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" height="28" @@ -539,7 +519,6 @@ name="close" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" min_width="21" @@ -567,7 +546,6 @@ name="new_window" mouse_opaque="false" auto_resize="false" - user_resize="false" layout="topleft" top="0" min_width="22" @@ -596,8 +574,7 @@ mouse_opaque="false" top="0" width="0" - layout="topleft" - user_resize="false" /> + layout="topleft"/> </layout_stack> <panel name="media_region" diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml index 4535c56339..860caf2d21 100644 --- a/indra/newview/skins/default/xui/en/panel_progress.xml +++ b/indra/newview/skins/default/xui/en/panel_progress.xml @@ -12,45 +12,43 @@ height="768" layout="topleft" left="0" - name="stack1" + name="horizontal_centering" orientation="horizontal" top="0" width="1024"> <layout_panel layout="topleft" min_width="10" - name="panel1" - user_resize="false" + name="left" width="150" /> <layout_panel height="768" layout="topleft" - min_width="640" - name="panel2" - user_resize="false" - width="640"> + min_width="670" + name="center" + width="670"> <layout_stack follows="left|right|top|bottom" height="768" layout="topleft" left="0" orientation="vertical" - name="stack2" + name="vertical_centering" top="0" - width="640"> + width="670"> <layout_panel height="200" layout="topleft" min_height="10" name="panel3" - width="640" /> + width="670" /> <layout_panel auto_resize="false" height="250" layout="topleft" min_height="250" name="panel4" - width="640"> + width="670"> <icon color="LoginProgressBoxCenterColor" follows="left|right|bottom|top" @@ -59,7 +57,7 @@ layout="topleft" left="0" top="0" - width="640" /> + width="670" /> <text follows="left|right|top" font="SansSerifHuge" @@ -71,7 +69,7 @@ name="title_text" text_color="LoginProgressBoxTextColor" top_delta="50" - width="593" /> + right="-47"/> <text follows="left|right|top" font="SansSerif" @@ -83,7 +81,7 @@ name="progress_text" text_color="LoginProgressBoxTextColor" top_pad="5" - width="593" + right="-47" word_wrap="true"/> <progress_bar bottom="115" @@ -106,7 +104,7 @@ name="message_text" text_color="LoginProgressBoxTextColor" top="145" - width="550" + right="-90" word_wrap="true"/> </layout_panel> <layout_panel @@ -114,14 +112,13 @@ layout="topleft" min_width="10" name="panel5" - width="640" /> + width="670" /> </layout_stack> </layout_panel> <layout_panel layout="topleft" min_width="10" - name="panel6" - user_resize="false" + name="right" width="150" /> </layout_stack> <button diff --git a/indra/newview/skins/default/xui/en/panel_region_estate.xml b/indra/newview/skins/default/xui/en/panel_region_estate.xml index 6b28639a77..bfd796a62b 100644 --- a/indra/newview/skins/default/xui/en/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/en/panel_region_estate.xml @@ -134,26 +134,26 @@ name="Only Allow" top_delta="-30" width="278"> - Restrict Access to accounts verified by: + Allow access only to Residents who: </text> <check_box follows="top|left" height="16" - label="Payment Information on File" + label="Have payment information on file" layout="topleft" left_delta="0" name="limit_payment" - tool_tip="Ban unidentified Residents" + tool_tip="Residents must have payment information on file to access this estate. See the [SUPPORT_SITE] for more information." top_pad="2" width="278" /> <check_box follows="top|left" height="16" - label="Age Verification" + label="Have been age-verified" layout="topleft" left_delta="0" name="limit_age_verified" - tool_tip="Ban Residents who have not verified their age. See the [SUPPORT_SITE] for more information." + tool_tip="Residents must be age verified to access this estate. See the [SUPPORT_SITE] for more information." top_pad="2" width="278" /> diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_local.xml b/indra/newview/skins/default/xui/en/panel_snapshot_local.xml index ae0215a578..b966358f18 100644 --- a/indra/newview/skins/default/xui/en/panel_snapshot_local.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_local.xml @@ -96,7 +96,6 @@ layout="topleft" left="0" name="local_image_size_lp" - user_resize="false" auto_resize="false" top="0" right="-1" @@ -145,7 +144,6 @@ layout="topleft" left="0" name="local_image_format_quality_lp" - user_resize="false" auto_resize="true" top="0" right="-1" diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml index 91ac9ad658..5bd383b81e 100644 --- a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml @@ -84,7 +84,6 @@ layout="topleft" left="0" name="profile_image_size_lp" - user_resize="false" auto_resize="false" top="0" right="-1" @@ -132,7 +131,6 @@ layout="topleft" left="0" name="profile_image_metadata_lp" - user_resize="false" auto_resize="true" top="0" right="-1" diff --git a/indra/newview/skins/default/xui/en/panel_toolbar_view.xml b/indra/newview/skins/default/xui/en/panel_toolbar_view.xml index 3c69a0cb6c..58911bed56 100644 --- a/indra/newview/skins/default/xui/en/panel_toolbar_view.xml +++ b/indra/newview/skins/default/xui/en/panel_toolbar_view.xml @@ -20,7 +20,6 @@ mouse_opaque="false"> <layout_panel name="vertical_toolbar_panel" auto_resize="true" - user_resize="false" width="1024" height="500" mouse_opaque="false"> @@ -34,7 +33,6 @@ mouse_opaque="false"> <layout_panel name="left_toolbar_panel" auto_resize="false" - user_resize="false" height="500" width="30" mouse_opaque="false"> @@ -61,7 +59,6 @@ </layout_panel> <layout_panel name="non_toolbar_panel" auto_resize="true" - user_resize="false" mouse_opaque="false" height="100" width="200"> @@ -102,7 +99,6 @@ </layout_panel> <layout_panel name="right_toolbar_panel" auto_resize="false" - user_resize="false" height="500" width="30" mouse_opaque="false"> @@ -132,7 +128,6 @@ </layout_panel> <layout_panel name="bottom_toolbar_panel" auto_resize="false" - user_resize="false" height="30" width="1024" mouse_opaque="false"> diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml index b52784d6bc..fcba937bdb 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - background_visible="true" follows="all" height="570" label="Things" @@ -30,11 +29,12 @@ width="330"> <layout_panel name="main_inventory_layout_panel" - layout="topleft" + layout="topleft" + auto_resize="true" + user_resize="true" min_dim="150" width="330" follows="bottom|left|right" - user_resize="false" height="300"> <panel class="panel_main_inventory" @@ -48,41 +48,18 @@ height="300" width="330" /> </layout_panel> - <layout_panel - width="330" - layout="topleft" - auto_resize="true" - user_resize="false" - follows="bottom|left|right" - name="inbox_outbox_layout_panel" - visible="false" - min_dim="35" - max_dim="235" - expanded_min_dim="125" - height="235"> - <layout_stack - follows="left|right|top|bottom" - layout="topleft" - left="0" - top="0" - orientation="vertical" - name="inbox_outbox_layout_stack" - open_time_constant="0.02" - close_time_constant="0.02" - height="235" - width="330"> - <layout_panel + <layout_panel width="330" - layout="topleft" + layout="topleft" auto_resize="true" - user_resize="false" + user_resize="true" follows="left|right|top" name="inbox_layout_panel" visible="false" min_dim="35" - max_dim="200" + max_dim="235" expanded_min_dim="90" - height="200"> + height="235"> <panel follows="all" layout="topleft" @@ -91,13 +68,13 @@ class="panel_marketplace_inbox" top="0" label="" - height="200" + height="235" width="330"> <string name="InboxLabelWithArg">Received items ([NUM])</string> <string name="InboxLabelNoArg">Received items</string> <button label="Received items" - font="SansSerifMedium" + font="SansSerifMedium" name="inbox_btn" height="35" width="308" @@ -129,7 +106,7 @@ <panel follows="all" left="10" - bottom="200" + bottom="235" width="308" top="35" bg_opaque_color="InventoryBackgroundColor" @@ -145,7 +122,7 @@ top="0" left="0" width="308" - height="165" + height="200" wrap="true" halign="center"> Purchases from the marketplace will be delivered here. @@ -153,139 +130,6 @@ </panel> </panel> </layout_panel> - <layout_panel - width="330" - layout="topleft" - auto_resize="true" - user_resize="false" - follows="all" - name="outbox_layout_panel" - visible="false" - min_dim="35" - max_dim="200" - expanded_min_dim="90" - height="200"> - <panel - follows="all" - layout="topleft" - left="0" - name="marketplace_outbox" - class="panel_marketplace_outbox" - top="0" - label="" - height="200" - width="330"> - <string name="OutboxLabelWithArg">Merchant outbox ([NUM])</string> - <string name="OutboxLabelNoArg">Merchant outbox</string> - <button - label="Merchant outbox" - font="SansSerifMedium" - name="outbox_btn" - height="35" - width="308" - image_unselected="MarketplaceBtn_Off" - image_selected="MarketplaceBtn_Selected" - halign="left" - handle_right_mouse="false" - follows="top|left|right" - is_toggle="true" - tab_stop="false" - pad_left="35" - top="0" - left="10" /> - <button - image_unselected="OutboxPush_Off" - image_selected="OutboxPush_Selected" - image_hover_selected="OutboxPush_Selected_Over" - image_hover_unselected="OutboxPush_Over" - image_disabled_selected="OutboxPush_Selected_Disabled" - image_disabled="OutboxPush_Disabled" - image_pressed="OutboxPush_Press" - image_pressed_selected="OutboxPush_Selected_Press" - label="" - tool_tip="Push to my Marketplace Storefront" - is_toggle="false" - name="outbox_sync_btn" - follows="top|right" - tab_stop="false" - halign="center" - top="6" - left="-50" - height="23" - width="32" - enabled="false" /> - <loading_indicator - follows="top|right" - name="outbox_sync_indicator" - top="6" - left="-50" - height="23" - width="32" - images_per_sec="1.15" - tab_stop="false" - visible="false"> - <images> - <image name="OutboxPush_Progress_1"/> - <image name="OutboxPush_Progress_2"/> - <image name="OutboxPush_Progress_3"/> - <image name="OutboxPush_Progress_4"/> - <image name="OutboxPush_Progress_5"/> - <image name="OutboxPush_Progress_6"/> - </images> - </loading_indicator> - <panel - follows="all" - left="10" - bottom="200" - width="308" - top="35" - bg_opaque_color="InventoryBackgroundColor" - background_visible="true" - background_opaque="true" - > - <panel - name="outbox_inventory_placeholder_panel" - follows="all" - layout="topleft" - top="0" - left="0" - width="308" - height="165" - bg_opaque_color="InventoryBackgroundColor" - background_visible="true" - background_opaque="true" - > - <text - name="outbox_inventory_placeholder_title" - type="string" - follows="all" - layout="topleft" - top="10" - left="0" - width="308" - height="25" - wrap="true" - halign="center" - font="SansSerifBold"> - Loading... - </text> - <text - name="outbox_inventory_placeholder_text" - type="string" - follows="all" - layout="topleft" - top="35" - left="0" - width="308" - height="130" - wrap="true" - halign="left" /> - </panel> - </panel> - </panel> - </layout_panel> - </layout_stack> - </layout_panel> </layout_stack> <panel follows="bottom|left|right" @@ -312,7 +156,6 @@ left="0" mouse_opaque="false" name="info_btn_lp" - user_resize="false" auto_resize="true" width="101"> <button @@ -334,7 +177,6 @@ left_pad="1" mouse_opaque="false" name="share_btn_lp" - user_resize="false" auto_resize="true" width="100"> <button @@ -356,7 +198,6 @@ left_pad="1" mouse_opaque="false" name="shop_btn_lp" - user_resize="false" auto_resize="true" width="100"> <button @@ -406,8 +247,7 @@ </layout_stack> </panel> </panel> - -<panel + <panel follows="all" layout="topleft" left="0" @@ -420,8 +260,7 @@ visible="false" width="330"> </panel> - -<panel + <panel follows="all" layout="topleft" left="0" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 8d6d4801bf..d2ccf7a396 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -18,7 +18,7 @@ <string name="StartupClearingCache">Clearing cache...</string> <string name="StartupInitializingTextureCache">Initializing texture cache...</string> <string name="StartupInitializingVFS">Initializing VFS...</string> - <string name="StartupRequireDriverUpdate">Graphics initialization failed. Please update your graphics driver!</string> + <string name="StartupRequireDriverUpdate">Graphics initialization failed. Please update your graphics driver!</string> <!-- progress --> <string name="ProgressRestoring">Restoring...</string> @@ -35,9 +35,9 @@ <string name="LoginAttempt">Previous login attempt failed. Logging in, attempt [NUMBER]</string> <string name="LoginPrecaching">Loading world...</string> <string name="LoginInitializingBrowser">Initializing embedded web browser...</string> - <string name="LoginInitializingMultimedia">Initializing multimedia...</string> - <string name="LoginInitializingFonts">Loading fonts...</string> - <string name="LoginVerifyingCache">Verifying cache files (can take 60-90 seconds)...</string> + <string name="LoginInitializingMultimedia">Initializing multimedia...</string> + <string name="LoginInitializingFonts">Loading fonts...</string> + <string name="LoginVerifyingCache">Verifying cache files (can take 60-90 seconds)...</string> <string name="LoginProcessingResponse">Processing response...</string> <string name="LoginInitializingWorld">Initializing world...</string> <string name="LoginDecodingImages">Decoding images...</string> @@ -49,12 +49,12 @@ <string name="LoginWaitingForRegionHandshake">Waiting for region handshake...</string> <string name="LoginConnectingToRegion">Connecting to region...</string> <string name="LoginDownloadingClothing">Downloading clothing...</string> - <string name="InvalidCertificate">The server returned an invalid or corrupt certificate. Please contact the Grid administrator.</string> - <string name="CertInvalidHostname">An invalid hostname was used to access the server, please check your SLURL or Grid hostname.</string> - <string name="CertExpired">The certificate returned by the Grid appears to be expired. Please check your system clock, or contact your Grid administrator.</string> - <string name="CertKeyUsage">The certificate returned by the server could not be used for SSL. Please contact your Grid administrator.</string> - <string name="CertBasicConstraints">Too many certificates were in the servers Certificate chain. Please contact your Grid administrator.</string> - <string name="CertInvalidSignature">The certificate signature returned by the Grid server could not be verified. Please contact your Grid administrator.</string> + <string name="InvalidCertificate">The server returned an invalid or corrupt certificate. Please contact the Grid administrator.</string> + <string name="CertInvalidHostname">An invalid hostname was used to access the server, please check your SLURL or Grid hostname.</string> + <string name="CertExpired">The certificate returned by the Grid appears to be expired. Please check your system clock, or contact your Grid administrator.</string> + <string name="CertKeyUsage">The certificate returned by the server could not be used for SSL. Please contact your Grid administrator.</string> + <string name="CertBasicConstraints">Too many certificates were in the servers Certificate chain. Please contact your Grid administrator.</string> + <string name="CertInvalidSignature">The certificate signature returned by the Grid server could not be verified. Please contact your Grid administrator.</string> <string name="LoginFailedNoNetwork">Network error: Could not establish connection, please check your network connection.</string> <string name="LoginFailed">Login failed.</string> @@ -164,11 +164,19 @@ Please try logging in again in a minute.</string> <string name="TooltipLand">Land:</string> <string name="TooltipMustSingleDrop">Only a single item can be dragged here</string> <string name="TooltipPrice" value="L$[AMOUNT]: "/> - <string name="TooltipOutboxNoTransfer">One or more of these objects cannot be sold or transferred to another user.</string> - <string name="TooltipOutboxWorn">You are wearing one or more of these objects. Remove them from your avatar and try moving them again.</string> - <string name="TooltipOutboxFolderLevels">This folder has too many levels of subfolders. Rearrange the interior folders to a maximum of 4 levels deep (Root Folder contains A contains B contains C).</string> - <string name="TooltipOutboxTooManyObjects">This folder contains more than 200 objects. Box some of the items to reduce the object count.</string> + <string name="TooltipOutboxDragToWorld">You can not rez items in your merchant outbox</string> + <string name="TooltipOutboxNoTransfer">One or more of these objects cannot be sold or transferred.</string> + <string name="TooltipOutboxNotInInventory">Your merchant outbox can only accept items directly from your inventory</string> + <string name="TooltipOutboxWorn">You can not put items you are wearing into your merchant outbox</string> + <string name="TooltipOutboxCallingCard">You can not put calling cards into your merchant outbox</string> + <string name="TooltipOutboxFolderLevels">Depth of nested folders exceeds 3</string> + <string name="TooltipOutboxTooManyFolders">Subfolder count in top-level folder exceeds 20</string> + <string name="TooltipOutboxTooManyObjects">Item count in top-level folder exceeds 200</string> + + <string name="TooltipDragOntoOwnChild">You can't move a folder into its child</string> + <string name="TooltipDragOntoSelf">You can't move a folder into itself</string> + <!-- tooltips for Urls --> <string name="TooltipHttpUrl">Click to view this web page</string> <string name="TooltipSLURL">Click to view this location's information</string> @@ -2029,24 +2037,28 @@ Returns a string with the requested data about the region <string name="PlacesNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search].</string> <string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string> <string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string> - <string name="InventoryInboxNoItems">When you purchase or otherwise receive an item, it will appear here so you can drag it to a folder in your inventory, or delete it if you do not wish to keep it.</string> - <string name="MarketplaceURL">http://marketplace.[DOMAIN_NAME]</string> - <string name="MarketplaceURL_CreateStore">http://marketplace.[DOMAIN_NAME]/create_store</string> - <string name="MarketplaceURL_LearnMore">http://marketplace.[DOMAIN_NAME]/learn_more</string> - <string name="InventoryOutboxCreationErrorTitle">Your Merchant Outbox is not properly configured</string> - <string name="InventoryOutboxCreationErrorTooltip">Merchant Outbox configuration error</string> - <string name="InventoryOutboxCreationError">Please contact Customer Service to correct the problem.</string> - <string name="InventoryOutboxNotMerchantTitle">Anyone can sell items on the Marketplace</string> - <string name="InventoryOutboxNotMerchantTooltip">Become a merchant!</string> - <string name="InventoryOutboxNotMerchant">[[MARKETPLACE_URL] The Second Life Marketplace] offers more than one million virtual products for sale, all of them created by Residents. You, too, can sell items you create, as well as some of the items you have purchased. It’s easy and setup is free. [[LEARN_MORE_URL] Learn more] or [[CREATE_STORE_URL] create a store] on the Marketplace to get started.</string> - <string name="InventoryOutboxNoItemsTitle">A new way to send items to the Marketplace</string> - <string name="InventoryOutboxNoItemsTooltip">Drag and drop items here to prepare them for sale on the Marketplace</string> - <string name="InventoryOutboxNoItems">Drag items or folders that you wish to sell into this area. A copy of the item will appear, leaving your inventory unchanged, unless you have dragged a no-copy item. When you are ready to send the items to the Marketplace, click the Upload button. Once your items have been moved to your Marketplace Inventory, they will disappear from this folder.</string> + <string name="InventoryInboxNoItems">Certain items you receive, such as premium gifts, will appear here. You may then drag them into your inventory.</string> + <string name="MarketplaceURL">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/</string> + <string name="MarketplaceURL_CreateStore">http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4</string> + <string name="MarketplaceURL_Dashboard">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard</string> + <string name="MarketplaceURL_Imports">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports</string> + <string name="MarketplaceURL_LearnMore">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more</string> + <string name="InventoryOutboxNotMerchantTitle">Anyone can sell items on the Marketplace.</string> + <string name="InventoryOutboxNotMerchantTooltip"></string> + <string name="InventoryOutboxNotMerchant"> +If you'd like to become a merchant, you'll need to [[MARKETPLACE_CREATE_STORE_URL] create a Marketplace store]. + </string> + <string name="InventoryOutboxNoItemsTitle">Your outbox is empty.</string> + <string name="InventoryOutboxNoItemsTooltip"></string> + <string name="InventoryOutboxNoItems"> +Drag folders to this area and click "Send to Marketplace" to list them for sale on the [[MARKETPLACE_DASHBOARD_URL] Marketplace]. + </string> <string name="Marketplace Error None">No errors</string> <string name="Marketplace Error Not Merchant">Error: Before sending items to the Marketplace you will need to set yourself up as a merchant (free of charge).</string> <string name="Marketplace Error Empty Folder">Error: This folder has no contents.</string> - <string name="Marketplace Error Unassociated Products">Error: This item failed to upload because your merchant account has too many items unassociated with products. To fix this error, login to the marketplace website and reduce your unassociated item count.</string> + <string name="Marketplace Error Unassociated Products">Error: This item failed to upload because your merchant account has too many items unassociated with products. To fix this error, log in to the marketplace website and reduce your unassociated item count.</string> + <string name="Marketplace Error Object Limit">Error: This item contains too many objects. Fix this error by placing objects together in boxes to reduce the total count to less than 200.</string> <string name="Marketplace Error Folder Depth">Error: This item contains too many levels of nested folders. Reorganize it to a maximum of 3 levels of nested folders.</string> <string name="Marketplace Error Unsellable Item">Error: This item can not be sold on the marketplace.</string> @@ -3681,6 +3693,7 @@ Try enclosing path to the editor with double quotes. <string name="Command_Marketplace_Label">Marketplace</string> <string name="Command_MiniMap_Label">Mini-map</string> <string name="Command_Move_Label">Walk / run / fly</string> + <string name="Command_Outbox_Label">Merchant outbox</string> <string name="Command_Pathfinding_Label">Pathfinding</string> <string name="Command_People_Label">People</string> <string name="Command_PF_Linksets_Label">Pathfinding Linksets</string> @@ -3708,6 +3721,7 @@ Try enclosing path to the editor with double quotes. <string name="Command_Marketplace_Tooltip">Go shopping</string> <string name="Command_MiniMap_Tooltip">Show nearby people</string> <string name="Command_Move_Tooltip">Moving your avatar</string> + <string name="Command_Outbox_Tooltip">Transfer items to your marketplace for sale</string> <string name="Command_Pathfinding_Tooltip">Information about pathfinding</string> <string name="Command_People_Tooltip">Friends, groups, and nearby people</string> <string name="Command_PF_Linksets_Tooltip">Manipulation of pathfinding linksets</string> diff --git a/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml b/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml index 0792996107..d19c47f54f 100644 --- a/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml +++ b/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml @@ -6,14 +6,4 @@ item_top_pad="4" selection_image="Rounded_Square" > - <error_badge - label=" " - label_offset_horiz="-1" - location="right" - padding_horiz="12.5" - padding_vert="2" - location_offset_hcenter="-23" - image="Error_Tag_Background" - image_color="Black" - /> </outbox_folder_view_folder> diff --git a/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml index e3f2072819..3964569da2 100644 --- a/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml +++ b/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<outbox_inventory_panel show_load_status="false" /> +<outbox_inventory_panel show_empty_message="false" show_load_status="false" /> diff --git a/indra/newview/skins/default/xui/pl/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml index c072ea9b5a..24c961fa26 100644 --- a/indra/newview/skins/default/xui/pl/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pl/menu_viewer.xml @@ -20,8 +20,6 @@ <menu_item_call label="Tryb oddalenia" name="Set Away"/> <menu_item_call label="Tryb pracy" name="Set Busy"/> </menu> - <menu_item_call label="Zażądaj statusu administratora" name="Request Admin Options"/> - <menu_item_call label="Wyłącz atatus administratora" name="Leave Admin Options"/> <menu_item_call label="Wyłącz [APP_NAME]" name="Quit"/> </menu> <menu label="Komunikacja" name="Communicate"> @@ -36,11 +34,10 @@ <menu_item_check label="Szukaj" name="Search"/> <menu_item_call label="Zrób zdjęcie" name="Take Snapshot"/> <menu_item_call label="Zapamiętaj to miejsce (LM)" name="Create Landmark Here"/> - <menu label="Miejsce" name="Land"> - <menu_item_call label="Profil miejsca" name="Place Profile"/> - <menu_item_call label="O posiadłości" name="About Land"/> - <menu_item_call label="Region/Majątek" name="Region/Estate"/> - </menu> + <menu_item_separator/> + <menu_item_call label="Profil miejsca" name="Place Profile"/> + <menu_item_call label="O posiadłości" name="About Land"/> + <menu_item_call label="Region/Majątek" name="Region/Estate"/> <menu_item_call label="Kup posiadłość" name="Buy Land"/> <menu_item_call label="Moje posiadłości" name="My Land"/> <menu label="Pokaż" name="LandShow"> @@ -56,7 +53,7 @@ </menu> <menu_item_call label="Teleportuj do Miejsca Startu" name="Teleport Home"/> <menu_item_call label="Ustaw Miejsce Startu" name="Set Home to Here"/> - <menu label="Słońce" name="Environment Settings"> + <menu label="Słońce" name="Sun"> <menu_item_call label="Wschód Słońca" name="Sunrise"/> <menu_item_call label="Południe" name="Noon"/> <menu_item_call label="Zachód Słońca" name="Sunset"/> @@ -153,22 +150,22 @@ <menu_item_check label="Pokaż celownik myszki" name="ShowCrosshairs"/> </menu> <menu label="Rodzaje renderowania" name="Rendering Types"> - <menu_item_check label="Podstawowe" name="Simple"/> - <menu_item_check label="Maska alpha" name="Alpha"/> - <menu_item_check label="Drzewo" name="Tree"/> - <menu_item_check label="Awatary" name="Character"/> - <menu_item_check label="Płaszczyzna powierzchni" name="SurfacePath"/> - <menu_item_check label="Niebo" name="Sky"/> - <menu_item_check label="Woda" name="Water"/> - <menu_item_check label="Ziemia" name="Ground"/> - <menu_item_check label="Głośność" name="Volume"/> - <menu_item_check label="Trawa" name="Grass"/> - <menu_item_check label="Chmury" name="Clouds"/> - <menu_item_check label="Cząsteczki" name="Particles"/> - <menu_item_check label="Zderzenie" name="Bump"/> + <menu_item_check label="Podstawowe" name="Rendering Type Simple"/> + <menu_item_check label="Maska alpha" name="Rendering Type Alpha"/> + <menu_item_check label="Drzewo" name="Rendering Type Tree"/> + <menu_item_check label="Awatary" name="Rendering Type Character"/> + <menu_item_check label="Płaszczyzna powierzchni" name="Rendering Type Surface Patch"/> + <menu_item_check label="Niebo" name="Rendering Type Sky"/> + <menu_item_check label="Woda" name="Rendering Type Water"/> + <menu_item_check label="Ziemia" name="Rendering Type Ground"/> + <menu_item_check label="Głośność" name="Rendering Type Volume"/> + <menu_item_check label="Trawa" name="Rendering Type Grass"/> + <menu_item_check label="Chmury" name="Rendering Type Clouds"/> + <menu_item_check label="Cząsteczki" name="Rendering Type Particles"/> + <menu_item_check label="Zderzenie" name="Rendering Type Bump"/> </menu> <menu label="Opcje renderowania" name="Rendering Features"> - <menu_item_check label="UI" name="UI"/> + <menu_item_check label="UI" name="ToggleUI"/> <menu_item_check label="Zaznaczone" name="Selected"/> <menu_item_check label="Podświetlenie" name="Highlighted"/> <menu_item_check label="Tekstury dynamiczne" name="Dynamic Textures"/> @@ -180,10 +177,7 @@ <menu_item_call label="Wyczyść bufor danych grupy" name="ClearGroupCache"/> <menu_item_check label="Wygładzanie ruchu myszki" name="Mouse Smoothing"/> <menu label="Skróty" name="Shortcuts"> - <menu_item_call label="Obraz (L$[COST])..." name="Upload Image"/> - <menu_item_check label="Szukaj" name="Search"/> <menu_item_call label="Zwolnij klawisze" name="Release Keys"/> - <menu_item_call label="Domyślne ustawienia rozmiaru interfejsu" name="Set UI Size to Default"/> <menu_item_check label="Pokaż menu Zaawansowane - skrót" name="Show Advanced Menu - legacy shortcut"/> <menu_item_call label="Zamknij okno" name="Close Window"/> <menu_item_call label="Zamknij wszystkie okna" name="Close All Windows"/> @@ -192,13 +186,6 @@ <menu_item_check label="Wolna kamera" name="Joystick Flycam"/> <menu_item_call label="Reset widoku" name="Reset View"/> <menu_item_call label="Zobacz ostatniego rozmówcę" name="Look at Last Chatter"/> - <menu label="Wybierz narzędzie budowania" name="Select Tool"> - <menu_item_call label="Narzędzie ogniskowej" name="Focus"/> - <menu_item_call label="Narzędzie ruchu" name="Move"/> - <menu_item_call label="Narzędzie edycji" name="Edit"/> - <menu_item_call label="Stwórz narzędzie" name="Create"/> - <menu_item_call label="Narzędzia posiadłości" name="Land"/> - </menu> <menu_item_call label="Przybliż" name="Zoom In"/> <menu_item_call label="Domyślne przybliżenie" name="Zoom Default"/> <menu_item_call label="Oddal" name="Zoom Out"/> @@ -267,9 +254,8 @@ <menu_item_call label="Upuść pakiet pamięci" name="Drop a Packet"/> </menu> <menu_item_call label="Zderzenia, popchnięcia & uderzenia" name="Bumps, Pushes &amp; Hits"/> - <menu label="Świat" name="World"> + <menu label="Świat" name="DevelopWorld"> <menu_item_check label="Domyślne ustawienia środowiska Regionu" name="Sim Sun Override"/> - <menu_item_check label="Efekty emiterów" name="Cheesy Beacon"/> <menu_item_check label="Ustalona pogoda" name="Fixed Weather"/> <menu_item_call label="Zachowaj bufor pamięci obiektów regionu" name="Dump Region Object Cache"/> </menu> @@ -291,11 +277,11 @@ </menu> <menu label="Awatar" name="Character"> <menu label="Przesuń bakowaną teksturę" name="Grab Baked Texture"> - <menu_item_call label="Tęczówka oka" name="Iris"/> - <menu_item_call label="Głowa" name="Head"/> - <menu_item_call label="Górna część ciała" name="Upper Body"/> - <menu_item_call label="Dolna część ciała" name="Lower Body"/> - <menu_item_call label="Spódnica" name="Skirt"/> + <menu_item_call label="Tęczówka oka" name="Grab Iris"/> + <menu_item_call label="Głowa" name="Grab Head"/> + <menu_item_call label="Górna część ciała" name="Grab Upper Body"/> + <menu_item_call label="Dolna część ciała" name="Grab Lower Body"/> + <menu_item_call label="Spódnica" name="Grab Skirt"/> </menu> <menu label="Testy postaci" name="Character Tests"> <menu_item_call label="Przesuń geometrię postaci" name="Toggle Character Geometry"/> @@ -316,8 +302,8 @@ <menu_item_check label="Pokaż menu administratora" name="View Admin Options"/> </menu> <menu label="Administrator" name="Admin"> - <menu label="Object"> - <menu_item_call label="Weź kopię" name="Take Copy"/> + <menu label="Object" name="AdminObject"> + <menu_item_call label="Weź kopię" name="Admin Take Copy"/> <menu_item_call label="Reset właściciela" name="Force Owner To Me"/> <menu_item_call label="Reset przyzwolenia właściciela" name="Force Owner Permissive"/> <menu_item_call label="Usuń" name="Delete"/> diff --git a/indra/newview/skins/default/xui/zh/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml index f7be781cac..b6bb79bcbc 100644 --- a/indra/newview/skins/default/xui/zh/menu_viewer.xml +++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml @@ -20,8 +20,6 @@ <menu_item_call label="離開" name="Set Away"/> <menu_item_call label="忙碌" name="Set Busy"/> </menu> - <menu_item_call label="要求 Admin 狀態" name="Request Admin Options"/> - <menu_item_call label="離開 Admin 狀態" name="Leave Admin Options"/> <menu_item_call label="結束退出 [APP_NAME]" name="Quit"/> </menu> <menu label="溝通" name="Communicate"> @@ -36,11 +34,10 @@ <menu_item_check label="搜尋" name="Search"/> <menu_item_call label="拍攝快照" name="Take Snapshot"/> <menu_item_call label="將此處記下地標" name="Create Landmark Here"/> - <menu label="地點檔案" name="Land"> - <menu_item_call label="地點檔案" name="Place Profile"/> - <menu_item_call label="關於土地" name="About Land"/> - <menu_item_call label="地區 / 領地" name="Region/Estate"/> - </menu> + <menu_item_separator/> + <menu_item_call label="地點檔案" name="Place Profile"/> + <menu_item_call label="關於土地" name="About Land"/> + <menu_item_call label="地區 / 領地" name="Region/Estate"/> <menu_item_call label="購買這塊土地" name="Buy Land"/> <menu_item_call label="我的土地" name="My Land"/> <menu label="顯示" name="LandShow"> @@ -56,7 +53,7 @@ </menu> <menu_item_call label="瞬間瞬間傳送回家" name="Teleport Home"/> <menu_item_call label="設定家在此處" name="Set Home to Here"/> - <menu label="太陽" name="Environment Settings"> + <menu label="太陽" name="Sun"> <menu_item_call label="日出" name="Sunrise"/> <menu_item_call label="中午" name="Noon"/> <menu_item_call label="日落" name="Sunset"/> @@ -154,22 +151,22 @@ <menu_item_check label="顯示第一人稱視角準星" name="ShowCrosshairs"/> </menu> <menu label="Rendering Types" name="Rendering Types"> - <menu_item_check label="簡單" name="Simple"/> - <menu_item_check label="半透明" name="Alpha"/> - <menu_item_check label="樹木" name="Tree"/> - <menu_item_check label="化身" name="Character"/> - <menu_item_check label="地表" name="SurfacePath"/> - <menu_item_check label="天空" name="Sky"/> - <menu_item_check label="水文" name="Water"/> - <menu_item_check label="地面" name="Ground"/> - <menu_item_check label="體積" name="Volume"/> - <menu_item_check label="草地" name="Grass"/> - <menu_item_check label="雲彩" name="Clouds"/> - <menu_item_check label="粒子效果" name="Particles"/> - <menu_item_check label="碰撞" name="Bump"/> + <menu_item_check label="簡單" name="Rendering Type Simple"/> + <menu_item_check label="半透明" name="Rendering Type Alpha"/> + <menu_item_check label="樹木" name="Rendering Type Tree"/> + <menu_item_check label="化身" name="Rendering Type Character"/> + <menu_item_check label="地表" name="Rendering Type Surface Patch"/> + <menu_item_check label="天空" name="Rendering Type Sky"/> + <menu_item_check label="水文" name="Rendering Type Water"/> + <menu_item_check label="地面" name="Rendering Type Ground"/> + <menu_item_check label="體積" name="Rendering Type Volume"/> + <menu_item_check label="草地" name="Rendering Type Grass"/> + <menu_item_check label="雲彩" name="Rendering Type Clouds"/> + <menu_item_check label="粒子效果" name="Rendering Type Particles"/> + <menu_item_check label="碰撞" name="Rendering Type Bump"/> </menu> <menu label="Rendering Features" name="Rendering Features"> - <menu_item_check label="UI" name="UI"/> + <menu_item_check label="UI" name="ToggleUI"/> <menu_item_check label="Selected" name="Selected"/> <menu_item_check label="Highlighted" name="Highlighted"/> <menu_item_check label="Dynamic Textures" name="Dynamic Textures"/> @@ -182,10 +179,7 @@ <menu_item_call label="清除群組快取資料" name="ClearGroupCache"/> <menu_item_check label="滑鼠平滑移動" name="Mouse Smoothing"/> <menu label="快速鍵" name="Shortcuts"> - <menu_item_call label="圖像(L$[COST])..." name="Upload Image"/> - <menu_item_check label="搜尋" name="Search"/> <menu_item_call label="釋出按鍵" name="Release Keys"/> - <menu_item_call label="設定使用者界面大小至預設值" name="Set UI Size to Default"/> <menu_item_check label="顯示進階選單 - 舊版捷徑" name="Show Advanced Menu - legacy shortcut"/> <menu_item_call label="關閉視窗" name="Close Window"/> <menu_item_call label="關閉全部視窗" name="Close All Windows"/> @@ -194,13 +188,6 @@ <menu_item_check label="Joystick Flycam" name="Joystick Flycam"/> <menu_item_call label="重設視角" name="Reset View"/> <menu_item_call label="注視上一位聊天者" name="Look at Last Chatter"/> - <menu label="選擇建造工具" name="Select Tool"> - <menu_item_call label="聚焦工具" name="Focus"/> - <menu_item_call label="移動工具" name="Move"/> - <menu_item_call label="編輯工具" name="Edit"/> - <menu_item_call label="創造工具" name="Create"/> - <menu_item_call label="土地工具" name="Land"/> - </menu> <menu_item_call label="Zoom In" name="Zoom In"/> <menu_item_call label="Zoom Default" name="Zoom Default"/> <menu_item_call label="Zoom Out" name="Zoom Out"/> @@ -306,9 +293,8 @@ <menu_item_call label="開始錄製" name="Start Record"/> <menu_item_call label="停止錄製" name="Stop Record"/> </menu> - <menu label="世界" name="World"> + <menu label="世界" name="DevelopWorld"> <menu_item_check label="模擬器太陽設定覆蓋" name="Sim Sun Override"/> - <menu_item_check label="Cheesy Beacon" name="Cheesy Beacon"/> <menu_item_check label="固定天氣" name="Fixed Weather"/> <menu_item_call label="傾印地區物件快取" name="Dump Region Object Cache"/> </menu> @@ -340,11 +326,11 @@ </menu> <menu label="化身" name="Character"> <menu label="Grab Baked Texture" name="Grab Baked Texture"> - <menu_item_call label="Iris" name="Iris"/> - <menu_item_call label="頭部" name="Head"/> - <menu_item_call label="Upper Body" name="Upper Body"/> - <menu_item_call label="Lower Body" name="Lower Body"/> - <menu_item_call label="裙子" name="Skirt"/> + <menu_item_call label="Iris" name="Grab Iris"/> + <menu_item_call label="頭部" name="Grab Head"/> + <menu_item_call label="Upper Body" name="Grab Upper Body"/> + <menu_item_call label="Lower Body" name="Grab Lower Body"/> + <menu_item_call label="裙子" name="Grab Skirt"/> </menu> <menu label="Character Tests" name="Character Tests"> <menu_item_call label="Appearance To XML" name="Appearance To XML"/> @@ -378,8 +364,8 @@ <menu_item_check label="Show Admin Menu" name="View Admin Options"/> </menu> <menu label="Admin" name="Admin"> - <menu label="Object"> - <menu_item_call label="取得副本" name="Take Copy"/> + <menu label="Object" name="AdminObject"> + <menu_item_call label="取得副本" name="Admin Take Copy"/> <menu_item_call label="強制擁有者為我" name="Force Owner To Me"/> <menu_item_call label="Force Owner Permissive" name="Force Owner Permissive"/> <menu_item_call label="刪除" name="Delete"/> @@ -415,7 +401,7 @@ <menu_item_call label="身體物理" name="Physics"/> <menu_item_call label="全部衣服" name="All Clothes"/> </menu> - <menu label="幫助" name="Help"> + <menu label="幫助" name="DeprecatedHelp"> <menu_item_call label="林登官方部落格" name="Official Linden Blog"/> <menu_item_call label="Scripting Portal" name="Scripting Portal"/> <menu label="臭蟲回報" name="Bug Reporting"> |