summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcharacter/llmotioncontroller.cpp3
-rw-r--r--indra/llcommon/llframetimer.cpp6
-rw-r--r--indra/llcommon/llframetimer.h1
-rw-r--r--indra/llcommon/llsdutil.cpp13
-rw-r--r--indra/llcommon/llsdutil.h3
-rw-r--r--indra/llinventory/llparcel.cpp17
-rw-r--r--indra/llinventory/llparcel.h44
-rw-r--r--indra/llinventory/llparcelflags.h7
-rw-r--r--indra/llmessage/llbuffer.h1
-rw-r--r--indra/llmessage/llcachename.cpp6
-rw-r--r--indra/llmessage/llcachename.h2
-rw-r--r--indra/llmessage/llhttpclient.cpp53
-rw-r--r--indra/llmessage/llhttpclient.h8
-rw-r--r--indra/llmessage/llinstantmessage.cpp36
-rw-r--r--indra/llmessage/llinstantmessage.h20
-rw-r--r--indra/llmessage/llregionflags.h9
-rw-r--r--indra/llmessage/message.cpp12
-rw-r--r--indra/llui/llbutton.cpp78
-rw-r--r--indra/llui/llbutton.h7
-rw-r--r--indra/llui/llfloater.cpp73
-rw-r--r--indra/llui/llfloater.h10
-rw-r--r--indra/llui/llscrolllistctrl.cpp51
-rw-r--r--indra/llui/llscrolllistctrl.h8
-rw-r--r--indra/llui/lltabcontainer.cpp54
-rw-r--r--indra/llui/lltabcontainer.h7
-rw-r--r--indra/llui/lltexteditor.cpp32
-rw-r--r--indra/llui/lltexteditor.h2
-rw-r--r--indra/llui/llui.h91
-rw-r--r--indra/llwindow/llwindow.cpp10
-rw-r--r--indra/llwindow/llwindow.h2
-rw-r--r--indra/llwindow/llwindowmacosx.cpp8
-rw-r--r--indra/llwindow/llwindowsdl.cpp9
-rw-r--r--indra/llwindow/llwindowwin32.cpp49
-rw-r--r--indra/llxml/llxmlnode.cpp60
-rw-r--r--indra/llxml/llxmlnode.h4
-rw-r--r--indra/newview/English.lproj/InfoPlist.strings4
-rw-r--r--indra/newview/Info-SecondLife.plist2
-rw-r--r--indra/newview/llimpanel.cpp217
-rw-r--r--indra/newview/llimpanel.h7
-rw-r--r--indra/newview/llimview.cpp205
-rw-r--r--indra/newview/llviewermenu.cpp19
-rw-r--r--indra/newview/llviewermessage.cpp79
-rw-r--r--indra/newview/llviewerregion.cpp4
-rw-r--r--indra/win_updater/updater.cpp2
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);