diff options
78 files changed, 1215 insertions, 313 deletions
| diff --git a/doc/contributions.txt b/doc/contributions.txt index 52371a365a..49c9c2cb1d 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -190,7 +190,12 @@ Ansariel Hiller  	STORM-2094  	MAINT-5756  	MAINT-4677 +	MAINT-6300 +	MAINT-6397  	MAINT-6432 +	MAINT-6513 +	MAINT-6514 +	MAINT-6552  	STORM-2133  Aralara Rajal  Arare Chantilly @@ -789,6 +794,7 @@ Kitty Barnett  	MAINT-6152  	MAINT-6153  	MAINT-6154 +	MAINT-6568  Kolor Fall  Komiko Okamoto  Korvel Noh @@ -1264,6 +1270,7 @@ Sovereign Engineer      MAINT-6107      STORM-2107      MAINT-6218 +    MAINT-2141  SpacedOut Frye  	VWR-34  	VWR-45 diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index a548c96002..86f407cdb0 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -294,9 +294,11 @@ void LLScopedLock::unlock()  bool ll_apr_warn_status(apr_status_t status)  {  	if(APR_SUCCESS == status) return false; +#if !LL_LINUX  	char buf[MAX_STRING];	/* Flawfinder: ignore */  	apr_strerror(status, buf, sizeof(buf));  	LL_WARNS("APR") << "APR: " << buf << LL_ENDL; +#endif  	return true;  } diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp index 645c29d770..e38fc5b2a6 100644 --- a/indra/llcommon/llevents.cpp +++ b/indra/llcommon/llevents.cpp @@ -275,6 +275,8 @@ LLEventPumps::~LLEventPumps()  #pragma warning (push)  #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally  #endif +const std::string LLEventPump::ANONYMOUS = std::string(); +  LLEventPump::LLEventPump(const std::string& name, bool tweak):      // Register every new instance with LLEventPumps @@ -313,145 +315,162 @@ LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventL                                           const NameList& after,                                           const NameList& before)  { -    // Check for duplicate name before connecting listener to mSignal -    ConnectionMap::const_iterator found = mConnections.find(name); -    // In some cases the user might disconnect a connection explicitly -- or -    // might use LLEventTrackable to disconnect implicitly. Either way, we can -    // end up retaining in mConnections a zombie connection object that's -    // already been disconnected. Such a connection object can't be -    // reconnected -- nor, in the case of LLEventTrackable, would we want to -    // try, since disconnection happens with the destruction of the listener -    // object. That means it's safe to overwrite a disconnected connection -    // object with the new one we're attempting. The case we want to prevent -    // is only when the existing connection object is still connected. -    if (found != mConnections.end() && found->second.connected()) -    { -        throw DupListenerName(std::string("Attempt to register duplicate listener name '") + name + -                              "' on " + typeid(*this).name() + " '" + getName() + "'"); -    } -    // Okay, name is unique, try to reconcile its dependencies. Specify a new -    // "node" value that we never use for an mSignal placement; we'll fix it -    // later. -    DependencyMap::node_type& newNode = mDeps.add(name, -1.0, after, before); -    // What if this listener has been added, removed and re-added? In that -    // case newNode already has a non-negative value because we never remove a -    // listener from mDeps. But keep processing uniformly anyway in case the -    // listener was added back with different dependencies. Then mDeps.sort() -    // would put it in a different position, and the old newNode placement -    // value would be wrong, so we'd have to reassign it anyway. Trust that -    // re-adding a listener with the same dependencies is the trivial case for -    // mDeps.sort(): it can just replay its cache. -    DependencyMap::sorted_range sorted_range; -    try -    { -        // Can we pick an order that works including this new entry? -        sorted_range = mDeps.sort(); -    } -    catch (const DependencyMap::Cycle& e) -    { -        // No: the new node's after/before dependencies have made mDeps -        // unsortable. If we leave the new node in mDeps, it will continue -        // to screw up all future attempts to sort()! Pull it out. -        mDeps.remove(name); -        throw Cycle(std::string("New listener '") + name + "' on " + typeid(*this).name() + -                    " '" + getName() + "' would cause cycle: " + e.what()); -    } -    // Walk the list to verify that we haven't changed the order. -    float previous = 0.0, myprev = 0.0; -    DependencyMap::sorted_iterator mydmi = sorted_range.end(); // need this visible after loop -    for (DependencyMap::sorted_iterator dmi = sorted_range.begin(); -         dmi != sorted_range.end(); ++dmi) +    float nodePosition = 1.0; + +    // if the supplied name is empty we are not interested in the ordering mechanism  +    // and can bypass attempting to find the optimal location to insert the new  +    // listener.  We'll just tack it on to the end. +    if (!name.empty()) // should be the same as testing against ANONYMOUS      { -        // Since we've added the new entry with an invalid placement, -        // recognize it and skip it. -        if (dmi->first == name) +        // Check for duplicate name before connecting listener to mSignal +        ConnectionMap::const_iterator found = mConnections.find(name); +        // In some cases the user might disconnect a connection explicitly -- or +        // might use LLEventTrackable to disconnect implicitly. Either way, we can +        // end up retaining in mConnections a zombie connection object that's +        // already been disconnected. Such a connection object can't be +        // reconnected -- nor, in the case of LLEventTrackable, would we want to +        // try, since disconnection happens with the destruction of the listener +        // object. That means it's safe to overwrite a disconnected connection +        // object with the new one we're attempting. The case we want to prevent +        // is only when the existing connection object is still connected. +        if (found != mConnections.end() && found->second.connected())          { -            // Remember the iterator belonging to our new node, and which -            // placement value was 'previous' at that point. -            mydmi = dmi; -            myprev = previous; -            continue; +            throw DupListenerName(std::string("Attempt to register duplicate listener name '") + name + +                "' on " + typeid(*this).name() + " '" + getName() + "'");          } -        // If the new node has rearranged the existing nodes, we'll find -        // that their placement values are no longer in increasing order. -        if (dmi->second < previous) +        // Okay, name is unique, try to reconcile its dependencies. Specify a new +        // "node" value that we never use for an mSignal placement; we'll fix it +        // later. +        DependencyMap::node_type& newNode = mDeps.add(name, -1.0, after, before); +        // What if this listener has been added, removed and re-added? In that +        // case newNode already has a non-negative value because we never remove a +        // listener from mDeps. But keep processing uniformly anyway in case the +        // listener was added back with different dependencies. Then mDeps.sort() +        // would put it in a different position, and the old newNode placement +        // value would be wrong, so we'd have to reassign it anyway. Trust that +        // re-adding a listener with the same dependencies is the trivial case for +        // mDeps.sort(): it can just replay its cache. +        DependencyMap::sorted_range sorted_range; +        try          { -            // This is another scenario in which we'd better back out the -            // newly-added node from mDeps -- but don't do it yet, we want to -            // traverse the existing mDeps to report on it! -            // Describe the change to the order of our listeners. Copy -            // everything but the newest listener to a vector we can sort to -            // obtain the old order. -            typedef std::vector< std::pair<float, std::string> > SortNameList; -            SortNameList sortnames; -            for (DependencyMap::sorted_iterator cdmi(sorted_range.begin()), cdmend(sorted_range.end()); -                 cdmi != cdmend; ++cdmi) +            // Can we pick an order that works including this new entry? +            sorted_range = mDeps.sort(); +        } +        catch (const DependencyMap::Cycle& e) +        { +            // No: the new node's after/before dependencies have made mDeps +            // unsortable. If we leave the new node in mDeps, it will continue +            // to screw up all future attempts to sort()! Pull it out. +            mDeps.remove(name); +            throw Cycle(std::string("New listener '") + name + "' on " + typeid(*this).name() + +                " '" + getName() + "' would cause cycle: " + e.what()); +        } +        // Walk the list to verify that we haven't changed the order. +        float previous = 0.0, myprev = 0.0; +        DependencyMap::sorted_iterator mydmi = sorted_range.end(); // need this visible after loop +        for (DependencyMap::sorted_iterator dmi = sorted_range.begin(); +            dmi != sorted_range.end(); ++dmi) +        { +            // Since we've added the new entry with an invalid placement, +            // recognize it and skip it. +            if (dmi->first == name)              { -                if (cdmi->first != name) -                { -                    sortnames.push_back(SortNameList::value_type(cdmi->second, cdmi->first)); -                } +                // Remember the iterator belonging to our new node, and which +                // placement value was 'previous' at that point. +                mydmi = dmi; +                myprev = previous; +                continue;              } -            std::sort(sortnames.begin(), sortnames.end()); -            std::ostringstream out; -            out << "New listener '" << name << "' on " << typeid(*this).name() << " '" << getName() -                << "' would move previous listener '" << dmi->first << "'\nwas: "; -            SortNameList::const_iterator sni(sortnames.begin()), snend(sortnames.end()); -            if (sni != snend) +            // If the new node has rearranged the existing nodes, we'll find +            // that their placement values are no longer in increasing order. +            if (dmi->second < previous)              { -                out << sni->second; -                while (++sni != snend) +                // This is another scenario in which we'd better back out the +                // newly-added node from mDeps -- but don't do it yet, we want to +                // traverse the existing mDeps to report on it! +                // Describe the change to the order of our listeners. Copy +                // everything but the newest listener to a vector we can sort to +                // obtain the old order. +                typedef std::vector< std::pair<float, std::string> > SortNameList; +                SortNameList sortnames; +                for (DependencyMap::sorted_iterator cdmi(sorted_range.begin()), cdmend(sorted_range.end()); +                    cdmi != cdmend; ++cdmi)                  { -                    out << ", " << sni->second; +                    if (cdmi->first != name) +                    { +                        sortnames.push_back(SortNameList::value_type(cdmi->second, cdmi->first)); +                    }                  } -            } -            out << "\nnow: "; -            DependencyMap::sorted_iterator ddmi(sorted_range.begin()), ddmend(sorted_range.end()); -            if (ddmi != ddmend) -            { -                out << ddmi->first; -                while (++ddmi != ddmend) +                std::sort(sortnames.begin(), sortnames.end()); +                std::ostringstream out; +                out << "New listener '" << name << "' on " << typeid(*this).name() << " '" << getName() +                    << "' would move previous listener '" << dmi->first << "'\nwas: "; +                SortNameList::const_iterator sni(sortnames.begin()), snend(sortnames.end()); +                if (sni != snend)                  { -                    out << ", " << ddmi->first; +                    out << sni->second; +                    while (++sni != snend) +                    { +                        out << ", " << sni->second; +                    }                  } +                out << "\nnow: "; +                DependencyMap::sorted_iterator ddmi(sorted_range.begin()), ddmend(sorted_range.end()); +                if (ddmi != ddmend) +                { +                    out << ddmi->first; +                    while (++ddmi != ddmend) +                    { +                        out << ", " << ddmi->first; +                    } +                } +                // NOW remove the offending listener node. +                mDeps.remove(name); +                // Having constructed a description of the order change, inform caller. +                throw OrderChange(out.str());              } -            // NOW remove the offending listener node. -            mDeps.remove(name); -            // Having constructed a description of the order change, inform caller. -            throw OrderChange(out.str()); +            // This node becomes the previous one. +            previous = dmi->second;          } -        // This node becomes the previous one. -        previous = dmi->second; -    } -    // We just got done with a successful mDeps.add(name, ...) call. We'd -    // better have found 'name' somewhere in that sorted list! -    assert(mydmi != sorted_range.end()); -    // Four cases: -    // 0. name is the only entry: placement 1.0 -    // 1. name is the first of several entries: placement (next placement)/2 -    // 2. name is between two other entries: placement (myprev + (next placement))/2 -    // 3. name is the last entry: placement ceil(myprev) + 1.0 -    // Since we've cleverly arranged for myprev to be 0.0 if name is the -    // first entry, this folds down to two cases. Case 1 is subsumed by -    // case 2, and case 0 is subsumed by case 3. So we need only handle -    // cases 2 and 3, which means we need only detect whether name is the -    // last entry. Increment mydmi to see if there's anything beyond. -    if (++mydmi != sorted_range.end()) -    { -        // The new node isn't last. Place it between the previous node and -        // the successor. -        newNode = (myprev + mydmi->second)/2.f; -    } -    else -    { -        // The new node is last. Bump myprev up to the next integer, add -        // 1.0 and use that. -        newNode = std::ceil(myprev) + 1.f; +        // We just got done with a successful mDeps.add(name, ...) call. We'd +        // better have found 'name' somewhere in that sorted list! +        assert(mydmi != sorted_range.end()); +        // Four cases: +        // 0. name is the only entry: placement 1.0 +        // 1. name is the first of several entries: placement (next placement)/2 +        // 2. name is between two other entries: placement (myprev + (next placement))/2 +        // 3. name is the last entry: placement ceil(myprev) + 1.0 +        // Since we've cleverly arranged for myprev to be 0.0 if name is the +        // first entry, this folds down to two cases. Case 1 is subsumed by +        // case 2, and case 0 is subsumed by case 3. So we need only handle +        // cases 2 and 3, which means we need only detect whether name is the +        // last entry. Increment mydmi to see if there's anything beyond. +        if (++mydmi != sorted_range.end()) +        { +            // The new node isn't last. Place it between the previous node and +            // the successor. +            newNode = (myprev + mydmi->second) / 2.f; +        } +        else +        { +            // The new node is last. Bump myprev up to the next integer, add +            // 1.0 and use that. +            newNode = std::ceil(myprev) + 1.f; +        } + +        nodePosition = newNode;      }      // Now that newNode has a value that places it appropriately in mSignal,      // connect it. -    LLBoundListener bound = mSignal->connect(newNode, listener); -    mConnections[name] = bound; +    LLBoundListener bound = mSignal->connect(nodePosition, listener); +     +    if (!name.empty()) +    {   // note that we are not tracking anonymous listeners here either. +        // This means that it is the caller's responsibility to either assign  +        // to a TempBoundListerer (scoped_connection) or manually disconnect  +        // when done.  +        mConnections[name] = bound; +    }      return bound;  } diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index ba4fcd766e..694951e699 100644 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -365,6 +365,8 @@ typedef boost::signals2::trackable LLEventTrackable;  class LL_COMMON_API LLEventPump: public LLEventTrackable  {  public: +    static const std::string ANONYMOUS; // constant for anonymous listeners. +      /**       * Exception thrown by LLEventPump(). You are trying to instantiate an       * LLEventPump (subclass) using the same name as some other instance, and @@ -476,6 +478,12 @@ public:       * instantiate your listener, then passing the same name on each listen()       * call, allows us to optimize away the second and subsequent dependency       * sorts. +     *  +     * If name is set to LLEventPump::ANONYMOUS listen will bypass the entire  +     * dependency and ordering calculation. In this case, it is critical that  +     * the result be assigned to a LLTempBoundListener or the listener is  +     * manually disconnected when no longer needed since there will be no +     * way to later find and disconnect this listener manually.       *       * If (as is typical) you pass a <tt>boost::bind()</tt> expression as @a       * listener, listen() will inspect the components of that expression. If a diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index 7742cbc182..9bf38fb336 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -642,7 +642,7 @@ HttpRequestPumper::HttpRequestPumper(const LLCore::HttpRequest::ptr_t &request)      mHttpRequest(request)  {      mBoundListener = LLEventPumps::instance().obtain("mainloop"). -        listen(LLEventPump::inventName(), boost::bind(&HttpRequestPumper::pollRequest, this, _1)); +        listen(LLEventPump::ANONYMOUS, boost::bind(&HttpRequestPumper::pollRequest, this, _1));  }  HttpRequestPumper::~HttpRequestPumper() diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 8166ef6a07..f9664e0658 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -684,6 +684,13 @@ void LLFolderView::draw()  		}  	} +	if (mRenameItem && mRenamer && mRenamer->getVisible() && !getVisibleRect().overlaps(mRenamer->getRect())) +	{ +		// renamer is not connected to the item we are renaming in any form so manage it manually +		// TODO: consider stopping on any scroll action instead of when out of visible area +		finishRenamingItem(); +	} +  	// skip over LLFolderViewFolder::draw since we don't want the folder icon, label,   	// and arrow for the root folder  	LLView::draw(); diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 5eb5ca4f82..3d618548c4 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -127,6 +127,8 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)  	mIsSelected( FALSE ),  	mIsCurSelection( FALSE ),  	mSelectPending(FALSE), +	mIsItemCut(false), +	mCutGeneration(0),  	mLabelStyle( LLFontGL::NORMAL ),  	mHasVisibleChildren(FALSE),  	mIsFolderComplete(true), @@ -694,6 +696,19 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L  	return mIsCurSelection;  } +/*virtual*/ bool LLFolderViewItem::isFadeItem() +{ +    LLClipboard& clipboard = LLClipboard::instance(); +    if (mCutGeneration != clipboard.getGeneration()) +    { +        mCutGeneration = clipboard.getGeneration(); +        mIsItemCut = clipboard.isCutMode() +                     && ((getParentFolder() && getParentFolder()->isFadeItem()) +                        || getViewModelItem()->isCutToClipboard()); +    } +    return mIsItemCut; +} +  void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor,                                                            const LLUIColor &focusOutlineColor, const LLUIColor &mouseOverColor)  { @@ -875,6 +890,12 @@ void LLFolderViewItem::draw()      }      LLColor4 color = (mIsSelected && filled) ? mFontHighlightColor : mFontColor; + +    if (isFadeItem()) +    { +         // Fade out item color to indicate it's being cut +         color.mV[VALPHA] *= 0.5f; +    }      drawLabel(font, text_left, y, color, right_x);  	//--------------------------------------------------------------------------------// @@ -882,7 +903,7 @@ void LLFolderViewItem::draw()  	//  	if (!mLabelSuffix.empty())  	{ -		font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor, +		font->renderUTF8( mLabelSuffix, 0, right_x, y, isFadeItem() ? color : (LLColor4)sSuffixColor,  						  LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,  						  S32_MAX, S32_MAX, &right_x, FALSE );  	} diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index 0322c8836d..61c39e0175 100644 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -121,8 +121,11 @@ protected:  								mIsMouseOverTitle,  								mAllowWear,                                  mAllowDrop, -								mSelectPending; -	 +								mSelectPending, +								mIsItemCut; + +	S32							mCutGeneration; +  	LLUIColor                   mFontColor;  	LLUIColor                   mFontHighlightColor; @@ -145,6 +148,7 @@ protected:  	virtual void addFolder(LLFolderViewFolder*) { }  	virtual bool isHighlightAllowed();  	virtual bool isHighlightActive(); +	virtual bool isFadeItem();  	virtual bool isFlashing() { return false; }  	virtual void setFlashState(bool) { } diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index a395af537a..641241a88c 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -173,6 +173,7 @@ public:  	virtual BOOL isItemCopyable() const = 0;  	virtual BOOL copyToClipboard() const = 0;  	virtual BOOL cutToClipboard() = 0; +	virtual bool isCutToClipboard() { return false; };  	virtual BOOL isClipboardPasteable() const = 0;  	virtual void pasteFromClipboard() = 0; diff --git a/indra/llui/lltextvalidate.cpp b/indra/llui/lltextvalidate.cpp index 324ceb7fba..bfe0a5bb5d 100644 --- a/indra/llui/lltextvalidate.cpp +++ b/indra/llui/lltextvalidate.cpp @@ -328,6 +328,15 @@ namespace LLTextValidate  		return rv;  	} +	bool validateASCIINoLeadingSpace(const LLWString &str) +	{ +		if (LLStringOps::isSpace(str[0])) +		{ +			return FALSE; +		} +		return validateASCII(str); +	} +  	// Used for multiline text stored on the server.  	// Example is landmark description in Places SP.  	bool validateASCIIWithNewLine(const LLWString &str) diff --git a/indra/llui/lltextvalidate.h b/indra/llui/lltextvalidate.h index 5c830d7db3..e2b6c313d6 100644 --- a/indra/llui/lltextvalidate.h +++ b/indra/llui/lltextvalidate.h @@ -52,6 +52,7 @@ namespace LLTextValidate  	bool	validateASCIIPrintableNoPipe(const LLWString &str);   	bool	validateASCIIPrintableNoSpace(const LLWString &str);  	bool	validateASCII(const LLWString &str); +	bool	validateASCIINoLeadingSpace(const LLWString &str);  	bool	validateASCIIWithNewLine(const LLWString &str);  } diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index aabc7ed2e4..f790d8e005 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -522,7 +522,7 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)  		else  		{  			std::string part(ti->begin(), ti->end()); -			context = context->findChildView(part, recurse); +			context = context->findChildView(LLURI::unescape(part), recurse);  			recurse = false;  		}  	} diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 62c3f401bf..e1d9b1a487 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -391,7 +391,27 @@ static void buildPathname(std::ostream& out, const LLView* view)  	buildPathname(out, view->getParent());  	// Build pathname into ostream on the way back from recursion. -	out << '/' << view->getName(); +	out << '/'; + +	// substitute all '/' in name with appropriate code +	std::string name = view->getName(); +	std::size_t found = name.find('/'); +	std::size_t start = 0; +	while (found != std::string::npos) +	{ +		std::size_t sub_len = found - start; +		if (sub_len > 0) +		{ +			out << name.substr(start, sub_len); +		} +		out << "%2F"; +		start = found + 1; +		found = name.find('/', start); +	} +	if (start < name.size()) +	{ +		out << name.substr(start, name.size() - start); +	}  }  std::string LLView::getPathname() const diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index 5f4fb8f4a0..86a15f2ef2 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -531,6 +531,13 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd  	case LL_PATH_PER_ACCOUNT_CHAT_LOGS:  		prefix = getPerAccountChatLogsDir(); +		if (prefix.empty()) +		{ +			// potentially directory was not set yet +			// intentionally return a blank string to the caller +			LL_DEBUGS("LLDir") << "Conversation log directory is not yet set" << LL_ENDL; +			return std::string(); +		}  		break;  	case LL_PATH_LOGS: diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 0a30f4c807..a05ba8cbba 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -166,6 +166,8 @@ public:  	// Provide native key event data  	virtual LLSD getNativeKeyData() { return LLSD::emptyMap(); } +	// Get system UI size based on DPI (for 96 DPI UI size should be 1.0) +	virtual F32 getSystemUISize() { return 1.0; }  protected:  	LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags);  	virtual ~LLWindow(); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 875ffe4cd4..2a39029eee 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -78,6 +78,31 @@ LPWSTR gIconResource = IDI_APPLICATION;  LLW32MsgCallback gAsyncMsgCallback = NULL; +#ifndef DPI_ENUMS_DECLARED + +typedef enum PROCESS_DPI_AWARENESS { +	PROCESS_DPI_UNAWARE = 0, +	PROCESS_SYSTEM_DPI_AWARE = 1, +	PROCESS_PER_MONITOR_DPI_AWARE = 2 +} PROCESS_DPI_AWARENESS; + +typedef enum MONITOR_DPI_TYPE { +	MDT_EFFECTIVE_DPI = 0, +	MDT_ANGULAR_DPI = 1, +	MDT_RAW_DPI = 2, +	MDT_DEFAULT = MDT_EFFECTIVE_DPI +} MONITOR_DPI_TYPE; + +#endif + +typedef HRESULT(STDAPICALLTYPE *SetProcessDpiAwarenessType)(_In_ PROCESS_DPI_AWARENESS value); + +typedef HRESULT(STDAPICALLTYPE *GetDpiForMonitorType)( +	_In_ HMONITOR hmonitor, +	_In_ MONITOR_DPI_TYPE dpiType, +	_Out_ UINT *dpiX, +	_Out_ UINT *dpiY); +  //  // LLWindowWin32  // @@ -3878,6 +3903,46 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)  	return FALSE;  } +F32 LLWindowWin32::getSystemUISize() +{ +	float scale_value = 0; +	HWND hWnd = (HWND)getPlatformWindow(); +	HDC hdc = GetDC(hWnd); +	HMONITOR hMonitor; + +	HMODULE hShcore = LoadLibrary(L"shcore.dll"); + +	if (hShcore != NULL) +	{ +		SetProcessDpiAwarenessType pSPDA; +		pSPDA = (SetProcessDpiAwarenessType)GetProcAddress(hShcore, "SetProcessDpiAwareness"); +		GetDpiForMonitorType pGDFM; +		pGDFM = (GetDpiForMonitorType)GetProcAddress(hShcore, "GetDpiForMonitor"); +		if (pSPDA != NULL && pGDFM != NULL) +		{ +			pSPDA(PROCESS_PER_MONITOR_DPI_AWARE); +			POINT    pt; +			UINT     dpix = 0, dpiy = 0; +			HRESULT  hr = E_FAIL; + +			// Get the DPI for the main monitor, and set the scaling factor +			pt.x = 1; +			pt.y = 1; +			hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); +			hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy); +			scale_value = dpix / 96.0f; +		} +	} +	else +	{ +		LL_WARNS() << "Could not load shcore.dll library (included by <ShellScalingAPI.h> from Win 8.1 SDK). Using legacy DPI awareness API of Win XP/7" << LL_ENDL; +		scale_value = GetDeviceCaps(hdc, LOGPIXELSX) / 96.0f; +	} + +	ReleaseDC(hWnd, hdc); +	return scale_value; +} +  //static  std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList()  { diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 1a775eadaf..1386321912 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -110,6 +110,8 @@ public:  	/*virtual*/ void interruptLanguageTextInput();  	/*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); +	/*virtual*/ F32 getSystemUISize(); +  	LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url );  	static std::vector<std::string> getDynamicFallbackFontList(); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 6ccf89eabe..c3d7d67c86 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10218,6 +10218,17 @@        <key>Value</key>        <real>1.0</real>      </map> +    <key>RenderRiggedFactorMultiplier</key> +    <map> +      <key>Comment</key> +      <string>Affects level of detail for worn rigged meshes</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <real>7.5</real> +    </map>      <key>RenderWater</key>      <map>        <key>Comment</key> @@ -12792,6 +12803,17 @@        <key>Value</key>        <real>1.0</real>      </map> +    <key>LastSystemUIScaleFactor</key> +    <map> +      <key>Comment</key> +      <string>Size of system UI during last run. On Windows 100% (96 DPI) system setting is 1.0 UI size</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <real>1.0</real> +    </map>      <key>UIScrollbarSize</key>      <map>        <key>Comment</key> @@ -13287,6 +13309,17 @@        <key>Value</key>        <string>1</string>      </map> +    <key>UpdaterShowReleaseNotes</key> +    <map> +        <key>Comment</key> +        <string>Enables displaying of the Release notes in a web floater after update.</string> +        <key>Persist</key> +        <integer>1</integer> +        <key>Type</key> +        <string>Boolean</string> +        <key>Value</key> +        <integer>1</integer> +    </map>      <key>UploadBakedTexOld</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index d933537d2e..d8b0787852 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3895,11 +3895,17 @@ void LLAgent::handleTeleportFinished()  		mIsMaturityRatingChangingDuringTeleport = false;  	} -    // Init SLM Marketplace connection so we know which UI should be used for the user as a merchant -    // Note: Eventually, all merchant will be migrated to the new SLM system and there will be no reason to show the old UI at all. -    // Note: Some regions will not support the SLM cap for a while so we need to do that check for each teleport. -    // *TODO : Suppress that line from here once the whole grid migrated to SLM and move it to idle_startup() (llstartup.cpp) -    check_merchant_status(); +    if (mRegionp) +    { +        if (mRegionp->capabilitiesReceived()) +        { +            onCapabilitiesReceivedAfterTeleport(); +        } +        else +        { +            mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::onCapabilitiesReceivedAfterTeleport)); +        } +    }  }  void LLAgent::handleTeleportFailed() @@ -3931,6 +3937,14 @@ void LLAgent::handleTeleportFailed()  	}  } +/*static*/ +void LLAgent::onCapabilitiesReceivedAfterTeleport() +{ + +    check_merchant_status(); +} + +  void LLAgent::teleportRequest(  	const U64& region_handle,  	const LLVector3& pos_local, diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 3a533c2cba..d82ff7a67f 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -676,6 +676,8 @@ private:  	void            handleTeleportFinished();  	void            handleTeleportFailed(); +    static void     onCapabilitiesReceivedAfterTeleport(); +  	//--------------------------------------------------------------------  	// Teleport State  	//-------------------------------------------------------------------- diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index b76a66ab39..170e4063a1 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -62,23 +62,37 @@ using namespace LLAvatarAppearanceDefines;  /////////////////////////////////////////////////////////////////////////////// -// Callback to wear and start editing an item that has just been created. -void wear_and_edit_cb(const LLUUID& inv_item) +void set_default_permissions(LLViewerInventoryItem* item)  { -	if (inv_item.isNull()) return; -	 -		LLViewerInventoryItem* item = gInventory.getItem(inv_item); -		if (!item) return; - -		LLPermissions perm = item->getPermissions(); +	llassert(item); +	LLPermissions perm = item->getPermissions(); +	if (perm.getMaskNextOwner() != LLFloaterPerms::getNextOwnerPerms("Wearables") +		|| perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms("Wearables") +		|| perm.getMaskGroup() != LLFloaterPerms::getGroupPerms("Wearables")) +	{  		perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables"));  		perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables"));  		perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables")); +  		item->setPermissions(perm);  		item->updateServer(FALSE); -		gInventory.updateItem(item); -		gInventory.notifyObservers(); +	} +} + +// Callback to wear and start editing an item that has just been created. +void wear_and_edit_cb(const LLUUID& inv_item) +{ +	if (inv_item.isNull()) return; +	 +	LLViewerInventoryItem* item = gInventory.getItem(inv_item); +	if (!item) return; + +	set_default_permissions(item); + +	// item was just created, update even if permissions did not changed +	gInventory.updateItem(item); +	gInventory.notifyObservers();  	// Request editing the item after it gets worn.  	gAgentWearables.requestEditingWearable(inv_item); @@ -94,13 +108,8 @@ void wear_cb(const LLUUID& inv_item)  		LLViewerInventoryItem* item = gInventory.getItem(inv_item);  		if (item)  		{ -			LLPermissions perm = item->getPermissions(); -			perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables")); -			perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables")); -			perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables")); -			item->setPermissions(perm); +			set_default_permissions(item); -			item->updateServer(FALSE);  			gInventory.updateItem(item);  			gInventory.notifyObservers();  		} @@ -253,6 +262,7 @@ void LLAgentWearables::AddWearableToAgentInventoryCallback::fire(const LLUUID& i  	{  		LLAppearanceMgr::instance().addCOFItemLink(inv_item,   			new LLUpdateAppearanceAndEditWearableOnDestroy(inv_item), mDescription); +		editWearable(inv_item);  	}  } @@ -423,7 +433,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,  	// old_wearable may still be referred to by other inventory items. Revert  	// unsaved changes so other inventory items aren't affected by the changes  	// that were just saved. -	old_wearable->revertValues(); +	old_wearable->revertValuesWithoutUpdate();  }  void LLAgentWearables::revertWearable(const LLWearableType::EType type, const U32 index) @@ -1364,6 +1374,30 @@ void LLAgentWearables::findAttachmentsAddRemoveInfo(LLInventoryModel::item_array  	// LL_INFOS() << "remove " << remove_count << " add " << add_count << LL_ENDL;  } +std::vector<LLViewerObject*> LLAgentWearables::getTempAttachments() +{ +	llvo_vec_t temp_attachs; +	if (isAgentAvatarValid()) +	{ +		for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); iter != gAgentAvatarp->mAttachmentPoints.end();) +		{ +			LLVOAvatar::attachment_map_t::iterator curiter = iter++; +			LLViewerJointAttachment* attachment = curiter->second; +			for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +				attachment_iter != attachment->mAttachedObjects.end(); +				++attachment_iter) +			{ +				LLViewerObject *objectp = (*attachment_iter); +				if (objectp && objectp->isTempAttachment()) +				{ +					temp_attachs.push_back(objectp); +				} +			} +		} +	} +	return temp_attachs; +} +  void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remove)  {  	if (!isAgentAvatarValid()) return; diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 1004482020..b27698fd8f 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -185,6 +185,8 @@ public:  	static void		userRemoveMultipleAttachments(llvo_vec_t& llvo_array);  	static void		userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array); +	static llvo_vec_t getTempAttachments(); +  	//--------------------------------------------------------------------  	// Signals  	//-------------------------------------------------------------------- diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index a1d9786321..4a4361e94b 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -3916,6 +3916,10 @@ void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)  	LL_DEBUGS("Avatar") << "setAttachmentInvLinkEnable => " << (int) val << LL_ENDL;  	mAttachmentInvLinkEnabled = val;  } +boost::signals2::connection LLAppearanceMgr::setAttachmentsChangedCallback(attachments_changed_callback_t cb) +{ +	return mAttachmentsChangeSignal.connect(cb); +}  void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)  { @@ -3942,6 +3946,8 @@ void LLAppearanceMgr::registerAttachment(const LLUUID& item_id)  	gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);  	LLAttachmentsMgr::instance().onAttachmentArrived(item_id); + +	mAttachmentsChangeSignal();  }  void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id) @@ -3962,6 +3968,8 @@ void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)  	{  		//LL_INFOS() << "no link changes, inv link not enabled" << LL_ENDL;  	} + +	mAttachmentsChangeSignal();  }  BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 7069da7352..07ae5fba86 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -225,6 +225,10 @@ public:  	void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; }  	std::string getAppearanceServiceURL() const; +	typedef boost::function<void ()> attachments_changed_callback_t; +	typedef boost::signals2::signal<void ()> attachments_changed_signal_t; +	boost::signals2::connection setAttachmentsChangedCallback(attachments_changed_callback_t cb); +  private: @@ -268,6 +272,8 @@ private:  	LLTimer mInFlightTimer;  	static bool mActive; +	attachments_changed_signal_t		mAttachmentsChangeSignal; +  	std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;  	// Set of temp attachment UUIDs that should be removed diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 6bc1f67e32..950692a788 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -587,6 +587,7 @@ static void settings_to_globals()  	LLImageGL::sGlobalUseAnisotropic	= gSavedSettings.getBOOL("RenderAnisotropic");  	LLImageGL::sCompressTextures		= gSavedSettings.getBOOL("RenderCompressTextures");  	LLVOVolume::sLODFactor				= gSavedSettings.getF32("RenderVolumeLODFactor"); +	LLVOVolume::sRiggedFactorMultiplier	= gSavedSettings.getF32("RenderRiggedFactorMultiplier");  	LLVOVolume::sDistanceFactor			= 1.f-LLVOVolume::sLODFactor * 0.1f;  	LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");  	LLVOTree::sTreeFactor				= gSavedSettings.getF32("RenderTreeLODFactor"); @@ -696,7 +697,8 @@ LLAppViewer::LLAppViewer()  	mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),  	mFastTimerLogThread(NULL),  	mUpdater(new LLUpdaterService()), -	mSettingsLocationList(NULL) +	mSettingsLocationList(NULL), +	mIsFirstRun(false)  {  	if(NULL != sInstance)  	{ @@ -1220,6 +1222,8 @@ bool LLAppViewer::init()          boost::bind(&LLControlGroup::getU32, boost::ref(gSavedSettings), _1),          boost::bind(&LLControlGroup::declareU32, boost::ref(gSavedSettings), _1, _2, _3, LLControlVariable::PERSIST_ALWAYS)); +	showReleaseNotesIfRequired(); +  	return true;  } @@ -2483,7 +2487,10 @@ bool LLAppViewer::initConfiguration()  	if (gSavedSettings.getBOOL("FirstRunThisInstall"))  	{ -		// Note that the "FirstRunThisInstall" settings is currently unused. +		// Set firstrun flag to indicate that some further init actiona should be taken  +		// like determining screen DPI value and so on +		mIsFirstRun = true; +  		gSavedSettings.setBOOL("FirstRunThisInstall", FALSE);  	} @@ -3140,7 +3147,8 @@ bool LLAppViewer::initWindow()  		.min_width(gSavedSettings.getU32("MinWindowWidth"))  		.min_height(gSavedSettings.getU32("MinWindowHeight"))  		.fullscreen(gSavedSettings.getBOOL("FullScreen")) -		.ignore_pixel_depth(ignorePixelDepth); +		.ignore_pixel_depth(ignorePixelDepth) +		.first_run(mIsFirstRun);  	gViewerWindow = new LLViewerWindow(window_params); @@ -5799,6 +5807,18 @@ void LLAppViewer::launchUpdater()  	// LLAppViewer::instance()->forceQuit();  } +/** +* Check if user is running a new version of the viewer. +* Display the Release Notes if it's not overriden by the "UpdaterShowReleaseNotes" setting. +*/ +void LLAppViewer::showReleaseNotesIfRequired() +{ +	if (LLVersionInfo::getChannelAndVersion() != gLastRunVersion && gSavedSettings.getBOOL("UpdaterShowReleaseNotes")) +	{ +		LLSD info(getViewerInfo()); +		LLWeb::loadURLInternal(info["VIEWER_RELEASE_NOTES_URL"]); +	} +}  //virtual  void LLAppViewer::setMasterSystemAudioMute(bool mute) diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index b5e674bd7b..d4af2440be 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -254,6 +254,8 @@ private:      void sendLogoutRequest();      void disconnectViewer(); + +	void showReleaseNotesIfRequired();  	// *FIX: the app viewer class should be some sort of singleton, no?  	// Perhaps its child class is the singleton and this should be an abstract base. @@ -316,6 +318,7 @@ private:  	// llcorehttp library init/shutdown helper  	LLAppCoreHttp mAppCoreHttp; +	bool mIsFirstRun;  	//---------------------------------------------  	//*NOTE: Mani - legacy updater stuff  	// Still useable? diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 00fa6dd979..54c6c985d6 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -311,7 +311,8 @@ LLWString LLChatBar::stripChannelNumber(const LLWString &mesg, S32* channel)  	}  	else if (mesg[0] == '/'  			 && mesg[1] -			 && LLStringOps::isDigit(mesg[1])) +			 && (LLStringOps::isDigit(mesg[1]) +				 || (mesg[1] == '-' && mesg[2] && LLStringOps::isDigit(mesg[2]))))  	{  		// This a special "/20" speak on a channel  		S32 pos = 0; @@ -325,7 +326,7 @@ LLWString LLChatBar::stripChannelNumber(const LLWString &mesg, S32* channel)  			channel_string.push_back(c);  			pos++;  		} -		while(c && pos < 64 && LLStringOps::isDigit(c)); +		while(c && pos < 64 && (LLStringOps::isDigit(c) || (pos == 1 && c == '-')));  		// Move the pointer forward to the first non-whitespace char  		// Check isspace before looping, so we can handle "/33foo" diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp index 05c7e6caa5..4e69896b69 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -448,7 +448,12 @@ bool LLConversationLog::moveLog(const std::string &originDirectory, const std::s  std::string LLConversationLog::getFileName()  {  	std::string filename = "conversation"; -	return gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename) + ".log"; +	std::string log_address = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename); +	if (!log_address.empty()) +	{ +		log_address += ".log"; +	} +	return log_address;  }  bool LLConversationLog::saveToFile(const std::string& filename) diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 7a989806a1..257b39a7dd 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -798,7 +798,8 @@ LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32*  	}  	else if (mesg[0] == '/'  			 && mesg[1] -			 && LLStringOps::isDigit(mesg[1])) +			 && (LLStringOps::isDigit(mesg[1]) +				 || (mesg[1] == '-' && mesg[2] && LLStringOps::isDigit(mesg[2]))))  	{  		// This a special "/20" speak on a channel  		S32 pos = 0; @@ -812,7 +813,7 @@ LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32*  			channel_string.push_back(c);  			pos++;  		} -		while(c && pos < 64 && LLStringOps::isDigit(c)); +		while(c && pos < 64 && (LLStringOps::isDigit(c) || (pos==1 && c =='-')));  		// Move the pointer forward to the first non-whitespace char  		// Check isspace before looping, so we can handle "/33foo" @@ -837,19 +838,36 @@ LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32*  void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)  { -	LLMessageSystem* msg = gMessageSystem; -	msg->newMessageFast(_PREHASH_ChatFromViewer); -	msg->nextBlockFast(_PREHASH_AgentData); -	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -	msg->nextBlockFast(_PREHASH_ChatData); -	msg->addStringFast(_PREHASH_Message, utf8_out_text); -	msg->addU8Fast(_PREHASH_Type, type); -	msg->addS32("Channel", channel); - -	gAgent.sendReliableMessage(); - -	add(LLStatViewer::CHAT_COUNT, 1); +    LLMessageSystem* msg = gMessageSystem; + +    if (channel >= 0) +    { +        msg->newMessageFast(_PREHASH_ChatFromViewer); +        msg->nextBlockFast(_PREHASH_AgentData); +        msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +        msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +        msg->nextBlockFast(_PREHASH_ChatData); +        msg->addStringFast(_PREHASH_Message, utf8_out_text); +        msg->addU8Fast(_PREHASH_Type, type); +        msg->addS32("Channel", channel); + +    } +    else +    { +        // Hack: ChatFromViewer doesn't allow negative channels +        msg->newMessage("ScriptDialogReply"); +        msg->nextBlock("AgentData"); +        msg->addUUID("AgentID", gAgentID); +        msg->addUUID("SessionID", gAgentSessionID); +        msg->nextBlock("Data"); +        msg->addUUID("ObjectID", gAgentID); +        msg->addS32("ChatChannel", channel); +        msg->addS32("ButtonIndex", 0); +        msg->addString("ButtonLabel", utf8_out_text); +    } + +    gAgent.sendReliableMessage(); +    add(LLStatViewer::CHAT_COUNT, 1);  }  class LLChatCommandHandler : public LLCommandHandler diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 36bdcf4d89..20d8119606 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1411,7 +1411,7 @@ void LLAvatarComplexityControls::setIndirectMaxArc()  	else  	{  		// This is the inverse of the calculation in updateMaxComplexity -		indirect_max_arc = (U32)((log(max_arc) - MIN_ARC_LOG) / ARC_LIMIT_MAP_SCALE) + MIN_INDIRECT_ARC_LIMIT; +		indirect_max_arc = (U32)ll_round(((log(F32(max_arc)) - MIN_ARC_LOG) / ARC_LIMIT_MAP_SCALE)) + MIN_INDIRECT_ARC_LIMIT;  	}  	gSavedSettings.setU32("IndirectMaxComplexity", indirect_max_arc);  } @@ -1930,7 +1930,7 @@ void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* valu  	{  		// if this is changed, the inverse calculation in setIndirectMaxArc  		// must be changed to match -		max_arc = (U32)exp(MIN_ARC_LOG + (ARC_LIMIT_MAP_SCALE * (indirect_value - MIN_INDIRECT_ARC_LIMIT))); +		max_arc = (U32)ll_round(exp(MIN_ARC_LOG + (ARC_LIMIT_MAP_SCALE * (indirect_value - MIN_INDIRECT_ARC_LIMIT))));  	}  	gSavedSettings.setU32("RenderAvatarMaxComplexity", (U32)max_arc); diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index 7b8fc5b35b..eae16b9f03 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -660,6 +660,8 @@ BOOL LLPanelScriptLimitsRegionMemory::postBuild()  	{  		return FALSE;  	} +	list->setCommitCallback(boost::bind(&LLPanelScriptLimitsRegionMemory::checkButtonsEnabled, this)); +	checkButtonsEnabled();  	//set all columns to resizable mode even if some columns will be empty  	for(S32 column = 0; column < list->getNumColumns(); column++) @@ -750,6 +752,14 @@ void LLPanelScriptLimitsRegionMemory::clearList()  	getChild<LLUICtrl>("parcels_listed")->setValue(LLSD(msg_empty_string));  	mObjectListItems.clear(); +	checkButtonsEnabled(); +} + +void LLPanelScriptLimitsRegionMemory::checkButtonsEnabled() +{ +	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("scripts_list"); +	getChild<LLButton>("highlight_btn")->setEnabled(list->getNumSelected() > 0); +	getChild<LLButton>("return_btn")->setEnabled(list->getNumSelected() > 0);  }  // static diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h index e3cbbd185f..2ac3862b4f 100644 --- a/indra/newview/llfloaterscriptlimits.h +++ b/indra/newview/llfloaterscriptlimits.h @@ -113,6 +113,7 @@ public:  	void showBeacon();  	void returnObjectsFromParcel(S32 local_id);  	void returnObjects(); +	void checkButtonsEnabled();  private:  	void onNameCache(const LLUUID& id, diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp index 0cb37dabe7..b139e5daf5 100644 --- a/indra/newview/llfloatersellland.cpp +++ b/indra/newview/llfloatersellland.cpp @@ -257,7 +257,6 @@ void LLFloaterSellLandUI::setBadge(const char* id, Badge badge)  	static std::string badgeOK("badge_ok.j2c");  	static std::string badgeNote("badge_note.j2c");  	static std::string badgeWarn("badge_warn.j2c"); -	static std::string badgeError("badge_error.j2c");  	std::string badgeName;  	switch (badge) @@ -266,7 +265,7 @@ void LLFloaterSellLandUI::setBadge(const char* id, Badge badge)  		case BADGE_OK:		badgeName = badgeOK;	break;  		case BADGE_NOTE:	badgeName = badgeNote;	break;  		case BADGE_WARN:	badgeName = badgeWarn;	break; -		case BADGE_ERROR:	badgeName = badgeError;	break; +		case BADGE_ERROR:	badgeName = badgeWarn;	break;  	}  	getChild<LLUICtrl>(id)->setValue(badgeName); diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp index a9bf8a9a50..97cc7684e4 100644 --- a/indra/newview/llgiveinventory.cpp +++ b/indra/newview/llgiveinventory.cpp @@ -248,7 +248,7 @@ bool LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,  	gInventory.collectDescendentsIf (cat->getUUID(),  		cats,  		items, -		LLInventoryModel::EXCLUDE_TRASH, +		LLInventoryModel::INCLUDE_TRASH,  		giveable);  	S32 count = cats.size();  	bool complete = true; @@ -499,7 +499,7 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,  	gInventory.collectDescendentsIf (cat->getUUID(),  		cats,  		items, -		LLInventoryModel::EXCLUDE_TRASH, +		LLInventoryModel::INCLUDE_TRASH,  		giveable);  	bool give_successful = true; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 26c9b40fb1..f4bf38f65d 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -286,6 +286,16 @@ BOOL LLInvFVBridge::cutToClipboard()  	return FALSE;  } +// virtual +bool LLInvFVBridge::isCutToClipboard() +{ +    if (LLClipboard::instance().isCutMode()) +    { +        return LLClipboard::instance().isOnClipboard(mUUID); +    } +    return false; +} +  // Callback for cutToClipboard if DAMA required...  BOOL LLInvFVBridge::callback_cutToClipboard(const LLSD& notification, const LLSD& response)  { @@ -307,9 +317,7 @@ BOOL LLInvFVBridge::perform_cutToClipboard()  	if (obj && isItemMovable() && isItemRemovable())  	{  		LLClipboard::instance().setCutMode(true); -		BOOL added_to_clipboard = LLClipboard::instance().addToClipboard(mUUID); -        removeObject(&gInventory, mUUID);   // Always perform the remove even if the object couldn't make it to the clipboard -        return added_to_clipboard; +		return LLClipboard::instance().addToClipboard(mUUID);  	}  	return FALSE;  } diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 9053c61171..df25e01688 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -116,6 +116,7 @@ public:  	virtual BOOL isItemCopyable() const { return FALSE; }  	virtual BOOL copyToClipboard() const;  	virtual BOOL cutToClipboard(); +	virtual bool isCutToClipboard();  	virtual BOOL isClipboardPasteable() const;  	virtual BOOL isClipboardPasteableAsLink() const;  	virtual void pasteFromClipboard() {} diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 003bbcafed..e995c138b4 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -84,21 +84,18 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)  bool LLInventoryFilter::check(const LLFolderViewModelItem* item)   {  	const LLFolderViewModelItemInventory* listener = dynamic_cast<const LLFolderViewModelItemInventory*>(item); -	// Clipboard cut items are *always* filtered so we need this value upfront -	const BOOL passed_clipboard = (listener ? checkAgainstClipboard(listener->getUUID()) : TRUE);  	// If it's a folder and we're showing all folders, return automatically.  	const BOOL is_folder = listener->getInventoryType() == LLInventoryType::IT_CATEGORY;  	if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS))  	{ -		return passed_clipboard; +		return true;  	}  	bool passed = (mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) != std::string::npos : true);  	passed = passed && checkAgainstFilterType(listener);  	passed = passed && checkAgainstPermissions(listener);  	passed = passed && checkAgainstFilterLinks(listener); -	passed = passed && passed_clipboard;  	return passed;  } @@ -108,9 +105,8 @@ bool LLInventoryFilter::check(const LLInventoryItem* item)  	const bool passed_string = (mFilterSubString.size() ? item->getName().find(mFilterSubString) != std::string::npos : true);  	const bool passed_filtertype = checkAgainstFilterType(item);  	const bool passed_permissions = checkAgainstPermissions(item); -	const bool passed_clipboard = checkAgainstClipboard(item->getUUID()); -	return passed_filtertype && passed_permissions && passed_clipboard && passed_string; +	return passed_filtertype && passed_permissions && passed_string;  }  bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const @@ -129,13 +125,10 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const  bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const  { -	// Always check against the clipboard -	const BOOL passed_clipboard = checkAgainstClipboard(folder_id); -	  	// we're showing all folders, overriding filter  	if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)  	{ -		return passed_clipboard; +		return true;  	}  	// when applying a filter, matching folders get their contents downloaded first @@ -201,7 +194,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const  	LLViewerInventoryItem* item = gInventory.getItem(folder_id);  	if (item && item->getActualType() == LLAssetType::AT_LINK_FOLDER)  	{ -		return passed_clipboard; +		return true;  	}  	if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY) @@ -216,7 +209,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const  			return false;  	} -	return passed_clipboard; +	return true;  }  bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInventory* listener) const diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 9a33e210ff..5230e8dff9 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -582,7 +582,7 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,  	// Add the category to the internal representation  	LLPointer<LLViewerInventoryCategory> cat =  		new LLViewerInventoryCategory(id, parent_id, preferred_type, name, gAgent.getID()); -	cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL); +	cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1  	cat->setDescendentCount(0);  	LLCategoryUpdate update(cat->getParentUUID(), 1);  	accountForUpdate(update); @@ -640,7 +640,7 @@ void LLInventoryModel::createNewCategoryCoro(std::string url, LLSD postData, inv          result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),          result["name"].asString(), gAgent.getID()); -    cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL); +    cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1      cat->setDescendentCount(0);      LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1); @@ -914,8 +914,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)  			item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, category_id);  			if( item_array )  			{ +				LLInventoryModel::LLCategoryUpdate update(category_id, 1); +				gInventory.accountForUpdate(update); +  				// *FIX: bit of a hack to call update server from here... -				new_item->updateServer(TRUE); +				new_item->updateParentOnServer(FALSE);  				item_array->push_back(new_item);  			}  			else @@ -956,9 +959,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)  				item_array = get_ptr_in_map(mParentChildItemTree, parent_id);  				if(item_array)  				{ +					LLInventoryModel::LLCategoryUpdate update(parent_id, 1); +					gInventory.accountForUpdate(update);  					// *FIX: bit of a hack to call update server from  					// here... -					new_item->updateServer(TRUE); +					new_item->updateParentOnServer(FALSE);  					item_array->push_back(new_item);  				}  				else @@ -1045,7 +1050,6 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32  	if(old_cat)  	{  		// We already have an old category, modify its values -		U32 mask = LLInventoryObserver::NONE;  		LLUUID old_parent_id = old_cat->getParentUUID();  		LLUUID new_parent_id = cat->getParentUUID();  		if(old_parent_id != new_parent_id) @@ -1100,7 +1104,8 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32  		item_array_t* itemsp = new item_array_t;  		mParentChildCategoryTree[new_cat->getUUID()] = catsp;  		mParentChildItemTree[new_cat->getUUID()] = itemsp; -		addChangedMask(LLInventoryObserver::ADD, cat->getUUID()); +		mask |= LLInventoryObserver::ADD; +		addChangedMask(mask, cat->getUUID());  	}  } diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 639641d1c2..485d4677b1 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -244,7 +244,10 @@ std::string LLLogChat::makeLogFileName(std::string filename)  	filename = cleanFileName(filename);  	filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename); -	filename += '.' + LL_TRANSCRIPT_FILE_EXTENSION; +	if (!filename.empty()) +	{ +		filename += '.' + LL_TRANSCRIPT_FILE_EXTENSION; +	}  	return filename;  } diff --git a/indra/newview/llmanip.h b/indra/newview/llmanip.h index 1fb05e047a..69881e8589 100644 --- a/indra/newview/llmanip.h +++ b/indra/newview/llmanip.h @@ -1,4 +1,4 @@ -/**  +/**    * @file llmanip.h   * @brief LLManip class definition   * @@ -37,7 +37,7 @@ class LLToolComposite;  class LLVector3;  class LLObjectSelection; -const S32 MIN_DIVISION_PIXEL_WIDTH = 9; +const S32 MIN_DIVISION_PIXEL_WIDTH = 3;  class LLManip : public LLTool  { diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index b4259a456c..3975d3980b 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -1,4 +1,4 @@ -/**  +/**    * @file llmaniptranslate.cpp   * @brief LLManipTranslate class implementation   * @@ -548,12 +548,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)  		if (off_axis_magnitude > mSnapOffsetMeters)  		{  			mInSnapRegime = TRUE; -			LLVector3 mouse_down_offset(mDragCursorStartGlobal - mDragSelectionStartGlobal);  			LLVector3 cursor_snap_agent = gAgent.getPosAgentFromGlobal(cursor_point_snap_line); -			if (!gSavedSettings.getBOOL("SnapToMouseCursor")) -			{ -				cursor_snap_agent -= mouse_down_offset; -			}  			F32 cursor_grid_dist = (cursor_snap_agent - mGridOrigin) * axis_f; diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 6cc7a0fc99..54f95520db 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -773,7 +773,9 @@ void LLMarketplaceData::getMerchantStatusCoro()      std::string url = getSLMConnectURL("/merchant");      if (url.empty())      { -        LL_INFOS("Marketplace") << "No marketplace capability on Sim" << LL_ENDL; +        LL_WARNS("Marketplace") << "No marketplace capability on Sim" << LL_ENDL; +        setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE); +        return;      }      LLSD result = httpAdapter->getAndSuspend(httpRequest, url, httpOpts); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 18634de500..27b26efa51 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -4099,7 +4099,7 @@ F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32  		}  	} -	F32 max_area = 102932.f; //area of circle that encompasses region +	F32 max_area = 102944.f; //area of circle that encompasses region (see MAINT-6559)  	F32 min_area = 1.f;  	F32 high_area = llmin(F_PI*dmid*dmid, max_area); diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index b2164c1f21..d17f5494a0 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -199,7 +199,7 @@ void LLPanelGroupGeneral::setupCtrls(LLPanel* panel_group)  	mGroupNameEditor = panel_group->getChild<LLLineEditor>("group_name_editor"); -	mGroupNameEditor->setPrevalidate( LLTextValidate::validateASCII ); +	mGroupNameEditor->setPrevalidate( LLTextValidate::validateASCIINoLeadingSpace );  } diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 8331c152e2..8b9941c0ca 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -1059,9 +1059,6 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void)  		case LLAssetType::AT_BODYPART:  			applyListViewFilter(LVIT_BODYPART);  			break; -		case LLAssetType::AT_GESTURE: -			applyListViewFilter(LVIT_GESTURES); -			break;  		case LLAssetType::AT_CLOTHING:  		default:  			applyListViewFilter(LVIT_CLOTHING); diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 841bb4337a..30870daf40 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -80,7 +80,6 @@ public:  	{  		LVIT_ALL = 0,  		LVIT_CLOTHING, -		LVIT_GESTURES,  		LVIT_BODYPART,  		LVIT_ATTACHMENT,  		LVIT_SHAPE, diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index d0353259a5..796372ba04 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -30,13 +30,19 @@  #include "lltoggleablemenu.h" +#include "llagent.h" +#include "llaccordionctrl.h" +#include "llaccordionctrltab.h"  #include "llappearancemgr.h"  #include "llfloatersidepanelcontainer.h"  #include "llinventoryfunctions.h" +#include "llinventoryicon.h"  #include "llinventorymodel.h"  #include "llinventoryobserver.h"  #include "llmenubutton.h" +#include "llscrolllistctrl.h"  #include "llviewermenu.h" +#include "llviewerregion.h"  #include "llwearableitemslist.h"  #include "llsdserialize.h"  #include "llclipboard.h" @@ -146,11 +152,47 @@ protected:  		menu->setItemVisible("detach",		allow_detach);  		menu->setItemVisible("edit_outfit_separator", allow_take_off || allow_detach);  		menu->setItemVisible("show_original", mUUIDs.size() == 1); +		menu->setItemVisible("edit_item", FALSE);  	}  };  ////////////////////////////////////////////////////////////////////////// +class LLTempAttachmentsContextMenu : public LLListContextMenu +{ +public: +	LLTempAttachmentsContextMenu(LLPanelWearing* panel_wearing) +		:	mPanelWearing(panel_wearing) +	{} +protected: +	/* virtual */ LLContextMenu* createMenu() +	{ +		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + +		registrar.add("Wearing.EditItem", boost::bind(&LLPanelWearing::onEditAttachment, mPanelWearing)); +		registrar.add("Wearing.Detach", boost::bind(&LLPanelWearing::onRemoveAttachment, mPanelWearing)); +		LLContextMenu* menu = createFromFile("menu_wearing_tab.xml"); + +		updateMenuItemsVisibility(menu); + +		return menu; +	} + +	void updateMenuItemsVisibility(LLContextMenu* menu) +	{ +		menu->setItemVisible("take_off", FALSE); +		menu->setItemVisible("detach", TRUE); +		menu->setItemVisible("edit_outfit_separator", TRUE); +		menu->setItemVisible("show_original", FALSE); +		menu->setItemVisible("edit_item", TRUE); +		menu->setItemVisible("edit", FALSE); +	} + +	LLPanelWearing* 		mPanelWearing; +}; + +////////////////////////////////////////////////////////////////////////// +  std::string LLPanelAppearanceTab::sFilterSubString = LLStringUtil::null;  static LLPanelInjector<LLPanelWearing> t_panel_wearing("panel_wearing"); @@ -159,30 +201,47 @@ LLPanelWearing::LLPanelWearing()  	:	LLPanelAppearanceTab()  	,	mCOFItemsList(NULL)  	,	mIsInitialized(false) +	,	mAttachmentsChangedConnection()  {  	mCategoriesObserver = new LLInventoryCategoriesObserver();  	mGearMenu = new LLWearingGearMenu(this);  	mContextMenu = new LLWearingContextMenu(); +	mAttachmentsMenu = new LLTempAttachmentsContextMenu(this);  }  LLPanelWearing::~LLPanelWearing()  {  	delete mGearMenu;  	delete mContextMenu; +	delete mAttachmentsMenu;  	if (gInventory.containsObserver(mCategoriesObserver))  	{  		gInventory.removeObserver(mCategoriesObserver);  	}  	delete mCategoriesObserver; + +	if (mAttachmentsChangedConnection.connected()) +	{ +		mAttachmentsChangedConnection.disconnect(); +	}  }  BOOL LLPanelWearing::postBuild()  { +	mAccordionCtrl = getChild<LLAccordionCtrl>("wearables_accordion"); +	mWearablesTab = getChild<LLAccordionCtrlTab>("tab_wearables"); +	mAttachmentsTab = getChild<LLAccordionCtrlTab>("tab_temp_attachments"); +	mAttachmentsTab->setDropDownStateChangedCallback(boost::bind(&LLPanelWearing::onAccordionTabStateChanged, this)); +  	mCOFItemsList = getChild<LLWearableItemsList>("cof_items_list");  	mCOFItemsList->setRightMouseDownCallback(boost::bind(&LLPanelWearing::onWearableItemsListRightClick, this, _1, _2, _3)); +	mTempItemsList = getChild<LLScrollListCtrl>("temp_attachments_list"); +	mTempItemsList->setFgUnselectedColor(LLColor4::white); +	mTempItemsList->setRightMouseDownCallback(boost::bind(&LLPanelWearing::onTempAttachmentsListRightClick, this, _1, _2, _3)); +  	LLMenuButton* menu_gear_btn = getChild<LLMenuButton>("options_gear_btn");  	menu_gear_btn->setMenu(mGearMenu->getMenu()); @@ -223,6 +282,44 @@ void LLPanelWearing::onOpen(const LLSD& /*info*/)  	}  } +void LLPanelWearing::draw() +{ +	if (mUpdateTimer.getStarted() && (mUpdateTimer.getElapsedTimeF32() > 0.1)) +	{ +		mUpdateTimer.stop(); +		updateAttachmentsList(); +	} +	LLPanel::draw(); +} + +void LLPanelWearing::onAccordionTabStateChanged() +{ +	if(mAttachmentsTab->isExpanded()) +	{ +		startUpdateTimer(); +		mAttachmentsChangedConnection = LLAppearanceMgr::instance().setAttachmentsChangedCallback(boost::bind(&LLPanelWearing::startUpdateTimer, this)); +	} +	else +	{ +		if (mAttachmentsChangedConnection.connected()) +		{ +			mAttachmentsChangedConnection.disconnect(); +		} +	} +} + +void LLPanelWearing::startUpdateTimer() +{ +	if (!mUpdateTimer.getStarted()) +	{ +		mUpdateTimer.start(); +	} +	else +	{ +		mUpdateTimer.reset(); +	} +} +  // virtual  void LLPanelWearing::setFilterSubString(const std::string& string)  { @@ -251,6 +348,124 @@ bool LLPanelWearing::isActionEnabled(const LLSD& userdata)  	return false;  } +void LLPanelWearing::updateAttachmentsList() +{ +	std::vector<LLViewerObject*> attachs = LLAgentWearables::getTempAttachments(); +	mTempItemsList->deleteAllItems(); +	mAttachmentsMap.clear(); +	if(!attachs.empty()) +	{ +		if(!populateAttachmentsList()) +		{ +			requestAttachmentDetails(); +		} +	} +	else +	{ +		std::string no_attachments = getString("no_attachments"); +		LLSD row; +		row["columns"][0]["column"] = "text"; +		row["columns"][0]["value"] = no_attachments; +		row["columns"][0]["font"] = "SansSerifBold"; +		mTempItemsList->addElement(row); +	} +} + +bool LLPanelWearing::populateAttachmentsList(bool update) +{ +	bool populated = true; +	if(mTempItemsList) +	{ +		mTempItemsList->deleteAllItems(); +		mAttachmentsMap.clear(); +		std::vector<LLViewerObject*> attachs = LLAgentWearables::getTempAttachments(); + +		std::string icon_name = LLInventoryIcon::getIconName(LLAssetType::AT_OBJECT, LLInventoryType::IT_OBJECT); +		for (std::vector<LLViewerObject*>::iterator iter = attachs.begin(); +				iter != attachs.end(); ++iter) +		{ +			LLViewerObject *attachment = *iter; +			LLSD row; +			row["id"] = attachment->getID(); +			row["columns"][0]["column"] = "icon"; +			row["columns"][0]["type"] = "icon"; +			row["columns"][0]["value"] = icon_name; +			row["columns"][1]["column"] = "text"; +			if(mObjectNames.count(attachment->getID()) && !mObjectNames[attachment->getID()].empty()) +			{ +				row["columns"][1]["value"] = mObjectNames[attachment->getID()]; +			} +			else if(update) +			{ +				row["columns"][1]["value"] = attachment->getID(); +				populated = false; +			} +			else +			{ +				row["columns"][1]["value"] = "Loading..."; +				populated = false; +			} +			mTempItemsList->addElement(row); +			mAttachmentsMap[attachment->getID()] = attachment; +		} +	} +	return populated; +} + +void LLPanelWearing::requestAttachmentDetails() +{ +	LLSD body; +	std::string url = gAgent.getRegion()->getCapability("AttachmentResources"); +	if (!url.empty()) +	{ +		LLCoros::instance().launch("LLPanelWearing::getAttachmentLimitsCoro", +		boost::bind(&LLPanelWearing::getAttachmentLimitsCoro, this, url)); +	} +} + +void LLPanelWearing::getAttachmentLimitsCoro(std::string url) +{ +	LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +	LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +	httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getAttachmentLimitsCoro", httpPolicy)); +	LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + +	LLSD result = httpAdapter->getAndSuspend(httpRequest, url); + +	LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +	LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + +	if (!status) +	{ +		LL_WARNS() << "Unable to retrieve attachment limits." << LL_ENDL; +		return; +	} + +	result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); +	setAttachmentDetails(result); +} + + +void LLPanelWearing::setAttachmentDetails(LLSD content) +{ +	mObjectNames.clear(); +	S32 number_attachments = content["attachments"].size(); +	for(int i = 0; i < number_attachments; i++) +	{ +		S32 number_objects = content["attachments"][i]["objects"].size(); +		for(int j = 0; j < number_objects; j++) +		{ +			LLUUID task_id = content["attachments"][i]["objects"][j]["id"].asUUID(); +			std::string name = content["attachments"][i]["objects"][j]["name"].asString(); +			mObjectNames[task_id] = name; +		} +	} +	if(!mObjectNames.empty()) +	{ +		populateAttachmentsList(true); +	} +} +  boost::signals2::connection LLPanelWearing::setSelectionChangeCallback(commit_callback_t cb)  {  	if (!mCOFItemsList) return boost::signals2::connection(); @@ -270,6 +485,20 @@ void LLPanelWearing::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y)  	mContextMenu->show(ctrl, selected_uuids, x, y);  } +void LLPanelWearing::onTempAttachmentsListRightClick(LLUICtrl* ctrl, S32 x, S32 y) +{ +	LLScrollListCtrl* list = dynamic_cast<LLScrollListCtrl*>(ctrl); +	if (!list) return; +	list->selectItemAt(x, y, MASK_NONE); +	uuid_vec_t selected_uuids; + +	if(list->getCurrentID().notNull()) +	{ +		selected_uuids.push_back(list->getCurrentID()); +		mAttachmentsMenu->show(ctrl, selected_uuids, x, y); +	} +} +  bool LLPanelWearing::hasItemSelected()  {  	return mCOFItemsList->getSelectedItem() != NULL; @@ -280,6 +509,28 @@ void LLPanelWearing::getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const  	mCOFItemsList->getSelectedUUIDs(selected_uuids);  } +void LLPanelWearing::onEditAttachment() +{ +	LLScrollListItem* item = mTempItemsList->getFirstSelected(); +	if (item) +	{ +		LLSelectMgr::getInstance()->deselectAll(); +		LLSelectMgr::getInstance()->selectObjectAndFamily(mAttachmentsMap[item->getUUID()]); +		handle_object_edit(); +	} +} + +void LLPanelWearing::onRemoveAttachment() +{ +	LLScrollListItem* item = mTempItemsList->getFirstSelected(); +	if (item) +	{ +		LLSelectMgr::getInstance()->deselectAll(); +		LLSelectMgr::getInstance()->selectObjectAndFamily(mAttachmentsMap[item->getUUID()]); +		LLSelectMgr::getInstance()->sendDropAttachment(); +	} +} +  void LLPanelWearing::copyToClipboard()  {  	std::string text; diff --git a/indra/newview/llpanelwearing.h b/indra/newview/llpanelwearing.h index 9a212b3cca..c5cb79092a 100644 --- a/indra/newview/llpanelwearing.h +++ b/indra/newview/llpanelwearing.h @@ -31,9 +31,14 @@  // newview  #include "llpanelappearancetab.h" +#include "llselectmgr.h" +#include "lltimer.h" +class LLAccordionCtrl; +class LLAccordionCtrlTab;  class LLInventoryCategoriesObserver;  class LLListContextMenu; +class LLScrollListCtrl;  class LLWearableItemsList;  class LLWearingGearMenu; @@ -52,6 +57,8 @@ public:  	/*virtual*/ BOOL postBuild(); +	/*virtual*/ void draw(); +  	/*virtual*/ void onOpen(const LLSD& info);  	/*virtual*/ void setFilterSubString(const std::string& string); @@ -62,17 +69,43 @@ public:  	/*virtual*/ void copyToClipboard(); +	void startUpdateTimer(); +	void updateAttachmentsList(); +  	boost::signals2::connection setSelectionChangeCallback(commit_callback_t cb);  	bool hasItemSelected(); +	bool populateAttachmentsList(bool update = false); +	void onAccordionTabStateChanged(); +	void setAttachmentDetails(LLSD content); +	void requestAttachmentDetails(); +	void onEditAttachment(); +	void onRemoveAttachment(); +  private:  	void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y); +	void onTempAttachmentsListRightClick(LLUICtrl* ctrl, S32 x, S32 y); + +	void getAttachmentLimitsCoro(std::string url);  	LLInventoryCategoriesObserver* 	mCategoriesObserver;  	LLWearableItemsList* 			mCOFItemsList; +	LLScrollListCtrl*				mTempItemsList;  	LLWearingGearMenu*				mGearMenu;  	LLListContextMenu*				mContextMenu; +	LLListContextMenu*				mAttachmentsMenu; + +	LLAccordionCtrlTab* 			mWearablesTab; +	LLAccordionCtrlTab* 			mAttachmentsTab; +	LLAccordionCtrl*				mAccordionCtrl; + +	std::map<LLUUID, LLViewerObject*> mAttachmentsMap; + +	std::map<LLUUID, std::string> 	mObjectNames; + +	boost::signals2::connection 	mAttachmentsChangedConnection; +	LLFrameTimer					mUpdateTimer;  	bool							mIsInitialized;  }; diff --git a/indra/newview/llpathfindinglinksetlist.cpp b/indra/newview/llpathfindinglinksetlist.cpp index b886e46765..eb7b95552e 100644 --- a/indra/newview/llpathfindinglinksetlist.cpp +++ b/indra/newview/llpathfindinglinksetlist.cpp @@ -204,7 +204,10 @@ void LLPathfindingLinksetList::parseLinksetListData(const LLSD& pLinksetListData  	{  		const std::string& uuid(linksetDataIter->first);  		const LLSD& linksetData = linksetDataIter->second; -		LLPathfindingObjectPtr linksetPtr(new LLPathfindingLinkset(uuid, linksetData)); -		objectMap.insert(std::pair<std::string, LLPathfindingObjectPtr>(uuid, linksetPtr)); +		if(linksetData.size() != 0) +		{ +			LLPathfindingObjectPtr linksetPtr(new LLPathfindingLinkset(uuid, linksetData)); +			objectMap.insert(std::pair<std::string, LLPathfindingObjectPtr>(uuid, linksetPtr)); +		}  	}  } diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp index 9957039f72..836f63bffa 100644 --- a/indra/newview/llpresetsmanager.cpp +++ b/indra/newview/llpresetsmanager.cpp @@ -104,8 +104,7 @@ void LLPresetsManager::loadPresetNamesFromDir(const std::string& dir, preset_nam  		if (found)  		{  			std::string path = gDirUtilp->add(dir, file); -			std::string name = gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true); - +			std::string name = LLURI::unescape(gDirUtilp->getBaseFileName(path, /*strip_exten = */ true));              LL_DEBUGS() << "  Found preset '" << name << "'" << LL_ENDL;  			if (PRESETS_DEFAULT != name) diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index ba9845ef04..510d91839d 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -437,6 +437,23 @@ void LLPreviewNotecard::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId,      }  } +void LLPreviewNotecard::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId) +{ + +    LLSD floater_key; +    floater_key["taskid"] = taskId; +    floater_key["itemid"] = itemId; +    LLPreviewNotecard* nc = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", floater_key); +    if (nc) +    { +        if (nc->hasEmbeddedInventory()) +        { +            gVFS->removeFile(newAssetId, LLAssetType::AT_NOTECARD); +        } +        nc->setAssetId(newAssetId); +        nc->refreshFromInventory(); +    } +}  bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)  { @@ -485,7 +502,7 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)                  else if (!mObjectUUID.isNull() && !task_url.empty())                  {                      uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mObjectUUID, mItemUUID, LLAssetType::AT_NOTECARD, buffer,  -                        boost::bind(&LLPreviewNotecard::finishInventoryUpload, _1, _3, LLUUID::null))); +                        boost::bind(&LLPreviewNotecard::finishTaskUpload, _1, _3, mObjectUUID)));                      url = task_url;                  } diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h index ba571995f6..017c4485ba 100644 --- a/indra/newview/llpreviewnotecard.h +++ b/indra/newview/llpreviewnotecard.h @@ -96,6 +96,7 @@ protected:  	bool handleConfirmDeleteDialog(const LLSD& notification, const LLSD& response);      static void finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId); +    static void finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId);  protected:  	LLViewerTextEditor* mEditor; diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 86135ee6e8..f07f0ed86c 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -383,7 +383,7 @@ void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_cam  void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLViewerWearable *wearable, BOOL disable_camera_switch)  { -	if (!mEditWearable || mEditWearable->getVisible() == visible) +	if (!mEditWearable || ((mEditWearable->getWearable() == wearable) && mEditWearable->getVisible() == visible))  	{  		// visibility isn't changing, hence nothing to do  		return; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index a2c8e7772e..4e81d78455 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -771,7 +771,11 @@ bool idle_startup()  					LL_DEBUGS("AppInit") << "FirstLoginThisInstall off" << LL_ENDL;  				}  			} - +			display_startup(); +			if (gViewerWindow->getSystemUIScaleFactorChanged()) +			{ +				LLViewerWindow::showSystemUIScaleFactorChanged(); +			}  			LLStartUp::setStartupState( STATE_LOGIN_WAIT );		// Wait for user input  		}  		else diff --git a/indra/newview/llviewchildren.cpp b/indra/newview/llviewchildren.cpp index 5c5bbdc8f5..32b2f7e9f5 100644 --- a/indra/newview/llviewchildren.cpp +++ b/indra/newview/llviewchildren.cpp @@ -79,8 +79,9 @@ void LLViewChildren::setBadge(const std::string& id, Badge badge, bool visible)  			default:  			case BADGE_OK:		child->setValue(std::string("badge_ok.j2c"));	break;  			case BADGE_NOTE:	child->setValue(std::string("badge_note.j2c"));	break; -			case BADGE_WARN:	child->setValue(std::string("badge_warn.j2c"));	break; -			case BADGE_ERROR:	child->setValue(std::string("badge_error.j2c"));	break; +			case BADGE_WARN: +			case BADGE_ERROR: +				child->setValue(std::string("badge_warn.j2c"));	break;  		}  	}  } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 16f40fb747..5e74e9f019 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -207,6 +207,12 @@ static bool handleVolumeLODChanged(const LLSD& newvalue)  	return true;  } +static bool handleRiggedLODChanged(const LLSD& newvalue) +{ +    LLVOVolume::sRiggedFactorMultiplier = (F32)newvalue.asReal(); +    return true; +} +  static bool handleAvatarLODChanged(const LLSD& newvalue)  {  	LLVOAvatar::sLODFactor = (F32) newvalue.asReal(); @@ -619,6 +625,7 @@ void settings_setup_listeners()  	gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2)); +	gSavedSettings.getControl("RenderRiggedFactorMultiplier")->getSignal()->connect(boost::bind(&handleRiggedLODChanged, _2));  	gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2));  	gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2));  	gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _2)); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index d0813544f8..0bbe9fa2c2 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1007,6 +1007,22 @@ void activate_gesture_cb(const LLUUID& inv_item)  	LLGestureMgr::instance().activateGesture(inv_item);  } +void set_default_permissions(LLViewerInventoryItem* item, std::string perm_type) +{ +	llassert(item); +	LLPermissions perm = item->getPermissions(); +	if (perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms(perm_type) +		|| perm.getMaskGroup() != LLFloaterPerms::getGroupPerms(perm_type)) +	{ +		perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms(perm_type)); +		perm.setMaskGroup(LLFloaterPerms::getGroupPerms(perm_type)); + +		item->setPermissions(perm); + +		item->updateServer(FALSE); +	} +} +  void create_script_cb(const LLUUID& inv_item)  {  	if (!inv_item.isNull()) @@ -1014,13 +1030,9 @@ void create_script_cb(const LLUUID& inv_item)  		LLViewerInventoryItem* item = gInventory.getItem(inv_item);  		if (item)  		{ -			LLPermissions perm = item->getPermissions(); -			perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Scripts")); -			perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Scripts")); - -			item->setPermissions(perm); +			set_default_permissions(item, "Scripts"); -			item->updateServer(FALSE); +			// item was just created, update even if permissions did not changed  			gInventory.updateItem(item);  			gInventory.notifyObservers();  		} @@ -1036,13 +1048,8 @@ void create_gesture_cb(const LLUUID& inv_item)  		LLViewerInventoryItem* item = gInventory.getItem(inv_item);  		if (item)  		{ -			LLPermissions perm = item->getPermissions(); -			perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Gestures")); -			perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Gestures")); +			set_default_permissions(item, "Gestures"); -			item->setPermissions(perm); - -			item->updateServer(FALSE);  			gInventory.updateItem(item);  			gInventory.notifyObservers(); @@ -1061,13 +1068,8 @@ void create_notecard_cb(const LLUUID& inv_item)  		LLViewerInventoryItem* item = gInventory.getItem(inv_item);  		if (item)  		{ -			LLPermissions perm = item->getPermissions(); -			perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Notecards")); -			perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Notecards")); - -			item->setPermissions(perm); +			set_default_permissions(item, "Notecards"); -			item->updateServer(FALSE);  			gInventory.updateItem(item);  			gInventory.notifyObservers();  		} diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index f5b06fbd19..46f03f9971 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -397,13 +397,15 @@ void set_merchant_SLM_menu()  	gToolBarView->enableCommand(command->id(), true);  } -void check_merchant_status() +void check_merchant_status(bool force)  {      if (!gSavedSettings.getBOOL("InventoryOutboxDisplayBoth"))      { -        // Reset the SLM status: we actually want to check again, that's the point of calling check_merchant_status() -        LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED); -         +        if (force) +        { +            // Reset the SLM status: we actually want to check again, that's the point of calling check_merchant_status() +            LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED); +        }          // Hide SLM related menu item          gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible(FALSE); diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index b7bdf00157..a553bb79a2 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -83,7 +83,7 @@ BOOL enable_god_full(void* user_data);  BOOL enable_god_liaison(void* user_data);  BOOL enable_god_basic(void* user_data);  void set_underclothes_menu_options(); -void check_merchant_status(); +void check_merchant_status(bool force = false);  void exchange_callingcard(const LLUUID& dest_id); @@ -108,6 +108,7 @@ void handle_look_at_selection(const LLSD& param);  void handle_zoom_to_object(LLUUID object_id);  void handle_object_return();  void handle_object_delete(); +void handle_object_edit();  void handle_buy_land(); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 92df3866f7..3925154c0f 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1639,7 +1639,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&  			LLDiscardAgentOffer* discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID);  			discard_agent_offer->startFetch(); -			if (catp || (itemp && itemp->isFinished())) +			if ((catp && gInventory.isCategoryComplete(mObjectID)) || (itemp && itemp->isFinished()))  			{  				discard_agent_offer->done();  			} @@ -4719,7 +4719,9 @@ void process_sound_trigger(LLMessageSystem *msg, void **)  {  	if (!gAudiop)  	{ +#if !LL_LINUX  		LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; +#endif  		return;  	} @@ -4781,7 +4783,9 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data)  {  	if (!gAudiop)  	{ +#if !LL_LINUX  		LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; +#endif  		return;  	} diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 5edc3c9745..72a8595845 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -133,6 +133,7 @@ std::map<std::string, U32> LLViewerObject::sObjectDataMap;  // JC 3/18/2003  const F32 PHYSICS_TIMESTEP = 1.f / 45.f; +const F64 INV_REQUEST_EXPIRE_TIME_SEC = 60.f;  static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object"); @@ -245,7 +246,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe  	mInventory(NULL),  	mInventorySerialNum(0),  	mRegionp( regionp ), -	mInventoryPending(FALSE), +	mInvRequestExpireTime(0.f),  	mInventoryDirty(FALSE),  	mDead(FALSE),  	mOrphaned(FALSE), @@ -1434,10 +1435,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  					setChanged(MOVED | SILHOUETTE);  				} -				else if (mText.notNull()) +				else  				{ -					mText->markDead(); -					mText = NULL; +					if (mText.notNull()) +					{ +						mText->markDead(); +						mText = NULL; +					} +					mHudText.clear();  				}  				std::string media_url; @@ -1812,10 +1817,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  					setChanged(TEXTURE);  				} -				else if(mText.notNull()) +				else  				{ -					mText->markDead(); -					mText = NULL; +					if (mText.notNull()) +					{ +						mText->markDead(); +						mText = NULL; +					} +					mHudText.clear();  				}                  std::string media_url; @@ -2832,6 +2841,15 @@ void LLViewerObject::removeInventoryListener(LLVOInventoryListener* listener)  	}  } +BOOL LLViewerObject::isInventoryPending() +{ +    if (mInvRequestExpireTime == 0.f || mInvRequestExpireTime < LLFrameTimer::getTotalSeconds()) +    { +        return FALSE; +    } +    return TRUE; +} +  void LLViewerObject::clearInventoryListeners()  {  	for_each(mInventoryCallbacks.begin(), mInventoryCallbacks.end(), DeletePointer()); @@ -2870,7 +2888,7 @@ void LLViewerObject::requestInventory()  void LLViewerObject::fetchInventoryFromServer()  { -	if (!mInventoryPending) +	if (mInvRequestExpireTime == 0.f || mInvRequestExpireTime < LLFrameTimer::getTotalSeconds())  	{  		delete mInventory;  		LLMessageSystem* msg = gMessageSystem; @@ -2883,7 +2901,7 @@ void LLViewerObject::fetchInventoryFromServer()  		msg->sendReliable(mRegionp->getHost());  		// this will get reset by dirtyInventory or doInventoryCallback -		mInventoryPending = TRUE; +		mInvRequestExpireTime = LLFrameTimer::getTotalSeconds() + INV_REQUEST_EXPIRE_TIME_SEC;  	}  } @@ -3099,7 +3117,7 @@ void LLViewerObject::doInventoryCallback()  			mInventoryCallbacks.erase(curiter);  		}  	} -	mInventoryPending = FALSE; +	mInvRequestExpireTime = 0.f;  }  void LLViewerObject::removeInventory(const LLUUID& item_id) @@ -4990,8 +5008,26 @@ void LLViewerObject::initHudText()  void LLViewerObject::restoreHudText()  { -    if(mText) +    if (mHudText.empty()) +    { +        if (mText) +        { +            mText->markDead(); +            mText = NULL; +        } +    } +    else      { +        if (!mText) +        { +            initHudText(); +        } +        else +        { +            // Restore default values +            mText->setZCompare(TRUE); +            mText->setDoFade(TRUE); +        }          mText->setColor(mHudTextColor);          mText->setString(mHudText);      } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index cb8acfdcf8..b95190c554 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -437,7 +437,7 @@ public:  	// viewer object has the inventory stored locally.  	void registerInventoryListener(LLVOInventoryListener* listener, void* user_data);  	void removeInventoryListener(LLVOInventoryListener* listener); -	BOOL isInventoryPending() { return mInventoryPending; } +	BOOL isInventoryPending();  	void clearInventoryListeners();  	bool hasInventoryListeners();  	void requestInventory(); @@ -757,7 +757,7 @@ protected:  	S16 mInventorySerialNum;  	LLViewerRegion	*mRegionp;					// Region that this object belongs to. -	BOOL			mInventoryPending; +	F64				mInvRequestExpireTime;  	BOOL			mInventoryDirty;  	BOOL			mDead;  	BOOL			mOrphaned;					// This is an orphaned child diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index 023f1b92ba..86591ff4df 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -465,7 +465,7 @@ LLViewerOctreeGroup::LLViewerOctreeGroup(OctreeNode* node)  {  	LLVector4a tmp;  	tmp.splat(0.f); -	mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] =  +	mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[1] =   		mObjectExtents[0] = mObjectExtents[1] = tmp;  	mBounds[0] = node->getCenter(); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index ed719ae418..178aa1e646 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1200,7 +1200,7 @@ void LLViewerFetchedTexture::loadFromFastCache()              {                  S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;                  S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS; -                if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height) +                if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))                  {                      // scale oversized icon, no need to give more work to gl                      mRawImage->scale(expected_width, expected_height); @@ -1981,7 +1981,7 @@ bool LLViewerFetchedTexture::updateFetch()                  {                      S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;                      S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS; -                    if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height) +                    if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))                      {                          // scale oversized icon, no need to give more work to gl                          mRawImage->scale(expected_width, expected_height); diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp index 0f73515b5d..88eb13e7cd 100644 --- a/indra/newview/llviewerwearable.cpp +++ b/indra/newview/llviewerwearable.cpp @@ -451,7 +451,7 @@ void LLViewerWearable::copyDataFrom(const LLViewerWearable* src)  	// Probably reduntant, but ensure that the newly created wearable is not dirty by setting current value of params in new wearable  	// to be the same as the saved values (which were loaded from src at param->cloneParam(this)) -	revertValues(); +	revertValuesWithoutUpdate();  }  void LLViewerWearable::setItemID(const LLUUID& item_id) @@ -471,6 +471,11 @@ void LLViewerWearable::revertValues()  	}  } +void LLViewerWearable::revertValuesWithoutUpdate() +{ +	LLWearable::revertValues(); +} +  void LLViewerWearable::saveValues()  {  	LLWearable::saveValues(); diff --git a/indra/newview/llviewerwearable.h b/indra/newview/llviewerwearable.h index 62cd5e21ad..cc99f6af2f 100644 --- a/indra/newview/llviewerwearable.h +++ b/indra/newview/llviewerwearable.h @@ -85,6 +85,8 @@ public:  	/*virtual*/ void	revertValues();  	/*virtual*/ void	saveValues(); +	void 				revertValuesWithoutUpdate(); +  	// Something happened that requires the wearable's label to be updated (e.g. worn/unworn).  	/*virtual*/void		setUpdated() const; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index c17c50fd88..f47a37fcda 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1655,7 +1655,8 @@ LLViewerWindow::LLViewerWindow(const Params& p)  	mResDirty(false),  	mStatesDirty(false),  	mCurrResolutionIndex(0), -	mProgressView(NULL) +	mProgressView(NULL), +	mSystemUIScaleFactorChanged(false)  {  	// gKeyboard is still NULL, so it doesn't do LLWindowListener any good to  	// pass its value right now. Instead, pass it a nullary function that @@ -1743,6 +1744,16 @@ LLViewerWindow::LLViewerWindow(const Params& p)  		gSavedSettings.setS32("FullScreenHeight",scr.mY);      } + +	F32 system_scale_factor = mWindow->getSystemUISize(); +	if (p.first_run || gSavedSettings.getF32("LastSystemUIScaleFactor") != system_scale_factor) +	{ +		mSystemUIScaleFactorChanged = true; +		gSavedSettings.setF32("LastSystemUIScaleFactor", system_scale_factor); +		gSavedSettings.setF32("UIScaleFactor", system_scale_factor); +	} + +  	// Get the real window rect the window was created with (since there are various OS-dependent reasons why  	// the size of a window or fullscreen context may have been adjusted slightly...)  	F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor"); @@ -1838,6 +1849,28 @@ LLViewerWindow::LLViewerWindow(const Params& p)  	mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);  } +//static +void LLViewerWindow::showSystemUIScaleFactorChanged() +{ +	LLNotificationsUtil::add("SystemUIScaleFactorChanged", LLSD(), LLSD(), onSystemUIScaleFactorChanged); +} + +//static +bool LLViewerWindow::onSystemUIScaleFactorChanged(const LLSD& notification, const LLSD& response) +{ +	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +	if(option == 0) +	{ +		LLFloaterReg::toggleInstanceOrBringToFront("preferences"); +		LLFloater* pref_floater = LLFloaterReg::getInstance("preferences"); +		LLTabContainer* tab_container = pref_floater->getChild<LLTabContainer>("pref core"); +		tab_container->selectTabByName("advanced1"); + +	} +	return false;  +} + +  void LLViewerWindow::initGLDefaults()  {  	gGL.setSceneBlendType(LLRender::BT_ALPHA); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index ad06f00234..afe80358ca 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -155,7 +155,8 @@ public:  									min_width,  									min_height;  		Optional<bool>				fullscreen, -									ignore_pixel_depth; +									ignore_pixel_depth, +									first_run;  		Params();  	}; @@ -418,6 +419,9 @@ public:  	void			calcDisplayScale();  	static LLRect 	calcScaledRect(const LLRect & rect, const LLVector2& display_scale); +	bool getSystemUIScaleFactorChanged() { return mSystemUIScaleFactorChanged; } +	static void showSystemUIScaleFactorChanged(); +  private:  	bool                    shouldShowToolTipFor(LLMouseHandler *mh); @@ -431,6 +435,7 @@ private:  	S32				getChatConsoleBottomPad(); // Vertical padding for child console rect, varied by bottom clutter  	LLRect			getChatConsoleRect(); // Get optimal cosole rect. +	static bool onSystemUIScaleFactorChanged(const LLSD& notification, const LLSD& response);  private:  	LLWindow*		mWindow;						// graphical window object  	bool			mActive; @@ -509,6 +514,7 @@ private:  	LLPointer<LLViewerObject>	mDragHoveredObject;  	static LLTrace::SampleStatHandle<>	sMouseVelocityStat; +	bool mSystemUIScaleFactorChanged; // system UI scale factor changed from last run  };  // diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 486f6fae61..5fc571bf1d 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -86,6 +86,7 @@ BOOL gAnimateTextures = TRUE;  //extern BOOL gHideSelectedObjects;  F32 LLVOVolume::sLODFactor = 1.f; +F32 LLVOVolume::sRiggedFactorMultiplier = 6.f;  F32	LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop   F32 LLVOVolume::sDistanceFactor = 1.0f;  S32 LLVOVolume::sNumLODChanges = 0; @@ -1213,18 +1214,18 @@ void LLVOVolume::sculpt()  	}  } -S32	LLVOVolume::computeLODDetail(F32 distance, F32 radius) +S32	LLVOVolume::computeLODDetail(F32 distance, F32 radius, F32 lod_factor)  {  	S32	cur_detail;  	if (LLPipeline::sDynamicLOD)  	{  		// We've got LOD in the profile, and in the twist.  Use radius. -		F32 tan_angle = (LLVOVolume::sLODFactor*radius)/distance; +		F32 tan_angle = (lod_factor*radius) / distance;  		cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f));  	}  	else  	{ -		cur_detail = llclamp((S32) (sqrtf(radius)*LLVOVolume::sLODFactor*4.f), 0, 3);		 +		cur_detail = llclamp((S32)(sqrtf(radius)*lod_factor*4.f), 0, 3);  	}  	return cur_detail;  } @@ -1240,6 +1241,7 @@ BOOL LLVOVolume::calcLOD()  	F32 radius;  	F32 distance; +	F32 lod_factor = LLVOVolume::sLODFactor;  	if (mDrawable->isState(LLDrawable::RIGGED))  	{ @@ -1251,22 +1253,27 @@ BOOL LLVOVolume::calcLOD()  			return FALSE;  		} +		// Note: when changing, take note that a lot of rigged meshes have only one LOD. +		lod_factor *= LLVOVolume::sRiggedFactorMultiplier;  		distance = avatar->mDrawable->mDistanceWRTCamera; -		radius = avatar->getBinRadius(); +		F32 avatar_radius = avatar->getBinRadius(); +		F32 object_radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length(); +		radius = object_radius * LLVOVolume::sRiggedFactorMultiplier; +		radius = llmin(radius, avatar_radius);  	}  	else  	{  		distance = mDrawable->mDistanceWRTCamera;  		radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length();  	} -	 +  	//hold onto unmodified distance for debugging  	//F32 debug_distance = distance; -	 +  	distance *= sDistanceFactor; -	F32 rampDist = LLVOVolume::sLODFactor * 2; -	 +	F32 rampDist = lod_factor * 2; +  	if (distance < rampDist)  	{  		// Boost LOD when you're REALLY close @@ -1279,7 +1286,8 @@ BOOL LLVOVolume::calcLOD()  	distance *= F_PI/3.f;  	cur_detail = computeLODDetail(ll_round(distance, 0.01f),  -									ll_round(radius, 0.01f)); +									ll_round(radius, 0.01f), +									lod_factor);  	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) && @@ -1753,7 +1761,10 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)  		dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));  		compiled = TRUE;  		lodOrSculptChanged(drawable, compiled); -		genBBoxes(FALSE); +		if (!mLODChanged) +		{ +			genBBoxes(FALSE); +		}  	}  	// it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local  	else diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index a331908320..ca9917069b 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -327,7 +327,7 @@ public:  	void clearRiggedVolume();  protected: -	S32	computeLODDetail(F32	distance, F32 radius); +	S32	computeLODDetail(F32	distance, F32 radius, F32 lod_factor);  	BOOL calcLOD();  	LLFace* addFace(S32 face_index);  	void updateTEData(); @@ -379,6 +379,7 @@ private:  public:  	static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop  	static F32 sLODFactor;				// LOD scale factor +	static F32 sRiggedFactorMultiplier;	// Worn rigged LOD scale factor multiplier  	static F32 sDistanceFactor;			// LOD distance factor  	static LLPointer<LLObjectMediaDataClient> sObjectMediaClient; diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp index 066cb9a0ac..482a2a61e2 100644 --- a/indra/newview/llwlparamset.cpp +++ b/indra/newview/llwlparamset.cpp @@ -288,14 +288,6 @@ void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight)  {  	// set up the iterators -	// keep cloud positions and coverage the same -	/// TODO masking will do this later -	F32 cloudPos1X = (F32) mParamValues["cloud_pos_density1"][0].asReal(); -	F32 cloudPos1Y = (F32) mParamValues["cloud_pos_density1"][1].asReal(); -	F32 cloudPos2X = (F32) mParamValues["cloud_pos_density2"][0].asReal(); -	F32 cloudPos2Y = (F32) mParamValues["cloud_pos_density2"][1].asReal(); -	F32 cloudCover = (F32) mParamValues["cloud_shadow"][0].asReal(); -  	LLSD srcVal;  	LLSD destVal; @@ -379,15 +371,6 @@ void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight)  	setSunAngle((1 - weight) * srcSunAngle + weight * destSunAngle);  	setEastAngle((1 - weight) * srcEastAngle + weight * destEastAngle); -	 -	// now setup the sun properly - -	// reset those cloud positions -	mParamValues["cloud_pos_density1"][0] = cloudPos1X; -	mParamValues["cloud_pos_density1"][1] = cloudPos1Y; -	mParamValues["cloud_pos_density2"][0] = cloudPos2X; -	mParamValues["cloud_pos_density2"][1] = cloudPos2Y; -	mParamValues["cloud_shadow"][0] = cloudCover;  }  void LLWLParamSet::updateCloudScrolling(void)  diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp index 97a9eb7f5f..cc3645131d 100644 --- a/indra/newview/llxmlrpclistener.cpp +++ b/indra/newview/llxmlrpclistener.cpp @@ -322,7 +322,7 @@ public:          mBoundListener =              LLEventPumps::instance().              obtain("mainloop"). -            listen(LLEventPump::inventName(), boost::bind(&Poller::poll, this, _1)); +            listen(LLEventPump::ANONYMOUS, boost::bind(&Poller::poll, this, _1));          LL_INFOS("LLXMLRPCListener") << mMethod << " request sent to " << mUri << LL_ENDL;      } diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 72037a84b3..85f4ae587a 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -774,6 +774,9 @@ with the same filename but different name    <texture name="default_land_picture.j2c" />    <texture name="default_profile_picture.j2c" />    <texture name="locked_image.j2c" /> +  <texture name="badge_note.j2c" /> +  <texture name="badge_warn.j2c" /> +  <texture name="badge_ok.j2c" />    <texture name="materials_ui_x_24.png" />    <texture name="Progress_1" file_name="icons/Progress_1.png" preload="true" /> diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml index 5d05ecf127..550af03683 100644 --- a/indra/newview/skins/default/xui/en/fonts.xml +++ b/indra/newview/skins/default/xui/en/fonts.xml @@ -10,6 +10,7 @@        <file>ArialUni.ttf</file>      </os>      <os name="Mac"> +      <file>ヒラギノ角ゴシック W3.ttc</file>          <file>ヒラギノ角ゴ Pro W3.otf</file>        <file>ヒラギノ角ゴ ProN W3.otf</file>        <file>ヒラギノ明朝 ProN W3.ttc</file> diff --git a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml index 44b2727671..75c1de24aa 100644 --- a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml +++ b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml @@ -28,6 +28,13 @@           function="Wearing.Edit" />      </menu_item_call>      <menu_item_call +     label="Edit" +     layout="topleft" +     name="edit_item"> +        <on_click +         function="Wearing.EditItem" /> +    </menu_item_call> +    <menu_item_call       label="Show Original"       layout="topleft"       name="show_original"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index dfde38bc5f..54e90ac496 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -832,6 +832,13 @@ If you no longer wish to have these abilities granted to this role, disable them    </notification>    <notification +    icon="notify.tga" +    name="GroupBanUserOnBanlist" +    type="notify"> +Some residents have not been sent an invite due to being banned from the group. +  </notification> + +  <notification     icon="alertmodal.tga"     name="AttachmentDrop"     type="alertmodal"> @@ -3665,6 +3672,13 @@ Can't add estate owner to estate 'Banned Resident' list.    <notification     icon="alertmodal.tga" +   name="ProblemAddingEstateManagerBanned" +   type="alertmodal"> +Unable to add banned resident to estate manager list. +  </notification> + +  <notification +   icon="alertmodal.tga"     name="CanNotChangeAppearanceUntilLoaded"     type="alertmodal">  Can't change appearance until clothing and shape are loaded. @@ -4059,6 +4073,18 @@ Do you want to open your Web browser to view this content?    <notification     icon="alertmodal.tga" +   name="SystemUIScaleFactorChanged" +   type="alertmodal"> +System UI size factor has changed since last run. Do you want to open UI size adjustment settings page? +    <tag>confirm</tag> +    <usetemplate +     name="okcancelbuttons" +     notext="Cancel" +     yestext="OK"/> +  </notification> + +  <notification +   icon="alertmodal.tga"     name="WebLaunchJoinNow"     type="alertmodal">  Go to your [http://secondlife.com/account/ Dashboard] to manage your account? @@ -4178,6 +4204,14 @@ Leave Group?    </notification>    <notification +   icon="notify.tga" +   name="GroupDepart" +   type="notify"> +You have left the group '[group_name]'. +    <tag>group</tag> +  </notification> + +  <notification     icon="alertmodal.tga"     name="OwnerCannotLeaveGroup"     type="alertmodal"> @@ -4189,6 +4223,17 @@ Leave Group?    </notification>    <notification +   icon="alertmodal.tga" +   name="GroupDepartError" +   type="alertmodal"> +    Unable to leave group. +    <tag>group</tag> +    <usetemplate +     name="okbutton" +     yestext="OK"/> +  </notification> + +  <notification     icon="alert.tga"     name="ConfirmKick"     type="alert"> @@ -5310,6 +5355,17 @@ There are too many prims selected.  Please select [MAX_PRIM_COUNT] or fewer prim  	</notification>  	<notification +	  icon="alertmodal.tga" +	  name="TooManyScriptsSelected" +	  type="alertmodal"> +Too many scripts in the objects selected.  Please select fewer objects and try again +  <tag>fail</tag> +		<usetemplate +		 name="okbutton" +		 yestext="OK"/> +	</notification> + +	<notification     icon="alertmodal.tga"     name="ProblemImportingEstateCovenant"     type="alertmodal"> @@ -5728,6 +5784,17 @@ Warning: The 'Pay object' click action has been set, but it will only    <notification     icon="alertmodal.tga" +   name="PaymentBlockedButtonMismatch" +   type="alertmodal"> +    Payment stopped:  the price paid does not match any of the pay buttons set for this object. +    <tag>fail</tag> +    <usetemplate +     name="okbutton" +     yestext="OK"/> +  </notification> + +  <notification +   icon="alertmodal.tga"     name="OpenObjectCannotCopy"     type="alertmodal">  There are no items in this object that you are allowed to copy. @@ -6901,6 +6968,15 @@ This area has building disabled. You can't build or rez objects here.    </notification>    <notification +   icon="notify.tga" +   name="AutopilotCanceled" +   persist="true" +   type="notify"> +    <unique/> +Autopilot canceled +  </notification> + +  <notification       icon="notify.tga"       name="PathfindingDirty"       persist="true" @@ -8804,23 +8880,6 @@ Click and drag anywhere on the world to rotate your view    </notification>    <notification -  name="PopupAttempt" -  icon="Popup_Caution" -  type="browser"> -    A pop-up was prevented from opening. -    <form name="form"> -      <ignore name="ignore" -              control="MediaEnablePopups" -              invert_control="true" -              text="Enable all pop-ups"/> -      <button default="true" -              index="0" -              name="open" -              text="Open pop-up window"/> -    </form> -  </notification> - -  <notification     icon="alertmodal.tga"     name="SOCKS_NOT_PERMITTED"     type="alertmodal"> @@ -9802,6 +9861,14 @@ Can't move object '[OBJECT_NAME]' to    <notification     icon="alertmodal.tga" +   name="NoParcelPermsNoObject" +   type="notify"> +   <tag>fail</tag> +Copy failed because you lack access to that parcel. +  </notification> + +  <notification +   icon="alertmodal.tga"     name="CantMoveObjectRegionVersion"     type="notify">     <tag>fail</tag> @@ -9837,6 +9904,17 @@ You don't have permission to modify that object    <notification     icon="alertmodal.tga" +   name="TooMuchObjectInventorySelected" +   type="alertmodal"> +    <tag>fail</tag> +    Too many objects with large inventory are selected. Please select fewer objects and try again. +    <usetemplate +     name="okbutton" +     yestext="OK"/> +  </notification> + +  <notification +   icon="alertmodal.tga"     name="CantEnablePhysObjContributesToNav"     type="notify">     <tag>fail</tag> @@ -9934,6 +10012,22 @@ Cannot save to object contents: This would modify the attachment permissions.    <notification     icon="alertmodal.tga" +   name="AttachmentHasTooMuchInventory" +   type="notify"> +   <tag>fail</tag> +Your attachments contain too much inventory to add more. +  </notification> + +  <notification +   icon="alertmodal.tga" +   name="IllegalAttachment" +   type="notify"> +   <tag>fail</tag> +The attachment has requested a nonexistent point on the avatar. It has been attached to the chest instead. +  </notification> + +  <notification +   icon="alertmodal.tga"     name="TooManyScripts"     type="notify">     <tag>fail</tag> @@ -10972,6 +11066,14 @@ Money transfers to objects are currently disabled in this region.    <notification     icon="alertmodal.tga" +   name="DroppedMoneyTransferRequest" +   type="notify"> +   <tag>fail</tag> +Unable to make payment due to system load. +  </notification> + +  <notification +   icon="alertmodal.tga"     name="CantPayNoAgent"     type="notify">     <tag>fail</tag> diff --git a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml index d85b778db2..42a7974316 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml @@ -9,6 +9,26 @@   name="Wearing"   top="0"   width="312"> +<panel.string +    name="no_attachments"> +    No attachments worn. +   </panel.string> +     <accordion +     fit_parent="true" +     follows="all" +     height="400" +     layout="topleft" +     left="0" +     single_expansion="true" +     top="0" +     name="wearables_accordion" +     background_visible="true" +     bg_alpha_color="DkGray2" +     width="309"> +     <accordion_tab +     layout="topleft" +     name="tab_wearables" +     title="Wearables">      <wearable_items_list       follows="all"       height="400" @@ -20,6 +40,27 @@       top="0"       width="309"       worn_indication_enabled="false" /> +     </accordion_tab> +     <accordion_tab +     layout="topleft" +     name="tab_temp_attachments" +     title="Temporary attachments"> +    <scroll_list +     draw_heading="false" +     left="3" +     width="309" +     height="400" +     follows="all" +     name="temp_attachments_list"> +        <scroll_list.columns +         name="icon" +         width="15" /> +        <scroll_list.columns +         name="text" +         width="210" /> +  </scroll_list> +     </accordion_tab> +     </accordion>      <panel       background_visible="true"       follows="bottom|left|right" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml index 0b605cf6f7..c20f9b2c51 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml @@ -273,6 +273,18 @@      name="update_willing_to_test"      width="400"                 top_pad="5"/> +  <check_box +    top_delta="4" +    enabled="true" +    follows="left|top" +    height="14" +    control_name="UpdaterShowReleaseNotes" +    label="Show Release Notes after update" +    left_delta="0" +    mouse_opaque="true" +    name="update_show_release_notes" +    width="400" +    top_pad="5"/>    <text       type="string"       length="1" | 
