diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake
index 25c92bfd4b..6ac5cf3fc2 100644
--- a/indra/cmake/Python.cmake
+++ b/indra/cmake/Python.cmake
@@ -5,23 +5,32 @@ set(PYTHONINTERP_FOUND)
if (WINDOWS)
# On Windows, explicitly avoid Cygwin Python.
- find_program(PYTHON_EXECUTABLE
- NAMES python25.exe python23.exe python.exe
- NO_DEFAULT_PATH # added so that cmake does not find cygwin python
- PATHS
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.8\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.8\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath]
- )
+ if (DEFINED ENV{VIRTUAL_ENV})
+ find_program(PYTHON_EXECUTABLE
+ NAMES python.exe
+ PATHS
+ "$ENV{VIRTUAL_ENV}\\scripts"
+ NO_DEFAULT_PATH
+ )
+ else()
+ find_program(PYTHON_EXECUTABLE
+ NAMES python25.exe python23.exe python.exe
+ NO_DEFAULT_PATH # added so that cmake does not find cygwin python
+ PATHS
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.8\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.8\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath]
+ )
+ endif()
elseif (EXISTS /etc/debian_version)
# On Debian and Ubuntu, avoid Python 2.4 if possible.
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 49bbeb010f..2615b18a82 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -3530,6 +3530,14 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
if (node->hasName("multi_floater"))
{
LLFloater::setFloaterHost((LLMultiFloater*) this);
+
+ // MultiFloater without titlebar for hosted floater
+ BOOL show_titlebar;
+ if (node->getAttributeBOOL("hosted_floater_show_titlebar", show_titlebar))
+ {
+ static_cast(this)->setHostedFloaterShowtitlebar(show_titlebar);
+ }
+ //
}
LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node);
diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp
index 3a4371bfd7..3e7488c947 100644
--- a/indra/llui/llmultifloater.cpp
+++ b/indra/llui/llmultifloater.cpp
@@ -37,16 +37,23 @@
// LLMultiFloater
//
-// Update torn off status and add title bar
-static const std::string IM_CONTAINER = "floater_im_box";
+// MultiFloater without titlebar for hosted floater
+//static
+const LLMultiFloater::Params& LLMultiFloater::getDefaultParams()
+{
+ return LLUICtrlFactory::getDefaultParams();
+}
-LLMultiFloater::LLMultiFloater(const LLSD& key, const LLFloater::Params& params)
+//LLMultiFloater::LLMultiFloater(const LLSD& key, const LLFloater::Params& params)
+LLMultiFloater::LLMultiFloater(const LLSD& key, const Params& params)
+//
: LLFloater(key),
mTabContainer(NULL),
mTabPos(LLTabContainer::TOP),
mAutoResize(TRUE),
mOrigMinWidth(params.min_width),
- mOrigMinHeight(params.min_height)
+ mOrigMinHeight(params.min_height),
+ mHostedFloaterShowtitlebar(params.hosted_floater_show_titlebar) // MultiFloater without titlebar for hosted floater
{
}
@@ -203,7 +210,7 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,
floaterp->setBackgroundVisible(FALSE);
// Update torn off status and add title bar; Do this AFTER we stored the original rect!
- if (getName() == IM_CONTAINER)
+ if (!mHostedFloaterShowtitlebar)
{
floaterp->getDragHandle()->setTitleVisible(FALSE);
LLRect rect = floaterp->getRect();
@@ -256,7 +263,7 @@ void LLMultiFloater::updateFloaterTitle(LLFloater* floaterp)
// If the tab we're updating is the current tab, then
// update the overall title too, since we're showing it
// exclusively now.
- if (getName() == IM_CONTAINER && floaterp == mTabContainer->getCurrentPanel())
+ if (!mHostedFloaterShowtitlebar && floaterp == mTabContainer->getCurrentPanel())
{
mDragHandle->setTitle(mTitle.getString() + " - " + floaterp->getTitle());
}
@@ -310,7 +317,7 @@ void LLMultiFloater::removeFloater(LLFloater* floaterp)
return;
// Update torn off status and add title bar
- if (getName() == IM_CONTAINER)
+ if (!mHostedFloaterShowtitlebar)
{
floaterp->getDragHandle()->setTitleVisible(TRUE);
LLRect rect = floaterp->getRect();
@@ -477,7 +484,7 @@ void LLMultiFloater::onTabSelected()
{
tabOpen(floaterp, true);
// Update torn off status and add title bar
- if (getName() == IM_CONTAINER)
+ if (!mHostedFloaterShowtitlebar)
{
mDragHandle->setTitle(mTitle.getString() + " - " + floaterp->getTitle());
}
diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h
index b9e2abed19..70da0ac053 100644
--- a/indra/llui/llmultifloater.h
+++ b/indra/llui/llmultifloater.h
@@ -38,6 +38,20 @@
class LLMultiFloater : public LLFloater
{
public:
+ // MultiFloater without titlebar for hosted floater
+ struct Params
+ : public LLInitParam::Block
+ {
+ Optional hosted_floater_show_titlebar;
+
+ Params() :
+ hosted_floater_show_titlebar("hosted_floater_show_titlebar", true)
+ {}
+ };
+
+ static const Params& getDefaultParams();
+ //
+
LLMultiFloater(const LLSD& key, const Params& params = getDefaultParams());
virtual ~LLMultiFloater() {};
@@ -82,6 +96,9 @@ public:
// CTRL-W doesn't work with multifloaters
void closeDockedFloater();
+ // MultiFloater without titlebar for hosted floater
+ void setHostedFloaterShowtitlebar(bool show) { mHostedFloaterShowtitlebar = show; }
+
protected:
struct LLFloaterData
{
@@ -101,6 +118,9 @@ protected:
BOOL mAutoResize;
S32 mOrigMinWidth, mOrigMinHeight; // logically const but initialized late
+ // MultiFloater without titlebar for hosted floater
+ bool mHostedFloaterShowtitlebar;
+
private:
virtual void computeResizeLimits(S32& new_min_width, S32& new_min_height);
};
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index ea2b0ec580..1f77c53542 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2152,14 +2152,22 @@ if (WINDOWS)
windows-crash-logger
)
-
if (FMODSTUDIO)
- list(APPEND COPY_INPUT_DEPENDENCIES
+ if (ADDRESS_SIZE EQUAL 64)
+ list(APPEND COPY_INPUT_DEPENDENCIES
+ ${SHARED_LIB_STAGING_DIR}/Release/fmod64.dll
+ ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmod64.dll
+ ${SHARED_LIB_STAGING_DIR}/Debug/fmodL64.dll
+ )
+ else (ADDRESS_SIZE EQUAL 64)
+ list(APPEND COPY_INPUT_DEPENDENCIES
${SHARED_LIB_STAGING_DIR}/Release/fmod.dll
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmod.dll
${SHARED_LIB_STAGING_DIR}/Debug/fmodL.dll
)
+ endif (ADDRESS_SIZE EQUAL 64)
endif (FMODSTUDIO)
+
if (FMODEX)
list(APPEND COPY_INPUT_DEPENDENCIES
${SHARED_LIB_STAGING_DIR}/Release/fmodex.dll
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 4be1780b27..9b13d5b22f 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -988,7 +988,7 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
if ( (pItem) &&
( ((LLAssetType::AT_NOTECARD == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE))) ||
((LLAssetType::AT_LSL_TEXT == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT))) ||
- ((LLAssetType::AT_TEXTURE == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE))) ) )
+ ((LLAssetType::AT_TEXTURE == pItem->getType()) && (!RlvActions::canPreviewTextures()))))
{
disabled_items.push_back(std::string("Open"));
}
@@ -3999,7 +3999,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
}
// [RLVa:KB] - Checked: RLVa-2.1.0
- if ( ((item) && (!RlvActions::canPaste(item, dest_folder))) || ((cat) && (!RlvActions::canPaste(cat, dest_folder))) )
+ if ( ((item) && (!RlvActions::canPasteInventory(item, dest_folder))) || ((cat) && (!RlvActions::canPasteInventory(cat, dest_folder))) )
{
RlvActions::notifyBlocked(RLV_STRING_BLOCKED_INVFOLDER);
return;
@@ -4369,6 +4369,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
{
disabled_items.push_back(std::string("Delete"));
}
+
+ // FIRE-4595: Paste as Link missing for outfit folders
+ items.push_back(std::string("Paste As Link"));
+ if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ disabled_items.push_back(std::string("Paste As Link"));
+ }
+ //
}
}
@@ -5696,6 +5704,13 @@ bool LLTextureBridge::canSaveTexture(void)
return false;
}
+// [RLVa:KB] - Checked: RLVa-2.2
+ if (!RlvActions::canPreviewTextures())
+ {
+ return false;
+ }
+// [/RLVa:KB]
+
const LLViewerInventoryItem *item = model->getItem(mUUID);
if (item)
{
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index f1dc79c7a6..b91b0c46fb 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -67,6 +67,7 @@
#include "llviewerobjectlist.h"
#include "llviewermessage.h"
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
+#include "rlvactions.h"
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
@@ -767,7 +768,7 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
bool fLocked = (pAttachObj) ? gRlvAttachmentLocks.isLockedAttachment(pAttachObj->getRootEdit()) : false;
if ( ((LLAssetType::AT_NOTECARD == item->getType()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) || (fLocked))) ||
((LLAssetType::AT_LSL_TEXT == item->getType()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT)) || (fLocked))) ||
- ((LLAssetType::AT_TEXTURE == item->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE))) )
+ ((LLAssetType::AT_TEXTURE == item->getType()) && (!RlvActions::canPreviewTextures())))
{
disabled_items.push_back(std::string("Task Open"));
}
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 04945f8490..49b75d669b 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -2653,6 +2653,28 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
LLVector3d old_pos_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos); // Re-fetch in case it got clipped above
+ // FIRE-21915: Fix bogus avatar movement on region crossing
+ // Clip new_pos to current region. Moves across region boundaries should not be extrapolated.
+ // Extrapolation across region boundaries is almost always wrong, and if the region being
+ // entered is slow to respond, very wrong.
+ // Probably don't need edge of world check below any more since we are clipping the predictor to the region.
+ bool clipped; // true if clipped at boundary
+ LLVector3d clip_pos_global_region = LLWorld::getInstance()->clipToRegion(mRegionp,old_pos_global, new_pos_global, clipped);
+ if (clipped)
+ {
+ // Was clipped, so we crossed a region boundary
+ //LL_INFOS() << "Beyond region edge, clipped predicted position to " << mRegionp->getPosRegionFromGlobal(clip_pos_global_region)
+ // << " from [" << getPositionRegion() << " .. " << new_pos << "]" << LL_ENDL;
+ new_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global_region);
+ // Don't zero out velocity on the server. Telling the server affects scripts and audio.
+ //new_v.clear();
+ //setAcceleration(LLVector3::zero); // stop linear acceleration
+ LLVector3 new_angv;
+ new_angv.clear();
+ setAngularVelocity(new_angv); // stop rotation
+ }
+ //
+
// Clip the positions to known regions
LLVector3d clip_pos_global = LLWorld::getInstance()->clipToVisibleRegions(old_pos_global, new_pos_global);
if (clip_pos_global != new_pos_global)
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index c15cab4183..3392a75a2d 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -774,10 +774,26 @@ LLVector3d LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVe
}
LLViewerRegion* regionp = getRegionFromPosGlobal(start_pos);
- if (!regionp)
+// FIRE-21915: Fix bogus avatar movement on region crossing
+ //if (!regionp)
+ //{
+ // return start_pos;
+ //}
+ bool clipped = false; // sink, unused
+ return clipToRegion(regionp, start_pos, end_pos, clipped); // use common fn for clipping to region
+}
+
+// Clip to region, using a point along the line start_pos .. end_pos.
+// If start_pos is outside the region, use start_pos.
+LLVector3d LLWorld::clipToRegion(const LLViewerRegion* regionp, const LLVector3d &start_pos, const LLVector3d &end_pos, bool &clipped)
+{
+ clipped = false; // no clipping yet
+ if (!regionp) // no region. We're lost
{
+ clipped = true; // very bad
return start_pos;
}
+//
LLVector3d delta_pos = end_pos - start_pos;
LLVector3d delta_pos_abs;
@@ -785,8 +801,21 @@ LLVector3d LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVe
delta_pos_abs.abs();
LLVector3 region_coord = regionp->getPosRegionFromGlobal(end_pos);
- F64 clip_factor = 1.0;
+ // FIRE-21915: Fix bogus avatar movement on region crossing
+ //F64 clip_factor = 1.0;
+ LLVector3 region_coord_start = regionp->getPosRegionFromGlobal(start_pos);
+ F64 clip_factor = 0.0; // zero means no cli
+ //
F32 region_width = regionp->getWidth();
+ // FIRE-21915: Fix bogus avatar movement on region crossing
+ if (region_coord_start.mV[VX] < 0.f || region_coord_start.mV[VX] > region_width
+ || region_coord_start.mV[VY] < 0.f || region_coord_start.mV[VY] > region_width)
+ {
+ clip_factor = 1.0; // start pos outside region, use start pos
+ }
+ else // clip to region along line from start pos to end po
+ {
+ //
if (region_coord.mV[VX] < 0.f)
{
if (region_coord.mV[VY] < region_coord.mV[VX])
@@ -823,15 +852,38 @@ LLVector3d LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVe
// clip along y +
clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY];
}
+ // FIRE-21915: Fix bogus avatar movement on region crossing
+ if (!std::isfinite(clip_factor)) { clip_factor = 0.0; } // avoid NaN problems
+ clip_factor = llclamp(clip_factor, 0.0, 1.0); // avoid overflow problem
+ }
+ //
- // clamp to within region dimensions
+ // FIRE-21915: Fix bogus avatar movement on region crossing
+ //// clamp to within region dimensions
+ //LLVector3d final_region_pos = LLVector3d(region_coord) - (delta_pos * clip_factor);
+ //final_region_pos.mdV[VX] = llclamp(final_region_pos.mdV[VX], 0.0,
+ // (F64)(region_width - F_ALMOST_ZERO));
+ //final_region_pos.mdV[VY] = llclamp(final_region_pos.mdV[VY], 0.0,
+ // (F64)(region_width - F_ALMOST_ZERO));
+ //final_region_pos.mdV[VZ] = llclamp(final_region_pos.mdV[VZ], 0.0,
+ // (F64)(LLWorld::getInstance()->getRegionMaxHeight() - F_ALMOST_ZERO));
+
+ // True if clipped. Caller needs to know, because it will kill velocity if there's clipping
+ // Don't do this by comparing floating point numbers for equality. That has roundoff problems.
+ clipped = clip_factor > F_ALMOST_ZERO; // clipped in X or Y
LLVector3d final_region_pos = LLVector3d(region_coord) - (delta_pos * clip_factor);
- final_region_pos.mdV[VX] = llclamp(final_region_pos.mdV[VX], 0.0,
- (F64)(region_width - F_ALMOST_ZERO));
- final_region_pos.mdV[VY] = llclamp(final_region_pos.mdV[VY], 0.0,
- (F64)(region_width - F_ALMOST_ZERO));
+ clipped |= final_region_pos.mdV[VX] < -F_ALMOST_ZERO || final_region_pos.mdV[VX] > (F64)(region_width - F_ALMOST_ZERO);
+ clipped |= final_region_pos.mdV[VY] < -F_ALMOST_ZERO || final_region_pos.mdV[VY] > (F64)(region_width - F_ALMOST_ZERO);
+ clipped |= final_region_pos.mdV[VZ] < -F_ALMOST_ZERO || final_region_pos.mdV[VZ] > (F64)(LLWorld::getInstance()->getRegionMaxHeight() - F_ALMOST_ZERO); // if actually clipping
+ // Final sanity check - don't allow positions more than clamp_range out of region.
+ F64 clamp_range = region_width / 2.0; // half a region width
+ final_region_pos.mdV[VX] = llclamp(final_region_pos.mdV[VX], -clamp_range,
+ (F64)(region_width + clamp_range));
+ final_region_pos.mdV[VY] = llclamp(final_region_pos.mdV[VY], -clamp_range,
+ (F64)(region_width + clamp_range));
final_region_pos.mdV[VZ] = llclamp(final_region_pos.mdV[VZ], 0.0,
(F64)(LLWorld::getInstance()->getRegionMaxHeight() - F_ALMOST_ZERO));
+ //
return regionp->getPosGlobalFromRegion(LLVector3(final_region_pos));
}
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index aff8e4aa45..43ba91b8c6 100644
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -84,6 +84,7 @@ public:
LLViewerRegion* getRegionFromID(const LLUUID& region_id);
BOOL positionRegionValidGlobal(const LLVector3d& pos); // true if position is in valid region
LLVector3d clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos);
+ LLVector3d clipToRegion(const LLViewerRegion* regionp, const LLVector3d &start_pos, const LLVector3d &end_pos, bool &clipped); // clip to specified region // FIRE-21915: Fix bogus avatar movement on region crossing
void updateAgentOffset(const LLVector3d &offset);
diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp
index 0eb0f41ab3..95c17a5f6a 100644
--- a/indra/newview/rlvactions.cpp
+++ b/indra/newview/rlvactions.cpp
@@ -184,7 +184,7 @@ bool RlvActions::canSendIM(const LLUUID& idRecipient)
( (!gRlvHandler.hasBehaviour(RLV_BHVR_SENDIMTO)) || (!gRlvHandler.isException(RLV_BHVR_SENDIMTO, idRecipient)) ) );
}
-bool RlvActions::canStartIM(const LLUUID& idRecipient)
+bool RlvActions::canStartIM(const LLUUID& idRecipient, bool fIgnoreOpen)
{
// User can start an IM session with "recipient" (could be an agent or a group) if:
// - not generally restricted from starting IM sessions (or the recipient is an exception or inside the exclusion range)
@@ -194,7 +194,7 @@ bool RlvActions::canStartIM(const LLUUID& idRecipient)
(!isRlvEnabled()) ||
( ( (!gRlvHandler.hasBehaviour(RLV_BHVR_STARTIM)) || (gRlvHandler.isException(RLV_BHVR_STARTIM, idRecipient)) || (rlvCheckAvatarIMDistance(idRecipient, RLV_MODIFIER_STARTIMDISTMIN, RLV_MODIFIER_STARTIMDISTMAX)) ) &&
( (!gRlvHandler.hasBehaviour(RLV_BHVR_STARTIMTO)) || (!gRlvHandler.isException(RLV_BHVR_STARTIMTO, idRecipient)) ) ) ||
- ( (hasOpenP2PSession(idRecipient)) || (hasOpenGroupSession(idRecipient)) );
+ ( (!fIgnoreOpen) && ((hasOpenP2PSession(idRecipient)) || (hasOpenGroupSession(idRecipient))) );
}
bool RlvActions::canShowName(EShowNamesContext eContext, const LLUUID& idAgent)
@@ -250,7 +250,7 @@ EChatType RlvActions::checkChatVolume(EChatType chatType)
// Inventory
//
-bool RlvActions::canPaste(const LLInventoryCategory* pSourceCat, const LLInventoryCategory* pDestCat)
+bool RlvActions::canPasteInventory(const LLInventoryCategory* pSourceCat, const LLInventoryCategory* pDestCat)
{
// The user can paste the specified object into the destination if:
// - the source and destination are subject to the same lock type (or none at all) => NOTE: this happens to be the same logic we use for moving
@@ -258,7 +258,7 @@ bool RlvActions::canPaste(const LLInventoryCategory* pSourceCat, const LLInvento
( (pSourceCat) && (pDestCat) && ((!RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().canMoveFolder(pSourceCat->getUUID(), pDestCat->getUUID()))) );
}
-bool RlvActions::canPaste(const LLInventoryItem* pSourceItem, const LLInventoryCategory* pDestCat)
+bool RlvActions::canPasteInventory(const LLInventoryItem* pSourceItem, const LLInventoryCategory* pDestCat)
{
// The user can paste the specified object into the destination if:
// - the source and destination are subject to the same lock type (or none at all) => NOTE: this happens to be the same logic we use for moving
@@ -266,6 +266,11 @@ bool RlvActions::canPaste(const LLInventoryItem* pSourceItem, const LLInventoryC
( (pSourceItem) && (pDestCat) && ((!RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().canMoveItem(pSourceItem->getUUID(), pDestCat->getUUID()))) );
}
+bool RlvActions::canPreviewTextures()
+{
+ return (!gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE));
+}
+
// ============================================================================
// Movement
//
diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h
index 1e094fd3f1..afafa726b8 100644
--- a/indra/newview/rlvactions.h
+++ b/indra/newview/rlvactions.h
@@ -108,9 +108,9 @@ public:
static bool canSendIM(const LLUUID& idRecipient);
/*
- * Returns true if the user is allowed to start a - P2P or group - conversation with the specified UUID (or if the session already exists)
+ * Returns true if the user is allowed to start a - P2P or group - conversation with the specified UUID (or if the session already exists, unless 'ignore open' is specified)
*/
- static bool canStartIM(const LLUUID& idRecipient);
+ static bool canStartIM(const LLUUID& idRecipient, bool fIgnoreOpen = false);
/*
* Returns true if an avatar's name should be hidden for the requested operation/context
@@ -142,8 +142,13 @@ public:
/*
* Returns true if the user is allowed to paste the specified inventory object (item/folder) into the specified destination category (within user inventory)
*/
- static bool canPaste(const LLInventoryCategory* pSourceCat, const LLInventoryCategory* pDestCat);
- static bool canPaste(const LLInventoryItem* pSourceItem, const LLInventoryCategory* pDestCat);
+ static bool canPasteInventory(const LLInventoryCategory* pSourceCat, const LLInventoryCategory* pDestCat);
+ static bool canPasteInventory(const LLInventoryItem* pSourceItem, const LLInventoryCategory* pDestCat);
+
+ /*
+ * Returns true if the user can open the inventory floater for (user/library/notecard/object)inventory based textures
+ */
+ static bool canPreviewTextures();
// ========
// Movement
@@ -232,26 +237,26 @@ public:
static bool canShowHoverText(const LLViewerObject* pObj);
/*
- * Returns true if the user can touch the specified object (with an optional offset relative to its center)
+ * Returns true if the user can sit on the specified object (see canGroundSit() for sitting on land)
*/
- static bool canTouch(const LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero);
+ static bool canSit(const LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero);
/*
* Returns true if the user can see their in-world location
*/
static bool canShowLocation();
- /*
- * Returns true if the user can sit on the specified object (see canGroundSit() for sitting on land)
- */
- static bool canSit(const LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero);
-
/*
* Returns true if the user can stand up (returns true if the user isn't currently sitting)
*/
static bool canStand();
static bool canStand(const LLUUID& idRlvObjExcept);
+ /*
+ * Returns true if the user can touch the specified object (with an optional offset relative to its center)
+ */
+ static bool canTouch(const LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero);
+
// ================
// Helper functions
// ================
diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp
index ff26494b65..a50761cf19 100644
--- a/indra/newview/rlvcommon.cpp
+++ b/indra/newview/rlvcommon.cpp
@@ -551,14 +551,17 @@ bool RlvUtil::isNearbyRegion(const std::string& strRegion)
}
// Checked: 2011-04-11 (RLVa-1.3.0h) | Modified: RLVa-1.3.0h
-void RlvUtil::notifyBlocked(const std::string& strNotifcation, const LLSD& sdArgs)
+void RlvUtil::notifyBlocked(const std::string& strNotifcation, const LLSD& sdArgs, bool fLogToChat)
{
std::string strMsg = RlvStrings::getString(strNotifcation);
LLStringUtil::format(strMsg, sdArgs);
LLSD sdNotify;
sdNotify["MESSAGE"] = strMsg;
- LLNotificationsUtil::add("SystemMessageTip", sdNotify);
+ if (!fLogToChat)
+ LLNotificationsUtil::add("SystemMessageTip", sdNotify);
+ else
+ LLNotificationsUtil::add("ChatSystemMessageTip", sdNotify);
}
// Checked: 2010-11-11 (RLVa-1.2.1g) | Added: RLVa-1.2.1g
diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h
index ab635aaac3..0374825346 100644
--- a/indra/newview/rlvcommon.h
+++ b/indra/newview/rlvcommon.h
@@ -176,7 +176,7 @@ public:
static bool isForceTp() { return m_fForceTp; }
static void forceTp(const LLVector3d& posDest); // Ignores restrictions that might otherwise prevent tp'ing
- static void notifyBlocked(const std::string& strNotifcation, const LLSD& sdArgs = LLSD());
+ static void notifyBlocked(const std::string& strNotifcation, const LLSD& sdArgs = LLSD(), bool fLogToChat = false);
static void notifyBlockedGeneric() { notifyBlocked(RLV_STRING_BLOCKED_GENERIC); }
static void notifyBlockedViewXXX(LLAssetType::EType assetType) { notifyBlocked(RLV_STRING_BLOCKED_VIEWXXX, LLSD().with("[TYPE]", LLTrans::getString(LLAssetType::lookupHumanReadable(assetType)))); }
static void notifyFailedAssertion(const std::string& strAssert, const std::string& strFile, int nLine);
diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp
index 31420d4d24..4c3a95adf9 100644
--- a/indra/newview/rlvhandler.cpp
+++ b/indra/newview/rlvhandler.cpp
@@ -482,16 +482,19 @@ bool RlvHandler::processIMQuery(const LLUUID& idSender, const std::string& strMe
{
if ("@stopim" == strMessage)
{
- // If the user can't start an IM session and one is open terminate it - always notify the sender in this case
- if ( (!RlvActions::canStartIM(idSender)) && (RlvActions::hasOpenP2PSession(idSender)) )
+ // If the user can't start an IM session terminate it (if one is open) - always notify the sender in this case
+ if (!RlvActions::canStartIM(idSender, true))
{
RlvUtil::sendBusyMessage(idSender, RlvStrings::getString(RLV_STRING_STOPIM_ENDSESSION_REMOTE));
- LLAvatarActions::endIM(idSender);
- RlvUtil::notifyBlocked(RLV_STRING_STOPIM_ENDSESSION_LOCAL, LLSD().with("NAME", LLSLURL("agent", idSender, "about").getSLURLString()));
+ if (RlvActions::hasOpenP2PSession(idSender))
+ {
+ LLAvatarActions::endIM(idSender);
+ RlvUtil::notifyBlocked(RLV_STRING_STOPIM_ENDSESSION_LOCAL, LLSD().with("NAME", LLSLURL("agent", idSender, "about").getSLURLString()), true);
+ }
return true;
}
- // User can start an IM session (or one isn't open) so we do nothing - notify and hide it from the user only if IM queries are enabled
+ // User can start an IM session so we do nothing - notify and hide it from the user only if IM queries are enabled
if (!RlvSettings::getEnableIMQuery())
return false;
RlvUtil::sendBusyMessage(idSender, RlvStrings::getString(RLV_STRING_STOPIM_NOSESSION));
@@ -2577,9 +2580,10 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd)
LLViewerObject* pObj = NULL;
if (idTarget.isNull())
{
- if (!RlvActions::canGroundSit())
+ if ( (!RlvActions::canGroundSit()) || ((isAgentAvatarValid()) && (gAgentAvatarp->isSitting())) )
return RLV_RET_FAILED_LOCK;
gAgent.sitDown();
+ send_agent_update(TRUE, TRUE);
}
else if ( ((pObj = gObjectList.findObject(idTarget)) != NULL) && (LL_PCODE_VOLUME == pObj->getPCode()))
{
@@ -2588,7 +2592,7 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd)
if ((gRlvHandler.hasBehaviour(RLV_BHVR_STANDTP)) && (isAgentAvatarValid()))
{
- if (gAgentAvatarp->isSitting())
+ if ( (isAgentAvatarValid()) && (gAgentAvatarp->isSitting()) )
return RLV_RET_FAILED_LOCK;
gRlvHandler.m_posSitSource = gAgent.getPositionGlobal();
}
diff --git a/indra/newview/skins/default/xui/en/floater_fs_im_container.xml b/indra/newview/skins/default/xui/en/floater_fs_im_container.xml
index bb4f0dc1e8..a0ebae99f4 100644
--- a/indra/newview/skins/default/xui/en/floater_fs_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_fs_im_container.xml
@@ -4,6 +4,7 @@
can_minimize="true"
can_resize="true"
height="390"
+ hosted_floater_show_titlebar="false"
layout="topleft"
name="floater_im_box"
save_rect="true"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 7c2415bfdc..c3de954438 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6699,6 +6699,14 @@ URL: [AUDIOURL]
[MESSAGE]
+
+[MESSAGE]
+
+