merge of latest lindenlab/svn-imports-viewer-20

master
Mark Palange (Mani) 2009-10-01 18:19:45 -07:00
commit dde2153014
238 changed files with 10426 additions and 3426 deletions

View File

@ -671,7 +671,14 @@
<key>UploadBakedTexture</key>
<boolean>true</boolean>
</map>
<key>ObjectMedia</key>
<boolean>false</boolean>
<key>ObjectMediaNavigate</key>
<boolean>false</boolean>
</map>
<key>messageBans</key>
<map>

View File

@ -78,9 +78,9 @@ static std::set<std::string> default_trans_args;
void init_default_trans_args()
{
default_trans_args.insert("SECOND_LIFE"); // World
default_trans_args.insert("SECOND_LIFE_VIEWER");
default_trans_args.insert("APP_NAME");
default_trans_args.insert("SECOND_LIFE_GRID");
default_trans_args.insert("SECOND_LIFE_SUPPORT");
default_trans_args.insert("SUPPORT_SITE");
}
bool translate_init(std::string comma_delim_path_list,

View File

@ -202,5 +202,18 @@ const U32 CHANGED_OWNER = 0x80;
const U32 CHANGED_REGION = 0x100;
const U32 CHANGED_TELEPORT = 0x200;
const U32 CHANGED_REGION_START = 0x400;
const U32 CHANGED_MEDIA = 0x800;
// Possible error results
const U32 LSL_STATUS_OK = 0;
const U32 LSL_STATUS_MALFORMED_PARAMS = 1000;
const U32 LSL_STATUS_TYPE_MISMATCH = 1001;
const U32 LSL_STATUS_BOUNDS_ERROR = 1002;
const U32 LSL_STATUS_NOT_FOUND = 1003;
const U32 LSL_STATUS_NOT_SUPPORTED = 1004;
const U32 LSL_STATUS_INTERNAL_ERROR = 1999;
// Start per-function errors below, starting at 2000:
const U32 LSL_STATUS_WHITELIST_FAILED = 2001;
#endif

View File

@ -99,6 +99,8 @@ void LLPluginClassMedia::reset()
mSetMediaHeight = -1;
mRequestedMediaWidth = 0;
mRequestedMediaHeight = 0;
mFullMediaWidth = 0;
mFullMediaHeight = 0;
mTextureWidth = 0;
mTextureHeight = 0;
mMediaWidth = 0;
@ -266,8 +268,16 @@ unsigned char* LLPluginClassMedia::getBitsData()
void LLPluginClassMedia::setSize(int width, int height)
{
mSetMediaWidth = width;
mSetMediaHeight = height;
if((width > 0) && (height > 0))
{
mSetMediaWidth = width;
mSetMediaHeight = height;
}
else
{
mSetMediaWidth = -1;
mSetMediaHeight = -1;
}
setSizeInternal();
}
@ -279,16 +289,26 @@ void LLPluginClassMedia::setSizeInternal(void)
mRequestedMediaWidth = mSetMediaWidth;
mRequestedMediaHeight = mSetMediaHeight;
}
else if((mNaturalMediaWidth > 0) && (mNaturalMediaHeight > 0))
{
mRequestedMediaWidth = mNaturalMediaWidth;
mRequestedMediaHeight = mNaturalMediaHeight;
}
else
{
mRequestedMediaWidth = mDefaultMediaWidth;
mRequestedMediaHeight = mDefaultMediaHeight;
}
// Save these for size/interest calculations
mFullMediaWidth = mRequestedMediaWidth;
mFullMediaHeight = mRequestedMediaHeight;
if(mAllowDownsample)
{
switch(mPriority)
{
case PRIORITY_SLIDESHOW:
case PRIORITY_LOW:
// Reduce maximum texture dimension to (or below) mLowPrioritySizeLimit
while((mRequestedMediaWidth > mLowPrioritySizeLimit) || (mRequestedMediaHeight > mLowPrioritySizeLimit))
@ -309,6 +329,12 @@ void LLPluginClassMedia::setSizeInternal(void)
mRequestedMediaWidth = nextPowerOf2(mRequestedMediaWidth);
mRequestedMediaHeight = nextPowerOf2(mRequestedMediaHeight);
}
if(mRequestedMediaWidth > 2048)
mRequestedMediaWidth = 2048;
if(mRequestedMediaHeight > 2048)
mRequestedMediaHeight = 2048;
}
void LLPluginClassMedia::setAutoScale(bool auto_scale)
@ -519,6 +545,10 @@ void LLPluginClassMedia::setPriority(EPriority priority)
std::string priority_string;
switch(priority)
{
case PRIORITY_UNLOADED:
priority_string = "unloaded";
mSleepTime = 1.0f;
break;
case PRIORITY_STOPPED:
priority_string = "stopped";
mSleepTime = 1.0f;
@ -527,6 +557,10 @@ void LLPluginClassMedia::setPriority(EPriority priority)
priority_string = "hidden";
mSleepTime = 1.0f;
break;
case PRIORITY_SLIDESHOW:
priority_string = "slideshow";
mSleepTime = 1.0f;
break;
case PRIORITY_LOW:
priority_string = "low";
mSleepTime = 1.0f / 50.0f;
@ -550,6 +584,8 @@ void LLPluginClassMedia::setPriority(EPriority priority)
mPlugin->setSleepTime(mSleepTime);
}
LL_DEBUGS("PluginPriority") << this << ": setting priority to " << priority_string << LL_ENDL;
// This may affect the calculated size, so recalculate it here.
setSizeInternal();
}
@ -557,15 +593,27 @@ void LLPluginClassMedia::setPriority(EPriority priority)
void LLPluginClassMedia::setLowPrioritySizeLimit(int size)
{
if(mLowPrioritySizeLimit != size)
int power = nextPowerOf2(size);
if(mLowPrioritySizeLimit != power)
{
mLowPrioritySizeLimit = size;
mLowPrioritySizeLimit = power;
// This may affect the calculated size, so recalculate it here.
setSizeInternal();
}
}
F64 LLPluginClassMedia::getCPUUsage()
{
F64 result = 0.0f;
if(mPlugin)
{
result = mPlugin->getCPUUsage();
}
return result;
}
void LLPluginClassMedia::cut()
{
@ -722,7 +770,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mNaturalMediaWidth = width;
mNaturalMediaHeight = height;
setSize(width, height);
setSizeInternal();
}
else if(message_name == "size_change_response")
{

View File

@ -66,6 +66,8 @@ public:
int getBitsHeight() const { return (mTextureHeight > 0) ? mTextureHeight : 0; };
int getTextureWidth() const;
int getTextureHeight() const;
int getFullWidth() const { return mFullMediaWidth; };
int getFullHeight() const { return mFullMediaHeight; };
// This may return NULL. Callers need to check for and handle this case.
unsigned char* getBitsData();
@ -138,9 +140,11 @@ public:
typedef enum
{
PRIORITY_UNLOADED, // media plugin isn't even loaded.
PRIORITY_STOPPED, // media is not playing, shouldn't need to update at all.
PRIORITY_HIDDEN, // media is not being displayed or is out of view, don't need to do graphic updates, but may still update audio, playhead, etc.
PRIORITY_LOW, // media is in the far distance, may be rendered at reduced size
PRIORITY_SLIDESHOW, // media is in the far distance, updates very infrequently
PRIORITY_LOW, // media is in the distance, may be rendered at reduced size
PRIORITY_NORMAL, // normal (default) priority
PRIORITY_HIGH // media has user focus and/or is taking up most of the screen
}EPriority;
@ -148,6 +152,8 @@ public:
void setPriority(EPriority priority);
void setLowPrioritySizeLimit(int size);
F64 getCPUUsage();
// Valid after a MEDIA_EVENT_CURSOR_CHANGED event
std::string getCursorName() const { return mCursorName; };
@ -230,6 +236,7 @@ public:
void initializeUrlHistory(const LLSD& url_history);
protected:
LLPluginClassMediaOwner *mOwner;
// Notify this object's owner that an event has occurred.
@ -266,7 +273,11 @@ protected:
int mSetMediaWidth;
int mSetMediaHeight;
// Actual media size being set (may be affected by auto-scale)
// Full calculated media size (before auto-scale and downsample calculations)
int mFullMediaWidth;
int mFullMediaHeight;
// Actual media size being set (after auto-scale)
int mRequestedMediaWidth;
int mRequestedMediaHeight;

View File

@ -33,6 +33,7 @@
#include "llpluginmessage.h"
#include "llsdserialize.h"
#include "u64.h"
LLPluginMessage::LLPluginMessage()
{
@ -93,6 +94,14 @@ void LLPluginMessage::setValueReal(const std::string &key, F64 value)
mMessage["params"][key] = value;
}
void LLPluginMessage::setValuePointer(const std::string &key, void* value)
{
std::stringstream temp;
// iostreams should output pointer values in hex with an initial 0x by default.
temp << value;
setValue(key, temp.str());
}
std::string LLPluginMessage::getClass(void) const
{
return mMessage["class"];
@ -189,6 +198,20 @@ F64 LLPluginMessage::getValueReal(const std::string &key) const
return result;
}
void* LLPluginMessage::getValuePointer(const std::string &key) const
{
void* result = NULL;
if(mMessage["params"].has(key))
{
std::string value = mMessage["params"][key].asString();
result = (void*)llstrtou64(value.c_str(), NULL, 16);
}
return result;
}
std::string LLPluginMessage::generate(void) const
{
std::ostringstream result;

View File

@ -57,6 +57,7 @@ public:
void setValueU32(const std::string &key, U32 value);
void setValueBoolean(const std::string &key, bool value);
void setValueReal(const std::string &key, F64 value);
void setValuePointer(const std::string &key, void *value);
std::string getClass(void) const;
std::string getName(void) const;
@ -82,6 +83,9 @@ public:
// get the value of a key as a float.
F64 getValueReal(const std::string &key) const;
// get the value of a key as a pointer.
void* getValuePointer(const std::string &key) const;
// Flatten the message into a string
std::string generate(void) const;

View File

@ -43,6 +43,7 @@ LLPluginProcessChild::LLPluginProcessChild()
mInstance = NULL;
mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
mSleepTime = 1.0f / 100.0f; // default: send idle messages at 100Hz
mCPUElapsed = 0.0f;
}
LLPluginProcessChild::~LLPluginProcessChild()
@ -130,6 +131,7 @@ void LLPluginProcessChild::idle(void)
{
mHeartbeat.start();
mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS);
mCPUElapsed = 0.0f;
setState(STATE_PLUGIN_LOADED);
}
else
@ -158,10 +160,22 @@ void LLPluginProcessChild::idle(void)
mInstance->idle();
if(mHeartbeat.checkExpirationAndReset(HEARTBEAT_SECONDS))
if(mHeartbeat.hasExpired())
{
// This just proves that we're not stuck down inside the plugin code.
sendMessageToParent(LLPluginMessage(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "heartbeat"));
LLPluginMessage heartbeat(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "heartbeat");
// Calculate the approximage CPU usage fraction (floating point value between 0 and 1) used by the plugin this heartbeat cycle.
// Note that this will not take into account any threads or additional processes the plugin spawns, but it's a first approximation.
// If we could write OS-specific functions to query the actual CPU usage of this process, that would be a better approximation.
heartbeat.setValueReal("cpu_usage", mCPUElapsed / mHeartbeat.getElapsedTimeF64());
sendMessageToParent(heartbeat);
mHeartbeat.reset();
mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS);
mCPUElapsed = 0.0f;
}
}
// receivePluginMessage will transition to STATE_UNLOADING
@ -253,8 +267,11 @@ void LLPluginProcessChild::sendMessageToPlugin(const LLPluginMessage &message)
std::string buffer = message.generate();
LL_DEBUGS("Plugin") << "Sending to plugin: " << buffer << LL_ENDL;
LLTimer elapsed;
mInstance->sendMessage(buffer);
mCPUElapsed += elapsed.getElapsedTimeF64();
}
void LLPluginProcessChild::sendMessageToParent(const LLPluginMessage &message)
@ -317,12 +334,7 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
LLPluginMessage message("base", "shm_added");
message.setValue("name", name);
message.setValueS32("size", (S32)size);
// shm address is split into 2x32bit values because LLSD doesn't serialize 64bit values and we need to support 64-bit addressing.
void * address = region->getMappedAddress();
U32 address_lo = (U32)(U64(address) & 0xFFFFFFFF); // Extract the lower 32 bits
U32 address_hi = (U32)((U64(address)>>32) & 0xFFFFFFFF); // Extract the higher 32 bits
message.setValueU32("address", address_lo);
message.setValueU32("address_1", address_hi);
message.setValuePointer("address", region->getMappedAddress());
sendMessageToPlugin(message);
// and send the response to the parent
@ -380,7 +392,11 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
if(passMessage && mInstance != NULL)
{
LLTimer elapsed;
mInstance->sendMessage(message);
mCPUElapsed += elapsed.getElapsedTimeF64();
}
}
@ -454,6 +470,7 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message)
if(passMessage)
{
LL_DEBUGS("Plugin") << "Passing through to parent: " << message << LL_ENDL;
writeMessageRaw(message);
}
}

View File

@ -102,6 +102,7 @@ private:
LLTimer mHeartbeat;
F64 mSleepTime;
F64 mCPUElapsed;
};

View File

@ -38,7 +38,7 @@
#include "llapr.h"
// If we don't receive a heartbeat in this many seconds, we declare the plugin locked up.
static const F32 PLUGIN_LOCKED_UP_SECONDS = 10.0f;
static const F32 PLUGIN_LOCKED_UP_SECONDS = 15.0f;
// Somewhat longer timeout for initial launch.
static const F32 PLUGIN_LAUNCH_SECONDS = 20.0f;
@ -87,6 +87,7 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std
{
mProcess.setExecutable(launcher_filename);
mPluginFile = plugin_filename;
mCPUUsage = 0.0f;
setState(STATE_INITIALIZED);
}
@ -503,6 +504,11 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
{
// this resets our timer.
mHeartbeat.setTimerExpirySec(PLUGIN_LOCKED_UP_SECONDS);
mCPUUsage = message.getValueReal("cpu_usage");
LL_DEBUGS("Plugin") << "cpu usage reported as " << mCPUUsage << LL_ENDL;
}
else if(message_name == "shm_add_response")
{

View File

@ -96,6 +96,8 @@ public:
bool getDisableTimeout() { return mDisableTimeout; };
void setDisableTimeout(bool disable) { mDisableTimeout = disable; };
F64 getCPUUsage() { return mCPUUsage; };
private:
enum EState
@ -140,6 +142,7 @@ private:
LLTimer mHeartbeat;
F64 mSleepTime;
F64 mCPUUsage;
bool mDisableTimeout;
};

View File

@ -17,6 +17,7 @@ include_directories(
set(llprimitive_SOURCE_FILES
llmaterialtable.cpp
llmediaentry.cpp
llprimitive.cpp
llprimtexturelist.cpp
lltextureanim.cpp
@ -31,6 +32,7 @@ set(llprimitive_HEADER_FILES
legacy_object_types.h
llmaterialtable.h
llmediaentry.h
llprimitive.h
llprimtexturelist.h
lltextureanim.h
@ -49,3 +51,10 @@ set_source_files_properties(${llprimitive_HEADER_FILES}
list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES})
add_library (llprimitive ${llprimitive_SOURCE_FILES})
#add unit tests
INCLUDE(LLAddBuildTest)
SET(llprimitive_TEST_SOURCE_FILES
llmediaentry.cpp
)
LL_ADD_PROJECT_UNIT_TESTS(llprimitive "${llprimitive_TEST_SOURCE_FILES}")

View File

@ -0,0 +1,597 @@
/**
* @file llmediaentry.cpp
* @brief This is a single instance of media data related to the face of a prim
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llmediaentry.h"
#include "lllslconstants.h"
#include <boost/regex.hpp>
// LLSD key defines
// DO NOT REORDER OR REMOVE THESE!
// Some LLSD keys. Do not change!
#define MEDIA_ALT_IMAGE_ENABLE_KEY_STR "alt_image_enable"
#define MEDIA_CONTROLS_KEY_STR "controls"
#define MEDIA_CURRENT_URL_KEY_STR "current_url"
#define MEDIA_HOME_URL_KEY_STR "home_url"
#define MEDIA_AUTO_LOOP_KEY_STR "auto_loop"
#define MEDIA_AUTO_PLAY_KEY_STR "auto_play"
#define MEDIA_AUTO_SCALE_KEY_STR "auto_scale"
#define MEDIA_AUTO_ZOOM_KEY_STR "auto_zoom"
#define MEDIA_FIRST_CLICK_INTERACT_KEY_STR "first_click_interact"
#define MEDIA_WIDTH_PIXELS_KEY_STR "width_pixels"
#define MEDIA_HEIGHT_PIXELS_KEY_STR "height_pixels"
// "security" fields
#define MEDIA_WHITELIST_ENABLE_KEY_STR "whitelist_enable"
#define MEDIA_WHITELIST_KEY_STR "whitelist"
// "permissions" fields
#define MEDIA_PERMS_INTERACT_KEY_STR "perms_interact"
#define MEDIA_PERMS_CONTROL_KEY_STR "perms_control"
// "general" fields
const char* LLMediaEntry::ALT_IMAGE_ENABLE_KEY = MEDIA_ALT_IMAGE_ENABLE_KEY_STR;
const char* LLMediaEntry::CONTROLS_KEY = MEDIA_CONTROLS_KEY_STR;
const char* LLMediaEntry::CURRENT_URL_KEY = MEDIA_CURRENT_URL_KEY_STR;
const char* LLMediaEntry::HOME_URL_KEY = MEDIA_HOME_URL_KEY_STR;
const char* LLMediaEntry::AUTO_LOOP_KEY = MEDIA_AUTO_LOOP_KEY_STR;
const char* LLMediaEntry::AUTO_PLAY_KEY = MEDIA_AUTO_PLAY_KEY_STR;
const char* LLMediaEntry::AUTO_SCALE_KEY = MEDIA_AUTO_SCALE_KEY_STR;
const char* LLMediaEntry::AUTO_ZOOM_KEY = MEDIA_AUTO_ZOOM_KEY_STR;
const char* LLMediaEntry::FIRST_CLICK_INTERACT_KEY = MEDIA_FIRST_CLICK_INTERACT_KEY_STR;
const char* LLMediaEntry::WIDTH_PIXELS_KEY = MEDIA_WIDTH_PIXELS_KEY_STR;
const char* LLMediaEntry::HEIGHT_PIXELS_KEY = MEDIA_HEIGHT_PIXELS_KEY_STR;
// "security" fields
const char* LLMediaEntry::WHITELIST_ENABLE_KEY = MEDIA_WHITELIST_ENABLE_KEY_STR;
const char* LLMediaEntry::WHITELIST_KEY = MEDIA_WHITELIST_KEY_STR;
// "permissions" fields
const char* LLMediaEntry::PERMS_INTERACT_KEY = MEDIA_PERMS_INTERACT_KEY_STR;
const char* LLMediaEntry::PERMS_CONTROL_KEY = MEDIA_PERMS_CONTROL_KEY_STR;
#define DEFAULT_URL_PREFIX "http://"
// Constructor(s)
LLMediaEntry::LLMediaEntry() :
mAltImageEnable(false),
mControls(STANDARD),
mCurrentURL(""),
mHomeURL(""),
mAutoLoop(false),
mAutoPlay(false),
mAutoScale(false),
mAutoZoom(false),
mFirstClickInteract(false),
mWidthPixels(0),
mHeightPixels(0),
mWhiteListEnable(false),
// mWhiteList
mPermsInteract(PERM_ALL),
mPermsControl(PERM_ALL),
mMediaIDp(NULL)
{
}
LLMediaEntry::LLMediaEntry(const LLMediaEntry &rhs) :
mMediaIDp(NULL)
{
// "general" fields
mAltImageEnable = rhs.mAltImageEnable;
mControls = rhs.mControls;
mCurrentURL = rhs.mCurrentURL;
mHomeURL = rhs.mHomeURL;
mAutoLoop = rhs.mAutoLoop;
mAutoPlay = rhs.mAutoPlay;
mAutoScale = rhs.mAutoScale;
mAutoZoom = rhs.mAutoZoom;
mFirstClickInteract = rhs.mFirstClickInteract;
mWidthPixels = rhs.mWidthPixels;
mHeightPixels = rhs.mHeightPixels;
// "security" fields
mWhiteListEnable = rhs.mWhiteListEnable;
mWhiteList = rhs.mWhiteList;
// "permissions" fields
mPermsInteract = rhs.mPermsInteract;
mPermsControl = rhs.mPermsControl;
}
LLMediaEntry::~LLMediaEntry()
{
if (NULL != mMediaIDp)
{
delete mMediaIDp;
}
}
LLSD LLMediaEntry::asLLSD() const
{
LLSD sd;
asLLSD(sd);
return sd;
}
//
// LLSD functions
//
void LLMediaEntry::asLLSD(LLSD& sd) const
{
// "general" fields
sd[ALT_IMAGE_ENABLE_KEY] = mAltImageEnable;
sd[CONTROLS_KEY] = (LLSD::Integer)mControls;
sd[CURRENT_URL_KEY] = mCurrentURL;
sd[HOME_URL_KEY] = mHomeURL;
sd[AUTO_LOOP_KEY] = mAutoLoop;
sd[AUTO_PLAY_KEY] = mAutoPlay;
sd[AUTO_SCALE_KEY] = mAutoScale;
sd[AUTO_ZOOM_KEY] = mAutoZoom;
sd[FIRST_CLICK_INTERACT_KEY] = mFirstClickInteract;
sd[WIDTH_PIXELS_KEY] = mWidthPixels;
sd[HEIGHT_PIXELS_KEY] = mHeightPixels;
// "security" fields
sd[WHITELIST_ENABLE_KEY] = mWhiteListEnable;
for (U32 i=0; i<mWhiteList.size(); i++)
{
sd[WHITELIST_KEY].append(mWhiteList[i]);
}
// "permissions" fields
sd[PERMS_INTERACT_KEY] = mPermsInteract;
sd[PERMS_CONTROL_KEY] = mPermsControl;
}
// static
bool LLMediaEntry::checkLLSD(const LLSD& sd)
{
if (sd.isUndefined()) return true;
LLMediaEntry temp;
return temp.fromLLSDInternal(sd, true);
}
void LLMediaEntry::fromLLSD(const LLSD& sd)
{
(void)fromLLSDInternal(sd, true);
}
void LLMediaEntry::mergeFromLLSD(const LLSD& sd)
{
(void)fromLLSDInternal(sd, false);
}
// *NOTE: returns true if NO failures to set occurred, false otherwise.
// However, be aware that if a failure to set does occur, it does
// not stop setting fields from the LLSD!
bool LLMediaEntry::fromLLSDInternal(const LLSD& sd, bool overwrite)
{
// *HACK: we sort of cheat here and assume that status is a
// bit field. We "or" into status and instead of returning
// it, we return whether it finishes off as LSL_STATUS_OK or not.
U32 status = LSL_STATUS_OK;
// "general" fields
if ( overwrite || sd.has(ALT_IMAGE_ENABLE_KEY) )
{
status |= setAltImageEnable( sd[ALT_IMAGE_ENABLE_KEY] );
}
if ( overwrite || sd.has(CONTROLS_KEY) )
{
status |= setControls( (MediaControls)(LLSD::Integer)sd[CONTROLS_KEY] );
}
if ( overwrite || sd.has(CURRENT_URL_KEY) )
{
// Don't check whitelist
status |= setCurrentURLInternal( sd[CURRENT_URL_KEY], false );
}
if ( overwrite || sd.has(HOME_URL_KEY) )
{
status |= setHomeURL( sd[HOME_URL_KEY] );
}
if ( overwrite || sd.has(AUTO_LOOP_KEY) )
{
status |= setAutoLoop( sd[AUTO_LOOP_KEY] );
}
if ( overwrite || sd.has(AUTO_PLAY_KEY) )
{
status |= setAutoPlay( sd[AUTO_PLAY_KEY] );
}
if ( overwrite || sd.has(AUTO_SCALE_KEY) )
{
status |= setAutoScale( sd[AUTO_SCALE_KEY] );
}
if ( overwrite || sd.has(AUTO_ZOOM_KEY) )
{
status |= setAutoZoom( sd[AUTO_ZOOM_KEY] );
}
if ( overwrite || sd.has(FIRST_CLICK_INTERACT_KEY) )
{
status |= setFirstClickInteract( sd[FIRST_CLICK_INTERACT_KEY] );
}
if ( overwrite || sd.has(WIDTH_PIXELS_KEY) )
{
status |= setWidthPixels( (LLSD::Integer)sd[WIDTH_PIXELS_KEY] );
}
if ( overwrite || sd.has(HEIGHT_PIXELS_KEY) )
{
status |= setHeightPixels( (LLSD::Integer)sd[HEIGHT_PIXELS_KEY] );
}
// "security" fields
if ( overwrite || sd.has(WHITELIST_ENABLE_KEY) )
{
status |= setWhiteListEnable( sd[WHITELIST_ENABLE_KEY] );
}
if ( overwrite || sd.has(WHITELIST_KEY) )
{
status |= setWhiteList( sd[WHITELIST_KEY] );
}
// "permissions" fields
if ( overwrite || sd.has(PERMS_INTERACT_KEY) )
{
status |= setPermsInteract( 0xff & (LLSD::Integer)sd[PERMS_INTERACT_KEY] );
}
if ( overwrite || sd.has(PERMS_CONTROL_KEY) )
{
status |= setPermsControl( 0xff & (LLSD::Integer)sd[PERMS_CONTROL_KEY] );
}
return LSL_STATUS_OK == status;
}
LLMediaEntry& LLMediaEntry::operator=(const LLMediaEntry &rhs)
{
if (this != &rhs)
{
// "general" fields
mAltImageEnable = rhs.mAltImageEnable;
mControls = rhs.mControls;
mCurrentURL = rhs.mCurrentURL;
mHomeURL = rhs.mHomeURL;
mAutoLoop = rhs.mAutoLoop;
mAutoPlay = rhs.mAutoPlay;
mAutoScale = rhs.mAutoScale;
mAutoZoom = rhs.mAutoZoom;
mFirstClickInteract = rhs.mFirstClickInteract;
mWidthPixels = rhs.mWidthPixels;
mHeightPixels = rhs.mHeightPixels;
// "security" fields
mWhiteListEnable = rhs.mWhiteListEnable;
mWhiteList = rhs.mWhiteList;
// "permissions" fields
mPermsInteract = rhs.mPermsInteract;
mPermsControl = rhs.mPermsControl;
}
return *this;
}
bool LLMediaEntry::operator==(const LLMediaEntry &rhs) const
{
return (
// "general" fields
mAltImageEnable == rhs.mAltImageEnable &&
mControls == rhs.mControls &&
mCurrentURL == rhs.mCurrentURL &&
mHomeURL == rhs.mHomeURL &&
mAutoLoop == rhs.mAutoLoop &&
mAutoPlay == rhs.mAutoPlay &&
mAutoScale == rhs.mAutoScale &&
mAutoZoom == rhs.mAutoZoom &&
mFirstClickInteract == rhs.mFirstClickInteract &&
mWidthPixels == rhs.mWidthPixels &&
mHeightPixels == rhs.mHeightPixels &&
// "security" fields
mWhiteListEnable == rhs.mWhiteListEnable &&
mWhiteList == rhs.mWhiteList &&
// "permissions" fields
mPermsInteract == rhs.mPermsInteract &&
mPermsControl == rhs.mPermsControl
);
}
bool LLMediaEntry::operator!=(const LLMediaEntry &rhs) const
{
return (
// "general" fields
mAltImageEnable != rhs.mAltImageEnable ||
mControls != rhs.mControls ||
mCurrentURL != rhs.mCurrentURL ||
mHomeURL != rhs.mHomeURL ||
mAutoLoop != rhs.mAutoLoop ||
mAutoPlay != rhs.mAutoPlay ||
mAutoScale != rhs.mAutoScale ||
mAutoZoom != rhs.mAutoZoom ||
mFirstClickInteract != rhs.mFirstClickInteract ||
mWidthPixels != rhs.mWidthPixels ||
mHeightPixels != rhs.mHeightPixels ||
// "security" fields
mWhiteListEnable != rhs.mWhiteListEnable ||
mWhiteList != rhs.mWhiteList ||
// "permissions" fields
mPermsInteract != rhs.mPermsInteract ||
mPermsControl != rhs.mPermsControl
);
}
U32 LLMediaEntry::setWhiteList( const std::vector<std::string> &whitelist )
{
// *NOTE: This code is VERY similar to the setWhitelist below.
// IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER!
U32 size = 0;
U32 count = 0;
// First count to make sure the size constraint is not violated
std::vector<std::string>::const_iterator iter = whitelist.begin();
std::vector<std::string>::const_iterator end = whitelist.end();
for ( ; iter < end; ++iter)
{
const std::string &entry = (*iter);
size += entry.length() + 1; // Include one for \0
count ++;
if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT)
{
return LSL_STATUS_BOUNDS_ERROR;
}
}
// Next clear the vector
mWhiteList.clear();
// Then re-iterate and copy entries
iter = whitelist.begin();
for ( ; iter < end; ++iter)
{
const std::string &entry = (*iter);
mWhiteList.push_back(entry);
}
return LSL_STATUS_OK;
}
U32 LLMediaEntry::setWhiteList( const LLSD &whitelist )
{
// If whitelist is undef, this is a no-op.
if (whitelist.isUndefined()) return LSL_STATUS_OK;
// However, if the whitelist is an empty array, erase it.
if (whitelist.isArray())
{
// *NOTE: This code is VERY similar to the setWhitelist above.
// IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER!
U32 size = 0;
U32 count = 0;
// First check to make sure the size and count constraints are not violated
LLSD::array_const_iterator iter = whitelist.beginArray();
LLSD::array_const_iterator end = whitelist.endArray();
for ( ; iter < end; ++iter)
{
const std::string &entry = (*iter).asString();
size += entry.length() + 1; // Include one for \0
count ++;
if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT)
{
return LSL_STATUS_BOUNDS_ERROR;
}
}
// Next clear the vector
mWhiteList.clear();
// Then re-iterate and copy entries
iter = whitelist.beginArray();
for ( ; iter < end; ++iter)
{
const std::string &entry = (*iter).asString();
mWhiteList.push_back(entry);
}
return LSL_STATUS_OK;
}
else
{
return LSL_STATUS_MALFORMED_PARAMS;
}
}
static void prefix_with(std::string &str, const char *chars, const char *prefix)
{
// Given string 'str', prefix all instances of any character in 'chars'
// with 'prefix'
size_t found = str.find_first_of(chars);
size_t prefix_len = strlen(prefix);
while (found != std::string::npos)
{
str.insert(found, prefix, prefix_len);
found = str.find_first_of(chars, found+prefix_len+1);
}
}
static bool pattern_match(const std::string &candidate_str, const std::string &pattern)
{
// If the pattern is empty, it matches
if (pattern.empty()) return true;
// 'pattern' is a glob pattern, we only accept '*' chars
// copy it
std::string expression = pattern;
// Escape perl's regexp chars with a backslash, except all "*" chars
prefix_with(expression, ".[{()\\+?|^$", "\\");
prefix_with(expression, "*", ".");
// case-insensitive matching:
boost::regex regexp(expression, boost::regex::perl|boost::regex::icase);
return boost::regex_match(candidate_str, regexp);
}
bool LLMediaEntry::checkCandidateUrl(const std::string& url) const
{
if (getWhiteListEnable())
{
return checkUrlAgainstWhitelist(url, getWhiteList());
}
else
{
return true;
}
}
// static
bool LLMediaEntry::checkUrlAgainstWhitelist(const std::string& url,
const std::vector<std::string> &whitelist)
{
bool passes = true;
// *NOTE: no entries? Don't check
if (whitelist.size() > 0)
{
passes = false;
// Case insensitive: the reason why we toUpper both this and the
// filter
std::string candidate_url = url;
// Use lluri to see if there is a path part in the candidate URL. No path? Assume "/"
LLURI candidate_uri(candidate_url);
std::vector<std::string>::const_iterator iter = whitelist.begin();
std::vector<std::string>::const_iterator end = whitelist.end();
for ( ; iter < end; ++iter )
{
std::string filter = *iter;
LLURI filter_uri(filter);
bool scheme_passes = pattern_match( candidate_uri.scheme(), filter_uri.scheme() );
if (filter_uri.scheme().empty())
{
filter_uri = LLURI(DEFAULT_URL_PREFIX + filter);
}
bool authority_passes = pattern_match( candidate_uri.authority(), filter_uri.authority() );
bool path_passes = pattern_match( candidate_uri.escapedPath(), filter_uri.escapedPath() );
if (scheme_passes && authority_passes && path_passes)
{
passes = true;
break;
}
}
}
return passes;
}
U32 LLMediaEntry::setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit )
{
if ( value.length() > limit )
{
return LSL_STATUS_BOUNDS_ERROR;
}
else
{
field = value;
return LSL_STATUS_OK;
}
}
U32 LLMediaEntry::setControls(LLMediaEntry::MediaControls controls)
{
if (controls == STANDARD ||
controls == MINI)
{
mControls = controls;
return LSL_STATUS_OK;
}
return LSL_STATUS_BOUNDS_ERROR;
}
U32 LLMediaEntry::setPermsInteract( U8 val )
{
mPermsInteract = val & PERM_MASK;
return LSL_STATUS_OK;
}
U32 LLMediaEntry::setPermsControl( U8 val )
{
mPermsControl = val & PERM_MASK;
return LSL_STATUS_OK;
}
U32 LLMediaEntry::setCurrentURL(const std::string& current_url)
{
return setCurrentURLInternal( current_url, true );
}
U32 LLMediaEntry::setCurrentURLInternal(const std::string& current_url, bool check_whitelist)
{
if ( ! check_whitelist || checkCandidateUrl(current_url))
{
return setStringFieldWithLimit( mCurrentURL, current_url, MAX_URL_LENGTH );
}
else
{
return LSL_STATUS_WHITELIST_FAILED;
}
}
U32 LLMediaEntry::setHomeURL(const std::string& home_url)
{
return setStringFieldWithLimit( mHomeURL, home_url, MAX_URL_LENGTH );
}
U32 LLMediaEntry::setWidthPixels(U16 width)
{
if (width > MAX_WIDTH_PIXELS) return LSL_STATUS_BOUNDS_ERROR;
mWidthPixels = width;
return LSL_STATUS_OK;
}
U32 LLMediaEntry::setHeightPixels(U16 height)
{
if (height > MAX_HEIGHT_PIXELS) return LSL_STATUS_BOUNDS_ERROR;
mHeightPixels = height;
return LSL_STATUS_OK;
}
const LLUUID &LLMediaEntry::getMediaID() const
{
// Lazily generate media ID
if (NULL == mMediaIDp)
{
mMediaIDp = new LLUUID();
mMediaIDp->generate();
}
return *mMediaIDp;
}

View File

@ -0,0 +1,228 @@
/**
* @file llmediaentry.h
* @brief This is a single instance of media data related to the face of a prim
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLMEDIAENTRY_H
#define LL_LLMEDIAENTRY_H
#include "llsd.h"
#include "llstring.h"
// For return values of set*
#include "lllslconstants.h"
class LLMediaEntry
{
public:
enum MediaControls {
STANDARD = 0,
MINI
};
// Constructors
LLMediaEntry();
LLMediaEntry(const LLMediaEntry &rhs);
LLMediaEntry &operator=(const LLMediaEntry &rhs);
virtual ~LLMediaEntry();
bool operator==(const LLMediaEntry &rhs) const;
bool operator!=(const LLMediaEntry &rhs) const;
// Render as LLSD
LLSD asLLSD() const;
void asLLSD(LLSD& sd) const;
operator LLSD() const { return asLLSD(); }
// Returns false iff the given LLSD contains fields that violate any bounds
// limits.
static bool checkLLSD(const LLSD& sd);
// This doesn't merge, it overwrites the data, so will use
// LLSD defaults if need be. Note: does not check limits!
// Use checkLLSD() above first to ensure the LLSD is valid.
void fromLLSD(const LLSD& sd);
// This merges data from the incoming LLSD into our fields.
// Note that it also does NOT check limits! Use checkLLSD() above first.
void mergeFromLLSD(const LLSD& sd);
// "general" fields
bool getAltImageEnable() const { return mAltImageEnable; }
MediaControls getControls() const { return mControls; }
std::string getCurrentURL() const { return mCurrentURL; }
std::string getHomeURL() const { return mHomeURL; }
bool getAutoLoop() const { return mAutoLoop; }
bool getAutoPlay() const { return mAutoPlay; }
bool getAutoScale() const { return mAutoScale; }
bool getAutoZoom() const { return mAutoZoom; }
bool getFirstClickInteract() const { return mFirstClickInteract; }
U16 getWidthPixels() const { return mWidthPixels; }
U16 getHeightPixels() const { return mHeightPixels; }
// "security" fields
bool getWhiteListEnable() const { return mWhiteListEnable; }
const std::vector<std::string> &getWhiteList() const { return mWhiteList; }
// "permissions" fields
U8 getPermsInteract() const { return mPermsInteract; }
U8 getPermsControl() const { return mPermsControl; }
// Setters. Those that return a U32 return a status error code
// See lllslconstants.h
// "general" fields
U32 setAltImageEnable(bool alt_image_enable) { mAltImageEnable = alt_image_enable; return LSL_STATUS_OK; }
U32 setControls(MediaControls controls);
U32 setCurrentURL(const std::string& current_url);
U32 setHomeURL(const std::string& home_url);
U32 setAutoLoop(bool auto_loop) { mAutoLoop = auto_loop; return LSL_STATUS_OK; }
U32 setAutoPlay(bool auto_play) { mAutoPlay = auto_play; return LSL_STATUS_OK; }
U32 setAutoScale(bool auto_scale) { mAutoScale = auto_scale; return LSL_STATUS_OK; }
U32 setAutoZoom(bool auto_zoom) { mAutoZoom = auto_zoom; return LSL_STATUS_OK; }
U32 setFirstClickInteract(bool first_click) { mFirstClickInteract = first_click; return LSL_STATUS_OK; }
U32 setWidthPixels(U16 width);
U32 setHeightPixels(U16 height);
// "security" fields
U32 setWhiteListEnable( bool whitelist_enable ) { mWhiteListEnable = whitelist_enable; return LSL_STATUS_OK; }
U32 setWhiteList( const std::vector<std::string> &whitelist );
U32 setWhiteList( const LLSD &whitelist ); // takes an LLSD array
// "permissions" fields
U32 setPermsInteract( U8 val );
U32 setPermsControl( U8 val );
const LLUUID& getMediaID() const;
// Helper function to check a candidate URL against the whitelist
// Returns true iff candidate URL passes (or if there is no whitelist), false otherwise
bool checkCandidateUrl(const std::string& url) const;
public:
// Static function to check a URL against a whitelist
// Returns true iff url passes the given whitelist
static bool checkUrlAgainstWhitelist(const std::string &url,
const std::vector<std::string> &whitelist);
public:
// LLSD key defines
// "general" fields
static const char* ALT_IMAGE_ENABLE_KEY;
static const char* CONTROLS_KEY;
static const char* CURRENT_URL_KEY;
static const char* HOME_URL_KEY;
static const char* AUTO_LOOP_KEY;
static const char* AUTO_PLAY_KEY;
static const char* AUTO_SCALE_KEY;
static const char* AUTO_ZOOM_KEY;
static const char* FIRST_CLICK_INTERACT_KEY;
static const char* WIDTH_PIXELS_KEY;
static const char* HEIGHT_PIXELS_KEY;
// "security" fields
static const char* WHITELIST_ENABLE_KEY;
static const char* WHITELIST_KEY;
// "permissions" fields
static const char* PERMS_INTERACT_KEY;
static const char* PERMS_CONTROL_KEY;
// Field enumerations & constants
// *NOTE: DO NOT change the order of these, and do not insert values
// in the middle!
// Add values to the end, and make sure to change PARAM_MAX_ID!
enum Fields {
ALT_IMAGE_ENABLE_ID = 0,
CONTROLS_ID = 1,
CURRENT_URL_ID = 2,
HOME_URL_ID = 3,
AUTO_LOOP_ID = 4,
AUTO_PLAY_ID = 5,
AUTO_SCALE_ID = 6,
AUTO_ZOOM_ID = 7,
FIRST_CLICK_INTERACT_ID = 8,
WIDTH_PIXELS_ID = 9,
HEIGHT_PIXELS_ID = 10,
WHITELIST_ENABLE_ID = 11,
WHITELIST_ID = 12,
PERMS_INTERACT_ID = 13,
PERMS_CONTROL_ID = 14,
PARAM_MAX_ID = PERMS_CONTROL_ID
};
// "permissions" values
// (e.g. (PERM_OWNER | PERM_GROUP) sets permissions on for OWNER and GROUP
static const U8 PERM_NONE = 0x0;
static const U8 PERM_OWNER = 0x1;
static const U8 PERM_GROUP = 0x2;
static const U8 PERM_ANYONE = 0x4;
static const U8 PERM_ALL = PERM_OWNER|PERM_GROUP|PERM_ANYONE;
static const U8 PERM_MASK = PERM_OWNER|PERM_GROUP|PERM_ANYONE;
// Limits (in bytes)
static const U32 MAX_URL_LENGTH = 1024;
static const U32 MAX_WHITELIST_SIZE = 1024;
static const U32 MAX_WHITELIST_COUNT = 64;
static const U16 MAX_WIDTH_PIXELS = 2048;
static const U16 MAX_HEIGHT_PIXELS = 2048;
private:
U32 setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit );
U32 setCurrentURLInternal( const std::string &url, bool check_whitelist);
bool fromLLSDInternal(const LLSD &sd, bool overwrite);
private:
// "general" fields
bool mAltImageEnable;
MediaControls mControls;
std::string mCurrentURL;
std::string mHomeURL;
bool mAutoLoop;
bool mAutoPlay;
bool mAutoScale;
bool mAutoZoom;
bool mFirstClickInteract;
U16 mWidthPixels;
U16 mHeightPixels;
// "security" fields
bool mWhiteListEnable;
std::vector<std::string> mWhiteList;
// "permissions" fields
U8 mPermsInteract;
U8 mPermsControl;
mutable LLUUID *mMediaIDp; // temporary id assigned to media on the viewer
};
#endif

View File

@ -1319,6 +1319,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con
color.mV[VALPHA] = F32(255 - coloru.mV[VALPHA]) / 255.f;
retval |= setTEColor(i, color);
}
return retval;

View File

@ -32,13 +32,31 @@
#include "linden_common.h"
#include "lluuid.h"
#include "llmediaentry.h"
#include "lltextureentry.h"
#include "llsdutil.h"
#include "v4color.h"
const U8 DEFAULT_BUMP_CODE = 0; // no bump or shininess
const LLTextureEntry LLTextureEntry::null;
// Some LLSD keys. Do not change these!
#define OBJECT_ID_KEY_STR "object_id"
#define TEXTURE_INDEX_KEY_STR "texture_index"
#define OBJECT_MEDIA_VERSION_KEY_STR "object_media_version"
#define OBJECT_MEDIA_DATA_KEY_STR "object_media_data"
#define TEXTURE_MEDIA_DATA_KEY_STR "media_data"
/*static*/ const char* LLTextureEntry::OBJECT_ID_KEY = OBJECT_ID_KEY_STR;
/*static*/ const char* LLTextureEntry::OBJECT_MEDIA_DATA_KEY = OBJECT_MEDIA_DATA_KEY_STR;
/*static*/ const char* LLTextureEntry::MEDIA_VERSION_KEY = OBJECT_MEDIA_VERSION_KEY_STR;
/*static*/ const char* LLTextureEntry::TEXTURE_INDEX_KEY = TEXTURE_INDEX_KEY_STR;
/*static*/ const char* LLTextureEntry::TEXTURE_MEDIA_DATA_KEY = TEXTURE_MEDIA_DATA_KEY_STR;
static const std::string MEDIA_VERSION_STRING_PREFIX = "x-mv:";
// static
LLTextureEntry* LLTextureEntry::newTextureEntry()
{
@ -47,16 +65,19 @@ LLTextureEntry* LLTextureEntry::newTextureEntry()
//===============================================================
LLTextureEntry::LLTextureEntry()
: mMediaEntry(NULL)
{
init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
: mMediaEntry(NULL)
{
init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
: mMediaEntry(NULL)
{
mID = rhs.mID;
mScaleS = rhs.mScaleS;
@ -68,6 +89,10 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
mBump = rhs.mBump;
mMediaFlags = rhs.mMediaFlags;
mGlow = rhs.mGlow;
if (rhs.mMediaEntry != NULL) {
// Make a copy
mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
}
}
LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
@ -84,6 +109,16 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
mBump = rhs.mBump;
mMediaFlags = rhs.mMediaFlags;
mGlow = rhs.mGlow;
if (mMediaEntry != NULL) {
delete mMediaEntry;
}
if (rhs.mMediaEntry != NULL) {
// Make a copy
mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
}
else {
mMediaEntry = NULL;
}
}
return *this;
@ -103,10 +138,19 @@ void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 of
mGlow = 0;
setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
if (mMediaEntry != NULL) {
delete mMediaEntry;
}
mMediaEntry = NULL;
}
LLTextureEntry::~LLTextureEntry()
{
if(mMediaEntry)
{
delete mMediaEntry;
mMediaEntry = NULL;
}
}
bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const
@ -158,10 +202,17 @@ void LLTextureEntry::asLLSD(LLSD& sd) const
sd["bump"] = getBumpShiny();
sd["fullbright"] = getFullbright();
sd["media_flags"] = mMediaFlags;
if (hasMedia()) {
LLSD mediaData;
if (NULL != getMediaData()) {
getMediaData()->asLLSD(mediaData);
}
sd[TEXTURE_MEDIA_DATA_KEY] = mediaData;
}
sd["glow"] = mGlow;
}
bool LLTextureEntry::fromLLSD(LLSD& sd)
bool LLTextureEntry::fromLLSD(const LLSD& sd)
{
const char *w, *x;
w = "imageid";
@ -206,6 +257,17 @@ bool LLTextureEntry::fromLLSD(LLSD& sd)
{
setMediaTexGen( sd[w].asInteger() );
} else goto fail;
// If the "has media" flag doesn't match the fact that
// media data exists, updateMediaData will "fix" it
// by either clearing or setting the flag
w = TEXTURE_MEDIA_DATA_KEY;
if (hasMedia() != sd.has(w))
{
llwarns << "LLTextureEntry::fromLLSD: media_flags (" << hasMedia() <<
") does not match presence of media_data (" << sd.has(w) << "). Fixing." << llendl;
}
updateMediaData(sd[w]);
w = "glow";
if (sd.has(w))
{
@ -370,7 +432,19 @@ S32 LLTextureEntry::setMediaTexGen(U8 media)
if (mMediaFlags != media)
{
mMediaFlags = media;
return TEM_CHANGE_TEXTURE;
// Special code for media handling
if( hasMedia() && mMediaEntry == NULL)
{
mMediaEntry = new LLMediaEntry;
}
else if ( ! hasMedia() && mMediaEntry != NULL)
{
delete mMediaEntry;
mMediaEntry = NULL;
}
return TEM_CHANGE_MEDIA;
}
return TEM_CHANGE_NONE;
}
@ -430,7 +504,19 @@ S32 LLTextureEntry::setMediaFlags(U8 media_flags)
{
mMediaFlags &= ~TEM_MEDIA_MASK;
mMediaFlags |= media_flags;
return TEM_CHANGE_TEXTURE;
// Special code for media handling
if( hasMedia() && mMediaEntry == NULL)
{
mMediaEntry = new LLMediaEntry;
}
else if ( ! hasMedia() && mMediaEntry != NULL)
{
delete mMediaEntry;
mMediaEntry = NULL;
}
return TEM_CHANGE_MEDIA;
}
return TEM_CHANGE_NONE;
}
@ -456,3 +542,107 @@ S32 LLTextureEntry::setGlow(F32 glow)
}
return TEM_CHANGE_NONE;
}
void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)
{
mMediaFlags |= MF_HAS_MEDIA;
if (NULL != mMediaEntry)
{
delete mMediaEntry;
}
mMediaEntry = new LLMediaEntry(media_entry);
}
bool LLTextureEntry::updateMediaData(const LLSD& media_data)
{
if (media_data.isUndefined())
{
// clear the media data
clearMediaData();
return false;
}
else {
mMediaFlags |= MF_HAS_MEDIA;
if (mMediaEntry == NULL)
{
mMediaEntry = new LLMediaEntry;
}
// *NOTE: this will *clobber* all of the fields in mMediaEntry
// with whatever fields are present (or not present) in media_data!
mMediaEntry->fromLLSD(media_data);
return true;
}
}
void LLTextureEntry::clearMediaData()
{
mMediaFlags &= ~MF_HAS_MEDIA;
if (mMediaEntry != NULL) {
delete mMediaEntry;
}
mMediaEntry = NULL;
}
void LLTextureEntry::mergeIntoMediaData(const LLSD& media_fields)
{
mMediaFlags |= MF_HAS_MEDIA;
if (mMediaEntry == NULL)
{
mMediaEntry = new LLMediaEntry;
}
// *NOTE: this will *merge* the data in media_fields
// with the data in our media entry
mMediaEntry->mergeFromLLSD(media_fields);
}
//static
std::string LLTextureEntry::touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id)
{
// XXX TODO: make media version string binary (base64-encoded?)
// Media "URL" is a representation of a version and the last-touched agent
// x-mv:nnnnn/agent-id
// where "nnnnn" is version number
// *NOTE: not the most efficient code in the world...
U32 current_version = getVersionFromMediaVersionString(in_version) + 1;
const size_t MAX_VERSION_LEN = 10; // 2^32 fits in 10 decimal digits
char buf[MAX_VERSION_LEN+1];
snprintf(buf, (int)MAX_VERSION_LEN+1, "%0*u", (int)MAX_VERSION_LEN, current_version); // added int cast to fix warning/breakage on mac.
return MEDIA_VERSION_STRING_PREFIX + buf + "/" + agent_id.asString();
}
//static
U32 LLTextureEntry::getVersionFromMediaVersionString(const std::string &version_string)
{
U32 version = 0;
if (!version_string.empty())
{
size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
if (found != std::string::npos)
{
found = version_string.find_first_of("/", found);
std::string v = version_string.substr(MEDIA_VERSION_STRING_PREFIX.length(), found);
version = strtoul(v.c_str(),NULL,10);
}
}
return version;
}
//static
LLUUID LLTextureEntry::getAgentIDFromMediaVersionString(const std::string &version_string)
{
LLUUID id;
if (!version_string.empty())
{
size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
if (found != std::string::npos)
{
found = version_string.find_first_of("/", found);
if (found != std::string::npos)
{
std::string v = version_string.substr(found + 1);
id.set(v);
}
}
}
return id;
}

View File

@ -37,10 +37,13 @@
#include "v4color.h"
#include "llsd.h"
// These bits are used while unpacking TEM messages to tell which aspects of
// the texture entry changed.
const S32 TEM_CHANGE_NONE = 0x0;
const S32 TEM_CHANGE_COLOR = 0x1;
const S32 TEM_CHANGE_TEXTURE = 0x2;
const S32 TEM_INVALID = 0x4;
const S32 TEM_CHANGE_MEDIA = 0x4;
const S32 TEM_INVALID = 0x8;
const S32 TEM_BUMPMAP_COUNT = 32;
@ -65,6 +68,8 @@ const S32 TEM_MEDIA_MASK = 0x01;
const S32 TEM_TEX_GEN_MASK = 0x06;
const S32 TEM_TEX_GEN_SHIFT = 1;
// forward declarations
class LLMediaEntry;
class LLTextureEntry
{
@ -92,7 +97,7 @@ public:
LLSD asLLSD() const;
void asLLSD(LLSD& sd) const;
operator LLSD() const { return asLLSD(); }
bool fromLLSD(LLSD& sd);
bool fromLLSD(const LLSD& sd);
virtual LLTextureEntry* newBlank() const;
virtual LLTextureEntry* newCopy() const;
@ -140,9 +145,35 @@ public:
U8 getTexGen() const { return mMediaFlags & TEM_TEX_GEN_MASK; }
U8 getMediaTexGen() const { return mMediaFlags; }
F32 getGlow() const { return mGlow; }
// *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.
// CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData()
// to NOT return NULL.
bool hasMedia() const { return (bool)(mMediaFlags & MF_HAS_MEDIA); }
LLMediaEntry* getMediaData() const { return mMediaEntry; }
// Completely change the media data on this texture entry.
void setMediaData(const LLMediaEntry &media_entry);
// Returns true if media data was updated, false if it was cleared
bool updateMediaData(const LLSD& media_data);
// Clears media data, and sets the media flags bit to 0
void clearMediaData();
// Merges the given LLSD of media fields with this media entry.
// Only those fields that are set that match the keys in
// LLMediaEntry will be affected. If no fields are set or if
// the LLSD is undefined, this is a no-op.
void mergeIntoMediaData(const LLSD& media_fields);
// Takes a media version string (an empty string or a previously-returned string)
// and returns a "touched" string, touched by agent_id
static std::string touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id);
// Given a media version string, return the version
static U32 getVersionFromMediaVersionString(const std::string &version_string);
// Given a media version string, return the UUID of the agent
static LLUUID getAgentIDFromMediaVersionString(const std::string &version_string);
// Media flags
enum { MF_NONE = 0x0, MF_WEB_PAGE = 0x1 };
enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 };
public:
F32 mScaleS; // S, T offset
@ -152,6 +183,14 @@ public:
F32 mRotation; // anti-clockwise rotation in rad about the bottom left corner
static const LLTextureEntry null;
// LLSD key defines
static const char* OBJECT_ID_KEY;
static const char* OBJECT_MEDIA_DATA_KEY;
static const char* MEDIA_VERSION_KEY;
static const char* TEXTURE_INDEX_KEY;
static const char* TEXTURE_MEDIA_DATA_KEY;
protected:
LLUUID mID; // Texture GUID
LLColor4 mColor;
@ -159,6 +198,9 @@ protected:
U8 mMediaFlags; // replace with web page, movie, etc.
F32 mGlow;
// Note the media data is not sent via the same message structure as the rest of the TE
LLMediaEntry* mMediaEntry; // The media data for the face
// NOTE: when adding new data to this class, in addition to adding it to the serializers asLLSD/fromLLSD and the
// message packers (e.g. LLPrimitive::packTEMessage) you must also implement its copy in LLPrimitive::copyTEs()

View File

@ -0,0 +1,484 @@
/**
* @file llmediaentry_test.cpp
* @brief llmediaentry unit tests
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
* Copyright (c) 2001-2009, Linden Research, Inc.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "boost/lexical_cast.hpp"
#include "llstring.h"
#include "llsdutil.h"
#include "llsdserialize.h"
#include "../llmediaentry.h"
#include "lllslconstants.h"
#define DEFAULT_MEDIA_ENTRY "<llsd>\n\
<map>\n\
<key>alt_image_enable</key>\n\
<boolean>0</boolean>\n\
<key>auto_loop</key>\n\
<boolean>0</boolean>\n\
<key>auto_play</key>\n\
<boolean>0</boolean>\n\
<key>auto_scale</key>\n\
<boolean>0</boolean>\n\
<key>auto_zoom</key>\n\
<boolean>0</boolean>\n\
<key>controls</key>\n\
<integer>0</integer>\n\
<key>current_url</key>\n\
<string />\n\
<key>first_click_interact</key>\n\
<boolean>0</boolean>\n\
<key>height_pixels</key>\n\
<integer>0</integer>\n\
<key>home_url</key>\n\
<string />\n\
<key>perms_control</key>\n\
<integer>7</integer>\n\
<key>perms_interact</key>\n\
<integer>7</integer>\n\
<key>whitelist_enable</key>\n\
<boolean>0</boolean>\n\
<key>width_pixels</key>\n\
<integer>0</integer>\n\
</map>\n\
</llsd>"
#define EMPTY_MEDIA_ENTRY "<llsd>\n\
<map>\n\
<key>alt_image_enable</key>\n\
<boolean>0</boolean>\n\
<key>auto_loop</key>\n\
<boolean>0</boolean>\n\
<key>auto_play</key>\n\
<boolean>0</boolean>\n\
<key>auto_scale</key>\n\
<boolean>0</boolean>\n\
<key>auto_zoom</key>\n\
<boolean>0</boolean>\n\
<key>controls</key>\n\
<integer>0</integer>\n\
<key>current_url</key>\n\
<string />\n\
<key>first_click_interact</key>\n\
<boolean>0</boolean>\n\
<key>height_pixels</key>\n\
<integer>0</integer>\n\
<key>home_url</key>\n\
<string />\n\
<key>perms_control</key>\n\
<integer>0</integer>\n\
<key>perms_interact</key>\n\
<integer>0</integer>\n\
<key>whitelist_enable</key>\n\
<boolean>0</boolean>\n\
<key>width_pixels</key>\n\
<integer>0</integer>\n\
</map>\n\
</llsd>"
#define PARTIAL_MEDIA_ENTRY(CURRENT_URL) "<llsd>\n\
<map>\n\
<key>alt_image_enable</key>\n\
<boolean>0</boolean>\n\
<key>auto_loop</key>\n\
<boolean>0</boolean>\n\
<key>auto_play</key>\n\
<boolean>0</boolean>\n\
<key>auto_scale</key>\n\
<boolean>0</boolean>\n\
<key>auto_zoom</key>\n\
<boolean>0</boolean>\n\
<key>controls</key>\n\
<integer>0</integer>\n\
<key>current_url</key>\n\
<string>" CURRENT_URL "</string>\n\
<key>first_click_interact</key>\n\
<boolean>0</boolean>\n\
<key>height_pixels</key>\n\
<integer>0</integer>\n\
<key>home_url</key>\n\
<string />\n\
<key>perms_control</key>\n\
<integer>0</integer>\n\
<key>perms_interact</key>\n\
<integer>0</integer>\n\
<key>whitelist_enable</key>\n\
<boolean>0</boolean>\n\
<key>width_pixels</key>\n\
<integer>0</integer>\n\
</map>\n\
</llsd>"
namespace tut
{
// this is fixture data that gets created before each test and destroyed
// after each test. this is where we put all of the setup/takedown code
// and data needed for each test.
struct MediaEntry_test
{
MediaEntry_test() {
emptyMediaEntryStr = EMPTY_MEDIA_ENTRY;
std::istringstream e(EMPTY_MEDIA_ENTRY);
LLSDSerialize::fromXML(emptyMediaEntryLLSD, e);
defaultMediaEntryStr = DEFAULT_MEDIA_ENTRY;
std::istringstream d(DEFAULT_MEDIA_ENTRY);
LLSDSerialize::fromXML(defaultMediaEntryLLSD, d);
}
std::string emptyMediaEntryStr;
LLSD emptyMediaEntryLLSD;
std::string defaultMediaEntryStr;
LLSD defaultMediaEntryLLSD;
};
typedef test_group<MediaEntry_test, 55> factory;
typedef factory::object object;
}
namespace
{
// this is for naming our tests to make pretty output
tut::factory tf("MediaEntry Test");
}
namespace tut
{
bool llsd_equals(const LLSD& a, const LLSD& b) {
// cheesy, brute force, but it works
return std::string(ll_pretty_print_sd(a)) == std::string(ll_pretty_print_sd(b));
}
void ensure_llsd_equals(const std::string& msg, const LLSD& expected, const LLSD& actual)
{
if (! llsd_equals(expected, actual))
{
std::string message = msg;
message += ": actual: ";
message += ll_pretty_print_sd(actual);
message += "\n expected: ";
message += ll_pretty_print_sd(expected);
message += "\n";
ensure(message, false);
}
}
void ensure_string_equals(const std::string& msg, const std::string& expected, const std::string& actual)
{
if ( expected != actual )
{
std::string message = msg;
message += ": actual: ";
message += actual;
message += "\n expected: ";
message += expected;
message += "\n";
ensure(message, false);
}
}
void set_whitelist(LLMediaEntry &entry, const char *str)
{
std::vector<std::string> tokens;
LLStringUtil::getTokens(std::string(str), tokens, ",");
entry.setWhiteList(tokens);
}
void whitelist_test(bool enable, const char *whitelist, const char *candidate_url, bool expected_pass)
{
std::string message = "Whitelist test";
LLMediaEntry entry;
entry.setWhiteListEnable(enable);
set_whitelist(entry, whitelist);
bool passed_whitelist = entry.checkCandidateUrl(candidate_url);
if (passed_whitelist != expected_pass)
{
message += " failed: expected ";
message += (expected_pass) ? "" : "NOT ";
message += "to match\nwhitelist = ";
message += whitelist;
message += "\ncandidate_url = ";
message += candidate_url;
}
ensure(message, expected_pass == passed_whitelist);
}
void whitelist_test(const char *whitelist, const char *candidate_url, bool expected_pass)
{
whitelist_test(true, whitelist, candidate_url, expected_pass);
}
void whitelist_test(const char *whitelist, const char *candidate_url)
{
whitelist_test(true, whitelist, candidate_url, true);
}
template<> template<>
void object::test<1>()
{
set_test_name("Test LLMediaEntry Instantiation");
LLMediaEntry entry;
ensure_llsd_equals(get_test_name(), defaultMediaEntryLLSD, entry.asLLSD());
}
template<> template<>
void object::test<2>()
{
set_test_name("Test LLMediaEntry Instantiation from LLSD");
LLMediaEntry entry;
LLSD sd;
entry.fromLLSD(sd);
ensure_llsd_equals(get_test_name() + " failed", emptyMediaEntryLLSD, entry.asLLSD());
}
template<> template<>
void object::test<3>()
{
set_test_name("Test LLMediaEntry Partial Instantiation from LLSD");
LLMediaEntry entry;
LLSD sd;
sd[LLMediaEntry::CURRENT_URL_KEY] = "http://www.example.com";
entry.fromLLSD(sd);
LLSD golden;
std::istringstream p(PARTIAL_MEDIA_ENTRY("http://www.example.com"));
LLSDSerialize::fromXML(golden,p);
ensure_llsd_equals(get_test_name() + " failed", golden, entry.asLLSD());
}
// limit tests
const char *URL_OK = "http://www.example.com";
const char *URL_TOO_BIG = "http://www.example.com.qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq";
template<> template<>
void object::test<4>()
{
set_test_name("Test Limits on setting current URL");
LLMediaEntry entry;
U32 status = entry.setCurrentURL(URL_OK);
ensure(get_test_name() + " ok failed", status == LSL_STATUS_OK);
status = entry.setCurrentURL(URL_TOO_BIG);
ensure(get_test_name() + " ok failed", status == LSL_STATUS_BOUNDS_ERROR);
}
template<> template<>
void object::test<5>()
{
set_test_name("Test Limits on setting home URL");
LLMediaEntry entry;
U32 status = entry.setHomeURL(URL_OK);
ensure(get_test_name() + " ok failed", status == LSL_STATUS_OK);
status = entry.setHomeURL(URL_TOO_BIG);
ensure(get_test_name() + " ok failed", status == LSL_STATUS_BOUNDS_ERROR);
}
template<> template<>
void object::test<6>()
{
set_test_name("Test Limits on setting whitelist");
// Test a valid list
LLMediaEntry entry;
std::vector<std::string> whitelist;
whitelist.push_back(std::string(URL_OK));
S32 status = entry.setWhiteList(whitelist);
ensure(get_test_name() + " invalid result", status == LSL_STATUS_OK);
ensure(get_test_name() + " failed", whitelist == entry.getWhiteList());
}
template<> template<>
void object::test<7>()
{
set_test_name("Test Limits on setting whitelist too big");
// Test an invalid list
LLMediaEntry entry;
std::vector<std::string> whitelist, empty;
whitelist.push_back(std::string(URL_OK));
whitelist.push_back(std::string(URL_TOO_BIG));
S32 status = entry.setWhiteList(whitelist);
ensure(get_test_name() + " invalid result", status == LSL_STATUS_BOUNDS_ERROR);
ensure(get_test_name() + " failed", empty == entry.getWhiteList());
}
template<> template<>
void object::test<8>()
{
set_test_name("Test Limits on setting whitelist too many");
// Test an invalid list
LLMediaEntry entry;
std::vector<std::string> whitelist, empty;
for (int i=0; i < LLMediaEntry::MAX_WHITELIST_SIZE+1; i++) {
whitelist.push_back("Q");
}
S32 status = entry.setWhiteList(whitelist);
ensure(get_test_name() + " invalid result", status == LSL_STATUS_BOUNDS_ERROR);
ensure(get_test_name() + " failed", empty == entry.getWhiteList());
}
template<> template<>
void object::test<9>()
{
set_test_name("Test to make sure both setWhiteList() functions behave the same");
// Test a valid list
std::vector<std::string> whitelist, empty;
LLSD whitelist_llsd;
whitelist.push_back(std::string(URL_OK));
whitelist_llsd.append(std::string(URL_OK));
LLMediaEntry entry1, entry2;
ensure(get_test_name() + " setWhiteList(s) don't match",
entry1.setWhiteList(whitelist) == LSL_STATUS_OK &&
entry2.setWhiteList(whitelist_llsd)== LSL_STATUS_OK );
ensure(get_test_name() + " failed",
entry1.getWhiteList() == entry2.getWhiteList());
}
template<> template<>
void object::test<10>()
{
set_test_name("Test to make sure both setWhiteList() functions behave the same");
// Test an invalid list
std::vector<std::string> whitelist, empty;
LLSD whitelist_llsd;
whitelist.push_back(std::string(URL_OK));
whitelist.push_back(std::string(URL_TOO_BIG));
whitelist_llsd.append(std::string(URL_OK));
whitelist_llsd.append(std::string(URL_TOO_BIG));
LLMediaEntry entry1, entry2;
ensure(get_test_name() + " setWhiteList(s) don't match",
entry1.setWhiteList(whitelist) == LSL_STATUS_BOUNDS_ERROR &&
entry2.setWhiteList(whitelist_llsd) == LSL_STATUS_BOUNDS_ERROR);
ensure(get_test_name() + " failed",
empty == entry1.getWhiteList() &&
empty == entry2.getWhiteList());
}
template<> template<>
void object::test<11>()
{
set_test_name("Test to make sure both setWhiteList() functions behave the same");
// Test an invalid list, too many
std::vector<std::string> whitelist, empty;
LLSD whitelist_llsd;
for (int i=0; i < LLMediaEntry::MAX_WHITELIST_SIZE+1; i++) {
whitelist.push_back("Q");
whitelist_llsd.append("Q");
}
LLMediaEntry entry1, entry2;
ensure(get_test_name() + " invalid result",
entry1.setWhiteList(whitelist) == LSL_STATUS_BOUNDS_ERROR &&
entry2.setWhiteList(whitelist_llsd) == LSL_STATUS_BOUNDS_ERROR);
ensure(get_test_name() + " failed",
empty == entry1.getWhiteList() &&
empty == entry2.getWhiteList());
}
// Whitelist check tests
// Check the "empty whitelist" case
template<> template<>
void object::test<12>() { whitelist_test("", "http://www.example.com", true); }
// Check the "missing scheme" case
template<> template<>
void object::test<13>() { whitelist_test("www.example.com", "http://www.example.com", true); }
// Check the "exactly the same" case
template<> template<>
void object::test<14>() { whitelist_test("http://example.com", "http://example.com", true); }
// Check the enable flag
template<> template<>
void object::test<15>() { whitelist_test(false, "www.example.com", "http://www.secondlife.com", true); }
template<> template<>
void object::test<16>() { whitelist_test(true, "www.example.com", "http://www.secondlife.com", false); }
// Check permutations of trailing slash:
template<> template<>
void object::test<17>() { whitelist_test("http://www.example.com", "http://www.example.com/", true); }
template<> template<>
void object::test<18>() { whitelist_test("http://www.example.com/", "http://www.example.com/", true); }
template<> template<>
void object::test<19>() { whitelist_test("http://www.example.com/", "http://www.example.com", false); }
template<> template<>
void object::test<20>() { whitelist_test("http://www.example.com", "http://www.example.com/foobar", true); }
template<> template<>
void object::test<21>() { whitelist_test("http://www.example.com/", "http://www.example.com/foobar", false); }
// More cases...
template<> template<>
void object::test<22>() { whitelist_test("http://example.com", "http://example.com/wiki", true); }
template<> template<>
void object::test<23>() { whitelist_test("www.example.com", "http://www.example.com/help", true); }
template<> template<>
void object::test<24>() { whitelist_test("http://www.example.com", "http://wwwexample.com", false); }
template<> template<>
void object::test<25>() { whitelist_test("http://www.example.com", "http://www.example.com/wiki", true); }
template<> template<>
void object::test<26>() { whitelist_test("example.com", "http://wwwexample.com", false); }
template<> template<>
void object::test<27>() { whitelist_test("http://www.example.com/", "http://www.amazon.com/wiki", false); }
template<> template<>
void object::test<28>() { whitelist_test("www.example.com", "http://www.amazon.com", false); }
// regexp cases
template<> template<>
void object::test<29>() { whitelist_test("*.example.com", "http://www.example.com", true); }
template<> template<>
void object::test<30>() { whitelist_test("*.example.com", "http://www.amazon.com", false); }
template<> template<>
void object::test<31>() { whitelist_test("*.example.com", "http://www.example.com/foo/bar", true); }
template<> template<>
void object::test<32>() { whitelist_test("*.example.com", "http:/example.com/foo/bar", false); }
template<> template<>
void object::test<33>() { whitelist_test("*example.com", "http://example.com/foo/bar", true); }
template<> template<>
void object::test<34>() { whitelist_test("*example.com", "http://my.virus.com/foo/bar?example.com", false); }
template<> template<>
void object::test<35>() { whitelist_test("example.com", "http://my.virus.com/foo/bar?example.com", false); }
template<> template<>
void object::test<36>() { whitelist_test("*example.com", "http://my.virus.com/foo/bar?*example.com", false); }
template<> template<>
void object::test<37>() { whitelist_test("http://*example.com", "http://www.example.com", true); }
template<> template<>
void object::test<38>() { whitelist_test("http://*.example.com", "http://www.example.com", true); }
template<> template<>
void object::test<39>() { whitelist_test("http://*.e$?^.com", "http://www.e$?^.com", true); }
template<> template<>
void object::test<40>() { whitelist_test("*.example.com/foo/bar", "http://www.example.com/", false); }
template<> template<>
void object::test<41>() { whitelist_test("*.example.com/foo/bar", "http://example.com/foo/bar", false); }
template<> template<>
void object::test<42>() { whitelist_test("http://*.example.com/foo/bar", "http://www.example.com", false); }
template<> template<>
void object::test<43>() { whitelist_test("http://*.example.com", "https://www.example.com", false); }
template<> template<>
void object::test<44>() { whitelist_test("http*://*.example.com", "rtsp://www.example.com", false); }
template<> template<>
void object::test<45>() { whitelist_test("http*://*.example.com", "https://www.example.com", true); }
template<> template<>
void object::test<46>() { whitelist_test("example.com", "http://www.example.com", false); }
template<> template<>
void object::test<47>() { whitelist_test("www.example.com", "http://www.example.com:80", false); }
template<> template<>
void object::test<48>() { whitelist_test("www.example.com", "http://www.example.com", true); }
template<> template<>
void object::test<49>() { whitelist_test("www.example.com/", "http://www.example.com", false); }
template<> template<>
void object::test<50>() { whitelist_test("www.example.com/foo/bar/*", "http://www.example.com/foo/bar/baz", true); }
// Path only
template<> template<>
void object::test<51>() { whitelist_test("/foo/*/baz", "http://www.example.com/foo/bar/baz", true); }
template<> template<>
void object::test<52>() { whitelist_test("/foo/*/baz", "http://www.example.com/foo/bar/", false); }
}

View File

@ -85,6 +85,7 @@ set(llui_SOURCE_FILES
lltextbox.cpp
lltexteditor.cpp
lltextparser.cpp
lltransientfloatermgr.cpp
lltransutil.cpp
lltooltip.cpp
llui.cpp
@ -129,7 +130,7 @@ set(llui_HEADER_FILES
llfocusmgr.h
llfunctorregistry.h
llhandle.h
llhtmlhelp.h
llhelp.h
lliconctrl.h
llkeywords.h
lllayoutstack.h
@ -171,6 +172,7 @@ set(llui_HEADER_FILES
lltexteditor.h
lltextparser.h
lltooltip.h
lltransientfloatermgr.h
lltransutil.h
lluicolortable.h
lluiconstants.h

View File

@ -39,7 +39,6 @@
#include "llstring.h"
// Project includes
#include "llhtmlhelp.h"
#include "llkeyboard.h"
#include "llui.h"
#include "lluiconstants.h"
@ -49,8 +48,10 @@
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llwindow.h"
#include "llnotifications.h"
#include "llrender.h"
#include "lluictrlfactory.h"
#include "llhelp.h"
static LLDefaultChildRegistry::Register<LLButton> r("button");
@ -92,7 +93,6 @@ LLButton::Params::Params()
mouse_held_callback("mouse_held_callback"),
is_toggle("is_toggle", false),
scale_image("scale_image", true),
help_url("help_url"),
hover_glow_amount("hover_glow_amount"),
commit_on_return("commit_on_return", true),
picture_style("picture_style", false)
@ -173,11 +173,6 @@ LLButton::LLButton(const LLButton::Params& p)
mMouseDownTimer.stop();
if (p.help_url.isProvided())
{
setHelpURLCallback(p.help_url);
}
// if custom unselected button image provided...
if (p.image_unselected != default_params.image_unselected)
{
@ -1034,24 +1029,6 @@ void LLButton::addImageAttributeToXML(LLXMLNodePtr node,
}
}
void clicked_help(void* data)
{
LLButton* self = (LLButton*)data;
if (!self) return;
if (!LLUI::sHtmlHelp)
{
return;
}
LLUI::sHtmlHelp->show(self->getHelpURL());
}
void LLButton::setHelpURLCallback(const std::string &help_url)
{
mHelpURL = help_url;
setClickedCallback(clicked_help,this);
}
// static
void LLButton::toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname)
@ -1077,6 +1054,24 @@ void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname)
button->setClickedCallback(boost::bind(&LLFloaterReg::toggleFloaterInstance, sdname));
}
// static
void LLButton::showHelp(LLUICtrl* ctrl, const LLSD& sdname)
{
// search back through the button's parents for a panel
// with a help_topic string defined
std::string help_topic;
if (LLUI::sHelpImpl &&
ctrl->findHelpTopic(help_topic))
{
LLUI::sHelpImpl->showTopic(help_topic);
return; // success
}
// display an error if we can't find a help_topic string.
// fix this by adding a help_topic attribute to the xui file
LLNotifications::instance().add("UnableToFindHelpTopic");
}
void LLButton::resetMouseDownTimer()
{
mMouseDownTimer.stop();

View File

@ -118,7 +118,6 @@ public:
commit_on_return,
picture_style; //if true, don't display label
Optional<std::string> help_url;
Optional<F32> hover_glow_amount;
Optional<TimeIntervalParam> held_down_delay;
@ -230,12 +229,10 @@ public:
void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; }
BOOL getCommitOnReturn() const { return mCommitOnReturn; }
void setHelpURLCallback(const std::string &help_url);
const std::string& getHelpURL() const { return mHelpURL; }
static void onHeldDown(void *userdata); // to be called by gIdleCallbacks
static void toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname);
static void setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname);
static void showHelp(LLUICtrl* ctrl, const LLSD& sdname);
protected:
const LLPointer<LLUIImage>& getImageUnselected() const { return mImageUnselected; }
@ -314,8 +311,6 @@ private:
BOOL mCommitOnReturn;
BOOL mFadeWhenDisabled;
std::string mHelpURL;
LLFrameTimer mFlashingTimer;
};

View File

@ -483,7 +483,6 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p)
params.max_length_bytes(mMaxChars);
params.commit_callback.function(boost::bind(&LLComboBox::onTextCommit, this, _2));
params.keystroke_callback(boost::bind(&LLComboBox::onTextEntry, this, _1));
params.focus_lost_callback(NULL);
params.handle_edit_keys_directly(true);
params.commit_on_focus_lost(false);
params.follows.flags(FOLLOWS_ALL);

View File

@ -71,9 +71,9 @@ void LLDockableFloater::resetInstance()
if (sInstanceHandle.get() != NULL && sInstanceHandle.get()->isDocked())
{
sInstanceHandle.get()->setVisible(FALSE);
}
}
sInstanceHandle = getHandle();
}
}
}
void LLDockableFloater::setVisible(BOOL visible)
@ -105,11 +105,11 @@ void LLDockableFloater::setDocked(bool docked, bool pop_on_undock)
mDockControl.get()->off();
}
if (!docked && pop_on_undock)
{
// visually pop up a little bit to emphasize the undocking
translate(0, UNDOCK_LEAP_HEIGHT);
}
if (!docked && pop_on_undock)
{
// visually pop up a little bit to emphasize the undocking
translate(0, UNDOCK_LEAP_HEIGHT);
}
}
else
{
@ -126,8 +126,8 @@ void LLDockableFloater::draw()
mDockControl.get()->repositionDockable();
if (isDocked())
{
mDockControl.get()->drawToungue();
}
mDockControl.get()->drawToungue();
}
}
LLFloater::draw();
}

View File

@ -35,7 +35,7 @@
#include "lldockcontrol.h"
LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
const LLUIImagePtr& dockTongue, DocAt dockAt, get_rect_callback_t get_rect_callback) :
const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue(dockTongue)
{
mDockAt = dockAt;
@ -49,13 +49,13 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
off();
}
if (!(get_rect_callback))
if (!(get_allowed_rect_callback))
{
mGetRectCallback = boost::bind(&LLDockControl::getEnabledRect, this, _1);
mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1);
}
else
{
mGetRectCallback = get_rect_callback;
mGetAllowedRectCallback = get_allowed_rect_callback;
}
if (dockWidget != NULL)
@ -77,7 +77,7 @@ void LLDockControl::setDock(LLView* dockWidget)
}
}
void LLDockControl::getEnabledRect(LLRect& rect)
void LLDockControl::getAllowedRect(LLRect& rect)
{
rect = mDockableFloater->getRootView()->getRect();
}
@ -86,7 +86,7 @@ void LLDockControl::repositionDockable()
{
LLRect dockRect = mDockWidget->calcScreenRect();
LLRect rootRect;
mGetRectCallback(rootRect);
mGetAllowedRectCallback(rootRect);
static BOOL prev_visibility = !mDockWidget->getVisible();
// recalculate dockable position if dock position changed, dock visibility changed,
@ -100,7 +100,7 @@ void LLDockControl::repositionDockable()
mDockableFloater->setDocked(false);
// force off() since dockable may not have dockControll at this time
off();
}
}
else
{
moveDockable();
@ -123,10 +123,10 @@ bool LLDockControl::isDockVisible()
res = mDockWidget->isInVisibleChain();
if (res)
{
LLRect dockRect = mDockWidget->calcScreenRect();
LLRect dockRect = mDockWidget->calcScreenRect();
switch (mDockAt)
{
{
case TOP:
// check is dock inside parent rect
LLRect dockParentRect =
@ -149,25 +149,25 @@ void LLDockControl::moveDockable()
// calculate new dockable position
LLRect dockRect = mDockWidget->calcScreenRect();
LLRect rootRect;
mGetRectCallback(rootRect);
mGetAllowedRectCallback(rootRect);
LLRect dockableRect = mDockableFloater->calcScreenRect();
S32 x = 0;
S32 y = 0;
switch (mDockAt)
{
case TOP:
x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
LLRect dockableRect = mDockableFloater->calcScreenRect();
S32 x = 0;
S32 y = 0;
switch (mDockAt)
{
case TOP:
x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.getHeight();
// check is dockable inside root view rect
if (x < rootRect.mLeft)
{
x = rootRect.mLeft;
}
if (x + dockableRect.getWidth() > rootRect.mRight)
{
x = rootRect.mRight - dockableRect.getWidth();
}
if (x < rootRect.mLeft)
{
x = rootRect.mLeft;
}
if (x + dockableRect.getWidth() > rootRect.mRight)
{
x = rootRect.mRight - dockableRect.getWidth();
}
// calculate dock tongue position
@ -185,21 +185,21 @@ void LLDockControl::moveDockable()
{
mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
}
mDockTongueY = dockRect.mTop;
mDockTongueY = dockRect.mTop;
break;
}
break;
}
// move dockable
dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
dockableRect.getHeight());
LLRect localDocableParentRect;
mDockableFloater->getParent()->screenRectToLocal(dockableRect,
&localDocableParentRect);
mDockableFloater->setRect(localDocableParentRect);
dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
dockableRect.getHeight());
LLRect localDocableParentRect;
mDockableFloater->getParent()->screenRectToLocal(dockableRect,
&localDocableParentRect);
mDockableFloater->setRect(localDocableParentRect);
mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
&mDockTongueX, &mDockTongueY);
mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
&mDockTongueX, &mDockTongueY);
}
@ -207,9 +207,9 @@ void LLDockControl::on()
{
if (isDockVisible())
{
mDockableFloater->setCanDrag(false);
mEnabled = true;
mRecalculateDocablePosition = true;
mDockableFloater->setCanDrag(false);
mEnabled = true;
mRecalculateDocablePosition = true;
}
}

View File

@ -52,11 +52,11 @@ public:
public:
// callback for a function getting a rect valid for control's position
typedef boost::function<void (LLRect& )> get_rect_callback_t;
typedef boost::function<void (LLRect& )> get_allowed_rect_callback_t;
LOG_CLASS(LLDockControl);
LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
const LLUIImagePtr& dockTongue, DocAt dockAt, get_rect_callback_t get_rect_callback = NULL);
const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_rect_callback = NULL);
virtual ~LLDockControl();
public:
@ -67,13 +67,13 @@ public:
void drawToungue();
bool isDockVisible();
// gets a rect that bounds possible positions for a dockable control
void getEnabledRect(LLRect& rect);
// gets a rect that bounds possible positions for a dockable control (EXT-1111)
void getAllowedRect(LLRect& rect);
private:
virtual void moveDockable();
private:
get_rect_callback_t mGetRectCallback;
get_allowed_rect_callback_t mGetAllowedRectCallback;
bool mEnabled;
bool mRecalculateDocablePosition;
DocAt mDockAt;

View File

@ -39,8 +39,8 @@
static const LLDefaultChildRegistry::Register<LLFlatListView> flat_list_view("flat_list_view");
const LLSD SELECTED_EVENT = LLSD().insert("selected", true);
const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false);
const LLSD SELECTED_EVENT = LLSD().insert("selected", true);
const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false);
static const std::string COMMENT_TEXTBOX = "comment_text";

View File

@ -59,6 +59,7 @@
#include "lltabcontainer.h"
#include "v2math.h"
#include "lltrans.h"
#include "llhelp.h"
#include "llmultifloater.h"
// use this to control "jumping" behavior when Ctrl-Tabbing
@ -66,48 +67,35 @@ const S32 TABBED_FLOATER_OFFSET = 0;
std::string LLFloater::sButtonActiveImageNames[BUTTON_COUNT] =
{
"Icon_Close_Foreground", //BUTTON_CLOSE
"restore.tga", //BUTTON_RESTORE
"minimize.tga", //BUTTON_MINIMIZE
"tearoffbox.tga", //BUTTON_TEAR_OFF
"closebox.tga", //BUTTON_EDIT
"Icon_Dock_Foreground",
"Icon_Undock_Foreground"
};
// Empty string means programmatic glow effect, achieved by
// not setting explicit image.
std::string LLFloater::sButtonHoveredImageNames[BUTTON_COUNT] =
{
"", //BUTTON_CLOSE
"restore_pressed.tga", //BUTTON_RESTORE
"minimize_pressed.tga", //BUTTON_MINIMIZE
"tearoff_pressed.tga", //BUTTON_TEAR_OFF
"close_in_blue.tga", //BUTTON_EDIT
"", //BUTTON_DOCK
"", //BUTTON_UNDOCK
"Icon_Close_Foreground", //BUTTON_CLOSE
"Icon_Restore_Foreground", //BUTTON_RESTORE
"Icon_Minimize_Foreground", //BUTTON_MINIMIZE
"tearoffbox.tga", //BUTTON_TEAR_OFF
"Icon_Dock_Foreground", //BUTTON_DOCK
"Icon_Undock_Foreground", //BUTTON_UNDOCK
"Icon_Help_Foreground" //BUTTON_HELP
};
std::string LLFloater::sButtonPressedImageNames[BUTTON_COUNT] =
{
"Icon_Close_Press", //BUTTON_CLOSE
"restore_pressed.tga", //BUTTON_RESTORE
"minimize_pressed.tga", //BUTTON_MINIMIZE
"tearoff_pressed.tga", //BUTTON_TEAR_OFF
"close_in_blue.tga", //BUTTON_EDIT
"Icon_Dock_Press",
"Icon_Undock_Press"
"Icon_Close_Press", //BUTTON_CLOSE
"Icon_Restore_Press", //BUTTON_RESTORE
"Icon_Minimize_Press", //BUTTON_MINIMIZE
"tearoff_pressed.tga", //BUTTON_TEAR_OFF
"Icon_Dock_Press", //BUTTON_DOCK
"Icon_Undock_Press", //BUTTON_UNDOCK
"Icon_Help_Press" //BUTTON_HELP
};
std::string LLFloater::sButtonNames[BUTTON_COUNT] =
{
"llfloater_close_btn", //BUTTON_CLOSE
"llfloater_close_btn", //BUTTON_CLOSE
"llfloater_restore_btn", //BUTTON_RESTORE
"llfloater_minimize_btn", //BUTTON_MINIMIZE
"llfloater_tear_off_btn", //BUTTON_TEAR_OFF
"llfloater_edit_btn", //BUTTON_EDIT
"llfloater_dock_btn",
"llfloater_undock_btn"
"llfloater_dock_btn", //BUTTON_DOCK
"llfloater_undock_btn", //BUTTON_UNDOCK
"llfloater_help_btn" //BUTTON_HELP
};
std::string LLFloater::sButtonToolTips[BUTTON_COUNT];
@ -122,9 +110,9 @@ std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]=
"BUTTON_RESTORE", //"Restore", //BUTTON_RESTORE
"BUTTON_MINIMIZE", //"Minimize", //BUTTON_MINIMIZE
"BUTTON_TEAR_OFF", //"Tear Off", //BUTTON_TEAR_OFF
"BUTTON_EDIT", //"Edit", //BUTTON_EDIT
"BUTTON_DOCK",
"BUTTON_UNDOCK"
"BUTTON_UNDOCK",
"BUTTON_HELP"
};
LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
@ -133,13 +121,12 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
LLFloater::onClickMinimize, //BUTTON_RESTORE
LLFloater::onClickMinimize, //BUTTON_MINIMIZE
LLFloater::onClickTearOff, //BUTTON_TEAR_OFF
LLFloater::onClickEdit, //BUTTON_EDIT
LLFloater::onClickDock,
LLFloater::onClickDock
LLFloater::onClickDock, //BUTTON_DOCK
LLFloater::onClickDock, //BUTTON_UNDOCK
LLFloater::onClickHelp //BUTTON_HELP
};
LLMultiFloater* LLFloater::sHostp = NULL;
BOOL LLFloater::sEditModeEnabled = FALSE;
BOOL LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting
LLFloater::handle_map_t LLFloater::sFloaterMap;
@ -259,7 +246,6 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mMinimized(FALSE),
mForeground(FALSE),
mFirstLook(TRUE),
mEditing(FALSE),
mButtonScale(1.0f),
mAutoFocus(TRUE), // automatically take focus when opened
mCanDock(false),
@ -314,6 +300,12 @@ void LLFloater::initFloater()
mButtonsEnabled[BUTTON_CLOSE] = TRUE;
}
// Help button: '?'
if ( !mHelpTopic.empty() )
{
mButtonsEnabled[BUTTON_HELP] = TRUE;
}
// Minimize button only for top draggers
if ( !mDragOnLeft && mCanMinimize )
{
@ -804,7 +796,7 @@ void LLFloater::setTitle( const std::string& title )
applyTitle();
}
std::string LLFloater::getTitle()
std::string LLFloater::getTitle() const
{
if (mTitle.empty())
{
@ -822,7 +814,7 @@ void LLFloater::setShortTitle( const std::string& short_title )
applyTitle();
}
std::string LLFloater::getShortTitle()
std::string LLFloater::getShortTitle() const
{
if (mShortTitle.empty())
{
@ -834,8 +826,6 @@ std::string LLFloater::getShortTitle()
}
}
BOOL LLFloater::canSnapTo(const LLView* other_view)
{
if (NULL == other_view)
@ -1051,6 +1041,10 @@ void LLFloater::setMinimized(BOOL minimize)
reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE );
}
// don't show the help button while minimized - it's
// not very useful when minimized and uses up space
mButtonsEnabled[BUTTON_HELP] = !minimize;
applyTitle ();
make_ui_sound("UISndWindowClose");
@ -1387,28 +1381,6 @@ void LLFloater::setDocked(bool docked, bool pop_on_undock)
}
}
//static
void LLFloater::setEditModeEnabled(BOOL enable)
{
if (enable != sEditModeEnabled)
{
S32 count = 0;
for(handle_map_iter_t iter = sFloaterMap.begin(); iter != sFloaterMap.end(); ++iter)
{
LLFloater* floater = iter->second;
if (!floater->isDead())
{
iter->second->mButtonsEnabled[BUTTON_EDIT] = enable;
iter->second->updateButtons();
}
count++;
}
}
sEditModeEnabled = enable;
}
// static
void LLFloater::onClickMinimize(LLFloater* self)
{
@ -1455,14 +1427,6 @@ void LLFloater::onClickTearOff(LLFloater* self)
}
}
// static
void LLFloater::onClickEdit(LLFloater* self)
{
if (!self)
return;
self->mEditing = self->mEditing ? FALSE : TRUE;
}
// static
void LLFloater::onClickDock(LLFloater* self)
{
@ -1472,6 +1436,15 @@ void LLFloater::onClickDock(LLFloater* self)
}
}
// static
void LLFloater::onClickHelp( LLFloater* self )
{
if (self && LLUI::sHelpImpl)
{
LLUI::sHelpImpl->showTopic(self->getHelpTopic());
}
}
// static
LLFloater* LLFloater::getClosableFloaterFromFocus()
{
@ -1807,17 +1780,9 @@ void LLFloater::buildButtons()
// Selected, no matter if hovered or not, is "pressed"
p.image_selected.name(sButtonPressedImageNames[i]);
p.image_hover_selected.name(sButtonPressedImageNames[i]);
// Empty string means programmatic glow effect, achieved by
// not setting explicit image.
if (sButtonHoveredImageNames[i].empty())
{
// These icons are really small, need glow amount increased
p.hover_glow_amount( 0.22f );
}
else
{
p.image_hover_unselected.name(sButtonHoveredImageNames[i]);
}
// Use a glow effect when the user hovers over the button
// These icons are really small, need glow amount increased
p.hover_glow_amount( 0.33f );
p.click_callback.function(boost::bind(sButtonCallbacks[i], this));
p.tab_stop(false);
p.follows.flags(FOLLOWS_TOP|FOLLOWS_RIGHT);

View File

@ -101,9 +101,9 @@ public:
BUTTON_RESTORE,
BUTTON_MINIMIZE,
BUTTON_TEAR_OFF,
BUTTON_EDIT,
BUTTON_DOCK,
BUTTON_UNDOCK,
BUTTON_HELP,
BUTTON_COUNT
};
@ -173,9 +173,9 @@ public:
void applyTitle();
const std::string& getCurrentTitle() const;
void setTitle( const std::string& title);
std::string getTitle();
std::string getTitle() const;
void setShortTitle( const std::string& short_title );
std::string getShortTitle();
std::string getShortTitle() const;
void setTitleVisible(bool visible);
virtual void setMinimized(BOOL b);
void moveResizeHandlesToFront();
@ -256,12 +256,10 @@ public:
static void onClickClose(LLFloater* floater);
static void onClickMinimize(LLFloater* floater);
static void onClickTearOff(LLFloater* floater);
static void onClickEdit(LLFloater* floater);
static void onClickDock(LLFloater* floater);
static void onClickHelp(LLFloater* floater);
static void setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; }
static void setEditModeEnabled(BOOL enable);
static BOOL getEditModeEnabled() { return sEditModeEnabled; }
static LLMultiFloater* getFloaterHost() {return sHostp; }
protected:
@ -331,7 +329,6 @@ private:
BOOL mFirstLook; // TRUE if the _next_ time this floater is visible will be the first time in the session that it is visible.
BOOL mEditing;
typedef std::set<LLHandle<LLFloater> > handle_set_t;
typedef std::set<LLHandle<LLFloater> >::iterator handle_set_iter_t;
@ -350,11 +347,8 @@ private:
bool mDocked;
static LLMultiFloater* sHostp;
static BOOL sEditModeEnabled;
static BOOL sQuitting;
static std::string sButtonActiveImageNames[BUTTON_COUNT];
// Images to use when cursor hovered over an enabled button
static std::string sButtonHoveredImageNames[BUTTON_COUNT];
static std::string sButtonPressedImageNames[BUTTON_COUNT];
static std::string sButtonNames[BUTTON_COUNT];
static std::string sButtonToolTips[BUTTON_COUNT];

View File

@ -41,11 +41,6 @@ const F32 FOCUS_FADE_TIME = 0.3f;
// NOTE: the LLFocusableElement implementation has been moved here from lluictrl.cpp.
LLFocusableElement::LLFocusableElement()
: mFocusLostCallback(NULL),
mFocusReceivedCallback(NULL),
mFocusChangedCallback(NULL),
mTopLostCallback(NULL),
mFocusCallbackUserData(NULL)
{
}
@ -68,35 +63,19 @@ LLFocusableElement::~LLFocusableElement()
void LLFocusableElement::onFocusReceived()
{
if( mFocusReceivedCallback )
{
mFocusReceivedCallback( this, mFocusCallbackUserData );
}
if( mFocusChangedCallback )
{
mFocusChangedCallback( this, mFocusCallbackUserData );
}
mFocusReceivedCallback(this);
mFocusChangedCallback(this);
}
void LLFocusableElement::onFocusLost()
{
if( mFocusLostCallback )
{
mFocusLostCallback( this, mFocusCallbackUserData );
}
if( mFocusChangedCallback )
{
mFocusChangedCallback( this, mFocusCallbackUserData );
}
mFocusLostCallback(this);
mFocusChangedCallback(this);
}
void LLFocusableElement::onTopLost()
{
if (mTopLostCallback)
{
mTopLostCallback(this, mFocusCallbackUserData);
}
mTopLostCallback(this);
}
BOOL LLFocusableElement::hasFocus() const
@ -188,12 +167,9 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
view_handle_list_t new_focus_list;
// walk up the tree to root and add all views to the new_focus_list
for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl && ctrl != LLUI::getRootView(); ctrl = ctrl->getParent())
for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl; ctrl = ctrl->getParent())
{
if (ctrl)
{
new_focus_list.push_back(ctrl->getHandle());
}
new_focus_list.push_back(ctrl->getHandle());
}
// remove all common ancestors since their focus is unchanged
@ -216,10 +192,6 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
{
mCachedKeyboardFocusList.pop_front();
old_focus_view->onFocusLost();
// part of fix of EXT-996
// this need to handle event when user click inside in-world area
mFocusChangeSignal();
}
}

View File

@ -54,11 +54,12 @@ public:
virtual void setFocus( BOOL b );
virtual BOOL hasFocus() const;
typedef boost::function<void(LLFocusableElement*, void*)> focus_callback_t;
void setFocusLostCallback(focus_callback_t cb, void* user_data = NULL) { mFocusLostCallback = cb; mFocusCallbackUserData = user_data; }
void setFocusReceivedCallback(focus_callback_t cb, void* user_data = NULL) { mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; }
void setFocusChangedCallback(focus_callback_t cb, void* user_data = NULL ) { mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; }
void setTopLostCallback(focus_callback_t cb, void* user_data = NULL ) { mTopLostCallback = cb; mFocusCallbackUserData = user_data; }
typedef boost::signals2::signal<void(LLFocusableElement*)> focus_signal_t;
boost::signals2::connection setFocusLostCallback( const focus_signal_t::slot_type& cb) { return mFocusLostCallback.connect(cb);}
boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb) { return mFocusReceivedCallback.connect(cb);}
boost::signals2::connection setFocusChangedCallback(const focus_signal_t::slot_type& cb) { return mFocusChangedCallback.connect(cb);}
void setTopLostCallback(const focus_signal_t::slot_type& cb) { mTopLostCallback.connect(cb);}
// These were brought up the hierarchy from LLView so that we don't have to use dynamic_cast when dealing with keyboard focus.
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
@ -68,11 +69,10 @@ protected:
virtual void onFocusReceived();
virtual void onFocusLost();
virtual void onTopLost(); // called when registered as top ctrl and user clicks elsewhere
focus_callback_t mFocusLostCallback;
focus_callback_t mFocusReceivedCallback;
focus_callback_t mFocusChangedCallback;
focus_callback_t mTopLostCallback;
void* mFocusCallbackUserData;
focus_signal_t mFocusLostCallback;
focus_signal_t mFocusReceivedCallback;
focus_signal_t mFocusChangedCallback;
focus_signal_t mTopLostCallback;
};
@ -124,11 +124,6 @@ public:
void unlockFocus();
BOOL focusLocked() const { return mLockedView != NULL; }
void addFocusChangeCallback(const boost::signals2::signal<void ()>::slot_type& cb)
{
mFocusChangeSignal.connect(cb);
}
private:
LLUICtrl* mLockedView;
@ -155,8 +150,6 @@ private:
typedef std::map<LLHandle<LLView>, LLHandle<LLView> > focus_history_map_t;
focus_history_map_t mFocusHistory;
boost::signals2::signal<void()> mFocusChangeSignal;
#ifdef _DEBUG
std::string mMouseCaptorName;
std::string mKeyboardFocusName;

45
indra/llui/llhelp.h Normal file
View File

@ -0,0 +1,45 @@
/**
* @file llhelp.h
* @brief Abstract interface to the Help system
* @author Tofu Linden
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLHELP_H
#define LL_LLHELP_H
class LLHelp
{
public:
virtual void showTopic(const std::string &topic) = 0;
// return default (fallback) topic name suitable for showTopic()
virtual std::string defaultTopic() = 0;
};
#endif // headerguard

View File

@ -140,7 +140,7 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p)
params.prevalidate_callback(&LLLineEditor::prevalidateFloat);
params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
mEditor->setFocusReceivedCallback( &LLMultiSliderCtrl::onEditorGainFocus );
mEditor->setFocusReceivedCallback( boost::bind(LLMultiSliderCtrl::onEditorGainFocus, _1, this) );
// don't do this, as selecting the entire text is single clicking in some cases
// and double clicking in others
//mEditor->setSelectAllonFocusReceived(TRUE);

View File

@ -80,6 +80,7 @@ LLPanel::Params::Params()
strings("string"),
filename("filename"),
class_name("class"),
help_topic("help_topic"),
visible_callback("visible_callback")
{
name = "panel";
@ -98,6 +99,7 @@ LLPanel::LLPanel(const LLPanel::Params& p)
mDefaultBtn(NULL),
mBorder(NULL),
mLabel(p.label),
mHelpTopic(p.help_topic),
mCommitCallbackRegistrar(false),
mEnableCallbackRegistrar(false),
mXMLFilename(p.filename)
@ -416,6 +418,7 @@ void LLPanel::initFromParams(const LLPanel::Params& p)
}
setLabel(p.label());
setHelpTopic(p.help_topic);
setShape(p.rect);
parseFollowsFlags(p);

View File

@ -83,6 +83,7 @@ public:
Optional<std::string> filename;
Optional<std::string> class_name;
Optional<std::string> help_topic;
Multiple<LocalizedString> strings;
@ -139,10 +140,11 @@ public:
void updateDefaultBtn();
void setLabel(const LLStringExplicit& label) { mLabel = label; }
std::string getLabel() const { return mLabel; }
void setHelpTopic(const std::string& help_topic) { mHelpTopic = help_topic; }
std::string getHelpTopic() const { return mHelpTopic; }
void setCtrlsEnabled(BOOL b);
LLHandle<LLPanel> getHandle() const { return mPanelHandle; }
const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; }
@ -243,6 +245,8 @@ protected:
EnableCallbackRegistry::ScopedRegistrar mEnableCallbackRegistrar;
commit_signal_t mVisibleSignal; // Called when visibility changes, passes new visibility as LLSD()
std::string mHelpTopic; // the name of this panel's help topic to display in the Help Viewer
private:
LLUIColor mBgColorAlpha;
@ -259,7 +263,7 @@ private:
// for setting the xml filename when building panel in context dependent cases
std::string mXMLFilename;
}; // end class LLPanel
#endif

View File

@ -130,12 +130,6 @@ public:
void onLineUpBtnPressed(const LLSD& data);
void onLineDownBtnPressed(const LLSD& data);
void setBGColor(const LLUIColor& color) { mBGColor = color; }
const LLUIColor& getBGColor() const { return mBGColor; }
void setBGVisible() { mBGVisible = true; }
bool getBGVisible() const { return mBGVisible; }
private:
void updateThumbRect();
void changeLine(S32 delta, BOOL update_thumb );

View File

@ -143,7 +143,7 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
line_p.prevalidate_callback(&LLLineEditor::prevalidateFloat);
mEditor = LLUICtrlFactory::create<LLLineEditor>(line_p);
mEditor->setFocusReceivedCallback( &LLSliderCtrl::onEditorGainFocus, this );
mEditor->setFocusReceivedCallback( boost::bind(&LLSliderCtrl::onEditorGainFocus, _1, this ));
// don't do this, as selecting the entire text is single clicking in some cases
// and double clicking in others
//mEditor->setSelectAllonFocusReceived(TRUE);

View File

@ -142,7 +142,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
params.prevalidate_callback(&LLLineEditor::prevalidateFloat);
params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
mEditor->setFocusReceivedCallback( &LLSpinCtrl::onEditorGainFocus, this );
mEditor->setFocusReceivedCallback( boost::bind(&LLSpinCtrl::onEditorGainFocus, _1, this ));
//RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus
// than when it doesn't. Instead, if you always have to double click to select all the text,
// it's easier to understand

View File

@ -2001,6 +2001,8 @@ void LLTextEditor::cut()
deleteSelection( FALSE );
needsReflow();
onKeyStroke();
}
BOOL LLTextEditor::canCopy() const
@ -2105,6 +2107,8 @@ void LLTextEditor::pasteHelper(bool is_primary)
deselect();
needsReflow();
onKeyStroke();
}
@ -2492,6 +2496,8 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
if(text_may_have_changed)
{
needsReflow();
onKeyStroke();
}
needsScroll();
}
@ -2534,6 +2540,8 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
deselect();
needsReflow();
onKeyStroke();
}
return handled;
@ -2588,6 +2596,8 @@ void LLTextEditor::doDelete()
setCursorPos(mCursorPos + 1);
removeChar();
}
onKeyStroke();
}
needsReflow();
@ -2634,6 +2644,8 @@ void LLTextEditor::undo()
setCursorPos(pos);
needsReflow();
onKeyStroke();
}
BOOL LLTextEditor::canRedo() const
@ -2676,6 +2688,8 @@ void LLTextEditor::redo()
setCursorPos(pos);
needsReflow();
onKeyStroke();
}
void LLTextEditor::onFocusReceived()
@ -4402,6 +4416,8 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string,
// Update of the preedit should be caused by some key strokes.
mKeystrokeTimer.reset();
onKeyStroke();
}
BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const
@ -4648,3 +4664,30 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor)
ed->addDocumentChild(mView);
}
}
BOOL LLTextEditor::isDirty() const
{
if(mReadOnly)
{
return FALSE;
}
if( mPristineCmd )
{
return ( mPristineCmd == mLastCmd );
}
else
{
return ( NULL != mLastCmd );
}
}
void LLTextEditor::setKeystrokeCallback(const keystroke_signal_t::slot_type& callback)
{
mKeystrokeSignal.connect(callback);
}
void LLTextEditor::onKeyStroke()
{
mKeystrokeSignal(this);
}

View File

@ -139,6 +139,10 @@ public:
virtual ~LLTextEditor();
typedef boost::signals2::signal<void (LLTextEditor* caller)> keystroke_signal_t;
void setKeystrokeCallback(const keystroke_signal_t::slot_type& callback);
void setParseHighlights(BOOL parsing) {mParseHighlights=parsing;}
// mousehandler overrides
@ -169,7 +173,7 @@ public:
virtual void clear();
virtual void setFocus( BOOL b );
virtual BOOL acceptsTextInput() const;
virtual BOOL isDirty() const { return isPristine(); }
virtual BOOL isDirty() const;
virtual void setValue(const LLSD& value);
// LLEditMenuHandler interface
@ -503,6 +507,8 @@ private:
S32 getFirstVisibleLine() const;
void onKeyStroke();
//
// Data
//
@ -568,6 +574,8 @@ private:
BOOL mHandleEditKeysDirectly;
LLCoordGL mLastIMEPosition; // Last position of the IME editor
keystroke_signal_t mKeystrokeSignal;
}; // end class LLTextEditor

View File

@ -79,10 +79,10 @@ std::list<std::string> gUntranslated;
/*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL;
/*static*/ LLVector2 LLUI::sGLScaleFactor(1.f, 1.f);
/*static*/ LLWindow* LLUI::sWindow = NULL;
/*static*/ LLHtmlHelp* LLUI::sHtmlHelp = NULL;
/*static*/ LLView* LLUI::sRootView = NULL;
/*static*/ BOOL LLUI::sDirty = FALSE;
/*static*/ LLRect LLUI::sDirtyRect;
/*static*/ BOOL LLUI::sDirty = FALSE;
/*static*/ LLRect LLUI::sDirtyRect;
/*static*/ LLHelp* LLUI::sHelpImpl = NULL;
/*static*/ std::vector<std::string> LLUI::sXUIPaths;
/*static*/ LLFrameTimer LLUI::sMouseIdleTimer;
@ -695,44 +695,6 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
}
void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
{
if (NULL == image)
{
llwarns << "image == NULL; aborting function" << llendl;
return;
}
LLGLSUIDefault gls_ui;
gGL.pushMatrix();
{
gGL.translatef((F32)x, (F32)y, 0.f);
gGL.getTexUnit(0)->bind(image);
gGL.color4fv(color.mV);
gGL.begin(LLRender::QUADS);
{
gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
gGL.vertex2i(width, height );
gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
gGL.vertex2i(0, height );
gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
gGL.vertex2i(0, 0);
gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
gGL.vertex2i(width, 0);
}
gGL.end();
}
gGL.popMatrix();
}
void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )
{
phase = fmod(phase, 1.f);
@ -1592,6 +1554,9 @@ void LLUI::initClass(const settings_map_t& settings,
// Button initialization callback for toggle buttons
LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2));
// Display the help topic for the current context
LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ShowHelp", boost::bind(&LLButton::showHelp, _1, _2));
// Currently unused, but kept for reference:
LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2));
@ -1850,12 +1815,6 @@ LLPointer<LLUIImage> LLUI::getUIImage(const std::string& name)
return NULL;
}
// static
void LLUI::setHtmlHelp(LLHtmlHelp* html_help)
{
LLUI::sHtmlHelp = html_help;
}
LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
{
for (settings_map_t::iterator itor = sSettingGroups.begin();

View File

@ -57,13 +57,13 @@
#include "llfontgl.h"
class LLColor4;
class LLHtmlHelp;
class LLVector3;
class LLVector2;
class LLUIImage;
class LLUUID;
class LLWindow;
class LLView;
class LLHelp;
// UI colors
extern const LLColor4 UI_VERTEX_COLOR;
@ -104,8 +104,6 @@ void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LL
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
// Flip vertical, used for LLFloaterHTML
void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom);
void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f );
@ -203,7 +201,6 @@ public:
static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
static void screenRectToGL(const LLRect& screen, LLRect *gl);
static void glRectToScreen(const LLRect& gl, LLRect *screen);
static void setHtmlHelp(LLHtmlHelp* html_help);
// Returns the control group containing the control name, or the default group
static LLControlGroup& getControlControlGroup (const std::string& controlname);
static F32 getMouseIdleTime() { return sMouseIdleTimer.getElapsedTimeF32(); }
@ -223,8 +220,8 @@ public:
static LLUIAudioCallback sAudioCallback;
static LLVector2 sGLScaleFactor;
static LLWindow* sWindow;
static LLHtmlHelp* sHtmlHelp;
static LLView* sRootView;
static LLHelp* sHelpImpl;
private:
static LLImageProviderInterface* sImageProvider;
static std::vector<std::string> sXUIPaths;

View File

@ -114,7 +114,6 @@ void LLUICtrl::initFromParams(const Params& p)
}
setTabStop(p.tab_stop);
setFocusLostCallback(p.focus_lost_callback());
if (p.initial_value.isProvided()
&& !p.control_name.isProvided())
@ -763,6 +762,27 @@ LLUICtrl* LLUICtrl::getParentUICtrl() const
return NULL;
}
bool LLUICtrl::findHelpTopic(std::string& help_topic_out)
{
LLUICtrl* ctrl = this;
// search back through the control's parents for a panel
// with a help_topic string defined
while (ctrl)
{
LLPanel *panel = dynamic_cast<LLPanel *>(ctrl);
if (panel && !panel->getHelpTopic().empty())
{
help_topic_out = panel->getHelpTopic();
return true; // success
}
ctrl = ctrl->getParentUICtrl();
}
return false; // no help topic found
}
// *TODO: Deprecate; for backwards compatability only:
boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (LLUICtrl*,void*)> cb, void* data)
{
@ -800,14 +820,7 @@ namespace LLInitParam
return false;
}
template<>
bool ParamCompare<LLUICtrl::focus_callback_t>::equals(
const LLUICtrl::focus_callback_t &a,
const LLUICtrl::focus_callback_t &b)
{
return false;
}
template<>
bool ParamCompare<LLUICtrl::enable_callback_t>::equals(
const LLUICtrl::enable_callback_t &a,

View File

@ -124,8 +124,6 @@ public:
Optional<CommitCallbackParam> mouseenter_callback;
Optional<CommitCallbackParam> mouseleave_callback;
Optional<focus_callback_t> focus_lost_callback;
Optional<std::string> control_name;
Optional<EnableControls> enabled_controls;
Optional<ControlVisibility> controls_visibility;
@ -225,6 +223,10 @@ public:
LLUICtrl* getParentUICtrl() const;
// return true if help topic found by crawling through parents -
// topic then put in help_topic_out
bool findHelpTopic(std::string& help_topic_out);
boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ) { return mCommitSignal.connect(cb); }
boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb ) { return mValidateSignal.connect(cb); }
@ -309,11 +311,6 @@ namespace LLInitParam
const LLUICtrl::enable_callback_t &a,
const LLUICtrl::enable_callback_t &b);
template<>
bool ParamCompare<LLUICtrl::focus_callback_t>::equals(
const LLUICtrl::focus_callback_t &a,
const LLUICtrl::focus_callback_t &b);
template<>
bool ParamCompare<LLLazyValue<LLColor4> >::equals(
const LLLazyValue<LLColor4> &a, const LLLazyValue<LLColor4> &b);

View File

@ -134,4 +134,3 @@ void LLUrlAction::copyLabelToClipboard(std::string url)
LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(match.getLabel()));
}
}

View File

@ -466,16 +466,6 @@ LLRect LLView::getRequiredRect()
return mRect;
}
//virtual
void LLView::onFocusLost()
{
}
//virtual
void LLView::onFocusReceived()
{
}
BOOL LLView::focusNextRoot()
{
LLView::child_list_t result = LLView::getFocusRootsQuery().run(this);

View File

@ -405,10 +405,6 @@ public:
BOOL getSaveToXML() const { return mSaveToXML; }
void setSaveToXML(BOOL b) { mSaveToXML = b; }
// inherited from LLFocusableElement
/* virtual */ void onFocusLost();
/* virtual */ void onFocusReceived();
typedef enum e_hit_test_type
{
HIT_TEST_USE_BOUNDING_RECT,

View File

@ -383,7 +383,7 @@ BOOL LLDir_Linux::fileExists(const std::string &filename) const
/*virtual*/ std::string LLDir_Linux::getLLPluginLauncher()
{
return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() +
"SLPlugin";
}

View File

@ -424,7 +424,7 @@ BOOL LLDir_Mac::fileExists(const std::string &filename) const
/*virtual*/ std::string LLDir_Mac::getLLPluginLauncher()
{
return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
return gDirUtilp->getAppRODataDir() + gDirUtilp->getDirDelimiter() +
"SLPlugin";
}

View File

@ -397,7 +397,7 @@ BOOL LLDir_Win32::fileExists(const std::string &filename) const
/*virtual*/ std::string LLDir_Win32::getLLPluginLauncher()
{
return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() +
"SLPlugin.exe";
}

View File

@ -5,6 +5,7 @@ include(LLCommon)
include(LLMath)
include(LLMessage)
include(LLInventory)
include(LLPrimitive)
include(LScript)
include(FindCygwin)
@ -41,6 +42,7 @@ include_directories(
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLINVENTORY_INCLUDE_DIRS}
${LLPRIMITIVE_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}
)

View File

@ -34,6 +34,7 @@ FS (f|F)
#include "llregionflags.h"
#include "lscript_http.h"
#include "llclickaction.h"
#include "llmediaentry.h"
void count();
void line_comment();
@ -233,7 +234,8 @@ extern "C" { int yyerror(const char *fmt, ...); }
"CHANGED_OWNER" { count(); yylval.ival = CHANGED_OWNER; return(INTEGER_CONSTANT); }
"CHANGED_REGION" { count(); yylval.ival = CHANGED_REGION; return(INTEGER_CONSTANT); }
"CHANGED_TELEPORT" { count(); yylval.ival = CHANGED_TELEPORT; return(INTEGER_CONSTANT); }
"CHANGED_REGION_START" { count(); yylval.ival = CHANGED_REGION_START; return(INTEGER_CONSTANT); }
"CHANGED_REGION_START" { count(); yylval.ival = CHANGED_REGION_START; return(INTEGER_CONSTANT); }
"CHANGED_MEDIA" { count(); yylval.ival = CHANGED_MEDIA; return(INTEGER_CONSTANT); }
"OBJECT_UNKNOWN_DETAIL" { count(); yylval.ival = OBJECT_UNKNOWN_DETAIL; return(INTEGER_CONSTANT); }
"OBJECT_NAME" { count(); yylval.ival = OBJECT_NAME; return(INTEGER_CONSTANT); }
@ -622,6 +624,45 @@ extern "C" { int yyerror(const char *fmt, ...); }
"TOUCH_INVALID_VECTOR" { count(); return(TOUCH_INVALID_VECTOR); }
"TOUCH_INVALID_TEXCOORD" { count(); return(TOUCH_INVALID_TEXCOORD); }
"PRIM_MEDIA_ALT_IMAGE_ENABLE" { count(); yylval.ival = LLMediaEntry::ALT_IMAGE_ENABLE_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_CONTROLS" { count(); yylval.ival = LLMediaEntry::CONTROLS_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_CURRENT_URL" { count(); yylval.ival = LLMediaEntry::CURRENT_URL_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_HOME_URL" { count(); yylval.ival = LLMediaEntry::HOME_URL_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_AUTO_LOOP" { count(); yylval.ival = LLMediaEntry::AUTO_LOOP_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_AUTO_PLAY" { count(); yylval.ival = LLMediaEntry::AUTO_PLAY_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_AUTO_SCALE" { count(); yylval.ival = LLMediaEntry::AUTO_SCALE_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_AUTO_ZOOM" { count(); yylval.ival = LLMediaEntry::AUTO_ZOOM_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_FIRST_CLICK_INTERACT" { count(); yylval.ival = LLMediaEntry::FIRST_CLICK_INTERACT_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_WIDTH_PIXELS" { count(); yylval.ival = LLMediaEntry::WIDTH_PIXELS_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_HEIGHT_PIXELS" { count(); yylval.ival = LLMediaEntry::HEIGHT_PIXELS_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_WHITELIST_ENABLE" { count(); yylval.ival = LLMediaEntry::WHITELIST_ENABLE_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_WHITELIST" { count(); yylval.ival = LLMediaEntry::WHITELIST_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_PERMS_INTERACT" { count(); yylval.ival = LLMediaEntry::PERMS_INTERACT_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_PERMS_CONTROL" { count(); yylval.ival = LLMediaEntry::PERMS_CONTROL_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_PARAM_MAX" { count(); yylval.ival = LLMediaEntry::PARAM_MAX_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_CONTROLS_STANDARD" { count(); yylval.ival = LLMediaEntry::STANDARD; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_CONTROLS_MINI" { count(); yylval.ival = LLMediaEntry::MINI; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_PERM_NONE" { count(); yylval.ival = LLMediaEntry::PERM_NONE; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_PERM_OWNER" { count(); yylval.ival = LLMediaEntry::PERM_OWNER; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_PERM_GROUP" { count(); yylval.ival = LLMediaEntry::PERM_GROUP; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_PERM_ANYONE" { count(); yylval.ival = LLMediaEntry::PERM_ANYONE; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_MAX_URL_LENGTH" { count(); yylval.ival = LLMediaEntry::MAX_URL_LENGTH; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_MAX_WHITELIST_SIZE" { count(); yylval.ival = LLMediaEntry::MAX_WHITELIST_SIZE; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_MAX_WHITELIST_COUNT" { count(); yylval.ival = LLMediaEntry::MAX_WHITELIST_COUNT; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_MAX_WIDTH_PIXELS" { count(); yylval.ival = LLMediaEntry::MAX_WIDTH_PIXELS; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_MAX_HEIGHT_PIXELS" { count(); yylval.ival = LLMediaEntry::MAX_HEIGHT_PIXELS; return(INTEGER_CONSTANT); }
"STATUS_OK" { count(); yylval.ival = LSL_STATUS_OK; return(INTEGER_CONSTANT); }
"STATUS_MALFORMED_PARAMS" { count(); yylval.ival = LSL_STATUS_MALFORMED_PARAMS; return(INTEGER_CONSTANT); }
"STATUS_TYPE_MISMATCH" { count(); yylval.ival = LSL_STATUS_TYPE_MISMATCH; return(INTEGER_CONSTANT); }
"STATUS_BOUNDS_ERROR" { count(); yylval.ival = LSL_STATUS_BOUNDS_ERROR; return(INTEGER_CONSTANT); }
"STATUS_NOT_FOUND" { count(); yylval.ival = LSL_STATUS_NOT_FOUND; return(INTEGER_CONSTANT); }
"STATUS_NOT_SUPPORTED" { count(); yylval.ival = LSL_STATUS_NOT_SUPPORTED; return(INTEGER_CONSTANT); }
"STATUS_INTERNAL_ERROR" { count(); yylval.ival = LSL_STATUS_INTERNAL_ERROR; return(INTEGER_CONSTANT); }
"STATUS_WHITELIST_FAILED" { count(); yylval.ival = LSL_STATUS_WHITELIST_FAILED; return(INTEGER_CONSTANT); }
{L}({L}|{N})* { count(); yylval.sval = new char[strlen(yytext) + 1]; strcpy(yylval.sval, yytext); return(IDENTIFIER); }

View File

@ -450,7 +450,12 @@ void LLScriptLibrary::init()
addFunction(10.f, 0.f, dummy_func, "llHTTPResponse", NULL, "kis");
addFunction(10.f, 0.f, dummy_func, "llGetHTTPHeader", "s", "ks");
// energy, sleep, dummy_func, name, return type, parameters, gods-only
// Prim media (see lscript_prim_media.h)
addFunction(10.f, 1.0f, dummy_func, "llSetPrimMediaParams", "i", "il");
addFunction(10.f, 1.0f, dummy_func, "llGetPrimMediaParams", "l", "il");
addFunction(10.f, 1.0f, dummy_func, "llClearPrimMedia", "i", "i");
// energy, sleep, dummy_func, name, return type, parameters, help text, gods-only
// IF YOU ADD NEW SCRIPT CALLS, YOU MUST PUT THEM AT THE END OF THIS LIST.
// Otherwise the bytecode numbers for each call will be wrong, and all
@ -495,7 +500,7 @@ void LLScriptLibData::print(std::ostream &s, BOOL b_prepend_comma)
s << ", ";
}
switch (mType)
{
{
case LST_INTEGER:
s << mInteger;
break;

View File

@ -975,10 +975,7 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string)
else if(message_name == "shm_added")
{
SharedSegmentInfo info;
U64 address_lo = message_in.getValueU32("address");
U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0;
info.mAddress = (void*)((address_lo) |
(address_hi * (U64(1)<<31)));
info.mAddress = message_in.getValuePointer("address");
info.mSize = (size_t)message_in.getValueS32("size");
std::string name = message_in.getValue("name");

View File

@ -772,10 +772,7 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string)
else if(message_name == "shm_added")
{
SharedSegmentInfo info;
U64 address_lo = message_in.getValueU32("address");
U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0;
info.mAddress = (void*)((address_lo) |
(address_hi * (U64(1)<<31)));
info.mAddress = message_in.getValuePointer("address");
info.mSize = (size_t)message_in.getValueS32("size");
std::string name = message_in.getValue("name");

View File

@ -147,8 +147,11 @@ private:
#if LL_WINDOWS
// Enable plugins
LLQtWebKit::getInstance()->enablePlugins(true);
#else
LLQtWebKit::getInstance()->enablePlugins(false);
#elif LL_DARWIN
// Disable plugins
LLQtWebKit::getInstance()->enablePlugins(false);
#elif LL_LINUX
// Disable plugins
LLQtWebKit::getInstance()->enablePlugins(false);
#endif
@ -164,6 +167,11 @@ private:
// don't flip bitmap
LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true );
// Set the background color to black
LLQtWebKit::getInstance()->
// set background color to be black - mostly for initial login page
LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, 0x00, 0x00, 0x00 );
// go to the "home page"
// Don't do this here -- it causes the dreaded "white flash" when loading a browser instance.
@ -483,8 +491,8 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
mDepth = 4;
message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
message.setValueS32("default_width", 800);
message.setValueS32("default_height", 600);
message.setValueS32("default_width", 1024);
message.setValueS32("default_height", 1024);
message.setValueS32("depth", mDepth);
message.setValueU32("internalformat", GL_RGBA);
message.setValueU32("format", GL_RGBA);
@ -507,10 +515,7 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
else if(message_name == "shm_added")
{
SharedSegmentInfo info;
U64 address_lo = message_in.getValueU32("address");
U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0;
info.mAddress = (void*)((address_lo) |
(address_hi * (U64(1)<<31)));
info.mAddress = message_in.getValuePointer("address");
info.mSize = (size_t)message_in.getValueS32("size");
std::string name = message_in.getValue("name");

View File

@ -169,9 +169,9 @@ set(viewer_SOURCE_FILES
llfloatergroups.cpp
llfloaterhandler.cpp
llfloaterhardwaresettings.cpp
llfloaterhtmlcurrency.cpp
llfloaterhelpbrowser.cpp
llfloatermediabrowser.cpp
llfloaterhtmlsimple.cpp
llfloatermediasettings.cpp
llfloaterhud.cpp
llfloaterimagepreview.cpp
llfloaterinspect.cpp
@ -208,6 +208,7 @@ set(viewer_SOURCE_FILES
llfloaterurlentry.cpp
llfloatervoicedevicesettings.cpp
llfloaterwater.cpp
llfloaterwhitelistentry.cpp
llfloaterwindlight.cpp
llfloaterworldmap.cpp
llfoldertype.cpp
@ -260,6 +261,9 @@ set(viewer_SOURCE_FILES
llmanipscale.cpp
llmaniptranslate.cpp
llmapresponders.cpp
llmediactrl.cpp
llmediadataresponder.cpp
llmediadatafetcher.cpp
llmediaremotectrl.cpp
llmemoryview.cpp
llmenucommands.cpp
@ -321,6 +325,9 @@ set(viewer_SOURCE_FILES
llpanelmediahud.cpp
llpanelmeprofile.cpp
llpanelmovetip.cpp
llpanelmediasettingsgeneral.cpp
llpanelmediasettingssecurity.cpp
llpanelmediasettingspermissions.cpp
llpanelobject.cpp
llpanelpeople.cpp
llpanelpeoplemenus.cpp
@ -426,6 +433,8 @@ set(viewer_SOURCE_FILES
llviewerfloaterreg.cpp
llviewergenericmessage.cpp
llviewergesture.cpp
llviewerhelp.cpp
llviewerhelputil.cpp
llviewerinventory.cpp
llviewerjointattachment.cpp
llviewerjoint.cpp
@ -490,7 +499,6 @@ set(viewer_SOURCE_FILES
llwearabledictionary.cpp
llwearablelist.cpp
llweb.cpp
llmediactrl.cpp
llwind.cpp
llwlanimator.cpp
llwldaycycle.cpp
@ -632,9 +640,9 @@ set(viewer_HEADER_FILES
llfloatergroups.h
llfloaterhandler.h
llfloaterhardwaresettings.h
llfloaterhtmlcurrency.h
llfloaterhelpbrowser.h
llfloatermediabrowser.h
llfloaterhtmlsimple.h
llfloatermediasettings.h
llfloaterhud.h
llfloaterimagepreview.h
llfloaterinspect.h
@ -671,6 +679,7 @@ set(viewer_HEADER_FILES
llfloaterurlentry.h
llfloatervoicedevicesettings.h
llfloaterwater.h
llfloaterwhitelistentry.h
llfloaterwindlight.h
llfloaterworldmap.h
llfoldertype.h
@ -723,6 +732,8 @@ set(viewer_HEADER_FILES
llmanipscale.h
llmaniptranslate.h
llmapresponders.h
llmediadataresponder.h
llmediadatafetcher.h
llmediaremotectrl.h
llmemoryview.h
llmenucommands.h
@ -781,6 +792,9 @@ set(viewer_HEADER_FILES
llpanelmediahud.h
llpanelmeprofile.h
llpanelmovetip.h
llpanelmediasettingsgeneral.h
llpanelmediasettingssecurity.h
llpanelmediasettingspermissions.h
llpanelobject.h
llpanelpeople.h
llpanelpeoplemenus.h
@ -891,6 +905,7 @@ set(viewer_HEADER_FILES
llviewerfloaterreg.h
llviewergenericmessage.h
llviewergesture.h
llviewerhelp.h
llviewerinventory.h
llviewerjoint.h
llviewerjointattachment.h
@ -1526,6 +1541,7 @@ endif (INSTALL)
include(LLAddBuildTest)
SET(viewer_TEST_SOURCE_FILES
llagentaccess.cpp
llviewerhelputil.cpp
)
set_source_files_properties(
${viewer_TEST_SOURCE_FILES}
@ -1565,7 +1581,7 @@ if (WINDOWS)
-E
copy_if_different
${BUILT_SLPLUGIN}
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
COMMENT "Copying SLPlugin executable to the runtime folder."
)

View File

@ -40,14 +40,14 @@ not_at_rot_target not_at_rot_target():Result of LLRotTarget library function cal
money money(key id, integer amount):Triggered when L$ is given to task
email email(string time, string address, string subj, string message, integer num_left):Triggered when task receives email
run_time_permissions run_time_permissions(integer perm):Triggered when an agent grants run time permissions to task
attach attach(key id):Triggered when an agent attaches or detaches from agent
attach attach(key id):Triggered when task attaches or detaches from agent
dataserver dataserver(key queryid, string data):Triggered when task receives asynchronous data
moving_start moving_start():Triggered when task begins moving
moving_end moving_end():Triggered when task stops moving
on_rez on_rez(integer start_param):Triggered when task is rezed in from inventory or another task
object_rez object_rez(key id):Triggered when task rezes in another task
link_message link_message(integer sender_num, integer num, string str, key id):Triggered when task receives a link message via LLMessageLinked library function call
changed changed( integer change ):Triggered various event change the task:(test change with CHANGED_INVENTORY, CHANGED_COLOR, CHANGED_SHAPE, CHANGED_SCALE, CHANGED_TEXTURE, CHANGED_LINK, CHANGED_ALLOWED_DROP, CHANGED_OWNER, CHANGED_REGION, CHANGED_TELEPORT)
changed changed( integer change ):Triggered various event change the task:(test change with CHANGED_INVENTORY, CHANGED_COLOR, CHANGED_SHAPE, CHANGED_SCALE, CHANGED_TEXTURE, CHANGED_LINK, CHANGED_ALLOWED_DROP, CHANGED_OWNER, CHANGED_REGION, CHANGED_TELEPORT, CHANGED_REGION_START, CHANGED_MEDIA)
remote_data remote_data(integer event_type, key channel, key message_id, string sender,integer idata, string sdata):Triggered by various XML-RPC calls (event_type will be one of REMOTE_DATA_CHANNEL, REMOTE_DATA_REQUEST, REMOTE_DATA_REPLY)
http_response http_response(key request_id, integer status, list metadata, string body):Triggered when task receives a response to one of its llHTTPRequests
http_request http_request(key id, string method, string body):Triggered when task receives an http request against a public URL
@ -320,6 +320,7 @@ CHANGED_OWNER Parameter of changed event handler used to indicate change to tas
CHANGED_REGION Parameter of changed event handler used to indicate the region has changed
CHANGED_TELEPORT Parameter of changed event handler used to indicate teleport has completed
CHANGED_REGION_START Parameter of changed event handler used to indicate the region has been restarted
CHANGED_MEDIA Parameter of changed event handler used to indicate that media has changed on a face of the task
TYPE_INTEGER Indicates that the list entry is holding an integer
TYPE_FLOAT Indicates that the list entry is holding an float
@ -513,6 +514,46 @@ TOUCH_INVALID_TEXCOORD Value returned by llDetectedTouchUV() and llDetectedTouc
TOUCH_INVALID_VECTOR Value returned by llDetectedTouchPos(), llDetectedTouchNormal(), and llDetectedTouchBinormal() when the touch position is not valid.
TOUCH_INVALID_FACE Value returned by llDetectedTouchFace() when the touch position is not valid.
PRIM_MEDIA_ALT_IMAGE_ENABLE Used with ll{Get,Set}PrimMediaParams to enable the default alt image for media
PRIM_MEDIA_CONTROLS Used with ll{Get,Set}PrimMediaParams to determine the controls shown for media
PRIM_MEDIA_CURRENT_URL Used with ll{Get,Set}PrimMediaParams to navigate/access the current URL
PRIM_MEDIA_HOME_URL Used with ll{Get,Set}PrimMediaParams to access the home URL
PRIM_MEDIA_AUTO_LOOP Used with ll{Get,Set}PrimMediaParams to determine if media should auto-loop (if applicable)
PRIM_MEDIA_AUTO_PLAY Used with ll{Get,Set}PrimMediaParams to determine if media should start playing as soon as it is created
PRIM_MEDIA_AUTO_SCALE Used with ll{Get,Set}PrimMediaParams to determine if media should scale to fit the face it is on
PRIM_MEDIA_AUTO_ZOOM Used with ll{Get,Set}PrimMediaParams to determine if the user would zoom in when viewing media
PRIM_MEDIA_FIRST_CLICK_INTERACT Used with ll{Get,Set}PrimMediaParams to determine whether the user interacts with media or not when she first clicks it (versus selection)
PRIM_MEDIA_WIDTH_PIXELS Used with ll{Get,Set}PrimMediaParams to access the media's width in pixels
PRIM_MEDIA_HEIGHT_PIXELS Used with ll{Get,Set}PrimMediaParams to access the media's height in pixels
PRIM_MEDIA_WHITELIST_ENABLE Used with ll{Get,Set}PrimMediaParams to determine if the domain whitelist is enabled
PRIM_MEDIA_WHITELIST Used with ll{Get,Set}PrimMediaParams to access the media's list of allowable URL prefixes to navigate to
PRIM_MEDIA_PERMS_INTERACT Used with ll{Get,Set}PrimMediaParams to determine the permissions for who can interact with the media
PRIM_MEDIA_PERMS_CONTROL Used with ll{Get,Set}PrimMediaParams to determine the permissions for who has controls
PRIM_MEDIA_PARAM_MAX The value of the largest media param
PRIM_MEDIA_CONTROLS_STANDARD Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_CONTROLS value meaning "standard controls"
PRIM_MEDIA_CONTROLS_MINI Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_CONTROLS value meaning "mini controls"
PRIM_MEDIA_PERM_NONE Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, no permissions
PRIM_MEDIA_PERM_OWNER Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, owner permissions
PRIM_MEDIA_PERM_GROUP Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, group permissions
PRIM_MEDIA_PERM_ANYONE Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, anyone has permissions
PRIM_MEDIA_MAX_URL_LENGTH Used with ll{Get,Set}PrimMediaParams, the maximum length of PRIM_MEDIA_CURRENT_URL or PRIM_MEDIA_HOME_URL
PRIM_MEDIA_MAX_WHITELIST_SIZE Used with ll{Get,Set}PrimMediaParams, the maximum length, in bytes, of PRIM_MEDIA_WHITELIST
PRIM_MEDIA_MAX_WHITELIST_COUNT Used with ll{Get,Set}PrimMediaParams, the maximum number of items allowed in PRIM_MEDIA_WHITELIST
PRIM_MEDIA_MAX_WIDTH_PIXELS Used with ll{Get,Set}PrimMediaParams, the maximum width allowed in PRIM_MEDIA_WIDTH_PIXELS
PRIM_MEDIA_MAX_HEIGHT_PIXELS Used with ll{Get,Set}PrimMediaParams, the maximum width allowed in PRIM_MEDIA_HEIGHT_PIXELS
STATUS_OK Result of function call was success
STATUS_MALFORMED_PARAMS Function was called with malformed params
STATUS_TYPE_MISMATCH Argument(s) passed to function had a type mismatch
STATUS_BOUNDS_ERROR Argument(s) passed to function had a bounds error
STATUS_NOT_FOUND Object or other item was not found
STATUS_NOT_SUPPORTED Feature not supported
STATUS_INTERNAL_ERROR An internal error occurred
STATUS_WHITELIST_FAILED URL failed to pass whitelist
# string constants
[word .1, .3, .5]
NULL_KEY Indicates an empty key

View File

@ -3542,28 +3542,28 @@
<string>S32</string>
<key>Value</key>
<integer>400</integer>
</map>
<key>HelpHomeURL</key>
<map>
<key>Comment</key>
<string>URL of initial help page</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>help/index.html</string>
</map>
<key>HelpLastVisitedURL</key>
<key>HelpUseLocal</key>
<map>
<key>Comment</key>
<string>URL of last help page, will be shown next time help is accessed</string>
<string>If set, always use this for help: skins/default/html/[LANGUAGE]/help-offline/index.html</string>
<key>Persist</key>
<integer>1</integer>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>HelpURLFormat</key>
<map>
<key>Comment</key>
<string>URL pattern for help page; arguments will be encoded; see llviewerhelp.cpp:buildHelpURL for arguments</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>help/index.html</string>
<string>http://www.google.com/search?q=site%3Awiki.secondlife.com+[TOPIC]&amp;ignore_channel=[CHANNEL]&amp;ignore_version=[VERSION]&amp;ignore_os=[OS]&amp;ignore_language=[LANGUAGE]&amp;ignore_version_major=[VERSION_MAJOR]&amp;ignore_version_minor=[VERSION_MINOR]&amp;ignore_version_patch=[VERSION_PATCH]&amp;ignore_version_build=[VERSION_BUILD]</string>
</map>
<key>HighResSnapshot</key>
<map>
@ -3994,6 +3994,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>LastMediaSettingsTab</key>
<map>
<key>Comment</key>
<string>Last selected tab in media settings window</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>LastRunVersion</key>
<map>
<key>Comment</key>
@ -4455,7 +4466,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
<integer>1</integer>
</map>
<key>MemoryLogFrequency</key>
<map>
@ -5216,6 +5227,51 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>PluginInstancesCPULimit</key>
<map>
<key>Comment</key>
<string>Amount of total plugin CPU usage before inworld plugins start getting turned down to "slideshow" priority. Set to 0 to disable this check.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.0</real>
</map>
<key>PluginInstancesLow</key>
<map>
<key>Comment</key>
<string>Limit on the number of inworld media plugins that will run at "low" priority</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>4</integer>
</map>
<key>PluginInstancesNormal</key>
<map>
<key>Comment</key>
<string>Limit on the number of inworld media plugins that will run at "normal" priority</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>4</integer>
</map>
<key>PluginInstancesTotal</key>
<map>
<key>Comment</key>
<string>Hard limit on the number of plugins that will be instantiated at once</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>16</integer>
</map>
<key>PrecachingDelay</key>
<map>
<key>Comment</key>
@ -5238,6 +5294,28 @@
<key>Value</key>
<integer>13</integer>
</map>
<key>PrimMediaFetchQueueDelay</key>
<map>
<key>Comment</key>
<string>Timer delay for fetching media from the queue (in seconds).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>1.0</real>
</map>
<key>PrimMediaRetryTimerDelay</key>
<map>
<key>Comment</key>
<string>Timer delay for retrying on media queries (in seconds).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>5.0</real>
</map>
<key>ProbeHardwareOnStartup</key>
<map>
<key>Comment</key>

View File

@ -67,6 +67,7 @@
#include "llviewerobjectlist.h"
#include "llworldmap.h"
#include "llmutelist.h"
#include "llviewerhelp.h"
#include "lluicolortable.h"
#include "llurldispatcher.h"
#include "llurlhistory.h"
@ -663,8 +664,6 @@ bool LLAppViewer::init()
mNumSessions++;
gSavedSettings.setS32("NumSessions", mNumSessions);
gSavedSettings.setString("HelpLastVisitedURL",gSavedSettings.getString("HelpHomeURL"));
if (gSavedSettings.getBOOL("VerboseLogs"))
{
LLError::setPrintLocation(true);
@ -694,6 +693,9 @@ bool LLAppViewer::init()
LLUrlAction::setOpenURLExternalCallback(&LLWeb::loadURLExternal);
LLUrlAction::setExecuteSLURLCallback(&LLURLDispatcher::dispatchFromTextEditor);
// Let code in llui access the viewer help floater
LLUI::sHelpImpl = LLViewerHelp::getInstance();
// Set the link color for any Urls in text fields
LLTextBase::setLinkColor( LLUIColorTable::instance().getColor("HTMLLinkColor") );

View File

@ -41,6 +41,10 @@
static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
// Maximum number of avatars that can be added to a list in one pass.
// Used to limit time spent for avatar list update per frame.
static const unsigned ADD_LIMIT = 50;
static bool findInsensitive(std::string haystack, const std::string& needle_upper)
{
LLStringUtil::toUpper(haystack);
@ -65,6 +69,7 @@ LLAvatarList::LLAvatarList(const Params& p)
: LLFlatListView(p)
, mOnlineGoFirst(p.online_go_first)
, mContextMenu(NULL)
, mDirty(true) // to force initial update
{
setCommitOnSelectionChange(true);
@ -72,6 +77,138 @@ LLAvatarList::LLAvatarList(const Params& p)
setComparator(&NAME_COMPARATOR);
}
// virtual
void LLAvatarList::draw()
{
if (mDirty)
refresh();
LLFlatListView::draw();
}
void LLAvatarList::setNameFilter(const std::string& filter)
{
if (mNameFilter != filter)
{
mNameFilter = filter;
setDirty();
}
}
void LLAvatarList::sortByName()
{
setComparator(&NAME_COMPARATOR);
sort();
}
//////////////////////////////////////////////////////////////////////////
// PROTECTED SECTION
//////////////////////////////////////////////////////////////////////////
void LLAvatarList::refresh()
{
bool have_names = TRUE;
bool add_limit_exceeded = false;
bool modified = false;
bool have_filter = !mNameFilter.empty();
// Save selection.
std::vector<LLUUID> selected_ids;
getSelectedUUIDs(selected_ids);
LLUUID current_id = getSelectedUUID();
// Determine what to add and what to remove.
std::vector<LLUUID> added, removed;
LLAvatarList::computeDifference(getIDs(), added, removed);
// Handle added items.
unsigned nadded = 0;
for (std::vector<LLUUID>::const_iterator it=added.begin(); it != added.end(); it++)
{
std::string name;
const LLUUID& buddy_id = *it;
have_names &= (bool)gCacheName->getFullName(buddy_id, name);
if (!have_filter || findInsensitive(name, mNameFilter))
{
if (nadded >= ADD_LIMIT)
{
add_limit_exceeded = true;
break;
}
else
{
addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
modified = true;
nadded++;
}
}
}
// Handle removed items.
for (std::vector<LLUUID>::const_iterator it=removed.begin(); it != removed.end(); it++)
{
removeItemByUUID(*it);
modified = true;
}
// Handle filter.
if (have_filter)
{
std::vector<LLSD> cur_values;
getValues(cur_values);
for (std::vector<LLSD>::const_iterator it=cur_values.begin(); it != cur_values.end(); it++)
{
std::string name;
const LLUUID& buddy_id = it->asUUID();
have_names &= (bool)gCacheName->getFullName(buddy_id, name);
if (!findInsensitive(name, mNameFilter))
{
removeItemByUUID(buddy_id);
modified = true;
}
}
}
// Changed item in place, need to request sort and update columns
// because we might have changed data in a column on which the user
// has already sorted. JC
sort();
// re-select items
// selectMultiple(selected_ids); // TODO: implement in LLFlatListView if need
selectItemByUUID(current_id);
// If the name filter is specified and the names are incomplete,
// we need to re-update when the names are complete so that
// the filter can be applied correctly.
//
// Otherwise, if we have no filter then no need to update again
// because the items will update their names.
bool dirty = add_limit_exceeded || (have_filter && !have_names);
setDirty(dirty);
// Commit if we've added/removed items.
if (modified)
onCommit();
}
void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
{
LLAvatarListItem* item = new LLAvatarListItem();
item->showStatus(false);
item->showInfoBtn(true);
item->showSpeakingIndicator(true);
item->setName(name);
item->setAvatarId(id);
item->setContextMenu(mContextMenu);
item->childSetVisible("info_btn", false);
addItem(item, id, pos);
}
void LLAvatarList::computeDifference(
const std::vector<LLUUID>& vnew_unsorted,
std::vector<LLUUID>& vadded,
@ -106,97 +243,6 @@ void LLAvatarList::computeDifference(
vadded.erase(it, vadded.end());
}
BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter)
{
BOOL have_names = TRUE;
bool have_filter = name_filter != LLStringUtil::null;
// Save selection.
std::vector<LLUUID> selected_ids;
getSelectedUUIDs(selected_ids);
LLUUID current_id = getSelectedUUID();
// Determine what to add and what to remove.
std::vector<LLUUID> added, removed;
LLAvatarList::computeDifference(all_buddies, added, removed);
// Handle added items.
for (std::vector<LLUUID>::const_iterator it=added.begin(); it != added.end(); it++)
{
std::string name;
const LLUUID& buddy_id = *it;
have_names &= gCacheName->getFullName(buddy_id, name);
if (!have_filter || findInsensitive(name, name_filter))
addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
}
// Handle removed items.
for (std::vector<LLUUID>::const_iterator it=removed.begin(); it != removed.end(); it++)
{
removeItemByUUID(*it);
}
// Handle filter.
if (have_filter)
{
std::vector<LLSD> cur_values;
getValues(cur_values);
for (std::vector<LLSD>::const_iterator it=cur_values.begin(); it != cur_values.end(); it++)
{
std::string name;
const LLUUID& buddy_id = it->asUUID();
have_names &= gCacheName->getFullName(buddy_id, name);
if (!findInsensitive(name, name_filter))
removeItemByUUID(buddy_id);
}
}
// Changed item in place, need to request sort and update columns
// because we might have changed data in a column on which the user
// has already sorted. JC
sort();
// re-select items
// selectMultiple(selected_ids); // TODO: implement in LLFlatListView if need
selectItemByUUID(current_id);
// If the name filter is specified and the names are incomplete,
// we need to re-update when the names are complete so that
// the filter can be applied correctly.
//
// Otherwise, if we have no filter then no need to update again
// because the items will update their names.
return !have_filter || have_names;
}
void LLAvatarList::sortByName()
{
setComparator(&NAME_COMPARATOR);
sort();
}
//////////////////////////////////////////////////////////////////////////
// PROTECTED SECTION
//////////////////////////////////////////////////////////////////////////
void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
{
LLAvatarListItem* item = new LLAvatarListItem();
item->showStatus(false);
item->showInfoBtn(true);
item->showSpeakingIndicator(true);
item->setName(name);
item->setAvatarId(id);
item->setContextMenu(mContextMenu);
item->childSetVisible("info_btn", false);
addItem(item, id, pos);
}
bool LLAvatarItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
{
const LLAvatarListItem* avatar_item1 = dynamic_cast<const LLAvatarListItem*>(item1);

View File

@ -37,10 +37,22 @@
#include "llavatarlistitem.h"
/**
* Generic list of avatars.
*
* Updates itself when it's dirty, using optional name filter.
* To initiate update, modify the UUID list and call setDirty().
*
* @see getIDs()
* @see setDirty()
* @see setNameFilter()
*/
class LLAvatarList : public LLFlatListView
{
LOG_CLASS(LLAvatarList);
public:
typedef std::vector<LLUUID> uuid_vector_t;
struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
{
Optional<S32> volume_column_width;
@ -51,14 +63,19 @@ public:
LLAvatarList(const Params&);
virtual ~LLAvatarList() {}
BOOL update(const std::vector<LLUUID>& all_buddies,
const std::string& name_filter = LLStringUtil::null);
virtual void draw(); // from LLView
void setNameFilter(const std::string& filter);
void setDirty(bool val = true) { mDirty = val; }
uuid_vector_t& getIDs() { return mIDs; }
void setContextMenu(LLAvatarListItem::ContextMenu* menu) { mContextMenu = menu; }
void sortByName();
protected:
void refresh();
void addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
void computeDifference(
const std::vector<LLUUID>& vnew,
@ -68,6 +85,10 @@ protected:
private:
bool mOnlineGoFirst;
bool mDirty;
std::string mNameFilter;
uuid_vector_t mIDs;
LLAvatarListItem::ContextMenu* mContextMenu;
};

View File

@ -133,6 +133,7 @@ LLIMChiclet* LLBottomTray::createIMChiclet(const LLUUID& session_id)
case LLIMChiclet::TYPE_IM:
return getChicletPanel()->createChiclet<LLIMP2PChiclet>(session_id);
case LLIMChiclet::TYPE_GROUP:
case LLIMChiclet::TYPE_AD_HOC:
return getChicletPanel()->createChiclet<LLIMGroupChiclet>(session_id);
case LLIMChiclet::TYPE_UNKNOWN:
break;
@ -231,7 +232,7 @@ void LLBottomTray::showBottomTrayContextMenu(S32 x, S32 y, MASK mask)
mBottomTrayContextMenu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, mBottomTrayContextMenu, x, y);
}
}
}
void LLBottomTray::showGestureButton(BOOL visible)
@ -243,7 +244,7 @@ void LLBottomTray::showGestureButton(BOOL visible)
mGestureCombo->setVisible(visible);
if (!visible)
{
{
LLFloaterReg::hideFloaterInstance("gestures");
r.mRight -= mGestureCombo->getRect().getWidth();
}

View File

@ -77,7 +77,7 @@ LLScreenChannel* LLChannelManager::createNotificationChannel()
p.channel_align = CA_RIGHT;
// Getting a Channel for our notifications
return LLChannelManager::getInstance()->getChannel(p);
return dynamic_cast<LLScreenChannel*> (LLChannelManager::getInstance()->getChannel(p));
}
//--------------------------------------------------------------------------
@ -113,7 +113,7 @@ void LLChannelManager::onLoginCompleted()
LLChannelManager::Params p;
p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
p.channel_align = CA_RIGHT;
mStartUpChannel = getChannel(p);
mStartUpChannel = createChannel(p);
if(!mStartUpChannel)
{
@ -147,22 +147,32 @@ void LLChannelManager::onStartUpToastClose()
LLScreenChannel::setStartUpToastShown();
// force NEARBY CHAT CHANNEL to repost all toasts if present
LLScreenChannel* nearby_channel = findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
nearby_channel->loadStoredToastsToChannel();
nearby_channel->setCanStoreToasts(false);
//LLScreenChannelBase* nearby_channel = findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
//!!!!!!!!!!!!!!
//FIXME
//nearby_channel->loadStoredToastsToChannel();
//nearby_channel->setCanStoreToasts(false);
}
//--------------------------------------------------------------------------
LLScreenChannel* LLChannelManager::getChannel(LLChannelManager::Params& p)
LLScreenChannelBase* LLChannelManager::addChannel(LLScreenChannelBase* channel)
{
LLScreenChannel* new_channel = NULL;
if(!channel)
return 0;
new_channel = findChannelByID(p.id);
ChannelElem new_elem;
new_elem.id = channel->getChannelID();
new_elem.channel = channel;
if(new_channel)
return new_channel;
mChannelList.push_back(new_elem);
new_channel = new LLScreenChannel(p.id);
return channel;
}
LLScreenChannel* LLChannelManager::createChannel(LLChannelManager::Params& p)
{
LLScreenChannel* new_channel = new LLScreenChannel(p.id);
if(!new_channel)
{
@ -172,20 +182,26 @@ LLScreenChannel* LLChannelManager::getChannel(LLChannelManager::Params& p)
{
new_channel->setToastAlignment(p.toast_align);
new_channel->setChannelAlignment(p.channel_align);
new_channel->setDisplayToastsAlways(p.display_toasts_always);
new_channel->setDisplayToastsAlways(p.display_toasts_always);
ChannelElem new_elem;
new_elem.id = p.id;
new_elem.channel = new_channel;
mChannelList.push_back(new_elem);
addChannel(new_channel);
}
return new_channel;
}
LLScreenChannelBase* LLChannelManager::getChannel(LLChannelManager::Params& p)
{
LLScreenChannelBase* new_channel = findChannelByID(p.id);
if(new_channel)
return new_channel;
return createChannel(p);
}
//--------------------------------------------------------------------------
LLScreenChannel* LLChannelManager::findChannelByID(const LLUUID id)
LLScreenChannelBase* LLChannelManager::findChannelByID(const LLUUID id)
{
std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id);
if(it != mChannelList.end())

View File

@ -52,8 +52,8 @@ class LLChannelManager : public LLSingleton<LLChannelManager>
public:
struct Params
{
LLUUID id;
bool display_toasts_always;
LLUUID id;
bool display_toasts_always;
EToastAlignment toast_align;
EChannelAlignment channel_align;
@ -64,7 +64,7 @@ public:
struct ChannelElem
{
LLUUID id;
LLScreenChannel* channel;
LLScreenChannelBase* channel;
ChannelElem() : id(LLUUID("")), channel(NULL) { }
@ -89,19 +89,23 @@ public:
void onStartUpToastClose();
// creates a new ScreenChannel according to the given parameters or returns existing if present
LLScreenChannel* getChannel(LLChannelManager::Params& p);
LLScreenChannelBase* getChannel(LLChannelManager::Params& p);
LLScreenChannelBase* addChannel(LLScreenChannelBase* channel);
// returns a channel by its ID
LLScreenChannel* findChannelByID(const LLUUID id);
LLScreenChannelBase* findChannelByID(const LLUUID id);
// creator of the Notification channel, that is used in more than one handler
LLScreenChannel* createNotificationChannel();
LLScreenChannel* createNotificationChannel();
// remove channel methods
void removeChannelByID(const LLUUID id);
private:
LLScreenChannel* createChannel(LLChannelManager::Params& p);
LLScreenChannel* mStartUpChannel;
std::vector<ChannelElem> mChannelList;
};

View File

@ -125,8 +125,8 @@ BOOL LLChatBar::postBuild()
mInputEditor = getChild<LLLineEditor>("Chat Editor");
mInputEditor->setKeystrokeCallback(&onInputEditorKeystroke, this);
mInputEditor->setFocusLostCallback(&onInputEditorFocusLost, this);
mInputEditor->setFocusReceivedCallback( &onInputEditorGainFocus, this );
mInputEditor->setFocusLostCallback(boost::bind(&LLChatBar::onInputEditorFocusLost));
mInputEditor->setFocusReceivedCallback(boost::bind(&LLChatBar::onInputEditorGainFocus));
mInputEditor->setCommitOnFocusLost( FALSE );
mInputEditor->setRevertOnEsc( FALSE );
mInputEditor->setIgnoreTab(TRUE);
@ -538,14 +538,14 @@ void LLChatBar::onInputEditorKeystroke( LLLineEditor* caller, void* userdata )
}
// static
void LLChatBar::onInputEditorFocusLost( LLFocusableElement* caller, void* userdata)
void LLChatBar::onInputEditorFocusLost()
{
// stop typing animation
gAgent.stopTyping();
}
// static
void LLChatBar::onInputEditorGainFocus( LLFocusableElement* caller, void* userdata )
void LLChatBar::onInputEditorGainFocus()
{
LLFloaterChat::setHistoryCursorAndScrollToEnd();
}

View File

@ -87,8 +87,8 @@ public:
static void onTabClick( void* userdata );
static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
static void onInputEditorFocusLost(LLFocusableElement* caller,void* userdata);
static void onInputEditorGainFocus(LLFocusableElement* caller,void* userdata);
static void onInputEditorFocusLost();
static void onInputEditorGainFocus();
void onCommitGesture(LLUICtrl* ctrl);

View File

@ -44,6 +44,7 @@
#include "llviewercontrol.h"
#include "llagentdata.h"
/*
static const S32 BORDER_MARGIN = 2;
static const S32 PARENT_BORDER_MARGIN = 0;
@ -53,33 +54,27 @@ static const F32 MIN_AUTO_SCROLL_RATE = 120.f;
static const F32 MAX_AUTO_SCROLL_RATE = 500.f;
static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f;
#define MAX_CHAT_HISTORY 100
*/
static const S32 msg_left_offset = 30;
static const S32 msg_right_offset = 10;
#define MAX_CHAT_HISTORY 100
static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl> t2("chat_items_container");
//static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl> t2("chat_items_container");
//*******************************************************************************************************************
//LLChatItemCtrl
//*******************************************************************************************************************
LLChatItemCtrl* LLChatItemCtrl::createInstance()
LLNearbyChatToastPanel* LLNearbyChatToastPanel::createInstance()
{
LLChatItemCtrl* item = new LLChatItemCtrl();
LLNearbyChatToastPanel* item = new LLNearbyChatToastPanel();
LLUICtrlFactory::getInstance()->buildPanel(item, "panel_chat_item.xml");
item->setFollows(FOLLOWS_NONE);
return item;
}
void LLChatItemCtrl::draw()
{
LLPanel::draw();
}
void LLChatItemCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
void LLNearbyChatToastPanel::reshape (S32 width, S32 height, BOOL called_from_parent )
{
LLPanel::reshape(width, height,called_from_parent);
@ -101,13 +96,13 @@ void LLChatItemCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
}
}
BOOL LLChatItemCtrl::postBuild()
BOOL LLNearbyChatToastPanel::postBuild()
{
return LLPanel::postBuild();
}
std::string LLChatItemCtrl::appendTime()
std::string LLNearbyChatToastPanel::appendTime()
{
time_t utc_time;
utc_time = time_corrected();
@ -124,48 +119,63 @@ std::string LLChatItemCtrl::appendTime()
void LLChatItemCtrl::addText (const std::string& message)
void LLNearbyChatToastPanel::addText (const std::string& message)
{
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
msg_text->addText(message);
mMessages.push_back(message);
}
void LLChatItemCtrl::setMessage (const LLChat& msg)
void LLNearbyChatToastPanel::init(LLSD& notification)
{
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
mText = notification["message"].asString(); // UTF-8 line of text
mFromName = notification["from"].asString(); // agent or object name
mFromID = notification["from_id"].asUUID(); // agent id or object id
int sType = notification["source"].asInteger();
mSourceType = (EChatSourceType)sType;
std::string str_sender;
if(gAgentID != msg.mFromID)
str_sender = msg.mFromName;
if(gAgentID != mFromID)
str_sender = mFromName;
else
str_sender = LLTrans::getString("You");;
caption->getChild<LLTextBox>("sender_name", false)->setText(str_sender);
std::string tt = appendTime();
caption->getChild<LLTextBox>("msg_time", false)->setText(tt);
caption->getChild<LLTextBox>("msg_time", false)->setText(appendTime());
caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(msg.mFromID);
mOriginalMessage = msg;
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
msg_text->setText(msg.mText);
msg_text->setText(mText);
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
if(mSourceType != CHAT_SOURCE_AGENT)
msg_inspector->setVisible(false);
mMessages.clear();
snapToMessageHeight ();
mIsDirty = true;//will set Avatar Icon in draw
}
void LLChatItemCtrl::snapToMessageHeight ()
void LLNearbyChatToastPanel::setMessage (const LLChat& chat_msg)
{
LLSD notification;
notification["message"] = chat_msg.mText;
notification["from"] = chat_msg.mFromName;
notification["from_id"] = chat_msg.mFromID;
notification["time"] = chat_msg.mTime;
notification["source"] = (S32)chat_msg.mSourceType;
init(notification);
}
void LLNearbyChatToastPanel::snapToMessageHeight ()
{
LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
S32 new_height = text_box->getTextPixelHeight();
@ -184,14 +194,14 @@ void LLChatItemCtrl::snapToMessageHeight ()
}
void LLChatItemCtrl::setWidth(S32 width)
void LLNearbyChatToastPanel::setWidth(S32 width)
{
LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
text_box->reshape(width - msg_left_offset - msg_right_offset,100/*its not magic number, we just need any number*/);
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
if(mOriginalMessage.mText.length())
msg_text->setText(mOriginalMessage.mText);
if(mText.length())
msg_text->setText(mText);
for(size_t i=0;i<mMessages.size();++i)
msg_text->addText(mMessages[i]);
@ -200,25 +210,25 @@ void LLChatItemCtrl::setWidth(S32 width)
snapToMessageHeight ();
}
void LLChatItemCtrl::onMouseLeave (S32 x, S32 y, MASK mask)
void LLNearbyChatToastPanel::onMouseLeave (S32 x, S32 y, MASK mask)
{
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
msg_inspector->setVisible(false);
}
void LLChatItemCtrl::onMouseEnter (S32 x, S32 y, MASK mask)
void LLNearbyChatToastPanel::onMouseEnter (S32 x, S32 y, MASK mask)
{
if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
if(mSourceType != CHAT_SOURCE_AGENT)
return;
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
msg_inspector->setVisible(true);
}
BOOL LLChatItemCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
BOOL LLNearbyChatToastPanel::handleMouseDown (S32 x, S32 y, MASK mask)
{
if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
if(mSourceType != CHAT_SOURCE_AGENT)
return LLPanel::handleMouseDown(x,y,mask);
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
@ -226,12 +236,16 @@ BOOL LLChatItemCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
S32 local_y = y - msg_inspector->getRect().mBottom - caption->getRect().mBottom;
if(msg_inspector->pointInView(local_x, local_y))
{
LLFloaterReg::showInstance("inspect_avatar", mOriginalMessage.mFromID);
LLFloaterReg::showInstance("inspect_avatar", mFromID);
}
else
{
LLFloaterReg::showInstance("nearby_chat",LLSD());
}
return LLPanel::handleMouseDown(x,y,mask);
}
void LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e)
void LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
{
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
@ -243,7 +257,7 @@ void LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e)
}
bool LLChatItemCtrl::canAddText ()
bool LLNearbyChatToastPanel::canAddText ()
{
LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text");
if(!msg_text)
@ -251,7 +265,7 @@ bool LLChatItemCtrl::canAddText ()
return msg_text->getTextLinesNum()<10;
}
BOOL LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
BOOL LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
LLPanel* caption = getChild<LLPanel>("msg_caption", false);
LLUICtrl* avatar_icon = caption->getChild<LLUICtrl>("avatar_icon", false);
@ -260,296 +274,20 @@ BOOL LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
S32 local_y = y - avatar_icon->getRect().mBottom - caption->getRect().mBottom;
//eat message for avatar icon if msg was from object
if(avatar_icon->pointInView(local_x, local_y) && mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
if(avatar_icon->pointInView(local_x, local_y) && mSourceType != CHAT_SOURCE_AGENT)
return TRUE;
return LLPanel::handleRightMouseDown(x,y,mask);
}
//*******************************************************************************************************************
//LLChatItemsContainerCtrl
//*******************************************************************************************************************
LLChatItemsContainerCtrl::LLChatItemsContainerCtrl(const Params& params):LLPanel(params)
void LLNearbyChatToastPanel::draw()
{
mEShowItemHeader = CHATITEMHEADER_SHOW_BOTH;
}
void LLChatItemsContainerCtrl::addMessage(const LLChat& msg)
{
/*
if(msg.mChatType == CHAT_TYPE_DEBUG_MSG)
return;
*/
if(mItems.size() >= MAX_CHAT_HISTORY)
if(mIsDirty)
{
LLChatItemCtrl* item = mItems[0];
removeChild(item);
delete item;
mItems.erase(mItems.begin());
}
if(mItems.size() > 0
&& msg.mFromID == mItems[mItems.size()-1]->getMessage().mFromID
&& (msg.mTime-mItems[mItems.size()-1]->getMessage().mTime)<60
&& mItems[mItems.size()-1]->canAddText()
)
{
mItems[mItems.size()-1]->addText(msg.mText);
mItems[mItems.size()-1]->snapToMessageHeight();
}
else
{
LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
mItems.push_back(item);
addChild(item,0);
item->setWidth(getRect().getWidth() - 16);
item->setMessage(msg);
item->snapToMessageHeight();
item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
item->setVisible(true);
}
arrange(getRect().getWidth(),getRect().getHeight());
updateLayout(getRect().getWidth(),getRect().getHeight());
scrollToBottom();
}
void LLChatItemsContainerCtrl::scrollToBottom ()
{
if(mScrollbar->getVisible())
{
mScrollbar->setDocPos(mScrollbar->getDocPosMax());
onScrollPosChangeCallback(0,0);
}
}
void LLChatItemsContainerCtrl::draw()
{
LLLocalClipRect clip(getRect());
LLPanel::draw();
}
void LLChatItemsContainerCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
{
S32 delta_width = width - getRect().getWidth();
S32 delta_height = height - getRect().getHeight();
if (delta_width || delta_height || sForceReshape)
{
arrange(width, height);
}
updateBoundingRect();
}
void LLChatItemsContainerCtrl::arrange (S32 width, S32 height)
{
S32 delta_width = width - getRect().getWidth();
if(delta_width)//width changed...too bad. now we need to reformat all items
reformatHistoryScrollItems(width);
calcRecuiredHeight();
show_hide_scrollbar(width,height);
updateLayout(width,height);
}
void LLChatItemsContainerCtrl::reformatHistoryScrollItems(S32 width)
{
for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
{
(*it)->setWidth(width);
}
}
S32 LLChatItemsContainerCtrl::calcRecuiredHeight ()
{
S32 rec_height = 0;
std::vector<LLChatItemCtrl*>::iterator it;
for(it=mItems.begin(); it!=mItems.end(); ++it)
{
rec_height += (*it)->getRect().getHeight();
}
mInnerRect.setLeftTopAndSize(0,rec_height + BORDER_MARGIN*2,getRect().getWidth(),rec_height + BORDER_MARGIN);
return mInnerRect.getHeight();
}
void LLChatItemsContainerCtrl::updateLayout (S32 width, S32 height)
{
S32 panel_top = height - BORDER_MARGIN ;
S32 panel_width = width;
if(mScrollbar->getVisible())
{
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
panel_top+=mScrollbar->getDocPos();
panel_width-=scrollbar_size;
}
//set sizes for first panels and dragbars
for(size_t i=0;i<mItems.size();++i)
{
LLRect panel_rect = mItems[i]->getRect();
panelSetLeftTopAndSize(mItems[i],panel_rect.mLeft,panel_top,panel_width,panel_rect.getHeight());
panel_top-=panel_rect.getHeight();
}
}
void LLChatItemsContainerCtrl::show_hide_scrollbar (S32 width, S32 height)
{
calcRecuiredHeight();
if(getRecuiredHeight() > height )
showScrollbar(width, height);
else
hideScrollbar(width, height);
}
void LLChatItemsContainerCtrl::showScrollbar (S32 width, S32 height)
{
bool was_visible = mScrollbar->getVisible();
mScrollbar->setVisible(true);
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
panelSetLeftTopAndSize(mScrollbar,width-scrollbar_size
,height-PARENT_BORDER_MARGIN,scrollbar_size,height-2*PARENT_BORDER_MARGIN);
mScrollbar->setPageSize(height);
mScrollbar->setDocParams(mInnerRect.getHeight(),mScrollbar->getDocPos());
if(was_visible)
{
S32 scroll_pos = llmin(mScrollbar->getDocPos(), getRecuiredHeight() - height - 1);
mScrollbar->setDocPos(scroll_pos);
updateLayout(width,height);
return;
}
}
void LLChatItemsContainerCtrl::hideScrollbar (S32 width, S32 height)
{
if(mScrollbar->getVisible() == false)
return;
mScrollbar->setVisible(false);
mScrollbar->setDocPos(0);
if(mItems.size()>0)
{
S32 panel_top = height - BORDER_MARGIN; // Top coordinate of the first panel
S32 diff = panel_top - mItems[0]->getRect().mTop;
shiftPanels(diff);
}
}
//---------------------------------------------------------------------------------
void LLChatItemsContainerCtrl::panelSetLeftTopAndSize(LLView* panel, S32 left, S32 top, S32 width, S32 height)
{
if(!panel)
return;
LLRect panel_rect = panel->getRect();
panel_rect.setLeftTopAndSize( left, top, width, height);
panel->reshape( width, height, 1);
panel->setRect(panel_rect);
}
void LLChatItemsContainerCtrl::panelShiftVertical(LLView* panel,S32 delta)
{
if(!panel)
return;
panel->translate(0,delta);
}
void LLChatItemsContainerCtrl::shiftPanels(S32 delta)
{
//Arrange panels
for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
{
panelShiftVertical((*it),delta);
}
}
//---------------------------------------------------------------------------------
void LLChatItemsContainerCtrl::onScrollPosChangeCallback(S32, LLScrollbar*)
{
updateLayout(getRect().getWidth(),getRect().getHeight());
}
BOOL LLChatItemsContainerCtrl::postBuild()
{
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
LLRect scroll_rect;
scroll_rect.setOriginAndSize(
getRect().getWidth() - scrollbar_size,
1,
scrollbar_size,
getRect().getHeight() - 1);
LLScrollbar::Params sbparams;
sbparams.name("scrollable vertical");
sbparams.rect(scroll_rect);
sbparams.orientation(LLScrollbar::VERTICAL);
sbparams.doc_size(mInnerRect.getHeight());
sbparams.doc_pos(0);
sbparams.page_size(mInnerRect.getHeight());
sbparams.step_size(VERTICAL_MULTIPLE);
sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
sbparams.change_callback(boost::bind(&LLChatItemsContainerCtrl::onScrollPosChangeCallback, this, _1, _2));
mScrollbar = LLUICtrlFactory::create<LLScrollbar> (sbparams);
LLView::addChild( mScrollbar );
mScrollbar->setVisible( true );
mScrollbar->setFollowsRight();
mScrollbar->setFollowsTop();
mScrollbar->setFollowsBottom();
reformatHistoryScrollItems(getRect().getWidth());
arrange(getRect().getWidth(),getRect().getHeight());
return LLPanel::postBuild();
}
BOOL LLChatItemsContainerCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
{
return LLPanel::handleMouseDown(x,y,mask);
}
BOOL LLChatItemsContainerCtrl::handleKeyHere (KEY key, MASK mask)
{
if( mScrollbar->getVisible() && mScrollbar->handleKeyHere( key,mask ) )
return TRUE;
return LLPanel::handleKeyHere(key,mask);
}
BOOL LLChatItemsContainerCtrl::handleScrollWheel ( S32 x, S32 y, S32 clicks )
{
if( mScrollbar->getVisible() && mScrollbar->handleScrollWheel( 0, 0, clicks ) )
return TRUE;
return false;
}
void LLChatItemsContainerCtrl::setHeaderVisibility(EShowItemHeader e)
{
if(e == mEShowItemHeader)
return;
mEShowItemHeader = e;
for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
{
(*it)->setHeaderVisibility(e);
LLPanel* caption = findChild<LLPanel>("msg_caption", false);
if(caption)
caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(mFromID);
mIsDirty = false;
}
LLToastPanelBase::draw();
}

View File

@ -37,6 +37,7 @@
#include "llscrollbar.h"
#include "string"
#include "llchat.h"
#include "lltoastpanel.h"
typedef enum e_show_item_header
{
@ -45,20 +46,18 @@ typedef enum e_show_item_header
CHATITEMHEADER_SHOW_BOTH
} EShowItemHeader;
class LLChatItemCtrl: public LLPanel
class LLNearbyChatToastPanel: public LLToastPanelBase
{
protected:
LLChatItemCtrl(){};
LLNearbyChatToastPanel():mIsDirty(false){};
public:
~LLChatItemCtrl(){}
~LLNearbyChatToastPanel(){}
static LLChatItemCtrl* createInstance();
static LLNearbyChatToastPanel* createInstance();
void draw();
const LLChat& getMessage() const { return mOriginalMessage;}
const LLUUID& getFromID() const { return mFromID;}
void addText (const std::string& message);
void setMessage (const LLChat& msg);
@ -77,77 +76,26 @@ public:
void setHeaderVisibility(EShowItemHeader e);
BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual void init(LLSD& data);
virtual void draw();
private:
std::string appendTime ();
private:
LLChat mOriginalMessage;
std::string mText; // UTF-8 line of text
std::string mFromName; // agent or object name
LLUUID mFromID; // agent id or object id
EChatSourceType mSourceType;
std::vector<std::string> mMessages;
bool mIsDirty;
};
class LLChatItemsContainerCtrl: public LLPanel
{
public:
struct Params
: public LLInitParam::Block<Params, LLPanel::Params>
{
Params(){};
};
LLChatItemsContainerCtrl(const Params& params);
~LLChatItemsContainerCtrl(){}
void addMessage (const LLChat& msg);
void draw();
void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE);
void onScrollPosChangeCallback(S32, LLScrollbar*);
virtual BOOL postBuild();
BOOL handleMouseDown (S32 x, S32 y, MASK mask);
BOOL handleKeyHere (KEY key, MASK mask);
BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
void scrollToBottom ();
void setHeaderVisibility(EShowItemHeader e);
EShowItemHeader getHeaderVisibility() const { return mEShowItemHeader;};
private:
void reformatHistoryScrollItems(S32 width);
void arrange (S32 width, S32 height);
S32 calcRecuiredHeight ();
S32 getRecuiredHeight () const { return mInnerRect.getHeight(); }
void updateLayout (S32 width, S32 height);
void show_hide_scrollbar (S32 width, S32 height);
void showScrollbar (S32 width, S32 height);
void hideScrollbar (S32 width, S32 height);
void panelSetLeftTopAndSize (LLView* panel, S32 left, S32 top, S32 width, S32 height);
void panelShiftVertical (LLView* panel,S32 delta);
void shiftPanels (S32 delta);
private:
std::vector<LLChatItemCtrl*> mItems;
EShowItemHeader mEShowItemHeader;
LLRect mInnerRect;
LLScrollbar* mScrollbar;
};
#endif

View File

@ -102,7 +102,7 @@ void LLChatMsgBox::drawText(S32 x, S32 y, const LLWString &text, const LLColor4
// iterate through each block of text that has been added
y -= mLineSpacing;
for (std::vector<S32>::iterator it = mSeparatorOffset.begin(); true ;)
for (std::vector<S32>::iterator it = mSeparatorOffset.begin(); it != mSeparatorOffset.end() ;)
{
// display the text for this block
S32 num_chars = *it - start;

View File

@ -49,6 +49,7 @@
#include "llvoicecontrolpanel.h"
#include "llgroupmgr.h"
#include "llnotificationmanager.h"
#include "lltransientfloatermgr.h"
static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk");
@ -243,26 +244,36 @@ void LLIMChiclet::draw()
LLIMChiclet::EType LLIMChiclet::getIMSessionType(const LLUUID& session_id)
{
EType type = TYPE_UNKNOWN;
LLFloaterIMPanel* im = NULL;
if(session_id.isNull())
return type;
if (!(im = LLIMMgr::getInstance()->findFloaterBySession(session_id)))
EInstantMessage im_type = LLIMModel::getInstance()->getType(session_id);
if (IM_COUNT == im_type)
{
llassert_always(0 && "IM session not found"); // should never happen
return type;
}
switch(im->getDialogType())
switch(im_type)
{
case IM_NOTHING_SPECIAL:
case IM_SESSION_P2P_INVITE:
type = TYPE_IM;
break;
case IM_SESSION_GROUP_START:
case IM_SESSION_INVITE:
type = TYPE_GROUP;
if (gAgent.isInGroup(session_id))
{
type = TYPE_GROUP;
}
else
{
type = TYPE_AD_HOC;
}
break;
case IM_SESSION_CONFERENCE_START:
type = TYPE_AD_HOC;
default:
break;
}
@ -285,6 +296,11 @@ LLIMP2PChiclet::Params::Params()
avatar_icon.name("avatar_icon");
avatar_icon.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
// *NOTE dzaporozhan
// Changed icon height from 25 to 24 to fix ticket EXT-794.
// In some cases(after changing UI scale) 25 pixel height icon was
// drawn incorrectly, i'm not sure why.
avatar_icon.rect(LLRect(0, 24, 25, 0));
avatar_icon.mouse_opaque(false);
@ -458,6 +474,11 @@ LLIMGroupChiclet::Params::Params()
rect(LLRect(0, 25, 45, 0));
group_icon.name("group_icon");
// *NOTE dzaporozhan
// Changed icon height from 25 to 24 to fix ticket EXT-794.
// In some cases(after changing UI scale) 25 pixel height icon was
// drawn incorrectly, i'm not sure why.
group_icon.rect(LLRect(0, 24, 25, 0));
unread_notifications.name("unread");
@ -1164,6 +1185,7 @@ LLTalkButton::LLTalkButton(const Params& p)
speak_params.rect(speak_rect);
mSpeakBtn = LLUICtrlFactory::create<LLButton>(speak_params);
addChild(mSpeakBtn);
LLTransientFloaterMgr::getInstance()->addControlView(mSpeakBtn);
mSpeakBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_SpeakBtn, this));
mSpeakBtn->setToggleState(FALSE);
@ -1172,6 +1194,7 @@ LLTalkButton::LLTalkButton(const Params& p)
show_params.rect(show_rect);
mShowBtn = LLUICtrlFactory::create<LLButton>(show_params);
addChild(mShowBtn);
LLTransientFloaterMgr::getInstance()->addControlView(mShowBtn);
mShowBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_ShowBtn, this));
mShowBtn->setToggleState(FALSE);

View File

@ -275,7 +275,8 @@ public:
enum EType {
TYPE_UNKNOWN,
TYPE_IM,
TYPE_GROUP
TYPE_GROUP,
TYPE_AD_HOC
};
/*virtual*/ ~LLIMChiclet() {};

View File

@ -125,7 +125,7 @@ LLCurrencyUIManager::Impl::Impl(LLPanel& dialog)
mUserCurrencyBuy(2000), // note, this is a default, real value set in llfloaterbuycurrency.cpp
mUserEnteredCurrencyBuy(false),
mSiteCurrencyEstimated(false),
mSiteCurrencyEstimatedCost(0),
mSiteCurrencyEstimatedCost(0),
mBought(false),
mTransactionType(TransactionNone), mTransaction(0),
mCurrencyChanged(false)
@ -394,7 +394,7 @@ void LLCurrencyUIManager::Impl::updateUI()
}
}
mPanel.childSetTextArg("currency_est", "[USD]", llformat("%#.2f", mSiteCurrencyEstimatedCost / 100.0));
mPanel.childSetTextArg("currency_est", "[LOCALAMOUNT]", "US$ " + llformat("%#.2f", mSiteCurrencyEstimatedCost / 100.0));
mPanel.childSetVisible("currency_est", mSiteCurrencyEstimated && mUserCurrencyBuy > 0);
if (mPanel.childIsEnabled("buy_btn")
@ -478,7 +478,7 @@ void LLCurrencyUIManager::buy(const std::string& buy_msg)
LLUIString msg = buy_msg;
msg.setArg("[LINDENS]", llformat("%d", impl.mUserCurrencyBuy));
msg.setArg("[USD]", llformat("%#.2f", impl.mSiteCurrencyEstimatedCost / 100.0));
msg.setArg("[LOCALAMOUNT]", "US$ " + llformat("%#.2f", impl.mSiteCurrencyEstimatedCost / 100.0));
LLConfirmationManager::confirm(impl.mSiteConfirm,
msg,
impl,

View File

@ -960,6 +960,30 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
return retval;
}
const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one.
//static
S32 LLDrawable::getMinVisFrameRange()
{
return MIN_VIS_FRAME_RANGE ;
}
BOOL LLDrawable::isRecentlyVisible() const
{
//currently visible or visible in the previous frame.
BOOL vis = isVisible() || (sCurVisible - mVisible < MIN_VIS_FRAME_RANGE) ;
if(!vis)
{
LLSpatialGroup* group = getSpatialGroup();
if (group && group->isRecentlyVisible())
{
mVisible = sCurVisible;
vis = TRUE ;
}
}
return vis ;
}
BOOL LLDrawable::isVisible() const
{

View File

@ -78,7 +78,8 @@ public:
BOOL isLight() const;
BOOL isVisible() const;
BOOL isVisible() const;
BOOL isRecentlyVisible() const;
virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE);
@ -278,7 +279,8 @@ public:
S32 mQuietCount;
static S32 getCurrentFrame() { return sCurVisible; }
static S32 getMinVisFrameRange();
void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; }
LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; }

View File

@ -270,16 +270,34 @@ void LLFace::setTexture(LLViewerTexture* tex)
{
mTexture->removeFace(this) ;
removeAtlas() ;
}
}
mTexture = tex ;
if(mTexture.notNull())
{
mTexture->addFace(this) ;
}
}
void LLFace::switchTexture(LLViewerTexture* new_texture)
{
if(mTexture == new_texture)
{
return ;
}
if(!new_texture)
{
llerrs << "Can not switch to a null texture." << llendl ;
}
new_texture->addTextureStats(mTexture->getMaxVirtualSize()) ;
getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
setTexture(new_texture) ;
gPipeline.markTextured(getDrawable());
}
void LLFace::setTEOffset(const S32 te_offset)
{
mTEOffset = te_offset;

View File

@ -89,6 +89,7 @@ public:
U16 getGeomIndex() const { return mGeomIndex; } // index into draw pool
U16 getGeomStart() const { return mGeomIndex; } // index into draw pool
void setTexture(LLViewerTexture* tex) ;
void switchTexture(LLViewerTexture* new_texture);
LLXformMatrix* getXform() const { return mXform; }
BOOL hasGeometry() const { return mGeomCount > 0; }
LLVector3 getPositionAgent() const;

View File

@ -934,6 +934,17 @@ void LLFavoritesBarCtrl::onButtonRightClick( LLUUID item_id,LLView* fav_button,S
LLMenuGL::showPopup(fav_button, menu, x, y);
}
BOOL LLFavoritesBarCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = childrenHandleRightMouseDown( x, y, mask) != NULL;
if(!handled && !gMenuHolder->hasVisibleMenu())
{
show_navbar_context_menu(this,x,y);
handled = true;
}
return handled;
}
void copy_slurl_to_clipboard_cb(std::string& slurl)
{
gClipboard.copyFromString(utf8str_to_wstring(slurl));

View File

@ -62,7 +62,7 @@ public:
std::string& tooltip_msg);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
// LLInventoryObserver observer trigger
virtual void changed(U32 mask);
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);

View File

@ -159,6 +159,9 @@ void LLFloaterBuyCurrencyUI::draw()
updateUI();
}
// disable the Buy button when we are not able to buy
childSetEnabled("buy_btn", mManager.canBuy());
LLFloater::draw();
}
@ -194,29 +197,19 @@ void LLFloaterBuyCurrencyUI::updateUI()
// error section
if (hasError)
{
mChildren.setBadge(std::string("step_error"), LLViewChildren::BADGE_ERROR);
LLTextBox* message = getChild<LLTextBox>("error_message");
if (message)
{
message->setVisible(true);
message->setWrappedText(mManager.errorMessage());
}
childSetVisible("error_web", !mManager.errorURI().empty());
if (!mManager.errorURI().empty())
{
childHide("getting_data");
}
childHide("normal_background");
childShow("error_background");
childShow("cannot_buy_message");
childShow("error_web");
}
else
{
childHide("step_error");
childHide("error_message");
childShow("normal_background");
childHide("error_background");
childHide("cannot_buy_message");
childHide("error_web");
}
// currency
childSetVisible("contacting", false);
childSetVisible("buy_action", false);
@ -224,8 +217,6 @@ void LLFloaterBuyCurrencyUI::updateUI()
if (!hasError)
{
mChildren.setBadge(std::string("step_1"), LLViewChildren::BADGE_NOTE);
if (mManager.buying())
{
childSetVisible("contacting", true);
@ -286,9 +277,8 @@ void LLFloaterBuyCurrencyUI::updateUI()
childHide("purchase_warning_notenough");
}
childSetEnabled("buy_btn", mManager.canBuy());
if (!mManager.canBuy() && !childIsVisible("error_web"))
childHide("getting_data");
if (!mManager.canBuy() && !hasError)
{
childShow("getting_data");
}
@ -298,10 +288,6 @@ void LLFloaterBuyCurrencyUI::onClickBuy()
{
mManager.buy(getString("buy_currency"));
updateUI();
// JC: updateUI() doesn't get called again until progress is made
// with transaction processing, so the "Purchase" button would be
// left enabled for some time. Pre-emptively disable.
childSetEnabled("buy_btn", false);
}
void LLFloaterBuyCurrencyUI::onClickCancel()
@ -311,7 +297,7 @@ void LLFloaterBuyCurrencyUI::onClickCancel()
void LLFloaterBuyCurrencyUI::onClickErrorWeb()
{
LLWeb::loadURLExternal(mManager.errorURI());
LLWeb::loadURLExternal(getString("account_website"));
closeFloater();
}

View File

@ -66,7 +66,6 @@
#include "lllogchat.h"
#include "lltexteditor.h"
#include "lltextparser.h"
#include "llfloaterhtml.h"
#include "llweb.h"
#include "llstylemap.h"

View File

@ -363,7 +363,8 @@ LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater()
{
// only LLFloaterIMPanels are called "im_floater"
LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)panelp;
if (im_floaterp->getVoiceChannel() == LLVoiceChannel::getCurrentVoiceChannel())
LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(im_floaterp->getSessionID());
if (voice_channel == LLVoiceChannel::getCurrentVoiceChannel())
{
return im_floaterp;
}

View File

@ -0,0 +1,142 @@
/**
* @file llfloaterhelpbrowser.cpp
* @brief HTML Help floater - uses embedded web browser control
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterhelpbrowser.h"
#include "llfloaterreg.h"
#include "llpluginclassmedia.h"
#include "llmediactrl.h"
#include "llviewerwindow.h"
#include "llviewercontrol.h"
#include "llweb.h"
#include "llui.h"
#include "llurlhistory.h"
#include "llmediactrl.h"
#include "llviewermedia.h"
LLFloaterHelpBrowser::LLFloaterHelpBrowser(const LLSD& key)
: LLFloater(key)
{
// really really destroy the help browser when it's closed, it'll be recreated.
// *TODO: when onClose() is resurrected as a virtual, this bind can go away.
mCloseSignal.connect(boost::bind(&LLFloaterHelpBrowser::onClose, this));
}
BOOL LLFloaterHelpBrowser::postBuild()
{
mBrowser = getChild<LLMediaCtrl>("browser");
mBrowser->addObserver(this);
childSetAction("open_browser", onClickOpenWebBrowser, this);
buildURLHistory();
return TRUE;
}
void LLFloaterHelpBrowser::buildURLHistory()
{
// Get all of the entries in the "browser" collection
LLSD browser_history = LLURLHistory::getURLHistory("browser");
// initialize URL history in the plugin
LLPluginClassMedia *plugin = mBrowser->getMediaPlugin();
if (plugin)
{
plugin->initializeUrlHistory(browser_history);
}
}
void LLFloaterHelpBrowser::onClose()
{
destroy(); // really destroy this dialog on closure, it's relatively heavyweight.
}
void LLFloaterHelpBrowser::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
{
if(event == MEDIA_EVENT_LOCATION_CHANGED)
{
setCurrentURL(self->getLocation());
}
else if(event == MEDIA_EVENT_NAVIGATE_COMPLETE)
{
// nothing yet
}
}
void LLFloaterHelpBrowser::setCurrentURL(const std::string& url)
{
mCurrentURL = url;
// redirects will navigate momentarily to about:blank, don't add to history
if (mCurrentURL != "about:blank")
{
// Serialize url history
LLURLHistory::removeURL("browser", mCurrentURL);
LLURLHistory::addURL("browser", mCurrentURL);
}
}
//static
void LLFloaterHelpBrowser::onClickClose(void* user_data)
{
LLFloaterHelpBrowser* self = (LLFloaterHelpBrowser*)user_data;
self->closeFloater();
}
//static
void LLFloaterHelpBrowser::onClickOpenWebBrowser(void* user_data)
{
LLFloaterHelpBrowser* self = (LLFloaterHelpBrowser*)user_data;
std::string url = self->mCurrentURL.empty() ?
self->mBrowser->getHomePageUrl() :
self->mCurrentURL;
LLWeb::loadURLExternal(url);
}
void LLFloaterHelpBrowser::openMedia(const std::string& media_url)
{
mBrowser->setHomePageUrl(media_url);
//mBrowser->navigateTo("data:text/html;charset=utf-8,I'd really love to be going to:<br><b>" + media_url + "</b>"); // tofu HACK for debugging =:)
mBrowser->navigateTo(media_url);
setCurrentURL(media_url);
}
void LLFloaterHelpBrowser::navigateToLocalPage( const std::string& subdir, const std::string& filename_in )
{
mBrowser->navigateToLocalPage(subdir, filename_in);
}

View File

@ -0,0 +1,72 @@
/**
* @file llfloatermediabrowser.h
* @brief HTML Help floater - uses embedded web browser control
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERHELPBROWSER_H
#define LL_LLFLOATERHELPBROWSER_H
#include "llfloater.h"
#include "llmediactrl.h"
class LLMediaCtrl;
class LLFloaterHelpBrowser :
public LLFloater,
public LLViewerMediaObserver
{
public:
LLFloaterHelpBrowser(const LLSD& key);
/*virtual*/ BOOL postBuild();
void onClose();
// inherited from LLViewerMediaObserver
/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
void openMedia(const std::string& media_url);
void navigateToLocalPage( const std::string& subdir, const std::string& filename_in );
private:
void buildURLHistory();
void setCurrentURL(const std::string& url);
static void onClickClose(void* user_data);
static void onClickOpenWebBrowser(void* user_data);
private:
LLMediaCtrl* mBrowser;
std::string mCurrentURL;
};
#endif // LL_LLFLOATERHELPBROWSER_H

View File

@ -1169,7 +1169,8 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p)
mScroller(NULL),
mSortOrderSetting(p.sort_order_setting),
mInventory(p.inventory),
mAllowMultiSelect(p.allow_multi_select)
mAllowMultiSelect(p.allow_multi_select),
mHasInventoryConnection(false)
{
// contex menu callbacks
mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLInventoryPanel::doToSelected, this, _2));
@ -1230,9 +1231,10 @@ BOOL LLInventoryPanel::postBuild()
mInventoryObserver = new LLInventoryPanelObserver(this);
mInventory->addObserver(mInventoryObserver);
// build view of inventory if inventory ready, otherwise wait for modelChanged() callback
if (mInventory->isInventoryUsable())
if (mInventory->isInventoryUsable() && !mHasInventoryConnection)
{
rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD);
mHasInventoryConnection = true;
}
// bit of a hack to make sure the inventory is open.
@ -1332,9 +1334,10 @@ void LLInventoryPanel::modelChanged(U32 mask)
bool handled = false;
// inventory just initialized, do complete build
if ((mask & LLInventoryObserver::ADD) && gInventory.getChangedIDs().empty())
if ((mask & LLInventoryObserver::ADD) && gInventory.getChangedIDs().empty() && !mHasInventoryConnection)
{
rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD);
mHasInventoryConnection = true;
return;
}

View File

@ -179,6 +179,7 @@ protected:
LLScrollContainer* mScroller;
BOOL mAllowMultiSelect;
std::string mSortOrderSetting;
bool mHasInventoryConnection;
};
class LLFloaterInventory;

View File

@ -1043,7 +1043,7 @@ BOOL LLPanelLandObjects::postBuild()
mSelectedObjects = getChild<LLTextBox>("selected_objects_text");
mCleanOtherObjectsTime = getChild<LLLineEditor>("clean other time");
mCleanOtherObjectsTime->setFocusLostCallback(onLostFocus, this);
mCleanOtherObjectsTime->setFocusLostCallback(boost::bind(onLostFocus, _1, this));
mCleanOtherObjectsTime->setCommitCallback(onCommitClean, this);
childSetPrevalidate("clean other time", LLLineEditor::prevalidateNonNegativeS32);

View File

@ -1,6 +1,6 @@
/**
* @file llfloaterhtmlhelp.cpp
* @brief HTML Help floater - uses embedded web browser control
* @file llfloatermediabrowser.cpp
* @brief media browser floater - uses embedded media browser control
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
@ -33,7 +33,6 @@
#include "llviewerprecompiledheaders.h"
#include "llfloatermediabrowser.h"
#include "llfloaterhtml.h"
#include "llfloaterreg.h"
#include "llparcel.h"
@ -147,7 +146,10 @@ void LLFloaterMediaBrowser::buildURLHistory()
}
// initialize URL history in the plugin
mBrowser->getMediaPlugin()->initializeUrlHistory(browser_history);
if(mBrowser && mBrowser->getMediaPlugin())
{
mBrowser->getMediaPlugin()->initializeUrlHistory(browser_history);
}
}
std::string LLFloaterMediaBrowser::getSupportURL()
@ -330,69 +332,3 @@ void LLFloaterMediaBrowser::openMedia(const std::string& media_url)
mBrowser->navigateTo(media_url);
setCurrentURL(media_url);
}
////////////////////////////////////////////////////////////////////////////////
//
LLViewerHtmlHelp gViewerHtmlHelp;
////////////////////////////////////////////////////////////////////////////////
//
LLViewerHtmlHelp::LLViewerHtmlHelp()
{
LLUI::setHtmlHelp(this);
}
LLViewerHtmlHelp::~LLViewerHtmlHelp()
{
LLUI::setHtmlHelp(NULL);
}
void LLViewerHtmlHelp::show()
{
show("");
}
void LLViewerHtmlHelp::show(std::string url)
{
LLFloaterMediaBrowser* floater_html = dynamic_cast<LLFloaterMediaBrowser*>(LLFloaterReg::getInstance("media_browser"));
floater_html->setVisible(FALSE);
if (url.empty())
{
url = floater_html->getSupportURL();
}
if (gSavedSettings.getBOOL("UseExternalBrowser"))
{
LLSD notificationData;
notificationData["url"] = url;
LLNotifications::instance().add("ClickOpenF1Help", notificationData, LLSD(), onClickF1HelpLoadURL);
floater_html->closeFloater();
}
else
{
// don't wait, just do it
floater_html->setVisible(TRUE);
floater_html->openMedia(url);
}
}
// static
bool LLViewerHtmlHelp::onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response)
{
LLFloaterMediaBrowser* floater_html = dynamic_cast<LLFloaterMediaBrowser*>(LLFloaterReg::getInstance("media_browser"));
floater_html->setVisible(FALSE);
std::string url = floater_html->getSupportURL();
S32 option = LLNotification::getSelectedOption(notification, response);
if (option == 0)
{
LLWeb::loadURL(url);
}
floater_html->closeFloater();
return false;
}

View File

@ -1,6 +1,6 @@
/**
* @file llfloatermediabrowser.h
* @brief HTML Help floater - uses embedded web browser control
* @brief media browser floater - uses embedded media browser control
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
@ -33,23 +33,9 @@
#ifndef LL_LLFLOATERMEDIABROWSER_H
#define LL_LLFLOATERMEDIABROWSER_H
#include "llhtmlhelp.h"
#include "llfloater.h"
#include "llmediactrl.h"
class LLViewerHtmlHelp : public LLHtmlHelp
{
public:
LLViewerHtmlHelp();
virtual ~LLViewerHtmlHelp();
/*virtual*/ void show();
/*virtual*/ void show(std::string start_url);
void show(std::string start_url, std::string title);
static bool onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response);
};
class LLComboBox;
class LLMediaCtrl;
@ -93,7 +79,5 @@ private:
std::string mCurrentURL;
};
extern LLViewerHtmlHelp gViewerHtmlHelp;
#endif // LL_LLFLOATERMEDIABROWSER_H

View File

@ -0,0 +1,249 @@
/**
* @file llfloatermediasettings.cpp
* @brief Tabbed dialog for media settings - class implementation
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterreg.h"
#include "llfloatermediasettings.h"
#include "llpanelmediasettingsgeneral.h"
#include "llpanelmediasettingssecurity.h"
#include "llpanelmediasettingspermissions.h"
#include "llviewercontrol.h"
#include "lluictrlfactory.h"
#include "llbutton.h"
#include "llselectmgr.h"
LLFloaterMediaSettings* LLFloaterMediaSettings::sInstance = NULL;
////////////////////////////////////////////////////////////////////////////////
//
LLFloaterMediaSettings::LLFloaterMediaSettings(const LLSD& key)
: LLFloater(key),
mTabContainer(NULL),
mPanelMediaSettingsGeneral(NULL),
mPanelMediaSettingsSecurity(NULL),
mPanelMediaSettingsPermissions(NULL),
mWaitingToClose( false )
{
// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_media_settings.xml");
}
////////////////////////////////////////////////////////////////////////////////
//
LLFloaterMediaSettings::~LLFloaterMediaSettings()
{
if ( mPanelMediaSettingsGeneral )
{
delete mPanelMediaSettingsGeneral;
mPanelMediaSettingsGeneral = NULL;
}
if ( mPanelMediaSettingsSecurity )
{
delete mPanelMediaSettingsSecurity;
mPanelMediaSettingsSecurity = NULL;
}
if ( mPanelMediaSettingsPermissions )
{
delete mPanelMediaSettingsPermissions;
mPanelMediaSettingsPermissions = NULL;
}
sInstance = NULL;
}
////////////////////////////////////////////////////////////////////////////////
//
BOOL LLFloaterMediaSettings::postBuild()
{
mCloseSignal.connect(boost::bind(&LLFloaterMediaSettings::onClose, this));
mApplyBtn = getChild<LLButton>("Apply");
mApplyBtn->setClickedCallback(onBtnApply, this);
mCancelBtn = getChild<LLButton>("Cancel");
mCancelBtn->setClickedCallback(onBtnCancel, this);
mOKBtn = getChild<LLButton>("OK");
mOKBtn->setClickedCallback(onBtnOK, this);
mTabContainer = getChild<LLTabContainer>( "tab_container" );
mPanelMediaSettingsGeneral = new LLPanelMediaSettingsGeneral();
mTabContainer->addTabPanel(
LLTabContainer::TabPanelParams().
panel(mPanelMediaSettingsGeneral));
mPanelMediaSettingsGeneral->setParent( this );
// note that "permissions" tab is really "Controls" tab - refs to 'perms' and
// 'permissions' not changed to 'controls' since we don't want to change
// shared files in server code and keeping everything the same seemed best.
mPanelMediaSettingsPermissions = new LLPanelMediaSettingsPermissions();
mTabContainer->addTabPanel(
LLTabContainer::TabPanelParams().
panel(mPanelMediaSettingsPermissions));
mPanelMediaSettingsSecurity = new LLPanelMediaSettingsSecurity();
mTabContainer->addTabPanel(
LLTabContainer::TabPanelParams().
panel(mPanelMediaSettingsSecurity));
// restore the last tab viewed from persistance variable storage
if (!mTabContainer->selectTab(gSavedSettings.getS32("LastMediaSettingsTab")))
{
mTabContainer->selectFirstTab();
};
sInstance = this;
return TRUE;
}
//static
LLFloaterMediaSettings* LLFloaterMediaSettings::getInstance()
{
if ( !sInstance )
{
sInstance = (LLFloaterReg::getTypedInstance<LLFloaterMediaSettings>("media_settings"));
}
return sInstance;
}
//static
void LLFloaterMediaSettings::apply()
{
LLSD settings;
sInstance->mPanelMediaSettingsGeneral->getValues( settings );
sInstance->mPanelMediaSettingsSecurity->getValues( settings );
sInstance->mPanelMediaSettingsPermissions->getValues( settings );
LLSelectMgr::getInstance()->selectionSetMedia( LLTextureEntry::MF_HAS_MEDIA );
LLSelectMgr::getInstance()->selectionSetMediaData(settings);
}
////////////////////////////////////////////////////////////////////////////////
void LLFloaterMediaSettings::onClose()
{
if(mPanelMediaSettingsGeneral)
{
mPanelMediaSettingsGeneral->onClose();
}
LLFloaterReg::hideInstance("whitelist_entry");
}
////////////////////////////////////////////////////////////////////////////////
//static
void LLFloaterMediaSettings::initValues( const LLSD& media_settings )
{
sInstance->clearValues();
// update all panels with values from simulator
sInstance->mPanelMediaSettingsGeneral->
initValues( sInstance->mPanelMediaSettingsGeneral, media_settings );
sInstance->mPanelMediaSettingsSecurity->
initValues( sInstance->mPanelMediaSettingsSecurity, media_settings );
sInstance->mPanelMediaSettingsPermissions->
initValues( sInstance->mPanelMediaSettingsPermissions, media_settings );
}
////////////////////////////////////////////////////////////////////////////////
//
void LLFloaterMediaSettings::commitFields()
{
if (hasFocus())
{
LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
if (cur_focus->acceptsTextInput())
{
cur_focus->onCommit();
};
};
}
////////////////////////////////////////////////////////////////////////////////
//static
void LLFloaterMediaSettings::clearValues()
{
// clean up all panels before updating
sInstance->mPanelMediaSettingsGeneral->clearValues(sInstance->mPanelMediaSettingsGeneral);
sInstance->mPanelMediaSettingsSecurity->clearValues(sInstance->mPanelMediaSettingsSecurity);
sInstance->mPanelMediaSettingsPermissions->clearValues(sInstance->mPanelMediaSettingsPermissions);
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLFloaterMediaSettings::onBtnOK( void* userdata )
{
sInstance->commitFields();
sInstance->apply();
sInstance->closeFloater();
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLFloaterMediaSettings::onBtnApply( void* userdata )
{
sInstance->commitFields();
sInstance->apply();
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLFloaterMediaSettings::onBtnCancel( void* userdata )
{
sInstance->closeFloater();
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLFloaterMediaSettings::onTabChanged(void* user_data, bool from_click)
{
LLTabContainer* self = (LLTabContainer*)user_data;
gSavedSettings.setS32("LastMediaSettingsTab", self->getCurrentPanelIndex());
}
////////////////////////////////////////////////////////////////////////////////
//
void LLFloaterMediaSettings::enableOkApplyBtns( bool enable )
{
setCtrlsEnabled( enable );
childSetEnabled( "OK", enable );
childSetEnabled( "Apply", enable );
}

View File

@ -0,0 +1,81 @@
/**
* @file llfloatermediasettings.cpp
* @brief Tabbed dialog for media settings - class definition
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERMEDIASETTINGS_H
#define LL_LLFLOATERMEDIASETTINGS_H
#include "llfloater.h"
#include "lltabcontainer.h"
class LLPanelMediaSettingsGeneral;
class LLPanelMediaSettingsSecurity;
class LLPanelMediaSettingsPermissions;
class LLFloaterMediaSettings :
public LLFloater
{
public:
LLFloaterMediaSettings(const LLSD& key);
~LLFloaterMediaSettings();
virtual BOOL postBuild();
static LLFloaterMediaSettings* getInstance();
static void apply();
static void initValues( const LLSD& media_settings );
static void clearValues();
void enableOkApplyBtns( bool enable );
LLPanelMediaSettingsSecurity* getPanelSecurity(){return mPanelMediaSettingsSecurity;};
protected:
LLButton *mOKBtn;
LLButton *mCancelBtn;
LLButton *mApplyBtn;
LLTabContainer *mTabContainer;
LLPanelMediaSettingsGeneral* mPanelMediaSettingsGeneral;
LLPanelMediaSettingsSecurity* mPanelMediaSettingsSecurity;
LLPanelMediaSettingsPermissions* mPanelMediaSettingsPermissions;
void onClose();
static void onBtnOK(void*);
static void onBtnCancel(void*);
static void onBtnApply(void*);
static void onTabChanged(void* user_data, bool from_click);
void commitFields();
static LLFloaterMediaSettings* sInstance;
private:
bool mWaitingToClose;
};
#endif // LL_LLFLOATERMEDIASETTINGS_H

View File

@ -106,7 +106,7 @@ BOOL LLFloaterPostcard::postBuild()
childSetValue("name_form", LLSD(name_string));
// For the first time a user focusess to .the msg box, all text will be selected.
getChild<LLUICtrl>("msg_form")->setFocusChangedCallback(onMsgFormFocusRecieved, this);
getChild<LLUICtrl>("msg_form")->setFocusChangedCallback(boost::bind(onMsgFormFocusRecieved, _1, this));
childSetFocus("to_form", TRUE);

View File

@ -195,8 +195,8 @@ void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator);
viewer_media_t get_web_media()
{
viewer_media_t media_source = LLViewerMedia::newMediaImpl("", LLUUID::null, 0, 0, 0, 0, "text/html");
viewer_media_t media_source = LLViewerMedia::newMediaImpl(LLUUID::null);
media_source->initializeMedia("text/html");
return media_source;
}

View File

@ -1,6 +1,6 @@
/**
* @file llfloaterreporter.cpp
* @brief Bug and abuse reports.
* @brief Abuse reports.
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
@ -220,8 +220,7 @@ LLFloaterReporter::~LLFloaterReporter()
void LLFloaterReporter::draw()
{
// this is set by a static callback sometime after the dialog is created.
// Only disable screenshot for abuse reports to estate owners - bug reports always
// allow screenshots to be taken.
// Only disable screenshot for abuse reports to estate owners
if ( mEmailToEstateOwner )
{
childSetValue("screen_check", FALSE );
@ -479,15 +478,6 @@ void LLFloaterReporter::showFromMenu(EReportType report_type)
if (f)
{
f->setReportType(report_type);
if (report_type == BUG_REPORT)
{
LLNotifications::instance().add("HelpReportBug");
}
else
{
// popup for abuse reports is triggered elsewhere
}
}
}
@ -528,14 +518,7 @@ bool LLFloaterReporter::validateReport()
U8 category = (U8)category_sd.asInteger();
if (category == 0)
{
if ( mReportType != BUG_REPORT )
{
LLNotifications::instance().add("HelpReportAbuseSelectCategory");
}
else
{
LLNotifications::instance().add("HelpReportBugSelectCategory");
}
LLNotifications::instance().add("HelpReportAbuseSelectCategory");
return false;
}
@ -561,27 +544,13 @@ bool LLFloaterReporter::validateReport()
if ( childGetText("summary_edit").empty() )
{
if ( mReportType != BUG_REPORT )
{
LLNotifications::instance().add("HelpReportAbuseSummaryEmpty");
}
else
{
LLNotifications::instance().add("HelpReportBugSummaryEmpty");
}
LLNotifications::instance().add("HelpReportAbuseSummaryEmpty");
return false;
};
if ( childGetText("details_edit") == mDefaultSummary )
{
if ( mReportType != BUG_REPORT )
{
LLNotifications::instance().add("HelpReportAbuseDetailsEmpty");
}
else
{
LLNotifications::instance().add("HelpReportBugDetailsEmpty");
}
LLNotifications::instance().add("HelpReportAbuseDetailsEmpty");
return false;
};
return true;

View File

@ -1,7 +1,7 @@
/**
* @file llfloaterreporter.h
* @author Andrew Meadows
* @brief Bug and abuse reports.
* @brief Abuse reports.
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
@ -48,7 +48,7 @@ class LLMeanCollisionData;
struct LLResourceData;
// these flags are used to label info requests to the server
const U32 BUG_REPORT_REQUEST = 0x01 << 0;
//const U32 BUG_REPORT_REQUEST = 0x01 << 0; // DEPRECATED
const U32 COMPLAINT_REPORT_REQUEST = 0x01 << 1;
const U32 OBJECT_PAY_REQUEST = 0x01 << 2;
@ -73,7 +73,7 @@ enum EReportType
{
NULL_REPORT = 0, // don't use this value anywhere
UNKNOWN_REPORT = 1,
BUG_REPORT = 2,
//BUG_REPORT = 2, // DEPRECATED
COMPLAINT_REPORT = 3,
CS_REQUEST_REPORT = 4
};

View File

@ -44,9 +44,11 @@
#include "llcombobox.h"
#include "lldraghandle.h"
#include "llfloaterbuildoptions.h"
#include "llfloatermediasettings.h"
#include "llfloateropenobject.h"
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llmediaentry.h"
#include "llmenugl.h"
#include "llpanelcontents.h"
#include "llpanelface.h"
@ -97,7 +99,7 @@ const std::string PANEL_NAMES[LLFloaterTools::PANEL_COUNT] =
};
// Local prototypes
void commit_select_component(LLUICtrl *ctrl, void *data);
void commit_select_component(void *data);
void click_show_more(void*);
void click_popup_info(void*);
void click_popup_done(void*);
@ -105,15 +107,14 @@ void click_popup_minimize(void*);
void click_popup_rotate_left(void*);
void click_popup_rotate_reset(void*);
void click_popup_rotate_right(void*);
void commit_slider_dozer_size(LLUICtrl *, void*);
void commit_slider_dozer_force(LLUICtrl *, void*);
void commit_slider_dozer_force(LLUICtrl *);
void click_apply_to_selection(void*);
void commit_radio_group_focus(LLUICtrl* ctrl, void* data);
void commit_radio_group_move(LLUICtrl* ctrl, void* data);
void commit_radio_group_edit(LLUICtrl* ctrl, void* data);
void commit_radio_group_land(LLUICtrl* ctrl, void* data);
void commit_grid_mode(LLUICtrl *, void*);
void commit_slider_zoom(LLUICtrl *, void*);
void commit_radio_group_focus(LLUICtrl* ctrl);
void commit_radio_group_move(LLUICtrl* ctrl);
void commit_radio_group_edit(LLUICtrl* ctrl);
void commit_radio_group_land(LLUICtrl* ctrl);
void commit_grid_mode(LLUICtrl *);
void commit_slider_zoom(LLUICtrl *ctrl);
//static
@ -210,43 +211,28 @@ BOOL LLFloaterTools::postBuild()
getDragHandle()->setEnabled( !gSavedSettings.getBOOL("ToolboxAutoMove") );
LLRect rect;
mBtnFocus = getChild<LLButton>("button focus");//btn;
childSetAction("button focus",LLFloaterTools::setEditTool, (void*)LLToolCamera::getInstance());
mBtnMove = getChild<LLButton>("button move");
childSetAction("button move",LLFloaterTools::setEditTool, (void*)LLToolGrab::getInstance());
mBtnEdit = getChild<LLButton>("button edit");
childSetAction("button edit",LLFloaterTools::setEditTool, (void*)LLToolCompTranslate::getInstance());
mBtnCreate = getChild<LLButton>("button create");
childSetAction("button create",LLFloaterTools::setEditTool, (void*)LLToolCompCreate::getInstance());
mBtnLand = getChild<LLButton>("button land" );
childSetAction("button land",LLFloaterTools::setEditTool, (void*)LLToolSelectLand::getInstance());
mTextStatus = getChild<LLTextBox>("text status");
childSetCommitCallback("slider zoom",commit_slider_zoom,this);
mRadioGroupFocus = getChild<LLRadioGroup>("focus_radio_group");
childSetCommitCallback("focus_radio_group", commit_radio_group_focus, this);
mRadioGroupMove = getChild<LLRadioGroup>("move_radio_group");
childSetCommitCallback("move_radio_group", commit_radio_group_move, this);
mRadioGroupEdit = getChild<LLRadioGroup>("edit_radio_group");
childSetCommitCallback("edit_radio_group", commit_radio_group_edit, this);
mCheckSelectIndividual = getChild<LLCheckBoxCtrl>("checkbox edit linked parts");
mBtnFocus = getChild<LLButton>("button focus");//btn;
mBtnMove = getChild<LLButton>("button move");
mBtnEdit = getChild<LLButton>("button edit");
mBtnCreate = getChild<LLButton>("button create");
mBtnLand = getChild<LLButton>("button land" );
mTextStatus = getChild<LLTextBox>("text status");
mRadioGroupFocus = getChild<LLRadioGroup>("focus_radio_group");
mRadioGroupMove = getChild<LLRadioGroup>("move_radio_group");
mRadioGroupEdit = getChild<LLRadioGroup>("edit_radio_group");
mBtnGridOptions = getChild<LLButton>("Options...");
mCheckSelectIndividual = getChild<LLCheckBoxCtrl>("checkbox edit linked parts");
childSetValue("checkbox edit linked parts",(BOOL)gSavedSettings.getBOOL("EditLinkedParts"));
childSetCommitCallback("checkbox edit linked parts",commit_select_component,this);
mCheckSnapToGrid = getChild<LLCheckBoxCtrl>("checkbox snap to grid");
mCheckSnapToGrid = getChild<LLCheckBoxCtrl>("checkbox snap to grid");
childSetValue("checkbox snap to grid",(BOOL)gSavedSettings.getBOOL("SnapEnabled"));
mBtnGridOptions = getChild<LLButton>("Options...");
childSetAction("Options...",onClickGridOptions, this);
mCheckStretchUniform = getChild<LLCheckBoxCtrl>("checkbox uniform");
mCheckStretchUniform = getChild<LLCheckBoxCtrl>("checkbox uniform");
childSetValue("checkbox uniform",(BOOL)gSavedSettings.getBOOL("ScaleUniform"));
mCheckStretchTexture = getChild<LLCheckBoxCtrl>("checkbox stretch textures");
mCheckStretchTexture = getChild<LLCheckBoxCtrl>("checkbox stretch textures");
childSetValue("checkbox stretch textures",(BOOL)gSavedSettings.getBOOL("ScaleStretchTextures"));
mTextGridMode = getChild<LLTextBox>("text ruler mode");
mComboGridMode = getChild<LLComboBox>("combobox grid mode");
childSetCommitCallback("combobox grid mode",commit_grid_mode, this);
mTextGridMode = getChild<LLTextBox>("text ruler mode");
mComboGridMode = getChild<LLComboBox>("combobox grid mode");
//
// Create Buttons
//
@ -271,18 +257,11 @@ BOOL LLFloaterTools::postBuild()
mCheckCopyRotates = getChild<LLCheckBoxCtrl>("checkbox copy rotates");
childSetValue("checkbox copy rotates",(BOOL)gSavedSettings.getBOOL("CreateToolCopyRotates"));
mRadioGroupLand = getChild<LLRadioGroup>("land_radio_group");
childSetCommitCallback("land_radio_group", commit_radio_group_land, this);
mBtnApplyToSelection = getChild<LLButton>("button apply to selection");
childSetAction("button apply to selection",click_apply_to_selection, (void*)0);
mSliderDozerSize = getChild<LLSlider>("slider brush size");
childSetCommitCallback("slider brush size", commit_slider_dozer_size, (void*)0);
mRadioGroupLand = getChild<LLRadioGroup>("land_radio_group");
mBtnApplyToSelection = getChild<LLButton>("button apply to selection");
mSliderDozerSize = getChild<LLSlider>("slider brush size");
childSetValue( "slider brush size", gSavedSettings.getF32("LandBrushSize"));
mSliderDozerForce = getChild<LLSlider>("slider force");
childSetCommitCallback("slider force",commit_slider_dozer_force, (void*)0);
mSliderDozerForce = getChild<LLSlider>("slider force");
// the setting stores the actual force multiplier, but the slider is logarithmic, so we convert here
childSetValue( "slider force", log10(gSavedSettings.getF32("LandBrushForce")));
@ -369,6 +348,22 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mFactoryMap["land info panel"] = LLCallbackMap(createPanelLandInfo, this);//LLPanelLandInfo
//Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_tools.xml",FALSE);
mCommitCallbackRegistrar.add("BuildTool.setTool", boost::bind(&LLFloaterTools::setTool,this, _2));
mCommitCallbackRegistrar.add("BuildTool.commitZoom", boost::bind(&commit_slider_zoom, _1));
mCommitCallbackRegistrar.add("BuildTool.commitRadioFocus", boost::bind(&commit_radio_group_focus, _1));
mCommitCallbackRegistrar.add("BuildTool.commitRadioMove", boost::bind(&commit_radio_group_move,_1));
mCommitCallbackRegistrar.add("BuildTool.commitRadioEdit", boost::bind(&commit_radio_group_edit,_1));
mCommitCallbackRegistrar.add("BuildTool.selectComponent", boost::bind(&commit_select_component, this));
mCommitCallbackRegistrar.add("BuildTool.gridOptions", boost::bind(&LLFloaterTools::onClickGridOptions,this));
mCommitCallbackRegistrar.add("BuildTool.applyToSelection", boost::bind(&click_apply_to_selection, this));
mCommitCallbackRegistrar.add("BuildTool.gridMode", boost::bind(&commit_grid_mode,_1));
mCommitCallbackRegistrar.add("BuildTool.commitRadioLand", boost::bind(&commit_radio_group_land,_1));
mCommitCallbackRegistrar.add("BuildTool.LandBrushForce", boost::bind(&commit_slider_dozer_force,_1));
mCommitCallbackRegistrar.add("BuildTool.AddMedia", boost::bind(&LLFloaterTools::onClickBtnAddMedia,this));
mCommitCallbackRegistrar.add("BuildTool.DeleteMedia", boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this));
mCommitCallbackRegistrar.add("BuildTool.EditMedia", boost::bind(&LLFloaterTools::onClickBtnEditMedia,this));
}
LLFloaterTools::~LLFloaterTools()
@ -427,6 +422,7 @@ void LLFloaterTools::refresh()
mPanelObject->refresh();
mPanelVolume->refresh();
mPanelFace->refresh();
refreshMedia();
mPanelContents->refresh();
mPanelLandInfo->refresh();
}
@ -756,6 +752,7 @@ void LLFloaterTools::onClose()
LLToolMgr::getInstance()->getCurrentToolset()->selectFirstTool();
//gMenuBarView->setItemVisible("BuildTools", FALSE);
LLFloaterReg::hideInstance("media_settings");
}
void click_popup_info(void*)
@ -767,7 +764,7 @@ void click_popup_done(void*)
handle_reset_view();
}
void commit_radio_group_move(LLUICtrl* ctrl, void* data)
void commit_radio_group_move(LLUICtrl* ctrl)
{
LLRadioGroup* group = (LLRadioGroup*)ctrl;
std::string selected = group->getValue().asString();
@ -788,7 +785,7 @@ void commit_radio_group_move(LLUICtrl* ctrl, void* data)
}
}
void commit_radio_group_focus(LLUICtrl* ctrl, void* data)
void commit_radio_group_focus(LLUICtrl* ctrl)
{
LLRadioGroup* group = (LLRadioGroup*)ctrl;
std::string selected = group->getValue().asString();
@ -812,7 +809,7 @@ void commit_radio_group_focus(LLUICtrl* ctrl, void* data)
}
}
void commit_slider_zoom(LLUICtrl *ctrl, void*)
void commit_slider_zoom(LLUICtrl *ctrl)
{
// renormalize value, since max "volume" level is 0.5 for some reason
F32 zoom_level = (F32)ctrl->getValue().asReal() * 2.f; // / 0.5f;
@ -837,26 +834,19 @@ void click_popup_rotate_right(void*)
dialog_refresh_all();
}
void commit_slider_dozer_size(LLUICtrl *ctrl, void*)
{
F32 size = (F32)ctrl->getValue().asReal();
gSavedSettings.setF32("LandBrushSize", size);
}
void commit_slider_dozer_force(LLUICtrl *ctrl, void*)
void commit_slider_dozer_force(LLUICtrl *ctrl)
{
// the slider is logarithmic, so we exponentiate to get the actual force multiplier
F32 dozer_force = pow(10.f, (F32)ctrl->getValue().asReal());
gSavedSettings.setF32("LandBrushForce", dozer_force);
}
void click_apply_to_selection(void* user)
void click_apply_to_selection(void*)
{
LLToolBrushLand::getInstance()->modifyLandInSelectionGlobal();
}
void commit_radio_group_edit(LLUICtrl *ctrl, void *data)
void commit_radio_group_edit(LLUICtrl *ctrl)
{
S32 show_owners = gSavedSettings.getBOOL("ShowParcelOwners");
@ -881,7 +871,7 @@ void commit_radio_group_edit(LLUICtrl *ctrl, void *data)
gSavedSettings.setBOOL("ShowParcelOwners", show_owners);
}
void commit_radio_group_land(LLUICtrl* ctrl, void* data)
void commit_radio_group_land(LLUICtrl* ctrl)
{
LLRadioGroup* group = (LLRadioGroup*)ctrl;
std::string selected = group->getValue().asString();
@ -909,7 +899,7 @@ void commit_radio_group_land(LLUICtrl* ctrl, void* data)
}
}
void commit_select_component(LLUICtrl *ctrl, void *data)
void commit_select_component(void *data)
{
LLFloaterTools* floaterp = (LLFloaterTools*)data;
@ -933,7 +923,7 @@ void commit_select_component(LLUICtrl *ctrl, void *data)
}
}
void commit_grid_mode(LLUICtrl *ctrl, void *data)
void commit_grid_mode(LLUICtrl *ctrl)
{
LLComboBox* combo = (LLComboBox*)ctrl;
@ -948,10 +938,9 @@ void LLFloaterTools::setObjectType( LLPCode pcode )
gFocusMgr.setMouseCapture(NULL);
}
// static
void LLFloaterTools::onClickGridOptions(void* data)
void LLFloaterTools::onClickGridOptions()
{
//LLFloaterTools* floaterp = (LLFloaterTools*)data;
LLFloaterReg::showInstance("build_options");
// RN: this makes grid options dependent on build tools window
//floaterp->addDependentFloater(LLFloaterBuildOptions::getInstance(), FALSE);
@ -964,8 +953,558 @@ void LLFloaterTools::setEditTool(void* tool_pointer)
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( tool );
}
void LLFloaterTools::setTool(const LLSD& user_data)
{
std::string control_name = user_data.asString();
if(control_name == "Focus")
LLToolMgr::getInstance()->getCurrentToolset()->selectTool((LLTool *) LLToolCamera::getInstance() );
else if (control_name == "Move" )
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *)LLToolGrab::getInstance() );
else if (control_name == "Edit" )
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompTranslate::getInstance());
else if (control_name == "Create" )
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompCreate::getInstance());
else if (control_name == "Land" )
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolSelectLand::getInstance());
else
llwarns<<" no parameter name "<<control_name<<" found!! No Tool selected!!"<< llendl;
}
void LLFloaterTools::onFocusReceived()
{
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
LLFloater::onFocusReceived();
}
// Media stuff
void LLFloaterTools::refreshMedia()
{
getMediaState();
LLFloaterMediaSettings::getInstance();
LLFloaterMediaSettings::initValues(mMediaSettings );
}
void LLFloaterTools::getMediaState()
{
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
if( !objectp )
{
childSetEnabled("media_tex", FALSE);
childSetEnabled("add_media", FALSE);
childSetEnabled("delete_media", FALSE);
childSetEnabled("edit_media", FALSE);
updateMediaSettings();
return;
}
bool editable = gAgent.isGodlike() || (objectp->permModify() && objectp->getPCode() == LL_PCODE_VOLUME);
// Media settings
U8 has_media = (U8)0;
struct media_functor : public LLSelectedTEGetFunctor<U8>
{
U8 get(LLViewerObject* object, S32 face)
{
return (object->getTE(face)->getMediaTexGen());
}
} func;
bool identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, has_media );
// update UI depending on whether "object" (prim or face) has media
// and whether or not you are allowed to edit it.
bool bool_has_media = (has_media & LLTextureEntry::MF_HAS_MEDIA);
childSetEnabled("media_tex", bool_has_media & editable);
childSetEnabled( "edit_media", bool_has_media & editable );
childSetEnabled( "delete_media", bool_has_media & editable );
childSetEnabled( "add_media", ( ! bool_has_media ) & editable );
// load values for media settings
updateMediaSettings();
// if identical is set, all faces are same
if ( identical )
{
// TODO: display a list of all media on the face - use 'identical' flag
};
}
//////////////////////////////////////////////////////////////////////////////
// called when a user wants to add media to a prim or prim face
void LLFloaterTools::onClickBtnAddMedia()
{
// check for the edit tool and now many faces are selected
LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
if((tool != LLToolFace::getInstance()) || LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
{
LLNotifications::instance().add("MultipleFacesSelected",LLSD(), LLSD(), multipleFacesSelectedConfirm);
}
else
{
onClickBtnEditMedia();
}
}
// static
bool LLFloaterTools::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
switch( option )
{
case 0: // "Yes"
gFloaterTools->onClickBtnEditMedia();
break;
case 1: // "No"
default:
break;
}
return false;
}
//////////////////////////////////////////////////////////////////////////////
// called when a user wants to edit existing media settings on a prim or prim face
// TODO: test if there is media on the item and only allow editing if present
void LLFloaterTools::onClickBtnEditMedia()
{
refreshMedia();
LLFloaterReg::showInstance("media_settings");
}
//////////////////////////////////////////////////////////////////////////////
// called when a user wants to delete media from a prim or prim face
void LLFloaterTools::onClickBtnDeleteMedia()
{
LLNotifications::instance().add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
}
// static
bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
switch( option )
{
case 0: // "Yes"
LLSelectMgr::getInstance()->selectionSetMedia( 0 );
if(LLFloaterReg::instanceVisible("media_settings"))
{
LLFloaterReg::hideInstance("media_settings");
}
break;
case 1: // "No"
default:
break;
}
return false;
}
//////////////////////////////////////////////////////////////////////////////
//
void LLFloaterTools::updateMediaSettings()
{
bool identical( false );
std::string base_key( "" );
std::string value_str( "" );
int value_int = 0;
bool value_bool = false;
LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
// TODO: (CP) refactor this using something clever or boost or both !!
LLMediaEntry default_media_data;
// controls
U8 value_u8 = default_media_data.getControls();
struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
{
U8 get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getControls();
LLMediaEntry default_media_data;
return default_media_data.getControls();
};
} func_controls;
identical = selected_objects->getSelectedTEValue( &func_controls, value_u8 );
base_key = std::string( LLMediaEntry::CONTROLS_KEY );
mMediaSettings[ base_key ] = value_u8;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// First click (formerly left click)
value_bool = default_media_data.getFirstClickInteract();
struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getFirstClickInteract();
LLMediaEntry default_media_data;
return default_media_data.getFirstClickInteract();
};
} func_first_click;
identical = selected_objects->getSelectedTEValue( &func_first_click, value_bool );
base_key = std::string( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Home URL
value_str = default_media_data.getHomeURL();
struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
{
std::string get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getHomeURL();
LLMediaEntry default_media_data;
return default_media_data.getHomeURL();
};
} func_home_url;
identical = selected_objects->getSelectedTEValue( &func_home_url, value_str );
base_key = std::string( LLMediaEntry::HOME_URL_KEY );
mMediaSettings[ base_key ] = value_str;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
llwarns<<"Angela debug : home url string == "<<value_str<<llendl;
// Current URL
value_str = default_media_data.getCurrentURL();
struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
{
std::string get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getCurrentURL();
LLMediaEntry default_media_data;
return default_media_data.getCurrentURL();
};
} func_current_url;
identical = selected_objects->getSelectedTEValue( &func_current_url, value_str );
base_key = std::string( LLMediaEntry::CURRENT_URL_KEY );
mMediaSettings[ base_key ] = value_str;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Auto zoom
value_bool = default_media_data.getAutoZoom();
struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getAutoZoom();
LLMediaEntry default_media_data;
return default_media_data.getAutoZoom();
};
} func_auto_zoom;
identical = selected_objects->getSelectedTEValue( &func_auto_zoom, value_bool );
base_key = std::string( LLMediaEntry::AUTO_ZOOM_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Auto play
value_bool = default_media_data.getAutoPlay();
struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getAutoPlay();
LLMediaEntry default_media_data;
return default_media_data.getAutoPlay();
};
} func_auto_play;
identical = selected_objects->getSelectedTEValue( &func_auto_play, value_bool );
base_key = std::string( LLMediaEntry::AUTO_PLAY_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Auto scale
value_bool = default_media_data.getAutoScale();
struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getAutoScale();
LLMediaEntry default_media_data;
return default_media_data.getAutoScale();;
};
} func_auto_scale;
identical = selected_objects->getSelectedTEValue( &func_auto_scale, value_bool );
base_key = std::string( LLMediaEntry::AUTO_SCALE_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Auto loop
value_bool = default_media_data.getAutoLoop();
struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getAutoLoop();
LLMediaEntry default_media_data;
return default_media_data.getAutoLoop();
};
} func_auto_loop;
identical = selected_objects->getSelectedTEValue( &func_auto_loop, value_bool );
base_key = std::string( LLMediaEntry::AUTO_LOOP_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// width pixels (if not auto scaled)
value_int = default_media_data.getWidthPixels();
struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >
{
int get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getWidthPixels();
LLMediaEntry default_media_data;
return default_media_data.getWidthPixels();
};
} func_width_pixels;
identical = selected_objects->getSelectedTEValue( &func_width_pixels, value_int );
base_key = std::string( LLMediaEntry::WIDTH_PIXELS_KEY );
mMediaSettings[ base_key ] = value_int;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// height pixels (if not auto scaled)
value_int = default_media_data.getHeightPixels();
struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >
{
int get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getHeightPixels();
LLMediaEntry default_media_data;
return default_media_data.getHeightPixels();
};
} func_height_pixels;
identical = selected_objects->getSelectedTEValue( &func_height_pixels, value_int );
base_key = std::string( LLMediaEntry::HEIGHT_PIXELS_KEY );
mMediaSettings[ base_key ] = value_int;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Enable Alt image
value_bool = default_media_data.getAltImageEnable();
struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getAltImageEnable();
LLMediaEntry default_media_data;
return default_media_data.getAltImageEnable();
};
} func_enable_alt_image;
identical = selected_objects->getSelectedTEValue( &func_enable_alt_image, value_bool );
base_key = std::string( LLMediaEntry::ALT_IMAGE_ENABLE_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Perms - owner interact
value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER );
struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER));
LLMediaEntry default_media_data;
return 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER );
};
} func_perms_owner_interact;
identical = selected_objects->getSelectedTEValue( &func_perms_owner_interact, value_bool );
base_key = std::string( LLPanelContents::PERMS_OWNER_INTERACT_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Perms - owner control
value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER );
struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER));
LLMediaEntry default_media_data;
return 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER );
};
} func_perms_owner_control;
identical = selected_objects ->getSelectedTEValue( &func_perms_owner_control, value_bool );
base_key = std::string( LLPanelContents::PERMS_OWNER_CONTROL_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Perms - group interact
value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP );
struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP));
LLMediaEntry default_media_data;
return 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP );
};
} func_perms_group_interact;
identical = selected_objects->getSelectedTEValue( &func_perms_group_interact, value_bool );
base_key = std::string( LLPanelContents::PERMS_GROUP_INTERACT_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Perms - group control
value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP );
struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP));
LLMediaEntry default_media_data;
return 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP );
};
} func_perms_group_control;
identical = selected_objects->getSelectedTEValue( &func_perms_group_control, value_bool );
base_key = std::string( LLPanelContents::PERMS_GROUP_CONTROL_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Perms - anyone interact
value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE));
LLMediaEntry default_media_data;
return 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
};
} func_perms_anyone_interact;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_perms_anyone_interact, value_bool );
base_key = std::string( LLPanelContents::PERMS_ANYONE_INTERACT_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Perms - anyone control
value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE );
struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE));
LLMediaEntry default_media_data;
return 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE );
};
} func_perms_anyone_control;
identical = selected_objects->getSelectedTEValue( &func_perms_anyone_control, value_bool );
base_key = std::string( LLPanelContents::PERMS_ANYONE_CONTROL_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// security - whitelist enable
value_bool = default_media_data.getWhiteListEnable();
struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getWhiteListEnable();
LLMediaEntry default_media_data;
return default_media_data.getWhiteListEnable();
};
} func_whitelist_enable;
identical = selected_objects->getSelectedTEValue( &func_whitelist_enable, value_bool );
base_key = std::string( LLMediaEntry::WHITELIST_ENABLE_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// security - whitelist URLs
std::vector<std::string> value_vector_str = default_media_data.getWhiteList();
struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> >
{
std::vector<std::string> get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getWhiteList();
LLMediaEntry default_media_data;
return default_media_data.getWhiteList();
};
} func_whitelist_urls;
identical = selected_objects->getSelectedTEValue( &func_whitelist_urls, value_vector_str );
base_key = std::string( LLMediaEntry::WHITELIST_KEY );
mMediaSettings[ base_key ].clear();
std::vector< std::string >::iterator iter = value_vector_str.begin();
while( iter != value_vector_str.end() )
{
std::string white_list_url = *iter;
mMediaSettings[ base_key ].append( white_list_url );
++iter;
};
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
}

View File

@ -100,13 +100,24 @@ public:
void setStatusText(const std::string& text);
static void setEditTool(void* data);
void setTool(const LLSD& user_data);
void saveLastTool();
void onClickBtnDeleteMedia();
void onClickBtnAddMedia();
void onClickBtnEditMedia();
private:
void onClose();
void refresh();
void refreshMedia();
void getMediaState();
void updateMediaSettings();
void getMeidaState();
static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
static void setObjectType( LLPCode pcode );
static void onClickGridOptions(void* data);
void onClickGridOptions();
public:
LLButton *mBtnFocus;
@ -175,6 +186,10 @@ private:
BOOL mDirty;
std::map<std::string, std::string> mStatusText;
protected:
LLSD mMediaSettings;
};
extern LLFloaterTools *gFloaterTools;

View File

@ -35,6 +35,7 @@
#include "llfloaterurlentry.h"
#include "llpanellandmedia.h"
#include "llpanelface.h"
// project includes
#include "llcombobox.h"
@ -145,13 +146,23 @@ void LLFloaterURLEntry::buildURLHistory()
void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_type)
{
LLPanelLandMedia* panel_media = (LLPanelLandMedia*)mPanelLandMediaHandle.get();
LLPanelLandMedia* panel_media = dynamic_cast<LLPanelLandMedia*>(mPanelLandMediaHandle.get());
if (panel_media)
{
// status is ignored for now -- error = "none/none"
panel_media->setMediaType(mime_type);
panel_media->setMediaURL(mMediaURLEdit->getValue().asString());
}
else
{
LLPanelFace* panel_face = dynamic_cast<LLPanelFace*>(mPanelLandMediaHandle.get());
if(panel_face)
{
panel_face->setMediaType(mime_type);
panel_face->setMediaURL(mMediaURLEdit->getValue().asString());
}
}
// Decrement the cursor
getWindow()->decBusyCount();
childSetVisible("loading_label", false);
@ -159,29 +170,18 @@ void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_
}
// static
LLHandle<LLFloater> LLFloaterURLEntry::show(LLHandle<LLPanel> parent)
LLHandle<LLFloater> LLFloaterURLEntry::show(LLHandle<LLPanel> parent, const std::string media_url)
{
if (sInstance)
{
sInstance->openFloater();
}
else
if (!sInstance)
{
sInstance = new LLFloaterURLEntry(parent);
}
sInstance->updateFromLandMediaPanel();
sInstance->openFloater();
sInstance->addURLToCombobox(media_url);
return sInstance->getHandle();
}
void LLFloaterURLEntry::updateFromLandMediaPanel()
{
LLPanelLandMedia* panel_media = (LLPanelLandMedia*)mPanelLandMediaHandle.get();
if (panel_media)
{
std::string media_url = panel_media->getMediaURL();
addURLToCombobox(media_url);
}
}
bool LLFloaterURLEntry::addURLToCombobox(const std::string& media_url)
{

View File

@ -44,10 +44,8 @@ class LLFloaterURLEntry : public LLFloater
public:
// Can only be shown by LLPanelLandMedia, and pushes data back into
// that panel via the handle.
static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle);
static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle, const std::string media_url);
/*virtual*/ BOOL postBuild();
void updateFromLandMediaPanel();
void headerFetchComplete(U32 status, const std::string& mime_type);
bool addURLToCombobox(const std::string& media_url);

View File

@ -0,0 +1,97 @@
/**
* @file llfloaterwhitelistentry.cpp
* @brief LLFloaterWhistListEntry class implementation
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterreg.h"
#include "llfloatermediasettings.h"
#include "llfloaterwhitelistentry.h"
#include "llpanelmediasettingssecurity.h"
#include "lluictrlfactory.h"
#include "llwindow.h"
#include "llviewerwindow.h"
#include "lllineeditor.h"
///////////////////////////////////////////////////////////////////////////////
//
LLFloaterWhiteListEntry::LLFloaterWhiteListEntry( const LLSD& key ) :
LLFloater(key)
{
// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_whitelist_entry.xml");
}
///////////////////////////////////////////////////////////////////////////////
//
LLFloaterWhiteListEntry::~LLFloaterWhiteListEntry()
{
}
///////////////////////////////////////////////////////////////////////////////
//
BOOL LLFloaterWhiteListEntry::postBuild()
{
mWhiteListEdit = getChild<LLLineEditor>("whitelist_entry");
childSetAction("cancel_btn", onBtnCancel, this);
childSetAction("ok_btn", onBtnOK, this);
setDefaultBtn("ok_btn");
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// static
void LLFloaterWhiteListEntry::onBtnOK( void* userdata )
{
LLFloaterWhiteListEntry *self =(LLFloaterWhiteListEntry *)userdata;
LLPanelMediaSettingsSecurity* panel = LLFloaterReg::getTypedInstance<LLFloaterMediaSettings>("media_settings")->getPanelSecurity();
if ( panel )
{
std::string white_list_item = self->mWhiteListEdit->getText();
panel->addWhiteListItem( white_list_item );
};
self->closeFloater();
}
///////////////////////////////////////////////////////////////////////////////
// static
void LLFloaterWhiteListEntry::onBtnCancel( void* userdata )
{
LLFloaterWhiteListEntry *self =(LLFloaterWhiteListEntry *)userdata;
self->closeFloater();
}

View File

@ -0,0 +1,56 @@
/**
* @file llfloaterwhitelistentry.h
* @brief LLFloaterWhiteListEntry class definition
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERWHITELISTENTRY_H
#define LL_LLFLOATERWHITELISTENTRY_H
#include "llfloater.h"
class LLLineEditor;
class LLFloaterWhiteListEntry :
public LLFloater
{
public:
LLFloaterWhiteListEntry(const LLSD& key);
~LLFloaterWhiteListEntry();
BOOL postBuild();
private:
LLLineEditor* mWhiteListEdit;
static void onBtnOK(void*);
static void onBtnCancel(void*);
};
#endif // LL_LLFLOATERWHITELISTENTRY_H

Some files were not shown because too many files have changed in this diff Show More