diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 43b35877b5..ac962c6d03 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -1596,9 +1596,10 @@ BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num ) delete_and_clear_array(mCollisionVolumes); mNumCollisionVolumes = 0; - mCollisionVolumes = new LLAvatarJointCollisionVolume[num]; + mCollisionVolumes = new(std::nothrow) LLAvatarJointCollisionVolume[num]; if (!mCollisionVolumes) { + LL_WARNS() << "Failed to allocate collision volumes" << LL_ENDL; return FALSE; } diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index 056a4425e1..050674395a 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -582,8 +582,15 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact else { anim_file_size = anim_file->getSize(); - anim_data = new U8[anim_file_size]; - success = anim_file->read(anim_data, anim_file_size); /*Flawfinder: ignore*/ + anim_data = new(std::nothrow) U8[anim_file_size]; + if (anim_data) + { + success = anim_file->read(anim_data, anim_file_size); /*Flawfinder: ignore*/ + } + else + { + LL_WARNS() << "Failed to allocate buffer: " << anim_file_size << mID << LL_ENDL; + } delete anim_file; anim_file = NULL; } diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 3e4c4917a8..4d73533797 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -906,7 +906,7 @@ void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components) bool LLImageRaw::resize(U16 width, U16 height, S8 components) { - if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components)) + if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components) && !isBufferInvalid()) { return true; } @@ -915,7 +915,7 @@ bool LLImageRaw::resize(U16 width, U16 height, S8 components) allocateDataSize(width,height,components); - return true; + return !isBufferInvalid(); } bool LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height, diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp index e20e1192ed..a5ea5935dc 100644 --- a/indra/llimage/llimagebmp.cpp +++ b/indra/llimage/llimagebmp.cpp @@ -318,7 +318,7 @@ bool LLImageBMP::updateData() if( 0 != mColorPaletteColors ) { - mColorPalette = new U8[color_palette_size]; + mColorPalette = new(std::nothrow) U8[color_palette_size]; if (!mColorPalette) { LL_WARNS() << "Out of memory in LLImageBMP::updateData(), size: " << color_palette_size << LL_ENDL; @@ -344,7 +344,11 @@ bool LLImageBMP::decode(LLImageRaw* raw_image, F32 decode_time) return false; } - raw_image->resize(getWidth(), getHeight(), 3); + if (!raw_image->resize(getWidth(), getHeight(), 3)) + { + setLastError("llimagebmp failed to resize image!"); + return false; + } U8* src = mdata + mBitmapOffset; U8* dst = raw_image->getData(); diff --git a/indra/llimage/llimagedxt.cpp b/indra/llimage/llimagedxt.cpp index 3a7319d765..36317a5ba8 100644 --- a/indra/llimage/llimagedxt.cpp +++ b/indra/llimage/llimagedxt.cpp @@ -289,7 +289,11 @@ bool LLImageDXT::decode(LLImageRaw* raw_image, F32 time) return false; } - raw_image->resize(width, height, ncomponents); + if (!raw_image->resize(width, height, ncomponents)) + { + setLastError("llImageDXT failed to resize image!"); + return false; + } memcpy(raw_image->getData(), data, image_size); /* Flawfinder: ignore */ return true; diff --git a/indra/llimage/llimagejpeg.cpp b/indra/llimage/llimagejpeg.cpp index 5c372eb0e7..6b166769c1 100644 --- a/indra/llimage/llimagejpeg.cpp +++ b/indra/llimage/llimagejpeg.cpp @@ -29,6 +29,7 @@ #include "llimagejpeg.h" #include "llerror.h" +#include "llexception.h" jmp_buf LLImageJPEG::sSetjmpBuffer ; LLImageJPEG::LLImageJPEG(S32 quality) @@ -256,7 +257,10 @@ bool LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time) setSize(cinfo.image_width, cinfo.image_height, 3); // Force to 3 components (RGB) - raw_image->resize(getWidth(), getHeight(), getComponents()); + if (!raw_image->resize(getWidth(), getHeight(), getComponents())) + { + throw std::bad_alloc(); + } raw_image_data = raw_image->getData(); @@ -311,6 +315,13 @@ bool LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time) jpeg_destroy_decompress(&cinfo); } + catch (std::bad_alloc) + { + setLastError( "Out of memory"); + jpeg_destroy_decompress(&cinfo); + return true; // done + } + catch (int) { jpeg_destroy_decompress(&cinfo); @@ -370,10 +381,11 @@ boolean LLImageJPEG::encodeEmptyOutputBuffer( j_compress_ptr cinfo ) // Double the buffer size; S32 new_buffer_size = self->mOutputBufferSize * 2; - U8* new_buffer = new U8[ new_buffer_size ]; + U8* new_buffer = new(std::nothrow) U8[ new_buffer_size ]; if (!new_buffer) { - LL_WARNS() << "Out of memory in LLImageJPEG::encodeEmptyOutputBuffer( j_compress_ptr cinfo ), size: " << new_buffer_size << LL_ENDL; + self->setLastError("Out of memory in LLImageJPEG::encodeEmptyOutputBuffer( j_compress_ptr cinfo )"); + LLTHROW(LLContinueError("Out of memory in LLImageJPEG::encodeEmptyOutputBuffer( j_compress_ptr cinfo )")); return false; } memcpy( new_buffer, self->mOutputBuffer, self->mOutputBufferSize ); /* Flawfinder: ignore */ @@ -494,11 +506,13 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) disclaimMem(mOutputBufferSize); mOutputBufferSize = getWidth() * getHeight() * getComponents() + 1024; claimMem(mOutputBufferSize); - mOutputBuffer = new U8[ mOutputBufferSize ]; - if(!mOutputBuffer) + mOutputBuffer = new(std::nothrow) U8[ mOutputBufferSize ]; + if (mOutputBuffer == NULL) { - LL_WARNS() << "could not allocate memory for image encoding, size:" << mOutputBufferSize << LL_ENDL; - return FALSE; + disclaimMem(mOutputBufferSize); + mOutputBufferSize = 0; + setLastError("Failed to allocate output buffer"); + return false; } const U8* raw_image_data = NULL; diff --git a/indra/llimage/llimagepng.cpp b/indra/llimage/llimagepng.cpp index 2288fbb793..2ccb87e4e6 100644 --- a/indra/llimage/llimagepng.cpp +++ b/indra/llimage/llimagepng.cpp @@ -125,7 +125,12 @@ bool LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time) // Temporary buffer to hold the encoded image. Note: the final image // size should be much smaller due to compression. U32 bufferSize = getWidth() * getHeight() * getComponents() + 8192; - U8* tmpWriteBuffer = new U8[ bufferSize ]; + U8* tmpWriteBuffer = new(std::nothrow) U8[ bufferSize ]; + if (!tmpWriteBuffer) + { + setLastError("LLImagePNG::out of memory"); + return false; + } // Delegate actual encoding work to wrapper LLPngWrapper pngWrapper; diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp index b19a1707a1..d43f8dcc3b 100644 --- a/indra/llimage/llimagetga.cpp +++ b/indra/llimage/llimagetga.cpp @@ -263,7 +263,7 @@ bool LLImageTGA::updateData() // only allocate memory for one if _we_ intend to use it. if ( (1 == mImageType) || (9 == mImageType) ) { - mColorMap = new U8[ color_map_bytes ]; + mColorMap = new(std::nothrow) U8[ color_map_bytes ]; if (!mColorMap) { LL_WARNS() << "Out of Memory in bool LLImageTGA::updateData(), size: " << color_map_bytes << LL_ENDL; @@ -336,7 +336,11 @@ bool LLImageTGA::decode(LLImageRaw* raw_image, F32 decode_time) // Copy everything after the header. - raw_image->resize(getWidth(), getHeight(), getComponents()); + if( !raw_image->resize(getWidth(), getHeight(), getComponents())) + { + setLastError("LLImageTGA::out of memory"); + return false; + } // Handle out of memory situations a bit more graceful than a crash if( raw_image->isBufferInvalid() ) @@ -351,6 +355,11 @@ bool LLImageTGA::decode(LLImageRaw* raw_image, F32 decode_time) return false; } + if( raw_image->isBufferInvalid()) + { + setLastError("LLImageTGA::out of memory"); + return false; + } if( mOriginRightBit ) { @@ -405,6 +414,11 @@ bool LLImageTGA::decodeTruecolor( LLImageRaw* raw_image, bool rle, bool flipped // alpha was entirely opaque // convert to 24 bit image LLPointer compacted_image = new LLImageRaw(raw_image->getWidth(), raw_image->getHeight(), 3); + if (compacted_image->isBufferInvalid()) + { + success = false; + break; + } compacted_image->copy(raw_image); raw_image->resize(raw_image->getWidth(), raw_image->getHeight(), 3); raw_image->copy(compacted_image); @@ -421,9 +435,16 @@ bool LLImageTGA::decodeTruecolor( LLImageRaw* raw_image, bool rle, bool flipped // alpha was entirely opaque // convert to 24 bit image LLPointer compacted_image = new LLImageRaw(raw_image->getWidth(), raw_image->getHeight(), 3); - compacted_image->copy(raw_image); - raw_image->resize(raw_image->getWidth(), raw_image->getHeight(), 3); - raw_image->copy(compacted_image); + if (compacted_image->isBufferInvalid()) + { + success = false; + } + else + { + compacted_image->copy(raw_image); + raw_image->resize(raw_image->getWidth(), raw_image->getHeight(), 3); + raw_image->copy(compacted_image); + } } } @@ -1069,7 +1090,11 @@ bool LLImageTGA::decodeAndProcess( LLImageRaw* raw_image, F32 domain, F32 weight return false; } - raw_image->resize(getWidth(), getHeight(), getComponents()); + if( !raw_image->resize(getWidth(), getHeight(), getComponents()) ) + { + LL_ERRS() << "LLImageTGA: Failed to resize image" << LL_ENDL; + return false; + } U8* dst = raw_image->getData(); U8* src = getData() + mDataOffset; diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp index eb70b78a36..f298764cc0 100644 --- a/indra/llimage/llpngwrapper.cpp +++ b/indra/llimage/llpngwrapper.cpp @@ -173,8 +173,11 @@ BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInf // data space if (rawImage != NULL) { - rawImage->resize(static_cast(mWidth), - static_cast(mHeight), mChannels); + if (!rawImage->resize(static_cast(mWidth), + static_cast(mHeight), mChannels)) + { + LLTHROW(PngError("Failed to resize image")); + } U8 *dest = rawImage->getData(); int offset = mWidth * mChannels; @@ -207,6 +210,12 @@ BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInf releaseResources(); return (FALSE); } + catch (std::bad_alloc) + { + mErrorMessage = "LLPngWrapper"; + releaseResources(); + return (FALSE); + } // Clean up and return releaseResources(); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 753ab70cfb..8c1a45d022 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1270,7 +1270,8 @@ BOOL LLImageGL::createGLTexture() stop_glerror(); if (!mTexName) { - LL_ERRS() << "LLImageGL::createGLTexture failed to make an empty texture" << LL_ENDL; + LL_WARNS() << "LLImageGL::createGLTexture failed to make an empty texture" << LL_ENDL; + return FALSE; } return TRUE ; @@ -1403,7 +1404,16 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ } if (!mTexName) { - LL_ERRS() << "LLImageGL::createGLTexture failed to make texture" << LL_ENDL; + if (old_name) + { + sGlobalTextureMemory -= mTextureMemory; + LLImageGL::deleteTextures(1, &old_name); + disclaimMem(mTextureMemory); + stop_glerror(); + } + + LL_WARNS() << "LLImageGL::createGLTexture failed to make texture" << LL_ENDL; + return FALSE; } if (mUseMipMaps) diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 28fdacdba8..3b93a664e3 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -216,7 +216,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const // we're showing all folders, overriding filter if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS) { - return !gInventory.isCategoryHidden(folder_id); + return true; } // when applying a filter, matching folders get their contents downloaded first diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 375c659fef..58868c1ddf 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -362,34 +362,6 @@ LLViewerInventoryCategory* LLInventoryModel::getCategory(const LLUUID& id) const return category; } -bool LLInventoryModel::isCategoryHidden(const LLUUID& id) const -{ - // Show inbox folder depending on FSShowInboxFolder setting - static LLCachedControl fsShowInboxFolder(gSavedSettings, "FSShowInboxFolder"); - - bool res = false; - const LLViewerInventoryCategory* category = getCategory(id); - if (category) - { - LLFolderType::EType cat_type = category->getPreferredType(); - switch (cat_type) - { - case LLFolderType::FT_INBOX: - // Show inbox folder depending on FSShowInboxFolder setting - res = !fsShowInboxFolder; - break; - // - case LLFolderType::FT_OUTBOX: - case LLFolderType::FT_MARKETPLACE_LISTINGS: - res = true; - break; - default: - break; - } - } - return res; -} - S32 LLInventoryModel::getItemCount() const { return mItemMap.size(); diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 4f736a5947..af32f4bb64 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -341,9 +341,7 @@ public: // Copy content of all folders of type "type" into folder "id" and delete/purge the empty folders // Note : This method has been designed for FT_OUTBOX (aka Merchant Outbox) but can be used for other categories void consolidateForType(const LLUUID& id, LLFolderType::EType type); - - bool isCategoryHidden(const LLUUID& id) const; - + // ReplaceWornItemsOnly void wearItemsOnAvatar(LLInventoryCategory* category); void wearAttachmentsOnAvatarCheckRemove(LLViewerObject *object, const LLViewerJointAttachment *attachment); diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index ca089eb5ab..9bf0aed31d 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -1102,13 +1102,6 @@ void LLOutfitGallery::refreshOutfit(const LLUUID& category_id) updates["name"] = new_name; update_inventory_item(inv_id, updates, NULL); mOutfitRenamePending.setNull(); - // FIRE-20526: Outfit snapshot upload closes inventory; No idea what purpose serves closing the inventory window here - //LLFloater* inv_floater = LLFloaterReg::getInstance("inventory"); - //if (inv_floater) - //{ - // inv_floater->closeFloater(); - //} - // LLFloater* appearance_floater = LLFloaterReg::getInstance("appearance"); if (appearance_floater) { @@ -1242,7 +1235,7 @@ void LLOutfitGallery::uploadOutfitImage(const std::vector& filename LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), - upload_pending_name, callback, expected_upload_cost, nruserdata); + upload_pending_name, callback, expected_upload_cost, nruserdata, false); mOutfitLinkPending = outfit_id; } delete unit; diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 3f8f299446..1d3a3378c3 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -314,6 +314,8 @@ void LLPanelGroupNotices::activate() { if(mNoticesList) mNoticesList->deleteAllItems(); + + mPrevSelectedNotice = LLUUID(); BOOL can_send = gAgent.hasPowerInGroup(mGroupID,GP_NOTICES_SEND); BOOL can_receive = gAgent.hasPowerInGroup(mGroupID,GP_NOTICES_RECEIVE); @@ -466,12 +468,18 @@ void LLPanelGroupNotices::refreshNotices() } +void LLPanelGroupNotices::clearNoticeList() +{ + mPrevSelectedNotice = mNoticesList->getStringUUIDSelectedItem(); + mNoticesList->deleteAllItems(); +} + void LLPanelGroupNotices::onClickRefreshNotices(void* data) { LL_DEBUGS() << "LLPanelGroupNotices::onClickGetPastNotices" << LL_ENDL; LLPanelGroupNotices* self = (LLPanelGroupNotices*)data; - self->mNoticesList->deleteAllItems(); + self->clearNoticeList(); LLMessageSystem* msg = gMessageSystem; msg->newMessage("GroupNoticesListRequest"); @@ -562,7 +570,6 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg) LLSD row; row["id"] = id; - row["columns"][0]["column"] = "icon"; if (has_attachment) { @@ -590,13 +597,13 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg) mNoticesList->setNeedsSort(save_sort); mNoticesList->updateSort(); - // Don't do this while composing a new notice or you will lose it - //mNoticesList->selectFirstItem(); if (mPanelViewNotice->getVisible()) { - mNoticesList->selectFirstItem(); + if (!mNoticesList->selectByID(mPrevSelectedNotice)) + { + mNoticesList->selectFirstItem(); + } } - // } void LLPanelGroupNotices::onSelectNotice(LLUICtrl* ctrl, void* data) diff --git a/indra/newview/llpanelgroupnotices.h b/indra/newview/llpanelgroupnotices.h index be0c2daeac..01b35e0007 100644 --- a/indra/newview/llpanelgroupnotices.h +++ b/indra/newview/llpanelgroupnotices.h @@ -65,6 +65,8 @@ public: void refreshNotices(); + void clearNoticeList(); + virtual void setGroupID(const LLUUID& id); private: @@ -114,6 +116,8 @@ private: LLOfferInfo* mInventoryOffer; + LLUUID mPrevSelectedNotice; + static std::map sInstances; }; diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 45fc1c63be..172def4395 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -496,11 +496,6 @@ void LLPanelObject::getState( ) return; } - // can move or rotate only linked group with move permissions, or sub-object with move and modify perms - BOOL enable_move = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts")); - BOOL enable_scale = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && objectp->permModify(); - BOOL enable_rotate = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts")); - S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME )) && (selected_count == 1); @@ -510,20 +505,13 @@ void LLPanelObject::getState( ) updateLimits(objectp->isAttachment()); // FIRE-8205 - if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() > 1) - { - enable_move = FALSE; - enable_scale = FALSE; - enable_rotate = FALSE; - } + bool enable_move; + bool enable_modify; -// [RLVa:KB] - Checked: 2010-03-31 (RLVa-1.2.0c) | Modified: RLVa-1.0.0g - if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP))) ) - { - if ( (isAgentAvatarValid()) && (gAgentAvatarp->isSitting()) && (gAgentAvatarp->getRoot() == objectp->getRootEdit()) ) - enable_move = enable_scale = enable_rotate = FALSE; - } -// [/RLVa:KB] + LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(enable_move, enable_modify); + + BOOL enable_scale = enable_modify; + BOOL enable_rotate = enable_move; // already accounts for a case of children, which needs permModify() as well LLVector3 vec; if (enable_move) diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 1dbc3d4345..d578b3b478 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -3792,6 +3792,51 @@ void LLSelectMgr::selectForceDelete() SEND_ONLY_ROOTS); } +BOOL LLSelectMgr::selectGetEditMoveLinksetPermissions(bool &move, bool &modify) +{ + move = true; + modify = true; + // gSavedSettings replacement + //bool selecting_linked_set = !gSavedSettings.getBOOL("EditLinkedParts"); + static LLCachedControl editLinkedParts(gSavedSettings, "EditLinkedParts"); + bool selecting_linked_set = !editLinkedParts(); + // + + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++) + { + LLSelectNode* nodep = *iter; + LLViewerObject* object = nodep->getObject(); + if (!object || !nodep->mValid) + { + move = false; + modify = false; + return FALSE; + } + + LLViewerObject *root_object = object->getRootEdit(); + bool this_object_movable = false; + if (object->permMove() && !object->isPermanentEnforced() && + ((root_object == NULL) || !root_object->isPermanentEnforced()) && + (object->permModify() || selecting_linked_set)) + { + this_object_movable = true; + +// [RLVa:KB] - Checked: 2010-03-31 (RLVa-1.2.0c) | Modified: RLVa-1.0.0g + if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP))) ) + { + if ( (isAgentAvatarValid()) && (gAgentAvatarp->isSitting()) && (gAgentAvatarp->getRoot() == object->getRootEdit()) ) + move = modify = false; + } +// [/RLVa:KB] + } + move = move && this_object_movable; + modify = modify && object->permModify(); + } + + return TRUE; +} + void LLSelectMgr::selectGetAggregateSaleInfo(U32 &num_for_sale, BOOL &is_for_sale_mixed, BOOL &is_sale_price_mixed, diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index fb1df347af..2df76e2d18 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -754,6 +754,11 @@ public: // returns TRUE if all the nodes are valid. Accumulates // permissions in the parameter. BOOL selectGetPermissions(LLPermissions& perm); + + // returns TRUE if all the nodes are valid. Depends onto "edit linked" state + // Children in linksets are a bit special - they require not only move permission + // but also modify if "edit linked" is set, since you move them relative to parent + BOOL selectGetEditMoveLinksetPermissions(bool &move, bool &modify); // Get a bunch of useful sale information for the object(s) selected. // "_mixed" is true if not all objects have the same setting. diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index deff615eaa..af101af9af 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -1178,7 +1178,7 @@ void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name) tid, LLAssetType::AT_TEXTURE, res_name, res_desc, 0, folder_type, inv_type, PERM_ALL, LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), - expected_upload_cost)); + expected_upload_cost, !outfit_snapshot)); upload_new_resource(assetUploadInfo); diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index aacf1b9596..181130e14d 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -674,8 +674,8 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB); LL_DEBUGS("UserInput") << "hover handled by LLToolPie (inactive)" << LL_ENDL; } - else if ( (object && object->flagHandleTouch()) - || (parent && parent->flagHandleTouch())) + else if ((!object || !object->isAttachment() || object->getClickAction() != CLICK_ACTION_DISABLED) + && ((object && object->flagHandleTouch()) || (parent && parent->flagHandleTouch()))) { show_highlight = true; gViewerWindow->setCursor(UI_CURSOR_HAND); diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index b727d8ef3e..d7b9163262 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -66,7 +66,7 @@ LLResourceUploadInfo::LLResourceUploadInfo(LLTransactionID transactId, LLAssetType::EType assetType, std::string name, std::string description, S32 compressionInfo, LLFolderType::EType destinationType, LLInventoryType::EType inventoryType, U32 nextOWnerPerms, - U32 groupPerms, U32 everyonePerms, S32 expectedCost) : + U32 groupPerms, U32 everyonePerms, S32 expectedCost, bool showInventory) : mTransactionId(transactId), mAssetType(assetType), mName(name), @@ -78,6 +78,7 @@ LLResourceUploadInfo::LLResourceUploadInfo(LLTransactionID transactId, mGroupPerms(groupPerms), mEveryonePerms(everyonePerms), mExpectedUploadCost(expectedCost), + mShowInventory(showInventory), mFolderId(LLUUID::null), mItemId(LLUUID::null), mAssetId(LLAssetID::null) @@ -87,7 +88,7 @@ LLResourceUploadInfo::LLResourceUploadInfo(LLTransactionID transactId, LLResourceUploadInfo::LLResourceUploadInfo(std::string name, std::string description, S32 compressionInfo, LLFolderType::EType destinationType, LLInventoryType::EType inventoryType, - U32 nextOWnerPerms, U32 groupPerms, U32 everyonePerms, S32 expectedCost): + U32 nextOWnerPerms, U32 groupPerms, U32 everyonePerms, S32 expectedCost, bool showInventory) : mName(name), mDescription(description), mCompressionInfo(compressionInfo), @@ -97,6 +98,7 @@ LLResourceUploadInfo::LLResourceUploadInfo(std::string name, mGroupPerms(groupPerms), mEveryonePerms(everyonePerms), mExpectedUploadCost(expectedCost), + mShowInventory(showInventory), mTransactionId(), mAssetType(LLAssetType::AT_NONE), mFolderId(LLUUID::null), @@ -118,6 +120,7 @@ LLResourceUploadInfo::LLResourceUploadInfo(LLAssetID assetId, LLAssetType::EType mGroupPerms(0), mEveryonePerms(0), mExpectedUploadCost(0), + mShowInventory(true), mTransactionId(), mFolderId(LLUUID::null), mItemId(LLUUID::null) @@ -337,10 +340,11 @@ LLNewFileResourceUploadInfo::LLNewFileResourceUploadInfo( U32 nextOWnerPerms, U32 groupPerms, U32 everyonePerms, - S32 expectedCost) : + S32 expectedCost, + bool show_inventory) : LLResourceUploadInfo(name, description, compressionInfo, destinationType, inventoryType, - nextOWnerPerms, groupPerms, everyonePerms, expectedCost), + nextOWnerPerms, groupPerms, everyonePerms, expectedCost, show_inventory), mFileName(fileName) { } diff --git a/indra/newview/llviewerassetupload.h b/indra/newview/llviewerassetupload.h index 43e23a0d42..ee1806b782 100644 --- a/indra/newview/llviewerassetupload.h +++ b/indra/newview/llviewerassetupload.h @@ -53,7 +53,8 @@ public: U32 nextOWnerPerms, U32 groupPerms, U32 everyonePerms, - S32 expectedCost); + S32 expectedCost, + bool showInventory = true); virtual ~LLResourceUploadInfo() { } @@ -79,7 +80,7 @@ public: S32 getExpectedUploadCost() const { return mExpectedUploadCost; }; virtual bool showUploadDialog() const { return true; } - virtual bool showInventoryPanel() const { return true; } + virtual bool showInventoryPanel() const { return mShowInventory; } virtual std::string getDisplayName() const; @@ -97,7 +98,8 @@ protected: U32 nextOWnerPerms, U32 groupPerms, U32 everyonePerms, - S32 expectedCost); + S32 expectedCost, + bool showInventory = true); LLResourceUploadInfo( LLAssetID assetId, @@ -130,6 +132,7 @@ private: LLUUID mFolderId; LLUUID mItemId; LLAssetID mAssetId; + bool mShowInventory; }; //------------------------------------------------------------------------- @@ -146,7 +149,8 @@ public: U32 nextOWnerPerms, U32 groupPerms, U32 everyonePerms, - S32 expectedCost); + S32 expectedCost, + bool show_inventory = true); virtual LLSD prepareUpload(); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 677becb77f..ac066ccb02 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -717,7 +717,8 @@ LLUUID upload_new_resource( const std::string& display_name, LLAssetStorage::LLStoreAssetCallback callback, S32 expected_upload_cost, - void *userdata) + void *userdata, + bool show_inventory) { LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo( @@ -725,7 +726,7 @@ LLUUID upload_new_resource( name, desc, compression_info, destination_folder_type, inv_type, next_owner_perms, group_perms, everyone_perms, - expected_upload_cost)); + expected_upload_cost, show_inventory)); upload_new_resource(uploadInfo, callback, userdata); return LLUUID::null; diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index d9a84dbd26..a4c3a8052e 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -56,7 +56,8 @@ LLUUID upload_new_resource( const std::string& display_name, LLAssetStorage::LLStoreAssetCallback callback, S32 expected_upload_cost, - void *userdata); + void *userdata, + bool show_inventory = true); void upload_new_resource( LLResourceUploadInfo::ptr_t &uploadInfo, diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 74eda66ca4..b2fe7c4361 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -783,7 +783,7 @@ void response_group_invitation_coro(std::string url, LLUUID group_id, bool notif LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("friendshipResponceErrorProcessing", httpPolicy)); + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("responseGroupInvitation", httpPolicy)); LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); LLSD payload; @@ -851,6 +851,7 @@ void send_join_group_response(LLUUID group_id, LLUUID transaction_id, bool accep if (!url.empty()) { + LL_DEBUGS("GroupInvite") << "Capability url: " << url << LL_ENDL; LLCoros::instance().launch("LLMessageSystem::acceptGroupInvitation", boost::bind(response_group_invitation_coro, url, group_id, accept_invite)); } @@ -862,6 +863,8 @@ void send_join_group_response(LLUUID group_id, LLUUID transaction_id, bool accep } else { + LL_DEBUGS("GroupInvite") << "Replying to group invite via IM message" << LL_ENDL; + EInstantMessage type = accept_invite ? IM_GROUP_INVITATION_ACCEPT : IM_GROUP_INVITATION_DECLINE; send_improved_im(group_id, diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index ce6690ce79..c631654cee 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -3079,7 +3079,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("ParcelVoiceInfoRequest"); capabilityNames.append("ProductInfoRequest"); capabilityNames.append("ProvisionVoiceAccountRequest"); - capabilityNames.append("ReadOfflineMsgs"); // Only use with AcceptGroupInvite AcceptFriendship + capabilityNames.append("ReadOfflineMsgs"); // Requires to respond reliably: AcceptFriendship, AcceptGroupInvite, DeclineFriendship, DeclineGroupInvite capabilityNames.append("RemoteParcelRequest"); capabilityNames.append("RenderMaterials"); capabilityNames.append("RequestTextureDownload"); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index cf5e473552..07f81a3e60 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4953,50 +4953,22 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, { if( !LLSelectMgr::getInstance()->getSelection()->isEmpty() ) { - BOOL moveable_object_selected = FALSE; - BOOL all_selected_objects_move = TRUE; - BOOL all_selected_objects_modify = TRUE; - // gSavedSettings replacement - //BOOL selecting_linked_set = !gSavedSettings.getBOOL("EditLinkedParts"); - static LLCachedControl editLinkedParts(gSavedSettings, "EditLinkedParts"); - BOOL selecting_linked_set = !(BOOL)editLinkedParts; - // - - for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin(); - iter != LLSelectMgr::getInstance()->getSelection()->end(); iter++) - { - LLSelectNode* nodep = *iter; - LLViewerObject* object = nodep->getObject(); - LLViewerObject *root_object = (object == NULL) ? NULL : object->getRootEdit(); - BOOL this_object_movable = FALSE; - if (object->permMove() && !object->isPermanentEnforced() && - ((root_object == NULL) || !root_object->isPermanentEnforced()) && - (object->permModify() || selecting_linked_set)) - { - moveable_object_selected = TRUE; - this_object_movable = TRUE; - -// [RLVa:KB] - Checked: 2010-03-31 (RLVa-1.2.0c) | Modified: RLVa-0.2.0g - if ( (rlv_handler_t::isEnabled()) && - ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP))) ) - { - if ((isAgentAvatarValid()) && (gAgentAvatarp->isSitting()) && (gAgentAvatarp->getRoot() == object->getRootEdit())) - moveable_object_selected = this_object_movable = FALSE; - } -// [/RLVa:KB] - } - all_selected_objects_move = all_selected_objects_move && this_object_movable; - all_selected_objects_modify = all_selected_objects_modify && object->permModify(); - } + bool all_selected_objects_move; + bool all_selected_objects_modify; + // Note: This might be costly to do on each frame and when a lot of objects are selected + // we might be better off with some kind of memory for selection and/or states, consider + // optimizing, perhaps even some kind of selection generation at level of LLSelectMgr to + // make whole viewer benefit. + LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(all_selected_objects_move, all_selected_objects_modify); BOOL draw_handles = TRUE; - if (tool == LLToolCompTranslate::getInstance() && (!moveable_object_selected || !all_selected_objects_move)) + if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move) { draw_handles = FALSE; } - if (tool == LLToolCompRotate::getInstance() && (!moveable_object_selected || !all_selected_objects_move)) + if (tool == LLToolCompRotate::getInstance() && !all_selected_objects_move) { draw_handles = FALSE; } diff --git a/indra/newview/skins/default/xui/ru/floater_tos.xml b/indra/newview/skins/default/xui/ru/floater_tos.xml index 3f2b5747d5..7196a04de1 100644 --- a/indra/newview/skins/default/xui/ru/floater_tos.xml +++ b/indra/newview/skins/default/xui/ru/floater_tos.xml @@ -16,6 +16,6 @@ Я прочитал и согласен с Условиями и положениями по конфиденциальности Пользовательского соглашения, включая требования по разрешению разногласий Second Life. -