summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOz Linden <oz@lindenlab.com>2016-05-06 09:05:51 -0400
committerOz Linden <oz@lindenlab.com>2016-05-06 09:05:51 -0400
commita07a8cbf6eca73272f2c774df7122a1f0c5e1aa9 (patch)
treef716bdae5a265aabf8f9da1413df6a19fe3ada52
parentc938e165062cbe53065dcdaa434fc1c3d9f38774 (diff)
parent94559950a2c670990db56bd74e65d26652421b8c (diff)
merge changes for 4.0.4-release
-rwxr-xr-x.hgtags1
-rwxr-xr-xdoc/contributions.txt1
-rwxr-xr-xindra/llcommon/lleventcoro.cpp22
-rwxr-xr-xindra/llcommon/lleventcoro.h5
-rwxr-xr-xindra/llcommon/lleventfilter.cpp4
-rwxr-xr-xindra/llcommon/lleventfilter.h19
-rwxr-xr-xindra/llcommon/llevents.h6
-rwxr-xr-xindra/llmath/llrect.h6
-rw-r--r--indra/llmessage/llcoproceduremanager.cpp3
-rw-r--r--indra/llmessage/llcorehttputil.cpp38
-rw-r--r--indra/llmessage/llcorehttputil.h9
-rwxr-xr-xindra/llrender/llglslshader.cpp10
-rw-r--r--indra/llrender/llgltexture.cpp3
-rwxr-xr-xindra/llui/lliconctrl.cpp11
-rwxr-xr-xindra/llui/lliconctrl.h2
-rwxr-xr-xindra/llui/llnotifications.cpp6
-rwxr-xr-xindra/llui/llnotifications.h3
-rwxr-xr-xindra/llui/llnotificationtemplate.h17
-rwxr-xr-xindra/llui/llradiogroup.cpp12
-rwxr-xr-xindra/llui/lltextbase.cpp14
-rwxr-xr-xindra/llui/lltextbase.h2
-rwxr-xr-xindra/llui/lltexteditor.cpp17
-rwxr-xr-xindra/llui/llurlaction.cpp5
-rwxr-xr-xindra/llui/llurlaction.h2
-rw-r--r--indra/llwindow/llopenglview-objc.mm124
-rwxr-xr-xindra/llwindow/llwindowcallbacks.cpp4
-rwxr-xr-xindra/llwindow/llwindowcallbacks.h1
-rwxr-xr-xindra/llwindow/llwindowmacosx-objc.h16
-rwxr-xr-xindra/llwindow/llwindowmacosx-objc.mm5
-rwxr-xr-xindra/llwindow/llwindowmacosx.cpp23
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rwxr-xr-xindra/newview/app_settings/settings.xml46
-rwxr-xr-xindra/newview/app_settings/settings_per_account.xml13
-rwxr-xr-xindra/newview/llappcorehttp.cpp5
-rwxr-xr-xindra/newview/llappearancemgr.cpp148
-rwxr-xr-xindra/newview/llappearancemgr.h7
-rwxr-xr-xindra/newview/llavataractions.cpp3
-rwxr-xr-xindra/newview/llavatariconctrl.cpp6
-rwxr-xr-xindra/newview/llexpandabletextbox.cpp22
-rwxr-xr-xindra/newview/llexpandabletextbox.h1
-rwxr-xr-xindra/newview/llfloaterland.cpp162
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp16
-rwxr-xr-xindra/newview/llfloatermodelpreview.h1
-rwxr-xr-xindra/newview/llfloaterregioninfo.cpp81
-rwxr-xr-xindra/newview/llfloaterregioninfo.h7
-rwxr-xr-xindra/newview/llfloatersidepanelcontainer.cpp6
-rwxr-xr-xindra/newview/llfloatertopobjects.cpp11
-rwxr-xr-xindra/newview/llgroupiconctrl.cpp12
-rwxr-xr-xindra/newview/llgroupiconctrl.h2
-rwxr-xr-xindra/newview/llgrouplist.cpp6
-rwxr-xr-xindra/newview/llgrouplist.h4
-rwxr-xr-xindra/newview/llinventorybridge.cpp1
-rwxr-xr-xindra/newview/llinventorymodel.cpp73
-rwxr-xr-xindra/newview/llinventorymodel.h9
-rwxr-xr-xindra/newview/llinventoryobserver.cpp6
-rwxr-xr-xindra/newview/llinventorypanel.cpp5
-rwxr-xr-xindra/newview/lllocalbitmaps.cpp10
-rwxr-xr-xindra/newview/llmanipscale.cpp2
-rwxr-xr-xindra/newview/llmarketplacefunctions.cpp9
-rwxr-xr-xindra/newview/llnavigationbar.cpp36
-rwxr-xr-xindra/newview/llnavigationbar.h6
-rwxr-xr-xindra/newview/llpanelface.cpp2
-rw-r--r--indra/newview/llpanelgroupexperiences.cpp4
-rwxr-xr-xindra/newview/llpanelpermissions.cpp39
-rwxr-xr-xindra/newview/llpersistentnotificationstorage.cpp25
-rwxr-xr-xindra/newview/llsidepanelappearance.cpp2
-rwxr-xr-xindra/newview/llsurface.cpp1
-rwxr-xr-xindra/newview/lltexturecache.cpp1
-rwxr-xr-xindra/newview/lltexturectrl.cpp2
-rwxr-xr-xindra/newview/lltexturefetch.cpp2
-rwxr-xr-xindra/newview/lltoast.cpp4
-rwxr-xr-xindra/newview/lltoastalertpanel.cpp1
-rwxr-xr-xindra/newview/lltoastgroupnotifypanel.cpp8
-rwxr-xr-xindra/newview/llviewermedia.cpp7
-rwxr-xr-xindra/newview/llviewermessage.cpp29
-rw-r--r--indra/newview/llvieweroctree.cpp12
-rwxr-xr-xindra/newview/llviewertexture.cpp17
-rwxr-xr-xindra/newview/llviewertexturelist.cpp36
-rwxr-xr-xindra/newview/llviewertexturelist.h4
-rwxr-xr-xindra/newview/llviewerwindow.cpp42
-rwxr-xr-xindra/newview/llviewerwindow.h3
-rwxr-xr-xindra/newview/llvoavatar.cpp15
-rwxr-xr-xindra/newview/llvoiceclient.cpp18
-rwxr-xr-xindra/newview/llvoicevivox.cpp195
-rwxr-xr-xindra/newview/skins/default/xui/da/notifications.xml2
-rwxr-xr-xindra/newview/skins/default/xui/de/notifications.xml2
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_about_land.xml7
-rwxr-xr-xindra/newview/skins/default/xui/en/notifications.xml67
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_group_list_item.xml2
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_group_notify.xml2
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_preferences_alerts.xml22
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_preferences_graphics1.xml1
-rwxr-xr-xindra/newview/skins/default/xui/en/role_actions.xml3
-rwxr-xr-xindra/newview/skins/default/xui/en/strings.xml2
-rwxr-xr-xindra/newview/skins/default/xui/es/notifications.xml2
-rwxr-xr-xindra/newview/skins/default/xui/fr/notifications.xml2
-rwxr-xr-xindra/newview/skins/default/xui/it/notifications.xml2
-rwxr-xr-xindra/newview/skins/default/xui/ja/notifications.xml2
-rwxr-xr-xindra/newview/skins/default/xui/pl/notifications.xml2
-rwxr-xr-xindra/newview/skins/default/xui/pt/notifications.xml2
-rwxr-xr-xindra/newview/skins/default/xui/ru/notifications.xml2
-rwxr-xr-xindra/newview/skins/default/xui/ru/strings.xml6
-rwxr-xr-xindra/newview/skins/default/xui/tr/notifications.xml2
-rwxr-xr-xindra/newview/skins/default/xui/zh/notifications.xml2
104 files changed, 1203 insertions, 509 deletions
diff --git a/.hgtags b/.hgtags
index 81fccf8afd..8705a4c5b8 100755
--- a/.hgtags
+++ b/.hgtags
@@ -514,3 +514,4 @@ ae3297cdd03ab14f19f3811acbc4acd3eb600336 4.0.0-release
759710a9acef61aaf7b69f4bc4a5a913de87ad8a 4.0.1-release
e9d350764dfbf5a46229e627547ef5c1b1eeef00 4.0.2-release
86dfba7ec4332c323025ebeacd8bf343ed0d8cfd 4.0.3-release
+0a5de9ec2cb868f367501024d8d6958c20869053 4.0.4-release
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 00f70d7ca4..3d8da14029 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -331,6 +331,7 @@ Cinder Roxley
STORM-2037
STORM-2053
STORM-2113
+ STORM-2127
Clara Young
Coaldust Numbers
VWR-1095
diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp
index 578a2b62c8..2d5f964deb 100755
--- a/indra/llcommon/lleventcoro.cpp
+++ b/indra/llcommon/lleventcoro.cpp
@@ -229,6 +229,28 @@ LLSD llcoro::postAndSuspend(const LLSD& event, const LLEventPumpOrPumpName& requ
return value;
}
+LLSD llcoro::suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& suspendPumpOrName,
+ F32 timeoutin, const LLSD &timeoutResult)
+{
+ /**
+ * The timeout pump is attached upstream of of the waiting pump and will
+ * pass the timeout event through it. We CAN NOT attach downstream since
+ * doing so will cause the suspendPump to fire any waiting events immediately
+ * and they will be lost. This becomes especially problematic with the
+ * LLEventTimeout(pump) constructor which will also attempt to fire those
+ * events using the virtual listen_impl method in the not yet fully constructed
+ * timeoutPump.
+ */
+ LLEventTimeout timeoutPump;
+ LLEventPump &suspendPump = suspendPumpOrName.getPump();
+
+ LLTempBoundListener timeoutListener(timeoutPump.listen(suspendPump.getName(),
+ boost::bind(&LLEventPump::post, &suspendPump, _1)));
+
+ timeoutPump.eventAfter(timeoutin, timeoutResult);
+ return llcoro::suspendUntilEventOn(suspendPump);
+}
+
namespace
{
diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h
index 2105faf861..87926c692d 100755
--- a/indra/llcommon/lleventcoro.h
+++ b/indra/llcommon/lleventcoro.h
@@ -147,6 +147,11 @@ LLSD suspendUntilEventOn(const LLEventPumpOrPumpName& pump)
return postAndSuspend(LLSD(), LLEventPumpOrPumpName(), pump);
}
+/// Suspend the coroutine until an event is fired on the identified pump
+/// or the timeout duration has elapsed. If the timeout duration
+/// elapses the specified LLSD is returned.
+LLSD suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& suspendPumpOrName, F32 timeoutin, const LLSD &timeoutResult);
+
} // namespace llcoro
/// return type for two-pump variant of suspendUntilEventOn()
diff --git a/indra/llcommon/lleventfilter.cpp b/indra/llcommon/lleventfilter.cpp
index d36a107254..64ab58adcd 100755
--- a/indra/llcommon/lleventfilter.cpp
+++ b/indra/llcommon/lleventfilter.cpp
@@ -39,9 +39,9 @@
#include "llsdutil.h" // llsd_matches()
LLEventFilter::LLEventFilter(LLEventPump& source, const std::string& name, bool tweak):
- LLEventStream(name, tweak)
+ LLEventStream(name, tweak),
+ mSource(source.listen(getName(), boost::bind(&LLEventFilter::post, this, _1)))
{
- source.listen(getName(), boost::bind(&LLEventFilter::post, this, _1));
}
LLEventMatching::LLEventMatching(const LLSD& pattern):
diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h
index e822a664f5..66f3c14869 100755
--- a/indra/llcommon/lleventfilter.h
+++ b/indra/llcommon/lleventfilter.h
@@ -49,6 +49,9 @@ public:
/// Post an event to all listeners
virtual bool post(const LLSD& event) = 0;
+
+private:
+ LLTempBoundListener mSource;
};
/**
@@ -181,11 +184,23 @@ protected:
private:
bool tick(const LLSD&);
- LLBoundListener mMainloop;
+ LLTempBoundListener mMainloop;
Action mAction;
};
-/// Production implementation of LLEventTimoutBase
+/**
+ * Production implementation of LLEventTimoutBase.
+ *
+ * @NOTE: Caution should be taken when using the LLEventTimeout(LLEventPump &)
+ * constructor to ensure that the upstream event pump is not an LLEventMaildrop
+ * or any other kind of store and forward pump which may have events outstanding.
+ * Using this constructor will cause the upstream event pump to fire any pending
+ * events and could result in the invocation of a virtual method before the timeout
+ * has been fully constructed. The timeout should instead be connected upstream
+ * from the event pump and attached using the listen method.
+ * See llcoro::suspendUntilEventOnWithTimeout() for an example.
+ */
+
class LL_COMMON_API LLEventTimeout: public LLEventTimeoutBase
{
public:
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h
index 6175329a9d..ba4fcd766e 100755
--- a/indra/llcommon/llevents.h
+++ b/indra/llcommon/llevents.h
@@ -616,6 +616,12 @@ public:
* a queue. Subsequent attaching listeners will receive stored events from the queue
* until a listener indicates that the event has been handled. In order to receive
* multiple events from a mail drop the listener must disconnect and reconnect.
+ *
+ * @NOTE: When using an LLEventMailDrop (or LLEventQueue) with a LLEventTimeout or
+ * LLEventFilter attaching the filter downstream using Timeout's constructor will
+ * cause the MailDrop to discharge any of it's stored events. The timeout should
+ * instead be connected upstream using its listen() method.
+ * See llcoro::suspendUntilEventOnWithTimeout() for an example.
*/
class LL_COMMON_API LLEventMailDrop : public LLEventStream
{
diff --git a/indra/llmath/llrect.h b/indra/llmath/llrect.h
index c51e0e0ae6..58f02d4d2b 100755
--- a/indra/llmath/llrect.h
+++ b/indra/llmath/llrect.h
@@ -118,8 +118,10 @@ public:
if (end_y < mBottom) clip_y = end_y - mBottom;
// clip_? and delta_? should have same sign, since starting point is in rect
// so ratios will be positive
- F32 ratio_x = ((F32)clip_x / (F32)delta_x);
- F32 ratio_y = ((F32)clip_y / (F32)delta_y);
+ F32 ratio_x = 0;
+ F32 ratio_y = 0;
+ if (delta_x != 0) ratio_x = ((F32)clip_x / (F32)delta_x);
+ if (delta_y != 0) ratio_y = ((F32)clip_y / (F32)delta_y);
if (ratio_x > ratio_y)
{
// clip along x direction
diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp
index f0fe1ab01b..d4c0788b7d 100644
--- a/indra/llmessage/llcoproceduremanager.cpp
+++ b/indra/llmessage/llcoproceduremanager.cpp
@@ -36,7 +36,8 @@
static std::map<std::string, U32> DefaultPoolSizes =
boost::assign::map_list_of
(std::string("Upload"), 1)
- (std::string("AIS"), 25);
+ (std::string("AIS"), 1);
+ // *TODO: Rider for the moment keep AIS calls serialized otherwise the COF will tend to get out of sync.
#define DEFAULT_POOL_SIZE 5
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index 9a23ede81b..7742cbc182 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -41,14 +41,41 @@
#include "message.h" // for getting the port
-using namespace LLCore;
+using namespace LLCore;
namespace LLCoreHttpUtil
{
const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
+namespace
+{
+ const std::string HTTP_LOGBODY_KEY("HTTPLogBodyOnError");
+
+ BoolSettingQuery_t mBoolSettingGet;
+ BoolSettingUpdate_t mBoolSettingPut;
+
+ inline bool getBoolSetting(const std::string &keyname)
+ {
+ if (!mBoolSettingGet || mBoolSettingGet.empty())
+ return(false);
+ return mBoolSettingGet(HTTP_LOGBODY_KEY);
+ }
+
+}
+
+void setPropertyMethods(BoolSettingQuery_t queryfn, BoolSettingUpdate_t updatefn)
+{
+ mBoolSettingGet = queryfn;
+ mBoolSettingPut = updatefn;
+
+ if (mBoolSettingPut && !mBoolSettingPut.empty())
+ {
+ mBoolSettingPut(HTTP_LOGBODY_KEY, false, "Log the entire HTTP body in the case of an HTTP error.");
+ }
+}
+
void logMessageSuccess(std::string logAuth, std::string url, std::string message)
{
@@ -293,10 +320,11 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons
bas >> std::noskipws;
bodyData.assign(std::istream_iterator<U8>(bas), std::istream_iterator<U8>());
httpStatus["error_body"] = LLSD(bodyData);
-#if 1
- // commenting out, but keeping since this can be useful for debugging
- LL_WARNS() << "Returned body=" << std::endl << httpStatus["error_body"].asString() << LL_ENDL;
-#endif
+ if (getBoolSetting(HTTP_LOGBODY_KEY))
+ {
+ // commenting out, but keeping since this can be useful for debugging
+ LL_WARNS() << "Returned body=" << std::endl << httpStatus["error_body"].asString() << LL_ENDL;
+ }
}
mReplyPump.post(result);
diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h
index d21f5ff45c..6f0b865f83 100644
--- a/indra/llmessage/llcorehttputil.h
+++ b/indra/llmessage/llcorehttputil.h
@@ -57,7 +57,14 @@
///
namespace LLCoreHttpUtil
{
- extern const F32 HTTP_REQUEST_EXPIRY_SECS;
+/// Allow access to to the property settings methods.
+typedef boost::function<bool(const std::string &)> BoolSettingQuery_t;
+typedef boost::function<void(const std::string &, bool, const std::string &)> BoolSettingUpdate_t;
+
+void setPropertyMethods(BoolSettingQuery_t queryfn, BoolSettingUpdate_t updatefn);
+
+
+extern const F32 HTTP_REQUEST_EXPIRY_SECS;
/// Attempt to convert a response object's contents to LLSD.
/// It is expected that the response body will be of non-zero
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 52b8de8365..b30bc1aed6 100755
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -345,15 +345,11 @@ void LLGLSLShader::unloadInternal()
GLhandleARB obj[1024];
GLsizei count;
- glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
+ glGetAttachedObjectsARB(mProgramObject, sizeof(obj)/sizeof(obj[0]), &count, obj);
for (GLsizei i = 0; i < count; i++)
{
-#if !LL_DARWIN
- if (glIsProgramARB(obj[i]))
-#endif
- {
- glDeleteObjectARB(obj[i]);
- }
+ glDetachObjectARB(mProgramObject, obj[i]);
+ glDeleteObjectARB(obj[i]);
}
glDeleteObjectARB(mProgramObject);
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp
index 56e263c5f1..3a6eebebba 100644
--- a/indra/llrender/llgltexture.cpp
+++ b/indra/llrender/llgltexture.cpp
@@ -112,7 +112,8 @@ void LLGLTexture::setBoostLevel(S32 level)
if(mBoostLevel != level)
{
mBoostLevel = level ;
- if(mBoostLevel != LLGLTexture::BOOST_NONE)
+ if(mBoostLevel != LLGLTexture::BOOST_NONE
+ && mBoostLevel != LLGLTexture::BOOST_ICON)
{
setNoDelete() ;
}
diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp
index f841901801..82b01e705d 100755
--- a/indra/llui/lliconctrl.cpp
+++ b/indra/llui/lliconctrl.cpp
@@ -83,7 +83,12 @@ void LLIconCtrl::draw()
// virtual
// value might be a string or a UUID
-void LLIconCtrl::setValue(const LLSD& value )
+void LLIconCtrl::setValue(const LLSD& value)
+{
+ setValue(value, mPriority);
+}
+
+void LLIconCtrl::setValue(const LLSD& value, S32 priority)
{
LLSD tvalue(value);
if (value.isString() && LLUUID::validate(value.asString()))
@@ -94,11 +99,11 @@ void LLIconCtrl::setValue(const LLSD& value )
LLUICtrl::setValue(tvalue);
if (tvalue.isUUID())
{
- mImagep = LLUI::getUIImageByID(tvalue.asUUID(), mPriority);
+ mImagep = LLUI::getUIImageByID(tvalue.asUUID(), priority);
}
else
{
- mImagep = LLUI::getUIImage(tvalue.asString(), mPriority);
+ mImagep = LLUI::getUIImage(tvalue.asString(), priority);
}
if(mImagep.notNull()
diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h
index 7971cd44d3..dd83e78fd3 100755
--- a/indra/llui/lliconctrl.h
+++ b/indra/llui/lliconctrl.h
@@ -59,6 +59,8 @@ protected:
LLIconCtrl(const Params&);
friend class LLUICtrlFactory;
+ void setValue(const LLSD& value, S32 priority);
+
public:
virtual ~LLIconCtrl();
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 77e7d375c8..0cb959a315 100755
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -417,6 +417,7 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
mExpireOption(p.expire_option),
mURLOption(p.url.option),
mURLTarget(p.url.target),
+ mForceUrlsExternal(p.force_urls_external),
mUnique(p.unique.isProvided()),
mCombineBehavior(p.unique.combine),
mPriority(p.priority),
@@ -748,6 +749,11 @@ S32 LLNotification::getURLOpenExternally() const
return(mTemplatep? mTemplatep->mURLTarget == "_external": -1);
}
+bool LLNotification::getForceUrlsExternal() const
+{
+ return (mTemplatep ? mTemplatep->mForceUrlsExternal : false);
+}
+
bool LLNotification::hasUniquenessConstraints() const
{
return (mTemplatep ? mTemplatep->mUnique : false);
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 010e6caba2..354add0b82 100755
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -553,7 +553,8 @@ public:
std::string getLabel() const;
std::string getURL() const;
S32 getURLOption() const;
- S32 getURLOpenExternally() const;
+ S32 getURLOpenExternally() const; //for url responce option
+ bool getForceUrlsExternal() const;
bool canLogToChat() const;
bool canLogToIM() const;
bool canShowToast() const;
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index c23fc53763..bed29254d8 100755
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -177,7 +177,8 @@ struct LLNotificationTemplate
Optional<bool> persist,
log_to_im,
show_toast,
- log_to_chat;
+ log_to_chat,
+ force_urls_external;
Optional<std::string> functor,
icon,
label,
@@ -201,6 +202,7 @@ struct LLNotificationTemplate
log_to_im("log_to_im", false),
show_toast("show_toast", true),
log_to_chat("log_to_chat", true),
+ force_urls_external("force_urls_external", false),
functor("functor"),
icon("icon"),
label("label"),
@@ -284,11 +286,16 @@ struct LLNotificationTemplate
// that URL. Obsolete this and eliminate the buttons for affected
// messages when we allow clickable URLs in the UI
U32 mURLOption;
-
- std::string mURLTarget;
- //This is a flag that tells if the url needs to open externally dispite
+
+ //This is a flag that tells if option url needs to open externally dispite
//what the user setting is.
-
+ std::string mURLTarget;
+
+ // All links clicked inside notification will be opened in external browser
+ // Note: Some notifications block and exit viewer, yet they provide a link
+ // to click, we should be able to open such links in external browser.
+ bool mForceUrlsExternal;
+
// does this notification persist across sessions? if so, it will be
// serialized to disk on first receipt and read on startup
bool mPersist;
diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp
index b53bb16d97..8cf72928ff 100755
--- a/indra/llui/llradiogroup.cpp
+++ b/indra/llui/llradiogroup.cpp
@@ -179,6 +179,18 @@ BOOL LLRadioGroup::setSelectedIndex(S32 index, BOOL from_event)
return FALSE;
}
+ if (index < -1)
+ {
+ // less then minimum value
+ return FALSE;
+ }
+
+ if (index < 0 && mSelectedIndex >= 0 && !mAllowDeselect)
+ {
+ // -1 is "nothing selected"
+ return FALSE;
+ }
+
if (mSelectedIndex >= 0)
{
LLRadioCtrl* old_radio_item = mRadioButtons[mSelectedIndex];
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 4309e6557e..4ccf1ef009 100755
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -164,6 +164,7 @@ LLTextBase::Params::Params()
trusted_content("trusted_content", true),
use_ellipses("use_ellipses", false),
parse_urls("parse_urls", false),
+ force_urls_external("force_urls_external", false),
parse_highlights("parse_highlights", false)
{
addSynonym(track_end, "track_bottom");
@@ -216,6 +217,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mWordWrap(p.wrap),
mUseEllipses( p.use_ellipses ),
mParseHTML(p.parse_urls),
+ mForceUrlsExternal(p.force_urls_external),
mParseHighlights(p.parse_highlights),
mBGVisible(p.bg_visible),
mScroller(NULL),
@@ -1937,7 +1939,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
registrar.add("Url.Open", boost::bind(&LLUrlAction::openURL, url));
registrar.add("Url.OpenInternal", boost::bind(&LLUrlAction::openURLInternal, url));
registrar.add("Url.OpenExternal", boost::bind(&LLUrlAction::openURLExternal, url));
- registrar.add("Url.Execute", boost::bind(&LLUrlAction::executeSLURL, url));
+ registrar.add("Url.Execute", boost::bind(&LLUrlAction::executeSLURL, url, true));
registrar.add("Url.Block", boost::bind(&LLUrlAction::blockObject, url));
registrar.add("Url.Teleport", boost::bind(&LLUrlAction::teleportToLocation, url));
registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url));
@@ -3227,7 +3229,15 @@ BOOL LLNormalTextSegment::handleMouseUp(S32 x, S32 y, MASK mask)
// Only process the click if it's actually in this segment, not to the right of the end-of-line.
if(mEditor.getSegmentAtLocalPos(x, y, false) == this)
{
- LLUrlAction::clickAction(getStyle()->getLinkHREF(), mEditor.isContentTrusted());
+ std::string url = getStyle()->getLinkHREF();
+ if (!mEditor.mForceUrlsExternal)
+ {
+ LLUrlAction::clickAction(url, mEditor.isContentTrusted());
+ }
+ else if (!LLUrlAction::executeSLURL(url, mEditor.isContentTrusted()))
+ {
+ LLUrlAction::openURLExternal(url);
+ }
return TRUE;
}
}
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index ac408bbe7a..7d87271b0e 100755
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -300,6 +300,7 @@ public:
wrap,
use_ellipses,
parse_urls,
+ force_urls_external,
parse_highlights,
clip,
clip_partial,
@@ -654,6 +655,7 @@ protected:
S32 mLineSpacingPixels; // padding between lines
bool mBorderVisible;
bool mParseHTML; // make URLs interactive
+ bool mForceUrlsExternal; // URLs from this textbox will be opened in external browser
bool mParseHighlights; // highlight user-defined keywords
bool mWordWrap;
bool mUseEllipses;
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 926326aaff..3c86b539c4 100755
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -1716,7 +1716,20 @@ void LLTextEditor::unindentLineBeforeCloseBrace()
LLWString text = getWText();
if( ' ' == text[ mCursorPos - 1 ] )
{
- removeCharOrTab();
+ S32 line = getLineNumFromDocIndex(mCursorPos, false);
+ S32 line_start = getLineStart(line);
+
+ // Jump over spaces in the current line
+ while ((' ' == text[line_start]) && (line_start < mCursorPos))
+ {
+ line_start++;
+ }
+
+ // Make sure there is nothing but ' ' before the Brace we are unindenting
+ if (line_start == mCursorPos)
+ {
+ removeCharOrTab();
+ }
}
}
}
@@ -1800,7 +1813,7 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
// Handle most keys only if the text editor is writeable.
if( !mReadOnly )
{
- if( '}' == uni_char )
+ if( mAutoIndent && '}' == uni_char )
{
unindentLineBeforeCloseBrace();
}
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index 12537d9dd1..027a3e3a64 100755
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -83,12 +83,13 @@ void LLUrlAction::openURLExternal(std::string url)
}
}
-void LLUrlAction::executeSLURL(std::string url)
+bool LLUrlAction::executeSLURL(std::string url, bool trusted_content)
{
if (sExecuteSLURLCallback)
{
- sExecuteSLURLCallback(url ,true);
+ return sExecuteSLURLCallback(url, trusted_content);
}
+ return false;
}
void LLUrlAction::clickAction(std::string url, bool trusted_content)
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index 5f3626490c..5497e28bb4 100755
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -57,7 +57,7 @@ public:
static void openURLExternal(std::string url);
/// execute the given secondlife: SLURL
- static void executeSLURL(std::string url);
+ static bool executeSLURL(std::string url, bool trusted_content = true);
/// if the Url specifies an SL location, teleport there
static void teleportToLocation(std::string url);
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 406bc9cf47..22f3339cf1 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -25,13 +25,69 @@
*/
#import "llopenglview-objc.h"
-#include "llwindowmacosx-objc.h"
+#import "llwindowmacosx-objc.h"
#import "llappdelegate-objc.h"
+#pragma mark local functions
+NativeKeyEventData extractKeyDataFromKeyEvent(NSEvent* theEvent)
+{
+ NativeKeyEventData eventData;
+ eventData.mKeyEvent = NativeKeyEventData::KEYUNKNOWN;
+ eventData.mEventType = [theEvent type];
+ eventData.mEventModifiers = [theEvent modifierFlags];
+ eventData.mEventKeyCode = [theEvent keyCode];
+ NSString *strEventChars = [theEvent characters];
+ eventData.mEventChars = (strEventChars.length) ? [strEventChars characterAtIndex:0] : 0;
+ NSString *strEventUChars = [theEvent charactersIgnoringModifiers];
+ eventData.mEventUnmodChars = (strEventUChars.length) ? [strEventUChars characterAtIndex:0] : 0;
+ eventData.mEventRepeat = [theEvent isARepeat];
+ return eventData;
+}
+
+NativeKeyEventData extractKeyDataFromModifierEvent(NSEvent* theEvent)
+{
+ NativeKeyEventData eventData;
+ eventData.mKeyEvent = NativeKeyEventData::KEYUNKNOWN;
+ eventData.mEventType = [theEvent type];
+ eventData.mEventModifiers = [theEvent modifierFlags];
+ eventData.mEventKeyCode = [theEvent keyCode];
+ return eventData;
+}
+attributedStringInfo getSegments(NSAttributedString *str)
+{
+ attributedStringInfo segments;
+ segment_lengths seg_lengths;
+ segment_standouts seg_standouts;
+ NSRange effectiveRange;
+ NSRange limitRange = NSMakeRange(0, [str length]);
+
+ while (limitRange.length > 0) {
+ NSNumber *attr = [str attribute:NSUnderlineStyleAttributeName atIndex:limitRange.location longestEffectiveRange:&effectiveRange inRange:limitRange];
+ limitRange = NSMakeRange(NSMaxRange(effectiveRange), NSMaxRange(limitRange) - NSMaxRange(effectiveRange));
+
+ if (effectiveRange.length <= 0)
+ {
+ effectiveRange.length = 1;
+ }
+
+ if ([attr integerValue] == 2)
+ {
+ seg_lengths.push_back(effectiveRange.length);
+ seg_standouts.push_back(true);
+ } else
+ {
+ seg_lengths.push_back(effectiveRange.length);
+ seg_standouts.push_back(false);
+ }
+ }
+ segments.seg_lengths = seg_lengths;
+ segments.seg_standouts = seg_standouts;
+ return segments;
+}
-//---------------------------
+#pragma mark class implementations
@implementation NSScreen (PointConversion)
@@ -63,53 +119,6 @@
@end
-void extractKeyDataFromEvent (NSEvent *theEvent, NativeKeyEventData * eventData)
-{
- eventData->mKeyEvent = NativeKeyEventData::KEYUNKNOWN;
- eventData->mEventType = [theEvent type];
- eventData->mEventModifiers = [theEvent modifierFlags];
- eventData->mEventKeyCode = [theEvent keyCode];
- NSString *strEventChars = [theEvent characters];
- eventData->mEventChars = (strEventChars.length) ? [strEventChars characterAtIndex:0] : 0;
- NSString *strEventUChars = [theEvent charactersIgnoringModifiers];
- eventData->mEventUnmodChars = (strEventUChars.length) ? [strEventUChars characterAtIndex:0] : 0;
- eventData->mEventRepeat = [theEvent isARepeat];
-
-}
-
-
-attributedStringInfo getSegments(NSAttributedString *str)
-{
- attributedStringInfo segments;
- segment_lengths seg_lengths;
- segment_standouts seg_standouts;
- NSRange effectiveRange;
- NSRange limitRange = NSMakeRange(0, [str length]);
-
- while (limitRange.length > 0) {
- NSNumber *attr = [str attribute:NSUnderlineStyleAttributeName atIndex:limitRange.location longestEffectiveRange:&effectiveRange inRange:limitRange];
- limitRange = NSMakeRange(NSMaxRange(effectiveRange), NSMaxRange(limitRange) - NSMaxRange(effectiveRange));
-
- if (effectiveRange.length <= 0)
- {
- effectiveRange.length = 1;
- }
-
- if ([attr integerValue] == 2)
- {
- seg_lengths.push_back(effectiveRange.length);
- seg_standouts.push_back(true);
- } else
- {
- seg_lengths.push_back(effectiveRange.length);
- seg_standouts.push_back(false);
- }
- }
- segments.seg_lengths = seg_lengths;
- segments.seg_standouts = seg_standouts;
- return segments;
-}
-
@implementation LLOpenGLView
// Force a high quality update after live resizing
@@ -341,6 +350,9 @@ attributedStringInfo getSegments(NSAttributedString *str)
callRightMouseUp(mMousePos, [theEvent modifierFlags]);
mSimulatedRightClick = false;
} else {
+ NSPoint mPoint = [theEvent locationInWindow];
+ mMousePos[0] = mPoint.x;
+ mMousePos[1] = mPoint.y;
callLeftMouseUp(mMousePos, [theEvent modifierFlags]);
}
}
@@ -388,7 +400,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
NSPoint mPoint = [theEvent locationInWindow];
mMousePos[0] = mPoint.x;
mMousePos[1] = mPoint.y;
- callMouseMoved(mMousePos, 0);
+ callMouseDragged(mMousePos, 0);
}
- (void) otherMouseDown:(NSEvent *)theEvent
@@ -423,18 +435,14 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (void) keyUp:(NSEvent *)theEvent
{
- NativeKeyEventData eventData;
-
- extractKeyDataFromEvent( theEvent, &eventData );
+ NativeKeyEventData eventData = extractKeyDataFromKeyEvent(theEvent);
eventData.mKeyEvent = NativeKeyEventData::KEYUP;
callKeyUp(&eventData, [theEvent keyCode], [theEvent modifierFlags]);
}
- (void) keyDown:(NSEvent *)theEvent
{
- NativeKeyEventData eventData;
-
- extractKeyDataFromEvent( theEvent, &eventData );
+ NativeKeyEventData eventData = extractKeyDataFromKeyEvent(theEvent);
eventData.mKeyEvent = NativeKeyEventData::KEYDOWN;
uint keycode = [theEvent keyCode];
@@ -472,9 +480,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (void)flagsChanged:(NSEvent *)theEvent
{
- NativeKeyEventData eventData;
-
- extractKeyDataFromEvent( theEvent, &eventData );
+ NativeKeyEventData eventData = extractKeyDataFromModifierEvent(theEvent);
mModifiers = [theEvent modifierFlags];
callModifier([theEvent modifierFlags]);
diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp
index eadff8a6b4..d2afb3f91b 100755
--- a/indra/llwindow/llwindowcallbacks.cpp
+++ b/indra/llwindow/llwindowcallbacks.cpp
@@ -112,6 +112,10 @@ void LLWindowCallbacks::handleMouseMove(LLWindow *window, const LLCoordGL pos, M
{
}
+void LLWindowCallbacks::handleMouseDragged(LLWindow *window, const LLCoordGL pos, MASK mask)
+{
+}
+
void LLWindowCallbacks::handleScrollWheel(LLWindow *window, S32 clicks)
{
}
diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h
index 7da5959700..6a7137e593 100755
--- a/indra/llwindow/llwindowcallbacks.h
+++ b/indra/llwindow/llwindowcallbacks.h
@@ -52,6 +52,7 @@ public:
virtual BOOL handleActivate(LLWindow *window, BOOL activated);
virtual BOOL handleActivateApp(LLWindow *window, BOOL activating);
virtual void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask);
+ virtual void handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask);
virtual void handleScrollWheel(LLWindow *window, S32 clicks);
virtual void handleResize(LLWindow *window, S32 width, S32 height);
virtual void handleFocus(LLWindow *window);
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index dc184b91fb..c22f3382fb 100755
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -55,13 +55,13 @@ struct NativeKeyEventData {
KEYCHAR
};
- EventType mKeyEvent;
- uint32_t mEventType;
- uint32_t mEventModifiers;
- uint32_t mEventKeyCode;
- uint32_t mEventChars;
- uint32_t mEventUnmodChars;
- bool mEventRepeat;
+ EventType mKeyEvent = KEYUNKNOWN;
+ uint32_t mEventType = 0;
+ uint32_t mEventModifiers = 0;
+ uint32_t mEventKeyCode = 0;
+ uint32_t mEventChars = 0;
+ uint32_t mEventUnmodChars = 0;
+ bool mEventRepeat = false;
};
typedef const NativeKeyEventData * NSKeyEventRef;
@@ -92,6 +92,7 @@ void setCrossCursor();
void setNotAllowedCursor();
void hideNSCursor();
void showNSCursor();
+bool isCGCursorVisible();
void hideNSCursorTillMove(bool hide);
void requestUserAttention();
long showAlert(std::string title, std::string text, int type);
@@ -133,6 +134,7 @@ void callLeftMouseUp(float *pos, unsigned int mask);
void callDoubleClick(float *pos, unsigned int mask);
void callResize(unsigned int width, unsigned int height);
void callMouseMoved(float *pos, unsigned int mask);
+void callMouseDragged(float *pos, unsigned int mask);
void callScrollMoved(float delta);
void callMouseExit();
void callWindowFocus();
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 1a21bf8430..43ce9a2255 100755
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -163,6 +163,11 @@ void showNSCursor()
[NSCursor unhide];
}
+bool isCGCursorVisible()
+{
+ return CGCursorIsVisible();
+}
+
void hideNSCursorTillMove(bool hide)
{
[NSCursor setHiddenUntilMouseMoves:hide];
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 0d41884462..754306b5d2 100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -343,6 +343,18 @@ void callMouseMoved(float *pos, MASK mask)
//gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, 0);
}
+void callMouseDragged(float *pos, MASK mask)
+{
+ LLCoordGL outCoords;
+ outCoords.mX = ll_round(pos[0]);
+ outCoords.mY = ll_round(pos[1]);
+ float deltas[2];
+ gWindowImplementation->getMouseDeltas(deltas);
+ outCoords.mX += deltas[0];
+ outCoords.mY += deltas[1];
+ gWindowImplementation->getCallbacks()->handleMouseDragged(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
+}
+
void callScrollMoved(float delta)
{
gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, delta);
@@ -1445,8 +1457,15 @@ void LLWindowMacOSX::updateCursor()
mNextCursor = UI_CURSOR_WORKING;
}
- if(mCurrentCursor == mNextCursor)
- return;
+ if(mCurrentCursor == mNextCursor)
+ {
+ if(mCursorHidden && mHideCursorPermanent && isCGCursorVisible())
+ {
+ hideNSCursor();
+ adjustCursorDecouple();
+ }
+ return;
+ }
// RN: replace multi-drag cursors with single versions
if (mNextCursor == UI_CURSOR_ARROWDRAGMULTI)
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index c5106e6d13..7636e75650 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-4.0.4
+4.0.5
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index c4a8fe3532..15f6fe5649 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4856,6 +4856,17 @@
<key>Value</key>
<integer>7</integer>
</map>
+ <key>InventoryTrashMaxCapacity</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum capacity of the Trash folder. User will ve offered to clean it up when exceeded.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>5000</integer>
+ </map>
<key>MarketplaceListingsSortOrder</key>
<map>
<key>Comment</key>
@@ -7004,6 +7015,28 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>NotifyMoneySpend</key>
+ <map>
+ <key>Comment</key>
+ <string>Pop up notifications when spending L$</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>NotifyMoneyReceived</key>
+ <map>
+ <key>Comment</key>
+ <string>Pop up notifications when receiving L$</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>NotifyTipDuration</key>
<map>
<key>Comment</key>
@@ -8171,6 +8204,17 @@
<key>Value</key>
<integer>256</integer>
</map>
+ <key>RegionCheckTextureHeights</key>
+ <map>
+ <key>Comment</key>
+ <string>Don't allow user to set low heights greater than high</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>RememberPassword</key>
<map>
<key>Comment</key>
@@ -14446,7 +14490,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <integer>25</integer>
+ <integer>1</integer>
</map>
<key>PoolSizeUpload</key>
<map>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index c62b45ed81..fd6b1b5b3f 100755
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -98,7 +98,18 @@
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
- </map>
+ </map>
+ <key>NavigationBarRatio</key>
+ <map>
+ <key>Comment</key>
+ <string>The ratio between the width of Navigation layout panel and the width of whole Navigation layout stack</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.6</real>
+ </map>
<key>InstantMessageLogPath</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
index 7dee309a62..49291ea564 100755
--- a/indra/newview/llappcorehttp.cpp
+++ b/indra/newview/llappcorehttp.cpp
@@ -36,6 +36,8 @@
#include "llsecapi.h"
#include <curl/curl.h>
+#include "llcorehttputil.h"
+
// Here is where we begin to get our connection usage under control.
// This establishes llcorehttp policy classes that, among other
// things, limit the maximum number of connections to outside
@@ -138,6 +140,9 @@ LLAppCoreHttp::~LLAppCoreHttp()
void LLAppCoreHttp::init()
{
+ LLCoreHttpUtil::setPropertyMethods(
+ boost::bind(&LLControlGroup::getBOOL, boost::ref(gSavedSettings), _1),
+ boost::bind(&LLControlGroup::declareBOOL, boost::ref(gSavedSettings), _1, _2, _3, LLControlVariable::PERSIST_NONDFT));
LLCore::LLHttp::initialize();
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 99dcb80a4a..cc676550ab 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -65,7 +65,12 @@
#pragma warning (disable:4702)
#endif
-#if 1
+namespace
+{
+ const S32 BAKE_RETRY_MAX_COUNT = 5;
+ const F32 BAKE_RETRY_TIMEOUT = 2.0F;
+}
+
// *TODO$: LLInventoryCallback should be deprecated to conform to the new boost::bind/coroutine model.
// temp code in transition
void doAppearanceCb(LLPointer<LLInventoryCallback> cb, LLUUID id)
@@ -73,8 +78,6 @@ void doAppearanceCb(LLPointer<LLInventoryCallback> cb, LLUUID id)
if (cb.notNull())
cb->fire(id);
}
-#endif
-
std::string self_av_string()
{
@@ -2073,7 +2076,7 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
}
const LLUUID& base_id = append ? getBaseOutfitUUID() : category;
LLViewerInventoryCategory *base_cat = gInventory.getCategory(base_id);
- if (base_cat)
+ if (base_cat && (base_cat->getPreferredType() == LLFolderType::FT_OUTFIT))
{
LLSD base_contents;
base_contents["name"] = base_cat->getName();
@@ -3354,12 +3357,36 @@ LLSD LLAppearanceMgr::dumpCOF() const
void LLAppearanceMgr::requestServerAppearanceUpdate()
{
- LLCoprocedureManager::CoProcedure_t proc = boost::bind(&LLAppearanceMgr::serverAppearanceUpdateCoro, this, _1);
- LLCoprocedureManager::instance().enqueueCoprocedure("AIS", "LLAppearanceMgr::serverAppearanceUpdateCoro", proc);
+ if (!mOutstandingAppearanceBakeRequest)
+ {
+#ifdef APPEARANCEBAKE_AS_IN_AIS_QUEUE
+ mRerequestAppearanceBake = false;
+ LLCoprocedureManager::CoProcedure_t proc = boost::bind(&LLAppearanceMgr::serverAppearanceUpdateCoro, this, _1);
+ LLCoprocedureManager::instance().enqueueCoprocedure("AIS", "LLAppearanceMgr::serverAppearanceUpdateCoro", proc);
+#else
+ LLCoros::instance().launch("serverAppearanceUpdateCoro",
+ boost::bind(&LLAppearanceMgr::serverAppearanceUpdateCoro, this));
+
+#endif
+ }
+ else
+ {
+ mRerequestAppearanceBake = true;
+ }
}
+#ifdef APPEARANCEBAKE_AS_IN_AIS_QUEUE
void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter)
+#else
+void LLAppearanceMgr::serverAppearanceUpdateCoro()
+#endif
{
+#ifndef APPEARANCEBAKE_AS_IN_AIS_QUEUE
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(
+ new LLCoreHttpUtil::HttpCoroutineAdapter("serverAppearanceUpdateCoro", LLCore::HttpRequest::DEFAULT_POLICY_ID));
+#endif
+
+ mRerequestAppearanceBake = false;
if (!gAgent.getRegion())
{
LL_WARNS("Avatar") << "Region not set, cannot request server appearance update" << LL_ENDL;
@@ -3386,57 +3413,57 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
return;
}
-#if 0
- static int reqcount = 0;
- int r_count = ++reqcount;
- LL_WARNS("Avatar") << "START: Server Bake request #" << r_count << "!" << LL_ENDL;
-#endif
-
- // If we have already received an update for this or higher cof version,
- // put a warning in the log but request anyway.
- S32 cofVersion = getCOFVersion();
- S32 lastRcv = gAgentAvatarp->mLastUpdateReceivedCOFVersion;
- S32 lastReq = gAgentAvatarp->mLastUpdateRequestCOFVersion;
-
- LL_INFOS("Avatar") << "Requesting COF version " << cofVersion <<
- " (Last Received:" << lastRcv << ")" <<
- " (Last Requested:" << lastReq << ")" << LL_ENDL;
-
- if ((cofVersion != LLViewerInventoryCategory::VERSION_UNKNOWN))
+ llcoro::suspend();
+ S32 retryCount(0);
+ bool bRetry;
+ do
{
- if (cofVersion < lastRcv)
+ BoolSetter outstanding(mOutstandingAppearanceBakeRequest);
+
+ // If we have already received an update for this or higher cof version,
+ // put a warning in the log and cancel the request.
+ S32 cofVersion = getCOFVersion();
+ S32 lastRcv = gAgentAvatarp->mLastUpdateReceivedCOFVersion;
+ S32 lastReq = gAgentAvatarp->mLastUpdateRequestCOFVersion;
+
+ LL_INFOS("Avatar") << "Requesting COF version " << cofVersion <<
+ " (Last Received:" << lastRcv << ")" <<
+ " (Last Requested:" << lastReq << ")" << LL_ENDL;
+
+ if (cofVersion == LLViewerInventoryCategory::VERSION_UNKNOWN)
{
- LL_WARNS("Avatar") << "Have already received update for cof version " << lastRcv
- << " but requesting for " << cofVersion << LL_ENDL;
+ LL_WARNS("AVatar") << "COF version is unknown... not requesting until COF version is known." << LL_ENDL;
+ return;
}
- if (lastReq > cofVersion)
+ else
{
- LL_WARNS("Avatar") << "Request already in flight for cof version " << lastReq
- << " but requesting for " << cofVersion << LL_ENDL;
+ if (cofVersion < lastRcv)
+ {
+ LL_WARNS("Avatar") << "Have already received update for cof version " << lastRcv
+ << " but requesting for " << cofVersion << LL_ENDL;
+ return;
+ }
+ if (lastReq > cofVersion)
+ {
+ LL_WARNS("Avatar") << "Request already in flight for cof version " << lastReq
+ << " but requesting for " << cofVersion << LL_ENDL;
+ return;
+ }
}
- }
-
- // Actually send the request.
- LL_DEBUGS("Avatar") << "Will send request for cof_version " << cofVersion << LL_ENDL;
-// LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter(
-// "UpdateAvatarAppearance", gAgent.getAgentPolicy()));
+ // Actually send the request.
+ LL_DEBUGS("Avatar") << "Will send request for cof_version " << cofVersion << LL_ENDL;
- bool bRetry;
- do
- {
bRetry = false;
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest());
- S32 reqCofVersion = getCOFVersion(); // Treat COF version (gets set by AISAPI as authoritative,
- // not what the bake request tells us to use).
if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
{
- reqCofVersion += 999;
+ cofVersion += 999;
LL_WARNS("Avatar") << "Forcing version failure on COF Baking" << LL_ENDL;
}
- LL_INFOS() << "Requesting bake for COF version " << reqCofVersion << LL_ENDL;
+ LL_INFOS() << "Requesting bake for COF version " << cofVersion << LL_ENDL;
LLSD postData;
if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate"))
@@ -3445,10 +3472,10 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
}
else
{
- postData["cof_version"] = reqCofVersion;
+ postData["cof_version"] = cofVersion;
}
- gAgentAvatarp->mLastUpdateRequestCOFVersion = reqCofVersion;
+ gAgentAvatarp->mLastUpdateRequestCOFVersion = cofVersion;
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData);
@@ -3466,14 +3493,30 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
// on multiple machines.
if (result.has("expected"))
{
+
S32 expectedCofVersion = result["expected"].asInteger();
+ LL_WARNS("Avatar") << "Server expected " << expectedCofVersion << " as COF version" << LL_ENDL;
+
bRetry = true;
// Wait for a 1/2 second before trying again. Just to keep from asking too quickly.
- llcoro::suspendUntilTimeout(0.5);
+ if (++retryCount > BAKE_RETRY_MAX_COUNT)
+ {
+ LL_WARNS("Avatar") << "Bake retry count exceeded!" << LL_ENDL;
+ break;
+ }
+ F32 timeout = pow(BAKE_RETRY_TIMEOUT, static_cast<float>(retryCount)) - 1.0;
- LL_WARNS("Avatar") << "Server expected " << expectedCofVersion << " as COF version" << LL_ENDL;
+ LL_WARNS("Avatar") << "Bake retry #" << retryCount << " in " << timeout << " seconds." << LL_ENDL;
+
+ llcoro::suspendUntilTimeout(timeout);
+ bRetry = true;
continue;
}
+ else
+ {
+ LL_WARNS("Avatar") << "No retry attempted." << LL_ENDL;
+ break;
+ }
}
LL_DEBUGS("Avatar") << "succeeded" << LL_ENDL;
@@ -3484,10 +3527,11 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
} while (bRetry);
-#if 0
- LL_WARNS("Avatar") << "END: Server Bake request #" << r_count << "!" << LL_ENDL;
-#endif
-
+ if (mRerequestAppearanceBake)
+ { // A bake request came in while this one was still outstanding.
+ // Requeue ourself for a later request.
+ requestServerAppearanceUpdate();
+ }
}
/*static*/
@@ -3855,7 +3899,9 @@ LLAppearanceMgr::LLAppearanceMgr():
mOutfitLocked(false),
mInFlightCounter(0),
mInFlightTimer(),
- mIsInUpdateAppearanceFromCOF(false)
+ mIsInUpdateAppearanceFromCOF(false),
+ mOutstandingAppearanceBakeRequest(false),
+ mRerequestAppearanceBake(false)
{
LLOutfitObserver& outfit_observer = LLOutfitObserver::instance();
// unlock outfit on save operation completed
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index b97f9018c0..bf181cb4ad 100755
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -228,7 +228,12 @@ public:
private:
+#ifdef APPEARANCEBAKE_AS_IN_AIS_QUEUE
void serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter);
+#else
+ void serverAppearanceUpdateCoro();
+#endif
+
static void debugAppearanceUpdateCOF(const LLSD& content);
std::string mAppearanceServiceURL;
@@ -255,6 +260,8 @@ private:
bool mAttachmentInvLinkEnabled;
bool mOutfitIsDirty;
bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls.
+ bool mOutstandingAppearanceBakeRequest; // A bake request is outstanding. Do not overlap.
+ bool mRerequestAppearanceBake;
/**
* Lock for blocking operations on outfit until server reply or timeout exceed
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 8dc8a2ff20..00bc8ebe87 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -564,7 +564,8 @@ namespace action_give_inventory
static LLInventoryPanel* get_active_inventory_panel()
{
LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
- if (!active_panel)
+ LLFloater* floater_appearance = LLFloaterReg::findInstance("appearance");
+ if (!active_panel || (floater_appearance && floater_appearance->hasFocus()))
{
active_panel = get_outfit_editor_inventory_panel();
}
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index 932326acae..c131dc641b 100755
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -196,7 +196,7 @@ LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p)
}
else
{
- LLIconCtrl::setValue(mDefaultIconName);
+ LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
}
}
@@ -243,7 +243,7 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)
// *TODO: Consider getting avatar icon/badge directly from
// People API, rather than sending AvatarPropertyRequest
// messages. People API already hits the user table.
- LLIconCtrl::setValue(mDefaultIconName);
+ LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
app->addObserver(mAvatarId, this);
app->sendAvatarPropertiesRequest(mAvatarId);
}
@@ -284,7 +284,7 @@ bool LLAvatarIconCtrl::updateFromCache()
}
else
{
- LLIconCtrl::setValue(mDefaultIconName);
+ LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
return false;
}
diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp
index 4dbed114bb..f0331f20d8 100755
--- a/indra/newview/llexpandabletextbox.cpp
+++ b/indra/newview/llexpandabletextbox.cpp
@@ -122,8 +122,6 @@ LLExpandableTextBox::LLTextBoxEx::LLTextBoxEx(const Params& p)
void LLExpandableTextBox::LLTextBoxEx::reshape(S32 width, S32 height, BOOL called_from_parent)
{
LLTextEditor::reshape(width, height, called_from_parent);
-
- hideOrShowExpandTextAsNeeded();
}
void LLExpandableTextBox::LLTextBoxEx::setText(const LLStringExplicit& text,const LLStyle::Params& input_params)
@@ -298,6 +296,12 @@ void LLExpandableTextBox::updateTextBoxRect()
mTextBox->reshape(rc.getWidth(), rc.getHeight());
mTextBox->setRect(rc);
+ // *HACK
+ // hideExpandText brakes text styles (replaces hyper-links with plain text), see ticket EXT-3290
+ // Also text segments are not removed properly. Same issue at expandTextBox().
+ // So set text again to make text box re-apply styles and clear segments.
+ // *TODO Find a solution that does not involve text segment.
+ mTextBox->setText(mText);
}
S32 LLExpandableTextBox::recalculateTextDelta(S32 text_delta)
@@ -403,8 +407,6 @@ void LLExpandableTextBox::collapseTextBox()
setRect(mCollapsedRect);
updateTextBoxRect();
-
- gViewerWindow->removePopup(this);
}
void LLExpandableTextBox::onFocusLost()
@@ -423,13 +425,19 @@ void LLExpandableTextBox::onTopLost()
void LLExpandableTextBox::updateTextShape()
{
- // I guess this should be done on every reshape(),
- // but adding this code to reshape() currently triggers bug VWR-26455,
- // which makes the text virtually unreadable.
llassert(!mExpanded);
updateTextBoxRect();
}
+void LLExpandableTextBox::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ mExpanded = false;
+ LLUICtrl::reshape(width, height, called_from_parent);
+ updateTextBoxRect();
+
+ gViewerWindow->removePopup(this);
+}
+
void LLExpandableTextBox::setValue(const LLSD& value)
{
collapseTextBox();
diff --git a/indra/newview/llexpandabletextbox.h b/indra/newview/llexpandabletextbox.h
index 90d46ab262..aaf393277f 100755
--- a/indra/newview/llexpandabletextbox.h
+++ b/indra/newview/llexpandabletextbox.h
@@ -147,6 +147,7 @@ public:
* *HACK: Update the inner textbox shape.
*/
void updateTextShape();
+ virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
/**
* Draws text box, collapses text box if its expanded and its parent's position changed
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index f9fd5069af..7f952d4dd4 100755
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -39,6 +39,7 @@
#include "llagent.h"
#include "llagentaccess.h"
+#include "llappviewer.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
@@ -475,13 +476,36 @@ BOOL LLPanelLandGeneral::postBuild()
mBtnBuyLand = getChild<LLButton>("Buy Land...");
mBtnBuyLand->setClickedCallback(onClickBuyLand, (void*)&BUY_PERSONAL_LAND);
+
+ mBtnBuyGroupLand = getChild<LLButton>("Buy For Group...");
+ mBtnBuyGroupLand->setClickedCallback(onClickBuyLand, (void*)&BUY_GROUP_LAND);
+
+
+ mBtnBuyPass = getChild<LLButton>("Buy Pass...");
+ mBtnBuyPass->setClickedCallback(onClickBuyPass, this);
+
+ mBtnReleaseLand = getChild<LLButton>("Abandon Land...");
+ mBtnReleaseLand->setClickedCallback(onClickRelease, NULL);
+
+ mBtnReclaimLand = getChild<LLButton>("Reclaim Land...");
+ mBtnReclaimLand->setClickedCallback(onClickReclaim, NULL);
+
+ mBtnStartAuction = getChild<LLButton>("Linden Sale...");
+ mBtnStartAuction->setClickedCallback(onClickStartAuction, this);
+
+ mBtnScriptLimits = getChild<LLButton>("Scripts...");
+
+ if(gDisconnected)
+ {
+ return TRUE;
+ }
+
// note: on region change this will not be re checked, should not matter on Agni as
// 99% of the time all regions will return the same caps. In case of an erroneous setting
// to enabled the floater will just throw an error when trying to get it's cap
std::string url = gAgent.getRegion()->getCapability("LandResources");
if (!url.empty())
{
- mBtnScriptLimits = getChild<LLButton>("Scripts...");
if(mBtnScriptLimits)
{
mBtnScriptLimits->setClickedCallback(onClickScriptLimits, this);
@@ -489,28 +513,11 @@ BOOL LLPanelLandGeneral::postBuild()
}
else
{
- mBtnScriptLimits = getChild<LLButton>("Scripts...");
if(mBtnScriptLimits)
{
mBtnScriptLimits->setVisible(false);
}
}
-
- mBtnBuyGroupLand = getChild<LLButton>("Buy For Group...");
- mBtnBuyGroupLand->setClickedCallback(onClickBuyLand, (void*)&BUY_GROUP_LAND);
-
-
- mBtnBuyPass = getChild<LLButton>("Buy Pass...");
- mBtnBuyPass->setClickedCallback(onClickBuyPass, this);
-
- mBtnReleaseLand = getChild<LLButton>("Abandon Land...");
- mBtnReleaseLand->setClickedCallback(onClickRelease, NULL);
-
- mBtnReclaimLand = getChild<LLButton>("Reclaim Land...");
- mBtnReclaimLand->setClickedCallback(onClickReclaim, NULL);
-
- mBtnStartAuction = getChild<LLButton>("Linden Sale...");
- mBtnStartAuction->setClickedCallback(onClickStartAuction, this);
return TRUE;
}
@@ -524,9 +531,58 @@ LLPanelLandGeneral::~LLPanelLandGeneral()
// public
void LLPanelLandGeneral::refresh()
{
- mBtnStartAuction->setVisible(gAgent.isGodlike());
+ mEditName->setEnabled(FALSE);
+ mEditName->setText(LLStringUtil::null);
- LLParcel *parcel = mParcel->getParcel();
+ mEditDesc->setEnabled(FALSE);
+ mEditDesc->setText(getString("no_selection_text"));
+
+ mTextSalePending->setText(LLStringUtil::null);
+ mTextSalePending->setEnabled(FALSE);
+
+ mBtnDeedToGroup->setEnabled(FALSE);
+ mBtnSetGroup->setEnabled(FALSE);
+ mBtnStartAuction->setEnabled(FALSE);
+
+ mCheckDeedToGroup ->set(FALSE);
+ mCheckDeedToGroup ->setEnabled(FALSE);
+ mCheckContributeWithDeed->set(FALSE);
+ mCheckContributeWithDeed->setEnabled(FALSE);
+
+ mTextOwner->setText(LLStringUtil::null);
+ mContentRating->setText(LLStringUtil::null);
+ mLandType->setText(LLStringUtil::null);
+ mBtnProfile->setLabel(getString("profile_text"));
+ mBtnProfile->setEnabled(FALSE);
+
+ mTextClaimDate->setText(LLStringUtil::null);
+ mTextGroup->setText(LLStringUtil::null);
+ mTextPrice->setText(LLStringUtil::null);
+
+ mSaleInfoForSale1->setVisible(FALSE);
+ mSaleInfoForSale2->setVisible(FALSE);
+ mSaleInfoForSaleObjects->setVisible(FALSE);
+ mSaleInfoForSaleNoObjects->setVisible(FALSE);
+ mSaleInfoNotForSale->setVisible(FALSE);
+ mBtnSellLand->setVisible(FALSE);
+ mBtnStopSellLand->setVisible(FALSE);
+
+ mTextPriceLabel->setText(LLStringUtil::null);
+ mTextDwell->setText(LLStringUtil::null);
+
+ mBtnBuyLand->setEnabled(FALSE);
+ mBtnScriptLimits->setEnabled(FALSE);
+ mBtnBuyGroupLand->setEnabled(FALSE);
+ mBtnReleaseLand->setEnabled(FALSE);
+ mBtnReclaimLand->setEnabled(FALSE);
+ mBtnBuyPass->setEnabled(FALSE);
+
+ if(gDisconnected)
+ {
+ return;
+ }
+
+ mBtnStartAuction->setVisible(gAgent.isGodlike());
bool region_owner = false;
LLViewerRegion* regionp = LLViewerParcelMgr::getInstance()->getSelectionRegion();
if(regionp && (regionp->getOwner() == gAgent.getID()))
@@ -540,56 +596,8 @@ void LLPanelLandGeneral::refresh()
mBtnReleaseLand->setVisible(TRUE);
mBtnReclaimLand->setVisible(FALSE);
}
- if (!parcel)
- {
- // nothing selected, disable panel
- mEditName->setEnabled(FALSE);
- mEditName->setText(LLStringUtil::null);
-
- mEditDesc->setEnabled(FALSE);
- mEditDesc->setText(getString("no_selection_text"));
-
- mTextSalePending->setText(LLStringUtil::null);
- mTextSalePending->setEnabled(FALSE);
-
- mBtnDeedToGroup->setEnabled(FALSE);
- mBtnSetGroup->setEnabled(FALSE);
- mBtnStartAuction->setEnabled(FALSE);
-
- mCheckDeedToGroup ->set(FALSE);
- mCheckDeedToGroup ->setEnabled(FALSE);
- mCheckContributeWithDeed->set(FALSE);
- mCheckContributeWithDeed->setEnabled(FALSE);
-
- mTextOwner->setText(LLStringUtil::null);
- mContentRating->setText(LLStringUtil::null);
- mLandType->setText(LLStringUtil::null);
- mBtnProfile->setLabel(getString("profile_text"));
- mBtnProfile->setEnabled(FALSE);
-
- mTextClaimDate->setText(LLStringUtil::null);
- mTextGroup->setText(LLStringUtil::null);
- mTextPrice->setText(LLStringUtil::null);
-
- mSaleInfoForSale1->setVisible(FALSE);
- mSaleInfoForSale2->setVisible(FALSE);
- mSaleInfoForSaleObjects->setVisible(FALSE);
- mSaleInfoForSaleNoObjects->setVisible(FALSE);
- mSaleInfoNotForSale->setVisible(FALSE);
- mBtnSellLand->setVisible(FALSE);
- mBtnStopSellLand->setVisible(FALSE);
-
- mTextPriceLabel->setText(LLStringUtil::null);
- mTextDwell->setText(LLStringUtil::null);
-
- mBtnBuyLand->setEnabled(FALSE);
- mBtnScriptLimits->setEnabled(FALSE);
- mBtnBuyGroupLand->setEnabled(FALSE);
- mBtnReleaseLand->setEnabled(FALSE);
- mBtnReclaimLand->setEnabled(FALSE);
- mBtnBuyPass->setEnabled(FALSE);
- }
- else
+ LLParcel *parcel = mParcel->getParcel();
+ if (parcel)
{
// something selected, hooray!
BOOL is_leased = (LLParcel::OS_LEASED == parcel->getOwnershipStatus());
@@ -1246,7 +1254,7 @@ void LLPanelLandObjects::refresh()
mOwnerList->deleteAllItems();
mOwnerList->setEnabled(FALSE);
- if (!parcel)
+ if (!parcel || gDisconnected)
{
mSWTotalObjects->setTextArg("[COUNT]", llformat("%d", 0));
mSWTotalObjects->setTextArg("[TOTAL]", llformat("%d", 0));
@@ -1974,7 +1982,7 @@ void LLPanelLandOptions::refresh()
refreshSearch();
LLParcel *parcel = mParcel->getParcel();
- if (!parcel)
+ if (!parcel || gDisconnected)
{
mCheckEditObjects ->set(FALSE);
mCheckEditObjects ->setEnabled(FALSE);
@@ -2154,7 +2162,7 @@ void LLPanelLandOptions::draw()
void LLPanelLandOptions::refreshSearch()
{
LLParcel *parcel = mParcel->getParcel();
- if (!parcel)
+ if (!parcel || gDisconnected)
{
mCheckShowDirectory->set(FALSE);
mCheckShowDirectory->setEnabled(FALSE);
@@ -2419,7 +2427,7 @@ void LLPanelLandAccess::refresh()
LLParcel *parcel = mParcel->getParcel();
// Display options
- if (parcel)
+ if (parcel && !gDisconnected)
{
BOOL use_access_list = parcel->getParcelFlag(PF_USE_ACCESS_LIST);
BOOL use_group = parcel->getParcelFlag(PF_USE_ACCESS_GROUP);
@@ -2599,7 +2607,7 @@ void LLPanelLandAccess::refresh_ui()
getChildView("remove_banned")->setEnabled(FALSE);
LLParcel *parcel = mParcel->getParcel();
- if (parcel)
+ if (parcel && !gDisconnected)
{
BOOL can_manage_allowed = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_ALLOWED);
BOOL can_manage_banned = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_BANNED);
@@ -2945,7 +2953,7 @@ BOOL LLPanelLandCovenant::postBuild()
void LLPanelLandCovenant::refresh()
{
LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
- if(!region) return;
+ if(!region || gDisconnected) return;
LLTextBox* region_name = getChild<LLTextBox>("region_name_text");
if (region_name)
@@ -3170,7 +3178,7 @@ void LLPanelLandExperiences::refreshPanel(LLPanelExperienceListEditor* panel, U3
{
return;
}
- if (parcel == NULL)
+ if (!parcel || gDisconnected)
{
// disable the panel
panel->setEnabled(FALSE);
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index a6a9838a3c..576d6e890f 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -338,25 +338,25 @@ BOOL LLFloaterModelPreview::postBuild()
LLTextBox* text = getChild<LLTextBox>(lod_label_name[i]);
if (text)
{
- text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
+ text->setMouseDownCallback(boost::bind(&LLFloaterModelPreview::setPreviewLOD, this, i));
}
text = getChild<LLTextBox>(lod_triangles_name[i]);
if (text)
{
- text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
+ text->setMouseDownCallback(boost::bind(&LLFloaterModelPreview::setPreviewLOD, this, i));
}
text = getChild<LLTextBox>(lod_vertices_name[i]);
if (text)
{
- text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
+ text->setMouseDownCallback(boost::bind(&LLFloaterModelPreview::setPreviewLOD, this, i));
}
text = getChild<LLTextBox>(lod_status_name[i]);
if (text)
{
- text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
+ text->setMouseDownCallback(boost::bind(&LLFloaterModelPreview::setPreviewLOD, this, i));
}
}
std::string current_grid = LLGridManager::getInstance()->getGridId();
@@ -1363,6 +1363,14 @@ void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost,
childSetTextArg("import_dimensions", "[Z]", llformat("%.3f", z));
}
+void LLFloaterModelPreview::setPreviewLOD(S32 lod)
+{
+ if (mModelPreview)
+ {
+ mModelPreview->setPreviewLOD(lod);
+ }
+}
+
void LLModelPreview::rebuildUploadData()
{
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index b2bb15ef05..a73ca50260 100755
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -95,6 +95,7 @@ public:
static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost);
+ void setPreviewLOD(S32 lod);
void onBrowseLOD(S32 lod);
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index aed3294189..4eacd728c3 100755
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -233,6 +233,11 @@ BOOL LLFloaterRegionInfo::postBuild()
panel->buildFromFile("panel_region_debug.xml");
mTab->addTabPanel(panel);
+ if(gDisconnected)
+ {
+ return TRUE;
+ }
+
if(!gAgent.getRegion()->getCapability("RegionExperiences").empty())
{
panel = new LLPanelRegionExperiences;
@@ -256,6 +261,11 @@ LLFloaterRegionInfo::~LLFloaterRegionInfo()
void LLFloaterRegionInfo::onOpen(const LLSD& key)
{
+ if(gDisconnected)
+ {
+ disableTabCtrls();
+ return;
+ }
refreshFromRegion(gAgent.getRegion());
requestRegionInfo();
requestMeshRezInfo();
@@ -479,7 +489,16 @@ LLPanelRegionExperiences* LLFloaterRegionInfo::getPanelExperiences()
return (LLPanelRegionExperiences*)tab->getChild<LLPanel>("Experiences");
}
+void LLFloaterRegionInfo::disableTabCtrls()
+{
+ LLTabContainer* tab = getChild<LLTabContainer>("region_panels");
+ tab->getChild<LLPanel>("General")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Debug")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Terrain")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("panel_env_info")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Estate")->setCtrlsEnabled(FALSE);
+}
void LLFloaterRegionInfo::onTabSelected(const LLSD& param)
{
@@ -1160,6 +1179,22 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
return TRUE;
}
+BOOL LLPanelRegionTerrainInfo::validateTextureHeights()
+{
+ for (S32 i = 0; i < CORNER_COUNT; ++i)
+ {
+ std::string low = llformat("height_start_spin_%d", i);
+ std::string high = llformat("height_range_spin_%d", i);
+
+ if (getChild<LLUICtrl>(low)->getValue().asReal() > getChild<LLUICtrl>(high)->getValue().asReal())
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
/////////////////////////////////////////////////////////////////////////////
// LLPanelRegionTerrainInfo
/////////////////////////////////////////////////////////////////////////////
@@ -1192,6 +1227,9 @@ BOOL LLPanelRegionTerrainInfo::postBuild()
childSetAction("upload_raw_btn", onClickUploadRaw, this);
childSetAction("bake_terrain_btn", onClickBakeTerrain, this);
+ mAskedTextureHeights = false;
+ mConfirmedTextureHeights = false;
+
return LLPanelRegionInfo::postBuild();
}
@@ -1274,6 +1312,21 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate()
return FALSE;
}
+ // Check if terrain Elevation Ranges are correct
+ if (gSavedSettings.getBOOL("RegionCheckTextureHeights") && !validateTextureHeights())
+ {
+ if (!mAskedTextureHeights)
+ {
+ LLNotificationsUtil::add("ConfirmTextureHeights", LLSD(), LLSD(), boost::bind(&LLPanelRegionTerrainInfo::callbackTextureHeights, this, _1, _2));
+ mAskedTextureHeights = true;
+ return FALSE;
+ }
+ else if (!mConfirmedTextureHeights)
+ {
+ return FALSE;
+ }
+ }
+
LLTextureCtrl* texture_ctrl;
std::string id_str;
LLMessageSystem* msg = gMessageSystem;
@@ -1314,6 +1367,29 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate()
return TRUE;
}
+bool LLPanelRegionTerrainInfo::callbackTextureHeights(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0) // ok
+ {
+ mConfirmedTextureHeights = true;
+ }
+ else if (option == 1) // cancel
+ {
+ mConfirmedTextureHeights = false;
+ }
+ else if (option == 2) // don't ask
+ {
+ gSavedSettings.setBOOL("RegionCheckTextureHeights", FALSE);
+ mConfirmedTextureHeights = true;
+ }
+
+ onBtnSet();
+
+ mAskedTextureHeights = false;
+ return false;
+}
+
// static
void LLPanelRegionTerrainInfo::onClickDownloadRaw(void* data)
{
@@ -3018,6 +3094,11 @@ bool LLPanelEnvironmentInfo::refreshFromRegion(LLViewerRegion* region)
void LLPanelEnvironmentInfo::refresh()
{
+ if(gDisconnected)
+ {
+ return;
+ }
+
populateWaterPresetsList();
populateSkyPresetsList();
populateDayCyclesList();
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index 3c74618fff..46f2b42137 100755
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -113,6 +113,7 @@ private:
protected:
void onTabSelected(const LLSD& param);
+ void disableTabCtrls();
void refreshFromRegion(LLViewerRegion* region);
// member data
@@ -240,6 +241,7 @@ public:
void setEnvControls(bool available); // Whether environment settings are available for this region
BOOL validateTextureSizes();
+ BOOL validateTextureHeights();
//static void onChangeAnything(LLUICtrl* ctrl, void* userData); // callback for any change, to enable commit button
@@ -249,6 +251,11 @@ public:
static void onClickUploadRaw(void*);
static void onClickBakeTerrain(void*);
bool callbackBakeTerrain(const LLSD& notification, const LLSD& response);
+ bool callbackTextureHeights(const LLSD& notification, const LLSD& response);
+
+private:
+ bool mConfirmedTextureHeights;
+ bool mAskedTextureHeights;
};
/////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llfloatersidepanelcontainer.cpp b/indra/newview/llfloatersidepanelcontainer.cpp
index aee20ff706..c7218ad9d5 100755
--- a/indra/newview/llfloatersidepanelcontainer.cpp
+++ b/indra/newview/llfloatersidepanelcontainer.cpp
@@ -69,7 +69,11 @@ void LLFloaterSidePanelContainer::closeFloater(bool app_quitting)
LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance*>(getPanel("appearance"));
if ( panel_appearance )
{
- panel_appearance->getWearable()->onClose();
+ LLPanelEditWearable *edit_wearable_ptr = panel_appearance->getWearable();
+ if (edit_wearable_ptr)
+ {
+ edit_wearable_ptr->onClose();
+ }
panel_appearance->showOutfitsInventoryPanel();
}
}
diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index f8681fe098..e20360066e 100755
--- a/indra/newview/llfloatertopobjects.cpp
+++ b/indra/newview/llfloatertopobjects.cpp
@@ -183,10 +183,15 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
msg->getU32("DataExtended", "TimeStamp", time_stamp, block);
msg->getF32("DataExtended", "MonoScore", mono_score, block);
msg->getS32("DataExtended", "PublicURLs", public_urls, block);
- if (msg->getSize("DataExtended", "ParcelName") > 0)
+
+ std::string parcel_name;
+ F32 script_size = 0.f;
+ msg->getString("DataExtended", "ParcelName", parcel_name, block);
+ msg->getF32("DataExtended", "Size", script_size, block);
+ if (parcel_name.size() > 0 || script_size > 0)
{
- msg->getString("DataExtended", "ParcelName", parcel_buf, block);
- msg->getF32("DataExtended", "Size", script_memory, block);
+ parcel_buf = parcel_name;
+ script_memory = script_size;
}
}
diff --git a/indra/newview/llgroupiconctrl.cpp b/indra/newview/llgroupiconctrl.cpp
index 1974a073dd..271dd44c1f 100755
--- a/indra/newview/llgroupiconctrl.cpp
+++ b/indra/newview/llgroupiconctrl.cpp
@@ -64,7 +64,8 @@ LLGroupIconCtrl::LLGroupIconCtrl(const LLGroupIconCtrl::Params& p)
}
else
{
- LLIconCtrl::setValue(mDefaultIconName);
+ //TODO: Consider implementing dedicated setDefault() function instead of passing priority for local file
+ LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
}
}
@@ -73,6 +74,11 @@ LLGroupIconCtrl::~LLGroupIconCtrl()
LLGroupMgr::getInstance()->removeObserver(this);
}
+void LLGroupIconCtrl::setIconId(const LLSD& value)
+{
+ LLIconCtrl::setValue(value);
+}
+
void LLGroupIconCtrl::setValue(const LLSD& value)
{
if (value.isUUID())
@@ -91,7 +97,7 @@ void LLGroupIconCtrl::setValue(const LLSD& value)
// Check if cache already contains image_id for that group
if (!updateFromCache())
{
- LLIconCtrl::setValue(mDefaultIconName);
+ LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
gm->addObserver(this);
gm->sendGroupPropertiesRequest(mGroupId);
}
@@ -122,7 +128,7 @@ bool LLGroupIconCtrl::updateFromCache()
}
else
{
- LLIconCtrl::setValue(mDefaultIconName);
+ LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
}
if (mDrawTooltip && !group_data->mName.empty())
diff --git a/indra/newview/llgroupiconctrl.h b/indra/newview/llgroupiconctrl.h
index f42593c9e1..f8b22cf581 100755
--- a/indra/newview/llgroupiconctrl.h
+++ b/indra/newview/llgroupiconctrl.h
@@ -66,6 +66,8 @@ public:
*/
virtual void setValue(const LLSD& value);
+ void setIconId(const LLSD& value);
+
// LLGroupMgrObserver observer trigger
virtual void changed(LLGroupChange gc);
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index ef238cefe3..6126db2988 100755
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -30,7 +30,7 @@
// libs
#include "llbutton.h"
-#include "lliconctrl.h"
+#include "llgroupiconctrl.h"
#include "llmenugl.h"
#include "lltextbox.h"
#include "lltextutil.h"
@@ -319,7 +319,7 @@ LLGroupListItem::~LLGroupListItem()
//virtual
BOOL LLGroupListItem::postBuild()
{
- mGroupIcon = getChild<LLIconCtrl>("group_icon");
+ mGroupIcon = getChild<LLGroupIconCtrl>("group_icon");
mGroupNameBox = getChild<LLTextBox>("group_name");
mInfoBtn = getChild<LLButton>("info_btn");
@@ -381,7 +381,7 @@ void LLGroupListItem::setGroupIconID(const LLUUID& group_icon_id)
{
if (group_icon_id.notNull())
{
- mGroupIcon->setValue(group_icon_id);
+ mGroupIcon->setIconId(group_icon_id);
}
}
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index e96a720886..171b77fb00 100755
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -83,7 +83,7 @@ private:
};
class LLButton;
-class LLIconCtrl;
+class LLGroupIconCtrl;
class LLTextBox;
class LLGroupListItem : public LLPanel
@@ -113,7 +113,7 @@ private:
LLTextBox* mGroupNameBox;
LLUUID mGroupID;
- LLIconCtrl* mGroupIcon;
+ LLGroupIconCtrl* mGroupIcon;
LLButton* mInfoBtn;
std::string mGroupName;
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 1782653439..26c9b40fb1 100755
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1958,6 +1958,7 @@ BOOL LLItemBridge::removeItem()
}
LLNotifications::instance().forceResponse(params, 0);
+ model->checkTrashOverflow();
return TRUE;
}
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index bdbe253723..cada2d7cf2 100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -44,6 +44,7 @@
#include "llmarketplacefunctions.h"
#include "llwindow.h"
#include "llviewercontrol.h"
+#include "llviewernetwork.h"
#include "llpreview.h"
#include "llviewermessage.h"
#include "llviewerfoldertype.h"
@@ -73,7 +74,8 @@ BOOL LLInventoryModel::sFirstTimeInViewer2 = TRUE;
///----------------------------------------------------------------------------
//BOOL decompress_file(const char* src_filename, const char* dst_filename);
-static const char CACHE_FORMAT_STRING[] = "%s.inv";
+static const char PRODUCTION_CACHE_FORMAT_STRING[] = "%s.inv";
+static const char GRID_CACHE_FORMAT_STRING[] = "%s.%s.inv";
static const char * const LOG_INV("Inventory");
struct InventoryIDPtrLess
@@ -759,6 +761,22 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id,
}
}
+U32 LLInventoryModel::getDescendentsCountRecursive(const LLUUID& id, U32 max_item_limit)
+{
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ gInventory.collectDescendents(id, cats, items, LLInventoryModel::INCLUDE_TRASH);
+
+ U32 items_found = items.size() + cats.size();
+
+ for (U32 i = 0; i < cats.size() && items_found <= max_item_limit; ++i)
+ {
+ items_found += getDescendentsCountRecursive(cats[i]->getUUID(), max_item_limit - items_found);
+ }
+
+ return items_found;
+}
+
void LLInventoryModel::addChangedMaskForLinks(const LLUUID& object_id, U32 mask)
{
const LLInventoryObject *obj = getObject(object_id);
@@ -1607,6 +1625,29 @@ bool LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id) const
return cat->fetch();
}
+//static
+std::string LLInventoryModel::getInvCacheAddres(const LLUUID& owner_id)
+{
+ std::string inventory_addr;
+ std::string owner_id_str;
+ owner_id.toString(owner_id_str);
+ std::string path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, owner_id_str));
+ if (LLGridManager::getInstance()->isInProductionGrid())
+ {
+ inventory_addr = llformat(PRODUCTION_CACHE_FORMAT_STRING, path.c_str());
+ }
+ else
+ {
+ // NOTE: The inventory cache filenames now include the grid name.
+ // Add controls against directory traversal or problematic pathname lengths
+ // if your viewer uses grid names from an untrusted source.
+ const std::string& grid_id_str = LLGridManager::getInstance()->getGridId();
+ const std::string& grid_id_lower = utf8str_tolower(grid_id_str);
+ inventory_addr = llformat(GRID_CACHE_FORMAT_STRING, path.c_str(), grid_id_lower.c_str());
+ }
+ return inventory_addr;
+}
+
void LLInventoryModel::cache(
const LLUUID& parent_folder_id,
const LLUUID& agent_id)
@@ -1627,11 +1668,7 @@ void LLInventoryModel::cache(
items,
INCLUDE_TRASH,
can_cache);
- std::string agent_id_str;
- std::string inventory_filename;
- agent_id.toString(agent_id_str);
- std::string path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, agent_id_str));
- inventory_filename = llformat(CACHE_FORMAT_STRING, path.c_str());
+ std::string inventory_filename = getInvCacheAddres(agent_id);
saveToFile(inventory_filename, categories, items);
std::string gzip_filename(inventory_filename);
gzip_filename.append(".gz");
@@ -1935,11 +1972,7 @@ bool LLInventoryModel::loadSkeleton(
item_array_t items;
item_array_t possible_broken_links;
cat_set_t invalid_categories; // Used to mark categories that weren't successfully loaded.
- std::string owner_id_str;
- owner_id.toString(owner_id_str);
- std::string path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, owner_id_str));
- std::string inventory_filename;
- inventory_filename = llformat(CACHE_FORMAT_STRING, path.c_str());
+ std::string inventory_filename = getInvCacheAddres(owner_id);
const S32 NO_VERSION = LLViewerInventoryCategory::VERSION_UNKNOWN;
std::string gzip_filename(inventory_filename);
gzip_filename.append(".gz");
@@ -3320,6 +3353,7 @@ void LLInventoryModel::processMoveInventoryItem(LLMessageSystem* msg, void**)
//----------------------------------------------------------------------------
// Trash: LLFolderType::FT_TRASH, "ConfirmEmptyTrash"
+// Trash: LLFolderType::FT_TRASH, "TrashIsFull" when trash exceeds maximum capacity
// Lost&Found: LLFolderType::FT_LOST_AND_FOUND, "ConfirmEmptyLostAndFound"
bool LLInventoryModel::callbackEmptyFolderType(const LLSD& notification, const LLSD& response, LLFolderType::EType preferred_type)
@@ -3401,10 +3435,17 @@ void LLInventoryModel::removeCategory(const LLUUID& category_id)
changeCategoryParent(cat, trash_id, TRUE);
}
}
+
+ checkTrashOverflow();
}
void LLInventoryModel::removeObject(const LLUUID& object_id)
{
+ if(object_id.isNull())
+ {
+ return;
+ }
+
LLInventoryObject* obj = getObject(object_id);
if (dynamic_cast<LLViewerInventoryItem*>(obj))
{
@@ -3426,6 +3467,16 @@ void LLInventoryModel::removeObject(const LLUUID& object_id)
}
}
+void LLInventoryModel::checkTrashOverflow()
+{
+ static const U32 trash_max_capacity = gSavedSettings.getU32("InventoryTrashMaxCapacity");
+ const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if (getDescendentsCountRecursive(trash_id, trash_max_capacity) >= trash_max_capacity)
+ {
+ gInventory.emptyFolderType("TrashIsFull", LLFolderType::FT_TRASH);
+ }
+}
+
const LLUUID &LLInventoryModel::getRootFolderID() const
{
return mRootFolderID;
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index e1e6db19eb..3004eaf7c1 100755
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -164,7 +164,9 @@ public:
bool loadSkeleton(const LLSD& options, const LLUUID& owner_id);
void buildParentChildMap(); // brute force method to rebuild the entire parent-child relations
void createCommonSystemCategories();
-
+
+ static std::string getInvCacheAddres(const LLUUID& owner_id);
+
// Call on logout to save a terse representation.
void cache(const LLUUID& parent_folder_id, const LLUUID& agent_id);
private:
@@ -262,6 +264,9 @@ public:
// Follow parent chain to the top.
bool getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
+
+private:
+ U32 getDescendentsCountRecursive(const LLUUID& id, U32 max_item_limit);
//--------------------------------------------------------------------
// Find
@@ -403,6 +408,8 @@ public:
/// removeItem() or removeCategory(), whichever is appropriate
void removeObject(const LLUUID& object_id);
+ void checkTrashOverflow();
+
protected:
void updateLinkedObjectsFromPurge(const LLUUID& baseobj_id);
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index 6c81378622..72ec092ed4 100755
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -306,6 +306,12 @@ void LLInventoryFetchItemsObserver::startFetch()
continue;
}
+ if ((*it).isNull())
+ {
+ LL_WARNS("Inventory") << "Skip fetching for a NULL uuid" << LL_ENDL;
+ continue;
+ }
+
// It's incomplete, so put it on the incomplete container, and
// pack this on the message.
mIncomplete.push_back(*it);
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 02d378bc51..f5dcbf838d 100755
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1332,6 +1332,11 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
}
else
{
+ LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory");
+ if (floater_inventory)
+ {
+ floater_inventory->setFocus(TRUE);
+ }
active_panel->setSelection(obj_id, TAKE_FOCUS_YES);
}
}
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 366b9ac034..aa934f95a1 100755
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -135,7 +135,7 @@ LLLocalBitmap::~LLLocalBitmap()
}
// delete self from gimagelist
- LLViewerFetchedTexture* image = gTextureList.findImage(mWorldID, TEX_LIST_DISCARD);
+ LLViewerFetchedTexture* image = gTextureList.findImage(mWorldID, TEX_LIST_STANDARD);
gTextureList.deleteImage(image);
if (image)
@@ -207,7 +207,7 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)
texture->setCachedRawImage(LL_LOCAL_DISCARD_LEVEL, raw_image);
texture->ref();
- gTextureList.addImage(texture, TEX_LIST_DISCARD);
+ gTextureList.addImage(texture, TEX_LIST_STANDARD);
if (optional_firstupdate != UT_FIRSTUSE)
{
@@ -215,7 +215,7 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)
replaceIDs(old_id, mWorldID);
// remove old_id from gimagelist
- LLViewerFetchedTexture* image = gTextureList.findImage(old_id, TEX_LIST_DISCARD);
+ LLViewerFetchedTexture* image = gTextureList.findImage(old_id, TEX_LIST_STANDARD);
if (image != NULL)
{
gTextureList.deleteImage(image);
@@ -384,7 +384,7 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)
std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id, U32 channel)
{
std::vector<LLViewerObject*> obj_list;
- LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id, TEX_LIST_DISCARD);
+ LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id, TEX_LIST_STANDARD);
for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(channel); face_iterator++)
{
@@ -502,7 +502,7 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel)
void LLLocalBitmap::updateUserSculpts(LLUUID old_id, LLUUID new_id)
{
- LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id, TEX_LIST_DISCARD);
+ LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id, TEX_LIST_STANDARD);
for(U32 volume_iter = 0; volume_iter < old_texture->getNumVolumes(); volume_iter++)
{
LLVOVolume* volume_to_object = (*old_texture->getVolumeList())[volume_iter];
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index 85faa70552..3cbe742e3c 100755
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -2081,7 +2081,7 @@ BOOL LLManipScale::canAffectSelection()
{
LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit();
return objectp->permModify() && objectp->permMove() && !objectp->isPermanentEnforced() &&
- ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ (root_object == NULL || (!root_object->isPermanentEnforced() && !root_object->isSeat())) &&
!objectp->isSeat();
}
} func;
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index dfa33b37ef..6cc7a0fc99 100755
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -795,6 +795,15 @@ void LLMarketplaceData::getMerchantStatusCoro()
log_SLM_infos("Get /merchant", httpCode, std::string("Merchant is not migrated"));
setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT);
}
+ else if (httpCode == HTTP_INTERNAL_ERROR)
+ {
+ // 499 includes timeout and ssl error - marketplace is down or having issues, we do not show it in this request according to MAINT-5938
+ LL_WARNS("SLM") << "SLM Merchant Request failed with status: " << httpCode
+ << ", reason : " << status.toString()
+ << ", code : " << result["error_code"].asString()
+ << ", description : " << result["error_description"].asString() << LL_ENDL;
+ LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE);
+ }
else
{
std::string err_code = result["error_code"].asString();
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 8c4849d28d..84a2cd8be1 100755
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -44,6 +44,7 @@
#include "lllocationinputctrl.h"
#include "llpaneltopinfobar.h"
#include "llteleporthistory.h"
+#include "llresizebar.h"
#include "llsearchcombobox.h"
#include "llslurl.h"
#include "llurlregistry.h"
@@ -267,7 +268,10 @@ LLNavigationBar::LLNavigationBar()
mBtnForward(NULL),
mBtnHome(NULL),
mCmbLocation(NULL),
- mSaveToLocationHistory(false)
+ mSaveToLocationHistory(false),
+ mNavigationPanel(NULL),
+ mFavoritePanel(NULL),
+ mNavPanWidth(0)
{
buildFromFile( "panel_navigation_bar.xml");
@@ -286,7 +290,7 @@ BOOL LLNavigationBar::postBuild()
mBtnBack = getChild<LLPullButton>("back_btn");
mBtnForward = getChild<LLPullButton>("forward_btn");
mBtnHome = getChild<LLButton>("home_btn");
-
+
mCmbLocation= getChild<LLLocationInputCtrl>("location_combo");
mBtnBack->setEnabled(FALSE);
@@ -318,6 +322,11 @@ BOOL LLNavigationBar::postBuild()
LLHints::registerHintTarget("nav_bar", getHandle());
+ mNavigationPanel = getChild<LLLayoutPanel>("navigation_layout_panel");
+ mFavoritePanel = getChild<LLLayoutPanel>("favorites_layout_panel");
+ mNavigationPanel->getResizeBar()->setResizeListener(boost::bind(&LLNavigationBar::onNavbarResized, this));
+ mFavoritePanel->getResizeBar()->setResizeListener(boost::bind(&LLNavigationBar::onNavbarResized, this));
+
return TRUE;
}
@@ -356,7 +365,6 @@ BOOL LLNavigationBar::handleRightMouseDown(S32 x, S32 y, MASK mask)
show_navbar_context_menu(this,x,y);
handled = true;
}
-
return handled;
}
@@ -365,6 +373,18 @@ void LLNavigationBar::onBackButtonClicked()
LLTeleportHistory::getInstance()->goBack();
}
+void LLNavigationBar::onNavbarResized()
+{
+ S32 new_nav_pan_width = mNavigationPanel->getRect().getWidth();
+ if(mNavPanWidth != new_nav_pan_width)
+ {
+ S32 new_stack_width = new_nav_pan_width + mFavoritePanel->getRect().getWidth();
+ F32 ratio = (F32)new_nav_pan_width / (F32)new_stack_width;
+ gSavedPerAccountSettings.setF32("NavigationBarRatio", ratio);
+ mNavPanWidth = new_nav_pan_width;
+ }
+}
+
void LLNavigationBar::onBackOrForwardButtonHeldDown(LLUICtrl* ctrl, const LLSD& param)
{
if (param["count"].asInteger() == 0)
@@ -667,8 +687,18 @@ void LLNavigationBar::handleLoginComplete()
LLTeleportHistory::getInstance()->handleLoginComplete();
LLPanelTopInfoBar::instance().handleLoginComplete();
mCmbLocation->handleLoginComplete();
+ resizeLayoutPanel();
}
+void LLNavigationBar::resizeLayoutPanel()
+{
+ LLRect nav_bar_rect = mNavigationPanel->getRect();
+
+ S32 nav_panel_width = (nav_bar_rect.getWidth() + mFavoritePanel->getRect().getWidth()) * gSavedPerAccountSettings.getF32("NavigationBarRatio");
+
+ nav_bar_rect.setLeftTopAndSize(nav_bar_rect.mLeft, nav_bar_rect.mTop, nav_panel_width, nav_bar_rect.getHeight());
+ mNavigationPanel->handleReshape(nav_bar_rect,true);
+}
void LLNavigationBar::invokeSearch(std::string search_text)
{
LLFloaterReg::showInstance("search", LLSD().with("category", "all").with("query", LLSD(search_text)));
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index 7878bab24e..29dbaedf7a 100755
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -29,6 +29,7 @@
#include "llpanel.h"
#include "llbutton.h"
+#include "lllayoutstack.h"
class LLLocationInputCtrl;
class LLMenuGL;
@@ -108,6 +109,7 @@ private:
void rebuildTeleportHistoryMenu();
void showTeleportHistoryMenu(LLUICtrl* btn_ctrl);
void invokeSearch(std::string search_text);
+ void resizeLayoutPanel();
// callbacks
void onTeleportHistoryMenuItemClicked(const LLSD& userdata);
void onTeleportHistoryChanged();
@@ -120,6 +122,7 @@ private:
void onLocationPrearrange(const LLSD& data);
void onTeleportFinished(const LLVector3d& global_agent_pos);
void onTeleportFailed();
+ void onNavbarResized();
void onRegionNameResponse(
std::string typed_location,
std::string region_name,
@@ -135,6 +138,7 @@ private:
}
}
+ S32 mNavPanWidth;
LLMenuGL* mTeleportHistoryMenu;
LLPullButton* mBtnBack;
LLPullButton* mBtnForward;
@@ -142,6 +146,8 @@ private:
LLLocationInputCtrl* mCmbLocation;
LLRect mDefaultNbRect;
LLRect mDefaultFpRect;
+ LLLayoutPanel* mNavigationPanel;
+ LLLayoutPanel* mFavoritePanel;
boost::signals2::connection mTeleportFailedConnection;
boost::signals2::connection mTeleportFinishConnection;
boost::signals2::connection mHistoryMenuConnection;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 551495c6ad..ec2d37c30d 100755
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -2214,7 +2214,7 @@ void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical)
LLTextureEntry *te = object->getTE(te_index);
if (te)
{
- LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_DISCARD) : NULL;
+ LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL;
if(!tex)
{
tex = LLViewerFetchedTexture::sDefaultImagep;
diff --git a/indra/newview/llpanelgroupexperiences.cpp b/indra/newview/llpanelgroupexperiences.cpp
index a88a55ab22..6c40499208 100644
--- a/indra/newview/llpanelgroupexperiences.cpp
+++ b/indra/newview/llpanelgroupexperiences.cpp
@@ -30,7 +30,7 @@
#include "lluictrlfactory.h"
#include "roles_constants.h"
-
+#include "llappviewer.h"
#include "llagent.h"
#include "llviewerregion.h"
#include "llflatlistview.h"
@@ -67,7 +67,7 @@ BOOL LLPanelGroupExperiences::postBuild()
void LLPanelGroupExperiences::activate()
{
- if (getGroupID() == LLUUID::null)
+ if ((getGroupID() == LLUUID::null) || gDisconnected)
{
return;
}
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index 263c73dc0e..6e677bbce5 100755
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -1080,28 +1080,25 @@ void LLPanelPermissions::setAllSaleInfo()
LLSaleInfo new_sale_info(sale_type, price);
LLSelectMgr::getInstance()->selectionSetObjectSaleInfo(new_sale_info);
-
- U8 old_click_action = 0;
- LLSelectMgr::getInstance()->selectionGetClickAction(&old_click_action);
- if (old_sale_info.isForSale()
- && !new_sale_info.isForSale()
- && old_click_action == CLICK_ACTION_BUY)
- {
- // If turned off for-sale, make sure click-action buy is turned
- // off as well
- LLSelectMgr::getInstance()->
- selectionSetClickAction(CLICK_ACTION_TOUCH);
- }
- else if (new_sale_info.isForSale()
- && !old_sale_info.isForSale()
- && old_click_action == CLICK_ACTION_TOUCH)
- {
- // If just turning on for-sale, preemptively turn on one-click buy
- // unless user have a different click action set
- LLSelectMgr::getInstance()->
- selectionSetClickAction(CLICK_ACTION_BUY);
- }
+ struct f : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ return object->getClickAction() == CLICK_ACTION_BUY
+ || object->getClickAction() == CLICK_ACTION_TOUCH;
+ }
+ } check_actions;
+
+ // Selection should only contain objects that are of target
+ // action already or of action we are aiming to remove.
+ bool default_actions = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&check_actions);
+
+ if (default_actions && old_sale_info.isForSale() != new_sale_info.isForSale())
+ {
+ U8 new_click_action = new_sale_info.isForSale() ? CLICK_ACTION_BUY : CLICK_ACTION_TOUCH;
+ LLSelectMgr::getInstance()->selectionSetClickAction(new_click_action);
+ }
}
struct LLSelectionPayable : public LLSelectedObjectFunctor
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
index 9e4f50b7a7..9c0222d0bc 100755
--- a/indra/newview/llpersistentnotificationstorage.cpp
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -123,11 +123,28 @@ void LLPersistentNotificationStorage::loadNotifications()
LLNotifications& instance = LLNotifications::instance();
S32 processed_notifications = 0;
+ std::vector<LLSD> notifications_array;
for (LLSD::reverse_array_iterator notification_it = data.rbeginArray();
notification_it != data.rendArray();
++notification_it)
{
LLSD notification_params = *notification_it;
+ notifications_array.push_back(notification_params);
+
+ ++processed_notifications;
+ if (processed_notifications >= gSavedSettings.getS32("MaxPersistentNotifications"))
+ {
+ LL_WARNS() << "Too many persistent notifications."
+ << " Processed " << gSavedSettings.getS32("MaxPersistentNotifications") << " of " << data.size() << " persistent notifications." << LL_ENDL;
+ break;
+ }
+ }
+
+ for (LLSD::reverse_array_iterator notification_it = notifications_array.rbegin();
+ notification_it != notifications_array.rend();
+ ++notification_it)
+ {
+ LLSD notification_params = *notification_it;
LLNotificationPtr notification(new LLNotification(notification_params));
LLNotificationResponderPtr responder(createResponder(notification_params["name"], notification_params["responder"]));
@@ -143,14 +160,8 @@ void LLPersistentNotificationStorage::loadNotifications()
// hide saved toasts so they don't confuse the user
notification_channel->hideToast(notification->getID());
}
- ++processed_notifications;
- if (processed_notifications >= gSavedSettings.getS32("MaxPersistentNotifications"))
- {
- LL_WARNS() << "Too many persistent notifications."
- << " Processed " << gSavedSettings.getS32("MaxPersistentNotifications") << " of " << data.size() << " persistent notifications." << LL_ENDL;
- break;
- }
}
+
LLNotifications::instance().getChannel("Persistent")->
connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
LL_INFOS("LLPersistentNotificationStorage") << "finished loading notifications" << LL_ENDL;
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index ea7cf82674..86135ee6e8 100755
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -198,7 +198,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)
if (is_outfit_edit_visible || is_wearable_edit_visible)
{
- const LLViewerWearable *wearable_ptr = mEditWearable->getWearable();
+ const LLViewerWearable *wearable_ptr = mEditWearable ? mEditWearable->getWearable() : NULL;
if (!wearable_ptr)
{
LL_WARNS() << "Visibility change to invalid wearable" << LL_ENDL;
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index 503dd6747d..cb356726e6 100755
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -718,7 +718,6 @@ void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL
<< " quant_wbits " << (S32)ph.quant_wbits
<< " patchids " << (S32)ph.patchids
<< LL_ENDL;
- LLAppViewer::instance()->badNetworkHandler();
return;
}
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index bcdf8360ed..37cc908e84 100755
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -1491,6 +1491,7 @@ void LLTextureCache::readHeaderCache()
new_entries.push_back(entry);
}
}
+ mFreeList.clear(); // recreating list, no longer valid.
llassert_always(new_entries.size() <= sCacheMaxEntries);
mHeaderEntriesInfo.mEntries = new_entries.size();
writeEntriesHeader();
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 980810835e..e5aa740a33 100755
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -1393,7 +1393,7 @@ void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb)
void LLTextureCtrl::setImageAssetName(const std::string& name)
{
- LLPointer<LLUIImage> imagep = LLUI::getUIImage(name);
+ LLPointer<LLUIImage> imagep = LLUI::getUIImage(name, LLGLTexture::BOOST_PREVIEW);
if(imagep)
{
LLViewerFetchedTexture* pTexture = dynamic_cast<LLViewerFetchedTexture*>(imagep->getImage().get());
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 750140245b..a0e112c5e8 100755
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -4449,7 +4449,7 @@ void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker)
mRefetchedAllData += worker->mFormattedImage->getDataSize();
// refetch list only requests/creates normal images, so requesting ui='false'
- LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID, TEX_LIST_DISCARD);
+ LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID, TEX_LIST_STANDARD);
if(tex && mRefetchList[tex].begin() != mRefetchList[tex].end())
{
if(worker->mDecodedDiscard == mFetchingHistory[mRefetchList[tex][0]].mDecodedLevel)
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 63ede7f8ac..7020ac0c65 100755
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -380,10 +380,6 @@ void LLToast::setVisible(BOOL show)
{
mTimer->start();
}
- if (!getVisible())
- {
- LLModalDialog::setFrontmost(FALSE);
- }
}
else
{
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index 530bd9a18f..bbce717c20 100755
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -181,6 +181,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
params.wrap(true);
params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
params.allow_scroll(true);
+ params.force_urls_external(mNotification->getForceUrlsExternal());
LLTextBox * msg_box = LLUICtrlFactory::create<LLTextBox> (params);
// Compute max allowable height for the dialog text, so we can allocate
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index cafe757c1a..f6ca0bc9d7 100755
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -31,7 +31,7 @@
#include "llfocusmgr.h"
#include "llbutton.h"
-#include "lliconctrl.h"
+#include "llgroupiconctrl.h"
#include "llinventoryfunctions.h"
#include "llinventoryicon.h"
#include "llnotifications.h"
@@ -65,8 +65,10 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notifi
}
//group icon
- LLIconCtrl* pGroupIcon = getChild<LLIconCtrl>("group_icon", TRUE);
- pGroupIcon->setValue(groupData.mInsigniaID);
+ LLGroupIconCtrl* pGroupIcon = getChild<LLGroupIconCtrl>("group_icon", TRUE);
+
+ // We should already have this data preloaded, so no sense in setting icon through setValue(group_id)
+ pGroupIcon->setIconId(groupData.mInsigniaID);
//header title
std::string from_name = payload["sender_name"].asString();
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 3e027e3d05..a7ad7c80d9 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1312,6 +1312,13 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)
if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, cookie_path, httponly, secure) &&
media_instance->getMediaPlugin())
{
+ // MAINT-5711 - inexplicably, the CEF setCookie function will no longer set the cookie if the
+ // url and domain are not the same. This used to be my.sl.com and id.sl.com respectively and worked.
+ // For now, we use the URL for the OpenID POST request since it will have the same authority
+ // as the domain field.
+ // (Feels like there must be a less dirty way to construct a URL from component LLURL parts)
+ url = std::string(sOpenIDURL.mURI) + "://" + std::string(sOpenIDURL.mAuthority);
+
media_instance->getMediaPlugin()->setCookie(url, cookie_name, cookie_value, cookie_host, cookie_path, httponly, secure);
}
}
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index e43a6d2b8f..66eee552be 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2362,6 +2362,20 @@ static void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::s
}
}
+const std::string NOT_ONLINE_MSG("User not online - message will be stored and delivered later.");
+const std::string NOT_ONLINE_INVENTORY("User not online - inventory has been saved.");
+void translate_if_needed(std::string& message)
+{
+ if (message == NOT_ONLINE_MSG)
+ {
+ message = LLTrans::getString("not_online_msg");
+ }
+ else if (message == NOT_ONLINE_INVENTORY)
+ {
+ message = LLTrans::getString("not_online_inventory");
+ }
+}
+
void process_improved_im(LLMessageSystem *msg, void **user_data)
{
LLUUID from_id;
@@ -2426,6 +2440,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
chat.mFromID = from_id;
chat.mFromName = name;
chat.mSourceType = (from_id.isNull() || (name == std::string(SYSTEM_FROM))) ? CHAT_SOURCE_SYSTEM : CHAT_SOURCE_AGENT;
+
+ if (chat.mSourceType == CHAT_SOURCE_SYSTEM)
+ { // Translate server message if required (MAINT-6109)
+ translate_if_needed(message);
+ }
LLViewerObject *source = gObjectList.findObject(session_id); //Session ID is probably the wrong thing.
if (source)
@@ -5598,6 +5617,10 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg)
bool you_paid_someone = (source_id == gAgentID);
if (you_paid_someone)
{
+ if(!gSavedSettings.getBOOL("NotifyMoneySpend"))
+ {
+ return;
+ }
args["NAME"] = dest_slurl;
is_name_group = is_dest_group;
name_id = dest_id;
@@ -5635,6 +5658,10 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg)
}
else {
// ...someone paid you
+ if(!gSavedSettings.getBOOL("NotifyMoneyReceived"))
+ {
+ return;
+ }
args["NAME"] = source_slurl;
is_name_group = is_source_group;
name_id = source_id;
@@ -7419,7 +7446,7 @@ void callback_load_url_name(const LLUUID& id, const std::string& full_name, bool
args["URL"] = load_url_info["url"].asString();
args["MESSAGE"] = load_url_info["message"].asString();;
args["OBJECTNAME"] = load_url_info["object_name"].asString();
- args["NAME"] = owner_name;
+ args["NAME_SLURL"] = LLSLURL(is_group ? "group" : "agent", id, "about").getSLURLString();
LLNotificationsUtil::add("LoadWebPage", args, load_url_info);
}
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 03c3f0fc08..023f1b92ba 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -1201,6 +1201,12 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
bounds[0].add(*shift);
}
+ F32 OCCLUSION_FUDGE_Z = SG_OCCLUSION_FUDGE; //<-- #Solution #2
+ if (LLDrawPool::POOL_WATER == mSpatialPartition->mDrawableType)
+ {
+ OCCLUSION_FUDGE_Z = 1.;
+ }
+
// Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension
if (earlyFail(camera, bounds))
{
@@ -1260,7 +1266,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, bounds[0].getF32ptr());
shader->uniform3f(LLShaderMgr::BOX_SIZE, bounds[1][0]+SG_OCCLUSION_FUDGE,
bounds[1][1]+SG_OCCLUSION_FUDGE,
- bounds[1][2]+SG_OCCLUSION_FUDGE);
+ bounds[1][2]+OCCLUSION_FUDGE_Z);
if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)
{
@@ -1270,7 +1276,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
if (camera->getOrigin().isExactlyZero())
{ //origin is invalid, draw entire box
gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
- gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
}
else
{
@@ -1283,7 +1289,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
if (camera->getOrigin().isExactlyZero())
{ //origin is invalid, draw entire box
gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
- gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
}
else
{
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index e2b8ff8e80..c5e07f009f 100755
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -716,7 +716,8 @@ void LLViewerTexture::setBoostLevel(S32 level)
{
mBoostLevel = level;
if(mBoostLevel != LLViewerTexture::BOOST_NONE &&
- mBoostLevel != LLViewerTexture::BOOST_SELECTED)
+ mBoostLevel != LLViewerTexture::BOOST_SELECTED &&
+ mBoostLevel != LLViewerTexture::BOOST_ICON)
{
setNoDelete();
}
@@ -3322,7 +3323,7 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL
setCategory(LLGLTexture::MEDIA);
- LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_DISCARD);
+ LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
if(tex) //this media is a parcel media for tex.
{
tex->setParcelMedia(this);
@@ -3332,7 +3333,7 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL
//virtual
LLViewerMediaTexture::~LLViewerMediaTexture()
{
- LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_DISCARD);
+ LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
if(tex) //this media is a parcel media for tex.
{
tex->setParcelMedia(NULL);
@@ -3387,7 +3388,7 @@ BOOL LLViewerMediaTexture::findFaces()
BOOL ret = TRUE;
- LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_DISCARD);
+ LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
if(tex) //this media is a parcel media for tex.
{
for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
@@ -3496,7 +3497,7 @@ void LLViewerMediaTexture::addFace(U32 ch, LLFace* facep)
const LLTextureEntry* te = facep->getTextureEntry();
if(te && te->getID().notNull())
{
- LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_DISCARD);
+ LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_STANDARD);
if(tex)
{
mTextureList.push_back(tex);//increase the reference number by one for tex to avoid deleting it.
@@ -3525,7 +3526,7 @@ void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep)
const LLTextureEntry* te = facep->getTextureEntry();
if(te && te->getID().notNull())
{
- LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_DISCARD);
+ LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_STANDARD);
if(tex)
{
for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
@@ -3634,10 +3635,10 @@ void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep)
const LLTextureEntry* te = facep->getTextureEntry();
if(te)
{
- LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_DISCARD) : NULL;
+ LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL;
if(!tex && te->getID() != mID)//try parcel media.
{
- tex = gTextureList.findImage(mID, TEX_LIST_DISCARD);
+ tex = gTextureList.findImage(mID, TEX_LIST_STANDARD);
}
if(!tex)
{
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 9ee5ed758f..5cfd04b4c1 100755
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -72,20 +72,14 @@ static LLTrace::BlockTimerStatHandle FTM_PROCESS_IMAGES("Process Images");
ETexListType get_element_type(S32 priority)
{
- // don't discard flag can be used in some cases, but it usually is not set yet
- if (priority == LLViewerFetchedTexture::BOOST_ICON
- || priority == LLViewerFetchedTexture::BOOST_UI)
- {
- return TEX_LIST_UI;
- }
- return TEX_LIST_DISCARD;
+ return (priority == LLViewerFetchedTexture::BOOST_ICON) ? TEX_LIST_SCALE : TEX_LIST_STANDARD;
}
///////////////////////////////////////////////////////////////////////////////
LLTextureKey::LLTextureKey()
: textureId(LLUUID::null),
-textureType(TEX_LIST_DISCARD)
+textureType(TEX_LIST_STANDARD)
{
}
@@ -450,10 +444,16 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
if (boost_priority != 0)
{
- if (boost_priority == LLViewerFetchedTexture::BOOST_UI
- || boost_priority == LLViewerFetchedTexture::BOOST_ICON)
+ if (boost_priority == LLViewerFetchedTexture::BOOST_UI)
+ {
+ imagep->dontDiscard();
+ }
+ if (boost_priority == LLViewerFetchedTexture::BOOST_ICON)
{
+ // Agent and group Icons are downloadable content, nothing manages
+ // icon deletion yet, so they should not persist
imagep->dontDiscard();
+ imagep->forceActive();
}
imagep->setBoostLevel(boost_priority);
}
@@ -554,10 +554,16 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
if (boost_priority != 0)
{
- if (boost_priority == LLViewerFetchedTexture::BOOST_UI
- || boost_priority == LLViewerFetchedTexture::BOOST_ICON)
+ if (boost_priority == LLViewerFetchedTexture::BOOST_UI)
+ {
+ imagep->dontDiscard();
+ }
+ if (boost_priority == LLViewerFetchedTexture::BOOST_ICON)
{
+ // Agent and group Icons are downloadable content, nothing manages
+ // icon deletion yet, so they should not persist.
imagep->dontDiscard();
+ imagep->forceActive();
}
imagep->setBoostLevel(boost_priority);
}
@@ -579,7 +585,7 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
void LLViewerTextureList::findTexturesByID(const LLUUID &image_id, std::vector<LLViewerFetchedTexture*> &output)
{
- LLTextureKey search_key(image_id, TEX_LIST_DISCARD);
+ LLTextureKey search_key(image_id, TEX_LIST_STANDARD);
uuid_map_t::iterator iter = mUUIDMap.lower_bound(search_key);
while (iter != mUUIDMap.end() && iter->first.textureId == image_id)
{
@@ -1585,14 +1591,14 @@ void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **
LLUUID image_id;
msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, image_id);
- LLViewerFetchedTexture* image = gTextureList.findImage( image_id, TEX_LIST_DISCARD);
+ LLViewerFetchedTexture* image = gTextureList.findImage( image_id, TEX_LIST_STANDARD);
if( image )
{
LL_WARNS() << "Image not in db" << LL_ENDL;
image->setIsMissingAsset();
}
- image = gTextureList.findImage(image_id, TEX_LIST_UI);
+ image = gTextureList.findImage(image_id, TEX_LIST_SCALE);
if (image)
{
LL_WARNS() << "Icon not in db" << LL_ENDL;
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index 9f94f2f1bc..ba76770838 100755
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -61,8 +61,8 @@ typedef void (*LLImageCallback)(BOOL success,
enum ETexListType
{
- TEX_LIST_DISCARD = 0,
- TEX_LIST_UI
+ TEX_LIST_STANDARD = 0,
+ TEX_LIST_SCALE
};
struct LLTextureKey
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index f96c4b7bf0..50329d8576 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1037,7 +1037,16 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
{
- BOOL down = TRUE;
+ mAllowMouseDragging = FALSE;
+ if (!mMouseDownTimer.getStarted())
+ {
+ mMouseDownTimer.start();
+ }
+ else
+ {
+ mMouseDownTimer.reset();
+ }
+ BOOL down = TRUE;
return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down);
}
@@ -1056,7 +1065,11 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK ma
BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
{
- BOOL down = FALSE;
+ if (mMouseDownTimer.getStarted())
+ {
+ mMouseDownTimer.stop();
+ }
+ BOOL down = FALSE;
return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down);
}
@@ -1288,6 +1301,22 @@ void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask
}
}
+void LLViewerWindow::handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask)
+{
+ if (mMouseDownTimer.getStarted())
+ {
+ if (mMouseDownTimer.getElapsedTimeF32() > 0.1)
+ {
+ mAllowMouseDragging = TRUE;
+ mMouseDownTimer.stop();
+ }
+ }
+ if(mAllowMouseDragging || !LLToolCamera::getInstance()->hasMouseCapture())
+ {
+ handleMouseMove(window, pos, mask);
+ }
+}
+
void LLViewerWindow::handleMouseLeave(LLWindow *window)
{
// Note: we won't get this if we have captured the mouse.
@@ -1617,6 +1646,8 @@ LLViewerWindow::LLViewerWindow(const Params& p)
mMiddleMouseDown(FALSE),
mRightMouseDown(FALSE),
mMouseInWindow( FALSE ),
+ mAllowMouseDragging(TRUE),
+ mMouseDownTimer(),
mLastMask( MASK_NONE ),
mToolStored( NULL ),
mHideCursorPermanent( FALSE ),
@@ -4951,6 +4982,13 @@ void LLViewerWindow::stopGL(BOOL save_state)
gGLManager.mIsDisabled = TRUE;
stop_glerror();
+
+ //unload shader's
+ while (LLGLSLShader::sInstances.size())
+ {
+ LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin());
+ shader->unload();
+ }
LL_INFOS() << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemory.value() << " bytes" << LL_ENDL;
}
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index d34e76f6f6..ad06f00234 100755
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -193,6 +193,7 @@ public:
/*virtual*/ BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
/*virtual*/ LLWindowCallbacks::DragNDropResult handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, LLWindowCallbacks::DragNDropAction action, std::string data);
void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask);
+ void handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask);
/*virtual*/ void handleMouseLeave(LLWindow *window);
/*virtual*/ void handleResize(LLWindow *window, S32 x, S32 y);
/*virtual*/ void handleFocus(LLWindow *window);
@@ -463,6 +464,8 @@ private:
BOOL mMouseInWindow; // True if the mouse is over our window or if we have captured the mouse.
BOOL mFocusCycleMode;
+ BOOL mAllowMouseDragging;
+ LLFrameTimer mMouseDownTimer;
typedef std::set<LLHandle<LLView> > view_handle_set_t;
view_handle_set_t mMouseHoverViews;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 21c38e9bc1..ddf60b9464 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1992,7 +1992,7 @@ LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUU
uuid == IMG_INVISIBLE)
{
// Should already exist, don't need to find it on sim or baked-texture host.
- result = gTextureList.findImage(uuid, TEX_LIST_DISCARD);
+ result = gTextureList.findImage(uuid, TEX_LIST_STANDARD);
}
if (!result)
{
@@ -4313,7 +4313,7 @@ bool LLVOAvatar::allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const
{
for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
{
- LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_DISCARD);
+ LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD);
if (imagep && imagep->getDiscardLevel()!=0)
{
return false;
@@ -4385,7 +4385,7 @@ S32Bytes LLVOAvatar::totalTextureMemForUUIDS(std::set<LLUUID>& ids)
S32Bytes result(0);
for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
{
- LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_DISCARD);
+ LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD);
if (imagep)
{
result += imagep->getTextureMemory();
@@ -4473,7 +4473,7 @@ void LLVOAvatar::releaseOldTextures()
{
if (new_texture_ids.find(*it) == new_texture_ids.end())
{
- LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_DISCARD);
+ LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD);
if (imagep)
{
current_texture_mem += imagep->getTextureMemory();
@@ -7975,6 +7975,13 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
// show the cloned params inside the wearables as well.
gAgentAvatarp->dumpWearableInfo(outfile);
}
+ LLSD args;
+ args["PATH"] = fullpath;
+ LLNotificationsUtil::add("AppearanceToXMLSaved", args);
+ }
+ else
+ {
+ LLNotificationsUtil::add("AppearanceToXMLFailed");
}
// File will close when handle goes out of scope
}
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 56c0910983..5c125a236a 100755
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -657,19 +657,25 @@ void LLVoiceClient::keyDown(KEY key, MASK mask)
return;
}
- if(!mPTTIsMiddleMouse && LLAgent::isActionAllowed("speak"))
+ if (!mPTTIsMiddleMouse && LLAgent::isActionAllowed("speak") && (key == mPTTKey))
{
- bool down = (mPTTKey != KEY_NONE) && gKeyboard->getKeyDown(mPTTKey);
- if (down) { inputUserControlState(down); }
+ bool down = gKeyboard->getKeyDown(mPTTKey);
+ if (down)
+ {
+ inputUserControlState(down);
+ }
}
}
void LLVoiceClient::keyUp(KEY key, MASK mask)
{
- if(!mPTTIsMiddleMouse)
+ if (!mPTTIsMiddleMouse && (key == mPTTKey))
{
- bool down = (mPTTKey != KEY_NONE) && gKeyboard->getKeyDown(mPTTKey);
- if (down) { inputUserControlState(down); }
+ bool down = gKeyboard->getKeyDown(mPTTKey);
+ if (!down)
+ {
+ inputUserControlState(down);
+ }
}
}
void LLVoiceClient::middleMouseState(bool down)
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index c9661dfb11..07427e0377 100755
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -80,39 +80,49 @@
extern LLMenuBarGL* gMenuBarView;
extern void handle_voice_morphing_subscribe();
-const F32 VOLUME_SCALE_VIVOX = 0.01f;
+namespace {
+ const F32 VOLUME_SCALE_VIVOX = 0.01f;
-const F32 SPEAKING_TIMEOUT = 1.f;
+ const F32 SPEAKING_TIMEOUT = 1.f;
-static const std::string VOICE_SERVER_TYPE = "Vivox";
+ static const std::string VOICE_SERVER_TYPE = "Vivox";
-// Don't retry connecting to the daemon more frequently than this:
-const F32 CONNECT_THROTTLE_SECONDS = 1.0f;
+ // Don't retry connecting to the daemon more frequently than this:
+ const F32 CONNECT_THROTTLE_SECONDS = 1.0f;
-// Don't send positional updates more frequently than this:
-const F32 UPDATE_THROTTLE_SECONDS = 0.5f;
+ // Don't send positional updates more frequently than this:
+ const F32 UPDATE_THROTTLE_SECONDS = 0.5f;
-const F32 LOGIN_RETRY_SECONDS = 10.0f;
-const int MAX_LOGIN_RETRIES = 12;
+ const F32 LOGIN_ATTEMPT_TIMEOUT = 5.0f;
+ const int LOGIN_RETRY_MAX = 5;
+ const F32 LOGIN_RETRY_TIMEOUT = 4.0f;
-// Cosine of a "trivially" small angle
-const F32 MINUSCULE_ANGLE_COS = 0.999f;
+ const int PROVISION_RETRY_MAX = 5;
+ const F32 PROVISION_RETRY_TIMEOUT = 2.0;
-// Defines the maximum number of times(in a row) "stateJoiningSession" case for spatial channel is reached in stateMachine()
-// which is treated as normal. The is the number of frames to wait for a channel join before giving up. This was changed
-// from the original count of 50 for two reason. Modern PCs have higher frame rates and sometimes the SLVoice process
-// backs up processing join requests. There is a log statement that records when channel joins take longer than 100 frames.
-const int MAX_NORMAL_JOINING_SPATIAL_NUM = 1500;
+ // Cosine of a "trivially" small angle
+ const F32 MINUSCULE_ANGLE_COS = 0.999f;
-// How often to check for expired voice fonts in seconds
-const F32 VOICE_FONT_EXPIRY_INTERVAL = 10.f;
-// Time of day at which Vivox expires voice font subscriptions.
-// Used to replace the time portion of received expiry timestamps.
-static const std::string VOICE_FONT_EXPIRY_TIME = "T05:00:00Z";
+ const F32 SESSION_JOIN_TIMEOUT = 10.0f;
-// Maximum length of capture buffer recordings in seconds.
-const F32 CAPTURE_BUFFER_MAX_TIME = 10.f;
+ // Defines the maximum number of times(in a row) "stateJoiningSession" case for spatial channel is reached in stateMachine()
+ // which is treated as normal. The is the number of frames to wait for a channel join before giving up. This was changed
+ // from the original count of 50 for two reason. Modern PCs have higher frame rates and sometimes the SLVoice process
+ // backs up processing join requests. There is a log statement that records when channel joins take longer than 100 frames.
+ const int MAX_NORMAL_JOINING_SPATIAL_NUM = 1500;
+ // How often to check for expired voice fonts in seconds
+ const F32 VOICE_FONT_EXPIRY_INTERVAL = 10.f;
+ // Time of day at which Vivox expires voice font subscriptions.
+ // Used to replace the time portion of received expiry timestamps.
+ static const std::string VOICE_FONT_EXPIRY_TIME = "T05:00:00Z";
+
+ // Maximum length of capture buffer recordings in seconds.
+ const F32 CAPTURE_BUFFER_MAX_TIME = 10.f;
+
+ const int ERROR_VIVOX_OBJECT_NOT_FOUND = 1001;
+ const int ERROR_VIVOX_NOT_LOGGED_IN = 1007;
+}
static int scale_mic_volume(float volume)
{
@@ -129,8 +139,6 @@ static int scale_speaker_volume(float volume)
}
-const int ERROR_VIVOX_OBJECT_NOT_FOUND = 1001;
-const int ERROR_VIVOX_NOT_LOGGED_IN = 1007;
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -546,7 +554,7 @@ void LLVivoxVoiceClient::voiceControlCoro()
// if we hit this and mRelogRequested is true, that indicates
// that we attempted to relog into Vivox and were rejected.
// Rather than just quit out of voice, we will tear it down (above)
- // and then reconstruct the voice connecino from scratch.
+ // and then reconstruct the voice connecion from scratch.
if (mRelogRequested)
{
while (isGatewayRunning())
@@ -784,13 +792,15 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
if (status == LLCore::HttpStatus(404))
{
- if (++retryCount > 5)
+ if (++retryCount > PROVISION_RETRY_MAX)
{
- LL_WARNS("Voice") << "Could not access voice provision cap after 5 attempts." << LL_ENDL;
+ LL_WARNS("Voice") << "Could not access voice provision cap after " << PROVISION_RETRY_MAX << " attempts." << LL_ENDL;
return false;
}
- LL_WARNS("Voice") << "Provision CAP 404. Retrying in 1.0" << LL_ENDL;
- llcoro::suspendUntilTimeout(1.0);
+
+ F32 timeout = pow(PROVISION_RETRY_TIMEOUT, static_cast<float>(retryCount));
+ LL_WARNS("Voice") << "Provision CAP 404. Retrying in " << timeout << " seconds." << LL_ENDL;
+ llcoro::suspendUntilTimeout(timeout);
continue;
}
@@ -888,38 +898,42 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
bool LLVivoxVoiceClient::loginToVivox()
{
- int loginRetryCount(0);
LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
+ LLSD timeoutResult(LLSDMap("login", "timeout"));
+
+ int loginRetryCount(0);
+
bool response_ok(false);
bool account_login(false);
bool send_login(true);
do
{
+
mIsLoggingIn = true;
if (send_login)
loginSendMessage();
send_login = false;
- LLSD result = llcoro::suspendUntilEventOn(voicePump);
+ LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
if (result.has("login"))
{
std::string loginresp = result["login"];
- if (loginresp == "retry")
+ if ((loginresp == "retry") || (loginresp == "timeout"))
{
- if (!loginRetryCount)
+ if ((!loginRetryCount) && (loginresp != "timeout"))
{ // on first retry notify user
notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LOGIN_RETRY);
}
- if ((++loginRetryCount > MAX_LOGIN_RETRIES) || (!result["login_retry"]))
+ if ((++loginRetryCount > LOGIN_RETRY_MAX) || (loginresp == "timeout"))
{
- LL_WARNS("Voice") << "too many login retries, giving up." << LL_ENDL;
+ LL_WARNS("Voice") << "too many login retries or timeout connecting, giving up." << LL_ENDL;
LLSD args;
std::stringstream errs;
errs << mVoiceAccountServerURI << "\n:UDP: 3478, 3479, 5060, 5062, 12000-17000";
@@ -942,8 +956,10 @@ bool LLVivoxVoiceClient::loginToVivox()
account_login = false;
send_login = true;
- LL_INFOS("Voice") << "will retry login in " << LOGIN_RETRY_SECONDS << " seconds." << LL_ENDL;
- llcoro::suspendUntilTimeout(LOGIN_RETRY_SECONDS);
+ F32 timeout = pow(LOGIN_RETRY_TIMEOUT, static_cast<float>(loginRetryCount)) - 1.0f;
+
+ LL_INFOS("Voice") << "will retry login in " << timeout << " seconds." << LL_ENDL;
+ llcoro::suspendUntilTimeout(timeout);
}
else if (loginresp == "failed")
{
@@ -982,7 +998,6 @@ bool LLVivoxVoiceClient::loginToVivox()
void LLVivoxVoiceClient::logoutOfVivox(bool wait)
{
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
if (!mIsLoggedIn)
return;
@@ -995,7 +1010,10 @@ void LLVivoxVoiceClient::logoutOfVivox(bool wait)
if (wait)
{
- LLSD result = llcoro::suspendUntilEventOn(voicePump);
+ LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
+ LLSD timeoutResult(LLSDMap("lougout", "timeout"));
+
+ LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
@@ -1169,6 +1187,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
if (!mVoiceEnabled && mIsInitialized)
{
+ LL_DEBUGS("Voice") << "Voice no longer enabled. Exiting." << LL_ENDL;
mIsJoiningSession = false;
// User bailed out during connect -- jump straight to teardown.
terminateAudioSession(true);
@@ -1177,6 +1196,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
}
else if (mSessionTerminateRequested)
{
+ LL_DEBUGS("Voice") << "Terminate requested" << LL_ENDL;
if (mAudioSession && !mAudioSession->mHandle.empty())
{
// Only allow direct exits from this state in p2p calls (for cancelling an invite).
@@ -1194,15 +1214,17 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
bool added(true);
bool joined(false);
+ LLSD timeoutResult(LLSDMap("session", "timeout"));
+
// It appears that I need to wait for BOTH the SessionGroup.AddSession response and the SessionStateChangeEvent with state 4
// before continuing from this state. They can happen in either order, and if I don't wait for both, things can get stuck.
// For now, the SessionGroup.AddSession response handler sets mSessionHandle and the SessionStateChangeEvent handler transitions to stateSessionJoined.
// This is a cheap way to make sure both have happened before proceeding.
do
{
- result = llcoro::suspendUntilEventOn(voicePump);
+ result = llcoro::suspendUntilEventOnWithTimeout(voicePump, SESSION_JOIN_TIMEOUT, timeoutResult);
- LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
+ LL_INFOS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
if (result.has("session"))
{
if (result.has("handle"))
@@ -1215,14 +1237,15 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
}
std::string message = result["session"].asString();
+
if ((message == "added") || (message == "created"))
added = true;
else if (message == "joined")
joined = true;
- else if ((message == "failed") || (message == "removed"))
+ else if ((message == "failed") || (message == "removed") || (message == "timeout"))
{ // we will get a removed message if a voice call is declined.
- if (message == "failed")
+ if (message == "failed")
{
int reason = result["reason"].asInteger();
LL_WARNS("Voice") << "Add and join failed for reason " << reason << LL_ENDL;
@@ -1230,7 +1253,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
if ((reason == ERROR_VIVOX_NOT_LOGGED_IN) ||
(reason == ERROR_VIVOX_OBJECT_NOT_FOUND))
{
- LL_INFOS("Voice") << "Requesting reprovision and login." << LL_ENDL;
+ LL_DEBUGS("Voice") << "Requesting reprovision and login." << LL_ENDL;
requestRelog();
}
@@ -1472,11 +1495,9 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
notifyParticipantObservers();
notifyVoiceFontObservers();
- LLSD timeoutEvent = LLSD::emptyMap();
- timeoutEvent["timeout"] = LLSD::Boolean(true);
+ LLSD timeoutEvent(LLSDMap("timeout", LLSD::Boolean(true)));
LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
- LLEventTimeout timeout(voicePump);
mIsInChannel = true;
mMuteMicDirty = true;
@@ -1528,8 +1549,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
sendLocalAudioUpdates();
mIsInitialized = true;
- timeout.eventAfter(UPDATE_THROTTLE_SECONDS, timeoutEvent);
- LLSD result = llcoro::suspendUntilEventOn(timeout);
+ LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, UPDATE_THROTTLE_SECONDS, timeoutEvent);
if (!result.has("timeout")) // logging the timeout event spams the log
LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
if (result.has("session"))
@@ -1627,22 +1647,19 @@ void LLVivoxVoiceClient::recordingAndPlaybackMode()
int LLVivoxVoiceClient::voiceRecordBuffer()
{
- LLSD timeoutResult;
- timeoutResult["recplay"] = LLSD::String("stop");
+ LLSD timeoutResult(LLSDMap("recplay", "stop"));
LL_INFOS("Voice") << "Recording voice buffer" << LL_ENDL;
LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
- LLEventTimeout timeout(voicePump);
- timeout.eventAfter(CAPTURE_BUFFER_MAX_TIME, timeoutResult);
LLSD result;
captureBufferRecordStartSendMessage();
-
notifyVoiceFontObservers();
+
do
{
- result = llcoro::suspendUntilEventOn(voicePump);
+ result = llcoro::suspendUntilEventOnWithTimeout(voicePump, CAPTURE_BUFFER_MAX_TIME, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
} while (!result.has("recplay"));
@@ -1660,14 +1677,11 @@ int LLVivoxVoiceClient::voiceRecordBuffer()
int LLVivoxVoiceClient::voicePlaybackBuffer()
{
- LLSD timeoutResult;
- timeoutResult["recplay"] = LLSD::String("stop");
+ LLSD timeoutResult(LLSDMap("recplay", "stop"));
LL_INFOS("Voice") << "Playing voice buffer" << LL_ENDL;
LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
- LLEventTimeout timeout(voicePump);
- timeout.eventAfter(CAPTURE_BUFFER_MAX_TIME, timeoutResult);
LLSD result;
do
@@ -1682,7 +1696,7 @@ int LLVivoxVoiceClient::voicePlaybackBuffer()
// Update UI, should really use a separate callback.
notifyVoiceFontObservers();
- result = llcoro::suspendUntilEventOn(voicePump);
+ result = llcoro::suspendUntilEventOnWithTimeout(voicePump, CAPTURE_BUFFER_MAX_TIME, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL;
} while (!result.has("recplay"));
@@ -2902,11 +2916,9 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu
session->mErrorStatusString = statusString;
if(session == mAudioSession)
{
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["handle"] = LLSD::String(sessionHandle);
- vivoxevent["session"] = LLSD::String("failed");
- vivoxevent["reason"] = LLSD::Integer(statusCode);
+ LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
+ ("session", "failed")
+ ("reason", LLSD::Integer(statusCode)));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
}
@@ -2923,10 +2935,8 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu
{
setSessionHandle(session, sessionHandle);
}
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["handle"] = LLSD::String(sessionHandle);
- vivoxevent["session"] = LLSD::String("created");
+ LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
+ ("session", "created"));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
}
@@ -2950,10 +2960,8 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId,
session->mErrorStatusString = statusString;
if(session == mAudioSession)
{
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["handle"] = LLSD::String(sessionHandle);
- vivoxevent["session"] = LLSD::String("failed");
+ LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
+ ("session", "failed"));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
}
@@ -2971,10 +2979,8 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId,
setSessionHandle(session, sessionHandle);
}
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["handle"] = LLSD::String(sessionHandle);
- vivoxevent["session"] = LLSD::String("added");
+ LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
+ ("session", "added"));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
@@ -3019,9 +3025,7 @@ void LLVivoxVoiceClient::logoutResponse(int statusCode, std::string &statusStrin
LL_WARNS("Voice") << "Account.Logout response failure: " << statusString << LL_ENDL;
// Should this ever fail? do we care if it does?
}
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["logout"] = LLSD::Boolean(true);
+ LLSD vivoxevent(LLSDMap("logout", LLSD::Boolean(true)));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
}
@@ -3036,9 +3040,7 @@ void LLVivoxVoiceClient::connectorShutdownResponse(int statusCode, std::string &
mConnected = false;
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["connector"] = LLSD::Boolean(false);
+ LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false)));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
}
@@ -3146,10 +3148,8 @@ void LLVivoxVoiceClient::joinedAudioSession(const sessionStatePtr_t &session)
// This is the session we're joining.
if(mIsJoiningSession)
{
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["handle"] = LLSD::String(session->mHandle);
- vivoxevent["session"] = LLSD::String("joined");
+ LLSD vivoxevent(LLSDMap("handle", LLSD::String(session->mHandle))
+ ("session", "joined"));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
@@ -3292,10 +3292,8 @@ void LLVivoxVoiceClient::leftAudioSession(const sessionStatePtr_t &session)
{
if (mAudioSession == session)
{
- LLSD vivoxevent = LLSD::emptyMap();
-
- vivoxevent["handle"] = LLSD::String(session->mHandle);
- vivoxevent["session"] = LLSD::String("removed");
+ LLSD vivoxevent(LLSDMap("handle", LLSD::String(session->mHandle))
+ ("session", "removed"));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
}
@@ -6150,9 +6148,7 @@ void LLVivoxVoiceClient::accountGetSessionFontsResponse(int statusCode, const st
{
// *TODO: We seem to get multiple events of this type. Should figure a way to advance only after
// receiving the last one.
- LLSD result = LLSD::emptyMap();
-
- result["voice_fonts"] = LLSD::Boolean(true);
+ LLSD result(LLSDMap("voice_fonts", LLSD::Boolean(true)));
LLEventPumps::instance().post("vivoxClientPump", result);
}
@@ -6325,8 +6321,7 @@ void LLVivoxVoiceClient::recordPreviewBuffer()
mCaptureBufferRecording = true;
- LLSD result;
- result["recplay"] = "record";
+ LLSD result(LLSDMap("recplay", "record"));
LLEventPumps::instance().post("vivoxClientPump", result);
}
@@ -6349,8 +6344,7 @@ void LLVivoxVoiceClient::playPreviewBuffer(const LLUUID& effect_id)
mPreviewVoiceFont = effect_id;
mCaptureBufferPlaying = true;
- LLSD result;
- result["recplay"] = "playback";
+ LLSD result(LLSDMap("recplay", "playback"));
LLEventPumps::instance().post("vivoxClientPump", result);
}
@@ -6359,8 +6353,7 @@ void LLVivoxVoiceClient::stopPreviewBuffer()
mCaptureBufferRecording = false;
mCaptureBufferPlaying = false;
- LLSD result;
- result["recplay"] = "quit";
+ LLSD result(LLSDMap("recplay", "quit"));
LLEventPumps::instance().post("vivoxClientPump", result);
}
diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml
index aad3b9d062..3e0f0133dd 100755
--- a/indra/newview/skins/default/xui/da/notifications.xml
+++ b/indra/newview/skins/default/xui/da/notifications.xml
@@ -1432,7 +1432,7 @@ Hvis du ikke forlader regionen, vil du blive logget af.
[MESSAGE]
-Fra objekt: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, ejer: [NAME]?
+Fra objekt: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, ejer: [NAME_SLURL]?
<form name="form">
<button name="Gotopage" text="Gå til side"/>
<button name="Cancel" text="Afbryd"/>
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index fa7db0a8a3..670d081faf 100755
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -2956,7 +2956,7 @@ Wenn Sie in dieser Region bleiben, werden Sie abgemeldet.
[MESSAGE]
-Von Objekt: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, Eigentümer: [NAME]
+Von Objekt: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, Eigentümer: [NAME_SLURL]
<form name="form">
<button name="Gotopage" text="Zur Seite"/>
<button name="Cancel" text="Abbrechen"/>
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index 384ae6bb1e..8391bacf51 100755
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -570,8 +570,7 @@
left="0"
top="0"
help_topic="land_covenant_tab"
- name="land_covenant_panel"
- word_wrap="true">
+ name="land_covenant_panel">
<panel.string
name="can_resell"
word_wrap="true">
@@ -1076,7 +1075,7 @@
name="Autoreturn"
top_pad="0"
width="412"
- wrap="true">
+ word_wrap="true">
Auto return other Residents&apos; objects (minutes, 0 for off):
</text>
<line_editor
@@ -1461,7 +1460,7 @@ Only large parcels can be listed in search.
top="150"
name="allow_label5"
width="205"
- wrap="true">
+ word_wrap="true">
Avatars on other parcels can see and chat with avatars on this parcel
</text>
<check_box
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 0c09906155..f8e346afb9 100755
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3580,6 +3580,19 @@ Do you really want to bake the current terrain, make it the center for terrain r
<notification
icon="alertmodal.tga"
+ name="ConfirmTextureHeights"
+ type="alertmodal">
+You're about to use low values greater than high ones for Elevation Ranges. Proceed?
+ <tag>confirm</tag>
+ <usetemplate
+ name="yesnocancelbuttons"
+ yestext="Ok"
+ notext="Cancel"
+ canceltext="Don't ask"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="MaxAllowedAgentOnRegion"
type="alertmodal">
You can only have [MAX_AGENTS] Allowed Residents.
@@ -3857,9 +3870,10 @@ We have downloaded an update to your [APP_NAME] installation.
</notification>
<notification
- icon="alertmodal.tga"
- name="RequiredUpdateDownloadedVerboseDialog"
- type="alertmodal">
+ icon="alertmodal.tga"
+ name="RequiredUpdateDownloadedVerboseDialog"
+ type="alertmodal"
+ force_urls_external="true">
We have downloaded a required software update.
Version [VERSION] [[INFO_URL] Information about this update]
@@ -3871,9 +3885,10 @@ We must restart [APP_NAME] to install the update.
</notification>
<notification
- icon="alertmodal.tga"
- name="RequiredUpdateDownloadedDialog"
- type="alertmodal">
+ icon="alertmodal.tga"
+ name="RequiredUpdateDownloadedDialog"
+ type="alertmodal"
+ force_urls_external="true">
We must restart [APP_NAME] to install the update.
[[INFO_URL] Information about this update]
<tag>confirm</tag>
@@ -3913,9 +3928,10 @@ see [[INFO_URL] Information about this update]
</notification>
<notification
- icon="alertmodal.tga"
- name="OtherChannelRequiredUpdateDownloadedVerboseDialog"
- type="alertmodal">
+ icon="alertmodal.tga"
+ name="OtherChannelRequiredUpdateDownloadedVerboseDialog"
+ type="alertmodal"
+ force_urls_external="true">
We have downloaded a required software update.
Version [VERSION]
This experimental viewer has been replaced by a [NEW_CHANNEL] viewer;
@@ -3929,9 +3945,10 @@ We must restart [APP_NAME] to install the update.
</notification>
<notification
- icon="alertmodal.tga"
- name="OtherChannelRequiredUpdateDownloadedDialog"
- type="alertmodal">
+ icon="alertmodal.tga"
+ name="OtherChannelRequiredUpdateDownloadedDialog"
+ type="alertmodal"
+ force_urls_external="true">
We must restart [APP_NAME] to install the update.
This experimental viewer has been replaced by a [NEW_CHANNEL] viewer;
see [[INFO_URL] Information about this update]
@@ -5975,6 +5992,18 @@ Are you sure you want to permanently delete the contents of your Trash?
<notification
icon="alertmodal.tga"
+ name="TrashIsFull"
+ type="alertmodal">
+Your trash is overflowing. This may cause problems logging in.
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="I will empty trash later"
+ yestext="Empty trash now"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="ConfirmClearBrowserCache"
type="alertmodal">
Are you sure you want to delete your travel, web, and search history?
@@ -7520,8 +7549,8 @@ Load web page [URL] ?
[MESSAGE]
-From object: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, owner: [NAME]
- <tag>confirm</tag>
+From object: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, owner: [NAME_SLURL]
+ <tag>confirm</tag>
<form name="form">
<button
index="0"
@@ -8261,6 +8290,16 @@ Are you sure you want to close all IMs?
name="AttachmentSaved" type="notifytip">
Attachment has been saved.
</notification>
+
+ <notification icon="notify.tga" persist="true"
+ name="AppearanceToXMLSaved" type="notify">
+Appearance has been saved to XML to [PATH]
+ </notification>
+
+ <notification icon="notifytip.tga"
+ name="AppearanceToXMLFailed" type="notifytip">
+Failed to save appearance to XML.
+ </notification>
<notification
icon="alertmodal.tga"
diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item.xml b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
index cfe3aeb7c9..e758a8ce30 100755
--- a/indra/newview/skins/default/xui/en/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
@@ -27,7 +27,7 @@
top="0"
visible="false"
width="320" />
- <icon
+ <group_icon
height="20"
image_name="Generic_Group"
name="group_icon"
diff --git a/indra/newview/skins/default/xui/en/panel_group_notify.xml b/indra/newview/skins/default/xui/en/panel_group_notify.xml
index cded4cf31a..4121acdfb0 100755
--- a/indra/newview/skins/default/xui/en/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notify.xml
@@ -27,7 +27,7 @@
name="header"
top="0"
width="305">
- <icon
+ <group_icon
follows="all"
height="20"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/en/panel_preferences_alerts.xml
index 714dca7fac..93c97ded25 100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_alerts.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_alerts.xml
@@ -21,12 +21,12 @@
Tell me:
</text>
<check_box
- control_name="NotifyMoneyChange"
+ control_name="NotifyMoneySpend"
height="16"
- label="When I spend or get L$"
+ label="When I spend L$"
layout="topleft"
left_delta="50"
- name="notify_money_change_checkbox"
+ name="notify_money_spend_checkbox"
top_pad="4"
width="300" />
<check_box
@@ -34,10 +34,18 @@
height="16"
label="When my friends log in or out"
layout="topleft"
- left_delta="0"
- name="friends_online_notify_checkbox"
- top_pad="4"
- width="300" />
+ left_delta="150"
+ name="friends_online_notify_checkbox"
+ width="300" />
+ <check_box
+ control_name="NotifyMoneyReceived"
+ height="16"
+ label="When I get L$"
+ layout="topleft"
+ left_delta="-150"
+ top_pad="4"
+ name="notify_money_received_checkbox"
+ width="300" />
<text
type="string"
length="1"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 6c485c0595..e1b8662ece 100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -619,6 +619,7 @@
height="16"
increment="0.125"
initial_value="160"
+ min_val="0.125"
label=" Trees:"
label_width="185"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/role_actions.xml b/indra/newview/skins/default/xui/en/role_actions.xml
index c2e7c706d6..4d20ecb9b6 100755
--- a/indra/newview/skins/default/xui/en/role_actions.xml
+++ b/indra/newview/skins/default/xui/en/role_actions.xml
@@ -105,9 +105,6 @@
<action description="Always allow &apos;Create Objects&apos;"
longdescription="Members in a Role with this Ability can create objects on a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab."
name="land allow create" value="25" />
- <action description="Always allow &apos;Create Landmark&apos;"
- longdescription="Members in a Role with this Ability can landmark a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab."
- name="land allow landmark" value="26" />
<action description="Allow &apos;Set Home to Here&apos; on group land"
longdescription="Members in a Role with this Ability can use World menu &gt; Landmarks &gt; Set Home to Here on a parcel deeded to this group."
name="land allow set home" value="28" />
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index f2eddbb38e..ff98d2f109 100755
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3530,6 +3530,8 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="IM_unblock_only_groups_friends">To see this message, you must uncheck &apos;Only friends and groups can call or IM me&apos; in Preferences/Privacy.</string>
<string name="OnlineStatus">Online</string>
<string name="OfflineStatus">Offline</string>
+ <string name="not_online_msg">User not online - message will be stored and delivered later.</string>
+ <string name="not_online_inventory">User not online - inventory has been saved.</string>
<!-- voice calls -->
<string name="answered_call">Your call has been answered</string>
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index 1e367b33fc..2aac4458e3 100755
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -2950,7 +2950,7 @@ Si permaneces en esta región serás desconectado.
[MESSAGE]
-Del objeto: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, propietario: [NAME]
+Del objeto: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, propietario: [NAME_SLURL]
<form name="form">
<button name="Gotopage" text="Cargar"/>
<button name="Cancel" text="Cancelar"/>
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index 29e6fe1979..55a67e1187 100755
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -2942,7 +2942,7 @@ Si vous restez dans cette région, vous serez déconnecté(e).
[MESSAGE]
-Venant de l&apos;objet : &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, propriétaire : [NAME]
+Venant de l&apos;objet : &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, propriétaire : [NAME_SLURL]
<form name="form">
<button name="Gotopage" text="Charger"/>
<button name="Cancel" text="Annuler"/>
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index 61131b09c3..6aeabcc505 100755
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -2947,7 +2947,7 @@ Se rimani qui verrai scollegato da Second Life.
[MESSAGE]
-Dall&apos;oggetto: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, proprietario: [NAME]
+Dall&apos;oggetto: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, proprietario: [NAME_SLURL]
<form name="form">
<button name="Gotopage" text="Caricare"/>
<button name="Cancel" text="Annulla"/>
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index 5f0ce7a73b..b3b4e06a68 100755
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -2990,7 +2990,7 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ
[MESSAGE]
-送信元のオブジェクト:&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;、所有者:[NAME]
+送信元のオブジェクト:&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;、所有者:[NAME_SLURL]
<form name="form">
<button name="Gotopage" text="ページに移動"/>
<button name="Cancel" text="取り消し"/>
diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml
index c4a65d92b4..25cc43a6e3 100755
--- a/indra/newview/skins/default/xui/pl/notifications.xml
+++ b/indra/newview/skins/default/xui/pl/notifications.xml
@@ -2493,7 +2493,7 @@ Nastąpi wylogowanie jeżeli zostaniesz w tym regionie.
[MESSAGE]
-Od obiektu: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, właściciel właściciel: [NAME]?
+Od obiektu: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, właściciel właściciel: [NAME_SLURL]?
<form name="form">
<button name="Gotopage" text="Załaduj"/>
<button name="Cancel" text="Anuluj"/>
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index a264495404..3a3603307e 100755
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -2931,7 +2931,7 @@ Se permanecer aqui, você será desconectado.
[MESSAGE]
-Do objeto: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, de: [NAME]
+Do objeto: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, de: [NAME_SLURL]
<form name="form">
<button name="Gotopage" text="Carregar"/>
<button name="Cancel" text="Cancelar"/>
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index 70b9a25590..7b024926e2 100755
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -2942,7 +2942,7 @@ http://secondlife.com/download.
[MESSAGE]
-Из объекта: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, владелец: [NAME]
+Из объекта: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, владелец: [NAME_SLURL]
<form name="form">
<button name="Gotopage" text="Перейти на страницу"/>
<button name="Cancel" text="Отмена"/>
diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml
index 0d64b2cae9..18ae202230 100755
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -4223,6 +4223,12 @@ support@secondlife.com.
<string name="OfflineStatus">
Оффлайн
</string>
+ <string name="not_online_msg">
+ Пользователь оффлайн - сообщение будет сохранено и доставлено позже.
+ </string>
+ <string name="not_online_inventory">
+ Пользователь оффлайн - инвентарь сохранен.
+ </string>
<string name="answered_call">
На ваш звонок ответили
</string>
diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml
index df22251b3d..9875399b34 100755
--- a/indra/newview/skins/default/xui/tr/notifications.xml
+++ b/indra/newview/skins/default/xui/tr/notifications.xml
@@ -2942,7 +2942,7 @@ Bu bölgede kalmaya devam ederseniz oturumunuz sonlandırılacak.
[MESSAGE]
-Kaynak nesne: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, sahibi: [NAME]
+Kaynak nesne: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, sahibi: [NAME_SLURL]
<form name="form">
<button name="Gotopage" text="Sayfaya git"/>
<button name="Cancel" text="İptal"/>
diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml
index 0a98101b60..371f5d9b39 100755
--- a/indra/newview/skins/default/xui/zh/notifications.xml
+++ b/indra/newview/skins/default/xui/zh/notifications.xml
@@ -2932,7 +2932,7 @@ SHA1 指紋:[MD5_DIGEST]
[MESSAGE]
-來源物件:&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;(所有人:[NAME])
+來源物件:&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;(所有人:[NAME_SLURL])
<form name="form">
<button name="Gotopage" text="前往頁面"/>
<button name="Cancel" text="取消"/>