diff options
Diffstat (limited to 'indra')
49 files changed, 413 insertions, 198 deletions
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index e5089f028f..60359ca304 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -1566,9 +1566,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 f12c64023a..330d812985 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -579,8 +579,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 dca03cfe04..1a4dd2ca99 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -889,7 +889,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;  	} @@ -898,7 +898,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 2cdd26c22b..867b2bb47b 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_ERRS() << "Out of memory in LLImageBMP::updateData()" << 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 60b2d0faa5..3b1b060c02 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_ERRS() << "Out of memory in LLImageJPEG::encodeEmptyOutputBuffer( j_compress_ptr cinfo )" << 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 */ @@ -493,7 +505,14 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )  	disclaimMem(mOutputBufferSize);  	mOutputBufferSize = getWidth() * getHeight() * getComponents() + 1024;  	claimMem(mOutputBufferSize); -	mOutputBuffer = new U8[ mOutputBufferSize ]; +	mOutputBuffer = new(std::nothrow) U8[ mOutputBufferSize ]; +	if (mOutputBuffer == NULL) +	{ +		disclaimMem(mOutputBufferSize); +		mOutputBufferSize = 0; +		setLastError("Failed to allocate output buffer"); +		return false; +	}  	const U8* raw_image_data = NULL;  	S32 row_stride = 0; diff --git a/indra/llimage/llimagepng.cpp b/indra/llimage/llimagepng.cpp index a4823ed859..c4b98d8260 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 7c75aa1e2a..88bdae9b80 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_ERRS() << "Out of Memory in bool LLImageTGA::updateData()" << 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; +	}  	if( (getComponents() != 1) &&  		(getComponents() != 3) && @@ -346,6 +350,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 )  	{ @@ -395,6 +404,11 @@ bool LLImageTGA::decodeTruecolor( LLImageRaw* raw_image, bool rle, bool flipped  				// alpha was entirely opaque  				// convert to 24 bit image  				LLPointer<LLImageRaw> 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); @@ -411,9 +425,16 @@ bool LLImageTGA::decodeTruecolor( LLImageRaw* raw_image, bool rle, bool flipped  			// alpha was entirely opaque  			// convert to 24 bit image  			LLPointer<LLImageRaw> 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); +			}  		}  	} @@ -1053,7 +1074,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<U16>(mWidth), -				static_cast<U16>(mHeight), mChannels); +			if (!rawImage->resize(static_cast<U16>(mWidth), +				static_cast<U16>(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 89500dcc04..40217b2e80 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1262,7 +1262,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 ; @@ -1395,7 +1396,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/llfloaternotificationstabbed.cpp b/indra/newview/llfloaternotificationstabbed.cpp index 4b5fe4989a..d1679fd936 100644 --- a/indra/newview/llfloaternotificationstabbed.cpp +++ b/indra/newview/llfloaternotificationstabbed.cpp @@ -387,7 +387,8 @@ void LLFloaterNotificationsTabbed::onStoreToast(LLPanel* info_panel, LLUUID id)      p.notification_name = notify->getName();      p.transaction_id = payload["transaction_id"];      p.group_id = payload["group_id"]; -    p.fee =  payload["fee"]; +    p.fee = payload["fee"]; +    p.use_offline_cap = payload["use_offline_cap"].asInteger();      p.subject = payload["subject"].asString();      p.message = payload["message"].asString();      p.sender = payload["sender_name"].asString(); diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 491671c46f..e76b3d118e 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -814,10 +814,11 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,                  LLSD payload;                  payload["transaction_id"] = session_id; -                payload["group_id"] = from_id; +                payload["group_id"] = from_group ? from_id : aux_id;                  payload["name"] = name;                  payload["message"] = message;                  payload["fee"] = membership_fee; +                payload["use_offline_cap"] = session_id.isNull() && (offline == IM_OFFLINE);                  LLSD args;                  args["MESSAGE"] = message; @@ -1459,8 +1460,12 @@ void LLIMProcessing::requestOfflineMessages()          // Auto-accepted inventory items may require the avatar object          // to build a correct name.  Likewise, inventory offers from          // muted avatars require the mute list to properly mute. -        if (cap_url.empty()) +        if (cap_url.empty() +            || gAgent.getRegionCapability("AcceptFriendship").empty() +            || gAgent.getRegionCapability("AcceptGroupInvite").empty())          { +            // Offline messages capability provides no session/transaction ids for message AcceptFriendship and IM_GROUP_INVITATION to work +            // So make sure we have the caps before using it.              requestOfflineMessagesLegacy();          }          else @@ -1561,7 +1566,7 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url)              message_data["to_agent_id"].asUUID(),              IM_OFFLINE,              (EInstantMessage)message_data["dialog"].asInteger(), -            LLUUID::null, // session id, fix this for friendship offers to work +            LLUUID::null, // session id, since there is none we can only use frienship/group invite caps              message_data["timestamp"].asInteger(),              message_data["from_agent_name"].asString(),              message_data["message"].asString(), diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index f64c39c3ad..9193613e9f 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -153,7 +153,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 76bf87cfe5..b447166764 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -342,27 +342,6 @@ LLViewerInventoryCategory* LLInventoryModel::getCategory(const LLUUID& id) const  	return category;  } -bool LLInventoryModel::isCategoryHidden(const LLUUID& id) const -{ -	bool res = false; -	const LLViewerInventoryCategory* category = getCategory(id); -	if (category) -	{ -		LLFolderType::EType cat_type = category->getPreferredType(); -		switch (cat_type) -		{ -			case LLFolderType::FT_INBOX: -			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 576c5e9e20..01e0ed7e9b 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -316,9 +316,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; - +      private:  	mutable LLPointer<LLViewerInventoryItem> mLastItem; // cache recent lookups	 diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp index f2de8e54a0..a5bc75e6bd 100644 --- a/indra/newview/llnotificationlistitem.cpp +++ b/indra/newview/llnotificationlistitem.cpp @@ -312,38 +312,15 @@ void LLGroupInviteNotificationListItem::onClickJoinBtn()  		return;  	} -	if(mParams.fee > 0) -	{ -		LLSD args; -		args["COST"] = llformat("%d", mParams.fee); -		// Set the fee for next time to 0, so that we don't keep -		// asking about a fee. -		LLSD next_payload; -		next_payload["group_id"]=  mParams.group_id; -		next_payload["transaction_id"]= mParams.transaction_id; -		next_payload["fee"] = 0; -		LLNotificationsUtil::add("JoinGroupCanAfford", args, next_payload); -	} -	else -	{ -		send_improved_im(mParams.group_id, -						std::string("name"), -						std::string("message"), -						IM_ONLINE, -						IM_GROUP_INVITATION_ACCEPT, -						mParams.transaction_id); -	} +	send_join_group_response(mParams.group_id, mParams.transaction_id, true, mParams.fee, mParams.use_offline_cap); +  	LLNotificationListItem::onClickCloseBtn();  }  void LLGroupInviteNotificationListItem::onClickDeclineBtn()  { -	send_improved_im(mParams.group_id, -					std::string("name"), -					std::string("message"), -					IM_ONLINE, -					IM_GROUP_INVITATION_DECLINE, -					mParams.transaction_id); +	send_join_group_response(mParams.group_id, mParams.transaction_id, false, mParams.fee, mParams.use_offline_cap); +  	LLNotificationListItem::onClickCloseBtn();  } diff --git a/indra/newview/llnotificationlistitem.h b/indra/newview/llnotificationlistitem.h index 3dd52986b0..3d564fed0e 100644 --- a/indra/newview/llnotificationlistitem.h +++ b/indra/newview/llnotificationlistitem.h @@ -56,6 +56,7 @@ public:          std::string     message;          std::string     sender;          S32             fee; +        U8              use_offline_cap;          LLDate          time_stamp;          LLDate          received_time;          LLSD            inventory_offer; diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index a90a29a731..b2b6de94b3 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -1090,11 +1090,6 @@ void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)                      updates["name"] = new_name;                      update_inventory_item(inv_id, updates, NULL);                      mOutfitRenamePending.setNull(); -                    LLFloater* inv_floater = LLFloaterReg::getInstance("inventory"); -                    if (inv_floater) -                    { -                        inv_floater->closeFloater(); -                    }                      LLFloater* appearance_floater = LLFloaterReg::getInstance("appearance");                      if (appearance_floater)                      { @@ -1228,7 +1223,7 @@ void LLOutfitGallery::uploadOutfitImage(const std::vector<std::string>& 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 178b5db6c2..ce6834b4b3 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -303,6 +303,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); @@ -454,12 +456,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"); @@ -547,7 +555,6 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)  		LLSD row;  		row["id"] = id; -		  		row["columns"][0]["column"] = "icon";  		if (has_attachment)  		{ @@ -575,7 +582,13 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)  	mNoticesList->setNeedsSort(save_sort);  	mNoticesList->updateSort(); -	mNoticesList->selectFirstItem(); +	if (mPanelViewNotice->getVisible()) +	{ +		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 04629b5f6b..46c8c241c6 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: @@ -113,6 +115,8 @@ private:  	LLOfferInfo* mInventoryOffer; +	LLUUID mPrevSelectedNotice; +  	static std::map<LLUUID,LLPanelGroupNotices*>	sInstances;  }; diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 25cfb598e7..3665910c63 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -341,21 +341,17 @@ 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); -	if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() > 1) -	{ -		enable_move = FALSE; -		enable_scale = FALSE; -		enable_rotate = FALSE; -	} +	bool enable_move; +	bool enable_modify; + +	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 ddae109030..fce21fa30a 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -3676,6 +3676,39 @@ void LLSelectMgr::selectForceDelete()  		SEND_ONLY_ROOTS);  } +BOOL LLSelectMgr::selectGetEditMoveLinksetPermissions(bool &move, bool &modify) +{ +    move = true; +    modify = true; +    bool selecting_linked_set = !gSavedSettings.getBOOL("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; +        } +        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 e965dd80d5..87ac899325 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -675,6 +675,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/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp index a486a29aa2..2503e2a5e2 100644 --- a/indra/newview/llsidepaneliteminfo.cpp +++ b/indra/newview/llsidepaneliteminfo.cpp @@ -613,7 +613,7 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)  		LLCheckBoxCtrl* ctl = getChild<LLCheckBoxCtrl>("CheckShareWithGroup");  		if(ctl)  		{ -			ctl->setTentative(TRUE); +			ctl->setTentative(!ctl->getEnabled());  			ctl->set(TRUE);  		}  	} diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index d0cff1464b..5a40af14a3 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -1050,7 +1050,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/llstartup.cpp b/indra/newview/llstartup.cpp index 7a4c41779a..cc02642203 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -246,6 +246,7 @@ static bool mLoginStatePastUI = false;  const S32 DEFAULT_MAX_AGENT_GROUPS = 42;  const S32 ALLOWED_MAX_AGENT_GROUPS = 500; +const F32 STATE_AGENT_WAIT_TIMEOUT = 240; //seconds  boost::scoped_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));  boost::scoped_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener()); @@ -1615,6 +1616,13 @@ bool idle_startup()  			LLStartUp::setStartupState( STATE_INVENTORY_SEND );  		}  		display_startup(); + +		if (!gAgentMovementCompleted && timeout.getElapsedTimeF32() > STATE_AGENT_WAIT_TIMEOUT) +		{ +			LL_WARNS("AppInit") << "Backing up to login screen!" << LL_ENDL; +			LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status); +			reset_login(); +		}  		return FALSE;  	} diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 6a8843cb44..5082e16685 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -609,8 +609,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 4e13eceb55..97fbb8c601 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -60,7 +60,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), @@ -72,6 +72,7 @@ LLResourceUploadInfo::LLResourceUploadInfo(LLTransactionID transactId,      mGroupPerms(groupPerms),      mEveryonePerms(everyonePerms),      mExpectedUploadCost(expectedCost), +    mShowInventory(showInventory),      mFolderId(LLUUID::null),      mItemId(LLUUID::null),      mAssetId(LLAssetID::null) @@ -81,7 +82,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), @@ -91,6 +92,7 @@ LLResourceUploadInfo::LLResourceUploadInfo(std::string name,      mGroupPerms(groupPerms),      mEveryonePerms(everyonePerms),      mExpectedUploadCost(expectedCost), +    mShowInventory(showInventory),      mTransactionId(),      mAssetType(LLAssetType::AT_NONE),      mFolderId(LLUUID::null), @@ -112,6 +114,7 @@ LLResourceUploadInfo::LLResourceUploadInfo(LLAssetID assetId, LLAssetType::EType      mGroupPerms(0),      mEveryonePerms(0),      mExpectedUploadCost(0), +    mShowInventory(true),      mTransactionId(),      mFolderId(LLUUID::null),      mItemId(LLUUID::null) @@ -331,10 +334,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/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index f7250ffb66..ec851ddaf9 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -134,6 +134,7 @@  #include "llpathfindingmanager.h"  #include "llstartup.h"  #include "boost/unordered_map.hpp" +#include <boost/regex.hpp>  #include "llcleanup.h"  using namespace LLAvatarAppearanceDefines; @@ -8025,7 +8026,12 @@ void handle_report_bug(const LLSD& param)  	LLUIString url(param.asString());  	LLStringUtil::format_map_t replace; -	replace["[ENVIRONMENT]"] = LLURI::escape(LLAppViewer::instance()->getViewerInfoString(true)); +	std::string environment = LLAppViewer::instance()->getViewerInfoString(true); +	boost::regex regex; +	regex.assign("</?nolink>"); +	std::string stripped_env = boost::regex_replace(environment, regex, ""); + +	replace["[ENVIRONMENT]"] = LLURI::escape(stripped_env);  	LLSLURL location_url;  	LLAgentUI::buildSLURL(location_url);  	replace["[LOCATION]"] = LLURI::escape(location_url.getSLURLString()); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index cf1c442ce9..d2a5578568 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -689,7 +689,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( @@ -697,7 +698,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 35f86f606b..4e8348b5e5 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -55,7 +55,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 850d455c36..a2b4a6a91d 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -169,7 +169,8 @@ void accept_friendship_coro(std::string url, LLSD notification)      url += "?from=" + payload["from_id"].asString();      url += "&agent_name=\"" + LLURI::escape(gAgentAvatarp->getFullname()) + "\""; -    LLSD result = httpAdapter->getAndSuspend(httpRequest, url); +    LLSD data; +    LLSD result = httpAdapter->postAndSuspend(httpRequest, url, data);      LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];      LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); @@ -199,20 +200,20 @@ void accept_friendship_coro(std::string url, LLSD notification)  void decline_friendship_coro(std::string url, LLSD notification, S32 option)  { -    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); -    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t -        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("friendshipResponceErrorProcessing", httpPolicy)); -    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);      if (url.empty())      {          LL_WARNS("Friendship") << "Empty capability!" << LL_ENDL;          return;      } +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("friendshipResponceErrorProcessing", httpPolicy)); +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);      LLSD payload = notification["payload"];      url += "?from=" + payload["from_id"].asString(); -    LLSD result = httpAdapter->getAndSuspend(httpRequest, url); +    LLSD result = httpAdapter->deleteAndSuspend(httpRequest, url);      LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];      LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); @@ -732,6 +733,122 @@ void send_sound_trigger(const LLUUID& sound_id, F32 gain)  static LLSD sSavedGroupInvite;  static LLSD sSavedResponse; +void response_group_invitation_coro(std::string url, LLUUID group_id, bool notify_and_update) +{ +    if (url.empty()) +    { +        LL_WARNS("GroupInvite") << "Empty capability!" << LL_ENDL; +        return; +    } + +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("responseGroupInvitation", httpPolicy)); +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + +    LLSD payload; +    payload["group"] = group_id; + +    LLSD result = httpAdapter->postAndSuspend(httpRequest, url, payload); + +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + +    if (!status) +    { +        LL_WARNS("GroupInvite") << "HTTP status, " << status.toTerseString() << +            ". Group " << group_id << " invitation response processing failed." << LL_ENDL; +    } +    else +    { +        if (!result.has("success") || result["success"].asBoolean() == false) +        { +            LL_WARNS("GroupInvite") << "Server failed to process group " << group_id << " invitation response. " << httpResults << LL_ENDL; +        } +        else +        { +            LL_DEBUGS("GroupInvite") << "Successfully sent response to group " << group_id << " invitation" << LL_ENDL; +            if (notify_and_update) +            { +                LLNotificationsUtil::add("JoinGroupSuccess"); +                gAgent.sendAgentDataUpdateRequest(); + +                LLGroupMgr::getInstance()->clearGroupData(group_id); +                // refresh the floater for this group, if any. +                LLGroupActions::refresh(group_id); +            } +        } +    } +} + +void send_join_group_response(LLUUID group_id, LLUUID transaction_id, bool accept_invite, S32 fee, bool use_offline_cap, LLSD &payload) +{ +    if (accept_invite && fee > 0) +    { +        // If there is a fee to join this group, make +        // sure the user is sure they want to join. +            LLSD args; +            args["COST"] = llformat("%d", fee); +            // Set the fee for next time to 0, so that we don't keep +            // asking about a fee. +            LLSD next_payload = payload; +            next_payload["fee"] = 0; +            LLNotificationsUtil::add("JoinGroupCanAfford", +                args, +                next_payload); +    } +    else if (use_offline_cap) +    { +        std::string url; +        if (accept_invite) +        { +            url = gAgent.getRegionCapability("AcceptGroupInvite"); +        } +        else +        { +            url = gAgent.getRegionCapability("DeclineGroupInvite"); +        } + +        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)); +        } +        else +        { +            // if sim has no this cap, we can do nothing - regular request will fail +            LL_WARNS("GroupInvite") << "No capability, can't reply to offline invitation!" << LL_ENDL; +        } +    } +    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, +            std::string("name"), +            std::string("message"), +            IM_ONLINE, +            type, +            transaction_id); +    } +} + +void send_join_group_response(LLUUID group_id, LLUUID transaction_id, bool accept_invite, S32 fee, bool use_offline_cap) +{ +    LLSD payload; +    if (accept_invite) +    { +        payload["group_id"] = group_id; +        payload["transaction_id"] =  transaction_id; +        payload["fee"] =  fee; +        payload["use_offline_cap"] = use_offline_cap; +    } +    send_join_group_response(group_id, transaction_id, accept_invite, fee, use_offline_cap, payload); +} +  bool join_group_response(const LLSD& notification, const LLSD& response)  {  //	A bit of variable saving and restoring is used to deal with the case where your group list is full and you @@ -770,6 +887,7 @@ bool join_group_response(const LLSD& notification, const LLSD& response)  	std::string name = notification_adjusted["payload"]["name"].asString();  	std::string message = notification_adjusted["payload"]["message"].asString();  	S32 fee = notification_adjusted["payload"]["fee"].asInteger(); +	U8 use_offline_cap = notification_adjusted["payload"]["use_offline_cap"].asInteger();  	if (option == 2 && !group_id.isNull())  	{ @@ -798,42 +916,7 @@ bool join_group_response(const LLSD& notification, const LLSD& response)  			return false;  		}  	} - -	if (accept_invite) -	{ -		// If there is a fee to join this group, make -		// sure the user is sure they want to join. -		if (fee > 0) -		{ -			LLSD args; -			args["COST"] = llformat("%d", fee); -			// Set the fee for next time to 0, so that we don't keep -			// asking about a fee. -			LLSD next_payload = notification_adjusted["payload"]; -			next_payload["fee"] = 0; -			LLNotificationsUtil::add("JoinGroupCanAfford", -									args, -									next_payload); -		} -		else -		{ -			send_improved_im(group_id, -							 std::string("name"), -							 std::string("message"), -							IM_ONLINE, -							IM_GROUP_INVITATION_ACCEPT, -							transaction_id); -		} -	} -	else -	{ -		send_improved_im(group_id, -						 std::string("name"), -						 std::string("message"), -						IM_ONLINE, -						IM_GROUP_INVITATION_DECLINE, -						transaction_id); -	} +	send_join_group_response(group_id, transaction_id, accept_invite, fee, use_offline_cap, notification_adjusted["payload"]);  	sSavedGroupInvite[id] = LLSD::emptyMap();  	sSavedResponse[id] = LLSD::emptyMap(); @@ -1740,7 +1823,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&  		//don't spam them if they are getting flooded  		if (check_offer_throttle(mFromName, true))  		{ -			log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString("."); +			log_message = "<nolink>" + chatHistory_string + "</nolink> " + LLTrans::getString("InvOfferGaveYou") + " " + getSanitizedDescription() + LLTrans::getString(".");  			LLSD args;  			args["MESSAGE"] = log_message;  			LLNotificationsUtil::add("SystemMessageTip", args); @@ -1925,7 +2008,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const  			//don't spam them if they are getting flooded  			if (check_offer_throttle(mFromName, true))  			{ -				log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString("."); +				log_message = "<nolink>" + chatHistory_string + "</nolink> " + LLTrans::getString("InvOfferGaveYou") + " " + getSanitizedDescription() + LLTrans::getString(".");  				LLSD args;  				args["MESSAGE"] = log_message;  				LLNotificationsUtil::add("SystemMessageTip", args); @@ -1998,6 +2081,23 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const  	return false;  } +std::string LLOfferInfo::getSanitizedDescription() +{ +	// currently we get description from server as: 'Object' ( Location ) +	// object name shouldn't be shown as a hyperlink +	std::string description = mDesc; + +	std::size_t start = mDesc.find_first_of("'"); +	std::size_t end = mDesc.find_last_of("'"); +	if ((start != std::string::npos) && (end != std::string::npos)) +	{ +		description.insert(start, "<nolink>"); +		description.insert(end + 8, "</nolink>"); +	} +	return description; +} + +  void LLOfferInfo::initRespondFunctionMap()  {  	if(mRespondFunctions.empty()) diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index b0eaa37541..913abef2be 100644 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -66,6 +66,11 @@ enum InventoryOfferResponse  BOOL can_afford_transaction(S32 cost);  void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_group = FALSE,  				S32 trx_type = TRANS_GIFT, const std::string& desc = LLStringUtil::null); +void send_join_group_response(LLUUID group_id, +							  LLUUID transaction_id, +							  bool accept_invite, +							  S32 fee, +							  bool use_offline_cap);  void process_logout_reply(LLMessageSystem* msg, void**);  void process_layer_data(LLMessageSystem *mesgsys, void **user_data); @@ -257,6 +262,7 @@ public:  private:  	void initRespondFunctionMap(); +	std::string getSanitizedDescription();  	typedef boost::function<bool (const LLSD&, const LLSD&)> respond_function_t;  	typedef std::map<std::string, respond_function_t> respond_function_map_t; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index b759c2a3ab..4f0460da29 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2817,7 +2817,8 @@ void LLViewerRegion::unpackRegionHandshake()  void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  {  	capabilityNames.append("AbuseCategories"); -	//capabilityNames.append("AcceptFriendship"); +	capabilityNames.append("AcceptFriendship"); +	capabilityNames.append("AcceptGroupInvite"); // ReadOfflineMsgs recieved messages only!!!  	capabilityNames.append("AgentPreferences");  	capabilityNames.append("AgentState");  	capabilityNames.append("AttachmentResources"); @@ -2827,7 +2828,8 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("ChatSessionRequest");  	capabilityNames.append("CopyInventoryFromNotecard");  	capabilityNames.append("CreateInventoryCategory"); -	//capabilityNames.append("DeclineFriendship"); +	capabilityNames.append("DeclineFriendship"); +	capabilityNames.append("DeclineGroupInvite"); // ReadOfflineMsgs recieved messages only!!!  	capabilityNames.append("DispatchRegionInfo");  	capabilityNames.append("DirectDelivery");  	capabilityNames.append("EnvironmentSettings"); @@ -2878,7 +2880,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("ParcelVoiceInfoRequest");  	capabilityNames.append("ProductInfoRequest");  	capabilityNames.append("ProvisionVoiceAccountRequest"); -	//capabilityNames.append("ReadOfflineMsgs"); +	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 cef19c9c2d..01ec703fe6 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -3826,37 +3826,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; -					BOOL selecting_linked_set = !gSavedSettings.getBOOL("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; -						} -						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/llweb.cpp b/indra/newview/llweb.cpp index b816225b07..768db047a4 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -268,6 +268,12 @@ bool LLWeb::useExternalBrowser(const std::string &url)  		boost::match_results<std::string::const_iterator> matches;  		return !(boost::regex_search(uri_string, matches, pattern));  	} +	else +	{ +		boost::regex pattern = boost::regex("^mailto:", boost::regex::perl | boost::regex::icase); +		boost::match_results<std::string::const_iterator> matches; +		return boost::regex_search(url, matches, pattern); +	}  	return false;  #endif  } diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 3e66007627..45f14a1192 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -70,7 +70,7 @@ UI-Skalierung: [UI_SCALE]  Sichtweite: [DRAW_DISTANCE] m  Bandbreite: [NET_BANDWITH] kbit/s  LOD-Faktor: [LOD_FACTOR] -Darstellungsqualität: [RENDER_QUALITY] / 7 +Darstellungsqualität: [RENDER_QUALITY]  Erweitertes Beleuchtungsmodell: [GPU_SHADERS]  Texturspeicher: [TEXTURE_MEMORY] MB  Erstellungszeit VFS (Cache): [VFS_TIME] 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 4121acdfb0..60e5a03d51 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notify.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notify.xml @@ -43,6 +43,7 @@           layout="topleft"           left_pad="10"           name="title" +         parse_urls="false"           text_color="GroupNotifyTextColor"           top="5"           use_ellipses="true" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 882fbaf634..f5f4b4acab 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -53,7 +53,7 @@ UI Scaling: [UI_SCALE]  Draw distance: [DRAW_DISTANCE]m  Bandwidth: [NET_BANDWITH]kbit/s  LOD factor: [LOD_FACTOR] -Render quality: [RENDER_QUALITY] / 7 +Render quality: [RENDER_QUALITY]  Advanced Lighting Model: [GPU_SHADERS]  Texture memory: [TEXTURE_MEMORY]MB  VFS (cache) creation time: [VFS_TIME] diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index 341c6d2fe8..8e795de2d6 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -62,7 +62,7 @@ Ajuste de escala de IU: [UI_SCALE]  Distancia de dibujo: [DRAW_DISTANCE]m  Ancho de banda: [NET_BANDWITH]kbit/s  Factor de LOD: [LOD_FACTOR] -Calidad de renderizado: [RENDER_QUALITY] / 7 +Calidad de renderizado: [RENDER_QUALITY]  Modelo de iluminación avanzado: [GPU_SHADERS]  Memoria de textura: [TEXTURE_MEMORY]MB  Tiempo de creación de VFS (caché): [VFS_TIME] diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index d76beee93d..23d93e57bf 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -71,7 +71,7 @@ Ajustement de la taille de la police : [FONT_SIZE_ADJUSTMENT] pts  Limite d’affichage : [DRAW_DISTANCE] m  Bande passante : [NET_BANDWITH] kbit/s  Facteur LOD (niveau de détail) : [LOD_FACTOR] -Qualité de rendu : [RENDER_QUALITY] / 7 +Qualité de rendu : [RENDER_QUALITY]  Modèle d’éclairage avancé : [GPU_SHADERS]  Mémoire textures : [TEXTURE_MEMORY] Mo  Durée de création VFS (cache) : [VFS_TIME] diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index ad74e16170..e2610ef057 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -68,7 +68,7 @@ Scala UI: [UI_SCALE]  Distanza visualizzazione: [DRAW_DISTANCE] m  Larghezza banda: [NET_BANDWITH] kbit/s  Fattore livello di dettaglio: [LOD_FACTOR] -Qualità di rendering: [RENDER_QUALITY] / 7 +Qualità di rendering: [RENDER_QUALITY]  Modello illuminazione avanzato: [GPU_SHADERS]  Memoria texture: [TEXTURE_MEMORY] MB  Data/ora creazione VFS (cache): [VFS_TIME] @@ -1505,7 +1505,7 @@ Se continui a ricevere questo messaggio, contatta l'assistenza Second Life  		Trascina le cartelle in questa area per metterle in vendita su [[MARKETPLACE_DASHBOARD_URL] Marketplace].  	</string>  	<string name="InventoryItemsCount"> -		( [ITEM_COUNT] oggetti ) +		( [ITEMS_COUNT] oggetti )  	</string>  	<string name="Marketplace Validation Warning Stock">  		la cartella di magazzino deve essere inclusa in una cartella di versione diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index 5ca7ddd92c..7faf463fd4 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -71,7 +71,7 @@ UI スケーリング: [UI_SCALE]  描画距離:[DRAW_DISTANCE]m  帯域幅:[NET_BANDWITH]kbit/s  LOD 係数: [LOD_FACTOR] -表示品質: [RENDER_QUALITY] / 7 +表示品質: [RENDER_QUALITY]  高度なライティングモデル: [GPU_SHADERS]  テクスチャメモリ: [TEXTURE_MEMORY]MB  VFS(キャッシュ)作成時間: [VFS_TIME] diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index ee048e28e3..046e7db47c 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -62,7 +62,7 @@ Escala de interface: [UI_SCALE]  Dist. máxima: [DRAW_DISTANCE]m  Largura de banda: [NET_BANDWITH]kbit/s  Fator LOD: [LOD_FACTOR] -Qualidade de renderização: [RENDER_QUALITY] / 7 +Qualidade de renderização: [RENDER_QUALITY]  Modelo de iluminação avançado: [GPU_SHADERS]  Memória de textura: [TEXTURE_MEMORY]MB  Tempo de criação de VFS (cache): [VFS_TIME] 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 @@  	<text name="agree_list">  		Я прочитал и согласен с Условиями и положениями по конфиденциальности Пользовательского соглашения, включая требования по разрешению разногласий Second Life.  	</text> -	<button label="Продолжить" label_selected="Продолжить" name="Continue"/> +	<button label="Продолжить" label_selected="Продолжить" name="Continue" top_delta="45"/>  	<button label="Отмена" label_selected="Отмена" name="Cancel"/>  </floater> diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index 95225da7d0..267c717189 100644 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -71,7 +71,7 @@ SLURL: <nolink>[SLURL]</nolink>  Дальность отрисовки: [DRAW_DISTANCE] м  Ширина канала: [NET_BANDWITH] кбит/с  Коэффициент детализации: [LOD_FACTOR] -Качество визуализации: [RENDER_QUALITY] / 7 +Качество визуализации: [RENDER_QUALITY]  Расширенная модель освещения: [GPU_SHADERS]  Память текстур: [TEXTURE_MEMORY] МБ  Время создания VFS (кэш): [VFS_TIME] diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml index 6850c67df3..6542e61475 100644 --- a/indra/newview/skins/default/xui/tr/strings.xml +++ b/indra/newview/skins/default/xui/tr/strings.xml @@ -71,7 +71,7 @@ Kullanıcı Arayüzü Ölçekleme: [UI_SCALE]  Çizme mesafesi: [DRAW_DISTANCE] m  Bant genişliği: [NET_BANDWITH] kbit/sn  Ayrıntı seviyesi faktörü: [LOD_FACTOR] -İşleme kalitesi: [RENDER_QUALITY] / 7 +İşleme kalitesi: [RENDER_QUALITY]  Gelişmiş Aydınlatma Modeli: [GPU_SHADERS]  Doku belleği: [TEXTURE_MEMORY]MB  VFS (önbellek) oluşturma zamanı: [VFS_TIME] diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml index e4f9c5d433..24d8dc60cb 100644 --- a/indra/newview/skins/default/xui/zh/strings.xml +++ b/indra/newview/skins/default/xui/zh/strings.xml @@ -71,7 +71,7 @@  描繪距離:[DRAW_DISTANCE]公尺  頻寬:[NET_BANDWITH]千位元/秒  細節層次率:[LOD_FACTOR] -呈像品質:[RENDER_QUALITY] / 7 +呈像品質:[RENDER_QUALITY]  進階照明模型:[GPU_SHADERS]  材質記憶體:[TEXTURE_MEMORY]MB  VFS(快取)建立時間:[VFS_TIME]  | 
