diff options
Diffstat (limited to 'indra')
44 files changed, 949 insertions, 386 deletions
| diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index fad69fc6e9..6540b8c959 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -526,7 +526,6 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty  			{  				if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration())  				{ -					posep->setWeight(0.f);  					deactivateMotion(motionp);  				}  				continue; @@ -553,7 +552,6 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty  			}  			else  			{ -				posep->setWeight(0.f);  				deactivateMotion(motionp);  				continue;  			} @@ -804,6 +802,7 @@ BOOL LLMotionController::activateMotion(LLMotion *motion, F32 time)  //-----------------------------------------------------------------------------  BOOL LLMotionController::deactivateMotion(LLMotion *motion)  { +	motion->getPose()->setWeight(0.f);  	motion->deactivate();  	mActiveMotions.remove(motion); diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp index fca2bd2e85..2505295143 100644 --- a/indra/llcommon/llframetimer.cpp +++ b/indra/llcommon/llframetimer.cpp @@ -50,6 +50,12 @@ void LLFrameTimer::reset()  	mExpiry = sFrameTime;  } +void LLFrameTimer::resetWithExpiry(F32 expiration) +{ +	reset(); +	setTimerExpirySec(expiration); +} +  // Don't combine pause/unpause with start/stop  // Useage:  //  LLFrameTime foo; // starts automatically diff --git a/indra/llcommon/llframetimer.h b/indra/llcommon/llframetimer.h index c7c1c50c7b..da777e4ee6 100644 --- a/indra/llcommon/llframetimer.h +++ b/indra/llcommon/llframetimer.h @@ -55,6 +55,7 @@ public:  	void start();  	void stop();  	void reset(); +	void resetWithExpiry(F32 expiration);  	void pause();  	void unpause();  	void setTimerExpirySec(F32 expiration); diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index 57a024ecee..5a0a76b3f3 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -265,3 +265,16 @@ char* ll_print_sd(const LLSD& sd)  	buffer[bufferSize - 1] = '\0';  	return buffer;  } + +char* ll_pretty_print_sd(const LLSD& sd) +{ +	const U32 bufferSize = 10 * 1024; +	static char buffer[bufferSize]; +	std::ostringstream stream; +	//stream.rdbuf()->pubsetbuf(buffer, bufferSize); +	stream << LLSDOStreamer<LLSDXMLFormatter>(sd, LLSDFormatter::OPTIONS_PRETTY); +	stream << std::ends; +	strncpy(buffer, stream.str().c_str(), bufferSize); +	buffer[bufferSize - 1] = '\0'; +	return buffer; +}
\ No newline at end of file diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h index 860232044e..2241cf9426 100644 --- a/indra/llcommon/llsdutil.h +++ b/indra/llcommon/llsdutil.h @@ -65,4 +65,7 @@ LLSD ll_binary_from_string(const LLSD& sd);  // Serializes sd to static buffer and returns pointer, useful for gdb debugging.  char* ll_print_sd(const LLSD& sd); +// Serializes sd to static buffer and returns pointer, using "pretty printing" mode. +char* ll_pretty_print_sd(const LLSD& sd); +  #endif // LL_LLSDUTIL_H diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index c2b2eb27de..38b0cb06c6 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -296,6 +296,11 @@ void LLParcel::setLocalID(S32 local_id)  	mLocalID = local_id;  } +void LLParcel::setAllParcelFlags(U32 flags) +{ +	mParcelFlags = flags; +} +  void LLParcel::setParcelFlag(U32 flag, BOOL b)  {  	if (b) @@ -692,6 +697,16 @@ BOOL LLParcel::importStream(std::istream& input_stream)  			LLString::convertToU32(value, setting);  			setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, setting);  		} +		else if ("allow_voice_chat" == keyword) +		{ +			LLString::convertToU32(value, setting); +			setParcelFlag(PF_ALLOW_VOICE_CHAT, setting); +		} +		else if ("use_estate_voice_chan" == keyword) +		{ +			LLString::convertToU32(value, setting); +			setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, setting); +		}  		else if ("allow_scripts" == keyword)  		{  			LLString::convertToU32(value, setting); @@ -1084,6 +1099,8 @@ BOOL LLParcel::exportStream(std::ostream& output_stream)  	output_stream << "\t\t sound_local	   " << (getSoundLocal() ? 1 : 0)  << "\n";  	output_stream << "\t\t allow_scripts    " << (getAllowOtherScripts()  ? 1 : 0)  << "\n";  	output_stream << "\t\t allow_group_scripts    " << (getAllowGroupScripts()  ? 1 : 0)  << "\n"; +	output_stream << "\t\t allow_voice_chat    " << (getVoiceEnabled() ? 1 : 0) << "\n"; +	output_stream << "\t\t use_estate_voice_chan   " << (getVoiceUseEstateChannel() ? 1 : 0) << "\n";  	output_stream << "\t\t for_sale         " << (getForSale()       ? 1 : 0)  << "\n";  	output_stream << "\t\t sell_w_objects   " << (getSellWithObjects()	? 1 : 0)  << "\n";  	output_stream << "\t\t draw_distance    " << mDrawDistance  << "\n"; diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index af264731ad..1ad51dfd1e 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -147,21 +147,39 @@ public:  	// CREATORS  	LLParcel(); -	LLParcel(	const LLUUID &owner_id, -				BOOL modify, BOOL terraform, BOOL damage, -				time_t claim_date, S32 claim_price, S32 rent_price, S32 area, S32 sim_object_limit, F32 parcel_object_bonus, -				BOOL is_group_owned = FALSE); +	LLParcel( +		const LLUUID &owner_id, +		BOOL modify, +		BOOL terraform, +		BOOL damage, +		time_t claim_date, +		S32 claim_price, +		S32 rent_price, +		S32 area, +		S32 sim_object_limit, +		F32 parcel_object_bonus, +		BOOL is_group_owned = FALSE);  	virtual ~LLParcel(); -	void	init(	const LLUUID &owner_id, -					BOOL modify, BOOL terraform, BOOL damage, -					time_t claim_date, S32 claim_price, S32 rent_price, -					S32 area, S32 sim_object_limit, F32 parcel_object_bonus, BOOL is_group_owned = FALSE); +	void init( +		const LLUUID &owner_id, +		BOOL modify, +		BOOL terraform, +		BOOL damage, +		time_t claim_date, +		S32 claim_price, +		S32 rent_price, +		S32 area, +		S32 sim_object_limit, +		F32 parcel_object_bonus, +		BOOL is_group_owned = FALSE);  	// TODO: make an actual copy constructor for this -	void	overrideParcelFlags(U32 flags); +	void overrideParcelFlags(U32 flags);  	// if you specify an agent id here, the group id will be zeroed -	void	overrideOwner(const LLUUID& owner_id, BOOL is_group_owned = FALSE); +	void overrideOwner( +		const LLUUID& owner_id, +		BOOL is_group_owned = FALSE);  	void overrideSaleTimerExpires(F32 secs_left) { mSaleTimerExpires.setTimerExpirySec(secs_left); }  	// MANIPULATORS @@ -191,7 +209,7 @@ public:  	void setAuctionID(U32 auction_id) { mAuctionID = auction_id;} -	void	setAllParcelFlags(U32 flags) { mParcelFlags = flags; } +	void	setAllParcelFlags(U32 flags);  	void	setParcelFlag(U32 flag, BOOL b);  	void	setArea(S32 area, S32 sim_object_limit); @@ -390,6 +408,10 @@ public:  					{ return (mParcelFlags & PF_FOR_SALE) ? TRUE : FALSE; }  	BOOL	getSoundLocal() const  					{ return (mParcelFlags & PF_SOUND_LOCAL) ? TRUE : FALSE; } +	BOOL	getVoiceEnabled() const +					{ return (mParcelFlags & PF_ALLOW_VOICE_CHAT) ? TRUE : FALSE; } +	BOOL	getVoiceUseEstateChannel() const +					{ return (mParcelFlags & PF_USE_ESTATE_VOICE_CHAN) ? TRUE : FALSE; }  	BOOL	getAllowPublish() const  					{ return (mParcelFlags & PF_ALLOW_PUBLISH) ? TRUE : FALSE; }  	BOOL	getMaturePublish() const diff --git a/indra/llinventory/llparcelflags.h b/indra/llinventory/llparcelflags.h index 43571abe77..d78f9b630b 100644 --- a/indra/llinventory/llparcelflags.h +++ b/indra/llinventory/llparcelflags.h @@ -41,7 +41,8 @@ const U32 PF_ALLOW_GROUP_SCRIPTS		= 1 << 25;	// Allow scripts owned by group  const U32 PF_CREATE_GROUP_OBJECTS		= 1 << 26;	// Allow object creation by group members or objects  const U32 PF_ALLOW_ALL_OBJECT_ENTRY		= 1 << 27;	// Allow all objects to enter a parcel  const U32 PF_ALLOW_GROUP_OBJECT_ENTRY	= 1 << 28;	// Only allow group (and owner) objects to enter the parcel - +const U32 PF_ALLOW_VOICE_CHAT			= 1 << 29;	// Allow residents to use voice chat on this parcel +const U32 PF_USE_ESTATE_VOICE_CHAN      = 1 << 30;  const U32 PF_RESERVED			= 1 << 31; @@ -63,7 +64,9 @@ const U32 PF_DEFAULT =  PF_ALLOW_FLY  						| PF_CREATE_GROUP_OBJECTS  						| PF_USE_BAN_LIST  						| PF_ALLOW_ALL_OBJECT_ENTRY -						| PF_ALLOW_GROUP_OBJECT_ENTRY; +						| PF_ALLOW_GROUP_OBJECT_ENTRY +                        | PF_ALLOW_VOICE_CHAT +                        | PF_USE_ESTATE_VOICE_CHAN;  // Access list flags  const U32 AL_ACCESS  = (1 << 0); diff --git a/indra/llmessage/llbuffer.h b/indra/llmessage/llbuffer.h index 0a0a457d56..7933b84e5c 100644 --- a/indra/llmessage/llbuffer.h +++ b/indra/llmessage/llbuffer.h @@ -19,6 +19,7 @@   */  #include <list> +#include <vector>  /**    * @class LLChannelDescriptors diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp index b2e1500859..9c6e5e7f85 100644 --- a/indra/llmessage/llcachename.cpp +++ b/indra/llmessage/llcachename.cpp @@ -623,6 +623,12 @@ void LLCacheName::dumpStats()  			<< llendl;  } +//static  +LLString LLCacheName::getDefaultName() +{ +	return LLString(CN_WAITING); +} +  void LLCacheName::Impl::processPendingAsks()  {  	sendRequest(_PREHASH_UUIDNameRequest, mAskNameQueue); diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h index c4f88ac490..3c8a6587b1 100644 --- a/indra/llmessage/llcachename.h +++ b/indra/llmessage/llcachename.h @@ -81,6 +81,8 @@ public:  	void dump();		// Dumps the contents of the cache  	void dumpStats();	// Dumps the sizes of the cache and associated queues. +	static LLString getDefaultName(); +  private:  	class Impl;  	Impl& impl; diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index a7d187f534..16586dc9c7 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -50,6 +50,29 @@ void LLHTTPClient::Responder::result(const LLSD& content)  {  } +// virtual  +void LLHTTPClient::Responder::completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, +								const LLIOPipe::buffer_ptr_t& buffer) +{ +	LLBufferStream istr(channels, buffer.get()); +	LLSD content; + +	if (200 <= status && status < 300) +	{ +		LLSDSerialize::fromXML(content, istr); +/* +		const S32 parseError = -1; +		if(LLSDSerialize::fromXML(content, istr) == parseError) +		{ +			mStatus = 498; +			mReason = "Client Parse Error"; +		} +*/ +	} +	 +	completed(status, reason, content); +} +  // virtual  void LLHTTPClient::Responder::completed(U32 status, const std::string& reason, const LLSD& content)  { @@ -88,25 +111,9 @@ namespace  		virtual void complete(const LLChannelDescriptors& channels,  								const buffer_ptr_t& buffer)  		{ -			LLBufferStream istr(channels, buffer.get()); -			LLSD content; - -			if (200 <= mStatus && mStatus < 300) -			{ -				LLSDSerialize::fromXML(content, istr); -/* -				const S32 parseError = -1; -				if(LLSDSerialize::fromXML(content, istr) == parseError) -				{ -					mStatus = 498; -					mReason = "Client Parse Error"; -				} -*/ -			} -  			if (mResponder.get())  			{ -				mResponder->completed(mStatus, mReason, content); +				mResponder->completedRaw(mStatus, mReason, channels, buffer);  			}  		} @@ -223,15 +230,18 @@ namespace  	LLPumpIO* theClientPump = NULL;  } -static void request(const std::string& url, LLURLRequest::ERequestAction method, -	Injector* body_injector, LLHTTPClient::ResponderPtr responder, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS) +static void request( +	const std::string& url, +	LLURLRequest::ERequestAction method, +	Injector* body_injector, +	LLHTTPClient::ResponderPtr responder, +	const F32 timeout=HTTP_REQUEST_EXPIRY_SECS)  {  	if (!LLHTTPClient::hasPump())  	{  		responder->completed(U32_MAX, "No pump", LLSD());  		return;  	} -  	LLPumpIO::chain_t chain;  	LLURLRequest *req = new LLURLRequest(method, url); @@ -242,7 +252,8 @@ static void request(const std::string& url, LLURLRequest::ERequestAction method,  	}  	req->setCallback(new LLHTTPClientURLAdaptor(responder)); -	if (method == LLURLRequest::HTTP_POST  &&  gMessageSystem) { +	if (method == LLURLRequest::HTTP_POST  &&  gMessageSystem) +	{  		req->addHeader(llformat("X-SecondLife-UDP-Listen-Port: %d",  								gMessageSystem->mPort).c_str());     	} diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h index f2674ba417..447bd691ba 100644 --- a/indra/llmessage/llhttpclient.h +++ b/indra/llmessage/llhttpclient.h @@ -18,6 +18,8 @@  #include <boost/intrusive_ptr.hpp>  #include "llassettype.h" +#include "llbuffer.h" +#include "lliopipe.h"  extern const F32 HTTP_REQUEST_EXPIRY_SECS; @@ -38,7 +40,11 @@ public:  		virtual void error(U32 status, const std::string& reason);	// called with bad status codes  		virtual void result(const LLSD& content); -			 +		 +		// Override point for clients that may want to use this class when the response is some other format besides LLSD +		virtual void completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, +								const LLIOPipe::buffer_ptr_t& buffer); +  		virtual void completed(U32 status, const std::string& reason, const LLSD& content);  			/**< The default implemetnation calls  				either: diff --git a/indra/llmessage/llinstantmessage.cpp b/indra/llmessage/llinstantmessage.cpp index 28886108ea..132f4f6e7b 100644 --- a/indra/llmessage/llinstantmessage.cpp +++ b/indra/llmessage/llinstantmessage.cpp @@ -308,18 +308,46 @@ LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info)  	param_message["parent_estate_id"] = (S32)im_info->mParentEstateID;  	param_message["region_id"] = im_info->mRegionID;  	param_message["position"] = ll_sd_from_vector3(im_info->mPosition); -	if (im_info->mData) param_message["data"] = im_info->mData; +	param_message["data"] = im_info->mData; +	param_message["source"]= im_info->mSource; +	param_message["ttl"] = im_info->mTTL; +  	LLSD param_agent;  	param_agent["agent_id"] = im_info->mFromID;  	LLSD params; -	params.append(param_version); -	params.append(param_message); -	params.append(param_agent); +	params["version_params"] = param_version; +	params["message_params"] = param_message; +	params["agent_params"] = param_agent;  	return params;  } +LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd) +{ +	LLSD param_message = im_info_sd["message_params"]; +	LLSD param_agent = im_info_sd["agent_params"]; + +	LLPointer<LLIMInfo> im_info = new LLIMInfo( +		param_message["from_id"].asUUID(), +		param_message["from_group"].asBoolean(), +		param_message["to_id"].asUUID(), +		(EInstantMessage) param_message["type"].asInteger(), +		param_message["from_name"].asString(), +		param_message["message"].asString(), +		param_message["id"].asUUID(), +		(U32) param_message["parent_estate_id"].asInteger(), +		im_info->mRegionID = param_message["region_id"].asUUID(), +		ll_vector3_from_sd(param_message["position"]), +		param_message["data"], +		(U8) param_message["offline"].asInteger(), +		(U32) param_message["timestamp"].asInteger(), +		(EIMSource)param_message["source"].asInteger(), +		param_message["ttl"].asInteger()); + +	return im_info; +} +  LLPointer<LLIMInfo> LLIMInfo::clone()  {  	return new LLIMInfo( diff --git a/indra/llmessage/llinstantmessage.h b/indra/llmessage/llinstantmessage.h index 99b2734a70..7292ff42de 100644 --- a/indra/llmessage/llinstantmessage.h +++ b/indra/llmessage/llinstantmessage.h @@ -74,13 +74,10 @@ enum EInstantMessage  	// communicate with each other.  	// -	// Add users to a session. -	IM_SESSION_ADD = 13, +	// Invite users to a session. +	IM_SESSION_INVITE = 13, -	// IM sent automatically on call for help,  -	// sets up a way for each Helper reached to teleport to the -	// helpee -	IM_SESSION_911_SEND = 14, +	IM_SESSION_P2P_INVITE = 14,  	// start a session with your gruop  	IM_SESSION_GROUP_START = 15, @@ -92,7 +89,7 @@ enum EInstantMessage  	IM_SESSION_SEND = 17,  	// leave a session -	IM_SESSION_DROP = 18, +	IM_SESSION_LEAVE = 18,  	// an instant message from an object - for differentiation on the  	// viewer, since you can't IM an object yet. @@ -121,14 +118,6 @@ enum EInstantMessage  	// bucket.  	IM_GOTO_URL = 28, -	// IM for help from the GAURDIAN_ANGELS -	// Binary bucket contains the name of the session. -	IM_SESSION_911_START = 29, - -	// IM for requesting to teleport to the creator -	// of a livehelp session (assuming they are verified first) -	IM_TELEPORT_911 = 30, -  	// a message generated by a script which we don't want to  	// be sent through e-mail.  Similar to IM_FROM_TASK, but  	// it is shown as an alert on the viewer. @@ -268,6 +257,7 @@ public:  	S32 mTTL;  }; +LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd);  LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info);  void pack_instant_message( diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h index 15e7a32257..28a741789c 100644 --- a/indra/llmessage/llregionflags.h +++ b/indra/llmessage/llregionflags.h @@ -36,7 +36,7 @@ const U32 REGION_FLAGS_BLOCK_LAND_RESELL		= (1 << 7);  // All content wiped once per night  const U32 REGION_FLAGS_SANDBOX					= (1 << 8); - +const U32 REGION_FLAGS_NULL_LAYER				= (1 << 9);  const U32 REGION_FLAGS_SKIP_AGENT_ACTION		= (1 << 10);  const U32 REGION_FLAGS_SKIP_UPDATE_INTEREST_LIST= (1 << 11);  const U32 REGION_FLAGS_SKIP_COLLISIONS			= (1 << 12); // Pin all non agent rigid bodies @@ -68,11 +68,14 @@ const U32 REGION_FLAGS_ALLOW_PARCEL_CHANGES		= (1 << 26);  const U32 REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER = (1 << 27); -const U32 REGION_FLAGS_NULL_LAYER				= (1 << 9); +const U32 REGION_FLAGS_ALLOW_VOICE = (1 << 28); +  const U32 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK |  								 REGION_FLAGS_ALLOW_SET_HOME | -								 REGION_FLAGS_ALLOW_PARCEL_CHANGES; +                                 REGION_FLAGS_ALLOW_PARCEL_CHANGES | +                                 REGION_FLAGS_ALLOW_VOICE; +  const U32 REGION_FLAGS_PRELUDE_SET = REGION_FLAGS_RESET_HOME_ON_TELEPORT;  const U32 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK  diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index a305797fd2..c00a0fe154 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -2927,17 +2927,19 @@ static LLHTTPNode& messageRootNode()  }  //static -void LLMessageSystem::dispatch(const std::string& msg_name, -								const LLSD& message) +void LLMessageSystem::dispatch( +	const std::string& msg_name, +	const LLSD& message)  {  	LLPointer<LLSimpleResponse>	responsep =	LLSimpleResponse::create();  	dispatch(msg_name, message, responsep);  }  //static -void LLMessageSystem::dispatch(const std::string& msg_name, -								const LLSD& message, -							   LLHTTPNode::ResponsePtr responsep) +void LLMessageSystem::dispatch( +	const std::string& msg_name, +	const LLSD& message, +	LLHTTPNode::ResponsePtr responsep)  {  	if (msg_name.empty())  	{ diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index ddd81e77b3..d28cf96fa0 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -595,6 +595,56 @@ void LLButton::draw()  			gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, LLColor4::pink1, FALSE);  		} +		// draw overlay image +		if (mImageOverlay.notNull()) +		{ +			const S32 IMG_PAD = 4; +			// get max width and height (discard level 0) +			S32 overlay_width = mImageOverlay->getWidth(0); +			S32 overlay_height = mImageOverlay->getHeight(0); + +			F32 scale_factor = llmin((F32)mRect.getWidth() / (F32)overlay_width, (F32)mRect.getHeight() / (F32)overlay_height, 1.f); +			overlay_width = llround((F32)overlay_width * scale_factor); +			overlay_height = llround((F32)overlay_height * scale_factor); + +			S32 center_x = getLocalRect().getCenterX(); +			S32 center_y = getLocalRect().getCenterY(); + +			switch(mImageOverlayAlignment) +			{ +			case LLFontGL::LEFT: +				gl_draw_scaled_image( +					IMG_PAD,  +					center_y - (overlay_height / 2),  +					overlay_width,  +					overlay_height,  +					mImageOverlay, +					LLColor4::white); +				break; +			case LLFontGL::HCENTER: +				gl_draw_scaled_image( +					center_x - (overlay_width / 2),  +					center_y - (overlay_height / 2),  +					overlay_width,  +					overlay_height,  +					mImageOverlay, +					LLColor4::white); +				break; +			case LLFontGL::RIGHT: +				gl_draw_scaled_image( +					mRect.getWidth() - IMG_PAD - overlay_width,  +					center_y - (overlay_height / 2),  +					overlay_width,  +					overlay_height,  +					mImageOverlay, +					LLColor4::white); +				break; +			default: +				// draw nothing +				break; +			} +		} +  		// Draw label  		if( !label.empty() )  		{ @@ -806,6 +856,21 @@ void LLButton::setHoverImages( const LLString& image_name, const LLString& selec  	setImageHoverSelected(selected_name);  } +void LLButton::setImageOverlay(const LLString &image_name, LLFontGL::HAlign alignment) +{ +	if (image_name.empty()) +	{ +		mImageOverlay = NULL; +	} +	else +	{ +		LLUUID overlay_image_id = LLUI::findAssetUUIDByName(image_name); +		mImageOverlay = LLUI::sImageProvider->getUIImageByID(overlay_image_id); +		mImageOverlayAlignment = alignment; +	} +} + +  void LLButton::onMouseCaptureLost()  {  	mMouseDownTimer.stop(); @@ -978,6 +1043,18 @@ LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa  	LLString	image_disabled;  	if (node->hasAttribute("image_disabled")) node->getAttributeString("image_disabled",image_disabled); +	LLString	image_overlay; +	node->getAttributeString("image_overlay", image_overlay); + +	LLFontGL::HAlign image_overlay_alignment = LLFontGL::HCENTER; +	LLString image_overlay_alignment_string; +	if (node->hasAttribute("image_overlay_alignment")) +	{ +		node->getAttributeString("image_overlay_alignment", image_overlay_alignment_string); +		image_overlay_alignment = LLFontGL::hAlignFromName(image_overlay_alignment_string); +	} + +  	LLButton *button = new LLButton(name,   			LLRect(),  			image_unselected, @@ -1000,6 +1077,7 @@ LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa  	if(image_disabled != LLString::null) button->setImageDisabled(image_disabled); +	if(image_overlay != LLString::null) button->setImageOverlay(image_overlay, image_overlay_alignment);  	if (node->hasAttribute("halign"))  	{ diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 9048358bd8..470c34fb64 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -122,6 +122,10 @@ public:  	void			setDisabledSelectedLabelColor( const LLColor4& c )	{ mDisabledSelectedLabelColor = c; } +	void			setImageOverlay(const LLString &image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER); +	LLPointer<LLImageGL> getImageOverlay() { return mImageOverlay; } +	 +  	virtual void	setValue(const LLSD& value );  	virtual LLSD	getValue() const; @@ -182,6 +186,9 @@ protected:  	F32				mHeldDownDelay;		// seconds, after which held-down callbacks get called  	S32				mHeldDownFrameDelay;	// frames, after which held-down callbacks get called +	LLPointer<LLImageGL>	mImageOverlay; +	LLFontGL::HAlign		mImageOverlayAlignment; +  	LLPointer<LLImageGL>	mImageUnselected;  	LLUIString				mUnselectedLabel;  	LLColor4				mUnselectedLabelColor; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index fd8947c594..66642d8f34 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -555,17 +555,20 @@ void LLFloater::close(bool app_quitting)  		cleanupHandles();  		gFocusMgr.clearLastFocusForGroup(this); -		// Do this early, so UI controls will commit before the -		// window is taken down. -		releaseFocus(); - -		// give focus to dependee floater if it exists, and we had focus first -		if (isDependent()) +		if (hasFocus())  		{ -			LLFloater* dependee = LLFloater::getFloaterByHandle(mDependeeHandle); -			if (dependee && !dependee->isDead()) +			// Do this early, so UI controls will commit before the +			// window is taken down. +			releaseFocus(); + +			// give focus to dependee floater if it exists, and we had focus first +			if (isDependent())  			{ -				dependee->setFocus(TRUE); +				LLFloater* dependee = LLFloater::getFloaterByHandle(mDependeeHandle); +				if (dependee && !dependee->isDead()) +				{ +					dependee->setFocus(TRUE); +				}  			}  		} @@ -1150,6 +1153,28 @@ BOOL LLFloater::getEditModeEnabled()  	return sEditModeEnabled;  } +//static  +void LLFloater::show(LLFloater* floaterp) +{ +	if (floaterp) floaterp->open(); +} + +//static  +void LLFloater::hide(LLFloater* floaterp) +{ +	if (floaterp) floaterp->close(); +} + +//static +BOOL LLFloater::visible(LLFloater* floaterp) +{ +	if (floaterp)  +	{ +		return floaterp->isInVisibleChain(); +	} +	return FALSE; +} +  // static  void LLFloater::onClickMinimize(void *userdata)  { @@ -2352,7 +2377,7 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)  LLMultiFloater::LLMultiFloater() :  	mTabContainer(NULL),  	mTabPos(LLTabContainerCommon::TOP), -	mAutoResize(FALSE) +	mAutoResize(TRUE)  {  } @@ -2360,7 +2385,7 @@ LLMultiFloater::LLMultiFloater() :  LLMultiFloater::LLMultiFloater(LLTabContainerCommon::TabPosition tab_pos) :  	mTabContainer(NULL),  	mTabPos(tab_pos), -	mAutoResize(FALSE) +	mAutoResize(TRUE)  {  } @@ -2574,15 +2599,12 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,  	floaterp->setCanResize(FALSE);  	floaterp->setCanDrag(FALSE); -	S32 new_width = llmax(mRect.getWidth(), floaterp->getRect().getWidth());  -	S32 new_height = llmax(mRect.getHeight(), floaterp->getRect().getHeight() + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT);  - -	reshape(new_width, new_height); -  	//add the panel, add it to proper maps  	mTabContainer->addTabPanel(floaterp, floaterp->getTitle(), FALSE, onTabSelected, this, 0, FALSE, insertion_point);  	mFloaterDataMap[floaterp->getHandle()] = floater_data; +	resizeToContents(); +  	if ( select_added_floater )  	{  		mTabContainer->selectLastTab(); @@ -2656,10 +2678,7 @@ void LLMultiFloater::removeFloater(LLFloater* floaterp)  	floaterp->setBackgroundVisible(TRUE);  	floaterp->setHost(NULL); -	if (mAutoResize) -	{ -		resizeToContents(); -	} +	resizeToContents();  	tabOpen((LLFloater*)mTabContainer->getCurrentPanel(), false);  } @@ -2709,7 +2728,8 @@ BOOL LLMultiFloater::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)  		if (key == 'W')  		{  			LLFloater* floater = getActiveFloater(); -			if (floater && floater->canClose()) +			// is user closeable and is system closeable +			if (floater && floater->canClose() && floater->isCloseable())  			{  				floater->close();  			} @@ -2828,10 +2848,17 @@ void LLMultiFloater::resizeToContents()  	S32 cur_height = mRect.getHeight(); -	reshape(new_width, new_height); +	if (mAutoResize) +	{ +		reshape(new_width, new_height); +	} +	else +	{ +		reshape(llmax(new_min_width, mRect.getWidth()), llmax(new_min_height, mRect.getHeight())); +	}  	// make sure upper left corner doesn't move -	translate(0, cur_height - new_height); +	translate(0, cur_height - mRect.getHeight());  	// Try to keep whole view onscreen, don't allow partial offscreen.  	gFloaterView->adjustToFitScreen(this, FALSE); diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 90063108f5..c71f3df3e8 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -192,6 +192,10 @@ public:  	static BOOL		getEditModeEnabled();  	static LLMultiFloater*		getFloaterHost() {return sHostp; } +	static void		show(LLFloater* floaterp); +	static void		hide(LLFloater* floaterp); +	static BOOL		visible(LLFloater* floaterp); +  	static LLFloater* getFloaterByHandle(LLViewHandle handle);  protected: @@ -259,7 +263,6 @@ protected:  	std::vector<LLView*> mMinimizedHiddenChildren;  }; -  /////////////////////////////////////////////////////////////  // LLFloaterView  // Parent of all floating panels @@ -334,8 +337,8 @@ public:  	LLMultiFloater();  	LLMultiFloater(LLTabContainerCommon::TabPosition tab_pos);  	LLMultiFloater(const LLString& name); -	LLMultiFloater(const LLString& name, const LLRect& rect, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = FALSE); -	LLMultiFloater(const LLString& name, const LLString& rect_control, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = FALSE); +	LLMultiFloater(const LLString& name, const LLRect& rect, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE); +	LLMultiFloater(const LLString& name, const LLString& rect_control, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE);  	virtual ~LLMultiFloater();  	virtual BOOL postBuild(); @@ -396,3 +399,4 @@ extern LLFloaterView* gFloaterView;  #endif  // LL_FLOATER_H + diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 94d5d7ae75..4c01387941 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -79,7 +79,7 @@ protected:  // LLScrollListIcon  //  LLScrollListIcon::LLScrollListIcon(LLImageGL* icon, S32 width, LLUUID image_id) : -mIcon(icon), mImageUUID(image_id.asString()) +mIcon(icon), mColor(LLColor4::white), mImageUUID(image_id.asString())  {  	if (width)  	{ @@ -95,6 +95,16 @@ LLScrollListIcon::~LLScrollListIcon()  {  } +void LLScrollListIcon::setColor(const LLColor4& color) +{ +	mColor = color; +} + +void LLScrollListIcon::drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const	 +{ +	gl_draw_image(0, 0, mIcon, mColor);  +} +  //  // LLScrollListCheck  // @@ -188,6 +198,15 @@ LLScrollListText::~LLScrollListText()  	delete mColor;  } +void LLScrollListText::setColor(const LLColor4& color) +{ +	if (!mColor) +	{ +		mColor = new LLColor4(); +	} +	*mColor = color; +} +  void LLScrollListText::setText(const LLString& text)  {  	mText = text; @@ -2789,6 +2808,8 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p  		LLString fontname = (*itor)["font"].asString();  		LLString fontstyle = (*itor)["font-style"].asString();  		LLString type = (*itor)["type"].asString(); +		BOOL has_color = (*itor).has("color"); +		LLColor4 color = ((*itor)["color"]);  		const LLFontGL *font = gResMgr->getRes(fontname);  		if (!font) @@ -2801,21 +2822,41 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p  		{  			LLUUID image_id = value.asUUID();  			LLImageGL* icon = LLUI::sImageProvider->getUIImageByID(image_id); -			new_item->setColumn(index, new LLScrollListIcon(icon, width, image_id)); +			LLScrollListIcon* cell = new LLScrollListIcon(icon, width, image_id); +			if (has_color) +			{ +				cell->setColor(color); +			} +			new_item->setColumn(index, cell);  		}  		else if (type == "checkbox")  		{  			LLCheckBoxCtrl* ctrl = new LLCheckBoxCtrl(value.asString(),  														LLRect(0, 0, width, width), "label"); -			new_item->setColumn(index, new LLScrollListCheck(ctrl,width)); +			LLScrollListCheck* cell = new LLScrollListCheck(ctrl,width); +			if (has_color) +			{ +				cell->setColor(color); +			} +			new_item->setColumn(index, cell);  		}  		else if (type == "separator")  		{ -			new_item->setColumn(index, new LLScrollListSeparator(width)); +			LLScrollListSeparator* cell = new LLScrollListSeparator(width); +			if (has_color) +			{ +				cell->setColor(color); +			} +			new_item->setColumn(index, cell);  		}  		else  		{ -			new_item->setColumn(index, new LLScrollListText(value.asString(), font, width, font_style, font_alignment)); +			LLScrollListText* cell = new LLScrollListText(value.asString(), font, width, font_style, font_alignment); +			if (has_color) +			{ +				cell->setColor(color); +			} +			new_item->setColumn(index, cell);  			if (columnp->mHeader && !value.asString().empty())  			{  				columnp->mHeader->setHasResizableElement(TRUE); diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index de9b58bd1e..dff522bc0b 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -43,6 +43,7 @@ public:  	virtual void			setWidth(S32 width) = 0;  	virtual void			highlightText(S32 offset, S32 num_chars) {}  	virtual BOOL			isText() = 0; +	virtual void			setColor(const LLColor4&) = 0;  	virtual BOOL	handleClick() { return FALSE; }  	virtual	void	setEnabled(BOOL enable) { } @@ -57,6 +58,7 @@ public:  	virtual S32				getWidth() const {return mWidth;}  	virtual S32				getHeight() const { return 5; };  	virtual void			setWidth(S32 width) {mWidth = width; } +	virtual void			setColor(const LLColor4&) {};  	virtual BOOL			isText() { return FALSE; }  protected: @@ -77,6 +79,7 @@ public:  	virtual const BOOL			getVisible() const  { return mVisible; }  	virtual void	highlightText(S32 offset, S32 num_chars) {mHighlightOffset = offset; mHighlightCount = num_chars;}  	void			setText(const LLString& text); +	virtual void	setColor(const LLColor4&);  	virtual BOOL	isText() { return TRUE; }  private: @@ -100,18 +103,20 @@ class LLScrollListIcon : public LLScrollListCell  public:  	LLScrollListIcon( LLImageGL* icon, S32 width = 0, LLUUID image_id = LLUUID::null);  	/*virtual*/ ~LLScrollListIcon(); -	virtual void	drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const	{ gl_draw_image(0, 0, mIcon); } +	virtual void	drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const;  	virtual S32		getWidth() const			{ return mWidth; }  	virtual S32		getHeight() const			{ return mIcon->getHeight(); }  	virtual const LLString& getText() const { return mImageUUID; }  	virtual const LLString& getTextLower() const { return mImageUUID; }  	virtual void	setWidth(S32 width)			{ mWidth = width; } +	virtual void	setColor(const LLColor4&);  	virtual BOOL	isText() { return FALSE; }  private:  	LLPointer<LLImageGL> mIcon;  	LLString mImageUUID;  	S32 mWidth; +	LLColor4 mColor;  };  class LLScrollListCheck : public LLScrollListCell @@ -126,6 +131,7 @@ public:  	virtual BOOL	handleClick();  	virtual void	setEnabled(BOOL enable)		{ if (mCheckBox) mCheckBox->setEnabled(enable); } +	virtual void	setColor(const LLColor4& color) {};  	LLCheckBoxCtrl*	getCheckBox()				{ return mCheckBox; }  	virtual BOOL	isText() { return FALSE; } diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index a5bad91670..2844640291 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -57,7 +57,8 @@ LLTabContainerCommon::LLTabContainerCommon(  	mCallbackUserdata( callback_userdata ),  	mTitleBox(NULL),  	mTopBorderHeight(LLPANEL_BORDER_WIDTH), -	mTabPosition(pos) +	mTabPosition(pos), +	mLockedTabCount(0)  {   	setMouseOpaque(FALSE);  } @@ -122,6 +123,13 @@ void LLTabContainerCommon::addPlaceholder(LLPanel* child, const LLString& label)  	addTabPanel(child, label, FALSE, NULL, NULL, 0, TRUE);  } +void LLTabContainerCommon::lockTabs() +{ +	// count current tabs and ensure no new tabs get +	// inserted between them +	mLockedTabCount = getTabCount(); +} +  void LLTabContainerCommon::removeTabPanel(LLPanel* child)  {  	BOOL has_focus = gFocusMgr.childHasKeyboardFocus(this); @@ -144,6 +152,10 @@ void LLTabContainerCommon::removeTabPanel(LLPanel* child)  			break;  		}  	} + +	// make sure we don't have more locked tabs than we have tabs +	mLockedTabCount = llmin(getTabCount(), mLockedTabCount); +  	if (mCurrentTabIdx >= (S32)mTabList.size())  	{  		mCurrentTabIdx = mTabList.size()-1; @@ -506,6 +518,15 @@ void LLTabContainerCommon::setTabPanelFlashing(LLPanel* child, BOOL state )  	}  } +void LLTabContainerCommon::setTabImage(LLPanel* child, std::string img_name) +{ +	LLTabTuple* tuple = getTabByPanel(child); +	if( tuple ) +	{ +		tuple->mButton->setImageOverlay(img_name, LLFontGL::RIGHT); +	} +} +  void LLTabContainerCommon::setTitle(const LLString& title)  {  	if (mTitleBox) @@ -667,12 +688,12 @@ void LLTabContainerCommon::insertTuple(LLTabTuple * tuple, eInsertionPoint inser  	{  	case START:  		// insert the new tab in the front of the list -		mTabList.insert(mTabList.begin(), tuple); +		mTabList.insert(mTabList.begin() + mLockedTabCount, tuple);  		break;  	case RIGHT_OF_CURRENT: -		// insert the new tab after the current tab +		// insert the new tab after the current tab (but not before mLockedTabCount)  		{ -		tuple_list_t::iterator current_iter = mTabList.begin() + mCurrentTabIdx + 1; +		tuple_list_t::iterator current_iter = mTabList.begin() + llmax(mLockedTabCount, mCurrentTabIdx + 1);  		mTabList.insert(current_iter, tuple);  		}  		break; @@ -1229,6 +1250,7 @@ void LLTabContainer::draw()  		for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)  		{  			LLTabTuple* tuple = *iter; +  			tuple->mButton->translate( left - tuple->mButton->getRect().mLeft, 0 );  			left += tuple->mButton->getRect().getWidth(); @@ -1576,3 +1598,27 @@ BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,	BOOL drop,	EDrag  	return LLView::handleDragAndDrop(x,	y, mask, drop, type, cargo_data,  accept, tooltip);  } + +void LLTabContainer::setTabImage(LLPanel* child, std::string image_name) +{ +	LLTabTuple* tuple = getTabByPanel(child); +	if( tuple ) +	{ +		tuple->mButton->setImageOverlay(image_name, LLFontGL::RIGHT); + +		const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); +		// remove current width from total tab strip width +		mTotalTabWidth -= tuple->mButton->getRect().getWidth(); + +		S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ?  +			tuple->mButton->getImageOverlay()->getWidth(0) : +			0; +		tuple->mButton->reshape(llclamp(fontp->getWidth(tuple->mButton->getLabelSelected()) + TAB_PADDING + image_overlay_width, mMinTabWidth, mMaxTabWidth),  +								tuple->mButton->getRect().getHeight()); +		// add back in button width to total tab strip width +		mTotalTabWidth += tuple->mButton->getRect().getWidth(); + +		// tabs have changed size, might need to scroll to see current tab +		updateMaxScrollPos(); +	} +}
\ No newline at end of file diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index aa4c1c608a..fbb73b951b 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -67,7 +67,8 @@ public:  							 BOOL placeholder = FALSE,  							 eInsertionPoint insertion_point = END) = 0;  	virtual void		addPlaceholder(LLPanel* child, const LLString& label); -	 +	virtual void		lockTabs(); +  	virtual void		enableTabButton(S32 which, BOOL enable);  	virtual void removeTabPanel( LLPanel* child ); @@ -93,6 +94,7 @@ public:  	BOOL        getTabPanelFlashing(LLPanel* child);  	void		setTabPanelFlashing(LLPanel* child, BOOL state); +	virtual void setTabImage(LLPanel* child, std::string img_name);  	void		setTitle( const LLString& title );  	const LLString getPanelTitle(S32 index); @@ -160,6 +162,7 @@ protected:  	S32								mTopBorderHeight;  	TabPosition 					mTabPosition; +	S32								mLockedTabCount;  protected:  	void		scrollPrev(); @@ -201,7 +204,7 @@ public:  	/*virtual*/ void removeTabPanel( LLPanel* child );  	/*virtual*/ void		setPanelTitle(S32 index, const LLString& title); - +	/*virtual*/ void		setTabImage(LLPanel* child, std::string img_name);  	/*virtual*/ void		setRightTabBtnOffset( S32 offset );  	/*virtual*/ void		setMinTabWidth(S32 width); diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 9363415dc2..f8e1e33cad 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -331,7 +331,7 @@ LLTextEditor::LLTextEditor(  	mBorder = new LLViewBorder( "text ed border", LLRect(0, mRect.getHeight(), mRect.getWidth(), 0), LLViewBorder::BEVEL_IN, LLViewBorder::STYLE_LINE, UI_TEXTEDITOR_BORDER );  	addChild( mBorder ); -	setText(default_text); +	appendText(default_text, FALSE, FALSE);  	mParseHTML=FALSE;  	mHTML=""; @@ -2630,7 +2630,8 @@ void LLTextEditor::drawSelectionBackground()  		{  			LLGLSNoTexture no_texture;  			const LLColor4& color = mReadOnly ? mReadOnlyBgColor : mWriteableBgColor; -			glColor3f( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2] ); +			F32 alpha = hasFocus() ? 1.f : 0.5f; +			glColor4f( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], alpha );  			if( selection_left_y == selection_right_y )  			{ @@ -3357,6 +3358,14 @@ void LLTextEditor::appendColoredText(const LLString &new_text,  	style.setVisible(true);  	style.setColor(color);  	style.setFontName(font_name); +	appendStyledText(new_text, allow_undo, prepend_newline, &style); +} + +void LLTextEditor::appendStyledText(const LLString &new_text,  +									 bool allow_undo,  +									 bool prepend_newline, +									 const LLStyle* style) +{  	if(mParseHTML)  	{ @@ -3367,10 +3376,13 @@ void LLTextEditor::appendColoredText(const LLString &new_text,  			LLStyle html;  			html.setVisible(true);  			html.setColor(mLinkColor); -			html.setFontName(font_name); +			if (style) +			{ +				html.setFontName(style->getFontString()); +			}  			html.mUnderline = TRUE; -			if (start > 0) appendText(text.substr(0,start),allow_undo, prepend_newline, &style); +			if (start > 0) appendText(text.substr(0,start),allow_undo, prepend_newline, style);  			html.setLinkHREF(text.substr(start,end-start));  			appendText(text.substr(start, end-start),allow_undo, prepend_newline, &html);  			if (end < (S32)text.length())  @@ -3383,22 +3395,14 @@ void LLTextEditor::appendColoredText(const LLString &new_text,  				break;  			}  		} -		if (end < (S32)text.length()) appendText(text,allow_undo, prepend_newline, &style);		 +		if (end < (S32)text.length()) appendText(text,allow_undo, prepend_newline, style);	  	}  	else  	{ -		appendText(new_text, allow_undo, prepend_newline, &style); +		appendText(new_text, allow_undo, prepend_newline, style);  	}  } -void LLTextEditor::appendStyledText(const LLString &new_text,  -									 bool allow_undo,  -									 bool prepend_newline, -									 const LLStyle &style) -{ -	appendText(new_text, allow_undo, prepend_newline, &style); -} -  // Appends new text to end of document  void LLTextEditor::appendText(const LLString &new_text, bool allow_undo, bool prepend_newline,  							  const LLStyle* segment_style) diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 7454b192fd..1a82d3e8c8 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -139,7 +139,7 @@ public:  	// if styled text starts a line, you need to prepend a newline.  	void 			appendStyledText(const LLString &new_text, bool allow_undo,   									 bool prepend_newline, -									 const LLStyle &style); +									 const LLStyle* style);  	// Removes text from the end of document  	// Does not change highlight or cursor position. diff --git a/indra/llui/llui.h b/indra/llui/llui.h index c8c244072e..dbe79338e5 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -255,4 +255,95 @@ typedef enum e_widget_type  	WIDGET_TYPE_COUNT  } EWidgetType; +// Manages generation of UI elements by LLSD, such that there is +// only one instance per uniquely identified LLSD parameter +// Class T is the instance type being managed, and INSTANCE_ADDAPTOR +// wraps an instance of the class with handlers for show/hide semantics, etc. +template <class T, class INSTANCE_ADAPTOR = T> +class LLUIInstanceMgr +{ +public: +	LLUIInstanceMgr() +	{ +	} + + 	virtual ~LLUIInstanceMgr()  +	{  +	} + +	// default show and hide methods +	static T* showInstance(const LLSD& seed)  +	{  +		T* instance = INSTANCE_ADAPTOR::getInstance(seed);  +		INSTANCE_ADAPTOR::show(instance); +		return instance; +	} + +	static void hideInstance(const LLSD& seed)  +	{  +		T* instance = INSTANCE_ADAPTOR::getInstance(seed);  +		INSTANCE_ADAPTOR::hide(instance); +	} + +	static void toggleInstance(const LLSD& seed) +	{ +		if (!INSTANCE_ADAPTOR::instanceVisible(seed)) +		{ +			INSTANCE_ADAPTOR::showInstance(seed); +		} +		else +		{ +			INSTANCE_ADAPTOR::hideInstance(seed); +		} +	} + +	static BOOL instanceVisible(const LLSD& seed) +	{ +		T* instance = INSTANCE_ADAPTOR::findInstance(seed); +		return instance != NULL && INSTANCE_ADAPTOR::visible(instance); +	} + +	static T* getInstance(const LLSD& seed)  +	{ +		T* instance = INSTANCE_ADAPTOR::findInstance(seed); +		if (instance == NULL) +		{ +			instance = INSTANCE_ADAPTOR::createInstance(seed); +		} +		return instance; +	} +}; + +// Creates a UI singleton by ignoring the identifying parameter +// and always generating the same instance via the LLUIInstanceMgr interface. +// Note that since UI elements can be destroyed by their hierarchy, this singleton +// pattern uses a static pointer to an instance that will be re-created as needed. +template <class T, class INSTANCE_ADAPTOR = T> +class LLUISingleton: public LLUIInstanceMgr<T, INSTANCE_ADAPTOR> +{ +public: +	// default constructor assumes T is derived from LLUISingleton (a true singleton) +	LLUISingleton() : LLUIInstanceMgr<T, INSTANCE_ADAPTOR>() { sInstance = (T*)this; } +	~LLUISingleton() { sInstance = NULL; } + +	static T* findInstance(const LLSD& seed) +	{ +		return sInstance; +	} + +	static T* createInstance(const LLSD& seed) +	{ +		if (sInstance == NULL) +		{ +			sInstance = new T(seed); +		} +		return sInstance; +	} + +protected: +	static T*	sInstance; +}; + +template <class T, class U> T* LLUISingleton<T,U>::sInstance = NULL; +  #endif diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index f7df94c65c..650398cb65 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -105,6 +105,16 @@ BOOL LLWindowCallbacks::handleRightMouseUp(LLWindow *window, const LLCoordGL pos  	return FALSE;  } +BOOL LLWindowCallbacks::handleMiddleMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask) +{ +	return FALSE; +} + +BOOL LLWindowCallbacks::handleMiddleMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask) +{ +	return FALSE; +} +  BOOL LLWindowCallbacks::handleActivate(LLWindow *window, BOOL activated)  {  	return FALSE; diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 5c5f712b32..6e26285e29 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -76,6 +76,8 @@ public:  	virtual void handleQuit(LLWindow *window);  	virtual BOOL handleRightMouseDown(LLWindow *window,  LLCoordGL pos, MASK mask);  	virtual BOOL handleRightMouseUp(LLWindow *window,  LLCoordGL pos, MASK mask); +	virtual BOOL handleMiddleMouseDown(LLWindow *window,  LLCoordGL pos, MASK mask); +	virtual BOOL handleMiddleMouseUp(LLWindow *window,  LLCoordGL pos, MASK mask);  	virtual BOOL handleActivate(LLWindow *window, BOOL activated);  	virtual void handleMouseMove(LLWindow *window,  LLCoordGL pos, MASK mask);  	virtual void handleScrollWheel(LLWindow *window,  S32 clicks); diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 4152de51c5..62743d4d08 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -2157,6 +2157,10 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e  					case kEventMouseButtonSecondary:  						mCallbacks->handleRightMouseDown(this, outCoords, mask);  						break; +					 +					case kEventMouseButtonTertiary: +						mCallbacks->handleMiddleMouseDown(this, outCoords, mask); +						break;  					}  					result = noErr;  					break; @@ -2179,6 +2183,10 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e  					case kEventMouseButtonSecondary:  						mCallbacks->handleRightMouseUp(this, outCoords, mask);  						break; + +					case kEventMouseButtonTertiary: +						mCallbacks->handleMiddleMouseUp(this, outCoords, mask); +						break;  					}  					result = noErr;  					break; diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 71c766db8e..6c1ee967df 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -2032,7 +2032,9 @@ void LLWindowSDL::gatherInput()                  }                  else if (event.button.button == SDL_BUTTON_MIDDLE)  // middle -				    ;  // Middle mouse isn't handled right now in Second Life ... mCallbacks->handleMiddleMouseDown(this, openGlCoord, mask); +				{ +				    mCallbacks->handleMiddleMouseDown(this, openGlCoord, mask); +				}                  else if (event.button.button == 4)  // mousewheel up...thanks to X11 for making SDL consider these "buttons".  					mCallbacks->handleScrollWheel(this, -1);                  else if (event.button.button == 5)  // mousewheel down...thanks to X11 for making SDL consider these "buttons". @@ -2053,8 +2055,9 @@ void LLWindowSDL::gatherInput()                  else if (event.button.button == SDL_BUTTON_RIGHT)  // right ... yes, it's 3, not 2, in SDL...  				    mCallbacks->handleRightMouseUp(this, openGlCoord, mask);                  else if (event.button.button == SDL_BUTTON_MIDDLE)  // middle -				    ;  // UNUSED IN SECOND LIFE RIGHT NOW mCallbacks->handleMiddleMouseUp(this, openGlCoord, mask); - +				{ +					mCallbacks->handleMiddleMouseUp(this, openGlCoord, mask); +				}                  // don't handle mousewheel here...                  break; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index e6bce27ce2..095b2113a7 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -2052,7 +2052,54 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_  			break;  		case WM_MBUTTONDOWN: -			// Handle middle button click +//		case WM_MBUTTONDBLCLK: +			{ +				// Because we move the cursor position in tllviewerhe app, we need to query +				// to find out where the cursor at the time the event is handled. +				// If we don't do this, many clicks could get buffered up, and if the +				// first click changes the cursor position, all subsequent clicks +				// will occur at the wrong location.  JC +				LLCoordWindow cursor_coord_window; +				if (window_imp->mMousePositionModified) +				{ +					window_imp->getCursorPosition(&cursor_coord_window); +					window_imp->convertCoords(cursor_coord_window, &gl_coord); +				} +				else +				{ +					window_imp->convertCoords(window_coord, &gl_coord); +				} +				MASK mask = gKeyboard->currentMask(TRUE); +				if (window_imp->mCallbacks->handleMiddleMouseDown(window_imp, gl_coord, mask)) +				{ +					return 0; +				} +			} +			break; + +		case WM_MBUTTONUP: +			{ +				// Because we move the cursor position in tllviewerhe app, we need to query +				// to find out where the cursor at the time the event is handled. +				// If we don't do this, many clicks could get buffered up, and if the +				// first click changes the cursor position, all subsequent clicks +				// will occur at the wrong location.  JC +				LLCoordWindow cursor_coord_window; +				if (window_imp->mMousePositionModified) +				{ +					window_imp->getCursorPosition(&cursor_coord_window); +					window_imp->convertCoords(cursor_coord_window, &gl_coord); +				} +				else +				{ +					window_imp->convertCoords(window_coord, &gl_coord); +				} +				MASK mask = gKeyboard->currentMask(TRUE); +				if (window_imp->mCallbacks->handleMiddleMouseUp(window_imp, gl_coord, mask)) +				{ +					return 0; +				} +			}  			break;  		case WM_MOUSEWHEEL: diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 0b0385d92f..02c762cbe0 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -617,6 +617,66 @@ bool LLXMLNode::parseBuffer(  	return true;  } +// static +bool LLXMLNode::parseStream( +	std::istream& str, +	LLXMLNodePtr& node,  +	LLXMLNode* defaults) +{ +	// Init +	XML_Parser my_parser = XML_ParserCreate(NULL); +	XML_SetElementHandler(my_parser, StartXMLNode, EndXMLNode); +	XML_SetCharacterDataHandler(my_parser, XMLData); + +	// Create a root node +	LLXMLNode *file_node_ptr = new LLXMLNode("XML", FALSE); +	LLXMLNodePtr file_node = file_node_ptr; + +	file_node->mParser = &my_parser; + +	XML_SetUserData(my_parser, (void *)file_node_ptr); + +	const int BUFSIZE = 1024;  +	U8* buffer = new U8[BUFSIZE]; + +	while(str.good()) +	{ +		str.read((char*)buffer, BUFSIZE); +		int count = str.gcount(); +		 +		if (XML_Parse(my_parser, (const char *)buffer, count, !str.good()) != XML_STATUS_OK) +		{ +			llwarns << "Error parsing xml error code: " +					<< XML_ErrorString(XML_GetErrorCode(my_parser)) +					<< " on lne " << XML_GetCurrentLineNumber(my_parser) +					<< llendl; +			break; +		} +	} +	 +	delete [] buffer; + +	// Deinit +	XML_ParserFree(my_parser); + +	if (!file_node->mChildren || file_node->mChildren->map.size() != 1) +	{ +		llwarns << "Parse failure - wrong number of top-level nodes xml." +				<< llendl; +		node = new LLXMLNode(); +		return false; +	} + +	LLXMLNode *return_node = file_node->mChildren->map.begin()->second; + +	return_node->setDefault(defaults); +	return_node->updateDefault(); + +	node = return_node; +	return true; +} + +  BOOL LLXMLNode::isFullyDefault()  {  	if (mDefault.isNull()) diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index e95904dad8..24fccb72c6 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -97,6 +97,10 @@ public:  		U32 length,  		LLXMLNodePtr& node,   		LLXMLNode* defaults); +	static bool parseStream( +		std::istream& str, +		LLXMLNodePtr& node,  +		LLXMLNode* defaults);  	static bool updateNode(  	LLXMLNodePtr& node,  	LLXMLNodePtr& update_node); diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings index 8fae01fbdc..9df6a820fb 100644 --- a/indra/newview/English.lproj/InfoPlist.strings +++ b/indra/newview/English.lproj/InfoPlist.strings @@ -1,5 +1,5 @@  /* Localized versions of Info.plist keys */  CFBundleName = "Second Life"; -CFBundleShortVersionString = "Second Life version 1.16.0.5"; -CFBundleGetInfoString = "Second Life version 1.16.0.5, Copyright 2004-2007 Linden Research, Inc."; +CFBundleShortVersionString = "Second Life version 1.17.0.12"; +CFBundleGetInfoString = "Second Life version 1.17.0.12, Copyright 2004-2007 Linden Research, Inc."; diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index 764b1520f0..a02f664d54 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -32,7 +32,7 @@  		</dict>  	</array>  	<key>CFBundleVersion</key> -	<string>1.16.0.5</string> +	<string>1.17.0.12</string>  	<key>CSResourcesFileMapped</key>  	<true/>  </dict> diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 0484027455..a7c110fec4 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -13,6 +13,7 @@  #include "indra_constants.h"  #include "llfocusmgr.h"  #include "llfontgl.h" +#include "llhttpclient.h"  #include "llrect.h"  #include "llerror.h"  #include "llstring.h" @@ -40,6 +41,7 @@  #include "llvieweruictrlfactory.h"  #include "lllogchat.h"  #include "llfloaterhtml.h" +#include "llviewerregion.h"  #include "llweb.h"  // @@ -93,8 +95,7 @@ bool send_start_session_messages(const LLUUID& temp_session_id,  								 const LLDynamicArray<LLUUID>& ids,  								 EInstantMessage dialog)  { -	if ( (dialog == IM_SESSION_911_START) || -		 (dialog == IM_SESSION_GROUP_START) || +	if ( (dialog == IM_SESSION_GROUP_START) ||  		 (dialog == IM_SESSION_CONFERENCE_START) )  	{  		S32 count = ids.size(); @@ -109,7 +110,6 @@ bool send_start_session_messages(const LLUUID& temp_session_id,  		switch(dialog)  		{  		case IM_SESSION_GROUP_START: -		case IM_SESSION_911_START:  			gMessageSystem->addBinaryDataFast(_PREHASH_BinaryBucket,  											  EMPTY_BINARY_BUCKET,  											  EMPTY_BINARY_BUCKET_SIZE); @@ -190,9 +190,8 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& name,  	mSessionInitialized(FALSE),  	mSessionInitRequested(FALSE)  { -	init(session_label); -  	mSessionInitialTargetIDs = ids; +	init(session_label);  } @@ -216,11 +215,33 @@ void LLFloaterIMPanel::init(const LLString& session_label)  				       (void *)this);  	} -	if(IM_SESSION_911_START == mDialog) +	if ( !mSessionInitialized )  	{ -		LLTextBox* live_help_text =  -			LLUICtrlFactory::getTextBoxByName(this, "live_help_dialog"); -		addHistoryLine(live_help_text->getText()); +		if ( !send_start_session_messages( +				 mSessionUUID, +				 mOtherParticipantUUID, +				 mSessionInitialTargetIDs, +				 mDialog) ) +		{ +			//we don't need to need to wait for any responses +			//so we're already initialized +			mSessionInitialized = TRUE; +		} +		else +		{ +			//locally echo a little "starting session" message +			LLUIString session_start = sSessionStartString; + +			session_start.setArg("[NAME]", getTitle()); +			mSessionStartMsgPos =  +				mHistoryEditor->getText().length(); + +			bool log_to_file = false; +			addHistoryLine( +				session_start, +				LLColor4::grey, +				log_to_file); +		}  	}  } @@ -235,7 +256,6 @@ BOOL LLFloaterIMPanel::postBuild()  	requires("title_string", WIDGET_TYPE_TEXT_BOX);  	requires("typing_start_string", WIDGET_TYPE_TEXT_BOX);  	requires("session_start_string", WIDGET_TYPE_TEXT_BOX); -	requires("teleport_btn", WIDGET_TYPE_BUTTON);  	if (checkRequirements())  	{ @@ -253,16 +273,10 @@ BOOL LLFloaterIMPanel::postBuild()  		LLButton* close_btn = LLUICtrlFactory::getButtonByName(this, "close_btn");  		close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this); -		LLButton* tp_btn = LLUICtrlFactory::getButtonByName(this, "teleport_btn"); -		tp_btn->setClickedCallback(&LLFloaterIMPanel::onTeleport, this); -		tp_btn->setVisible(FALSE); -		tp_btn->setEnabled(FALSE); -  		mHistoryEditor = LLViewerUICtrlFactory::getViewerTextEditorByName(this, "im_history");  		mHistoryEditor->setParseHTML(TRUE); -		if (IM_SESSION_GROUP_START == mDialog -			|| IM_SESSION_911_START == mDialog) +		if (IM_SESSION_GROUP_START == mDialog)  		{  			profile_btn->setEnabled(FALSE);  		} @@ -308,55 +322,55 @@ void LLFloaterIMPanel::draw()  	LLFloater::draw();  } +class LLSessionInviteResponder : public LLHTTPClient::Responder +{ +public: +	LLSessionInviteResponder(const LLUUID& session_id) +	{ +		mSessionID = session_id; +	} + +	void error(U32 statusNum, const std::string& reason) +	{ +		llinfos << "Error inviting all agents to session" << llendl; + +		//throw something back to the viewer here? +	} + +private: +	LLUUID mSessionID; +}; -BOOL LLFloaterIMPanel::addParticipants(const LLDynamicArray<LLUUID>& ids) +BOOL LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids)  {  	S32 count = ids.count();  	if( isAddAllowed() && (count > 0) )  	{ -		llinfos << "LLFloaterIMPanel::addParticipants() - adding participants" << llendl; -		const S32 MAX_AGENTS = 50; -		if(count > MAX_AGENTS) return FALSE; - -		LLMessageSystem *msg = gMessageSystem; -		msg->newMessageFast(_PREHASH_ImprovedInstantMessage); -		msg->nextBlockFast(_PREHASH_AgentData); -		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -		msg->nextBlockFast(_PREHASH_MessageBlock); -		msg->addBOOLFast(_PREHASH_FromGroup, FALSE); -		msg->addUUIDFast(_PREHASH_ToAgentID, mOtherParticipantUUID); -		msg->addU8Fast(_PREHASH_Offline, IM_ONLINE); -		msg->addU8Fast(_PREHASH_Dialog, IM_SESSION_ADD); -		msg->addUUIDFast(_PREHASH_ID, mSessionUUID); -		msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary -		std::string name; -		gAgent.buildFullname(name); -		msg->addStringFast(_PREHASH_FromAgentName, name); -		msg->addStringFast(_PREHASH_Message, LLString::null); -		msg->addU32Fast(_PREHASH_ParentEstateID, 0); -		msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null); -		msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); +		llinfos << "LLFloaterIMPanel::inviteToSession() - adding participants" << llendl; -		// *FIX: this could suffer from endian issues -		S32 bucket_size = UUID_BYTES * count; -		U8* bucket = new U8[bucket_size]; -		U8* pos = bucket; -		for(S32 i = 0; i < count; ++i) +		std::string url = +			gAgent.getRegion()->getCapability("ChatSessionRequest"); + +		LLSD data; +		data["params"] = LLSD::emptyArray(); +		for (int i = 0; i < count; i++)  		{ -			memcpy(pos, &(ids.get(i)), UUID_BYTES); -			pos += UUID_BYTES; +			data["params"].append(ids.get(i));  		} -		msg->addBinaryDataFast(_PREHASH_BinaryBucket, -							   bucket, -							   bucket_size); -		delete[] bucket; -		gAgent.sendReliableMessage(); + +		data["method"] = "invite"; +		data["session-id"] = mSessionUUID; +		LLHTTPClient::post( +			url, +			data, +			new LLSessionInviteResponder(mSessionUUID)); +		  	}  	else  	{ -		llinfos << "LLFloaterIMPanel::addParticipants() - no need to add agents for " +		llinfos << "LLFloaterIMPanel::inviteToSession -" +				<< " no need to invite agents for "  				<< mDialog << llendl;  		// successful add, because everyone that needed to get added  		// was added. @@ -512,7 +526,7 @@ BOOL LLFloaterIMPanel::dropCallingCard(LLInventoryItem* item, BOOL drop)  		{  			LLDynamicArray<LLUUID> ids;  			ids.put(item->getCreatorUUID()); -			addParticipants(ids); +			inviteToSession(ids);  		}  	}  	else @@ -548,7 +562,7 @@ BOOL LLFloaterIMPanel::dropCategory(LLInventoryCategory* category, BOOL drop)  			{  				ids.put(items.get(i)->getCreatorUUID());  			} -			addParticipants(ids); +			inviteToSession(ids);  		}  	}  	return rv; @@ -558,7 +572,7 @@ BOOL LLFloaterIMPanel::isAddAllowed() const  {  	return ((IM_SESSION_CONFERENCE_START == mDialog)  -			|| (IM_SESSION_ADD) ); +			|| (IM_SESSION_INVITE) );  } @@ -592,39 +606,6 @@ void LLFloaterIMPanel::onClickClose( void* userdata )  	}  } -void LLFloaterIMPanel::addTeleportButton() -{ -	LLButton* btn = -		LLViewerUICtrlFactory::getButtonByName(this, "teleport_btn"); - -	if ( !btn->getEnabled() ) -	{ -		//it's required, don't need to check for null here -		// adjust the size of the editor to make room for the button -		LLRect rect = mInputEditor->getRect(); -		S32 editor_right = rect.mRight - btn->getRect().getWidth(); -		rect.mRight = editor_right; -		mInputEditor->reshape(rect.getWidth(), rect.getHeight(), FALSE); -		mInputEditor->setRect(rect); - -		btn->setVisible(TRUE); -		btn->setEnabled(TRUE); -	} -} - -// static -void LLFloaterIMPanel::onTeleport(void* userdata) -{ -	LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; -	if(self) -	{ -		send_simple_im(self->mSessionUUID, //to -					   "", -					   IM_TELEPORT_911, -					   self->mSessionUUID);//session -	} -} -  // static  void LLFloaterIMPanel::onInputEditorFocusReceived( LLUICtrl* caller, void* userdata )  { @@ -672,7 +653,7 @@ void LLFloaterIMPanel::onClose(bool app_quitting)  			name.c_str(),   			"",  			IM_ONLINE, -			IM_SESSION_DROP, +			IM_SESSION_LEAVE,  			mSessionUUID);  		gAgent.sendReliableMessage();  	} @@ -697,11 +678,7 @@ void deliver_message(const std::string& utf8_text,  	// which case it's probably an IM to everyone.  	U8 new_dialog = dialog; -	if ( dialog == IM_SESSION_911_START ) -	{ -		new_dialog = IM_SESSION_911_SEND; -	} -	else if ( dialog != IM_NOTHING_SPECIAL ) +	if ( dialog != IM_NOTHING_SPECIAL )  	{  		new_dialog = IM_SESSION_SEND;  	} @@ -737,49 +714,6 @@ void LLFloaterIMPanel::sendMsg()  		std::string utf8_text = wstring_to_utf8str(text);  		utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); -		if ( !mSessionInitialized ) -		{ -			//we send requests (if we need to) to initialize our session -			if ( !mSessionInitRequested ) -			{ -				mSessionInitRequested = TRUE; -				if ( !send_start_session_messages(mSessionUUID, -												 mOtherParticipantUUID, -												 mSessionInitialTargetIDs, -												 mDialog) ) -				{ -					//we don't need to need to wait for any responses -					//so we don't need to disable -					mSessionInitialized = TRUE; -				} -				else -				{ -					//queue up the message to send once the session is -					//initialized -					mQueuedMsgsForInit.append(utf8_text); - -					//locally echo a little "starting session" message -					LLUIString session_start = sSessionStartString; - -					session_start.setArg("[NAME]", getTitle()); -					mSessionStartMsgPos =  -						mHistoryEditor->getText().length(); - -					bool log_to_file = false; -					addHistoryLine(session_start, -								   LLColor4::grey, -								   log_to_file); - -				} -			} -			else -			{ -				//queue up the message to send once the session is -				//initialized -				mQueuedMsgsForInit.append(utf8_text); -			} -		} -  		if ( mSessionInitialized )  		{  			deliver_message(utf8_text, @@ -813,6 +747,10 @@ void LLFloaterIMPanel::sendMsg()  				addHistoryLine(history_echo);  			}  		} +		else +		{ +			mQueuedMsgsForInit.append(utf8_text); +		}  		gViewerStats->incStat(LLViewerStats::ST_IM_COUNT);  	} @@ -951,3 +889,4 @@ void LLFloaterIMPanel::chatFromLogFile(LLString line, void* userdata)  	self->mHistoryEditor->appendColoredText(line, false, true, LLColor4::grey);  } + diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index 45dda8ec79..5348308a83 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -51,7 +51,7 @@ public:  	// add target ids to the session.   	// Return TRUE if successful, otherwise FALSE. -	BOOL addParticipants(const LLDynamicArray<LLUUID>& agent_ids); +	BOOL inviteToSession(const LLDynamicArray<LLUUID>& agent_ids);  	void addHistoryLine(const std::string &utf8msg,   						const LLColor4& color = LLColor4::white,  @@ -78,10 +78,7 @@ public:  	const LLUUID& getSessionID() const { return mSessionUUID; }  	const LLUUID& getOtherParticipantID() const { return mOtherParticipantUUID; } - -	// HACK -- for enabling a teleport button for helpers -	static void onTeleport(void* userdata); -	void addTeleportButton(); +	const EInstantMessage getDialogType() const { return mDialog; }  	void sessionInitReplyReceived(const LLUUID& im_session_id); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 553c6ec6c3..5a40b4a7c1 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -12,29 +12,37 @@  #include "llfontgl.h"  #include "llrect.h" +#include "lldbstrings.h"  #include "llerror.h"  #include "llbutton.h" +#include "llsdutil.h"  #include "llstring.h"  #include "linked_lists.h"  #include "llvieweruictrlfactory.h"  #include "llagent.h"  #include "llcallingcard.h" +#include "llchat.h"  #include "llviewerwindow.h"  #include "llresmgr.h" +#include "llfloaterchat.h"  #include "llfloaternewim.h" +#include "llhttpclient.h"  #include "llhttpnode.h"  #include "llimpanel.h"  #include "llresizebar.h"  #include "lltabcontainer.h"  #include "viewer.h"  #include "llfloater.h" +#include "llmutelist.h"  #include "llresizehandle.h"  #include "llkeyboard.h"  #include "llui.h"  #include "llviewermenu.h"  #include "llcallingcard.h"  #include "lltoolbar.h" +#include "llviewermessage.h" +#include "llviewerregion.h"  const EInstantMessage GROUP_DIALOG = IM_SESSION_GROUP_START;  const EInstantMessage DEFAULT_DIALOG = IM_NOTHING_SPECIAL; @@ -129,11 +137,9 @@ BOOL LLFloaterIM::postBuild()  		sErrorStringsMap["no_user_911"] =  			childGetText("user_no_help"); -		sEventStringsMap["add"] = childGetText("add_session_event");; +		sEventStringsMap["add"] = childGetText("add_session_event");  		sEventStringsMap["message"] = -			childGetText("message_session_event");; -		sEventStringsMap["teleport"] = -			childGetText("teleport_session_event");; +			childGetText("message_session_event");  		sForceCloseSessionMap["removed"] =  			childGetText("removed_from_group"); @@ -357,10 +363,10 @@ void LLIMView::addMessage(  		//if we have recently requsted to be dropped from a session  		//but are still receiving messages from the session, don't make  		//a new floater -//		if ( mSessionsDropRequested.has(session_id.asString()) ) -//		{ -//			return ; -//		} +		if ( mSessionsDropRequested.has(session_id.asString()) ) +		{ +			return ; +		}  		const char* name = from;  		if(session_name && (strlen(session_name)>1)) @@ -523,10 +529,10 @@ void LLIMView::removeSession(const LLUUID& session_id)  		//mTabContainer->removeTabPanel(floater);  	} -//	if ( session_id.notNull() ) -//	{ -//		mSessionsDropRequested[session_id.asString()] = LLSD(); -//	} +	if ( session_id.notNull() && floater->getDialogType() != IM_NOTHING_SPECIAL ) +	{ +		mSessionsDropRequested[session_id.asString()] = LLSD(); +	}  }  void LLIMView::refresh() @@ -831,9 +837,10 @@ public:  		desc.source(__FILE__, __LINE__);  	} -	virtual void post(ResponsePtr response, -					  const LLSD& context, -					  const LLSD& input) const +	virtual void post( +		ResponsePtr response, +		const LLSD& context, +		const LLSD& input) const  	{  		LLSD body;  		LLUUID temp_session_id; @@ -847,8 +854,9 @@ public:  		if ( success )  		{  			session_id = body["session_id"].asUUID(); -			gIMView->updateFloaterSessionID(temp_session_id, -											session_id); +			gIMView->updateFloaterSessionID( +				temp_session_id, +				session_id);  		}  		else  		{ @@ -863,11 +871,11 @@ public:  					sErrorStringsMap[body["error"].asString()];  				args["[RECIPIENT]"] = floater->getTitle(); -				gViewerWindow->alertXml("IMSessionStartError", -										args, -										onConfirmForceCloseError, -										floater); - +				gViewerWindow->alertXml( +					"IMSessionStartError", +					args, +					onConfirmForceCloseError, +					floater);  			}  		}  	} @@ -970,18 +978,163 @@ public:  	}  }; +class LLViewerChatterBoxSessionAgentListUpdates : public LLHTTPNode +{ +public: +	virtual void post( +		ResponsePtr responder, +		const LLSD& context, +		const LLSD& input) const +	{ +	} +}; + +class LLViewerChatterBoxInvitation : public LLHTTPNode +{ +public: +	virtual void post( +		ResponsePtr responder, +		const LLSD& context, +		const LLSD& input) const +	{ +		if ( input["body"].has("instantmessage") ) +		{ +			LLSD message_params = +				input["body"]["instantmessage"]["message_params"]; + +			//this is just replicated code from process_improved_im +			//and should really go in it's own function -jwolk +			if (gNoRender) +			{ +				return; +			} + +			char buffer[DB_IM_MSG_BUF_SIZE * 2];  /* Flawfinder: ignore */ +			LLChat chat; + +			std::string message = message_params["message"].asString(); +			std::string name = message_params["from_name"].asString(); +			LLUUID from_id = message_params["from_id"].asUUID(); +			LLUUID session_id = message_params["id"].asUUID(); +			std::vector<U8> bin_bucket = message_params["data"]["binary_bucket"].asBinary(); +			U8 offline = (U8)message_params["offline"].asInteger(); +			 +			time_t timestamp = +				(time_t) message_params["timestamp"].asInteger(); + +			BOOL is_busy = gAgent.getBusy(); +			BOOL is_muted =  gMuteListp->isMuted(from_id, name); +			BOOL is_linden = gMuteListp->isLinden( +				name.c_str()); +			char separator_string[3]=": ";		/* Flawfinder: ignore */ +			int message_offset=0; + +			//Handle IRC styled /me messages. +			if (!strncmp(message.c_str(), "/me ", 4) || +				!strncmp(message.c_str(), "/me'", 4)) +			{ +				strcpy(separator_string,"");	   /* Flawfinder: ignore */ +				message_offset = 3; +			} +			 +			chat.mMuted = is_muted && !is_linden; +			chat.mFromID = from_id; +			chat.mFromName = name; +			if (!is_linden && is_busy) +			{ +				return; +			} + +			// standard message, not from system +			char saved[MAX_STRING];		/* Flawfinder: ignore */ +			saved[0] = '\0'; +			if(offline == IM_OFFLINE) +			{ +				char time_buf[TIME_STR_LENGTH]; /* Flawfinder: ignore */ +				snprintf(saved,		/* Flawfinder: ignore */ +						 MAX_STRING,  +						 "(Saved %s) ",  +						 formatted_time(timestamp, time_buf)); +			} +			snprintf( +				buffer, +				sizeof(buffer), +				"%s%s%s%s", +				name.c_str(), +				separator_string, +				saved, +				(message.c_str() + message_offset)); /*Flawfinder: ignore*/ + +			BOOL is_this_agent = FALSE; +			if(from_id == gAgentID) +			{ +				from_id = LLUUID::null; +				is_this_agent = TRUE; +			} +			gIMView->addMessage( +				session_id, +				from_id, +				name.c_str(), +				buffer, +				(char*)&bin_bucket[0], +				IM_SESSION_INVITE, +				message_params["parent_estate_id"].asInteger(), +				message_params["region_id"].asUUID(), +				ll_vector3_from_sd(message_params["position"])); + +			snprintf( +				buffer, +				sizeof(buffer), +				"IM: %s%s%s%s", +				name.c_str(), +				separator_string, +				saved, +				(message.c_str()+message_offset)); /* Flawfinder: ignore */ +			chat.mText = buffer; +			LLFloaterChat::addChat(chat, TRUE, is_this_agent); + +			//if we succesfully accepted the invitation +			//send a message back down + +			//TODO - When availble, have this response just be part +			//of an automatic response system +			std::string url = gAgent.getRegion()->getCapability( +				"ChatSessionRequest"); + +			if ( url != "" ) +			{ +				LLSD data; +				data["method"] = "accept invitation"; +				data["session-id"] = input["body"]["session_id"]; +				LLHTTPClient::post( +					url, +					data, +					NULL); +			} +		} //end if invitation has instant message +	} +}; +  LLHTTPRegistration<LLViewerIMSessionStartReply>     gHTTPRegistrationMessageImsessionstartreply( -	   "/message/IMSessionStartReply"); +	   "/message/ChatterBoxSessionStartReply");  LLHTTPRegistration<LLViewerIMSessionEventReply>     gHTTPRegistrationMessageImsessioneventreply( -	   "/message/IMSessionEventReply"); +	   "/message/ChatterBoxSessionEventReply");  LLHTTPRegistration<LLViewerForceCloseIMSession>      gHTTPRegistrationMessageForceCloseImSession( -		"/message/ForceCloseIMSession"); +		"/message/ForceCloseChatterBoxSession");  LLHTTPRegistration<LLViewerIMSessionDropReply>      gHTTPRegistrationMessageImSessionDropReply( -		"/message/IMSessionDropReply"); +		"/message/ChatterBoxSessionLeaveReply"); + +LLHTTPRegistration<LLViewerChatterBoxSessionAgentListUpdates> +    gHTTPRegistrationMessageChatterboxsessionagentlistupdates( +	    "/message/ChatterBoxSessionAgentListUpdates"); + +LLHTTPRegistration<LLViewerChatterBoxInvitation> +    gHTTPRegistrationMessageChatterBoxInvitation( +		"/message/ChatterBoxInvitation"); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 1565a5875b..9aaac2af66 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3010,24 +3010,6 @@ class LLHelpMOTD : public view_listener_t  	}  }; -class LLHelpLiveHelp : public view_listener_t -{ -	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) -	{ -		// the session_id of a 911 session will always be this agent's session id -		static LLUUID session_id(LLUUID::null); -		if (session_id.isNull()) -		{ -			session_id.generate(); -		} -		gIMView->setFloaterOpen(TRUE); -		LLDynamicArray<LLUUID> members; -		members.put(gAgent.getID()); -		gIMView->addSession("Help Request", IM_SESSION_911_START, session_id, members); //xui: translate -		return true; -	} -}; -  //  // Major mode switching  // @@ -7642,7 +7624,6 @@ void initialize_menus()  	addMenu(new LLToolsVisibleTakeObject(), "Tools.VisibleTakeObject");*/  	// Help menu -	addMenu(new LLHelpLiveHelp(), "Help.LiveHelp");  	addMenu(new LLHelpMOTD(), "Help.MOTD");  	// Self pie menu diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 9bcf1ccaee..3b28148c4f 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1691,86 +1691,23 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  	}  	break; -	case IM_SESSION_911_SEND: +	case IM_SESSION_SEND:  	{ -		//this is just the same code as IM_SESSION_SEND for a bit -		//I was too lazy to make this a function....sorry - jwolk  		if (!is_linden && is_busy)  		{  			return;  		} -			 -		// standard message, not from system -		char saved[MAX_STRING];		/* Flawfinder: ignore */ -		saved[0] = '\0'; -		if(offline == IM_OFFLINE) -		{ -			char time_buf[TIME_STR_LENGTH];		/* Flawfinder: ignore */ -			snprintf(saved,		/* Flawfinder: ignore */ -					 MAX_STRING,  -					 "(Saved %s) ",  -					 formatted_time(timestamp, time_buf)); -		} -	 -		snprintf(buffer, 		/* Flawfinder: ignore */ -				 sizeof(buffer), -				 "%s%s%s%s", -				 name, -				 separator_string, -				 saved, -				 (message+message_offset)); -		BOOL is_this_agent = FALSE; -		if(from_id == gAgentID) -		{ -			from_id = LLUUID::null; -			is_this_agent = TRUE; -		} - -		gIMView->addMessage( -			session_id, -			from_id, -			name, -			buffer, -			(char*)binary_bucket, -			IM_SESSION_ADD, -			parent_estate_id, -			region_id, -			position); - -		snprintf(buffer, sizeof(buffer), "IM: %s%s%s%s", name, separator_string, saved, (message+message_offset));		/* Flawfinder: ignore */ -		chat.mText = buffer; -		LLFloaterChat::addChat(chat, TRUE, is_this_agent); - -		//ok, now we want to add a teleport button if we are receving -		//a message from not ourself -		LLFloaterIMPanel* panel = -			gIMView->findFloaterBySession(session_id); - -		if (panel && !is_this_agent ) -		{ -			//don't add a teleport button for yourself -			panel->addTeleportButton(); -		} -		break; -	} -	case IM_SESSION_SEND: -	{ -		if (!is_linden && is_busy) +		// System messages, specifically "Foo Bar has left this session" +		// are not shown unless you actually have that session open. +		// Band-aid.  JC +		if (offline == IM_ONLINE +			&& chat.mFromName == SYSTEM_FROM +			&& !gIMView->hasSession(session_id))  		{  			return;  		} -			// System messages, specifically "Foo Bar has left this session" -			// are not shown unless you actually have that session open. -			// Band-aid.  JC -			if (offline == IM_ONLINE -				&& chat.mFromName == SYSTEM_FROM -				&& !gIMView->hasSession(session_id)) -			{ -				return; -			} -  		// standard message, not from system  		char saved[MAX_STRING];		/* Flawfinder: ignore */  		saved[0] = '\0'; @@ -1795,7 +1732,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  			name,  			buffer,  			(char*)binary_bucket, -			IM_SESSION_ADD, +			IM_SESSION_INVITE,  			parent_estate_id,  			region_id,  			position); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 6f68f04d67..6fd31f3e72 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1283,7 +1283,9 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	capabilityNames.append("SendUserReportWithScreenshot");  	capabilityNames.append("RequestTextureDownload");  	capabilityNames.append("UntrustedSimulatorMessage"); -	 +	capabilityNames.append("ParcelVoiceInfoRequest"); +	capabilityNames.append("ChatSessionRequest"); +  	LLHTTPClient::post(url, capabilityNames, BaseCapabilitiesComplete::build(this));  } diff --git a/indra/win_updater/updater.cpp b/indra/win_updater/updater.cpp index c5207f0082..536553a4ed 100644 --- a/indra/win_updater/updater.cpp +++ b/indra/win_updater/updater.cpp @@ -147,7 +147,7 @@ int WINAPI get_url_into_file(WCHAR *uri, char *path, int *cancelled)  			fflush(logfile);  		}  #endif -		 +  #if _DEBUG  		fprintf(logfile,"Reading Data, bytes_read = %d\n",bytes_read);  		fflush(logfile); | 
