diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index 2348f152b..b3a02e410 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -244,15 +244,11 @@ protected: virtual void dirtyMesh(S32 priority) = 0; // Dirty the avatar mesh, with priority protected: + friend class WavefrontSaver; typedef std::multimap polymesh_map_t; polymesh_map_t mPolyMeshes; avatar_joint_list_t mMeshLOD; -// -public: - const virtual avatar_joint_list_t& getMeshLOD() const { return mMeshLOD; } -// - /** Meshes ** ** *******************************************************************************/ diff --git a/indra/llappearance/llavatarjointmesh.h b/indra/llappearance/llavatarjointmesh.h index 90a0a5725..53b82c50a 100644 --- a/indra/llappearance/llavatarjointmesh.h +++ b/indra/llappearance/llavatarjointmesh.h @@ -62,6 +62,7 @@ public: class LLAvatarJointMesh : public virtual LLAvatarJoint { protected: + friend class WavefrontSaver; LLColor4 mColor; // color value // LLColor4 mSpecular; // specular color (always white for now) F32 mShiny; // shiny value @@ -131,10 +132,6 @@ public: void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; } - // -public: - LLFace* getFace() { return mFace; } - // private: // Allocate skin data BOOL allocateSkinData( U32 numSkinJoints ); diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index 05e59d51f..3f0e8dd6c 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -63,6 +63,7 @@ enum LAND_STAT_FLAGS STAT_FILTER_BY_PARCEL = 0x00000001, STAT_FILTER_BY_OWNER = 0x00000002, STAT_FILTER_BY_OBJECT = 0x00000004, + STAT_FILTER_BY_PARCEL_NAME = 0x00000008, STAT_REQUEST_LAST_ENTRY = 0x80000000, }; diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index 9397701f8..aaf5bf8e1 100644 --- a/indra/llmessage/aihttptimeoutpolicy.cpp +++ b/indra/llmessage/aihttptimeoutpolicy.cpp @@ -940,7 +940,6 @@ P2(groupMemberDataResponder, transfer_300s); P2(groupProposalBallotResponder, transfer_300s); P(homeLocationResponder); P2(HTTPGetResponder, reply_15s); -P(iamHereLogin); P(iamHere); P(iamHereVoice); P2(inventoryModelFetchDescendentsResponder, transfer_300s); @@ -949,6 +948,7 @@ P(lcl_responder); P(MPImportGetResponder); P(MPImportPostResponder); P(mapLayerResponder); +P(materialsResponder); P2(maturityPreferences, transfer_30s_connect_10s); P(mediaDataClientResponder); P(mediaTypeResponder); diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 0234c9e59..e9478bb06 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -20,6 +20,8 @@ include_directories( ) set(llprimitive_SOURCE_FILES + llmaterialid.cpp + llmaterial.cpp llmaterialtable.cpp llmediaentry.cpp llmodel.cpp @@ -37,6 +39,8 @@ set(llprimitive_HEADER_FILES CMakeLists.txt legacy_object_types.h + llmaterial.h + llmaterialid.h llmaterialtable.h llmediaentry.h llmodel.h diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp new file mode 100644 index 000000000..cf4c645cf --- /dev/null +++ b/indra/llprimitive/llmaterial.cpp @@ -0,0 +1,227 @@ +/** + * @file llmaterial.cpp + * @brief Material definition + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llmaterial.h" + +/** + * Materials cap parameters + */ +#define MATERIALS_CAP_NORMAL_MAP_FIELD "NormMap" +#define MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD "NormOffsetX" +#define MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD "NormOffsetY" +#define MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD "NormRepeatX" +#define MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD "NormRepeatY" +#define MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD "NormRotation" + +#define MATERIALS_CAP_SPECULAR_MAP_FIELD "SpecMap" +#define MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD "SpecOffsetX" +#define MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD "SpecOffsetY" +#define MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD "SpecRepeatX" +#define MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD "SpecRepeatY" +#define MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD "SpecRotation" + +#define MATERIALS_CAP_SPECULAR_COLOR_FIELD "SpecColor" +#define MATERIALS_CAP_SPECULAR_EXP_FIELD "SpecExp" +#define MATERIALS_CAP_ENV_INTENSITY_FIELD "EnvIntensity" +#define MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD "AlphaMaskCutoff" +#define MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD "DiffuseAlphaMode" + +const LLColor4U LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR(255,255,255,255); + +/** + * Materials constants + */ + +const F32 MATERIALS_MULTIPLIER = 10000.f; + +/** + * Helper functions + */ + +template T getMaterialField(const LLSD& data, const std::string& field, const LLSD::Type field_type) +{ + if ( (data.has(field)) && (field_type == data[field].type()) ) + { + return (T)data[field]; + } + llerrs << "Missing or mistyped field '" << field << "' in material definition" << llendl; + return (T)LLSD(); +} + +// GCC didn't like the generic form above for some reason +template<> LLUUID getMaterialField(const LLSD& data, const std::string& field, const LLSD::Type field_type) +{ + if ( (data.has(field)) && (field_type == data[field].type()) ) + { + return data[field].asUUID(); + } + llerrs << "Missing or mistyped field '" << field << "' in material definition" << llendl; + return LLUUID::null; +} + +/** + * LLMaterial class + */ + +const LLMaterial LLMaterial::null; + +LLMaterial::LLMaterial() + : mNormalOffsetX(0.0f) + , mNormalOffsetY(0.0f) + , mNormalRepeatX(1.0f) + , mNormalRepeatY(1.0f) + , mNormalRotation(0.0f) + , mSpecularOffsetX(0.0f) + , mSpecularOffsetY(0.0f) + , mSpecularRepeatX(1.0f) + , mSpecularRepeatY(1.0f) + , mSpecularRotation(0.0f) + , mSpecularLightColor(LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR) + , mSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT) + , mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY) + , mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) + , mAlphaMaskCutoff(0) +{ +} + +LLMaterial::LLMaterial(const LLSD& material_data) +{ + fromLLSD(material_data); +} + +LLSD LLMaterial::asLLSD() const +{ + LLSD material_data; + + material_data[MATERIALS_CAP_NORMAL_MAP_FIELD] = mNormalID; + material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD] = llround(mNormalOffsetX * MATERIALS_MULTIPLIER); + material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD] = llround(mNormalOffsetY * MATERIALS_MULTIPLIER); + material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD] = llround(mNormalRepeatX * MATERIALS_MULTIPLIER); + material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD] = llround(mNormalRepeatY * MATERIALS_MULTIPLIER); + material_data[MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD] = llround(mNormalRotation * MATERIALS_MULTIPLIER); + + material_data[MATERIALS_CAP_SPECULAR_MAP_FIELD] = mSpecularID; + material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD] = llround(mSpecularOffsetX * MATERIALS_MULTIPLIER); + material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD] = llround(mSpecularOffsetY * MATERIALS_MULTIPLIER); + material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD] = llround(mSpecularRepeatX * MATERIALS_MULTIPLIER); + material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD] = llround(mSpecularRepeatY * MATERIALS_MULTIPLIER); + material_data[MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD] = llround(mSpecularRotation * MATERIALS_MULTIPLIER); + + material_data[MATERIALS_CAP_SPECULAR_COLOR_FIELD] = mSpecularLightColor.getValue(); + material_data[MATERIALS_CAP_SPECULAR_EXP_FIELD] = mSpecularLightExponent; + material_data[MATERIALS_CAP_ENV_INTENSITY_FIELD] = mEnvironmentIntensity; + material_data[MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD] = mDiffuseAlphaMode; + material_data[MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD] = mAlphaMaskCutoff; + + return material_data; +} + +void LLMaterial::fromLLSD(const LLSD& material_data) +{ + mNormalID = getMaterialField(material_data, MATERIALS_CAP_NORMAL_MAP_FIELD, LLSD::TypeUUID); + mNormalOffsetX = (F32)getMaterialField(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; + mNormalOffsetY = (F32)getMaterialField(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; + mNormalRepeatX = (F32)getMaterialField(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; + mNormalRepeatY = (F32)getMaterialField(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; + mNormalRotation = (F32)getMaterialField(material_data, MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; + + mSpecularID = getMaterialField(material_data, MATERIALS_CAP_SPECULAR_MAP_FIELD, LLSD::TypeUUID); + mSpecularOffsetX = (F32)getMaterialField(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; + mSpecularOffsetY = (F32)getMaterialField(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; + mSpecularRepeatX = (F32)getMaterialField(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; + mSpecularRepeatY = (F32)getMaterialField(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; + mSpecularRotation = (F32)getMaterialField(material_data, MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER; + + mSpecularLightColor.setValue(getMaterialField(material_data, MATERIALS_CAP_SPECULAR_COLOR_FIELD, LLSD::TypeArray)); + mSpecularLightExponent = (U8)getMaterialField(material_data, MATERIALS_CAP_SPECULAR_EXP_FIELD, LLSD::TypeInteger); + mEnvironmentIntensity = (U8)getMaterialField(material_data, MATERIALS_CAP_ENV_INTENSITY_FIELD, LLSD::TypeInteger); + mDiffuseAlphaMode = (U8)getMaterialField(material_data, MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD, LLSD::TypeInteger); + mAlphaMaskCutoff = (U8)getMaterialField(material_data, MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD, LLSD::TypeInteger); +} + +bool LLMaterial::isNull() const +{ + return (*this == null); +} + +bool LLMaterial::operator == (const LLMaterial& rhs) const +{ + return + (mNormalID == rhs.mNormalID) && (mNormalOffsetX == rhs.mNormalOffsetX) && (mNormalOffsetY == rhs.mNormalOffsetY) && + (mNormalRepeatX == rhs.mNormalRepeatX) && (mNormalRepeatY == rhs.mNormalRepeatY) && (mNormalRotation == rhs.mNormalRotation) && + (mSpecularID == rhs.mSpecularID) && (mSpecularOffsetX == rhs.mSpecularOffsetX) && (mSpecularOffsetY == rhs.mSpecularOffsetY) && + (mSpecularRepeatX == rhs.mSpecularRepeatX) && (mSpecularRepeatY == rhs.mSpecularRepeatY) && (mSpecularRotation == rhs.mSpecularRotation) && + (mSpecularLightColor == rhs.mSpecularLightColor) && (mSpecularLightExponent == rhs.mSpecularLightExponent) && + (mEnvironmentIntensity == rhs.mEnvironmentIntensity) && (mDiffuseAlphaMode == rhs.mDiffuseAlphaMode) && (mAlphaMaskCutoff == rhs.mAlphaMaskCutoff); +} + +bool LLMaterial::operator != (const LLMaterial& rhs) const +{ + return !(*this == rhs); +} + + +U32 LLMaterial::getShaderMask(U32 alpha_mode) +{ //NEVER incorporate this value into the message system -- this function will vary depending on viewer implementation + U32 ret = 0; + + //two least significant bits are "diffuse alpha mode" + if (alpha_mode != DIFFUSE_ALPHA_MODE_DEFAULT) + { + ret = alpha_mode; + } + else + { + ret = getDiffuseAlphaMode(); + } + + llassert(ret < SHADER_COUNT); + + //next bit is whether or not specular map is present + const U32 SPEC_BIT = 0x4; + + if (getSpecularID().notNull()) + { + ret |= SPEC_BIT; + } + + llassert(ret < SHADER_COUNT); + + //next bit is whether or not normal map is present + const U32 NORM_BIT = 0x8; + if (getNormalID().notNull()) + { + ret |= NORM_BIT; + } + + llassert(ret < SHADER_COUNT); + + return ret; +} + + diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h new file mode 100644 index 000000000..9f52a3f6c --- /dev/null +++ b/indra/llprimitive/llmaterial.h @@ -0,0 +1,155 @@ +/** + * @file llmaterial.h + * @brief Material definition + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLMATERIAL_H +#define LL_LLMATERIAL_H + +#include + +#include "llmaterialid.h" +#include "llsd.h" +#include "v4coloru.h" +#include "llpointer.h" +#include "llrefcount.h" + +class LLMaterial : public LLRefCount +{ +public: + + typedef enum + { + DIFFUSE_ALPHA_MODE_NONE = 0, + DIFFUSE_ALPHA_MODE_BLEND = 1, + DIFFUSE_ALPHA_MODE_MASK = 2, + DIFFUSE_ALPHA_MODE_EMISSIVE = 3, + DIFFUSE_ALPHA_MODE_DEFAULT = 4, + } eDiffuseAlphaMode; + + typedef enum + { + SHADER_COUNT = 16, + ALPHA_SHADER_COUNT = 4 + } eShaderCount; + + + + static const U8 DEFAULT_SPECULAR_LIGHT_EXPONENT = ((U8)(0.2f * 255)); + static const LLColor4U DEFAULT_SPECULAR_LIGHT_COLOR; + static const U8 DEFAULT_ENV_INTENSITY = 0; + + LLMaterial(); + LLMaterial(const LLSD& material_data); + + LLSD asLLSD() const; + void fromLLSD(const LLSD& material_data); + + const LLUUID& getNormalID() const { return mNormalID; } + void setNormalID(const LLUUID& normal_id) { mNormalID = normal_id; } + void getNormalOffset(F32& offset_x, F32& offset_y) const { offset_x = mNormalOffsetX; offset_y = mNormalOffsetY; } + F32 getNormalOffsetX() const { return mNormalOffsetX; } + F32 getNormalOffsetY() const { return mNormalOffsetY; } + + void setNormalOffset(F32 offset_x, F32 offset_y) { mNormalOffsetX = offset_x; mNormalOffsetY = offset_y; } + void setNormalOffsetX(F32 offset_x) { mNormalOffsetX = offset_x; } + void setNormalOffsetY(F32 offset_y) { mNormalOffsetY = offset_y; } + + void getNormalRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mNormalRepeatX; repeat_y = mNormalRepeatY; } + F32 getNormalRepeatX() const { return mNormalRepeatX; } + F32 getNormalRepeatY() const { return mNormalRepeatY; } + + void setNormalRepeat(F32 repeat_x, F32 repeat_y) { mNormalRepeatX = repeat_x; mNormalRepeatY = repeat_y; } + void setNormalRepeatX(F32 repeat_x) { mNormalRepeatX = repeat_x; } + void setNormalRepeatY(F32 repeat_y) { mNormalRepeatY = repeat_y; } + + F32 getNormalRotation() const { return mNormalRotation; } + void setNormalRotation(F32 rot) { mNormalRotation = rot; } + + const LLUUID& getSpecularID() const { return mSpecularID; } + void setSpecularID(const LLUUID& specular_id) { mSpecularID = specular_id; } + void getSpecularOffset(F32& offset_x, F32& offset_y) const { offset_x = mSpecularOffsetX; offset_y = mSpecularOffsetY; } + F32 getSpecularOffsetX() const { return mSpecularOffsetX; } + F32 getSpecularOffsetY() const { return mSpecularOffsetY; } + + void setSpecularOffset(F32 offset_x, F32 offset_y) { mSpecularOffsetX = offset_x; mSpecularOffsetY = offset_y; } + void setSpecularOffsetX(F32 offset_x) { mSpecularOffsetX = offset_x; } + void setSpecularOffsetY(F32 offset_y) { mSpecularOffsetY = offset_y; } + + void getSpecularRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mSpecularRepeatX; repeat_y = mSpecularRepeatY; } + F32 getSpecularRepeatX() const { return mSpecularRepeatX; } + F32 getSpecularRepeatY() const { return mSpecularRepeatY; } + + void setSpecularRepeat(F32 repeat_x, F32 repeat_y) { mSpecularRepeatX = repeat_x; mSpecularRepeatY = repeat_y; } + void setSpecularRepeatX(F32 repeat_x) { mSpecularRepeatX = repeat_x; } + void setSpecularRepeatY(F32 repeat_y) { mSpecularRepeatY = repeat_y; } + + F32 getSpecularRotation() const { return mSpecularRotation; } + void setSpecularRotation(F32 rot) { mSpecularRotation = rot; } + + const LLColor4U getSpecularLightColor() const { return mSpecularLightColor; } + void setSpecularLightColor(const LLColor4U& color) { mSpecularLightColor = color; } + U8 getSpecularLightExponent() const { return mSpecularLightExponent; } + void setSpecularLightExponent(U8 exponent) { mSpecularLightExponent = exponent; } + U8 getEnvironmentIntensity() const { return mEnvironmentIntensity; } + void setEnvironmentIntensity(U8 intensity) { mEnvironmentIntensity = intensity; } + U8 getDiffuseAlphaMode() const { return mDiffuseAlphaMode; } + void setDiffuseAlphaMode(U8 alpha_mode) { mDiffuseAlphaMode = alpha_mode; } + U8 getAlphaMaskCutoff() const { return mAlphaMaskCutoff; } + void setAlphaMaskCutoff(U8 cutoff) { mAlphaMaskCutoff = cutoff; } + + bool isNull() const; + static const LLMaterial null; + + bool operator == (const LLMaterial& rhs) const; + bool operator != (const LLMaterial& rhs) const; + + U32 getShaderMask(U32 alpha_mode = DIFFUSE_ALPHA_MODE_DEFAULT); + +protected: + LLUUID mNormalID; + F32 mNormalOffsetX; + F32 mNormalOffsetY; + F32 mNormalRepeatX; + F32 mNormalRepeatY; + F32 mNormalRotation; + + LLUUID mSpecularID; + F32 mSpecularOffsetX; + F32 mSpecularOffsetY; + F32 mSpecularRepeatX; + F32 mSpecularRepeatY; + F32 mSpecularRotation; + + LLColor4U mSpecularLightColor; + U8 mSpecularLightExponent; + U8 mEnvironmentIntensity; + U8 mDiffuseAlphaMode; + U8 mAlphaMaskCutoff; +}; + +typedef LLPointer LLMaterialPtr; + +#endif // LL_LLMATERIAL_H + diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp new file mode 100644 index 000000000..820f62c43 --- /dev/null +++ b/indra/llprimitive/llmaterialid.cpp @@ -0,0 +1,183 @@ +/** +* @file llmaterialid.cpp +* @brief Implementation of llmaterialid +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "linden_common.h" + +#include "llmaterialid.h" + +#include + +#include "llformat.h" + +const LLMaterialID LLMaterialID::null; + +LLMaterialID::LLMaterialID() +{ + clear(); +} + +LLMaterialID::LLMaterialID(const LLSD& pMaterialID) +{ + llassert(pMaterialID.isBinary()); + parseFromBinary(pMaterialID.asBinary()); +} + +LLMaterialID::LLMaterialID(const LLSD::Binary& pMaterialID) +{ + parseFromBinary(pMaterialID); +} + +LLMaterialID::LLMaterialID(const void* pMemory) +{ + set(pMemory); +} + +LLMaterialID::LLMaterialID(const LLMaterialID& pOtherMaterialID) +{ + copyFromOtherMaterialID(pOtherMaterialID); +} + +LLMaterialID::~LLMaterialID() +{ +} + +bool LLMaterialID::operator == (const LLMaterialID& pOtherMaterialID) const +{ + return (compareToOtherMaterialID(pOtherMaterialID) == 0); +} + +bool LLMaterialID::operator != (const LLMaterialID& pOtherMaterialID) const +{ + return (compareToOtherMaterialID(pOtherMaterialID) != 0); +} + +bool LLMaterialID::operator < (const LLMaterialID& pOtherMaterialID) const +{ + return (compareToOtherMaterialID(pOtherMaterialID) < 0); +} + +bool LLMaterialID::operator <= (const LLMaterialID& pOtherMaterialID) const +{ + return (compareToOtherMaterialID(pOtherMaterialID) <= 0); +} + +bool LLMaterialID::operator > (const LLMaterialID& pOtherMaterialID) const +{ + return (compareToOtherMaterialID(pOtherMaterialID) > 0); +} + +bool LLMaterialID::operator >= (const LLMaterialID& pOtherMaterialID) const +{ + return (compareToOtherMaterialID(pOtherMaterialID) >= 0); +} + +LLMaterialID& LLMaterialID::operator = (const LLMaterialID& pOtherMaterialID) +{ + copyFromOtherMaterialID(pOtherMaterialID); + return (*this); +} + +bool LLMaterialID::isNull() const +{ + return (compareToOtherMaterialID(LLMaterialID::null) == 0); +} + +const U8* LLMaterialID::get() const +{ + return mID; +} + +void LLMaterialID::set(const void* pMemory) +{ + llassert(pMemory != NULL); + + // assumes that the required size of memory is available + memcpy(mID, pMemory, MATERIAL_ID_SIZE * sizeof(U8)); +} + +void LLMaterialID::clear() +{ + memset(mID, 0, MATERIAL_ID_SIZE * sizeof(U8)); +} + +LLSD LLMaterialID::asLLSD() const +{ + LLSD::Binary materialIDBinary; + + materialIDBinary.resize(MATERIAL_ID_SIZE * sizeof(U8)); + memcpy(materialIDBinary.data(), mID, MATERIAL_ID_SIZE * sizeof(U8)); + + LLSD materialID = materialIDBinary; + return materialID; +} + +std::string LLMaterialID::asString() const +{ + std::string materialIDString; + for (unsigned int i = 0U; i < static_cast(MATERIAL_ID_SIZE / sizeof(U32)); ++i) + { + if (i != 0U) + { + materialIDString += "-"; + } + const U32 *value = reinterpret_cast(&get()[i * sizeof(U32)]); + materialIDString += llformat("%08x", *value); + } + return materialIDString; +} + +std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id) +{ + s << material_id.asString(); + return s; +} + + +void LLMaterialID::parseFromBinary (const LLSD::Binary& pMaterialID) +{ + llassert(pMaterialID.size() == (MATERIAL_ID_SIZE * sizeof(U8))); + memcpy(mID, &pMaterialID[0], MATERIAL_ID_SIZE * sizeof(U8)); +} + +void LLMaterialID::copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID) +{ + memcpy(mID, pOtherMaterialID.get(), MATERIAL_ID_SIZE * sizeof(U8)); +} + +int LLMaterialID::compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const +{ + int retVal = 0; + + for (unsigned int i = 0U; (retVal == 0) && (i < static_cast(MATERIAL_ID_SIZE / sizeof(U32))); ++i) + { + const U32 *thisValue = reinterpret_cast(&get()[i * sizeof(U32)]); + const U32 *otherValue = reinterpret_cast(&pOtherMaterialID.get()[i * sizeof(U32)]); + retVal = ((*thisValue < *otherValue) ? -1 : ((*thisValue > *otherValue) ? 1 : 0)); + } + + return retVal; +} diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h new file mode 100644 index 000000000..0a9520408 --- /dev/null +++ b/indra/llprimitive/llmaterialid.h @@ -0,0 +1,76 @@ +/** +* @file llmaterialid.h +* @brief Header file for llmaterialid +* @author Stinson@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ +#ifndef LL_LLMATERIALID_H +#define LL_LLMATERIALID_H + +#define MATERIAL_ID_SIZE 16 + +#include + +class LLMaterialID +{ +public: + LLMaterialID(); + LLMaterialID(const LLSD& pMaterialID); + LLMaterialID(const LLSD::Binary& pMaterialID); + LLMaterialID(const void* pMemory); + LLMaterialID(const LLMaterialID& pOtherMaterialID); + ~LLMaterialID(); + + bool operator == (const LLMaterialID& pOtherMaterialID) const; + bool operator != (const LLMaterialID& pOtherMaterialID) const; + + bool operator < (const LLMaterialID& pOtherMaterialID) const; + bool operator <= (const LLMaterialID& pOtherMaterialID) const; + bool operator > (const LLMaterialID& pOtherMaterialID) const; + bool operator >= (const LLMaterialID& pOtherMaterialID) const; + + LLMaterialID& operator = (const LLMaterialID& pOtherMaterialID); + + bool isNull() const; + + const U8* get() const; + void set(const void* pMemory); + void clear(); + + LLSD asLLSD() const; + std::string asString() const; + + friend std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id); + + static const LLMaterialID null; + +private: + void parseFromBinary(const LLSD::Binary& pMaterialID); + void copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID); + int compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const; + + U8 mID[MATERIAL_ID_SIZE]; +} ; + +#endif // LL_LLMATERIALID_H + diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index e038a7a52..36969d27c 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -309,6 +309,15 @@ S32 LLPrimitive::setTERotation(const U8 index, const F32 r) return mTextureList.setRotation(index, r); } +S32 LLPrimitive::setTEMaterialID(const U8 index, const LLMaterialID& pMaterialID) +{ + return mTextureList.setMaterialID(index, pMaterialID); +} + +S32 LLPrimitive::setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams) +{ + return mTextureList.setMaterialParams(index, pMaterialParams); +} //=============================================================== S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump) @@ -356,6 +365,23 @@ S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow) return mTextureList.setGlow(index, glow); } +void LLPrimitive::setAllTESelected(bool sel) +{ + for (int i = 0, cnt = getNumTEs(); i < cnt; i++) + { + setTESelected(i, sel); + } +} + +void LLPrimitive::setTESelected(const U8 te, bool sel) +{ + LLTextureEntry* tep = getTE(te); + if ( (tep) && (tep->setSelected(sel)) && (!sel) && (tep->hasPendingMaterialUpdate()) ) + { + LLMaterialID material_id = tep->getMaterialID(); + setTEMaterialID(te, material_id); + } +} LLPCode LLPrimitive::legacyToPCode(const U8 legacy) { @@ -1080,6 +1106,7 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const U8 bump[MAX_TES]; U8 media_flags[MAX_TES]; U8 glow[MAX_TES]; + U8 material_data[MAX_TES*16]; const U32 MAX_TE_BUFFER = 4096; U8 packed_buffer[MAX_TE_BUFFER]; @@ -1117,6 +1144,9 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const bump[face_index] = te->getBumpShinyFullbright(); media_flags[face_index] = te->getMediaTexGen(); glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF)); + + // Directly sending material_ids is not safe! + memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */ } cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID); @@ -1138,6 +1168,8 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8); *cur_ptr++ = 0; cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID); } mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer)); @@ -1159,6 +1191,7 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const U8 bump[MAX_TES]; U8 media_flags[MAX_TES]; U8 glow[MAX_TES]; + U8 material_data[MAX_TES*16]; const U32 MAX_TE_BUFFER = 4096; U8 packed_buffer[MAX_TE_BUFFER]; @@ -1196,6 +1229,9 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const bump[face_index] = te->getBumpShinyFullbright(); media_flags[face_index] = te->getMediaTexGen(); glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF)); + + // Directly sending material_ids is not safe! + memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */ } cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID); @@ -1217,6 +1253,8 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8); *cur_ptr++ = 0; cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID); } dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry"); @@ -1226,6 +1264,9 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec) { S32 retval = 0; + // temp buffer for material ID processing + // data will end up in tec.material_id[] + U8 material_data[LLTEContents::MAX_TES*16]; if (block_num < 0) { @@ -1251,7 +1292,7 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, block_num, LLTEContents::MAX_TE_BUFFER); } - tec.face_count = getNumTEs(); + tec.face_count = llmin((U32)getNumTEs(),(U32)LLTEContents::MAX_TES); U8 *cur_ptr = tec.packed_buffer; cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_data, 16, tec.face_count, MVT_LLUUID); @@ -1274,6 +1315,21 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name cur_ptr++; cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.glow, 1, tec.face_count, MVT_U8); + if (cur_ptr < tec.packed_buffer + tec.size) + { + cur_ptr++; + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)material_data, 16, tec.face_count, MVT_LLUUID); + } + else + { + memset(material_data, 0, sizeof(material_data)); + } + + for (U32 i = 0; i < tec.face_count; i++) + { + tec.material_ids[i].set(&material_data[i * 16]); + } + retval = 1; return retval; } @@ -1294,6 +1350,9 @@ S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec) retval |= setTEBumpShinyFullbright(i, tec.bump[i]); retval |= setTEMediaTexGen(i, tec.media_flags[i]); retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF); + + retval |= setTEMaterialID(i, tec.material_ids[i]); + coloru = LLColor4U(tec.colors + 4*i); // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) @@ -1328,6 +1387,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) // Avoid construction of 32 UUIDs per call static LLUUID image_ids[MAX_TES]; + static LLMaterialID material_ids[MAX_TES]; U8 image_data[MAX_TES*16]; U8 colors[MAX_TES*4]; @@ -1339,6 +1399,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) U8 bump[MAX_TES]; U8 media_flags[MAX_TES]; U8 glow[MAX_TES]; + U8 material_data[MAX_TES*16]; const U32 MAX_TE_BUFFER = 4096; U8 packed_buffer[MAX_TE_BUFFER]; @@ -1381,10 +1442,20 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8); cur_ptr++; cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8); + if (cur_ptr < packed_buffer + size) + { + cur_ptr++; + cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)material_data, 16, face_count, MVT_LLUUID); + } + else + { + memset(material_data, 0, sizeof(material_data)); + } for (i = 0; i < face_count; i++) { memcpy(image_ids[i].mData,&image_data[i*16],16); /* Flawfinder: ignore */ + material_ids[i].set(&material_data[i * 16]); } LLColor4 color; @@ -1398,6 +1469,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) retval |= setTEBumpShinyFullbright(i, bump[i]); retval |= setTEMediaTexGen(i, media_flags[i]); retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF); + retval |= setTEMaterialID(i, material_ids[i]); coloru = LLColor4U(colors + 4*i); // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 75f9f494b..1effeea73 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -42,6 +42,7 @@ class LLMessageSystem; class LLVolumeParams; class LLColor4; class LLColor3; +class LLMaterialID; class LLTextureEntry; class LLDataPacker; class LLVolumeMgr; @@ -309,6 +310,7 @@ struct LLTEContents U8 bump[MAX_TES]; U8 media_flags[MAX_TES]; U8 glow[MAX_TES]; + LLMaterialID material_ids[MAX_TES]; static const U32 MAX_TE_BUFFER = 4096; U8 packed_buffer[MAX_TE_BUFFER]; @@ -359,6 +361,7 @@ public: LLTextureEntry* getTE(const U8 te_num) const; virtual void setNumTEs(const U8 num_tes); + virtual void setAllTESelected(bool sel); virtual void setAllTETextures(const LLUUID &tex_id); virtual void setTE(const U8 index, const LLTextureEntry& te); virtual S32 setTEColor(const U8 te, const LLColor4 &color); @@ -381,7 +384,10 @@ public: virtual S32 setTEFullbright(const U8 te, const U8 fullbright); virtual S32 setTEMediaFlags(const U8 te, const U8 flags); virtual S32 setTEGlow(const U8 te, const F32 glow); + virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); + virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams); virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed + virtual void setTESelected(const U8 te, bool sel); void copyTEs(const LLPrimitive *primitive); S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const; diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp index 7ef87ed38..537e7a669 100644 --- a/indra/llprimitive/llprimtexturelist.cpp +++ b/indra/llprimitive/llprimtexturelist.cpp @@ -27,6 +27,7 @@ #include "linden_common.h" #include "llprimtexturelist.h" +#include "llmaterialid.h" #include "lltextureentry.h" // static @@ -358,6 +359,24 @@ S32 LLPrimTextureList::setGlow(const U8 index, const F32 glow) return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setMaterialID(const U8 index, const LLMaterialID& pMaterialID) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setMaterialID(pMaterialID); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setMaterialParams(pMaterialParams); + } + return TEM_CHANGE_NONE; +} + S32 LLPrimTextureList::size() const { return mEntryList.size(); diff --git a/indra/llprimitive/llprimtexturelist.h b/indra/llprimitive/llprimtexturelist.h index 71b191ef7..c91764e7a 100644 --- a/indra/llprimitive/llprimtexturelist.h +++ b/indra/llprimitive/llprimtexturelist.h @@ -39,9 +39,11 @@ #include "lluuid.h" #include "v3color.h" #include "v4color.h" +#include "llmaterial.h" class LLTextureEntry; +class LLMaterialID; // this is a list of LLTextureEntry*'s because in practice the list's elements // are of some derived class: LLFooTextureEntry @@ -110,6 +112,8 @@ public: S32 setFullbright(const U8 index, const U8 t); S32 setMediaFlags(const U8 index, const U8 media_flags); S32 setGlow(const U8 index, const F32 glow); + S32 setMaterialID(const U8 index, const LLMaterialID& pMaterialID); + S32 setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams); S32 size() const; diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 34eff1751..597f07849 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -29,6 +29,7 @@ #include "lluuid.h" #include "llmediaentry.h" #include "lltextureentry.h" +#include "llmaterialid.h" #include "llsdutil_math.h" #include "v4color.h" @@ -60,18 +61,24 @@ LLTextureEntry* LLTextureEntry::newTextureEntry() //=============================================================== LLTextureEntry::LLTextureEntry() : mMediaEntry(NULL) + , mSelected(false) + , mMaterialUpdatePending(false) { init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE); } LLTextureEntry::LLTextureEntry(const LLUUID& tex_id) : mMediaEntry(NULL) + , mSelected(false) + , mMaterialUpdatePending(false) { init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE); } LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs) : mMediaEntry(NULL) + , mSelected(false) + , mMaterialUpdatePending(false) { mID = rhs.mID; mScaleS = rhs.mScaleS; @@ -83,6 +90,8 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs) mBump = rhs.mBump; mMediaFlags = rhs.mMediaFlags; mGlow = rhs.mGlow; + mMaterialID = rhs.mMaterialID; + mMaterial = rhs.mMaterial; if (rhs.mMediaEntry != NULL) { // Make a copy mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry); @@ -103,6 +112,8 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) mBump = rhs.mBump; mMediaFlags = rhs.mMediaFlags; mGlow = rhs.mGlow; + mMaterialID = rhs.mMaterialID; + mMaterial = rhs.mMaterial; if (mMediaEntry != NULL) { delete mMediaEntry; } @@ -130,6 +141,7 @@ void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 of mBump = bump; mMediaFlags = 0x0; mGlow = 0; + mMaterialID.clear(); setColor(LLColor4(1.f, 1.f, 1.f, 1.f)); if (mMediaEntry != NULL) { @@ -159,6 +171,7 @@ bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const if (mBump != rhs.mBump) return (true); if (mMediaFlags != rhs.mMediaFlags) return (true); if (mGlow != rhs.mGlow) return (true); + if (mMaterialID != rhs.mMaterialID) return (true); return(false); } @@ -174,6 +187,7 @@ bool LLTextureEntry::operator==(const LLTextureEntry &rhs) const if (mBump != rhs.mBump) return (false); if (mMediaFlags != rhs.mMediaFlags) return false; if (mGlow != rhs.mGlow) return false; + if (mMaterialID != rhs.mMaterialID) return (false); return(true); } @@ -523,6 +537,34 @@ S32 LLTextureEntry::setGlow(F32 glow) return TEM_CHANGE_NONE; } +S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID) +{ + if ( (mMaterialID != pMaterialID) || (mMaterialUpdatePending && !mSelected) ) + { + if (mSelected) + { + mMaterialUpdatePending = true; + mMaterialID = pMaterialID; + return TEM_CHANGE_NONE; + } + + mMaterialUpdatePending = false; + mMaterialID = pMaterialID; + return TEM_CHANGE_TEXTURE; + } + return TEM_CHANGE_NONE; +} + +S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams) +{ + if (mSelected) + { + mMaterialUpdatePending = true; + } + mMaterial = pMaterialParams; + return TEM_CHANGE_TEXTURE; +} + void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry) { mMediaFlags |= MF_HAS_MEDIA; diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index d0181421f..cbd8665d3 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -30,6 +30,8 @@ #include "lluuid.h" #include "v4color.h" #include "llsd.h" +#include "llmaterialid.h" +#include "llmaterial.h" // These bits are used while unpacking TEM messages to tell which aspects of // the texture entry changed. @@ -98,6 +100,10 @@ public: void init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump); + bool hasPendingMaterialUpdate() const { return mMaterialUpdatePending; } + bool isSelected() const { return mSelected; } + bool setSelected(bool sel) { bool prev_sel = mSelected; mSelected = sel; return prev_sel; } + // These return a TEM_ flag from above to indicate if something changed. S32 setID (const LLUUID &tex_id); S32 setColor(const LLColor4 &color); @@ -121,6 +127,8 @@ public: S32 setTexGen(U8 texGen); S32 setMediaTexGen(U8 media); S32 setGlow(F32 glow); + S32 setMaterialID(const LLMaterialID& pMaterialID); + S32 setMaterialParams(const LLMaterialPtr pMaterialParams); virtual const LLUUID &getID() const { return mID; } const LLColor4 &getColor() const { return mColor; } @@ -139,6 +147,8 @@ public: U8 getTexGen() const { return mMediaFlags & TEM_TEX_GEN_MASK; } U8 getMediaTexGen() const { return mMediaFlags; } F32 getGlow() const { return mGlow; } + const LLMaterialID& getMaterialID() const { return mMaterialID; }; + const LLMaterialPtr getMaterialParams() const { return mMaterial; }; // *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() @@ -188,11 +198,15 @@ public: static const char* TEXTURE_MEDIA_DATA_KEY; protected: + bool mSelected; LLUUID mID; // Texture GUID LLColor4 mColor; U8 mBump; // Bump map, shiny, and fullbright U8 mMediaFlags; // replace with web page, movie, etc. F32 mGlow; + bool mMaterialUpdatePending; + LLMaterialID mMaterialID; + LLMaterialPtr mMaterial; // 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 diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 4b6c6156d..057e7d0ca 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -35,6 +35,7 @@ set(llui_SOURCE_FILES lleditmenuhandler.cpp llfiltereditor.cpp llfloater.cpp + llflyoutbutton.cpp llfocusmgr.cpp llfunctorregistry.cpp lliconctrl.cpp @@ -59,7 +60,10 @@ set(llui_SOURCE_FILES llscrollbar.cpp llscrollcontainer.cpp llscrollingpanellist.cpp + llscrolllistcell.cpp + llscrolllistcolumn.cpp llscrolllistctrl.cpp + llscrolllistitem.cpp llsearcheditor.cpp llslider.cpp llsliderctrl.cpp @@ -105,6 +109,7 @@ set(llui_HEADER_FILES lleditmenuhandler.h llfiltereditor.h llfloater.h + llflyoutbutton.h llfocusmgr.h llfunctorregistry.h llhtmlhelp.h @@ -134,7 +139,10 @@ set(llui_HEADER_FILES llscrollbar.h llscrollcontainer.h llscrollingpanellist.h + llscrolllistcell.h + llscrolllistcolumn.h llscrolllistctrl.h + llscrolllistitem.h llslider.h llsliderctrl.h llspinctrl.h diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 6fd7084df..64d003f0b 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -2,31 +2,25 @@ * @file llcombobox.cpp * @brief LLComboBox base class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * 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 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * 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 + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * 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. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,6 +42,8 @@ #include "llwindow.h" #include "llfloater.h" #include "llscrollbar.h" +#include "llscrolllistcell.h" +#include "llscrolllistitem.h" #include "llcontrol.h" #include "llfocusmgr.h" #include "lllineeditor.h" @@ -58,10 +54,9 @@ S32 LLCOMBOBOX_HEIGHT = 0; S32 LLCOMBOBOX_WIDTH = 0; S32 MAX_COMBO_WIDTH = 500; -static LLRegisterWidget r1("combo_box"); +static LLRegisterWidget register_combo_box("combo_box"); -LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std::string& label, - commit_callback_t commit_callback) +LLComboBox::LLComboBox(const std::string& name, const LLRect& rect, const std::string& label, commit_callback_t commit_callback) : LLUICtrl(name, rect, TRUE, commit_callback, FOLLOWS_LEFT | FOLLOWS_TOP), mTextEntry(NULL), mTextEntryTentative(TRUE), @@ -81,9 +76,7 @@ LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std:: { // Always use text box // Text label button - mButton = new LLButton(mLabel, - LLRect(), - LLStringUtil::null); + mButton = new LLButton(mLabel, LLRect(), LLStringUtil::null); mButton->setImageUnselected(LLUI::getUIImage("square_btn_32x128.tga")); mButton->setImageSelected(LLUI::getUIImage("square_btn_selected_32x128.tga")); mButton->setImageDisabled(LLUI::getUIImage("square_btn_32x128.tga")); @@ -94,19 +87,16 @@ LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std:: mButton->setFont(LLFontGL::getFontSansSerifSmall()); mButton->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_RIGHT); mButton->setHAlign( LLFontGL::LEFT ); - if(mAllowTextEntry) - { - mButton->setRightHPad(2); - } + mButton->setRightHPad(2); addChild(mButton); // disallow multiple selection - mList = new LLScrollListCtrl(std::string("ComboBox"), LLRect(), + mList = new LLScrollListCtrl(std::string("ComboBox"), LLRect(), boost::bind(&LLComboBox::onItemSelected, this, _2), FALSE); - mList->setVisible(FALSE); + mList->setVisible(false); mList->setBgWriteableColor(mListColor); - mList->setCommitOnKeyboardMovement(FALSE); + mList->setCommitOnKeyboardMovement(false); addChild(mList); // Mouse-down on button will transfer mouse focus to the list @@ -117,12 +107,11 @@ LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std:: mButton->setImageOverlay("combobox_arrow.tga", LLFontGL::RIGHT); updateLayout(); - + mTopLostSignalConnection = setTopLostCallback(boost::bind(&LLComboBox::hideList, this)); } - // virtual LLXMLNodePtr LLComboBox::getXML(bool save_children) const { @@ -131,16 +120,12 @@ LLXMLNodePtr LLComboBox::getXML(bool save_children) const node->setName(LL_COMBO_BOX_TAG); // Attributes - node->createChild("allow_text_entry", TRUE)->setBoolValue(mAllowTextEntry); - node->createChild("max_chars", TRUE)->setIntValue(mMaxChars); // Contents - std::vector data_list = mList->getAllData(); - std::vector::iterator data_itor; - for (data_itor = data_list.begin(); data_itor != data_list.end(); ++data_itor) + for (std::vector::iterator data_itor = data_list.begin(); data_itor != data_list.end(); ++data_itor) { LLScrollListItem* item = *data_itor; LLScrollListCell* cell = item->getColumn(0); @@ -172,9 +157,7 @@ LLView* LLComboBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory * S32 max_chars = 20; node->getAttributeS32("max_chars", max_chars); - LLComboBox* combo_box = new LLComboBox("combo_box", - rect, - label); + LLComboBox* combo_box = new LLComboBox("combo_box", rect, label); combo_box->setAllowTextEntry(allow_text_entry, max_chars); const std::string& contents = node->getValue(); @@ -201,7 +184,7 @@ LLView* LLComboBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory * { std::string tool_tip = label; child->getAttributeString("tool_tip", tool_tip); - item->setToolTip(tool_tip); + item->getColumn(0)->setToolTip(tool_tip); } } } @@ -257,7 +240,6 @@ void LLComboBox::onCommit() mTextEntry->setValue(getSimple()); mTextEntry->setTentative(FALSE); } - setControlValue(getValue()); LLUICtrl::onCommit(); } @@ -305,7 +287,6 @@ void LLComboBox::resetTextDirty() } } - // add item "name" to menu LLScrollListItem* LLComboBox::add(const std::string& name, EAddPosition pos, BOOL enabled) { @@ -577,7 +558,7 @@ void LLComboBox::updateLayout() if (!mTextEntry) { LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); - text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); + text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * shadow_size; // clear label on button std::string cur_label = mButton->getLabelSelected(); mTextEntry = new LLLineEditor(std::string("combo_text_entry"), @@ -590,9 +571,9 @@ void LLComboBox::updateLayout() mTextEntry->setSelectAllonFocusReceived(TRUE); mTextEntry->setHandleEditKeysDirectly(TRUE); mTextEntry->setCommitOnFocusLost(FALSE); + mTextEntry->setFollows(FOLLOWS_ALL); mTextEntry->setText(cur_label); mTextEntry->setIgnoreTab(TRUE); - mTextEntry->setFollowsAll(); addChild(mTextEntry); } else @@ -617,7 +598,7 @@ void LLComboBox::updateLayout() { mTextEntry->setVisible(FALSE); } - mButton->setFollowsAll(); + mButton->setFollows(FOLLOWS_ALL); } } @@ -755,10 +736,6 @@ void LLComboBox::hideList() } } -//------------------------------------------------------------------ -// static functions -//------------------------------------------------------------------ - void LLComboBox::onButtonMouseDown() { if (!mList->getVisible()) @@ -896,7 +873,10 @@ BOOL LLComboBox::handleKeyHere(KEY key, MASK mask) return FALSE; } // if selection has changed, pop open list - else if (mList->getLastSelectedItem() != last_selected_item) + else if (mList->getLastSelectedItem() != last_selected_item + || ((key == KEY_DOWN || key == KEY_UP) + && mList->getCanSelect() + && !mList->isEmpty())) { showList(); } @@ -931,6 +911,7 @@ BOOL LLComboBox::handleUnicodeCharHere(llwchar uni_char) void LLComboBox::setAllowTextEntry(BOOL allow, S32 max_chars, BOOL set_tentative) { mAllowTextEntry = allow; + mTextEntryTentative = set_tentative; mMaxChars = max_chars; @@ -1026,7 +1007,7 @@ void LLComboBox::updateSelection() if(mSuppressAutoComplete) { return; } - + LLWString left_wstring = mTextEntry->getWText().substr(0, mTextEntry->getCursor()); // user-entered portion of string, based on assumption that any selected // text was a result of auto-completion @@ -1236,168 +1217,3 @@ BOOL LLComboBox::selectItemRange( S32 first, S32 last ) return mList->selectItemRange(first, last); } - -// -// LLFlyoutButton -// - -static LLRegisterWidget r2("flyout_button"); - -const S32 FLYOUT_BUTTON_ARROW_WIDTH = 24; - -LLFlyoutButton::LLFlyoutButton( - const std::string& name, - const LLRect &rect, - const std::string& label) -: LLComboBox(name, rect, LLStringUtil::null), - mToggleState(FALSE), - mActionButton(NULL) -{ - // Always use text box - // Text label button - mActionButton = new LLButton(label, - LLRect(), LLStringUtil::null, boost::bind(&LLFlyoutButton::onActionButtonClick, this)); - mActionButton->setScaleImage(TRUE); - mActionButton->setFollowsAll(); - mActionButton->setHAlign( LLFontGL::HCENTER ); - mActionButton->setLabel(label); - addChild(mActionButton); - - mActionButtonImage = LLUI::getUIImage("flyout_btn_left.tga"); - mExpanderButtonImage = LLUI::getUIImage("flyout_btn_right.tga"); - mActionButtonImageSelected = LLUI::getUIImage("flyout_btn_left_selected.tga"); - mExpanderButtonImageSelected = LLUI::getUIImage("flyout_btn_right_selected.tga"); - mActionButtonImageDisabled = LLUI::getUIImage("flyout_btn_left_disabled.tga"); - mExpanderButtonImageDisabled = LLUI::getUIImage("flyout_btn_right_disabled.tga"); - - mActionButton->setImageSelected(mActionButtonImageSelected); - mActionButton->setImageUnselected(mActionButtonImage); - mActionButton->setImageDisabled(mActionButtonImageDisabled); - mActionButton->setImageDisabledSelected(LLPointer(NULL)); - - mButton->setImageSelected(mExpanderButtonImageSelected); - mButton->setImageUnselected(mExpanderButtonImage); - mButton->setImageDisabled(mExpanderButtonImageDisabled); - mButton->setImageDisabledSelected(LLPointer(NULL)); - mButton->setRightHPad(6); - - updateLayout(); -} - -// virtual -LLXMLNodePtr LLFlyoutButton::getXML(bool save_children) const -{ - LLXMLNodePtr node = LLComboBox::getXML(); - - node->setName(LL_FLYOUT_BUTTON_TAG); - - LLXMLNodePtr child; - - for (child = node->getFirstChild(); child.notNull();) - { - if (child->hasName("combo_item")) - { - child->setName(LL_FLYOUT_BUTTON_ITEM_TAG); - - //setName does a delete and add, so we have to start over - child = node->getFirstChild(); - } - else - { - child = child->getNextSibling(); - } - } - - return node; -} - -//static -LLView* LLFlyoutButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) -{ - std::string label(""); - node->getAttributeString("label", label); - - LLRect rect; - createRect(node, rect, parent, LLRect()); - - LLFlyoutButton* flyout_button = new LLFlyoutButton("flyout_button", - rect, - label); - - std::string list_position; - node->getAttributeString("list_position", list_position); - if (list_position == "below") - { - flyout_button->mListPosition = BELOW; - } - else if (list_position == "above") - { - flyout_button->mListPosition = ABOVE; - } - - - flyout_button->initFromXML(node, parent); - - LLXMLNodePtr child; - for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) - { - if (child->hasName("flyout_button_item")) - { - std::string label = child->getTextContents(); - - std::string value = label; - child->getAttributeString("value", value); - - flyout_button->add(label, LLSD(value) ); - } - } - - flyout_button->updateLayout(); - - return flyout_button; -} - -void LLFlyoutButton::updateLayout() -{ - LLComboBox::updateLayout(); - - mButton->setOrigin(getRect().getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, 0); - mButton->reshape(FLYOUT_BUTTON_ARROW_WIDTH, getRect().getHeight()); - mButton->setFollows(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM); - mButton->setTabStop(FALSE); - mButton->setImageOverlay(mListPosition == BELOW ? "down_arrow.tga" : "up_arrow.tga", LLFontGL::RIGHT); - - mActionButton->setOrigin(0, 0); - mActionButton->reshape(getRect().getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, getRect().getHeight()); -} - -void LLFlyoutButton::onActionButtonClick() -{ - // remember last list selection? - mList->deselect(); - onCommit(); -} - -void LLFlyoutButton::draw() -{ - mActionButton->setToggleState(mToggleState); - mButton->setToggleState(mToggleState); - - //FIXME: this should be an attribute of comboboxes, whether they have a distinct label or - // the label reflects the last selected item, for now we have to manually remove the label - mButton->setLabel(LLStringUtil::null); - LLComboBox::draw(); -} - -void LLFlyoutButton::setEnabled(BOOL enabled) -{ - mActionButton->setEnabled(enabled); - LLComboBox::setEnabled(enabled); -} - - -void LLFlyoutButton::setToggleState(BOOL state) -{ - mToggleState = state; -} - diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index b6165ae0f..2131ba06c 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -2,31 +2,25 @@ * @file llcombobox.h * @brief LLComboBox base class * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * 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 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * 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 + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * 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. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,15 +33,12 @@ #include "llbutton.h" #include "lluictrl.h" #include "llctrlselectioninterface.h" -#include "llimagegl.h" #include "llrect.h" +#include "llscrolllistctrl.h" // Classes class LLFontGL; -class LLButton; -class LLSquareButton; -class LLScrollListCtrl; class LLLineEditor; class LLViewBorder; @@ -64,15 +55,12 @@ public: BELOW } EPreferredPosition; - LLComboBox( - const std::string& name, - const LLRect &rect, - const std::string& label, - commit_callback_t commit_callback = NULL - ); virtual ~LLComboBox(); protected: -void prearrangeList(std::string filter = ""); + friend class LLFloaterTestImpl; + friend class LLUICtrlFactory; + LLComboBox(const std::string& name, const LLRect& rect, const std::string& label, commit_callback_t commit_callback = NULL); + void prearrangeList(std::string filter = ""); public: // LLView interface @@ -191,7 +179,6 @@ public: void onButtonMouseDown(); void onListMouseUp(); void onItemSelected(const LLSD& data); - void onTextCommit(const LLSD& data); void setSuppressTentative(bool suppress); @@ -226,34 +213,4 @@ private: S32 mLastSelectedIndex; }; -class LLFlyoutButton : public LLComboBox -{ -public: - LLFlyoutButton( - const std::string& name, - const LLRect &rect, - const std::string& label); - - virtual void updateLayout(); - virtual void draw(); - virtual void setEnabled(BOOL enabled); - - void setToggleState(BOOL state); - - virtual LLXMLNodePtr getXML(bool save_children = true) const; - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); - void onActionButtonClick(); - void onSelectAction(LLUICtrl* ctrl); - -protected: - LLButton* mActionButton; - LLPointer mActionButtonImage; - LLPointer mExpanderButtonImage; - LLPointer mActionButtonImageSelected; - LLPointer mExpanderButtonImageSelected; - LLPointer mActionButtonImageDisabled; - LLPointer mExpanderButtonImageDisabled; - BOOL mToggleState; -}; - #endif diff --git a/indra/llui/llfiltereditor.cpp b/indra/llui/llfiltereditor.cpp index 12e1c2d52..1d13b1536 100644 --- a/indra/llui/llfiltereditor.cpp +++ b/indra/llui/llfiltereditor.cpp @@ -58,7 +58,7 @@ LLView* LLFilterEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto S32 max_text_length = 128; node->getAttributeS32("max_length", max_text_length); - std::string text = node->getValue().substr(0, max_text_length - 1); + //std::string text = node->getValue().substr(0, max_text_length - 1); LLFilterEditor* search_editor = new LLFilterEditor("filter_editor", rect, @@ -70,7 +70,7 @@ LLView* LLFilterEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto search_editor->setLabel(label); } - search_editor->setText(text); + //search_editor->setText(text); search_editor->initFromXML(node, parent); diff --git a/indra/llui/llflyoutbutton.cpp b/indra/llui/llflyoutbutton.cpp new file mode 100644 index 000000000..db16d9ccb --- /dev/null +++ b/indra/llui/llflyoutbutton.cpp @@ -0,0 +1,172 @@ +/** + * @file llflyoutbutton.cpp + * @brief LLFlyoutButton base class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +// file includes +#include "llflyoutbutton.h" + +static LLRegisterWidget r2("flyout_button"); + +const S32 FLYOUT_BUTTON_ARROW_WIDTH = 24; + +LLFlyoutButton::LLFlyoutButton(const std::string& name, const LLRect& rect, const std::string& label) +: LLComboBox(name, rect, LLStringUtil::null), + mToggleState(FALSE), + mActionButton(NULL) +{ + // Always use text box + // Text label button + mActionButton = new LLButton(label, LLRect(), LLStringUtil::null, boost::bind(&LLFlyoutButton::onActionButtonClick, this, _2)); + mActionButton->setScaleImage(true); + mActionButton->setFollowsAll(); + mActionButton->setHAlign(LLFontGL::HCENTER); + mActionButton->setLabel(label); + addChild(mActionButton); + + mActionButton->setImageSelected(LLUI::getUIImage("flyout_btn_left_selected.tga")); + mActionButton->setImageUnselected(LLUI::getUIImage("flyout_btn_left.tga")); + mActionButton->setImageDisabled(LLUI::getUIImage("flyout_btn_left_disabled.tga")); + mActionButton->setImageDisabledSelected(LLPointer(NULL)); + + mButton->setImageSelected(LLUI::getUIImage("flyout_btn_right_selected.tga")); + mButton->setImageUnselected(LLUI::getUIImage("flyout_btn_right.tga")); + mButton->setImageDisabled(LLUI::getUIImage("flyout_btn_right_disabled.tga")); + mButton->setImageDisabledSelected(LLPointer(NULL)); + mButton->setRightHPad(6); + + updateLayout(); +} + +// virtual +LLXMLNodePtr LLFlyoutButton::getXML(bool save_children) const +{ + LLXMLNodePtr node = LLComboBox::getXML(); + node->setName(LL_FLYOUT_BUTTON_TAG); + + for (LLXMLNodePtr child = node->getFirstChild(); child.notNull();) + { + if (child->hasName("combo_item")) + { + child->setName(LL_FLYOUT_BUTTON_ITEM_TAG); + + //setName does a delete and add, so we have to start over + child = node->getFirstChild(); + } + else + { + child = child->getNextSibling(); + } + } + + return node; +} + +//static +LLView* LLFlyoutButton::fromXML(LLXMLNodePtr node, LLView* parent, LLUICtrlFactory* factory) +{ + std::string label(""); + node->getAttributeString("label", label); + + LLRect rect; + createRect(node, rect, parent, LLRect()); + + LLFlyoutButton* flyout_button = new LLFlyoutButton("flyout_button", rect, label); + + std::string list_position; + node->getAttributeString("list_position", list_position); + if (list_position == "below") + { + flyout_button->mListPosition = BELOW; + } + else if (list_position == "above") + { + flyout_button->mListPosition = ABOVE; + } + + flyout_button->initFromXML(node, parent); + + for (LLXMLNodePtr child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) + { + if (child->hasName(LL_FLYOUT_BUTTON_ITEM_TAG)) + { + std::string label(child->getTextContents()); + std::string value(label); + child->getAttributeString("value", value); + + flyout_button->add(label, LLSD(value)); + } + } + + flyout_button->updateLayout(); + + return flyout_button; +} + +void LLFlyoutButton::updateLayout() +{ + LLComboBox::updateLayout(); + + mButton->setOrigin(getRect().getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, 0); + mButton->reshape(FLYOUT_BUTTON_ARROW_WIDTH, getRect().getHeight()); + mButton->setFollows(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM); + mButton->setTabStop(false); + mButton->setImageOverlay(mListPosition == BELOW ? "down_arrow.tga" : "up_arrow.tga", LLFontGL::RIGHT); + + mActionButton->setOrigin(0, 0); + mActionButton->reshape(getRect().getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, getRect().getHeight()); +} + +void LLFlyoutButton::onActionButtonClick(const LLSD& data) +{ + // remember last list selection? + mList->deselect(); + onCommit(); +} + +void LLFlyoutButton::draw() +{ + mActionButton->setToggleState(mToggleState); + mButton->setToggleState(mToggleState); + + //FIXME: this should be an attribute of comboboxes, whether they have a distinct label or + // the label reflects the last selected item, for now we have to manually remove the label + mButton->setLabel(LLStringUtil::null); + LLComboBox::draw(); +} + +void LLFlyoutButton::setEnabled(BOOL enabled) +{ + mActionButton->setEnabled(enabled); + LLComboBox::setEnabled(enabled); +} + +void LLFlyoutButton::setToggleState(BOOL state) +{ + mToggleState = state; +} + + diff --git a/indra/llui/llflyoutbutton.h b/indra/llui/llflyoutbutton.h new file mode 100644 index 000000000..0d9ce80bf --- /dev/null +++ b/indra/llui/llflyoutbutton.h @@ -0,0 +1,59 @@ +/** + * @file llflyoutbutton.h + * @brief LLFlyoutButton base class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// A control that displays the name of the chosen item, which when clicked +// shows a scrolling box of choices. + +#ifndef LL_LLFLYOUTBUTTON_H +#define LL_LLFLYOUTBUTTON_H + +#include "llcombobox.h" + +// Classes + +class LLFlyoutButton : public LLComboBox +{ +protected: + LLFlyoutButton(const std::string& name, const LLRect& rect, const std::string& label); + friend class LLUICtrlFactory; +public: + virtual void updateLayout(); + virtual void draw(); + virtual void setEnabled(BOOL enabled); + + void setToggleState(BOOL state); + + virtual LLXMLNodePtr getXML(bool save_children = true) const; + static LLView* fromXML(LLXMLNodePtr node, LLView* parent, LLUICtrlFactory* factory); + void onActionButtonClick(const LLSD& data); + void onSelectAction(LLUICtrl* ctrl); + +protected: + LLButton* mActionButton; + BOOL mToggleState; +}; + +#endif // LL_LLFLYOUTBUTTON_H diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp new file mode 100644 index 000000000..83479888f --- /dev/null +++ b/indra/llui/llscrolllistcell.cpp @@ -0,0 +1,437 @@ +/** + * @file llscrolllistcell.cpp + * @brief Scroll lists are composed of rows (items), each of which + * contains columns (cells). + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llscrolllistcell.h" + +#include "llcheckboxctrl.h" +#include "llresmgr.h" + +//static +LLScrollListCell* LLScrollListCell::create(LLScrollListCell::Params cell_p) +{ + LLScrollListCell* cell = NULL; + + if (cell_p.type() == "icon") + { + cell = new LLScrollListIcon(cell_p); + } + else if (cell_p.type() == "checkbox") + { + cell = new LLScrollListCheck(cell_p); + } + else if (cell_p.type() == "date") + { + if (!cell_p.color.isProvided()) cell_p.color = LLUI::sColorsGroup->getColor("DefaultListText"); + cell = new LLScrollListDate(cell_p); + } + else // default is "text" + { + if (!cell_p.color.isProvided()) cell_p.color = LLUI::sColorsGroup->getColor("DefaultListText"); + cell = new LLScrollListText(cell_p); + } + + if (cell_p.value.isProvided()) + { + cell->setValue(cell_p.value); + } + + return cell; +} + + +LLScrollListCell::LLScrollListCell(const LLScrollListCell::Params& p) +: mWidth(p.width), + mToolTip(p.tool_tip) +{} + +// virtual +const LLSD LLScrollListCell::getValue() const +{ + return LLStringUtil::null; +} + +// +// LLScrollListIcon +// +LLScrollListIcon::LLScrollListIcon(const LLScrollListCell::Params& p) +: LLScrollListCell(p), + // + mCallback(NULL), + // + mColor(p.color), + mAlignment(p.font_halign) +{ + setValue(p.value().asString()); +} + +LLScrollListIcon::~LLScrollListIcon() +{ +} + +/*virtual*/ +S32 LLScrollListIcon::getHeight() const +{ return mIcon ? mIcon->getHeight() : 0; } + +/*virtual*/ +const LLSD LLScrollListIcon::getValue() const +{ return mIcon.isNull() ? LLStringUtil::null : mIcon->getName(); } + +void LLScrollListIcon::setValue(const LLSD& value) +{ + if (value.isUUID()) + { + // don't use default image specified by LLUUID::null, use no image in that case + LLUUID image_id = value.asUUID(); + mIcon = image_id.notNull() ? LLUI::getUIImageByID(image_id) : LLUIImagePtr(NULL); + } + else + { + std::string value_string = value.asString(); + if (LLUUID::validate(value_string)) + { + setValue(LLUUID(value_string)); + } + else if (!value_string.empty()) + { + mIcon = LLUI::getUIImage(value.asString()); + } + else + { + mIcon = NULL; + } + } +} + + +void LLScrollListIcon::setColor(const LLColor4& color) +{ + mColor = color; +} + +S32 LLScrollListIcon::getWidth() const +{ + // if no specified fix width, use width of icon + if (LLScrollListCell::getWidth() == 0 && mIcon.notNull()) + { + return mIcon->getWidth(); + } + return LLScrollListCell::getWidth(); +} + + +void LLScrollListIcon::draw(const LLColor4& color, const LLColor4& highlight_color) const +{ + if (mIcon) + { + switch(mAlignment) + { + case LLFontGL::LEFT: + mIcon->draw(0, 0, mColor); + break; + case LLFontGL::RIGHT: + mIcon->draw(getWidth() - mIcon->getWidth(), 0, mColor); + break; + case LLFontGL::HCENTER: + mIcon->draw((getWidth() - mIcon->getWidth()) / 2, 0, mColor); + break; + default: + break; + } + } +} + +// +// LLScrollListText +// +U32 LLScrollListText::sCount = 0; + +LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p) +: LLScrollListCell(p), + mText(p.value().asString()), + mFont(p.font.isProvided() ? LLResMgr::getInstance()->getRes(p.font) : LLFontGL::getFontSansSerifSmall()), + mColor(p.color), + mUseColor(p.color.isProvided()), + mFontStyle(LLFontGL::getStyleFromString(p.font_style)), + mFontAlignment(p.font_halign), + mVisible(p.visible), + mHighlightCount( 0 ), + mHighlightOffset( 0 ) +{ + sCount++; + + mTextWidth = getWidth(); + + // initialize rounded rect image + if (!mRoundedRectImage) + { + mRoundedRectImage = LLUI::getUIImage("rounded_square.tga"); + } +} + +//virtual +void LLScrollListText::highlightText(S32 offset, S32 num_chars) +{ + mHighlightOffset = offset; + mHighlightCount = num_chars; +} + +//virtual +BOOL LLScrollListText::isText() const +{ + return TRUE; +} + +//virtual +const std::string &LLScrollListText::getToolTip() const +{ + // If base class has a tooltip, return that + if (! LLScrollListCell::getToolTip().empty()) + return LLScrollListCell::getToolTip(); + + // ...otherwise, return the value itself as the tooltip + return mText.getString(); +} + +// virtual +BOOL LLScrollListText::needsToolTip() const +{ + // If base class has a tooltip, return that + if (LLScrollListCell::needsToolTip()) + return LLScrollListCell::needsToolTip(); + + // ...otherwise, show tooltips for truncated text + return mFont->getWidth(mText.getString()) > getWidth(); +} + +//virtual +BOOL LLScrollListText::getVisible() const +{ + return mVisible; +} + +//virtual +S32 LLScrollListText::getHeight() const +{ + return llround(mFont->getLineHeight()); +} + + +LLScrollListText::~LLScrollListText() +{ + sCount--; +} + +S32 LLScrollListText::getContentWidth() const +{ + return mFont->getWidth(mText.getString()); +} + + +void LLScrollListText::setColor(const LLColor4& color) +{ + mColor = color; + mUseColor = TRUE; +} + +void LLScrollListText::setText(const LLStringExplicit& text) +{ + mText = text; +} + +void LLScrollListText::setFontStyle(const U8 font_style) +{ + mFontStyle = font_style; +} + +//virtual +void LLScrollListText::setValue(const LLSD& text) +{ + setText(text.asString()); +} + +//virtual +const LLSD LLScrollListText::getValue() const +{ + return LLSD(mText.getString()); +} + + +void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_color) const +{ + LLColor4 display_color; + if (mUseColor) + { + display_color = mColor; + } + else + { + display_color = color; + } + + if (mHighlightCount > 0) + { + S32 left = 0; + switch(mFontAlignment) + { + case LLFontGL::LEFT: + left = mFont->getWidth(mText.getString(), 0, mHighlightOffset); + break; + case LLFontGL::RIGHT: + left = getWidth() - mFont->getWidth(mText.getString(), mHighlightOffset, S32_MAX); + break; + case LLFontGL::HCENTER: + left = (getWidth() - mFont->getWidth(mText.getString())) / 2; + break; + } + LLRect highlight_rect(left - 2, + llround(mFont->getLineHeight()) + 1, + left + mFont->getWidth(mText.getString(), mHighlightOffset, mHighlightCount) + 1, + 1); + mRoundedRectImage->draw(highlight_rect, highlight_color); + } + + // Try to draw the entire string + F32 right_x; + U32 string_chars = mText.length(); + F32 start_x = 0.f; + switch(mFontAlignment) + { + case LLFontGL::LEFT: + start_x = (mFontStyle & LLFontGL::ITALIC) ? 2.f : 0.f; //Italic text seems to need a little padding. + break; + case LLFontGL::RIGHT: + start_x = (F32)getWidth(); + break; + case LLFontGL::HCENTER: + start_x = (F32)getWidth() * 0.5f; + break; + } + mFont->render(mText.getWString(), 0, + start_x, 2.f, + display_color, + mFontAlignment, + LLFontGL::BOTTOM, + mFontStyle, + LLFontGL::NO_SHADOW, + string_chars, + getTextWidth(), + &right_x, + FALSE, + TRUE); +} + +// +// LLScrollListCheck +// +LLScrollListCheck::LLScrollListCheck(const LLScrollListCell::Params& p) +: LLScrollListCell(p) +{ + mCheckBox = new LLCheckBoxCtrl("checkbox", LLRect(0, p.width, p.width, 0), "", NULL, NULL, p.value()); + mCheckBox->setEnabled(p.enabled); + + LLRect rect(mCheckBox->getRect()); + if (p.width) + { + rect.mRight = rect.mLeft + p.width; + mCheckBox->setRect(rect); + setWidth(p.width); + } + else + { + setWidth(rect.getWidth()); //check_box->getWidth(); + } + + mCheckBox->setColor(p.color); +} + + +LLScrollListCheck::~LLScrollListCheck() +{ + delete mCheckBox; + mCheckBox = NULL; +} + +void LLScrollListCheck::draw(const LLColor4& color, const LLColor4& highlight_color) const +{ + mCheckBox->draw(); +} + +BOOL LLScrollListCheck::handleClick() +{ + if (mCheckBox->getEnabled()) + { + mCheckBox->toggle(); + } + // don't change selection when clicking on embedded checkbox + return TRUE; +} + +/*virtual*/ +const LLSD LLScrollListCheck::getValue() const +{ + return mCheckBox->getValue(); +} + +/*virtual*/ +void LLScrollListCheck::setValue(const LLSD& value) +{ + mCheckBox->setValue(value); +} + +/*virtual*/ +void LLScrollListCheck::onCommit() +{ + mCheckBox->onCommit(); +} + +/*virtual*/ +void LLScrollListCheck::setEnabled(BOOL enable) +{ + mCheckBox->setEnabled(enable); +} + +// +// LLScrollListDate +// + +LLScrollListDate::LLScrollListDate( const LLScrollListCell::Params& p) +: LLScrollListText(p), + mDate(p.value().asDate()) +{} + +void LLScrollListDate::setValue(const LLSD& value) +{ + mDate = value.asDate(); + LLScrollListText::setValue(mDate.asRFC1123()); +} + +const LLSD LLScrollListDate::getValue() const +{ + return mDate; +} diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h new file mode 100644 index 000000000..3e4a9cd06 --- /dev/null +++ b/indra/llui/llscrolllistcell.h @@ -0,0 +1,236 @@ +/** + * @file llscrolllistcell.h + * @brief Scroll lists are composed of rows (items), each of which + * contains columns (cells). + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LLSCROLLLISTCELL_H +#define LLSCROLLLISTCELL_H + +#include "llfontgl.h" // HAlign +#include "llpointer.h" // LLPointer<> +#include "lluistring.h" +#include "v4color.h" +#include "llui.h" +#include "llinitparam.h" + +class LLCheckBoxCtrl; +class LLSD; + +/* + * Represents a cell in a scrollable table. + * + * Sub-classes must return height and other properties + * though width accessors are implemented by the base class. + * It is therefore important for sub-class constructors to call + * setWidth() with realistic values. + */ +class LLScrollListCell +{ +public: + struct Params : public LLInitParam::Block + { + Optional type, + column; + + Optional width; + Optional enabled, + visible; + + Optional userdata; + Optional value; + Optional tool_tip; + + Optional font; + Optional font_color; + Optional font_halign; + Optional font_style; + + Optional color; + + Params() + : type("type", "text"), + column("column"), + width("width"), + enabled("enabled", true), + visible("visible", true), + value("value"), + tool_tip("tool_tip", ""), + font("font"/*, LLFontGL::getFontSansSerifSmall()*/), + font_color("font_color", LLColor4::black), + font_style("font-style"), + color("color", LLColor4::white), + font_halign("halign", LLFontGL::LEFT) + { + addSynonym(column, "name"); + addSynonym(font_color, "font-color"); + } + }; + + static LLScrollListCell* create(Params); + + LLScrollListCell(const LLScrollListCell::Params&); + virtual ~LLScrollListCell() {}; + + virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const {}; // truncate to given width, if possible + virtual S32 getWidth() const {return mWidth;} + virtual S32 getContentWidth() const { return 0; } + virtual S32 getHeight() const { return 0; } + virtual const LLSD getValue() const; + virtual void setValue(const LLSD& value) { } + virtual const std::string &getToolTip() const { return mToolTip; } + virtual void setToolTip(const std::string &str) { mToolTip = str; } + virtual BOOL getVisible() const { return TRUE; } + virtual void setWidth(S32 width) { mWidth = width; } + virtual void highlightText(S32 offset, S32 num_chars) {} + virtual BOOL isText() const { return FALSE; } + virtual BOOL needsToolTip() const { return ! mToolTip.empty(); } + virtual void setColor(const LLColor4&) {} + virtual void onCommit() {}; + + virtual BOOL handleClick() { return FALSE; } + virtual void setEnabled(BOOL enable) { } + +private: + S32 mWidth; + std::string mToolTip; +}; + +class LLScrollListSpacer : public LLScrollListCell +{ +public: + LLScrollListSpacer(const LLScrollListCell::Params& p) : LLScrollListCell(p) {} + /*virtual*/ ~LLScrollListSpacer() {}; + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const {} +}; + +/* + * Cell displaying a text label. + */ +class LLScrollListText : public LLScrollListCell +{ +public: + LLScrollListText(const LLScrollListCell::Params&); + /*virtual*/ ~LLScrollListText(); + + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ S32 getContentWidth() const; + /*virtual*/ S32 getHeight() const; + /*virtual*/ void setValue(const LLSD& value); + /*virtual*/ const LLSD getValue() const; + /*virtual*/ BOOL getVisible() const; + /*virtual*/ void highlightText(S32 offset, S32 num_chars); + + /*virtual*/ void setColor(const LLColor4&); + /*virtual*/ BOOL isText() const; + /*virtual*/ const std::string & getToolTip() const; + /*virtual*/ BOOL needsToolTip() const; + + S32 getTextWidth() const { return mTextWidth;} + void setTextWidth(S32 value) { mTextWidth = value;} + virtual void setWidth(S32 width) { LLScrollListCell::setWidth(width); mTextWidth = width; } + + void setText(const LLStringExplicit& text); + void setFontStyle(const U8 font_style); + +private: + LLUIString mText; + S32 mTextWidth; + const LLFontGL* mFont; + LLColor4 mColor; + U8 mUseColor; + U8 mFontStyle; + LLFontGL::HAlign mFontAlignment; + BOOL mVisible; + S32 mHighlightCount; + S32 mHighlightOffset; + + LLPointer mRoundedRectImage; + + static U32 sCount; +}; + +/* + * Cell displaying an image. + */ +class LLScrollListIcon : public LLScrollListCell +{ +public: + LLScrollListIcon(const LLScrollListCell::Params& p); + /*virtual*/ ~LLScrollListIcon(); + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ S32 getWidth() const; + /*virtual*/ S32 getHeight() const; + /*virtual*/ const LLSD getValue() const; + /*virtual*/ void setColor(const LLColor4&); + /*virtual*/ void setValue(const LLSD& value); + // + void setClickCallback(boost::function cb) { mCallback = cb; } + /*virtual*/ BOOL handleClick() { return mCallback ? mCallback() : false; } + // + +private: + LLPointer mIcon; + LLColor4 mColor; + LLFontGL::HAlign mAlignment; + // + boost::function mCallback; + // +}; + +/* + * An interactive cell containing a check box. + */ +class LLScrollListCheck : public LLScrollListCell +{ +public: + LLScrollListCheck( const LLScrollListCell::Params&); + /*virtual*/ ~LLScrollListCheck(); + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ S32 getHeight() const { return 0; } + /*virtual*/ const LLSD getValue() const; + /*virtual*/ void setValue(const LLSD& value); + /*virtual*/ void onCommit(); + + /*virtual*/ BOOL handleClick(); + /*virtual*/ void setEnabled(BOOL enable); + + LLCheckBoxCtrl* getCheckBox() { return mCheckBox; } + +private: + LLCheckBoxCtrl* mCheckBox; +}; + +class LLScrollListDate : public LLScrollListText +{ +public: + LLScrollListDate( const LLScrollListCell::Params& p ); + virtual void setValue(const LLSD& value); + virtual const LLSD getValue() const; + +private: + LLDate mDate; +}; + +#endif diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp new file mode 100644 index 000000000..6353528c4 --- /dev/null +++ b/indra/llui/llscrolllistcolumn.cpp @@ -0,0 +1,350 @@ +/** + * @file llscrollcolumnheader.cpp + * @brief Scroll lists are composed of rows (items), each of which + * contains columns (cells). + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llscrolllistcolumn.h" + +#include "llbutton.h" +#include "llkeyboard.h" // For gKeyboard +#include "llresizebar.h" +#include "llscrolllistctrl.h" +#include "lluictrlfactory.h" + +const S32 MIN_COLUMN_WIDTH = 20; + +//--------------------------------------------------------------------------- +// LLScrollColumnHeader +//--------------------------------------------------------------------------- +LLScrollColumnHeader::LLScrollColumnHeader(const std::string& name, const LLRect& rect, LLScrollListColumn* column) +: LLButton(name, rect, "square_btn_32x128.tga", "square_btn_selected_32x128.tga", LLStringUtil::null, NULL, LLFontGL::getFontSansSerifSmall()), + mColumn(column), + mHasResizableElement(FALSE) +{ + setClickedCallback(boost::bind(&LLScrollColumnHeader::onClick, this, _2)); + setHAlign(LLFontGL::LEFT); + + // resize handles on left and right + const S32 RESIZE_BAR_THICKNESS = 3; + LLResizeBar::Params resize_bar_p; + resize_bar_p.resizing_view(this); + resize_bar_p.rect(LLRect(getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0)); + resize_bar_p.min_size(MIN_COLUMN_WIDTH); + resize_bar_p.side(LLResizeBar::RIGHT); + resize_bar_p.enabled(false); + mResizeBar = LLUICtrlFactory::create(resize_bar_p); + addChild(mResizeBar); +} + +LLScrollColumnHeader::~LLScrollColumnHeader() +{} + +void LLScrollColumnHeader::draw() +{ + std::string sort_column = mColumn->mParentCtrl->getSortColumnName(); + BOOL draw_arrow = !mColumn->mLabel.empty() + && mColumn->mParentCtrl->isSorted() + // check for indirect sorting column as well as column's sorting name + && (sort_column == mColumn->mSortingColumn || sort_column == mColumn->mName); + + BOOL is_ascending = mColumn->mParentCtrl->getSortAscending(); + if (draw_arrow) + { + setImageOverlay(is_ascending ? "up_arrow.tga" : "down_arrow.tga", LLFontGL::RIGHT, LLColor4::white); + } + else + { + setImageOverlay(LLUUID::null); + } + + // Draw children + LLButton::draw(); +} + +//virtual +BOOL LLScrollColumnHeader::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) +{ + if (!getRect().pointInRect(x,y)) return false; + std::string tool_tip = LLUI::sShowXUINames ? getShowNamesToolTip() : getToolTip(); + if (tool_tip.empty()) tool_tip = getLabelUnselected(); // Fallback on label + + if (!tool_tip.empty()) + { + msg = tool_tip; + // Convert rect local to screen coordinates + localPointToScreen(0, 0, &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom)); + localPointToScreen(getRect().getWidth(), getRect().getHeight(), &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop)); + } + return !tool_tip.empty(); +} + +BOOL LLScrollColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + if (canResize() && mResizeBar->getRect().pointInRect(x, y)) + { + // reshape column to max content width + mColumn->mParentCtrl->calcMaxContentWidth(); + LLRect column_rect = getRect(); + column_rect.mRight = column_rect.mLeft + mColumn->mMaxContentWidth; + setShape(column_rect, true); + } + else + { + onClick(LLSD()); + } + return TRUE; +} + +void LLScrollColumnHeader::onClick(const LLSD& data) +{ + if (mColumn) + { + LLScrollListCtrl::onClickColumn(mColumn); + } +} + +LLView* LLScrollColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding) +{ + // this logic assumes dragging on right + llassert(snap_edge == SNAP_RIGHT); + + // use higher snap threshold for column headers + threshold = llmin(threshold, 10); + + LLRect snap_rect = getSnapRect(); + + mColumn->mParentCtrl->calcMaxContentWidth(); + + S32 snap_delta = mColumn->mMaxContentWidth - snap_rect.getWidth(); + + // x coord growing means column growing, so same signs mean we're going in right direction + if (llabs(snap_delta) <= threshold && mouse_dir.mX * snap_delta > 0 ) + { + new_edge_val = snap_rect.mRight + snap_delta; + } + else + { + LLScrollListColumn* next_column = mColumn->mParentCtrl->getColumn(mColumn->mIndex + 1); + while (next_column) + { + if (next_column->mHeader) + { + snap_delta = (next_column->mHeader->getSnapRect().mRight - next_column->mMaxContentWidth) - snap_rect.mRight; + if (llabs(snap_delta) <= threshold && mouse_dir.mX * snap_delta > 0 ) + { + new_edge_val = snap_rect.mRight + snap_delta; + } + break; + } + next_column = mColumn->mParentCtrl->getColumn(next_column->mIndex + 1); + } + } + + return this; +} + +void LLScrollColumnHeader::handleReshape(const LLRect& new_rect, bool by_user) +{ + S32 new_width = new_rect.getWidth(); + S32 delta_width = new_width - (getRect().getWidth() /*+ mColumn->mParentCtrl->getColumnPadding()*/); + + if (delta_width != 0) + { + S32 remaining_width = -delta_width; + S32 col; + for (col = mColumn->mIndex + 1; col < mColumn->mParentCtrl->getNumColumns(); col++) + { + LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col); + if (!columnp) continue; + + if (columnp->mHeader && columnp->mHeader->canResize()) + { + // how many pixels in width can this column afford to give up? + S32 resize_buffer_amt = llmax(0, columnp->getWidth() - MIN_COLUMN_WIDTH); + + // user shrinking column, need to add width to other columns + if (delta_width < 0) + { + if (columnp->getWidth() > 0) + { + // statically sized column, give all remaining width to this column + columnp->setWidth(columnp->getWidth() + remaining_width); + if (columnp->mRelWidth > 0.f) + { + columnp->mRelWidth = (F32)columnp->getWidth() / (F32)mColumn->mParentCtrl->getItemListRect().getWidth(); + } + // all padding went to this widget, we're done + break; + } + } + else + { + // user growing column, need to take width from other columns + remaining_width += resize_buffer_amt; + + if (columnp->getWidth() > 0) + { + columnp->setWidth(columnp->getWidth() - llmin(columnp->getWidth() - MIN_COLUMN_WIDTH, delta_width)); + if (columnp->mRelWidth > 0.f) + { + columnp->mRelWidth = (F32)columnp->getWidth() / (F32)mColumn->mParentCtrl->getItemListRect().getWidth(); + } + } + + if (remaining_width >= 0) + { + // width sucked up from neighboring columns, done + break; + } + } + } + } + + // clamp resize amount to maximum that can be absorbed by other columns + if (delta_width > 0) + { + delta_width += llmin(remaining_width, 0); + } + + // propagate constrained delta_width to new width for this column + new_width = getRect().getWidth() + delta_width - mColumn->mParentCtrl->getColumnPadding(); + + // use requested width + mColumn->setWidth(new_width); + + // update proportional spacing + if (mColumn->mRelWidth > 0.f) + { + mColumn->mRelWidth = (F32)new_width / (F32)mColumn->mParentCtrl->getItemListRect().getWidth(); + } + + // tell scroll list to layout columns again + // do immediate update to get proper feedback to resize handle + // which needs to know how far the resize actually went + mColumn->mParentCtrl->dirtyColumns(); //Must flag as dirty, else updateColumns will probably be a noop. + mColumn->mParentCtrl->updateColumns(); + } +} + +void LLScrollColumnHeader::setHasResizableElement(BOOL resizable) +{ + if (mHasResizableElement != resizable) + { + mColumn->mParentCtrl->dirtyColumns(); + mHasResizableElement = resizable; + } +} + +void LLScrollColumnHeader::updateResizeBars() +{ + S32 num_resizable_columns = 0; + S32 col; + for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++) + { + LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col); + if (columnp->mHeader && columnp->mHeader->canResize()) + { + num_resizable_columns++; + } + } + + S32 num_resizers_enabled = 0; + + // now enable/disable resize handles on resizable columns if we have at least two + for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++) + { + LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col); + if (!columnp->mHeader) continue; + BOOL enable = num_resizable_columns >= 2 && num_resizers_enabled < (num_resizable_columns - 1) && columnp->mHeader->canResize(); + columnp->mHeader->enableResizeBar(enable); + if (enable) + { + num_resizers_enabled++; + } + } +} + +void LLScrollColumnHeader::enableResizeBar(BOOL enable) +{ + mResizeBar->setEnabled(enable); +} + +BOOL LLScrollColumnHeader::canResize() +{ + return getVisible() && (mHasResizableElement || mColumn->mDynamicWidth); +} + +void LLScrollListColumn::SortNames::declareValues() +{ + declare("ascending", LLScrollListColumn::ASCENDING); + declare("descending", LLScrollListColumn::DESCENDING); +} + +// +// LLScrollListColumn +// +/* Singu TODO: LLUICtrlFactory::getDefaultParams +//static +const LLScrollListColumn::Params& LLScrollListColumn::getDefaultParams() +{ + return LLUICtrlFactory::getDefaultParams(); +}*/ + + +LLScrollListColumn::LLScrollListColumn(const Params& p, LLScrollListCtrl* parent) +: mWidth(0), + mIndex (-1), + mParentCtrl(parent), + mName(p.name), + mLabel(p.header.label), + mHeader(NULL), + mMaxContentWidth(0), + mDynamicWidth(p.width.dynamic_width), + mRelWidth(p.width.relative_width), + mFontAlignment(p.halign), + mSortingColumn(p.sort_column) +{ + if (p.sort_ascending.isProvided()) + { + mSortDirection = p.sort_ascending() ? ASCENDING : DESCENDING; + } + else + { + mSortDirection = p.sort_direction; + } + + setWidth(p.width.pixel_width); +} + +void LLScrollListColumn::setWidth(S32 width) +{ + if (!mDynamicWidth && mRelWidth <= 0.f) + { + mParentCtrl->updateStaticColumnWidth(this, width); + } + mWidth = width; +} diff --git a/indra/llui/llscrolllistcolumn.h b/indra/llui/llscrolllistcolumn.h new file mode 100644 index 000000000..2026e075c --- /dev/null +++ b/indra/llui/llscrolllistcolumn.h @@ -0,0 +1,170 @@ +/** + * @file llscrollcolumnheader.h + * @brief Scroll lists are composed of rows (items), each of which + * contains columns (cells). + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LLSCROLLLISTCOLUMN_H +#define LLSCROLLLISTCOLUMN_H + +#include "llrect.h" +#include "lluistring.h" +#include "llbutton.h" +#include "llinitparam.h" + +class LLScrollListColumn; +class LLResizeBar; +class LLScrollListCtrl; + +class LLScrollColumnHeader : public LLButton +{ +public: + LLScrollColumnHeader(const std::string& name, const LLRect& rect, LLScrollListColumn* column); + ~LLScrollColumnHeader(); + + /*virtual*/ void draw(); + /*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen); + /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + + /*virtual*/ LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding); + /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false); + + LLScrollListColumn* getColumn() { return mColumn; } + void setHasResizableElement(BOOL resizable); + void updateResizeBars(); + BOOL canResize(); + void enableResizeBar(BOOL enable); + + void onClick(const LLSD& data); + +private: + LLScrollListColumn* mColumn; + LLResizeBar* mResizeBar; + BOOL mHasResizableElement; +}; + +/* + * A simple data class describing a column within a scroll list. + */ +class LLScrollListColumn +{ +public: + typedef enum e_sort_direction + { + DESCENDING, + ASCENDING + } ESortDirection; + + struct SortNames + : public LLInitParam::TypeValuesHelper + { + static void declareValues(); + }; + + struct Params : public LLInitParam::Block + { + Optional name, + tool_tip; + Optional sort_column; + Optional sort_direction; + Optional sort_ascending; + + struct Width : public LLInitParam::ChoiceBlock + { + Alternative dynamic_width; + Alternative pixel_width; + Alternative relative_width; + + Width() + : dynamic_width("dynamic_width", false), + pixel_width("width"), + relative_width("relative_width", -1.f) + { + addSynonym(dynamic_width, "dynamicwidth"); // Singu TODO: deprecate and remove + addSynonym(relative_width, "relwidth"); + } + }; + Optional width; + + // either an image or label is used in column header + struct Header : public LLInitParam::ChoiceBlock
+ { + Alternative label; + Alternative image_overlay; + Alternative image; + + Header() + : label("label"), + image_overlay("image_overlay"), + image("image") + {} + }; + Optional
header; + + Optional halign; + + Params() + : name("name"), + tool_tip("tool_tip"), + sort_column("sort_column"), + sort_direction("sort_direction"), + sort_ascending("sort_ascending", true), + halign("halign", LLFontGL::LEFT) + { + // default choice to "dynamic_width" + changeDefault(width.dynamic_width, true); + + addSynonym(sort_column, "sort"); + } + }; + + //static const Params& getDefaultParams(); + + //NOTE: this is default constructible so we can store it in a map. + LLScrollListColumn(const Params& p = Params(), LLScrollListCtrl* = NULL); + + void setWidth(S32 width); + S32 getWidth() const { return mWidth; } + +public: + // Public data is fine so long as this remains a simple struct-like data class. + // If it ever gets any smarter than that, these should all become private + // with protected or public accessor methods added as needed. -MG + std::string mName; + std::string mSortingColumn; + ESortDirection mSortDirection; + LLUIString mLabel; + F32 mRelWidth; + BOOL mDynamicWidth; + S32 mMaxContentWidth; + S32 mIndex; + LLScrollListCtrl* mParentCtrl; + LLScrollColumnHeader* mHeader; + LLFontGL::HAlign mFontAlignment; + +private: + S32 mWidth; +}; + +#endif diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index ee9b62a9a..6eca09c04 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1,65 +1,59 @@ /** * @file llscrolllistctrl.cpp - * @brief LLScrollListCtrl base class + * @brief Scroll lists are composed of rows (items), each of which + * contains columns (cells). * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * 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 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * 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 + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * 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. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#include - #include "linden_common.h" -#include "llstl.h" -#include "llboost.h" #include "llscrolllistctrl.h" -#include "indra_constants.h" +#include + +#include "llstl.h" +#include "llboost.h" +//#include "indra_constants.h" #include "llcheckboxctrl.h" #include "llclipboard.h" #include "llfocusmgr.h" #include "lllocalcliprect.h" -#include "llrender.h" +//#include "llrender.h" #include "llresmgr.h" #include "llscrollbar.h" +#include "llscrolllistcell.h" +#include "llscrolllistcolumn.h" +#include "llscrolllistitem.h" #include "llstring.h" #include "llui.h" #include "lluictrlfactory.h" #include "llwindow.h" #include "llcontrol.h" #include "llkeyboard.h" -#include "llresizebar.h" -// -#include "lllineeditor.h" -// +#include "llsdparam.h" +#include "llmenugl.h" -const S32 MIN_COLUMN_WIDTH = 20; -const S32 LIST_SNAP_PADDING = 5; static LLRegisterWidget r("scroll_list"); @@ -111,563 +105,12 @@ struct SortScrollListItem const sort_order_t& mSortOrders; }; - -// -// LLScrollListIcon -// -LLScrollListIcon::LLScrollListIcon(LLUIImagePtr icon, S32 width) - : LLScrollListCell(width), - mIcon(icon), - // - mCallback(NULL), - // - mColor(LLColor4::white) -{ -} - -LLScrollListIcon::LLScrollListIcon(const LLSD& value, S32 width) - : LLScrollListCell(width), - // - mCallback(NULL), - // - mColor(LLColor4::white) -{ - setValue(value); -} - - -LLScrollListIcon::~LLScrollListIcon() -{ -} - -/*virtual*/ -S32 LLScrollListIcon::getHeight() const -{ return mIcon ? mIcon->getHeight() : 0; } - -/*virtual*/ -const LLSD LLScrollListIcon::getValue() const -{ return mIcon.isNull() ? LLStringUtil::null : mIcon->getName(); } - -void LLScrollListIcon::setValue(const LLSD& value) -{ - if (value.isUUID()) - { - // don't use default image specified by LLUUID::null, use no image in that case - LLUUID image_id = value.asUUID(); - mIcon = image_id.notNull() ? LLUI::getUIImageByID(image_id) : LLUIImagePtr(NULL); - } - else - { - std::string value_string = value.asString(); - if (LLUUID::validate(value_string)) - { - setValue(LLUUID(value_string)); - } - else if (!value_string.empty()) - { - mIcon = LLUI::getUIImage(value.asString()); - } - else - { - mIcon = NULL; - } - } -} - - -void LLScrollListIcon::setColor(const LLColor4& color) -{ - mColor = color; -} - -S32 LLScrollListIcon::getWidth() const -{ - // if no specified fix width, use width of icon - if (LLScrollListCell::getWidth() == 0 && mIcon.notNull()) - { - return mIcon->getWidth(); - } - return LLScrollListCell::getWidth(); -} - -// -void LLScrollListIcon::setClickCallback(boost::function cb) -{ - mCallback = cb; -} - -BOOL LLScrollListIcon::handleClick() -{ - if(mCallback) return mCallback(); - return FALSE; -} -// - -void LLScrollListIcon::draw(const LLColor4& color, const LLColor4& highlight_color) const -{ - if (mIcon) - { - mIcon->draw(0, 0, mColor); - } -} - -// -// -// LLScrollListLineEditor -// -LLScrollListLineEditor::LLScrollListLineEditor(LLLineEditor* line_editor, S32 width) -{ - mLineEditor = line_editor; - LLRect rect(mLineEditor->getRect()); - if (width) - { - - rect.mRight = rect.mLeft + width; - mLineEditor->setRect(rect); - setWidth(width); - } - else - { - setWidth(rect.getWidth()); //line_editor->getWidth(); - } -} - -LLScrollListLineEditor::~LLScrollListLineEditor() -{ - delete mLineEditor; -} - -void LLScrollListLineEditor::draw(const LLColor4& color, const LLColor4& highlight_color) const -{ - mLineEditor->draw(); -} - -BOOL LLScrollListLineEditor::handleClick() -{ - if (mLineEditor->getEnabled()) - { - mLineEditor->setFocus(TRUE); - mLineEditor->selectAll(); - } - // return value changes selection? - return FALSE; //TRUE; -} - -BOOL LLScrollListLineEditor::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) -{ - return TRUE; -} - -BOOL LLScrollListLineEditor::handleUnicodeCharHere(llwchar uni_char ) -{ - return TRUE; -} -// - - -// -// LLScrollListText -// -U32 LLScrollListText::sCount = 0; - -LLScrollListText::LLScrollListText( const std::string& text, const LLFontGL* font, S32 width, U8 font_style, LLFontGL::HAlign font_alignment, LLColor4& color, BOOL use_color, BOOL visible) -: LLScrollListCell(width), - mText( text ), - mFont( font ), - mColor(color), - mUseColor(use_color), - mFontStyle( font_style ), - mFontAlignment( font_alignment ), - mVisible( visible ), - mHighlightCount( 0 ), - mHighlightOffset( 0 ) -{ - sCount++; - - mTextWidth = getWidth(); - - // initialize rounded rect image - if (!mRoundedRectImage) - { - mRoundedRectImage = LLUI::getUIImage("rounded_square.tga"); - } -} -//virtual -void LLScrollListText::highlightText(S32 offset, S32 num_chars) -{ - mHighlightOffset = offset; - mHighlightCount = num_chars; -} - -//virtual -BOOL LLScrollListText::isText() const -{ - return TRUE; -} - -//virtual -BOOL LLScrollListText::getVisible() const -{ - return mVisible; -} - -//virtual -S32 LLScrollListText::getHeight() const -{ - return llround(mFont->getLineHeight()); -} - - -LLScrollListText::~LLScrollListText() -{ - sCount--; -} - -S32 LLScrollListText::getContentWidth() const -{ - return mFont->getWidth(mText.getString()); -} - - -void LLScrollListText::setColor(const LLColor4& color) -{ - mColor = color; - mUseColor = TRUE; -} - -void LLScrollListText::setText(const LLStringExplicit& text) -{ - mText = text; -} - -void LLScrollListText::setFontStyle(const U8 font_style) -{ - mFontStyle = font_style; -} - -//virtual -void LLScrollListText::setValue(const LLSD& text) -{ - setText(text.asString()); -} - -//virtual -const LLSD LLScrollListText::getValue() const -{ - return LLSD(mText.getString()); -} - - -void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_color) const -{ - LLColor4 display_color; - if (mUseColor) - { - display_color = mColor; - } - else - { - display_color = color; - } - - if (mHighlightCount > 0) - { - S32 left = 0; - switch(mFontAlignment) - { - case LLFontGL::LEFT: - left = mFont->getWidth(mText.getString(), 0, mHighlightOffset); - break; - case LLFontGL::RIGHT: - left = getWidth() - mFont->getWidth(mText.getString(), mHighlightOffset, S32_MAX); - break; - case LLFontGL::HCENTER: - left = (getWidth() - mFont->getWidth(mText.getString())) / 2; - break; - } - LLRect highlight_rect(left - 2, - llround(mFont->getLineHeight()) + 1, - left + mFont->getWidth(mText.getString(), mHighlightOffset, mHighlightCount) + 1, - 1); - mRoundedRectImage->draw(highlight_rect, highlight_color); - } - - // Try to draw the entire string - F32 right_x; - U32 string_chars = mText.length(); - F32 start_x = 0.f; - switch(mFontAlignment) - { - case LLFontGL::LEFT: - start_x = (mFontStyle & LLFontGL::ITALIC) ? 2.f : 0.f; //Italic text seems need a little padding. - break; - case LLFontGL::RIGHT: - start_x = (F32)getWidth(); - break; - case LLFontGL::HCENTER: - start_x = (F32)getWidth() * 0.5f; - break; - } - mFont->render(mText.getWString(), 0, - start_x, 2.f, - display_color, - mFontAlignment, - LLFontGL::BOTTOM, - mFontStyle, - LLFontGL::NO_SHADOW, - string_chars, - getTextWidth(), - &right_x, - FALSE, - TRUE); -} - -// -// LLScrollListCheck -// -LLScrollListCheck::LLScrollListCheck(LLCheckBoxCtrl* check_box, S32 width) -{ - mCheckBox = check_box; - LLRect rect(mCheckBox->getRect()); - if (width) - { - - rect.mRight = rect.mLeft + width; - mCheckBox->setRect(rect); - setWidth(width); - } - else - { - setWidth(rect.getWidth()); //check_box->getWidth(); - } -} - -LLScrollListCheck::~LLScrollListCheck() -{ - delete mCheckBox; - mCheckBox = NULL; -} - -void LLScrollListCheck::draw(const LLColor4& color, const LLColor4& highlight_color) const -{ - mCheckBox->draw(); -} - -BOOL LLScrollListCheck::handleClick() -{ - if (mCheckBox->getEnabled()) - { - mCheckBox->toggle(); - } - // don't change selection when clicking on embedded checkbox - return TRUE; -} - -/*virtual*/ -const LLSD LLScrollListCheck::getValue() const -{ - return mCheckBox->getValue(); -} - -/*virtual*/ -void LLScrollListCheck::setValue(const LLSD& value) -{ - mCheckBox->setValue(value); -} - -/*virtual*/ -void LLScrollListCheck::onCommit() -{ - mCheckBox->onCommit(); -} - -/*virtual*/ -void LLScrollListCheck::setEnabled(BOOL enable) -{ - mCheckBox->setEnabled(enable); -} - -LLScrollListDate::LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width, U8 font_style, LLFontGL::HAlign font_alignment, LLColor4& color, BOOL use_color, BOOL visible) -: LLScrollListText(date.asRFC1123(), font, width, font_style, font_alignment, color, use_color, visible), - mDate(date) -{ -} - -void LLScrollListDate::setValue(const LLSD& value) -{ - mDate = value.asDate(); - LLScrollListText::setValue(mDate.asRFC1123()); -} - -const LLSD LLScrollListDate::getValue() const -{ - return mDate; -} - -LLScrollListItem::~LLScrollListItem() -{ - std::for_each(mColumns.begin(), mColumns.end(), DeletePointer()); -} - -void LLScrollListItem::setNumColumns(S32 columns) -{ - S32 prev_columns = mColumns.size(); - if (columns < prev_columns) - { - std::for_each(mColumns.begin()+columns, mColumns.end(), DeletePointer()); - } - - mColumns.resize(columns); - - for (S32 col = prev_columns; col < columns; ++col) - { - mColumns[col] = NULL; - } -} - -void LLScrollListItem::setColumn( S32 column, LLScrollListCell *cell ) -{ - if (column < (S32)mColumns.size()) - { - delete mColumns[column]; - mColumns[column] = cell; - } - else - { - llerrs << "LLScrollListItem::setColumn: bad column: " << column << llendl; - } -} - - -S32 LLScrollListItem::getNumColumns() const -{ - return mColumns.size(); -} - -LLScrollListCell* LLScrollListItem::getColumn(const S32 i) const -{ - if (0 <= i && i < (S32)mColumns.size()) - { - return mColumns[i]; - } - return NULL; -} - -std::string LLScrollListItem::getContentsCSV() const -{ - std::string ret; - - S32 count = getNumColumns(); - for (S32 i=0; igetValue().asString(); - if (i < count-1) - { - ret += ", "; - } - } - - return ret; -} - -void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) -{ - // draw background rect - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLRect bg_rect = rect; - gl_rect_2d( bg_rect, bg_color ); - - S32 cur_x = rect.mLeft; - S32 num_cols = getNumColumns(); - S32 cur_col = 0; - - for (LLScrollListCell* cell = getColumn(0); cur_col < num_cols; cell = getColumn(++cur_col)) - { - // Two ways a cell could be hidden - if (cell->getWidth() < 0 - || !cell->getVisible()) continue; - - LLUI::pushMatrix(); - { - LLUI::translate((F32) cur_x, (F32) rect.mBottom); - - cell->draw( fg_color, highlight_color ); - } - LLUI::popMatrix(); - - cur_x += cell->getWidth() + column_padding; - } -} - - -// -// LLScrollListSeparator -// -/* - * Draws a horizontal line. - */ -class LLScrollListSeparator : public LLScrollListCell -{ -public: - LLScrollListSeparator(S32 width) : LLScrollListCell(width) {} - virtual ~LLScrollListSeparator() {}; - virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const - { - // *FIXME: use dynamic item heights and make separators narrow, and inactive - gl_line_2d(5, 8, llmax(5, getWidth() - 5), 8, color); - } - virtual S32 getHeight() const { return 5; }; - virtual BOOL isText() const { return FALSE; } -}; - -//--------------------------------------------------------------------------- -// LLScrollListItemSeparator -//--------------------------------------------------------------------------- - -class LLScrollListItemSeparator : public LLScrollListItem -{ -public: - LLScrollListItemSeparator() : LLScrollListItem(FALSE) - { - LLScrollListSeparator* cell = new LLScrollListSeparator(0); - setNumColumns(1); - setColumn(0, cell); - } - - /*virtual*/ void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) - { - //TODO* move LLScrollListSeparator::draw into here and get rid of it - LLScrollListCell* cell = getColumn(0); - if (cell) - { - // Two ways a cell could be hidden - if (cell->getWidth() < 0 - || !cell->getVisible()) return; - - LLUI::pushMatrix(); - { - LLUI::translate((F32)rect.mLeft, (F32)rect.mBottom, 0.0f); - - // force first cell to be width of entire item - cell->setWidth(rect.getWidth()); - cell->draw( fg_color, highlight_color ); - } - LLUI::popMatrix(); - } - } -}; - //--------------------------------------------------------------------------- // LLScrollListCtrl //--------------------------------------------------------------------------- -LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, - commit_callback_t commit_callback, - BOOL allow_multiple_selection, - BOOL show_border, - bool draw_heading - ) - : LLUICtrl(name, rect, TRUE, commit_callback), +LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, commit_callback_t commit_callback, bool multi_select, bool has_border, bool draw_heading) +: LLUICtrl(name, rect, TRUE, commit_callback), mLineHeight(0), mScrollLines(0), mMouseWheelOpaque(true), @@ -682,7 +125,6 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, mColumnsDirty(false), mMaxItemCount(INT_MAX), mMaxContentWidth(0), - mDefaultListTextColor( LLUI::sColorsGroup->getColor("DefaultListText") ), mBorderThickness( 2 ), mOnDoubleClickCallback( NULL ), mOnMaximumSelectCallback( NULL ), @@ -690,6 +132,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, mHighlightedItem(-1), mBorder(NULL), mSortCallback(NULL), + mPopupMenu(NULL), mCommentTextView(NULL), mNumDynamicWidthColumns(0), mTotalStaticColumnWidth(0), @@ -697,20 +140,20 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, mSorted(true), mDirty(false), mOriginalSelection(-1), - mLastSelected(NULL), + mLastSelected(NULL), mHeadingHeight(20), - mAllowMultipleSelection( allow_multiple_selection ), + mAllowMultipleSelection(multi_select), mDisplayColumnHeaders(draw_heading), mBackgroundVisible(true), mDrawStripes(true), - mBgWriteableColor( LLUI::sColorsGroup->getColor( "ScrollBgWriteableColor" ) ), - mBgReadOnlyColor( LLUI::sColorsGroup->getColor( "ScrollBgReadOnlyColor" ) ), - mBgSelectedColor( LLUI::sColorsGroup->getColor("ScrollSelectedBGColor") ), - mBgStripeColor( LLUI::sColorsGroup->getColor("ScrollBGStripeColor") ), - mFgSelectedColor( LLUI::sColorsGroup->getColor("ScrollSelectedFGColor") ), - mFgUnselectedColor( LLUI::sColorsGroup->getColor("ScrollUnselectedColor") ), - mFgDisabledColor( LLUI::sColorsGroup->getColor("ScrollDisabledColor") ), - mHighlightedColor( LLUI::sColorsGroup->getColor("ScrollHighlightedColor") ), + mBgWriteableColor(LLUI::sColorsGroup->getColor("ScrollBgWriteableColor")), + mBgReadOnlyColor(LLUI::sColorsGroup->getColor("ScrollBgReadOnlyColor")), + mBgSelectedColor(LLUI::sColorsGroup->getColor("ScrollSelectedBGColor")), + mBgStripeColor(LLUI::sColorsGroup->getColor("ScrollBGStripeColor")), + mFgSelectedColor(LLUI::sColorsGroup->getColor("ScrollSelectedFGColor")), + mFgUnselectedColor(LLUI::sColorsGroup->getColor("ScrollUnselectedColor")), + mFgDisabledColor(LLUI::sColorsGroup->getColor("ScrollDisabledColor")), + mHighlightedColor(LLUI::sColorsGroup->getColor("ScrollHighlightedColor")), mSearchColumn(0), mColumnPadding(5) { @@ -735,16 +178,14 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, mScrollLines, getLinesPerPage(), boost::bind(&LLScrollListCtrl::onScrollChange, this, _1, _2) ); - mScrollbar->setFollowsRight(); - mScrollbar->setFollowsTop(); - mScrollbar->setFollowsBottom(); - mScrollbar->setEnabled( TRUE ); + mScrollbar->setFollows(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM); + mScrollbar->setEnabled(true); // scrollbar is visible only when needed - mScrollbar->setVisible(FALSE); + mScrollbar->setVisible(false); addChild(mScrollbar); // Border - if (show_border) + if (has_border) { LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 ); mBorder = new LLViewBorder( std::string("dlg border"), border_rect, LLViewBorder::BEVEL_IN, LLViewBorder::STYLE_LINE, 1 ); @@ -753,7 +194,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, LLTextBox* textBox = new LLTextBox("comment_text",mItemListRect,std::string()); textBox->setBorderVisible(false); - textBox->setFollowsAll(); + textBox->setFollows(FOLLOWS_ALL); textBox->setFontShadow(LLFontGL::NO_SHADOW); textBox->setColor(LLUI::sColorsGroup->getColor("DefaultListText")); addChild(textBox); @@ -854,7 +295,6 @@ std::vector LLScrollListCtrl::getAllSelected() const return ret; } - item_list::const_iterator iter; for(iter = mItemList.begin(); iter != mItemList.end(); iter++) { @@ -885,7 +325,7 @@ S32 LLScrollListCtrl::getNumSelected() const { return 0; } - + S32 numSelected = 0; for(item_list::const_iterator iter = mItemList.begin(); iter != mItemList.end(); ++iter) @@ -907,7 +347,6 @@ S32 LLScrollListCtrl::getFirstSelectedIndex() const return -1; } - S32 CurSelectedIndex = 0; // make sure sort is up to date before returning an index @@ -1065,11 +504,8 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r single_sort_column.push_back(std::make_pair(0, TRUE)); mItemList.push_back(item); - std::stable_sort( - mItemList.begin(), - mItemList.end(), - SortScrollListItem(single_sort_column,mSortCallback)); - + std::stable_sort(mItemList.begin(), mItemList.end(), SortScrollListItem(single_sort_column,mSortCallback)); + // ADD_SORTED just sorts by first column... // this might not match user sort criteria, so flag list as being in unsorted state setNeedsSort(); @@ -1090,11 +526,11 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r // create new column on demand if (mColumns.empty() && requires_column) { - LLSD new_column; - new_column["name"] = "default_column"; - new_column["label"] = ""; - new_column["dynamicwidth"] = TRUE; - addColumn(new_column); + LLScrollListColumn::Params col_params; + col_params.name = "default_column"; + col_params.header.label = ""; + col_params.width.dynamic_width = true; + addColumn(col_params); } S32 num_cols = item->getNumColumns(); @@ -1146,7 +582,7 @@ S32 LLScrollListCtrl::calcMaxContentWidth() } max_item_width += column->mMaxContentWidth; } - + mMaxContentWidth = max_item_width; return max_item_width; } @@ -1286,13 +722,6 @@ void LLScrollListCtrl::updateColumns() } } -void LLScrollListCtrl::setDisplayHeading(BOOL display) -{ - mDisplayColumnHeaders = display; - - updateLayout(); -} - void LLScrollListCtrl::setHeadingHeight(S32 heading_height) { mHeadingHeight = heading_height; @@ -1438,7 +867,7 @@ void LLScrollListCtrl::moveToFront(S32 index) { return; } - + LLScrollListCtrl::item_list::iterator it = mItemList.begin(); std::advance(it,index); mItemList.push_front(*it); @@ -1689,7 +1118,6 @@ void LLScrollListCtrl::deselectAllItems(BOOL no_commit_on_change) /////////////////////////////////////////////////////////////////////////////////////////////////// // Use this to add comment text such as "Searching", which ignores column settings of list - void LLScrollListCtrl::setCommentText(const std::string& comment_text) { getChild("comment_text")->setWrappedText(comment_text); @@ -1697,13 +1125,20 @@ void LLScrollListCtrl::setCommentText(const std::string& comment_text) LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos) { - LLScrollListItem* item = new LLScrollListItemSeparator(); - addItem(item, pos, FALSE); - return item; + LLScrollListItem::Params separator_params; + separator_params.enabled(false); + LLScrollListCell::Params column_params; + column_params.type = "icon"; + column_params.value = "menu_separator.png"; + column_params.color = LLColor4(0.f, 0.f, 0.f, 0.7f); + column_params.font_halign = LLFontGL::HCENTER; + separator_params.columns.add(column_params); + return addRow( separator_params, pos ); } // Selects first enabled item of the given name. // Returns false if item not found. +// Calls getItemByLabel in order to combine functionality BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sensitive) { deselectAllItems(TRUE); // ensure that no stale items are selected, even if we don't find a match @@ -1852,16 +1287,18 @@ const std::string LLScrollListCtrl::getSelectedItemLabel(S32 column) const // "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which // has an associated, unique UUID, and only one of which can be selected at a time. -LLScrollListItem* LLScrollListCtrl::addStringUUIDItem(const std::string& item_text, const LLUUID& id, EAddPosition pos, BOOL enabled, S32 column_width) +LLScrollListItem* LLScrollListCtrl::addStringUUIDItem(const std::string& item_text, const LLUUID& id, EAddPosition pos, BOOL enabled) { - LLScrollListItem* item = NULL; if (getItemCount() < mMaxItemCount) { - item = new LLScrollListItem( enabled, NULL, id ); - item->addColumn(item_text, LLResMgr::getInstance()->getRes(LLFONT_SANSSERIF_SMALL), column_width); - addItem( item, pos ); + LLScrollListItem::Params item_p; + item_p.enabled(enabled); + item_p.value(id); + item_p.columns.add().value(item_text).type("text"); + + return addRow( item_p, pos ); } - return item; + return NULL; } // Select the line or lines that match this UUID @@ -2104,22 +1541,13 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti BOOL handled = FALSE; // show tooltip for full name of hovered item if it has been truncated LLScrollListItem* hit_item = hitItem(x, y); - if (hit_item) { - // If the item has a specific tool tip set by XUI use that first - std::string tooltip=hit_item->getToolTip(); - if(!tooltip.empty()) - { - msg=tooltip; - return TRUE; - } - LLScrollListCell* hit_cell = hit_item->getColumn(column_index); if (!hit_cell) return FALSE; - //S32 cell_required_width = hit_cell->getContentWidth(); if (hit_cell - && hit_cell->isText()) + //&& hit_cell->isText() // Singu Note: We welcome tooltips on any kind of cell + && hit_cell->needsToolTip()) { S32 row_index = getItemIndex(hit_item); LLRect cell_rect = getCellRect(row_index, column_index); @@ -2127,7 +1555,7 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti LLRect sticky_rect; localRectToScreen(cell_rect, sticky_rect_screen); - msg = hit_cell->getValue().asString(); + msg = hit_cell->getToolTip(); } handled = TRUE; } @@ -2136,7 +1564,13 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti LLScrollColumnHeader* headerp = columnp->mHeader; if (headerp && !handled) { - headerp->handleToolTip(x, y, msg, sticky_rect_screen); + handled = headerp->handleToolTip(x, y, msg, sticky_rect_screen); + } + + // Singu Note: If all else fails, try to use our own tooltip + if (!handled) + { + msg = LLUI::sShowXUINames ? getShowNamesToolTip() : getToolTip(); handled = !msg.empty(); } @@ -2262,8 +1696,6 @@ BOOL LLScrollListCtrl::handleMouseDown(S32 x, S32 y, MASK mask) mSelectionChanged = false; handleClick(x, y, mask); - - setFocus(TRUE); } return TRUE; @@ -2294,6 +1726,25 @@ BOOL LLScrollListCtrl::handleMouseUp(S32 x, S32 y, MASK mask) return LLUICtrl::handleMouseUp(x, y, mask); } +// virtual +BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + if (!mPopupMenu) return FALSE; // No menu, no bother + LLScrollListItem *item = hitItem(x, y); + if (item) + { + if (!item->getSelected()) selectItem(item); // Right click on unselected item is for that item only + } + else if (LLScrollListColumn* col = getColumn(getColumnIndexFromOffset(x))) + { + if (col->mHeader && col->mHeader->getRect().pointInRect(x,y)) // Right clicking a column header shouldn't bring up a menu + return FALSE; + } + mPopupMenu->buildDrawLabels(); + LLMenuGL::showPopup(this, mPopupMenu, x, y); + return TRUE; +} + BOOL LLScrollListCtrl::handleDoubleClick(S32 x, S32 y, MASK mask) { //BOOL handled = FALSE; @@ -2492,6 +1943,11 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask) return handled; } +void LLScrollListCtrl::onMouseLeave(S32 x, S32 y, MASK mask) +{ + // clear mouse highlight + mouseOverHighlightNthItem(-1); +} BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) { @@ -2851,6 +2307,7 @@ S32 LLScrollListCtrl::getLinesPerPage() } } + // Called by scrollbar void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar ) { @@ -2982,25 +2439,16 @@ void LLScrollListCtrl::updateStaticColumnWidth(LLScrollListColumn* col, S32 new_ LLXMLNodePtr LLScrollListCtrl::getXML(bool save_children) const { LLXMLNodePtr node = LLUICtrl::getXML(); - node->setName(LL_SCROLL_LIST_CTRL_TAG); // Attributes - node->createChild("multi_select", TRUE)->setBoolValue(mAllowMultipleSelection); - node->createChild("draw_border", TRUE)->setBoolValue((mBorder != NULL)); - node->createChild("draw_heading", TRUE)->setBoolValue(mDisplayColumnHeaders); - node->createChild("background_visible", TRUE)->setBoolValue(mBackgroundVisible); - node->createChild("draw_stripes", TRUE)->setBoolValue(mDrawStripes); - node->createChild("column_padding", TRUE)->setIntValue(mColumnPadding); - node->createChild("mouse_wheel_opaque", TRUE)->setBoolValue(mMouseWheelOpaque); - addColorXML(node, mBgWriteableColor, "bg_writeable_color", "ScrollBgWriteableColor"); addColorXML(node, mBgReadOnlyColor, "bg_read_only_color", "ScrollBgReadOnlyColor"); addColorXML(node, mBgSelectedColor, "bg_selected_color", "ScrollSelectedBGColor"); @@ -3011,8 +2459,6 @@ LLXMLNodePtr LLScrollListCtrl::getXML(bool save_children) const addColorXML(node, mHighlightedColor, "highlighted_color", "ScrollHighlightedColor"); // Contents - - std::map::const_iterator itor; std::vector sorted_list; sorted_list.resize(mColumns.size()); for (column_map_t::const_iterator itor = mColumns.begin(); itor != mColumns.end(); ++itor) @@ -3020,8 +2466,7 @@ LLXMLNodePtr LLScrollListCtrl::getXML(bool save_children) const sorted_list[itor->second->mIndex] = itor->second; } - std::vector::iterator itor2; - for (itor2 = sorted_list.begin(); itor2 != sorted_list.end(); ++itor2) + for (std::vector::iterator itor2 = sorted_list.begin(); itor2 != sorted_list.end(); ++itor2) { LLXMLNodePtr child_node = node->createChild("column", FALSE); const LLScrollListColumn *column = *itor2; @@ -3107,34 +2552,20 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac LLRect rect; createRect(node, rect, parent, LLRect()); - BOOL multi_select = FALSE; + BOOL multi_select = false; node->getAttributeBOOL("multi_select", multi_select); - - BOOL draw_border = TRUE; + BOOL draw_border = true; node->getAttributeBOOL("draw_border", draw_border); - - BOOL draw_heading = FALSE; + BOOL draw_heading = false; node->getAttributeBOOL("draw_heading", draw_heading); - S32 search_column = 0; node->getAttributeS32("search_column", search_column); - S32 sort_column = -1; node->getAttributeS32("sort_column", sort_column); - - BOOL sort_ascending = TRUE; + BOOL sort_ascending = true; node->getAttributeBOOL("sort_ascending", sort_ascending); - - BOOL mouse_wheel_opaque = TRUE; - node->getAttributeBOOL("mouse_wheel_opaque", mouse_wheel_opaque); - LLScrollListCtrl* scroll_list = new LLScrollListCtrl( - "scroll_list", - rect, - NULL, - multi_select, - draw_border, - draw_heading); + LLScrollListCtrl* scroll_list = new LLScrollListCtrl("scroll_list", rect, NULL, multi_select, draw_border, draw_heading); if (node->hasAttribute("heading_height")) { @@ -3144,66 +2575,71 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac } scroll_list->setScrollListParameters(node); - scroll_list->initFromXML(node, parent); - scroll_list->setSearchColumn(search_column); - + + BOOL mouse_wheel_opaque = true; + node->getAttributeBOOL("mouse_wheel_opaque", mouse_wheel_opaque); scroll_list->mMouseWheelOpaque = mouse_wheel_opaque; + std::string tool_tip; + node->getAttributeString("tool_tip", tool_tip); + scroll_list->setToolTip(tool_tip); + + std::string menu_file; + if (node->getAttributeString("menu_file", menu_file)) + { + LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu(menu_file, LLMenuGL::sMenuContainer); + LLMenuGL::sMenuContainer->addChild(menu); + scroll_list->setContextMenu(menu); + } + LLSD columns; S32 index = 0; - LLXMLNodePtr child; - for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) + for (LLXMLNodePtr child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) { if (child->hasName("column")) { std::string labelname(""); - child->getAttributeString("label", labelname); + if (child->getAttributeString("label", labelname)) + columns[index]["label"] = labelname; + else if (child->getAttributeString("image", labelname)) + columns[index]["image"] = labelname; + else if (child->getAttributeString("image_overlay", labelname)) + columns[index]["image_overlay"] = labelname; std::string columnname(labelname); - child->getAttributeString("name", columnname); + if (child->getAttributeString("name", columnname)) + columns[index]["name"] = columnname; std::string sortname(columnname); - child->getAttributeString("sort", sortname); - - BOOL sort_ascending = TRUE; - child->getAttributeBOOL("sort_ascending", sort_ascending); + if (child->getAttributeString("sort", sortname)) + columns[index]["sort"] = sortname; - std::string imagename; - child->getAttributeString("image", imagename); - - std::string imageoverlay; - child->getAttributeString("image_overlay", imageoverlay); - - BOOL columndynamicwidth = FALSE; - child->getAttributeBOOL("dynamicwidth", columndynamicwidth); + BOOL sort_ascending = true; + if (child->getAttributeBOOL("sort_ascending", sort_ascending)) + columns[index]["sort_ascending"] = sort_ascending; S32 columnwidth = -1; - child->getAttributeS32("width", columnwidth); - - std::string tooltip; - child->getAttributeString("tool_tip", tooltip); + if (child->getAttributeS32("width", columnwidth)) + columns[index]["width"] = columnwidth; F32 columnrelwidth = 0.f; - child->getAttributeF32("relwidth", columnrelwidth); + if (child->getAttributeF32("relwidth", columnrelwidth)) + columns[index]["relwidth"] = columnrelwidth; - LLFontGL::HAlign h_align = LLFontGL::LEFT; - h_align = LLView::selectFontHAlign(child); + BOOL columndynamicwidth = false; + if (child->getAttributeBOOL("dynamic_width", columndynamicwidth) + || child->getAttributeBOOL("dynamicwidth", columndynamicwidth)) // Singu TODO: Deprecate "dynamicwidth" + columns[index]["dynamic_width"] = columndynamicwidth; - columns[index]["name"] = columnname; - columns[index]["sort"] = sortname; - columns[index]["sort_ascending"] = sort_ascending; - columns[index]["image"] = imagename; - columns[index]["image_overlay"] = imageoverlay; - columns[index]["label"] = labelname; - columns[index]["width"] = columnwidth; - columns[index]["relwidth"] = columnrelwidth; - columns[index]["dynamicwidth"] = columndynamicwidth; + LLFontGL::HAlign h_align = LLView::selectFontHAlign(child); columns[index]["halign"] = (S32)h_align; - columns[index]["tool_tip"] = tooltip; - - index++; + + std::string tooltip; + if (child->getAttributeString("tool_tip", tooltip)) + columns[index]["tool_tip"] = tooltip; + ++index; } } scroll_list->setColumnHeadings(columns); @@ -3213,7 +2649,7 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac scroll_list->sortByColumnIndex(sort_column, sort_ascending); } - for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) + for (LLXMLNodePtr child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) { if (child->hasName("row") || child->hasName("rows")) { @@ -3229,27 +2665,26 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac S32 column_idx = 0; bool explicit_column = false; - LLXMLNodePtr row_child; - for (row_child = child->getFirstChild(); row_child.notNull(); row_child = row_child->getNextSibling()) + for (LLXMLNodePtr row_child = child->getFirstChild(); row_child.notNull(); row_child = row_child->getNextSibling()) { if (row_child->hasName("column")) { std::string value = row_child->getTextContents(); + row["columns"][column_idx]["value"] = value; std::string columnname(""); - row_child->getAttributeString("name", columnname); + if (row_child->getAttributeString("name", columnname)) + row["columns"][column_idx]["column"] = columnname; std::string font(""); - row_child->getAttributeString("font", font); + if (row_child->getAttributeString("font", font)) + row["columns"][column_idx]["font"] = font; std::string font_style(""); - row_child->getAttributeString("font-style", font_style); + if (row_child->getAttributeString("font-style", font_style)) + row["columns"][column_idx]["font-style"] = font_style; - row["columns"][column_idx]["column"] = columnname; - row["columns"][column_idx]["value"] = value; - row["columns"][column_idx]["font"] = font; - row["columns"][column_idx]["font-style"] = font_style; - column_idx++; + ++column_idx; explicit_column = true; } } @@ -3265,9 +2700,7 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac } } - std::string contents = node->getTextContents(); - scroll_list->setCommentText(contents); - + scroll_list->setCommentText(node->getTextContents()); return scroll_list; } @@ -3346,20 +2779,28 @@ BOOL LLScrollListCtrl::canDeselect() const void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) { - std::string name = column["name"].asString(); + LLScrollListColumn::Params p; + LLParamSDParser parser; + parser.readSD(column, p); + addColumn(p, pos); +} + +void LLScrollListCtrl::addColumn(const LLScrollListColumn::Params& column_params, EAddPosition pos) +{ + if (!column_params.validateBlock()) return; + + std::string name = column_params.name; // if no column name provided, just use ordinal as name if (name.empty()) { - std::ostringstream new_name; - new_name << mColumnsIndexed.size(); - name = new_name.str(); + name = llformat("%d", mColumnsIndexed.size()); } + if (mColumns.find(name) == mColumns.end()) { // Add column - LLScrollListColumn* new_column = new LLScrollListColumn(column, this); - mColumns[name] = new_column; - new_column->mParentCtrl = this; + mColumns[name] = new LLScrollListColumn(column_params, this); + LLScrollListColumn* new_column = mColumns[name]; new_column->mIndex = mColumns.size()-1; // Add button @@ -3392,36 +2833,33 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) } } - std::string button_name = "btn_" + name; S32 right = left+new_column->getWidth(); if (new_column->mIndex != (S32)mColumns.size()-1) { right += mColumnPadding; } + LLRect temp_rect = LLRect(left,top+mHeadingHeight,right,top); - new_column->mHeader = new LLScrollColumnHeader(button_name, temp_rect, new_column); - if(column["image"].asString() != "") + + new_column->mHeader = new LLScrollColumnHeader("btn_" + name, temp_rect, new_column); + new_column->mHeader->setToolTip(column_params.tool_tip()); + new_column->mHeader->setTabStop(false); + new_column->mHeader->setVisible(mDisplayColumnHeaders); + + if(column_params.header.image.isProvided()) { - //new_column->mHeader->setScaleImage(false); - new_column->mHeader->setImage(column["image"].asString()); + new_column->mHeader->setImages(column_params.header.image, column_params.header.image); } - else if(column["image_overlay"].asString() != "") + else if(column_params.header.image_overlay.isProvided()) { - new_column->mHeader->setImageOverlay(column["image_overlay"].asString()); + new_column->mHeader->setImageOverlay(column_params.header.image_overlay); } else { - new_column->mHeader->setLabel(new_column->mLabel); - //new_column->mHeader->setLabel(new_column->mLabel); + new_column->mHeader->setLabel(column_params.header.label()); } - new_column->mHeader->setToolTip(column["tool_tip"].asString()); - - //RN: although it might be useful to change sort order with the keyboard, - // mixing tab stops on child items along with the parent item is not supported yet - new_column->mHeader->setTabStop(FALSE); addChild(new_column->mHeader); - new_column->mHeader->setVisible(mDisplayColumnHeaders); sendChildToFront(mScrollbar); } @@ -3534,7 +2972,7 @@ LLScrollListColumn* LLScrollListCtrl::getColumn(const std::string& name) return NULL; } -void LLScrollListCtrl::setColumnHeadings(LLSD headings) +void LLScrollListCtrl::setColumnHeadings(const LLSD& headings) { mColumns.clear(); LLSD::array_const_iterator itor; @@ -3551,65 +2989,62 @@ void LLScrollListCtrl::setColumnHeadings(LLSD headings) "name" "label" "width" - "dynamic_width" + "dynamic_width" */ -LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition pos, void* userdata) +LLFastTimer::DeclareTimer FTM_ADD_SCROLLLIST_ELEMENT("Add Scroll List Item"); +LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& element, EAddPosition pos, void* userdata) { - // ID - LLSD id = value["id"]; + LLFastTimer _(FTM_ADD_SCROLLLIST_ELEMENT); + LLScrollListItem::Params item_params; + LLParamSDParser parser; + parser.readSD(element, item_params); + item_params.userdata = userdata; + return addRow(item_params, pos); +} - LLScrollListItem *new_item = new LLScrollListItem(id, userdata); - if (value.has("enabled")) - { - new_item->setEnabled( value["enabled"].asBoolean() ); - } +LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_p, EAddPosition pos) +{ + LLFastTimer _(FTM_ADD_SCROLLLIST_ELEMENT); + LLScrollListItem *new_item = new LLScrollListItem(item_p); + return addRow(new_item, item_p, pos); +} +LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLScrollListItem::Params& item_p, EAddPosition pos) +{ + LLFastTimer _(FTM_ADD_SCROLLLIST_ELEMENT); + if (!item_p.validateBlock() || !new_item) return NULL; new_item->setNumColumns(mColumns.size()); // Add any columns we don't already have - LLSD columns = value["columns"]; - LLSD::array_const_iterator itor; - S32 col_index = 0 ; - for (itor = columns.beginArray(); itor != columns.endArray(); ++itor) - { - if (itor->isUndefined()) - { - // skip unused columns in item passed in - continue; - } - std::string column = (*itor)["column"].asString(); + S32 col_index = 0; - LLScrollListColumn* columnp = NULL; + for(LLInitParam::ParamIterator::const_iterator itor = item_p.columns.begin(); + itor != item_p.columns.end(); + ++itor) + { + LLScrollListCell::Params cell_p = *itor; + std::string column = cell_p.column; // empty columns strings index by ordinal if (column.empty()) { - std::ostringstream new_name; - new_name << col_index; - column = new_name.str(); + column = llformat("%d", col_index); } - column_map_t::iterator column_itor = mColumns.find(column); - if (column_itor != mColumns.end()) - { - columnp = column_itor->second; - } + LLScrollListColumn* columnp = getColumn(column); // create new column on demand if (!columnp) { - LLSD new_column; - new_column["name"] = column; - new_column["label"] = column; + LLScrollListColumn::Params new_column; + new_column.name = column; + new_column.header.label = column; + // if width supplied for column, use it, otherwise // use adaptive width - if (itor->has("width")) + if (cell_p.width.isProvided()) { - new_column["width"] = (*itor)["width"]; - } - else - { - new_column["dynamicwidth"] = true; + new_column.width.pixel_width = cell_p.width; } addColumn(new_column); columnp = mColumns[column]; @@ -3617,104 +3052,20 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p } S32 index = columnp->mIndex; - S32 width = columnp->getWidth(); - LLFontGL::HAlign font_alignment = columnp->mFontAlignment; - LLColor4 fcolor = LLColor4::black; - - LLSD value = (*itor)["value"]; - std::string fontname = (*itor)["font"].asString(); - std::string fontstyle = (*itor)["font-style"].asString(); - std::string type = (*itor)["type"].asString(); - - if ((*itor).has("font-color")) + if (!cell_p.width.isProvided()) { - LLSD sd_color = (*itor)["font-color"]; - fcolor.setValue(sd_color); + cell_p.width = columnp->getWidth(); } - - BOOL has_color = (*itor).has("color"); - LLColor4 color = ((*itor)["color"]); - BOOL enabled = !(*itor).has("enabled") || (*itor)["enabled"].asBoolean() == true; + cell_p.font_halign = columnp->mFontAlignment; - const LLFontGL *font = LLResMgr::getInstance()->getRes(fontname); - if (!font) - { - font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ); - } - U8 font_style = LLFontGL::getStyleFromString(fontstyle); + LLScrollListCell* cell = LLScrollListCell::create(cell_p); - if (type == "icon") + if (cell) { - LLScrollListIcon* cell = new LLScrollListIcon(value, width); - if (has_color) - { - cell->setColor(color); - } new_item->setColumn(index, cell); - } - else if (type == "checkbox") - { - LLCheckBoxCtrl* ctrl = new LLCheckBoxCtrl(std::string("check"), - LLRect(0, width, width, 0), std::string(" ")); - ctrl->setEnabled(enabled); - ctrl->setValue(value); - LLScrollListCheck* cell = new LLScrollListCheck(ctrl,width); - if (has_color) - { - cell->setColor(color); - } - new_item->setColumn(index, cell); - } - else if (type == "separator") - { - LLScrollListSeparator* cell = new LLScrollListSeparator(width); - if (has_color) - { - cell->setColor(color); - } - new_item->setColumn(index, cell); - } - else if (type == "date") - { - LLScrollListDate* cell = new LLScrollListDate(value.asDate(), font, width, font_style, font_alignment); - if (has_color) - { - cell->setColor(color); - } - new_item->setColumn(index, cell); - if (columnp->mHeader && !value.asString().empty()) - { - columnp->mHeader->setHasResizableElement(TRUE); - } - } - // - else if(type == "line_editor") - { - LLLineEditor* ctrl = new LLLineEditor(std::string("line_editor"), - LLRect(0, width, width, 0), std::string("")); - ctrl->setEnabled(enabled); - ctrl->setValue(value); - LLScrollListLineEditor* cell = new LLScrollListLineEditor(ctrl,width); - if (has_color) - { - cell->setColor(color); - } - new_item->setColumn(index, cell); - } - // - else - { - LLScrollListText* cell = new LLScrollListText(value.asString(), font, width, font_style, font_alignment, fcolor, TRUE); - if (has_color) - { - cell->setColor(color); - } - else - { - cell->setColor(mDefaultListTextColor); - } - new_item->setColumn(index, cell); - if (columnp->mHeader && !value.asString().empty()) + if (columnp->mHeader + && cell->isText() + && !cell->getValue().asString().empty()) { columnp->mHeader->setHasResizableElement(TRUE); } @@ -3723,6 +3074,32 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p col_index++; } + if (item_p.columns.empty()) + { + if (mColumns.empty()) + { + LLScrollListColumn::Params new_column; + new_column.name = "0"; + + addColumn(new_column); + new_item->setNumColumns(mColumns.size()); + } + + LLScrollListCell* cell = LLScrollListCell::create(LLScrollListCell::Params().value(item_p.value)); + if (cell) + { + LLScrollListColumn* columnp = mColumns.begin()->second; + + new_item->setColumn(0, cell); + if (columnp->mHeader + && cell->isText() + && !cell->getValue().asString().empty()) + { + columnp->mHeader->setHasResizableElement(TRUE); + } + } + } + // add dummy cells for missing columns for (column_map_t::iterator column_it = mColumns.begin(); column_it != mColumns.end(); ++column_it) { @@ -3730,12 +3107,14 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p if (new_item->getColumn(column_idx) == NULL) { LLScrollListColumn* column_ptr = column_it->second; - new_item->setColumn(column_idx, new LLScrollListText(LLStringUtil::null, LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->getWidth(), LLFontGL::NORMAL)); + LLScrollListCell::Params cell_p; + cell_p.width = column_ptr->getWidth(); + + new_item->setColumn(column_idx, new LLScrollListSpacer(cell_p)); } } addItem(new_item, pos); - return new_item; } @@ -3748,14 +3127,13 @@ LLScrollListItem* LLScrollListCtrl::addSimpleElement(const std::string& value, E entry_id = value; } - LLScrollListItem *new_item = new LLScrollListItem(entry_id); + LLScrollListItem::Params item_params; + item_params.value(entry_id); + item_params.columns.add() + .value(value) + /*.font(LLFontGL::getFontSansSerifSmall())*/; - const LLFontGL *font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ); - - new_item->addColumn(value, font, getRect().getWidth()); - - addItem(new_item, pos); - return new_item; + return addRow(item_params, pos); } void LLScrollListCtrl::setValue(const LLSD& value ) @@ -3858,583 +3236,3 @@ void LLScrollListCtrl::onFocusLost() LLUICtrl::onFocusLost(); } -LLScrollColumnHeader::LLScrollColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL* fontp) : - LLComboBox(label, rect, label), - mColumn(column), - mOrigLabel(label), - mShowSortOptions(FALSE), - mHasResizableElement(FALSE) -{ - mListPosition = LLComboBox::ABOVE; - setCommitCallback(boost::bind(&LLScrollColumnHeader::onSelectSort, this)); - mButton->setTabStop(FALSE); - // require at least two frames between mouse down and mouse up event to capture intentional "hold" not just bad framerate - mButton->setHeldDownDelay(LLUI::sConfigGroup->getF32("ColumnHeaderDropDownDelay"), 2); - mButton->setHeldDownCallback(boost::bind(&LLScrollColumnHeader::showList, this)); - mButton->setClickedCallback(boost::bind(&LLScrollColumnHeader::onClick, this)); - mButton->setMouseDownCallback(boost::bind(&LLScrollColumnHeader::onMouseDown, this)); - - mButton->setToolTip(label); - - mAscendingText = std::string("[LOW]...[HIGH](Ascending)"); // *TODO: Translate - mDescendingText = std::string("[HIGH]...[LOW](Descending)"); // *TODO: Translate - - mList->reshape(llmax(mList->getRect().getWidth(), 110, getRect().getWidth()), mList->getRect().getHeight()); - - // resize handles on left and right - const S32 RESIZE_BAR_THICKNESS = 3; - LLResizeBar::Params p; - p.name = "resizebar"; - p.resizing_view = this; - p.rect = LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0); - p.min_size = MIN_COLUMN_WIDTH; - p.max_size = S32_MAX; - p.side = LLResizeBar::RIGHT; - mResizeBar = LLUICtrlFactory::create(p); - addChild(mResizeBar); - - mResizeBar->setEnabled(FALSE); - - mImageOverlayAlignment = LLFontGL::HCENTER; - mImageOverlayColor = LLColor4::white; -} - -LLScrollColumnHeader::~LLScrollColumnHeader() -{ -} - -void LLScrollColumnHeader::draw() -{ - std::string sort_column = mColumn->mParentCtrl->getSortColumnName(); - BOOL draw_arrow = !mColumn->mLabel.empty() - && mColumn->mParentCtrl->isSorted() - // check for indirect sorting column as well as column's sorting name - && (sort_column == mColumn->mSortingColumn || sort_column == mColumn->mName); - - BOOL is_ascending = mColumn->mParentCtrl->getSortAscending(); - mButton->setImageOverlay(is_ascending ? "up_arrow.tga" : "down_arrow.tga", LLFontGL::RIGHT, draw_arrow ? LLColor4::white : LLColor4::transparent); - mArrowImage = mButton->getImageOverlay(); - - //BOOL clip = getRect().mRight > mColumn->mParentCtrl->getItemListRect().getWidth(); - //LLGLEnable scissor_test(clip ? GL_SCISSOR_TEST : GL_FALSE); - - //LLRect column_header_local_rect(-getRect().mLeft, getRect().getHeight(), mColumn->mParentCtrl->getItemListRect().getWidth() - getRect().mLeft, 0); - //LLUI::setScissorRegionLocal(column_header_local_rect); - - // Draw children - LLComboBox::draw(); - - if (mImageOverlay.notNull()) //Ugly dupe code from llbutton... - { - BOOL pressed_by_keyboard = FALSE; - if (mButton->hasFocus()) - { - pressed_by_keyboard = gKeyboard->getKeyDown(' ') || (mButton->getCommitOnReturn() && gKeyboard->getKeyDown(KEY_RETURN)); - } - - // Unselected image assignments - S32 local_mouse_x; - S32 local_mouse_y; - LLUI::getMousePositionLocal(mButton, &local_mouse_x, &local_mouse_y); - - BOOL pressed = pressed_by_keyboard - || (mButton->hasMouseCapture() && mButton->pointInView(local_mouse_x, local_mouse_y)) - || mButton->getToggleState(); - - // Now draw special overlay.. - // let overlay image and text play well together - S32 button_width = mButton->getRect().getWidth(); - S32 button_height = mButton->getRect().getHeight(); - S32 text_left = mButton->getLeftHPad(); - S32 text_right = button_width - mButton->getRightHPad(); - S32 text_width = text_right - text_left; - - // draw overlay image - - // get max width and height (discard level 0) - S32 overlay_width = mImageOverlay->getWidth(); - S32 overlay_height = mImageOverlay->getHeight(); - - F32 scale_factor = llmin((F32)button_width / (F32)overlay_width, (F32)button_height / (F32)overlay_height, 1.f); - overlay_width = llround((F32)overlay_width * scale_factor); - overlay_height = llround((F32)overlay_height * scale_factor); - - S32 center_x = mButton->getLocalRect().getCenterX(); - S32 center_y = mButton->getLocalRect().getCenterY(); - - //FUGLY HACK FOR "DEPRESSED" BUTTONS - if (pressed) - { - center_y--; - center_x++; - } - - // fade out overlay images on disabled buttons - LLColor4 overlay_color = mImageOverlayColor; - if (!mButton->getEnabled()) - { - overlay_color.mV[VALPHA] = 0.5f; - } - - switch(mImageOverlayAlignment) - { - case LLFontGL::LEFT: - text_left += overlay_width + 1; - text_width -= overlay_width + 1; - mImageOverlay->draw( - text_left, - center_y - (overlay_height / 2), - overlay_width, - overlay_height, - overlay_color); - break; - case LLFontGL::HCENTER: - mImageOverlay->draw( - center_x - (overlay_width / 2), - center_y - (overlay_height / 2), - overlay_width, - overlay_height, - overlay_color); - break; - case LLFontGL::RIGHT: - text_right -= overlay_width + 1; - text_width -= overlay_width + 1; - mImageOverlay->draw( - text_right - overlay_width, - center_y - (overlay_height / 2), - overlay_width, - overlay_height, - overlay_color); - break; - default: - // draw nothing - break; - } - } - - - if (mList->getVisible()) - { - // sync sort order with list selection every frame - mColumn->mParentCtrl->sortByColumn(mColumn->mSortingColumn, getCurrentIndex() == 0); - } -} - -BOOL LLScrollColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask) -{ - if (canResize() && mResizeBar->getRect().pointInRect(x, y)) - { - // reshape column to max content width - mColumn->mParentCtrl->calcMaxContentWidth(); - LLRect column_rect = getRect(); - column_rect.mRight = column_rect.mLeft + mColumn->mMaxContentWidth; - setShape(column_rect,true); - } - else - { - onClick(); - } - return TRUE; -} - -void LLScrollColumnHeader::setImage(const std::string &image_name) -{ - if (mButton) - { - mButton->setImageSelected(LLUI::getUIImage(image_name)); - mButton->setImageUnselected(LLUI::getUIImage(image_name)); - } -} - -void LLScrollColumnHeader::setImageOverlay(const std::string &image_name, LLFontGL::HAlign alignment, const LLColor4& color) -{ - if (image_name.empty()) - { - mImageOverlay = NULL; - } - else - { - mImageOverlay = LLUI::getUIImage(image_name); - mImageOverlayAlignment = alignment; - mImageOverlayColor = color; - } -} - -void LLScrollColumnHeader::onClick() -{ - if (!mColumn) return; - - if (mList->getVisible()) - { - hideList(); - } - - LLScrollListCtrl::onClickColumn(mColumn); - - // propagate new sort order to sort order list - mList->selectNthItem(mColumn->mParentCtrl->getSortAscending() ? 0 : 1); - - mList->setFocus(TRUE); -} - -void LLScrollColumnHeader::onMouseDown() -{ - // for now, do nothing but block the normal showList() behavior - return; -} - -void LLScrollColumnHeader::showList() -{ - if (mShowSortOptions) - { - //LLSD item_val = mColumn->mParentCtrl->getFirstData()->getValue(); - mOrigLabel = mButton->getLabelSelected(); - - // move sort column over to this column and do initial sort - mColumn->mParentCtrl->sortByColumn(mColumn->mSortingColumn, mColumn->mParentCtrl->getSortAscending()); - - std::string low_item_text; - std::string high_item_text; - - LLScrollListItem* itemp = mColumn->mParentCtrl->getFirstData(); - if (itemp) - { - LLScrollListCell* cell = itemp->getColumn(mColumn->mIndex); - if (cell && cell->isText()) - { - if (mColumn->mParentCtrl->getSortAscending()) - { - low_item_text = cell->getValue().asString(); - } - else - { - high_item_text = cell->getValue().asString(); - } - } - } - - itemp = mColumn->mParentCtrl->getLastData(); - if (itemp) - { - LLScrollListCell* cell = itemp->getColumn(mColumn->mIndex); - if (cell && cell->isText()) - { - if (mColumn->mParentCtrl->getSortAscending()) - { - high_item_text = cell->getValue().asString(); - } - else - { - low_item_text = cell->getValue().asString(); - } - } - } - - LLStringUtil::truncate(low_item_text, 3); - LLStringUtil::truncate(high_item_text, 3); - - std::string ascending_string; - std::string descending_string; - - if (low_item_text.empty() || high_item_text.empty()) - { - ascending_string = "Ascending"; - descending_string = "Descending"; - } - else - { - mAscendingText.setArg("[LOW]", low_item_text); - mAscendingText.setArg("[HIGH]", high_item_text); - mDescendingText.setArg("[LOW]", low_item_text); - mDescendingText.setArg("[HIGH]", high_item_text); - ascending_string = mAscendingText.getString(); - descending_string = mDescendingText.getString(); - } - - S32 text_width = LLFontGL::getFontSansSerifSmall()->getWidth(ascending_string); - text_width = llmax(text_width, LLFontGL::getFontSansSerifSmall()->getWidth(descending_string)) + 10; - text_width = llmax(text_width, getRect().getWidth() - 30); - - mList->getColumn(0)->setWidth(text_width); - mList->getFirstData()->getColumn(0)->setValue(ascending_string); - mList->getLastData()->getColumn(0)->setValue(descending_string); - - mList->reshape(llmax(text_width + 30, 110, getRect().getWidth()), mList->getRect().getHeight()); - - LLComboBox::showList(); - } -} - -void LLScrollColumnHeader::onSelectSort() -{ - if (!mColumn) return; - LLScrollListCtrl* parent = mColumn->mParentCtrl; - if (!parent) return; - - if (getCurrentIndex() == 0) - { - // ascending - parent->sortByColumn(mColumn->mSortingColumn, TRUE); - } - else - { - // descending - parent->sortByColumn(mColumn->mSortingColumn, FALSE); - } - - // restore original column header - setLabel(mOrigLabel); -} - -LLView* LLScrollColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding) -{ - // this logic assumes dragging on right - llassert(snap_edge == SNAP_RIGHT); - - // use higher snap threshold for column headers - threshold = llmin(threshold, 10); - - LLRect snap_rect = getSnapRect(); - - S32 snap_delta = mColumn->mMaxContentWidth - snap_rect.getWidth(); - - // x coord growing means column growing, so same signs mean we're going in right direction - if (llabs(snap_delta) <= threshold && mouse_dir.mX * snap_delta > 0 ) - { - new_edge_val = snap_rect.mRight + snap_delta; - } - else - { - LLScrollListColumn* next_column = mColumn->mParentCtrl->getColumn(mColumn->mIndex + 1); - while (next_column) - { - if (next_column->mHeader) - { - snap_delta = (next_column->mHeader->getSnapRect().mRight - next_column->mMaxContentWidth) - snap_rect.mRight; - if (llabs(snap_delta) <= threshold && mouse_dir.mX * snap_delta > 0 ) - { - new_edge_val = snap_rect.mRight + snap_delta; - } - break; - } - next_column = mColumn->mParentCtrl->getColumn(next_column->mIndex + 1); - } - } - - return this; -} - -void LLScrollColumnHeader::handleReshape(const LLRect& new_rect, bool by_user) -{ - S32 new_width = new_rect.getWidth(); - S32 delta_width = new_width - (getRect().getWidth() /*+ mColumn->mParentCtrl->getColumnPadding()*/); - - if (delta_width != 0) - { - S32 remaining_width = -delta_width; - S32 col; - for (col = mColumn->mIndex + 1; col < mColumn->mParentCtrl->getNumColumns(); col++) - { - LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col); - if (!columnp) continue; - - if (columnp->mHeader && columnp->mHeader->canResize()) - { - // how many pixels in width can this column afford to give up? - S32 resize_buffer_amt = llmax(0, columnp->getWidth() - MIN_COLUMN_WIDTH); - - // user shrinking column, need to add width to other columns - if (delta_width < 0) - { - if (/*!columnp->mDynamicWidth && */columnp->getWidth() > 0) - { - // statically sized column, give all remaining width to this column - columnp->setWidth(columnp->getWidth() + remaining_width); - if (columnp->mRelWidth > 0.f) - { - columnp->mRelWidth = (F32)columnp->getWidth() / (F32)mColumn->mParentCtrl->getItemListRect().getWidth(); - } - // all padding went to this widget, we're done - break; - } - } - else - { - // user growing column, need to take width from other columns - remaining_width += resize_buffer_amt; - - if (/*!columnp->mDynamicWidth && */columnp->getWidth() > 0) - { - columnp->setWidth(columnp->getWidth() - llmin(columnp->getWidth() - MIN_COLUMN_WIDTH, delta_width)); - if (columnp->mRelWidth > 0.f) - { - columnp->mRelWidth = (F32)columnp->getWidth() / (F32)mColumn->mParentCtrl->getItemListRect().getWidth(); - } - } - - if (remaining_width >= 0) - { - // width sucked up from neighboring columns, done - break; - } - } - } - } - - // clamp resize amount to maximum that can be absorbed by other columns - if (delta_width > 0) - { - delta_width += llmin(remaining_width, 0); - } - - // propagate constrained delta_width to new width for this column - new_width = getRect().getWidth() + delta_width - mColumn->mParentCtrl->getColumnPadding(); - - // use requested width - mColumn->setWidth(new_width); - - // update proportional spacing - if (mColumn->mRelWidth > 0.f) - { - mColumn->mRelWidth = (F32)new_width / (F32)mColumn->mParentCtrl->getItemListRect().getWidth(); - } - - // tell scroll list to layout columns again - // do immediate update to get proper feedback to resize handle - // which needs to know how far the resize actually went - mColumn->mParentCtrl->dirtyColumns(); //Must flag as dirty, else updateColumns will probably be a noop. - mColumn->mParentCtrl->updateColumns(); - } -} - -void LLScrollColumnHeader::setHasResizableElement(BOOL resizable) -{ - // for now, dynamically spaced columns can't be resized -// if (mColumn->mDynamicWidth) return; - - if (mHasResizableElement != resizable) - { - mColumn->mParentCtrl->dirtyColumns(); - mHasResizableElement = resizable; - } -} - -void LLScrollColumnHeader::updateResizeBars() -{ - S32 num_resizable_columns = 0; - S32 col; - for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++) - { - LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col); - if (columnp->mHeader && columnp->mHeader->canResize()) - { - num_resizable_columns++; - } - } - - S32 num_resizers_enabled = 0; - - // now enable/disable resize handles on resizable columns if we have at least two - for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++) - { - LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col); - if (!columnp->mHeader) continue; - BOOL enable = num_resizable_columns >= 2 && num_resizers_enabled < (num_resizable_columns - 1) && columnp->mHeader->canResize(); - columnp->mHeader->enableResizeBar(enable); - if (enable) - { - num_resizers_enabled++; - } - } -} - -void LLScrollColumnHeader::enableResizeBar(BOOL enable) -{ - // for now, dynamically spaced columns can't be resized - //if (!mColumn->mDynamicWidth) - { - mResizeBar->setEnabled(enable); - } -} - -BOOL LLScrollColumnHeader::canResize() -{ - return getVisible() && (mHasResizableElement || mColumn->mDynamicWidth); -} - -// Default constructor -LLScrollListColumn::LLScrollListColumn() : - mName(), - mSortingColumn(), - mSortDirection(ASCENDING), - mLabel(), - mWidth(-1), - mRelWidth(-1.0), - mDynamicWidth(FALSE), - mMaxContentWidth(0), - mIndex(-1), - mParentCtrl(NULL), - mHeader(NULL), - mFontAlignment(LLFontGL::LEFT) -{ } - -LLScrollListColumn::LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent) : - mWidth(0), - mIndex (-1), - mParentCtrl(parent), - mHeader(NULL), - mMaxContentWidth(0), - mDynamicWidth(FALSE), - mRelWidth(-1.f) -{ - mName = sd.get("name").asString(); - mSortingColumn = mName; - if (sd.has("sort")) - { - mSortingColumn = sd.get("sort").asString(); - } - if (sd.has("sort_ascending")) - { - mSortDirection = sd.get("sort_ascending").asBoolean() ? ASCENDING : DESCENDING; - } - else - { - mSortDirection = ASCENDING; - } - mLabel = sd.get("label").asString(); - if (sd.has("relwidth") && (F32)sd.get("relwidth").asReal() > 0) - { - mRelWidth = (F32)sd.get("relwidth").asReal(); - if (mRelWidth < 0) mRelWidth = 0; - if (mRelWidth > 1) mRelWidth = 1; - mDynamicWidth = FALSE; - } - else if(sd.has("dynamicwidth") && (BOOL)sd.get("dynamicwidth").asBoolean() == TRUE) - { - mDynamicWidth = TRUE; - mRelWidth = -1; - } - else - { - setWidth(sd.get("width").asInteger()); - } - - if (sd.has("halign")) - { - mFontAlignment = (LLFontGL::HAlign)llclamp(sd.get("halign").asInteger(), (S32)LLFontGL::LEFT, (S32)LLFontGL::HCENTER); - } - else - { - mFontAlignment = LLFontGL::LEFT; - } - -} - -void LLScrollListColumn::setWidth(S32 width) -{ - if (!mDynamicWidth && mRelWidth <= 0.f) - { - mParentCtrl->updateStaticColumnWidth(this, width); - } - mWidth = width; -} diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 528f413ed..9babab009 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -1,31 +1,28 @@ /** * @file llscrolllistctrl.h + * @brief A scrolling list of items. This is the one you want to use + * in UI code. LLScrollListCell, LLScrollListItem, etc. are utility + * classes. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * 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 + * Copyright (C) 2010, Linden Research, Inc. * - * 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 + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * 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. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,325 +34,18 @@ #include "lluictrl.h" #include "llctrlselectioninterface.h" -#include "lldarray.h" +//#include "lldarray.h" #include "llfontgl.h" #include "llui.h" -#include "llstring.h" -#include "llimagegl.h" +#include "llstring.h" // LLWString #include "lleditmenuhandler.h" #include "llframetimer.h" -#include "llcheckboxctrl.h" -#include "llcombobox.h" + #include "llscrollbar.h" -#include "llresizebar.h" -#include "lldate.h" -// -#include "lllineeditor.h" -#include -// +#include "llscrolllistitem.h" +#include "llscrolllistcolumn.h" -/* - * Represents a cell in a scrollable table. - * - * Sub-classes must return height and other properties - * though width accessors are implemented by the base class. - * It is therefore important for sub-class constructors to call - * setWidth() with realistic values. - */ -class LLScrollListCell -{ -public: - LLScrollListCell(S32 width = 0) : mWidth(width) {}; - virtual ~LLScrollListCell() {}; - virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const = 0; // truncate to given width, if possible - virtual S32 getWidth() const {return mWidth;} - virtual S32 getContentWidth() const { return 0; } - virtual S32 getHeight() const { return 0; } - virtual const LLSD getValue() const { return LLStringUtil::null; } - virtual void setValue(const LLSD& value) { } - virtual BOOL getVisible() const { return TRUE; } - virtual void setWidth(S32 width) { mWidth = width; } - virtual void highlightText(S32 offset, S32 num_chars) {} - virtual BOOL isText() const { return FALSE; } - virtual void setColor(const LLColor4&) {} - virtual void onCommit() {}; - - virtual BOOL handleClick() { return FALSE; } - virtual void setEnabled(BOOL enable) { } - -private: - S32 mWidth; -}; - -/* - * Cell displaying a text label. - */ -class LLScrollListText : public LLScrollListCell -{ -public: - LLScrollListText( const std::string& text, const LLFontGL* font, S32 width = 0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE); - /*virtual*/ ~LLScrollListText(); - - /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; - /*virtual*/ S32 getContentWidth() const; - /*virtual*/ S32 getHeight() const; - /*virtual*/ void setValue(const LLSD& value); - /*virtual*/ const LLSD getValue() const; - /*virtual*/ BOOL getVisible() const; - /*virtual*/ void highlightText(S32 offset, S32 num_chars); - - /*virtual*/ void setColor(const LLColor4&); - /*virtual*/ BOOL isText() const; - - S32 getTextWidth() const { return mTextWidth;} - void setTextWidth(S32 value) { mTextWidth = value;} - virtual void setWidth(S32 width) { LLScrollListCell::setWidth(width); mTextWidth = width; } - - void setText(const LLStringExplicit& text); - void setFontStyle(const U8 font_style); - -private: - LLUIString mText; - S32 mTextWidth; - const LLFontGL* mFont; - LLColor4 mColor; - U8 mUseColor; - U8 mFontStyle; - LLFontGL::HAlign mFontAlignment; - BOOL mVisible; - S32 mHighlightCount; - S32 mHighlightOffset; - - LLPointer mRoundedRectImage; - - static U32 sCount; -}; - -/* - * Cell displaying an image. - */ -class LLScrollListIcon : public LLScrollListCell -{ -public: - LLScrollListIcon( LLUIImagePtr icon, S32 width = 0); - LLScrollListIcon(const LLSD& value, S32 width = 0); - /*virtual*/ ~LLScrollListIcon(); - /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; - /*virtual*/ S32 getWidth() const; - /*virtual*/ S32 getHeight() const; - /*virtual*/ const LLSD getValue() const; - /*virtual*/ void setColor(const LLColor4&); - /*virtual*/ void setValue(const LLSD& value); - // - void setClickCallback(boost::function cb); - virtual BOOL handleClick(); - // - -private: - LLPointer mIcon; - LLColor4 mColor; - // - boost::function mCallback; - // -}; - -/* - * An interactive cell containing a check box. - */ -class LLScrollListCheck : public LLScrollListCell -{ -public: - LLScrollListCheck( LLCheckBoxCtrl* check_box, S32 width = 0); - /*virtual*/ ~LLScrollListCheck(); - /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; - /*virtual*/ S32 getHeight() const { return 0; } - /*virtual*/ const LLSD getValue() const; - /*virtual*/ void setValue(const LLSD& value); - /*virtual*/ void onCommit(); - - /*virtual*/ BOOL handleClick(); - /*virtual*/ void setEnabled(BOOL enable); - - LLCheckBoxCtrl* getCheckBox() { return mCheckBox; } - -private: - LLCheckBoxCtrl* mCheckBox; -}; - - -class LLScrollListDate : public LLScrollListText -{ -public: - LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width=0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE); - virtual void setValue(const LLSD& value); - virtual const LLSD getValue() const; - -private: - LLDate mDate; -}; - -// -class LLScrollListLineEditor : public LLScrollListCell -{ -public: - LLScrollListLineEditor( LLLineEditor* line_editor, S32 width = 0); - /*virtual*/ ~LLScrollListLineEditor(); - virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; - virtual S32 getHeight() const { return 0; } - virtual const LLSD getValue() const { return mLineEditor->getValue(); } - virtual void setValue(const LLSD& value) { mLineEditor->setValue(value); } - virtual void onCommit() { mLineEditor->onCommit(); } - virtual BOOL handleClick(); - virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); - virtual BOOL handleUnicodeCharHere(llwchar uni_char ); - virtual void setEnabled(BOOL enable) { mLineEditor->setEnabled(enable); } - - LLLineEditor* getLineEditor() { return mLineEditor; } - virtual BOOL isText() const { return FALSE; } - -private: - LLLineEditor* mLineEditor; -}; -// - -class LLScrollListColumn; -class LLScrollColumnHeader : public LLComboBox -{ -public: - LLScrollColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL *font = NULL); - ~LLScrollColumnHeader(); - - /*virtual*/ void draw(); - /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); - - /*virtual*/ void showList(); - /*virtual*/ LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding); - /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false); - - void setImage(const std::string &image_name); - void setImageOverlay(const std::string &overlay_image, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white); - LLScrollListColumn* getColumn() { return mColumn; } - void setHasResizableElement(BOOL resizable); - void updateResizeBars(); - BOOL canResize(); - void enableResizeBar(BOOL enable); - std::string getLabel() { return mOrigLabel; } - - void onSelectSort(); - void onClick(); - void onMouseDown(); - -private: - LLScrollListColumn* mColumn; - LLResizeBar* mResizeBar; - std::string mOrigLabel; - LLUIString mAscendingText; - LLUIString mDescendingText; - BOOL mShowSortOptions; - BOOL mHasResizableElement; - - LLPointer mImageOverlay; - LLFontGL::HAlign mImageOverlayAlignment; - LLColor4 mImageOverlayColor; -}; - -/* - * A simple data class describing a column within a scroll list. - */ -class LLScrollListColumn -{ -public: - typedef enum e_sort_direction - { - DESCENDING, - ASCENDING - } ESortDirection; - LLScrollListColumn(); - LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent); - - void setWidth(S32 width); - S32 getWidth() const { return mWidth; } - - // Public data is fine so long as this remains a simple struct-like data class. - // If it ever gets any smarter than that, these should all become private - // with protected or public accessor methods added as needed. -MG - std::string mName; - std::string mSortingColumn; - ESortDirection mSortDirection; - std::string mLabel; - F32 mRelWidth; - BOOL mDynamicWidth; - S32 mMaxContentWidth; - S32 mIndex; - LLScrollListCtrl* mParentCtrl; - LLScrollColumnHeader* mHeader; - LLFontGL::HAlign mFontAlignment; - -private: - S32 mWidth; - -}; - -class LLScrollListItem : public LLHandleProvider -{ -public: - LLScrollListItem( BOOL enabled = TRUE, void* userdata = NULL, const LLUUID& uuid = LLUUID::null ) - : mSelected(FALSE), mEnabled( enabled ), mUserdata( userdata ), mItemValue( uuid ), mColumns() {} - LLScrollListItem( LLSD item_value, void* userdata = NULL ) - : mSelected(FALSE), mEnabled( TRUE ), mUserdata( userdata ), mItemValue( item_value ), mColumns() {} - - virtual ~LLScrollListItem(); - - void setSelected( BOOL b ) { mSelected = b; } - BOOL getSelected() const { return mSelected; } - - void setEnabled( BOOL b ) { mEnabled = b; } - BOOL getEnabled() const { return mEnabled; } - - void setUserdata( void* userdata ) { mUserdata = userdata; } - void* getUserdata() const { return mUserdata; } - - void setToolTip(const std::string tool_tip) { mToolTip=tool_tip; } - std::string getToolTip() { return mToolTip; } - - virtual LLUUID getUUID() const { return mItemValue.asUUID(); } - LLSD getValue() const { return mItemValue; } - - void setRect(LLRect rect) { mRectangle = rect; } - LLRect getRect() const { return mRectangle; } - - // If width = 0, just use the width of the text. Otherwise override with - // specified width in pixels. - void addColumn( const std::string& text, const LLFontGL* font, S32 width = 0 , U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, BOOL visible = TRUE) - { mColumns.push_back( new LLScrollListText(text, font, width, font_style, font_alignment, LLColor4::black, FALSE, visible) ); } - - void addColumn( LLUIImagePtr icon, S32 width = 0 ) - { mColumns.push_back( new LLScrollListIcon(icon, width) ); } - - void addColumn( LLCheckBoxCtrl* check, S32 width = 0 ) - { mColumns.push_back( new LLScrollListCheck(check,width) ); } - - void setNumColumns(S32 columns); - - void setColumn( S32 column, LLScrollListCell *cell ); - - S32 getNumColumns() const; - - LLScrollListCell *getColumn(const S32 i) const; - - std::string getContentsCSV() const; - - virtual void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding); - -private: - BOOL mSelected; - BOOL mEnabled; - void* mUserdata; - LLSD mItemValue; - std::string mToolTip; - std::vector mColumns; - LLRect mRectangle; -}; +class LLMenuGL; class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, public LLCtrlListInterface, public LLCtrlScrollInterface @@ -386,13 +76,10 @@ public: typedef boost::signals2::signal > sort_signal_t; - LLScrollListCtrl( - const std::string& name, - const LLRect& rect, - commit_callback_t commit_callback, - BOOL allow_multiple_selection, - BOOL draw_border = TRUE, bool draw_heading = false); + LLScrollListCtrl(const std::string& name, const LLRect& rect, commit_callback_t commit_callback, bool multi_select, bool has_border = true, bool draw_heading = false); + +public: virtual ~LLScrollListCtrl(); virtual LLXMLNodePtr getXML(bool save_children = true) const; @@ -404,16 +91,16 @@ public: void deleteAllItems() { clearRows(); } // Sets an array of column descriptors - void setColumnHeadings(LLSD headings); + void setColumnHeadings(const LLSD& headings); void sortByColumnIndex(U32 column, BOOL ascending); // LLCtrlListInterface functions virtual S32 getItemCount() const; // Adds a single column descriptor: ["name" : string, "label" : string, "width" : integer, "relwidth" : integer ] + virtual void addColumn(const LLScrollListColumn::Params& column, EAddPosition pos = ADD_BOTTOM); virtual void addColumn(const LLSD& column, EAddPosition pos = ADD_BOTTOM); virtual void clearColumns(); virtual void setColumnLabel(const std::string& column, const std::string& label); - virtual LLScrollListColumn* getColumn(S32 index); virtual LLScrollListColumn* getColumn(const std::string& name); virtual S32 getNumColumns() const { return mColumnsIndexed.size(); } @@ -421,7 +108,9 @@ public: // Adds a single element, from an array of: // "columns" => [ "column" => column name, "value" => value, "type" => type, "font" => font, "font-style" => style ], "id" => uuid // Creates missing columns automatically. - virtual LLScrollListItem* addElement(const LLSD& value, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); + virtual LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); + virtual LLScrollListItem* addRow(LLScrollListItem *new_item, const LLScrollListItem::Params& value, EAddPosition pos = ADD_BOTTOM); + virtual LLScrollListItem* addRow(const LLScrollListItem::Params& value, EAddPosition pos = ADD_BOTTOM); // Simple add element. Takes a single array of: // [ "value" => value, "font" => font, "font-style" => style ] virtual void clearRows(); // clears all elements @@ -473,8 +162,8 @@ public: S32 getHighlightedItemInx() const { return mHighlightedItem; } void setDoubleClickCallback( callback_t cb ) { mOnDoubleClickCallback = cb; } - void setMaximumSelectCallback( callback_t cb ) { mOnMaximumSelectCallback = cb; } - void setSortChangedCallback( callback_t cb ) { mOnSortChangedCallback = cb; } + void setMaximumSelectCallback( callback_t cb) { mOnMaximumSelectCallback = cb; } + void setSortChangedCallback( callback_t cb) { mOnSortChangedCallback = cb; } // Convenience function; *TODO: replace with setter above + boost::bind() in calling code void setDoubleClickCallback( boost::function cb, void* userdata) { mOnDoubleClickCallback = boost::bind(cb, userdata); } @@ -495,7 +184,6 @@ public: // one of which can be selected at a time. virtual LLScrollListItem* addSimpleElement(const std::string& value, EAddPosition pos = ADD_BOTTOM, const LLSD& id = LLSD()); - BOOL selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE ); // FALSE if item not found BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE); BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE); @@ -506,7 +194,7 @@ public: // DEPRECATED: Use LLSD versions of addCommentText() and getSelectedValue(). // "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which // has an associated, unique UUID, and only one of which can be selected at a time. - LLScrollListItem* addStringUUIDItem(const std::string& item_text, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE, S32 column_width = 0); + LLScrollListItem* addStringUUIDItem(const std::string& item_text, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); LLUUID getStringUUIDSelectedItem() const; LLScrollListItem* getFirstSelected() const; @@ -531,7 +219,7 @@ public: void setBgStripeColor(const LLColor4& c) { mBgStripeColor = c; } void setFgSelectedColor(const LLColor4 &c) { mFgSelectedColor = c; } void setFgUnselectedColor(const LLColor4 &c){ mFgUnselectedColor = c; } - void setHighlightedColor(const LLColor4 &c) { mHighlightedColor = c; } + void setHighlightedColor(const LLColor4 &c) { mHighlightedColor = c; } void setFgDisableColor(const LLColor4 &c) { mFgDisabledColor = c; } void setBackgroundVisible(BOOL b) { mBackgroundVisible = b; } @@ -548,11 +236,11 @@ public: virtual S32 getScrollPos() const; virtual void setScrollPos( S32 pos ); - + // S32 getPageLines() { return mPageLines; } // - + S32 getSearchColumn(); void setSearchColumn(S32 column) { mSearchColumn = column; } S32 getColumnIndexFromOffset(S32 x); @@ -561,10 +249,14 @@ public: void clearSearchString() { mSearchString.clear(); } + // support right-click context menus for avatar/group lists + void setContextMenu(LLMenuGL* menu) { mPopupMenu = menu; } + // Overridden from LLView /*virtual*/ void draw(); /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); @@ -575,6 +267,7 @@ public: /*virtual*/ void setFocus( BOOL b ); /*virtual*/ void onFocusReceived(); /*virtual*/ void onFocusLost(); + /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); virtual BOOL isDirty() const; @@ -592,7 +285,7 @@ public: LLRect getCellRect(S32 row_index, S32 column_index); // Used "internally" by the scroll bar. - void onScrollChange( S32 new_pos, LLScrollbar* src); + void onScrollChange( S32 new_pos, LLScrollbar* src ); static void onClickColumn(void *userdata); @@ -601,7 +294,6 @@ public: bool updateColumnWidths(); S32 getMaxContentWidth() { return mMaxContentWidth; } - void setDisplayHeading(BOOL display); void setHeadingHeight(S32 heading_height); /** * Sets max visible lines without scroolbar, if this value equals to 0, @@ -660,6 +352,7 @@ public: return mSortCallback->connect(cb); } + protected: // "Full" interface: use this when you're creating a list that has one or more of the following: // * contains icons @@ -736,7 +429,6 @@ private: LLColor4 mFgUnselectedColor; LLColor4 mFgDisabledColor; LLColor4 mHighlightedColor; - LLColor4 mDefaultListTextColor; S32 mBorderThickness; callback_t mOnDoubleClickCallback; @@ -745,6 +437,7 @@ private: S32 mHighlightedItem; class LLViewBorder* mBorder; + LLMenuGL *mPopupMenu; LLView *mCommentTextView; @@ -773,5 +466,4 @@ private: sort_signal_t* mSortCallback; }; // end class LLScrollListCtrl - #endif // LL_SCROLLLISTCTRL_H diff --git a/indra/llui/llscrolllistitem.cpp b/indra/llui/llscrolllistitem.cpp new file mode 100644 index 000000000..fc48e2578 --- /dev/null +++ b/indra/llui/llscrolllistitem.cpp @@ -0,0 +1,147 @@ +/** + * @file llscrolllistitem.cpp + * @brief Scroll lists are composed of rows (items), each of which + * contains columns (cells). + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llscrolllistitem.h" + + +//--------------------------------------------------------------------------- +// LLScrollListItem +//--------------------------------------------------------------------------- + +LLScrollListItem::LLScrollListItem( const Params& p ) +: mSelected(FALSE), + mEnabled(p.enabled), + mUserdata(p.userdata), + mItemValue(p.value), + mColumns() +{ +} + + +LLScrollListItem::~LLScrollListItem() +{ + std::for_each(mColumns.begin(), mColumns.end(), DeletePointer()); +} + +void LLScrollListItem::addColumn(const LLScrollListCell::Params& p) +{ + mColumns.push_back(LLScrollListCell::create(p)); +} + +void LLScrollListItem::setNumColumns(S32 columns) +{ + S32 prev_columns = mColumns.size(); + if (columns < prev_columns) + { + std::for_each(mColumns.begin()+columns, mColumns.end(), DeletePointer()); + } + + mColumns.resize(columns); + + for (S32 col = prev_columns; col < columns; ++col) + { + mColumns[col] = NULL; + } +} + +void LLScrollListItem::setColumn( S32 column, LLScrollListCell *cell ) +{ + if (column < (S32)mColumns.size()) + { + delete mColumns[column]; + mColumns[column] = cell; + } + else + { + llerrs << "LLScrollListItem::setColumn: bad column: " << column << llendl; + } +} + + +S32 LLScrollListItem::getNumColumns() const +{ + return mColumns.size(); +} + +LLScrollListCell* LLScrollListItem::getColumn(const S32 i) const +{ + if (0 <= i && i < (S32)mColumns.size()) + { + return mColumns[i]; + } + return NULL; +} + +std::string LLScrollListItem::getContentsCSV() const +{ + std::string ret; + + S32 count = getNumColumns(); + for (S32 i=0; igetValue().asString(); + if (i < count-1) + { + ret += ", "; + } + } + + return ret; +} + + +void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding) +{ + // draw background rect + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLRect bg_rect = rect; + gl_rect_2d( bg_rect, bg_color ); + + S32 cur_x = rect.mLeft; + S32 num_cols = getNumColumns(); + S32 cur_col = 0; + + for (LLScrollListCell* cell = getColumn(0); cur_col < num_cols; cell = getColumn(++cur_col)) + { + // Two ways a cell could be hidden + if (cell->getWidth() < 0 + || !cell->getVisible()) continue; + + LLUI::pushMatrix(); + { + LLUI::translate((F32) cur_x, (F32) rect.mBottom); + + cell->draw( fg_color, highlight_color ); + } + LLUI::popMatrix(); + + cur_x += cell->getWidth() + column_padding; + } +} + diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h new file mode 100644 index 000000000..0d87a0fbf --- /dev/null +++ b/indra/llui/llscrolllistitem.h @@ -0,0 +1,109 @@ +/** + * @file llscrolllistitem.h + * @brief Scroll lists are composed of rows (items), each of which + * contains columns (cells). + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LLSCROLLLISTITEM_H +#define LLSCROLLLISTITEM_H + +#include "llsd.h" +#include "llscrolllistcell.h" + +//--------------------------------------------------------------------------- +// LLScrollListItem +//--------------------------------------------------------------------------- +class LLScrollListItem +{ + friend class LLScrollListCtrl; +public: + struct Params : public LLInitParam::Block + { + Optional enabled; + Optional userdata; + Optional value; + + Ignored name; // use for localization tools + Ignored type; + Ignored length; + + Multiple columns; + + Params() + : enabled("enabled", true), + value("value"), + name("name"), + type("type"), + length("length"), + columns("columns") + { + addSynonym(columns, "column"); + addSynonym(value, "id"); + } + }; + + virtual ~LLScrollListItem(); + + void setSelected( BOOL b ) { mSelected = b; } + BOOL getSelected() const { return mSelected; } + + void setEnabled( BOOL b ) { mEnabled = b; } + BOOL getEnabled() const { return mEnabled; } + + void setUserdata( void* userdata ) { mUserdata = userdata; } + void* getUserdata() const { return mUserdata; } + + virtual LLUUID getUUID() const { return mItemValue.asUUID(); } + LLSD getValue() const { return mItemValue; } + + void setRect(LLRect rect) { mRectangle = rect; } + LLRect getRect() const { return mRectangle; } + + void addColumn( const LLScrollListCell::Params& p ); + + void setNumColumns(S32 columns); + + void setColumn( S32 column, LLScrollListCell *cell ); + + S32 getNumColumns() const; + + LLScrollListCell *getColumn(const S32 i) const; + + std::string getContentsCSV() const; + + virtual void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding); + +protected: + LLScrollListItem( const Params& ); + +private: + BOOL mSelected; + BOOL mEnabled; + void* mUserdata; + LLSD mItemValue; + std::vector mColumns; + LLRect mRectangle; +}; + +#endif diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp index 6ccfed88a..de8327003 100644 --- a/indra/llui/llsearcheditor.cpp +++ b/indra/llui/llsearcheditor.cpp @@ -153,7 +153,7 @@ LLView* LLSearchEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto S32 max_text_length = 128; node->getAttributeS32("max_length", max_text_length); - std::string text = node->getValue().substr(0, max_text_length - 1); + //std::string text = node->getValue().substr(0, max_text_length - 1); LLSearchEditor* search_editor = new LLSearchEditor("search_editor", rect, @@ -165,7 +165,7 @@ LLView* LLSearchEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto search_editor->setLabel(label); } - search_editor->setText(text); + //search_editor->setText(text); search_editor->initFromXML(node, parent); diff --git a/indra/lscript/lscript_byteformat.h b/indra/lscript/lscript_byteformat.h index 09c8b1281..49e78e717 100644 --- a/indra/lscript/lscript_byteformat.h +++ b/indra/lscript/lscript_byteformat.h @@ -2,31 +2,25 @@ * @file lscript_byteformat.h * @brief Shared code between compiler and assembler and LSL * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * 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 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * 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 + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * 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. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -536,7 +530,10 @@ typedef enum e_lscript_runtime_permissions SCRIPT_PERMISSION_TRACK_CAMERA, SCRIPT_PERMISSION_CONTROL_CAMERA, SCRIPT_PERMISSION_TELEPORT, + SCRIPT_PERMISSION_EXPERIENCE, + SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT, SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS, + SCRIPT_PERMISSION_RETURN_OBJECTS, SCRIPT_PERMISSION_EOF } LSCRIPTRunTimePermissions; @@ -554,7 +551,10 @@ const U32 LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_EOF] = (0x1 << 10),// SCRIPT_PERMISSION_TRACK_CAMERA (0x1 << 11),// SCRIPT_PERMISSION_CONTROL_CAMERA (0x1 << 12),// SCRIPT_PERMISSION_TELEPORT - (0x1 << 15),// SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS + (0x1 << 13),// SCRIPT_PERMISSION_EXPERIENCE, + (0x1 << 14),// SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT, + (0x1 << 15),// SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS, + (0x1 << 16),// SCRIPT_PERMISSION_RETURN_OBJECTS, }; // http_request string constants diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index a8b4d24dc..58da1cacc 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -88,6 +88,7 @@ set(viewer_SOURCE_FILES ascentprefsvan.cpp awavefront.cpp chatbar_as_cmdline.cpp + daeexport.cpp floaterao.cpp floaterlocalassetbrowse.cpp floatervoicelicense.cpp @@ -319,6 +320,7 @@ set(viewer_SOURCE_FILES llmapresponders.cpp llmarketplacefunctions.cpp llmarketplacenotifications.cpp + llmaterialmgr.cpp llmediactrl.cpp llmediadataclient.cpp llmediaremotectrl.cpp @@ -600,6 +602,7 @@ set(viewer_HEADER_FILES ascentprefsvan.h awavefront.h chatbar_as_cmdline.h + daeexport.h floaterao.h floaterlocalassetbrowse.h floatervoicelicense.h @@ -832,6 +835,7 @@ set(viewer_HEADER_FILES llmapresponders.h llmarketplacefunctions.h llmarketplacenotifications.h + llmaterialmgr.h llmediactrl.h llmediadataclient.h llmediaremotectrl.h diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index e9cd38814..503242ade 100644 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -99,7 +99,9 @@ PERMISSION_CHANGE_LINKS Passed to llRequestPermissions library function to req PERMISSION_TRACK_CAMERA Passed to llRequestPermissions library function to request permission to track agent's camera PERMISSION_CONTROL_CAMERA Passed to llRequestPermissions library function to request permission to change agent's camera PERMISSION_TELEPORT Passed to llRequestPermissions library function to request permission to teleport agent -PERMISSION_OVERRIDE_ANIMATIONS Passed to llRequestPermissions library function to request permission to override agent's animations +SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT Passed to llRequestPermissions library function to request permission to silently modify estate access lists +PERMISSION_OVERRIDE_ANIMATIONS Passed to llRequestPermissions library function to request permission to override animations on agent +PERMISSION_RETURN_OBJECTS Passed to llRequestPermissions library function to request permission to return objects DEBUG_CHANNEL Chat channel reserved for debug and error messages from scripts PUBLIC_CHANNEL Chat channel that broadcasts to all nearby users @@ -132,6 +134,11 @@ PSYS_PART_END_ALPHA PSYS_PART_END_SCALE PSYS_PART_MAX_AGE +PSYS_PART_BLEND_FUNC_SOURCE +PSYS_PART_BLEND_FUNC_DEST +PSYS_PART_START_GLOW +PSYS_PART_END_GLOW + PSYS_PART_BOUNCE_MASK PSYS_PART_WIND_MASK PSYS_PART_INTERP_COLOR_MASK @@ -141,6 +148,16 @@ PSYS_PART_FOLLOW_VELOCITY_MASK PSYS_PART_TARGET_POS_MASK PSYS_PART_EMISSIVE_MASK PSYS_PART_TARGET_LINEAR_MASK +PSYS_PART_RIBBON_MASK + +PSYS_PART_BF_ONE +PSYS_PART_BF_ZERO +PSYS_PART_BF_DEST_COLOR +PSYS_PART_BF_SOURCE_COLOR +PSYS_PART_BF_ONE_MINUS_DEST_COLOR +PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR +PSYS_PART_BF_SOURCE_ALPHA +PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA PSYS_SRC_PATTERN PSYS_SRC_INNERANGLE Deprecated -- Use PSYS_SRC_ANGLE_BEGIN @@ -182,6 +199,13 @@ OBJECT_SERVER_COST Used with llGetObjectDetails to get the server cost. OBJECT_STREAMING_COST Used with llGetObjectDetails to get the streaming (download) cost. OBJECT_PHYSICS_COST Used with llGetObjectDetails to get the physics cost. OBJECT_PATHFINDING_TYPE Used with llGetObjectDetails to get an object's pathfinding settings. +OBJECT_CHARACTER_TIME Used with llGetObjectDetails to get an object's average CPU time (in seconds) used by the object for navigation, if the object is a pathfinding character. Returns 0 for non-characters. +OBJECT_ROOT Used with llGetObjectDetails to get an object's root prim ID. +OBJECT_ATTACHED_POINT Used with llGetObjectDetails to get an object's attachment point. +OBJECT_RETURN_PARCEL Used with llReturnObjectsByOwner to return all objects on the same parcel as the script which are owned by 'owner'. +OBJECT_RETURN_PARCEL_OWNER Used with llReturnObjectsByOwner to return all objects owned by 'owner' which are over parcels owned by the owner of the script. +OBJECT_RETURN_REGION Used with llReturnObjectsByOwner to return all objects in the region owned by 'owner' - only works when the script is owned by the estate owner or an estate manager. + OPT_UNKNOWN Returned object pathfinding type by llGetObjectDetails for attachments, Linden trees and grass. OPT_LEGACY_LINKSET Returned object pathfinding type by llGetObjectDetails for movable obstacles, movable phantoms, physical, and volumedetect objects. OPT_AVATAR Returned object pathfinding type by llGetObjectDetails for avatars. @@ -675,6 +699,7 @@ REQUIRE_LINE_OF_SIGHT Used with llPursue(). Define whether the character needs PURSUIT_FUZZ_FACTOR Used with llPursue(). Selects a random destination near the PURSUIT_OFFSET. The valid fuzz factor range is from 0 to 1, where 1 is most random. This option requires a nonzero PURSUIT_OFFSET. PURSUIT_INTERCEPT Used with llPursue(). Define whether the character attempts to predict the target's future location. PURSUIT_GOAL_TOLERANCE Used with llPursue(). Defines approximately how close the character must be to the current goal to consider itself to be at the desired position. The valid range is from 0.25 to 10m. +FORCE_DIRECT_PATH Used with llNavigateTo(). Makes character navigate in a straight line toward pos. May be set to TRUE or FALSE. VERTICAL Constant to indicate that the orientation of the capsule for a Pathfinding character is vertical. HORIZONTAL Constant to indicate that the orientation of the capsule for a Pathfinding character is horizontal. AVOID_CHARACTERS TODO: add documentation @@ -715,10 +740,37 @@ CHARACTER_TURN_SPEED_MULTIPLIER TODO: add documentation CHARACTER_DESIRED_TURN_SPEED The character's maximum speed while turning--note that this is only loosely enforced (i.e., a character may turn at higher speeds under certain conditions) CHARACTER_MAX_TURN_RADIUS The character's turn radius when traveling at CHARACTER_DESIRED_TURN_SPEED. CHARACTER_MAX_SPEED The character's maximum speed. Affects speed when avoiding dynamic obstacles and when traversing low-walkability objects in TRAVERSAL_TYPE_FAST mode. +CHARACTER_STAY_WITHIN_PARCEL Characters which have CHARACTER_STAY_WITHIN_PARCEL set to TRUE treat the parcel boundaries as one-way obstacles. PATROL_PAUSE_AT_WAYPOINTS Used with llPatrolPoints(). Defines if characters slow down and momentarily pause at each waypoint. WANDER_PAUSE_AT_WAYPOINTS Used with llWanderWithin(). Defines if characters should pause after reaching each wander waypoint. +CONTENT_TYPE_TEXT text/plain +CONTENT_TYPE_HTML text/html +CONTENT_TYPE_XML application/xml +CONTENT_TYPE_XHTML application/xhtml+xml +CONTENT_TYPE_ATOM application/atom+xml +CONTENT_TYPE_JSON application/json +CONTENT_TYPE_LLSD application/llsd+xml +CONTENT_TYPE_FORM application/x-www-form-urlencoded +CONTENT_TYPE_RSS application/rss+xml + +JSON_INVALID Returned by llJsonGetValue and llJsonValueType if the specifiers to do specify a valid in the json value. +JSON_OBJECT Represents a json datatype represented in LSL as a strided list of name/value pairs +JSON_ARRAY Represents a json datatype mappable to the LSL datatype "list" +JSON_NUMBER Represents a json datatype mappable to the LSL datatypes "integer" and "float" +JSON_STRING Represents a json datatype mappable to the LSL datatype "string" +JSON_TRUE Represents the constant "true" of a json value. +JSON_FALSE Represents the constant "false" of a json value. +JSON_NULL Represents the constant "null" of a json value. +JSON_APPEND Used with llJsonSetValue as a specifier to indicate appending the value to the end of the array at that level. + +ERR_GENERIC Returned by llReturnObjectsByID and llReturnObjectsByOwner in case of a general error. +ERR_PARCEL_PERMISSIONS Returned by llReturnObjectsByID and llReturnObjectsByOwner in case of a parcel owner permission error. +ERR_MALFORMED_PARAMS Returned by llReturnObjectsByID and llReturnObjectsByOwner in case of malformed parameters. +ERR_RUNTIME_PERMISSIONS Returned by llReturnObjectsByID and llReturnObjectsByOwner in case of a runtime permission error. +ERR_THROTTLED Returned by llReturnObjectsByID and llReturnObjectsByOwner in case of being throttled. + # --- OpenSim and Aurora-Sim constants Below --- # OpenSim Constants (\OpenSim\Region\ScriptEngine\Shared\Api\Runtime\LSL_Constants.cs) # Constants for cmWindlight (\OpenSim\Region\ScriptEngine\Shared\Api\Runtime\CM_Constants.cs) diff --git a/indra/newview/app_settings/lsl_functions_sl.xml b/indra/newview/app_settings/lsl_functions_sl.xml index 563414c6e..31a455888 100644 --- a/indra/newview/app_settings/lsl_functions_sl.xml +++ b/indra/newview/app_settings/lsl_functions_sl.xml @@ -1020,5 +1020,24 @@ llResetAnimationOverride + + llJson2List + + llList2Json + + llJsonGetValue + + llJsonSetValue + + llJsonValueType + + + llReturnObjectsByID + + llReturnObjectsByOwner + + + llXorBase64 + - \ No newline at end of file + diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 95f2971b9..2a991e9b7 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -707,6 +707,17 @@ Value 1 + LiruMapShowAvCount + + Comment + Whether or not to display the count of avatars in each region on the world map as part of the region name and maturity label. + Persist + 1 + Type + Boolean + Value + 0 + LiruNoTransactionClutter Comment @@ -4326,17 +4337,6 @@ This should be as low as possible, but too low may break functionality 1.0 - ColumnHeaderDropDownDelay - - Comment - Time in seconds of mouse click before column header shows sort options list - Persist - 1 - Type - F32 - Value - 0.300000011921 - CompileOutputRect Comment @@ -10432,6 +10432,17 @@ This should be as low as possible, but too low may break functionality Value 0 + PrimMediaAutoPlayEnable + + Comment + Auto play prim media when available + Persist + 1 + Type + Boolean + Value + 0 + PerAccountSettingsFile Comment diff --git a/indra/newview/app_settings/settings_ascent.xml b/indra/newview/app_settings/settings_ascent.xml index e60c658c2..d5c0fd2e3 100644 --- a/indra/newview/app_settings/settings_ascent.xml +++ b/indra/newview/app_settings/settings_ascent.xml @@ -642,6 +642,28 @@ Value 0 + OBJExportNotifyFailed + + Comment + Show a notification when exporting to OBJ fails (both partially and completely) + Persist + 1 + Type + Boolean + Value + 1 + + OBJExportNotifySuccess + + Comment + Show a notification when exporting to OBJ succeeds + Persist + 1 + Type + Boolean + Value + 1 + OBJExportSwapYZ Comment @@ -653,5 +675,5 @@ Value 0 - + diff --git a/indra/newview/awavefront.cpp b/indra/newview/awavefront.cpp index d4cc49520..3f4d2c994 100644 --- a/indra/newview/awavefront.cpp +++ b/indra/newview/awavefront.cpp @@ -1,7 +1,7 @@ /** * @file awavefront.cpp * @brief A system which allows saving in-world objects to Wavefront .OBJ files for offline texturizing/shading. - * @author Apelsin + * @authors Apelsin, Lirusaito * * $LicenseInfo:firstyear=2011&license=LGPLV3$ * Copyright (C) 2011-2013 Apelsin @@ -27,13 +27,14 @@ // library includes #include "aifilepicker.h" +#include "llnotificationsutil.h" // newview includes +#include "lfsimfeaturehandler.h" #include "llavatarappearancedefines.h" #include "llface.h" #include "llvoavatar.h" - -typedef std::vector avatar_joint_list_t; +#include "llvovolume.h" // menu includes #include "llevent.h" @@ -42,12 +43,16 @@ typedef std::vector avatar_joint_list_t; #include "llselectmgr.h" LLVOAvatar* find_avatar_from_object(LLViewerObject* object); +extern LLUUID gAgentID; +//Typedefs used in other files, using here for consistency. +typedef std::vector avatar_joint_list_t; typedef LLMemberListener view_listener_t; namespace { const std::string OBJ(".obj"); + void save_wavefront_continued(WavefrontSaver* wfsaver, AIFilePicker* filepicker) { if (filepicker->hasFilename()) @@ -57,6 +62,8 @@ namespace { wfsaver->saveFile(fp); llinfos << "OBJ file saved to " << selected_filename << llendl; + if (gSavedSettings.getBOOL("OBJExportNotifySuccess")) + LLNotificationsUtil::add("WavefrontExportSuccess", LLSD().with("FILENAME", selected_filename)); fclose(fp); } else llerrs << "can't open: " << selected_filename << llendl; @@ -65,6 +72,25 @@ namespace delete wfsaver; } + + void save_wavefront_picker(WavefrontSaver* wfsaver, std::string name) + { + AIFilePicker* filepicker = AIFilePicker::create(); + filepicker->open(name); + filepicker->run(boost::bind(&save_wavefront_continued, wfsaver, filepicker)); + } + + void save_wavefront_on_confirm(const LLSD& notification, const LLSD& response, WavefrontSaver* wfsaver, std::string name) + { + if (LLNotificationsUtil::getSelectedOption(notification, response) == 0) // 0 - Proceed, first choice + { + save_wavefront_picker(wfsaver, name); + } + else + { + delete wfsaver; + } + } } Wavefront::Wavefront(vert_t v, tri_t t) @@ -123,19 +149,19 @@ Wavefront::Wavefront(LLFace* face, LLPolyMesh* mesh, const LLXform* transform, c const U16 start = face->getGeomStart(); const U32 end = start + (mesh ? mesh->getNumVertices() : vb->getNumVerts()) - 1; //vertices - for (int i = start; i <= end; ++i) + for (U32 i = start; i <= end; ++i) vertices.push_back(std::make_pair(getVerts[i], getCoord[i])); if (transform) Transform(vertices, transform); - for (int i = start; i <= end; ++i) + for (U32 i = start; i <= end; ++i) normals.push_back(getNorms[i]); if (transform_normals) Transform(normals, transform_normals); const U32 pcount = mesh ? mesh->getNumFaces() : (vb->getNumIndices()/3); //indices const U16 offset = face->getIndicesStart(); //indices - for (int i = 0; i < pcount; ++i) + for (U32 i = 0; i < pcount; ++i) { triangles.push_back(tri(getIndices[i * 3 + offset] + start, getIndices[i * 3 + 1 + offset] + start, getIndices[i * 3 + 2 + offset] + start)); } @@ -192,26 +218,55 @@ void WavefrontSaver::Add(const LLViewerObject* some_vo) normfix.setRotation(v_form.getRotation()); //Should work... Add(some_vo->getVolume(), &v_form, &normfix); } - namespace { - class LLSaveSelectedObjects : public view_listener_t + bool can_export_node(const LLSelectNode* node) + { + if (const LLPermissions* perms = node->mPermissions) + { + if (gAgentID == perms->getCreator() || (LFSimFeatureHandler::instance().simSupportsExport() && gAgentID == perms->getOwner() && perms->getMaskEveryone() & PERM_EXPORT)) + { + return true; + } + } + return false; + } + class LFSaveSelectedObjects : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { if (LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection()) { - WavefrontSaver* wfsaver = new WavefrontSaver; //deleted in callback + WavefrontSaver* wfsaver = new WavefrontSaver; // deleted in callback wfsaver->offset = -selection->getFirstRootObject()->getRenderPosition(); + S32 total = 0; + S32 included = 0; for (LLObjectSelection::iterator iter = selection->begin(); iter != selection->end(); ++iter) { + total++; LLSelectNode* node = *iter; + if (!can_export_node(node)) continue; + included++; wfsaver->Add(node->getObject()); } + if (wfsaver->obj_v.empty()) + { + if (gSavedSettings.getBOOL("OBJExportNotifyFailed")) + LLNotificationsUtil::add("ExportFailed"); + delete wfsaver; + return true; + } - AIFilePicker* filepicker = AIFilePicker::create(); - filepicker->open(selection->getFirstNode()->mName.c_str()+OBJ); - filepicker->run(boost::bind(&save_wavefront_continued, wfsaver, filepicker)); + if (total != included) + { + LLSD args; + args["TOTAL"] = total; + args["FAILED"] = total - included; + LLNotificationsUtil::add("WavefrontExportPartial", args, LLSD(), boost::bind(&save_wavefront_on_confirm, _1, _2, wfsaver, selection->getFirstNode()->mName.c_str() + OBJ)); + return true; + } + + save_wavefront_picker(wfsaver, selection->getFirstNode()->mName.c_str() + OBJ); } return true; } @@ -221,7 +276,7 @@ namespace void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too! { offset = -av_vo->getRenderPosition(); - avatar_joint_list_t vjv = av_vo->getMeshLOD(); + avatar_joint_list_t vjv = av_vo->mMeshLOD; for (avatar_joint_list_t::const_iterator itervj = vjv.begin(); itervj != vjv.end(); ++itervj) { const LLViewerJoint* vj = dynamic_cast(*itervj); @@ -231,7 +286,7 @@ void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too! if (!vjm) continue; vjm->updateJointGeometry(); - LLFace* face = vjm->getFace(); + LLFace* face = vjm->mFace; if (!face) continue; //Beware: this is a hack because LLFace has multiple LODs @@ -271,6 +326,11 @@ void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too! { const LLViewerObject* c = *iterc; if (!c) continue; + if (const LLSelectNode* n = LLSelectMgr::getInstance()->getSelection()->findNode(const_cast(c))) + { + if (!can_export_node(n)) continue; + } + else continue; const LLVolume* vol = c->getVolume(); if (!vol) continue; @@ -293,17 +353,28 @@ void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too! } } } - namespace { - class LLSaveSelectedAvatar : public view_listener_t + class LFSaveSelectedAvatar : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { if (const LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject())) { - WavefrontSaver* wfsaver = new WavefrontSaver; //deleted in callback + if (!avatar->isSelf()) + { + if (gSavedSettings.getBOOL("OBJExportNotifyFailed")) LLNotificationsUtil::add("ExportFailed"); + return true; + } + WavefrontSaver* wfsaver = new WavefrontSaver; // deleted in callback wfsaver->Add(avatar); + if (wfsaver->obj_v.empty()) + { + if (gSavedSettings.getBOOL("OBJExportNotifyFailed")) + LLNotificationsUtil::add("ExportFailed"); + delete wfsaver; + return true; + } AIFilePicker* filepicker = AIFilePicker::create(); filepicker->open(avatar->getFullname()+OBJ); @@ -383,9 +454,9 @@ bool WavefrontSaver::saveFile(LLFILE* fp) } void addMenu(view_listener_t* menu, const std::string& name); -void add_wave_listeners() //Called in llviewermenu with other addMenu calls, function linked against +void add_wave_listeners() // Called in llviewermenu with other addMenu calls, function linked against { - addMenu(new LLSaveSelectedObjects(), "Object.SaveAsOBJ"); - addMenu(new LLSaveSelectedAvatar(), "Avatar.SaveAsOBJ"); + addMenu(new LFSaveSelectedObjects(), "Object.SaveAsOBJ"); + addMenu(new LFSaveSelectedAvatar(), "Avatar.SaveAsOBJ"); } diff --git a/indra/newview/awavefront.h b/indra/newview/awavefront.h index f97099cd1..3f58ee4a0 100644 --- a/indra/newview/awavefront.h +++ b/indra/newview/awavefront.h @@ -1,7 +1,7 @@ /** * @file awavefront.h * @brief A system which allows saving in-world objects to Wavefront .OBJ files for offline texturizing/shading. - * @author Apelsin + * @authors Apelsin, Lirusaito * * $LicenseInfo:firstyear=2011&license=LGPLV3$ * Copyright (C) 2011-2013 Apelsin @@ -24,14 +24,6 @@ #ifndef AWAVEFRONT #define AWAVEFRONT -#include -#include "v3math.h" -#include "v2math.h" -#include "llface.h" -#include "llvolume.h" - -using namespace std; - class LLFace; class LLPolyMesh; class LLViewerObject; diff --git a/indra/newview/daeexport.cpp b/indra/newview/daeexport.cpp new file mode 100644 index 000000000..586dc8cf5 --- /dev/null +++ b/indra/newview/daeexport.cpp @@ -0,0 +1,450 @@ +/** +* @file daeexport.cpp +* @brief A system which allows saving in-world objects to Collada .DAE files for offline texturizing/shading. +* @authors Latif Khalifa +* +* $LicenseInfo:firstyear=2011&license=LGPLV3$ +* Copyright (C) 2013 Latif Khalifa +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 3 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General +* Public License along with this library; if not, write to the +* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +* Boston, MA 02110-1301 USA */ + +#include "llviewerprecompiledheaders.h" + +#include "daeexport.h" + +//colladadom includes +#if LL_MSVC +#pragma warning (disable : 4018) +#pragma warning (push) +#pragma warning (disable : 4068) +#pragma warning (disable : 4263) +#pragma warning (disable : 4264) +#endif +#pragma GCC diagnostic ignored "-Woverloaded-virtual" +#include "dae.h" +//#include "dom.h" +#include "dom/domAsset.h" +#include "dom/domBind_material.h" +#include "dom/domCOLLADA.h" +#include "dom/domConstants.h" +#include "dom/domController.h" +#include "dom/domEffect.h" +#include "dom/domGeometry.h" +#include "dom/domInstance_geometry.h" +#include "dom/domInstance_material.h" +#include "dom/domInstance_node.h" +#include "dom/domInstance_effect.h" +#include "dom/domMaterial.h" +#include "dom/domMatrix.h" +#include "dom/domNode.h" +#include "dom/domProfile_COMMON.h" +#include "dom/domRotate.h" +#include "dom/domScale.h" +#include "dom/domTranslate.h" +#include "dom/domVisual_scene.h" +#if LL_MSVC +#pragma warning (pop) +#endif + +// library includes +#include "aifilepicker.h" +#include "llnotificationsutil.h" +#include "boost/date_time/posix_time/posix_time.hpp" + +// newview includes +#include "lfsimfeaturehandler.h" +#include "llface.h" +#include "llvovolume.h" + +// menu includes +#include "llevent.h" +#include "llmemberlistener.h" +#include "llview.h" +#include "llselectmgr.h" + +#define ANY_FACE -1 + +extern LLUUID gAgentID; + +//Typedefs used in other files, using here for consistency. +typedef LLMemberListener view_listener_t; + +namespace DAEExportUtil +{ + void saveImpl(DAESaver* daesaver, AIFilePicker* filepicker) + { + if (filepicker->hasFilename()) + { + const std::string selected_filename = filepicker->getFilename(); + + daesaver->saveDAE(selected_filename); + LLNotificationsUtil::add("WavefrontExportSuccess", LLSD().with("FILENAME", selected_filename)); + } + else llwarns << "No file; bailing" << llendl; + + delete daesaver; + } + + void filePicker(DAESaver* daesaver, std::string name) + { + AIFilePicker* filepicker = AIFilePicker::create(); + filepicker->open(name); + filepicker->run(boost::bind(&saveImpl, daesaver, filepicker)); + } + + void onPatialExportConfirm(const LLSD& notification, const LLSD& response, DAESaver* daesaver, std::string name) + { + if (LLNotificationsUtil::getSelectedOption(notification, response) == 0) // 0 - Proceed, first choice + { + filePicker(daesaver, name); + } + else + { + delete daesaver; + } + } + + bool canExportNode(const LLSelectNode* node) + { + if (const LLPermissions* perms = node->mPermissions) + { + if (gAgentID == perms->getCreator() || (LFSimFeatureHandler::instance().simSupportsExport() && gAgentID == perms->getOwner() && perms->getMaskEveryone() & PERM_EXPORT)) + { + return true; + } + } + return false; + } + + void saveSelectedObject() + { + static const std::string file_ext = ".dae"; + + if (LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection()) + { + DAESaver* daesaver = new DAESaver; // deleted in callback + daesaver->mOffset = -selection->getFirstRootObject()->getRenderPosition(); + S32 total = 0; + S32 included = 0; + + for (LLObjectSelection::iterator iter = selection->begin(); iter != selection->end(); ++iter) + { + total++; + LLSelectNode* node = *iter; + if (!canExportNode(node) || !node->getObject()->getVolume()) continue; + included++; + daesaver->Add(node->getObject(), node->mName); + } + + if (daesaver->mObjects.empty()) + { + LLNotificationsUtil::add("ExportFailed"); + delete daesaver; + return; + } + + if (total != included) + { + LLSD args; + args["TOTAL"] = total; + args["FAILED"] = total - included; + LLNotificationsUtil::add("WavefrontExportPartial", args, LLSD(), boost::bind(&onPatialExportConfirm, _1, _2, daesaver, selection->getFirstNode()->mName.c_str() + file_ext)); + return; + } + + filePicker(daesaver, selection->getFirstNode()->mName.c_str() + file_ext); + } + return; + } + + class DAESaveSelectedObjects : public view_listener_t + { + bool handleEvent(LLPointer event, const LLSD& userdata) + { + saveSelectedObject(); + return true; + } + }; +} + + +void DAESaver::Add(const LLViewerObject* prim, const std::string name) +{ + mObjects.push_back(std::pair((LLViewerObject*)prim, name)); +} + +class v4adapt +{ +private: + LLStrider mV4aStrider; +public: + v4adapt(LLVector4a* vp){ mV4aStrider = vp; } + inline LLVector3 operator[] (const unsigned int i) + { + return LLVector3((F32*)&mV4aStrider[i]); + } +}; + +void DAESaver::addSource(daeElement* mesh, const char* src_id, std::string params, const std::vector &vals) +{ + daeElement* source = mesh->add("source"); + source->setAttribute("id", src_id); + daeElement* src_array = source->add("float_array"); + + src_array->setAttribute("id", llformat("%s-%s", src_id, "array").c_str()); + src_array->setAttribute("count", llformat("%d", vals.size()).c_str()); + + for (S32 i = 0; i < vals.size(); i++) + { + ((domFloat_array*)src_array)->getValue().append(vals[i]); + } + + domAccessor* acc = daeSafeCast(source->add("technique_common accessor")); + acc->setSource(llformat("#%s-%s", src_id, "array").c_str()); + acc->setCount(vals.size()); + acc->setStride(params.size()); + + for (std::string::iterator p_iter = params.begin(); p_iter != params.end(); ++p_iter) + { + domElement* pX = acc->add("param"); + pX->setAttribute("name", llformat("%c", *p_iter).c_str()); + pX->setAttribute("type", "float"); + } +} + +void DAESaver::addPolygons(daeElement* mesh, const char* geomID, const char* materialID, LLViewerObject* obj, int face_to_include) +{ + domPolylist* polylist = daeSafeCast(mesh->add("polylist")); + polylist->setMaterial(materialID); + + // Vertices semantic + { + domInputLocalOffset* input = daeSafeCast(polylist->add("input")); + input->setSemantic("VERTEX"); + input->setOffset(0); + input->setSource(llformat("#%s-%s", geomID, "vertices").c_str()); + } + + // Normals semantic + { + domInputLocalOffset* input = daeSafeCast(polylist->add("input")); + input->setSemantic("NORMAL"); + input->setOffset(0); + input->setSource(llformat("#%s-%s", geomID, "normals").c_str()); + } + + // UV semantic + { + domInputLocalOffset* input = daeSafeCast(polylist->add("input")); + input->setSemantic("TEXCOORD"); + input->setOffset(0); + input->setSource(llformat("#%s-%s", geomID, "map0").c_str()); + } + + // Save indices + domP* p = daeSafeCast(polylist->add("p")); + domPolylist::domVcount *vcount = daeSafeCast(polylist->add("vcount")); + S32 index_offset = 0; + S32 num_tris = 0; + for (S32 face_num = 0; face_num < obj->getVolume()->getNumVolumeFaces(); face_num++) + { + const LLVolumeFace* face = (LLVolumeFace*)&obj->getVolume()->getVolumeFace(face_num); + + if (face_to_include == ANY_FACE || face_to_include == face_num) + { + for (S32 i = 0; i < face->mNumIndices; i++) + { + U16 index = index_offset + face->mIndices[i]; + (p->getValue()).append(index); + if (i % 3 == 0) + { + (vcount->getValue()).append(3); + num_tris++; + } + } + } + index_offset += face->mNumVertices; + } + polylist->setCount(num_tris); +} + +bool DAESaver::saveDAE(std::string filename) +{ + DAE dae; + // First set the filename to save + daeElement* root = dae.add(filename); + + // Obligatory elements in header + daeElement* asset = root->add("asset"); + // Get ISO format time + std::string date = boost::posix_time::to_iso_extended_string(boost::posix_time::second_clock::local_time()); + daeElement* created = asset->add("created"); + created->setCharData(date); + daeElement* modified = asset->add("modified"); + modified->setCharData(date); + daeElement* unit = asset->add("unit"); + unit->setAttribute("name", "meter"); + unit->setAttribute("value", "1"); + daeElement* up_axis = asset->add("up_axis"); + up_axis->setCharData("Z_UP"); + + // File creator + daeElement* contributor = asset->add("contributor"); + contributor->add("author")->setCharData("Singularity User"); + contributor->add("authoring_tool")->setCharData("Singularity Viewer Collada Export"); + + daeElement* geomLib = root->add("library_geometries"); + daeElement* effects = root->add("library_effects"); + daeElement* materials = root->add("library_materials"); + daeElement* scene = root->add("library_visual_scenes visual_scene"); + scene->setAttribute("id", "Scene"); + scene->setAttribute("name", "Scene"); + + S32 prim_nr = 0; + + for (obj_info_t::iterator obj_iter = mObjects.begin(); obj_iter != mObjects.end(); ++obj_iter) + { + LLViewerObject* obj = obj_iter->first; + S32 total_num_vertices = 0; + + std::string name = ""; + if (name.empty()) name = llformat("prim%d", prim_nr++); + + const char* geomID = name.c_str(); + + daeElement* geom = geomLib->add("geometry"); + geom->setAttribute("id", llformat("%s-%s", geomID, "mesh").c_str()); + daeElement* mesh = geom->add("mesh"); + + std::vector position_data; + std::vector normal_data; + std::vector uv_data; + + S32 num_faces = obj->getVolume()->getNumVolumeFaces(); + + for (S32 face_num = 0; face_num < num_faces; face_num++) + { + const LLVolumeFace* face = (LLVolumeFace*)&obj->getVolume()->getVolumeFace(face_num); + total_num_vertices += face->mNumVertices; + + v4adapt verts(face->mPositions); + v4adapt norms(face->mNormals); + for (S32 i=0; i < face->mNumVertices; i++) + { + const LLVector3 v = verts[i]; + position_data.push_back(v.mV[VX]); + position_data.push_back(v.mV[VY]); + position_data.push_back(v.mV[VZ]); + + const LLVector3 n = norms[i]; + normal_data.push_back(n.mV[VX]); + normal_data.push_back(n.mV[VY]); + normal_data.push_back(n.mV[VZ]); + + const LLVector2 uv = face->mTexCoords[i]; + uv_data.push_back(uv.mV[VX]); + uv_data.push_back(uv.mV[VY]); + } + } + + + addSource(mesh, llformat("%s-%s", geomID, "positions").c_str(), "XYZ", position_data); + addSource(mesh, llformat("%s-%s", geomID, "normals").c_str(), "XYZ", normal_data); + addSource(mesh, llformat("%s-%s", geomID, "map0").c_str(), "ST", uv_data); + + // Add the element + { + daeElement* verticesNode = mesh->add("vertices"); + verticesNode->setAttribute("id", llformat("%s-%s", geomID, "vertices").c_str()); + daeElement* verticesInput = verticesNode->add("input"); + verticesInput->setAttribute("semantic", "POSITION"); + verticesInput->setAttribute("source", llformat("#%s-%s", geomID, "positions").c_str()); + } + + // Add triangles + for (S32 face_num = 0; face_num < num_faces; face_num++) + { + addPolygons(mesh, geomID, llformat("%s-f%d-%s", geomID, face_num, "material").c_str(), obj, face_num); + } + + // Effects (face color, alpha) + for (S32 face_num = 0; face_num < num_faces; face_num++) + { + LLTextureEntry* te = obj->getTE(face_num); + LLColor4 color = te->getColor(); + domEffect* effect = (domEffect*)effects->add("effect"); + effect->setId(llformat("%s-f%d-%s", geomID, face_num, "fx").c_str()); + daeElement* t = effect->add("profile_COMMON technique"); + t->setAttribute("sid", "common"); + domElement* phong = t->add("phong"); + phong->add("diffuse color")->setCharData(llformat("%f %f %f %f", color.mV[0], color.mV[1], color.mV[2], color.mV[3]).c_str()); + phong->add("transparency float")->setCharData(llformat("%f", color.mV[3]).c_str()); + } + + // Materials + for (S32 face_num = 0; face_num < num_faces; face_num++) + { + domMaterial* mat = (domMaterial*)materials->add("material"); + mat->setId(llformat("%s-f%d-%s", geomID, face_num, "material").c_str()); + domElement* matEffect = mat->add("instance_effect"); + matEffect->setAttribute("url", llformat("#%s-f%d-%s", geomID, face_num, "fx").c_str()); + } + + daeElement* node = scene->add("node"); + node->setAttribute("type", "NODE"); + node->setAttribute("id", geomID); + node->setAttribute("name", geomID); + + // Set tranform matrix (node position, rotation and scale) + domMatrix* matrix = (domMatrix*)node->add("matrix"); + LLXform srt; + srt.setScale(obj->getScale()); + srt.setPosition(obj->getRenderPosition() + mOffset); + srt.setRotation(obj->getRenderRotation()); + LLMatrix4 m4; + srt.getLocalMat4(m4); + for (int i=0; i<4; i++) + for (int j=0; j<4; j++) + (matrix->getValue()).append(m4.mMatrix[j][i]); + + // Geometry of the node + daeElement* nodeGeometry = node->add("instance_geometry"); + + // Bind materials + daeElement* tq = nodeGeometry->add("bind_material technique_common"); + for (S32 face_num = 0; face_num < num_faces; face_num++) + { + daeElement* instanceMaterial = tq->add("instance_material"); + instanceMaterial->setAttribute("symbol", llformat("%s-f%d-%s", geomID, face_num, "material").c_str()); + instanceMaterial->setAttribute("target", llformat("#%s-f%d-%s", geomID, face_num, "material").c_str()); + } + + nodeGeometry->setAttribute("url", llformat("#%s-%s", geomID, "mesh").c_str()); + + } + root->add("scene instance_visual_scene")->setAttribute("url", "#Scene"); + + return dae.writeAll(); +} + +DAESaver::DAESaver() +{} + +void addMenu(view_listener_t* menu, const std::string& name); +void add_dae_listeners() // Called in llviewermenu with other addMenu calls, function linked against +{ + addMenu(new DAEExportUtil::DAESaveSelectedObjects(), "Object.SaveAsDAE"); +} diff --git a/indra/newview/daeexport.h b/indra/newview/daeexport.h new file mode 100644 index 000000000..6abc561e0 --- /dev/null +++ b/indra/newview/daeexport.h @@ -0,0 +1,48 @@ +/** +* @file daeexport.h +* @brief A system which allows saving in-world objects to Collada .DAE files for offline texturizing/shading. +* @authors Latif Khalifa +* +* $LicenseInfo:firstyear=2011&license=LGPLV3$ +* Copyright (C) 2013 Latif Khalifa +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 3 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General +* Public License along with this library; if not, write to the +* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +* Boston, MA 02110-1301 USA */ + +#ifndef DAEEXPORT_H_ +#define DAEEXPORT_H_ + +#include + +class LLViewerObject; + +class DAESaver +{ + typedef std::vector > obj_info_t; + +public: + obj_info_t mObjects; + LLVector3 mOffset; + DAESaver(); + void Add(const LLViewerObject* prim, const std::string name); + bool saveDAE(std::string filename); + +private: + void addSource(daeElement* mesh, const char* src_id, std::string params, const std::vector &vals); + void addPolygons(daeElement* mesh, const char* geomID, const char* materialID, LLViewerObject* obj, int face_to_include); +}; + +#endif // DAEEXPORT_H_ + diff --git a/indra/newview/floaterlocalassetbrowse.cpp b/indra/newview/floaterlocalassetbrowse.cpp index ef6de943d..abcb19c98 100644 --- a/indra/newview/floaterlocalassetbrowse.cpp +++ b/indra/newview/floaterlocalassetbrowse.cpp @@ -38,7 +38,6 @@ this feature is still a work in progress. /* basic headers */ #include "llviewerprecompiledheaders.h" -#include "lluictrlfactory.h" /* own class header && upload floater header */ #include "floaterlocalassetbrowse.h" @@ -50,6 +49,12 @@ this feature is still a work in progress. #include "llimagejpeg.h" #include "llimagepng.h" +/* llui headers */ +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llscrolllistitem.h" +#include "lluictrlfactory.h" + /* misc headers */ #include #include @@ -60,13 +65,7 @@ this feature is still a work in progress. #include "llfloaterimagepreview.h" #include "llfile.h" -/* repeated in header */ -#include "lltexturectrl.h" -#include "llscrolllistctrl.h" -#include "llviewercontrol.h" - /* including to force rebakes when needed */ -#include "llagent.h" #include "llvoavatarself.h" /* sculpt refresh */ diff --git a/indra/newview/floaterlocalassetbrowse.h b/indra/newview/floaterlocalassetbrowse.h index 7cd8ab559..b4cbc149f 100644 --- a/indra/newview/floaterlocalassetbrowse.h +++ b/indra/newview/floaterlocalassetbrowse.h @@ -44,6 +44,8 @@ tag: vaa emerald local_asset_browser #include "lldrawable.h" #include "lleventtimer.h" +class LLCheckBoxCtrl; +class LLComboBox; /*=======================================*/ /* Global structs / enums / defines */ diff --git a/indra/newview/hbfloatergrouptitles.cpp b/indra/newview/hbfloatergrouptitles.cpp index f75211730..c96189de1 100644 --- a/indra/newview/hbfloatergrouptitles.cpp +++ b/indra/newview/hbfloatergrouptitles.cpp @@ -41,8 +41,8 @@ #include "llagent.h" #include "llgroupactions.h" +#include "llscrolllistitem.h" #include "lluictrlfactory.h" -#include "llviewercontrol.h" // static variable HBFloaterGroupTitles* HBFloaterGroupTitles::sInstance = NULL; diff --git a/indra/newview/jcfloaterareasearch.cpp b/indra/newview/jcfloaterareasearch.cpp index 0c37a1da8..8b1ac9d77 100644 --- a/indra/newview/jcfloaterareasearch.cpp +++ b/indra/newview/jcfloaterareasearch.cpp @@ -33,16 +33,16 @@ #include "llviewerprecompiledheaders.h" -#include "lluuid.h" -#include "lluictrlfactory.h" +#include "jcfloaterareasearch.h" + +#include "llfiltereditor.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" +#include "lluictrlfactory.h" #include "llagent.h" -#include "llfiltereditor.h" #include "lltracker.h" #include "llviewerobjectlist.h" -#include "llviewercontrol.h" -#include "jcfloaterareasearch.h" const std::string request_string = "JCFloaterAreaSearch::Requested_\xF8\xA7\xB5"; const F32 min_refresh_interval = 0.25f; // Minimum interval between list refreshes in seconds. diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c9b3d6944..d1454847d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -158,6 +158,7 @@ // Included so that constants/settings might be initialized // in save_settings_to_globals() #include "llbutton.h" +#include "llcombobox.h" #include "llstatusbar.h" #include "llsurface.h" #include "llvosky.h" diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 1851e389b..efc51d319 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -31,7 +31,7 @@ #include "llavatarnamecache.h" // IDEVO #include "llnotifications.h" -#include "llnotificationsutil.h" // for LLNotificationsUtil +#include "llnotificationsutil.h" #include "roles_constants.h" // for GP_MEMBER_INVITE #include "llagent.h" @@ -75,6 +75,9 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin payload["name"] = name; LLNotificationsUtil::add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage); + + // add friend to recent people list + //LLRecentPeople::instance().add(id); } void on_avatar_name_friendship(const LLUUID& id, const LLAvatarName av_name) @@ -218,7 +221,6 @@ static void on_avatar_name_cache_start_call(const LLUUID& agent_id, make_ui_sound("UISndStartIM"); } - // static void LLAvatarActions::startCall(const LLUUID& id) { @@ -240,8 +242,7 @@ void LLAvatarActions::startCall(const LLUUID& id) } // [/RLVa:KB] - LLAvatarNameCache::get(id, - boost::bind(&on_avatar_name_cache_start_call, _1, _2)); + LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_cache_start_call, _1, _2)); } // static @@ -568,8 +569,8 @@ void LLAvatarActions::inviteToGroup(const LLUUID& id) { widget->center(); widget->setPowersMask(GP_MEMBER_INVITE); - //widget->removeNoneOption(); - widget->setSelectCallback(callback_invite_to_group, (void*)&id); + widget->removeNoneOption(); + widget->setSelectGroupCallback(boost::bind(callback_invite_to_group, _1, id)); } } @@ -625,10 +626,10 @@ bool LLAvatarActions::handlePay(const LLSD& notification, const LLSD& response, } // static -void LLAvatarActions::callback_invite_to_group(LLUUID group_id, void* id) +void LLAvatarActions::callback_invite_to_group(LLUUID group_id, LLUUID id) { uuid_vec_t agent_ids; - agent_ids.push_back(*static_cast(id)); + agent_ids.push_back(id); LLFloaterGroupInvite::showForGroup(group_id, &agent_ids); } @@ -725,7 +726,6 @@ void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::stri LLSD payload; payload["from_id"] = target_id; - //payload["SUPPRESS_TOAST"] = true; LLNotificationsUtil::add("FriendshipOffered", args, payload); } @@ -754,4 +754,3 @@ bool LLAvatarActions::canBlock(const LLUUID& id) bool is_self = id == gAgentID; return !is_self && !is_linden; } - diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index b0ac68df0..6131954a6 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -187,7 +187,7 @@ private: static bool handleKick(const LLSD& notification, const LLSD& response); static bool handleFreeze(const LLSD& notification, const LLSD& response); static bool handleUnfreeze(const LLSD& notification, const LLSD& response); - static void callback_invite_to_group(LLUUID group_id, void* id); + static void callback_invite_to_group(LLUUID group_id, LLUUID id); public: // Just request friendship, no dialog. diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 636a9b585..61762272d 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -140,6 +140,17 @@ void LLDrawPoolAvatar::prerender() { sBufferUsage = GL_STREAM_DRAW_ARB; } + + if (!mDrawFace.empty()) + { + + const LLFace *facep = mDrawFace[0]; + if (facep && facep->getDrawable()) + { + LLVOAvatar* avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); + updateRiggedVertexBuffers(avatarp); + } + } } LLMatrix4& LLDrawPoolAvatar::getModelView() @@ -1546,7 +1557,6 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) void LLDrawPoolAvatar::renderDeferredRiggedSimple(LLVOAvatar* avatar) { - updateRiggedVertexBuffers(avatar); renderRigged(avatar, RIGGED_DEFERRED_SIMPLE); } @@ -1610,7 +1620,6 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) void LLDrawPoolAvatar::renderRiggedSimple(LLVOAvatar* avatar) { - updateRiggedVertexBuffers(avatar); renderRigged(avatar, RIGGED_SIMPLE); } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 5d0371601..bdce7b2b3 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1072,6 +1072,12 @@ bool LLFace::canRenderAsMask() return false; } + LLMaterial* mat = te->getMaterialParams(); + if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) + { + return false; + } + static const LLCachedControl use_rmse_auto_mask("SHUseRMSEAutoMask",false); static const LLCachedControl auto_mask_max_rmse("SHAutoMaskMaxRMSE",.09f); if ((te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index c41e7f1db..de8075e4c 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -20,12 +20,14 @@ #include "llavatarnamecache.h" #include "llfloateravatarlist.h" +#include "llnotificationsutil.h" +#include "llradiogroup.h" +#include "llscrolllistcolumn.h" +#include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "lluictrlfactory.h" #include "llviewerwindow.h" #include "llwindow.h" -#include "llscrolllistctrl.h" -#include "llradiogroup.h" -#include "llnotificationsutil.h" #include "llvoavatar.h" #include "llimview.h" @@ -493,6 +495,7 @@ void LLFloaterAvatarList::assessColumns() client_col->mDynamicWidth = !client_hidden; name_col->mDynamicWidth = client_hidden; + mAvatarList->setNumDynamicColumns(1); // Dynamic width is set on only one column, be sure to let the list know, otherwise we may divide by zero if(!client_hidden) { @@ -775,7 +778,7 @@ void LLFloaterAvatarList::refreshAvatarList() BOOST_FOREACH(av_list_t::value_type& entry, mAvatars) { - LLSD element; + LLScrollListItem::Params element; LLUUID av_id; std::string av_name; @@ -822,33 +825,30 @@ void LLFloaterAvatarList::refreshAvatarList() continue; } + element.value = av_id; - element["id"] = av_id; - - element["columns"][LIST_MARK]["column"] = "marked"; - element["columns"][LIST_MARK]["type"] = "text"; + LLScrollListCell::Params mark; + mark.column = "marked"; + mark.type = "text"; if (entry->isMarked()) { - element["columns"][LIST_MARK]["value"] = "X"; - element["columns"][LIST_MARK]["color"] = LLColor4::blue.getValue(); - element["columns"][LIST_MARK]["font-style"] = "BOLD"; - } - else - { - element["columns"][LIST_MARK]["value"] = ""; + mark.value = "X"; + mark.color = LLColor4::blue; + mark.font_style = "BOLD"; } - element["columns"][LIST_AVATAR_NAME]["column"] = "avatar_name"; - element["columns"][LIST_AVATAR_NAME]["type"] = "text"; - element["columns"][LIST_AVATAR_NAME]["value"] = av_name; + LLScrollListCell::Params name; + name.column = "avatar_name"; + name.type = "text"; + name.value = av_name; if (entry->isFocused()) { - element["columns"][LIST_AVATAR_NAME]["font-style"] = "BOLD"; + name.font_style = "BOLD"; } // custom colors for certain types of avatars! //Changed a bit so people can modify them in settings. And since they're colors, again it's possibly account-based. Starting to think I need a function just to determine that. - HgB - //element["columns"][LIST_AVATAR_NAME]["color"] = gColors.getColor( "MapAvatar" ).getValue(); + //name.color = gColors.getColor( "MapAvatar" ); LLViewerRegion* parent_estate = LLWorld::getInstance()->getRegionFromPosGlobal(entry->getPosition()); LLUUID estate_owner = LLUUID::null; if(parent_estate && parent_estate->isAlive()) @@ -892,12 +892,13 @@ void LLFloaterAvatarList::refreshAvatarList() name_color = name_color*0.5f + unselected_color*0.5f; - element["columns"][LIST_AVATAR_NAME]["color"] = name_color.getValue(); + name.color = name_color; char temp[32]; LLColor4 color = sDefaultListText; - element["columns"][LIST_DISTANCE]["column"] = "distance"; - element["columns"][LIST_DISTANCE]["type"] = "text"; + LLScrollListCell::Params dist; + dist.column = "distance"; + dist.type = "text"; if (UnknownAltitude) { strcpy(temp, "?"); @@ -929,9 +930,10 @@ void LLFloaterAvatarList::refreshAvatarList() snprintf(temp, sizeof(temp), "%d", (S32)distance); } } - element["columns"][LIST_DISTANCE]["value"] = temp; - element["columns"][LIST_DISTANCE]["color"] = color.getValue(); + dist.value = temp; + dist.color = color; + LLScrollListCell::Params pos; position = position - simpos; S32 x = (S32)position.mdV[VX]; @@ -960,12 +962,13 @@ void LLFloaterAvatarList::refreshAvatarList() strcat(temp, "E"); } } - element["columns"][LIST_POSITION]["column"] = "position"; - element["columns"][LIST_POSITION]["type"] = "text"; - element["columns"][LIST_POSITION]["value"] = temp; + pos.column = "position"; + pos.type = "text"; + pos.value = temp; - element["columns"][LIST_ALTITUDE]["column"] = "altitude"; - element["columns"][LIST_ALTITUDE]["type"] = "text"; + LLScrollListCell::Params alt; + alt.column = "altitude"; + alt.type = "text"; if (UnknownAltitude) { strcpy(temp, "?"); @@ -974,10 +977,11 @@ void LLFloaterAvatarList::refreshAvatarList() { snprintf(temp, sizeof(temp), "%d", (S32)position.mdV[VZ]); } - element["columns"][LIST_ALTITUDE]["value"] = temp; + alt.value = temp; - element["columns"][LIST_ACTIVITY]["column"] = "activity"; - element["columns"][LIST_ACTIVITY]["type"] = "icon"; + LLScrollListCell::Params act; + act.column = "activity"; + act.type = "icon"; std::string activity_icon = ""; std::string activity_tip = ""; @@ -1029,12 +1033,13 @@ void LLFloaterAvatarList::refreshAvatarList() break; } - element["columns"][LIST_ACTIVITY]["value"] = activity_icon;//icon_image_id; //"icn_active-speakers-dot-lvl0.tga"; - //element["columns"][LIST_AVATAR_ACTIVITY]["color"] = icon_color.getValue(); - element["columns"][LIST_ACTIVITY]["tool_tip"] = activity_tip; + act.value = activity_icon;//icon_image_id; //"icn_active-speakers-dot-lvl0.tga"; + //act.color = icon_color; + act.tool_tip = activity_tip; - element["columns"][LIST_AGE]["column"] = "age"; - element["columns"][LIST_AGE]["type"] = "text"; + LLScrollListCell::Params agep; + agep.column = "age"; + agep.type = "text"; color = sDefaultListText; std::string age = boost::lexical_cast(entry->mAge); if (entry->mAge > -1) @@ -1054,23 +1059,22 @@ void LLFloaterAvatarList::refreshAvatarList() { age = "?"; } - element["columns"][LIST_AGE]["value"] = age; - element["columns"][LIST_AGE]["color"] = color.getValue(); + agep.value = age; + agep.color = color; int dur = difftime(time(NULL), entry->getTime()); int hours = dur / 3600; int mins = (dur % 3600) / 60; int secs = (dur % 3600) % 60; - element["columns"][LIST_TIME]["column"] = "time"; - element["columns"][LIST_TIME]["type"] = "text"; - element["columns"][LIST_TIME]["value"] = llformat("%d:%02d:%02d", hours, mins, secs); + LLScrollListCell::Params time; + time.column = "time"; + time.type = "text"; + time.value = llformat("%d:%02d:%02d", hours, mins, secs); - element["columns"][LIST_CLIENT]["column"] = "client"; - element["columns"][LIST_CLIENT]["type"] = "text"; - - //element["columns"][LIST_METADATA]["column"] = "metadata"; - //element["columns"][LIST_METADATA]["type"] = "text"; + LLScrollListCell::Params viewer; + viewer.column = "client"; + viewer.type = "text"; static const LLCachedControl avatar_name_color(gColors, "AvatarNameColor",LLColor4(0.98f, 0.69f, 0.36f, 1.f)); LLColor4 client_color(avatar_name_color); @@ -1084,27 +1088,30 @@ void LLFloaterAvatarList::refreshAvatarList() client_color = unselected_color; client = "?"; } - element["columns"][LIST_CLIENT]["value"] = client.c_str(); - - // - // Don't expose Emerald's metadata. - - //if(avatarp->extraMetadata.length()) - //{ - // element["columns"][LIST_METADATA]["value"] = avatarp->extraMetadata.c_str(); - //} + viewer.value = client.c_str(); } else { - element["columns"][LIST_CLIENT]["value"] = "Out Of Range"; + viewer.value = getString("Out Of Range"); } //Blend to make the color show up better client_color = client_color *.5f + unselected_color * .5f; - element["columns"][LIST_CLIENT]["color"] = client_color.getValue(); + viewer.color = client_color; + + // Add individual column cell params to the item param + element.columns.add(mark); + element.columns.add(name); + element.columns.add(dist); + element.columns.add(pos); + element.columns.add(alt); + element.columns.add(act); + element.columns.add(agep); + element.columns.add(time); + element.columns.add(viewer); // Add to list - mAvatarList->addElement(element, ADD_BOTTOM); + mAvatarList->addRow(element); } // finish diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index a9e6bf4b6..dec0a2ef7 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -36,6 +36,9 @@ #include "llviewercontrol.h" #include "llviewerregion.h" // getCapability() #include "llworld.h" +// [RLVa:KB] - Checked: 2010-06-04 (RLVa-1.2.2a) +#include "rlvhandler.h" +// [/RLVa:KB] // Linden libraries #include "llavatarnamecache.h" // IDEVO @@ -43,13 +46,11 @@ #include "llcachename.h" #include "lllineeditor.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "lltabcontainer.h" #include "lluictrlfactory.h" #include "message.h" -// [RLVa:KB] -#include "rlvhandler.h" -// [/RLVa:KB] //put it back as a member once the legacy path is out? static std::map sAvatarNameMap; @@ -81,12 +82,13 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback, } // Default constructor -LLFloaterAvatarPicker::LLFloaterAvatarPicker() : - LLFloater(), +LLFloaterAvatarPicker::LLFloaterAvatarPicker() + : LLFloater(), mNumResultsReturned(0), mNearMeListComplete(FALSE), mCloseOnSelect(FALSE) { + mCommitCallbackRegistrar.add("Refresh.FriendList", boost::bind(&LLFloaterAvatarPicker::populateFriend, this)); LLUICtrlFactory::getInstance()->buildFloater(this, "floater_avatar_picker.xml", NULL); } @@ -111,7 +113,6 @@ BOOL LLFloaterAvatarPicker::postBuild() LLScrollListCtrl* friends = getChild("Friends"); friends->setDoubleClickCallback(boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this)); - childSetAction("RefreshFriends", boost::bind(&LLFloaterAvatarPicker::populateFriend, this)); getChild("Friends")->setCommitCallback(boost::bind(&LLFloaterAvatarPicker::onList, this)); childSetAction("ok_btn", boost::bind(&LLFloaterAvatarPicker::onBtnSelect, this)); @@ -130,7 +131,7 @@ BOOL LLFloaterAvatarPicker::postBuild() getChild("SearchResults")->setCommentText(getString("no_results")); getChild("ResidentChooserTabs")->setCommitCallback( - boost::bind(&LLFloaterAvatarPicker::onTabChanged,this)); + boost::bind(&LLFloaterAvatarPicker::onTabChanged, this)); setAllowMultiple(FALSE); @@ -199,7 +200,6 @@ static void getSelectedAvatarData(const LLUICtrl* from, uuid_vec_t& avatar_ids, addAvatarUUID(from->getValue().asUUID(), avatar_ids, avatar_names); } - void LLFloaterAvatarPicker::onBtnSelect() { @@ -271,6 +271,22 @@ void LLFloaterAvatarPicker::onRangeAdjust() void LLFloaterAvatarPicker::onList() { getChildView("ok_btn")->setEnabled(isSelectBtnEnabled()); + +// [RLVa:KB] - Checked: 2010-06-05 (RLVa-1.2.2a) | Modified: RLVa-1.2.0d + if (rlv_handler_t::isEnabled()) + { + LLTabContainer* pTabs = getChild("ResidentChooserTabs"); + LLPanel* pNearMePanel = getChild("NearMePanel"); + RLV_ASSERT( (pTabs) && (pNearMePanel) ); + if ( (pTabs) && (pNearMePanel) ) + { + bool fRlvEnable = !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES); + pTabs->enableTabButton(pTabs->getIndexForPanel(pNearMePanel), fRlvEnable); + if ( (!fRlvEnable) && (pTabs->getCurrentPanel() == pNearMePanel) ) + pTabs->selectTabByName("SearchPanel"); + } + } +// [/RLVa:KB] } void LLFloaterAvatarPicker::populateNearMe() @@ -364,31 +380,7 @@ void LLFloaterAvatarPicker::draw() } LLFloater::draw(); - -// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-1.0.0e - // TODO-RLVa: this code needs revisiting - if (rlv_handler_t::isEnabled()) - { - LLPanel* pNearMePanel = getChild("NearMePanel"); - if ( (pNearMePanel) && (childGetVisibleTab("ResidentChooserTabs") == pNearMePanel) ) - { - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) - { - if (mNearMeListComplete) - { - getChild("NearMe")->deleteAllItems(); - childSetEnabled("Select", false); - } - mNearMeListComplete = FALSE; - pNearMePanel->setCtrlsEnabled(FALSE); - return; - } - pNearMePanel->setCtrlsEnabled(TRUE); - } - } -// [/RLVa:KB] - - if (!mNearMeListComplete && getChild("ResidentChooserTabs")->getCurrentPanel() == getChild("NearMePanel")) + if (!mNearMeListComplete && getChild("ResidentChooserTabs")->getCurrentPanel() == getChild("NearMePanel")) { populateNearMe(); } @@ -425,7 +417,7 @@ public: LLUUID mQueryID; LLAvatarPickerResponder(const LLUUID& id) : mQueryID(id) { } - + /*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) { //std::ostringstream ss; @@ -443,8 +435,7 @@ public: } else { - llinfos << "avatar picker failed " << status - << " reason " << reason << llendl; + llwarns << "avatar picker failed " << status << " reason " << reason << llendl; } } @@ -605,7 +596,7 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* if(!instanceExists()) return; - LLFloaterAvatarPicker *floater = getInstance(); + LLFloaterAvatarPicker* floater = getInstance(); // floater is closed or these are not results from our last request if (NULL == floater || query_id != floater->mQueryID) @@ -760,6 +751,7 @@ bool LLFloaterAvatarPicker::isSelectBtnEnabled() std::string active_panel_name; LLUICtrl* list = NULL; LLPanel* active_panel = getChild("ResidentChooserTabs")->getCurrentPanel(); + if(active_panel) { active_panel_name = active_panel->getName(); @@ -783,8 +775,8 @@ bool LLFloaterAvatarPicker::isSelectBtnEnabled() if(list) { - uuid_vec_t avatar_ids; - std::vector avatar_names; + uuid_vec_t avatar_ids; + std::vector avatar_names; getSelectedAvatarData(list, avatar_ids, avatar_names); return mOkButtonValidateSignal(avatar_ids); } diff --git a/indra/newview/llfloaterblacklist.cpp b/indra/newview/llfloaterblacklist.cpp index 0f5098e16..bda356078 100644 --- a/indra/newview/llfloaterblacklist.cpp +++ b/indra/newview/llfloaterblacklist.cpp @@ -1,19 +1,22 @@ // #include "llviewerprecompiledheaders.h" + #include "llfloaterblacklist.h" + #include "llaudioengine.h" -#include "llvfs.h" -#include "lluictrlfactory.h" -#include "llsdserialize.h" -#include "llscrolllistctrl.h" -#include "llcheckboxctrl.h" -#include "statemachine/aifilepicker.h" -#include "llviewerwindow.h" -#include "llwindow.h" -#include "llviewercontrol.h" -#include "llviewerobjectlist.h" +#include "llcombobox.h" #include "lldate.h" +#include "llscrolllistctrl.h" +#include "llscrolllistitem.h" +#include "llsdserialize.h" +#include "lluictrlfactory.h" +#include "llvfs.h" +#include "llwindow.h" + #include "llagent.h" +#include "llviewerobjectlist.h" +#include "llviewerwindow.h" +#include "statemachine/aifilepicker.h" LLFloaterBlacklist* LLFloaterBlacklist::sInstance; diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp index 92b8e8eeb..bed9fea81 100644 --- a/indra/newview/llfloaterbulkpermission.cpp +++ b/indra/newview/llfloaterbulkpermission.cpp @@ -35,9 +35,9 @@ #include "llviewerprecompiledheaders.h" #include "llfloaterbulkpermission.h" #include "llfloaterperms.h" // for utilities -#include "llinventorydefines.h" #include "llagent.h" #include "llchat.h" +#include "llinventorydefines.h" #include "llviewerwindow.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" @@ -49,26 +49,28 @@ #include "llresmgr.h" #include "llbutton.h" #include "lldir.h" -#include "llfloaterchat.h" #include "llviewerstats.h" #include "lluictrlfactory.h" #include "llselectmgr.h" +#include "llcheckboxctrl.h" #include "llnotificationsutil.h" #include "roles_constants.h" // for GP_OBJECT_MANIPULATE -LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed) : mDone(FALSE) +LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed) +: LLFloater(), + mDone(FALSE) { mID.generate(); + mCommitCallbackRegistrar.add("BulkPermission.Help", boost::bind(LLFloaterBulkPermission::onHelpBtn)); + mCommitCallbackRegistrar.add("BulkPermission.Apply", boost::bind(&LLFloaterBulkPermission::onApplyBtn, this)); + mCommitCallbackRegistrar.add("BulkPermission.Close", boost::bind(&LLFloaterBulkPermission::onCloseBtn, this)); + mCommitCallbackRegistrar.add("BulkPermission.CheckAll", boost::bind(&LLFloaterBulkPermission::onCheckAll, this)); + mCommitCallbackRegistrar.add("BulkPermission.UncheckAll", boost::bind(&LLFloaterBulkPermission::onUncheckAll, this)); + mCommitCallbackRegistrar.add("BulkPermission.CommitCopy", boost::bind(&LLFloaterBulkPermission::onCommitCopy, this)); LLUICtrlFactory::getInstance()->buildFloater(this,"floater_bulk_perms.xml"); childSetEnabled("next_owner_transfer", gSavedSettings.getBOOL("BulkChangeNextOwnerCopy")); - childSetAction("help", onHelpBtn, this); - childSetAction("apply", onApplyBtn, this); - childSetAction("close", onCloseBtn, this); - childSetAction("check_all", onCheckAll, this); - childSetAction("check_none", onUncheckAll, this); - childSetCommitCallback("next_owner_copy", &onCommitCopy, this); } void LLFloaterBulkPermission::doApply() @@ -112,7 +114,7 @@ void LLFloaterBulkPermission::doApply() // worked on. // NOT static, virtual! void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object, - LLInventoryObject::object_list_t* inv, + LLInventoryObject::object_list_t* inv, S32, void* q_id) { @@ -146,34 +148,31 @@ void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object, } } -void LLFloaterBulkPermission::onApplyBtn(void* user_data) +void LLFloaterBulkPermission::onApplyBtn() { - LLFloaterBulkPermission* self = static_cast(user_data); - self->doApply(); + doApply(); } -void LLFloaterBulkPermission::onHelpBtn(void* user_data) +void LLFloaterBulkPermission::onHelpBtn() { LLNotificationsUtil::add("HelpBulkPermission"); } -void LLFloaterBulkPermission::onCloseBtn(void* user_data) +void LLFloaterBulkPermission::onCloseBtn() { - LLFloaterBulkPermission* self = static_cast(user_data); - self->onClose(false); + onClose(false); } //static -void LLFloaterBulkPermission::onCommitCopy(LLUICtrl* ctrl, void* data) +void LLFloaterBulkPermission::onCommitCopy() { - LLFloaterBulkPermission* self = static_cast(data); // Implements fair use BOOL copyable = gSavedSettings.getBOOL("BulkChangeNextOwnerCopy"); if(!copyable) { gSavedSettings.setBOOL("BulkChangeNextOwnerTransfer", TRUE); } - LLCheckBoxCtrl* xfer = self->getChild("next_owner_transfer"); + LLCheckBoxCtrl* xfer = getChild("next_owner_transfer"); xfer->setEnabled(copyable); } @@ -255,7 +254,7 @@ void LLFloaterBulkPermission::doCheckUncheckAll(BOOL check) } -void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInventoryObject::object_list_t* inv) +void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInventoryObject::object_list_t* inv) { LLScrollListCtrl* list = getChild("queue output"); diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h index 1036b04a2..cd8c5760f 100644 --- a/indra/newview/llfloaterbulkpermission.h +++ b/indra/newview/llfloaterbulkpermission.h @@ -44,8 +44,6 @@ #include "llfloater.h" #include "llscrolllistctrl.h" -#include "llviewerinventory.h" - class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener, public LLFloaterSingleton { public: @@ -62,7 +60,7 @@ private: // This is the callback method for the viewer object currently // being worked on. /*virtual*/ void inventoryChanged(LLViewerObject* obj, - LLInventoryObject::object_list_t* inv, + LLInventoryObject::object_list_t* inv, S32 serial_num, void* queue); @@ -76,12 +74,12 @@ private: U8 key, bool is_new); - static void onHelpBtn(void* user_data); - static void onCloseBtn(void* user_data); - static void onApplyBtn(void* user_data); - static void onCommitCopy(LLUICtrl* ctrl, void* data); - static void onCheckAll( void* user_data) { ((LLFloaterBulkPermission*)user_data)->doCheckUncheckAll(TRUE); } - static void onUncheckAll(void* user_data) { ((LLFloaterBulkPermission*)user_data)->doCheckUncheckAll(FALSE); } + static void onHelpBtn(); + void onCloseBtn(); + void onApplyBtn(); + void onCommitCopy(); + void onCheckAll() { doCheckUncheckAll(TRUE); } + void onUncheckAll() { doCheckUncheckAll(FALSE); } // returns true if this is done BOOL isDone() const { return (mCurrentObjectID.isNull() || (mObjectIDs.count() == 0)); } diff --git a/indra/newview/llfloaterexploresounds.cpp b/indra/newview/llfloaterexploresounds.cpp index 0e3934e2f..d1dacf4e3 100644 --- a/indra/newview/llfloaterexploresounds.cpp +++ b/indra/newview/llfloaterexploresounds.cpp @@ -3,15 +3,16 @@ #include "llviewerprecompiledheaders.h" #include "llfloaterexploresounds.h" -#include "lluictrlfactory.h" + #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" +#include "lluictrlfactory.h" + #include "llagent.h" #include "llagentcamera.h" -#include "llviewerwindow.h" +#include "llfloaterblacklist.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" -#include "llfloaterchat.h" -#include "llfloaterblacklist.h" static const size_t num_collision_sounds = 29; const LLUUID collision_sounds[num_collision_sounds] = diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp index c2c958f98..45cedfeac 100644 --- a/indra/newview/llfloaterfriends.cpp +++ b/indra/newview/llfloaterfriends.cpp @@ -46,8 +46,10 @@ #include "lleventtimer.h" #include "llfiltereditor.h" #include "llfloateravatarpicker.h" -#include "llnamelistctrl.h" #include "llnotificationsutil.h" +#include "llscrolllistcolumn.h" +#include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "llsdserialize.h" #include "lltextbox.h" #include "lluictrlfactory.h" diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp index d4d21f352..fc4287982 100644 --- a/indra/newview/llfloatergodtools.cpp +++ b/indra/newview/llfloatergodtools.cpp @@ -62,7 +62,6 @@ #include "llviewerwindow.h" #include "llworld.h" #include "llfloateravatarpicker.h" -#include "llnotify.h" #include "llxfermanager.h" #include "llvlcomposition.h" #include "llsurface.h" @@ -77,9 +76,9 @@ const F32 SECONDS_BETWEEN_UPDATE_REQUESTS = 5.0f; -// ***************************************************************************** +//***************************************************************************** // LLFloaterGodTools -// ***************************************************************************** +//***************************************************************************** void LLFloaterGodTools::onOpen() { @@ -100,6 +99,7 @@ void LLFloaterGodTools::onOpen() } } + // static void LLFloaterGodTools::refreshAll() { @@ -121,36 +121,31 @@ LLFloaterGodTools::LLFloaterGodTools() mCurrentHost(LLHost::invalid), mUpdateTimer() { - LLCallbackMap::map_t factory_map; - factory_map["grid"] = LLCallbackMap(createPanelGrid, this); - factory_map["region"] = LLCallbackMap(createPanelRegion, this); - factory_map["objects"] = LLCallbackMap(createPanelObjects, this); - factory_map["request"] = LLCallbackMap(createPanelRequest, this); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_god_tools.xml", &factory_map); + mFactoryMap["grid"] = LLCallbackMap(createPanelGrid, this); + mFactoryMap["region"] = LLCallbackMap(createPanelRegion, this); + mFactoryMap["objects"] = LLCallbackMap(createPanelObjects, this); + mFactoryMap["request"] = LLCallbackMap(createPanelRequest, this); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_god_tools.xml", &getFactoryMap()); } BOOL LLFloaterGodTools::postBuild() { - getChild("GodTools Tabs")->setCommitCallback(boost::bind(&LLFloaterGodTools::onTabChanged,_1,_2)); - sendRegionInfoRequest(); getChild("GodTools Tabs")->selectTabByName("region"); - - childSetTextArg("land cost text", "[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol()); + getChild("land cost text")->setTextArg("[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol()); return TRUE; } - // static void* LLFloaterGodTools::createPanelGrid(void *userdata) { - return new LLPanelGridTools("grid"); + return new LLPanelGridTools(); } // static void* LLFloaterGodTools::createPanelRegion(void *userdata) { LLFloaterGodTools* self = (LLFloaterGodTools*)userdata; - self->mPanelRegionTools = new LLPanelRegionTools("region"); + self->mPanelRegionTools = new LLPanelRegionTools(); return self->mPanelRegionTools; } @@ -158,14 +153,14 @@ void* LLFloaterGodTools::createPanelRegion(void *userdata) void* LLFloaterGodTools::createPanelObjects(void *userdata) { LLFloaterGodTools* self = (LLFloaterGodTools*)userdata; - self->mPanelObjectTools = new LLPanelObjectTools("objects"); + self->mPanelObjectTools = new LLPanelObjectTools(); return self->mPanelObjectTools; } // static void* LLFloaterGodTools::createPanelRequest(void *userdata) { - return new LLPanelRequestTools("region"); + return new LLPanelRequestTools(); } LLFloaterGodTools::~LLFloaterGodTools() @@ -226,14 +221,6 @@ void LLFloaterGodTools::showPanel(const std::string& panel_name) panel->setFocus(TRUE); } -//static -void LLFloaterGodTools::onTabChanged(LLUICtrl* ctrl, const LLSD& param) -{ - LLPanel* panel = (LLPanel*)ctrl->getChildView(param.asString(),false,false); - if (panel) - panel->setFocus(TRUE); -} - // static void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) { @@ -403,9 +390,9 @@ void LLFloaterGodTools::sendGodUpdateRegionInfo() } } -// ***************************************************************************** +//***************************************************************************** // LLPanelRegionTools -// ***************************************************************************** +//***************************************************************************** // || Region |______________________________________ @@ -440,72 +427,37 @@ const F32 PRICE_PER_METER_MIN = 0.f; const F32 PRICE_PER_METER_MAX = 100.f; -LLPanelRegionTools::LLPanelRegionTools(const std::string& title) -: LLPanel(title) +LLPanelRegionTools::LLPanelRegionTools() +: LLPanel() { + mCommitCallbackRegistrar.add("RegionTools.ChangeAnything", boost::bind(&LLPanelRegionTools::onChangeAnything, this)); + mCommitCallbackRegistrar.add("RegionTools.ChangePrelude", boost::bind(&LLPanelRegionTools::onChangePrelude, this)); + mCommitCallbackRegistrar.add("RegionTools.BakeTerrain", boost::bind(&LLPanelRegionTools::onBakeTerrain, this)); + mCommitCallbackRegistrar.add("RegionTools.RevertTerrain", boost::bind(&LLPanelRegionTools::onRevertTerrain, this)); + mCommitCallbackRegistrar.add("RegionTools.SwapTerrain", boost::bind(&LLPanelRegionTools::onSwapTerrain, this)); + mCommitCallbackRegistrar.add("RegionTools.Refresh", boost::bind(&LLPanelRegionTools::onRefresh, this)); + mCommitCallbackRegistrar.add("RegionTools.ApplyChanges", boost::bind(&LLPanelRegionTools::onApplyChanges, this)); + mCommitCallbackRegistrar.add("RegionTools.SelectRegion", boost::bind(&LLPanelRegionTools::onSelectRegion, this)); + mCommitCallbackRegistrar.add("RegionTools.SaveState", boost::bind(&LLPanelRegionTools::onSaveState, this)); } BOOL LLPanelRegionTools::postBuild() { - LLLineEditor* region_name = getChild("region name"); - region_name->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - region_name->setKeystrokeCallback(boost::bind(&LLPanelRegionTools::onChangeSimName, this)); - region_name->setPrevalidate(&LLLineEditor::prevalidatePrintableNotPipe); + getChild("region name")->setKeystrokeCallback(boost::bind(&LLPanelRegionTools::onChangeSimName, this)); + getChild("region name")->setPrevalidate(&LLLineEditor::prevalidatePrintableNotPipe); + getChild("estate")->setPrevalidate(&LLLineEditor::prevalidatePositiveS32); + getChild("parentestate")->setPrevalidate(&LLLineEditor::prevalidatePositiveS32); + getChildView("parentestate")->setEnabled(FALSE); + getChild("gridposx")->setPrevalidate(&LLLineEditor::prevalidatePositiveS32); + getChildView("gridposx")->setEnabled(FALSE); + getChild("gridposy")->setPrevalidate(&LLLineEditor::prevalidatePositiveS32); + getChildView("gridposy")->setEnabled(FALSE); + + getChild("redirectx")->setPrevalidate(&LLLineEditor::prevalidatePositiveS32); + getChild("redirecty")->setPrevalidate(&LLLineEditor::prevalidatePositiveS32); - getChild("check prelude")->setCommitCallback(boost::bind(&LLPanelRegionTools:: onChangePrelude, this)); - getChild("check fixed sun")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - getChild("check reset home")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - getChild("check visible")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - getChild("check damage")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - getChild("block dwell")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - getChild("block terraform")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - getChild("allow transfer")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - getChild("is sandbox")->setCommitCallback( boost::bind(&LLPanelRegionTools::onChangeAnything, this)); getChild("is gaming")->setVisible((gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_GOD_FLOATER)); - getChild("is gaming")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); getChild("hide from search")->setVisible(!gHippoGridManager->getConnectedGrid()->isSecondLife()); - getChild("hide from search")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - - childSetAction("Bake Terrain", boost::bind(&LLPanelRegionTools::onBakeTerrain, this)); - childSetAction("Revert Terrain", boost::bind(&LLPanelRegionTools::onRevertTerrain, this)); - childSetAction("Swap Terrain", boost::bind(&LLPanelRegionTools::onSwapTerrain, this)); - - LLLineEditor* estate = getChild("estate name"); - estate->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - estate->setPrevalidate(&LLLineEditor::prevalidatePositiveS32); - - LLLineEditor* parentestate = getChild("parentestate"); - parentestate->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - parentestate->setPrevalidate(&LLLineEditor::prevalidatePositiveS32); - parentestate->setEnabled(false); - - LLLineEditor* gridposx = getChild("gridposx"); - gridposx->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - gridposx->setPrevalidate(&LLLineEditor::prevalidatePositiveS32); - gridposx->setEnabled(false); - - LLLineEditor* gridposy = getChild("gridposy"); - gridposy->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - gridposy->setPrevalidate(&LLLineEditor::prevalidatePositiveS32); - gridposy->setEnabled(false); - - LLLineEditor* redirectx = getChild("redirectx"); - redirectx->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - redirectx->setPrevalidate(&LLLineEditor::prevalidatePositiveS32); - - LLLineEditor* redirecty = getChild("redirecty"); - redirecty->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - redirecty->setPrevalidate(&LLLineEditor::prevalidatePositiveS32); - - getChild("billable factor")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - - getChild("land cost")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); - - getChild("Refresh")->setClickedCallback(boost::bind(&LLPanelRegionTools::onRefresh, this)); - getChild("Apply")->setClickedCallback(boost::bind(&LLPanelRegionTools::onApplyChanges, this)); - - getChild("Select Region")->setClickedCallback(boost::bind(&LLPanelRegionTools::onSelectRegion, this)); - getChild("Autosave now")->setClickedCallback(boost::bind(&LLPanelRegionTools::onSaveState,(void*)NULL)); return TRUE; } @@ -592,8 +544,7 @@ void LLPanelRegionTools::enableAllWidgets() getChildView("Autosave now")->setEnabled(TRUE); } -//static -void LLPanelRegionTools::onSaveState(void*) +void LLPanelRegionTools::onSaveState(void* userdata) { if (gAgent.isGodlike()) { @@ -918,12 +869,13 @@ void LLPanelRegionTools::onSelectRegion() // LEFT R2 RIGHT const F32 HOURS_TO_RADIANS = (2.f*F_PI)/24.f; -const char FLOATER_GRID_ADMIN_TITLE[] = "Grid Administration"; -LLPanelGridTools::LLPanelGridTools(const std::string& name) : - LLPanel(name) +LLPanelGridTools::LLPanelGridTools() : + LLPanel() { + mCommitCallbackRegistrar.add("GridTools.KickAllUsers", boost::bind(&LLPanelGridTools::onClickKickAll, this)); + mCommitCallbackRegistrar.add("GridTools.FlushMapVisibilityCaches", boost::bind(&LLPanelGridTools::onClickFlushMapVisibilityCaches, this)); } // Destroys the object @@ -933,9 +885,6 @@ LLPanelGridTools::~LLPanelGridTools() BOOL LLPanelGridTools::postBuild() { - childSetAction("Kick all users", boost::bind(&LLPanelGridTools::onClickKickAll, this)); - childSetAction("Flush This Region's Map Visibility Caches", boost::bind(&LLPanelGridTools::onClickFlushMapVisibilityCaches, this)); - return TRUE; } @@ -943,7 +892,6 @@ void LLPanelGridTools::refresh() { } - void LLPanelGridTools::onClickKickAll() { LLNotificationsUtil::add("KickAllUsers", LLSD(), LLSD(), LLPanelGridTools::confirmKick); @@ -952,7 +900,7 @@ void LLPanelGridTools::onClickKickAll() // static bool LLPanelGridTools::confirmKick(const LLSD& notification, const LLSD& response) { - if (LLNotification::getSelectedOption(notification, response) == 0) + if (LLNotificationsUtil::getSelectedOption(notification, response) == 0) { LLSD payload; payload["kick_message"] = response["message"].asString(); @@ -964,7 +912,7 @@ bool LLPanelGridTools::confirmKick(const LLSD& notification, const LLSD& respons // static bool LLPanelGridTools::finishKick(const LLSD& notification, const LLSD& response) { - S32 option = LLNotification::getSelectedOption(notification, response); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (option == 0) { @@ -1036,10 +984,19 @@ bool LLPanelGridTools::flushMapVisibilityCachesConfirm(const LLSD& notification, // LEFT RIGHT // Default constructor -LLPanelObjectTools::LLPanelObjectTools(const std::string& title) - : LLPanel(title), +LLPanelObjectTools::LLPanelObjectTools() + : LLPanel(), mTargetAvatar() { + mCommitCallbackRegistrar.add("ObjectTools.ChangeAnything", boost::bind(&LLPanelObjectTools::onChangeAnything, this)); + mCommitCallbackRegistrar.add("ObjectTools.DeletePublicOwnedBy", boost::bind(&LLPanelObjectTools::onClickDeletePublicOwnedBy, this)); + mCommitCallbackRegistrar.add("ObjectTools.DeleteAllScriptedOwnedBy", boost::bind(&LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy, this)); + mCommitCallbackRegistrar.add("ObjectTools.DeleteAllOwnedBy", boost::bind(&LLPanelObjectTools::onClickDeleteAllOwnedBy, this)); + mCommitCallbackRegistrar.add("ObjectTools.ApplyChanges", boost::bind(&LLPanelObjectTools::onApplyChanges, this)); + mCommitCallbackRegistrar.add("ObjectTools.Set", boost::bind(&LLPanelObjectTools::onClickSet, this)); + mCommitCallbackRegistrar.add("ObjectTools.GetTopColliders", boost::bind(&LLPanelObjectTools::onGetTopColliders, this)); + mCommitCallbackRegistrar.add("ObjectTools.GetTopScripts", boost::bind(&LLPanelObjectTools::onGetTopScripts, this)); + mCommitCallbackRegistrar.add("ObjectTools.GetScriptDigest", boost::bind(&LLPanelObjectTools::onGetScriptDigest, this)); } // Destroys the object @@ -1050,22 +1007,6 @@ LLPanelObjectTools::~LLPanelObjectTools() BOOL LLPanelObjectTools::postBuild() { - getChild("disable scripts")->setCommitCallback(boost::bind(&LLPanelObjectTools::onChangeAnything, this)); - getChild("disable collisions")->setCommitCallback(boost::bind(&LLPanelObjectTools::onChangeAnything, this)); - getChild("disable physics")->setCommitCallback(boost::bind(&LLPanelObjectTools::onChangeAnything, this)); - - childSetAction("Apply", boost::bind(&LLPanelObjectTools::onApplyChanges, this)); - - childSetAction("Set Target", boost::bind(&LLPanelObjectTools::onClickSet, this)); - - childSetAction("Delete Target's Scripted Objects On Others Land", boost::bind(&LLPanelObjectTools::onClickDeletePublicOwnedBy, this)); - childSetAction("Delete Target's Scripted Objects On *Any* Land", boost::bind(&LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy, this)); - childSetAction("Delete *ALL* Of Target's Objects", boost::bind(&LLPanelObjectTools::onClickDeleteAllOwnedBy, this)); - - childSetAction("Get Top Colliders", boost::bind(&LLPanelObjectTools::onGetTopColliders, this)); - childSetAction("Get Top Scripts", boost::bind(&LLPanelObjectTools::onGetTopScripts, this)); - childSetAction("Scripts digest", boost::bind(&LLPanelObjectTools::onGetScriptDigest, this)); - refresh(); return TRUE; } @@ -1154,29 +1095,30 @@ void LLPanelObjectTools::enableAllWidgets() getChildView("Get Top Scripts")->setEnabled(TRUE); } + void LLPanelObjectTools::onGetTopColliders() { - LLFloaterGodTools* god_tools = LLFloaterGodTools::instanceExists() ? LLFloaterGodTools::getInstance() : NULL; - if(!god_tools) - return; + LLFloaterTopObjects* instance = LLFloaterTopObjects::getInstance(); + if(!instance) return; + if (gAgent.isGodlike()) { - LLFloaterTopObjects::show(); + instance->open(); LLFloaterTopObjects::setMode(STAT_REPORT_TOP_COLLIDERS); - LLFloaterTopObjects::onRefresh(NULL); + instance->onRefresh(); } } void LLPanelObjectTools::onGetTopScripts() { - LLFloaterGodTools* god_tools = LLFloaterGodTools::instanceExists() ? LLFloaterGodTools::getInstance() : NULL; - if(!god_tools) - return; + LLFloaterTopObjects* instance = LLFloaterTopObjects::getInstance(); + if(!instance) return; + if (gAgent.isGodlike()) { - LLFloaterTopObjects::show(); + instance->open(); LLFloaterTopObjects::setMode(STAT_REPORT_TOP_SCRIPTS); - LLFloaterTopObjects::onRefresh(NULL); + instance->onRefresh(); } } @@ -1282,7 +1224,7 @@ void LLPanelObjectTools::onClickSetBySelection(void* data) LLPanelObjectTools* panelp = (LLPanelObjectTools*) data; if (!panelp) return; - const BOOL non_root_ok = TRUE; + const BOOL non_root_ok = TRUE; LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(NULL, non_root_ok); if (!node) return; @@ -1336,9 +1278,10 @@ void LLPanelObjectTools::onApplyChanges() const std::string SELECTION = "Selection"; const std::string AGENT_REGION = "Agent Region"; -LLPanelRequestTools::LLPanelRequestTools(const std::string& name): - LLPanel(name) +LLPanelRequestTools::LLPanelRequestTools(): + LLPanel() { + mCommitCallbackRegistrar.add("GodTools.Request", boost::bind(&LLPanelRequestTools::onClickRequest, this)); } LLPanelRequestTools::~LLPanelRequestTools() @@ -1347,8 +1290,6 @@ LLPanelRequestTools::~LLPanelRequestTools() BOOL LLPanelRequestTools::postBuild() { - childSetAction("Make Request", boost::bind(&LLPanelRequestTools::onClickRequest, this)); - refresh(); return TRUE; diff --git a/indra/newview/llfloatergodtools.h b/indra/newview/llfloatergodtools.h index ecfdd98b4..f01c0ac44 100644 --- a/indra/newview/llfloatergodtools.h +++ b/indra/newview/llfloatergodtools.h @@ -52,7 +52,7 @@ class LLTextBox; class LLMessageSystem; class LLFloaterGodTools -: public LLFloater, public LLSingleton + : public LLFloater, public LLSingleton { public: @@ -94,8 +94,6 @@ public: // Send possibly changed values to simulator. void sendGodUpdateRegionInfo(); - static void onTabChanged(LLUICtrl* ctrl, const LLSD& param); - public: LLFloaterGodTools(); @@ -128,14 +126,14 @@ class LLPanelRegionTools : public LLPanel { public: - LLPanelRegionTools(const std::string& name); + LLPanelRegionTools(); /*virtual*/ ~LLPanelRegionTools(); BOOL postBuild(); /*virtual*/ void refresh(); - static void onSaveState(void*); + static void onSaveState(void* userdata); void onChangeSimName(); void onChangeAnything(); @@ -190,7 +188,7 @@ class LLPanelGridTools : public LLPanel { public: - LLPanelGridTools(const std::string& name); + LLPanelGridTools(); virtual ~LLPanelGridTools(); BOOL postBuild(); @@ -217,7 +215,7 @@ class LLPanelObjectTools : public LLPanel { public: - LLPanelObjectTools(const std::string& name); + LLPanelObjectTools(); /*virtual*/ ~LLPanelObjectTools(); BOOL postBuild(); @@ -258,7 +256,7 @@ protected: class LLPanelRequestTools : public LLPanel { public: - LLPanelRequestTools(const std::string& name); + LLPanelRequestTools(); /*virtual*/ ~LLPanelRequestTools(); BOOL postBuild(); diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index 1f5a9cf24..00d31dd1c 100644 --- a/indra/newview/llfloatergroups.cpp +++ b/indra/newview/llfloatergroups.cpp @@ -40,93 +40,68 @@ #include "llviewerprecompiledheaders.h" #include "llfloatergroups.h" -#include "llfloatergroupinvite.h" -#include "message.h" #include "roles_constants.h" #include "hbfloatergrouptitles.h" #include "llagent.h" #include "llbutton.h" -#include "llfloatergroupinfo.h" -#include "llfloaterdirectory.h" -#include "llfocusmgr.h" +#include "llfloatergroupinvite.h" #include "llgroupactions.h" -#include "llselectmgr.h" +#include "llimview.h" #include "llscrolllistctrl.h" -#include "llnotificationsutil.h" +#include "llscrolllistitem.h" #include "lltextbox.h" #include "lluictrlfactory.h" -#include "llviewerwindow.h" -#include "llimview.h" +#include "lltrans.h" #include "hippolimits.h" using namespace LLOldEvents; -// static -std::map LLFloaterGroupPicker::sInstances; - // helper functions -void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const std::string& none_text, U64 powers_mask = GP_ALL_POWERS); +void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, U64 powers_mask = GP_ALL_POWERS); ///---------------------------------------------------------------------------- /// Class LLFloaterGroupPicker ///---------------------------------------------------------------------------- // static -LLFloaterGroupPicker* LLFloaterGroupPicker::findInstance(const LLSD& seed) +LLFloaterGroupPicker* LLFloaterGroupPicker::showInstance(const LLSD& seed) { - instance_map_t::iterator found_it = sInstances.find(seed.asUUID()); - if (found_it != sInstances.end()) - { - return found_it->second; - } - return NULL; -} - -// static -LLFloaterGroupPicker* LLFloaterGroupPicker::createInstance(const LLSD &seed) -{ - LLFloaterGroupPicker* pickerp = new LLFloaterGroupPicker(seed); - LLUICtrlFactory::getInstance()->buildFloater(pickerp, "floater_choose_group.xml"); + LLFloaterGroupPicker* pickerp = getInstance(seed); + if (pickerp) pickerp->open(); + else pickerp = new LLFloaterGroupPicker(seed); return pickerp; } -LLFloaterGroupPicker::LLFloaterGroupPicker(const LLSD& seed) : - mSelectCallback(NULL), - mCallbackUserdata(NULL), - mPowersMask(GP_ALL_POWERS) +LLFloaterGroupPicker::LLFloaterGroupPicker(const LLSD& seed) +: LLFloater(), LLInstanceTracker(seed.asUUID()), + mPowersMask(GP_ALL_POWERS), + mID(seed.asUUID()) { - mID = seed.asUUID(); - sInstances.insert(std::make_pair(mID, this)); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_choose_group.xml"); } LLFloaterGroupPicker::~LLFloaterGroupPicker() { - sInstances.erase(mID); -} - -void LLFloaterGroupPicker::setSelectCallback(void (*callback)(LLUUID, void*), - void* userdata) -{ - mSelectCallback = callback; - mCallbackUserdata = userdata; } void LLFloaterGroupPicker::setPowersMask(U64 powers_mask) { mPowersMask = powers_mask; - postBuild(); + init_group_list(getChild("group list"), gAgent.getGroupID(), mPowersMask); } BOOL LLFloaterGroupPicker::postBuild() { - - const std::string none_text = getString("none"); - LLScrollListCtrl* group_list = getChild("group list"); - init_group_list(group_list, gAgent.getGroupID(), none_text, mPowersMask); + LLScrollListCtrl* list_ctrl = getChild("group list"); + if (list_ctrl) + { + init_group_list(list_ctrl, gAgent.getGroupID(), mPowersMask); + list_ctrl->setDoubleClickCallback(onBtnOK, this); + } childSetAction("OK", onBtnOK, this); @@ -134,13 +109,25 @@ BOOL LLFloaterGroupPicker::postBuild() setDefaultBtn("OK"); - group_list->setDoubleClickCallback(boost::bind(&LLFloaterGroupPicker::onBtnOK,this)); - - childEnable("OK"); + getChildView("OK")->setEnabled(TRUE); return TRUE; } +void LLFloaterGroupPicker::removeNoneOption() +{ + // Remove group "none" from list. Group "none" is added in init_group_list(). + // Some UI elements use group "none", we need to manually delete it here. + // Group "none" ID is LLUUID:null. + LLCtrlListInterface* group_list = getChild("group list")->getListInterface(); + if(group_list) + { + group_list->selectByValue(LLUUID::null); + group_list->operateOnSelection(LLCtrlListInterface::OP_DELETE); + } +} + + void LLFloaterGroupPicker::onBtnOK(void* userdata) { LLFloaterGroupPicker* self = (LLFloaterGroupPicker*)userdata; @@ -162,10 +149,7 @@ void LLFloaterGroupPicker::ok() { group_id = group_list->getCurrentID(); } - if(mSelectCallback) - { - mSelectCallback(group_id, mCallbackUserdata); - } + mGroupSelectSignal(group_id); close(); } @@ -201,38 +185,39 @@ LLPanelGroups::~LLPanelGroups() // clear the group list, and get a fresh set of info. void LLPanelGroups::reset() { - childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count())); - childSetTextArg("groupcount", "[MAX]", llformat("%d", gHippoLimits->getMaxAgentGroups())); - - const std::string none_text = getString("none"); - init_group_list(getChild("group list"), gAgent.getGroupID(), none_text); + getChild("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.count())); + getChild("groupcount")->setTextArg("[MAX]", llformat("%d", gHippoLimits->getMaxAgentGroups())); + + init_group_list(getChild("group list"), gAgent.getGroupID()); enableButtons(); } BOOL LLPanelGroups::postBuild() { - childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count())); - childSetTextArg("groupcount", "[MAX]", llformat("%d", gHippoLimits->getMaxAgentGroups())); + getChild("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.count())); + getChild("groupcount")->setTextArg("[MAX]", llformat("%d",gHippoLimits->getMaxAgentGroups())); - const std::string none_text = getString("none"); - LLScrollListCtrl *group_list = getChild("group list"); - init_group_list(group_list, gAgent.getGroupID(), none_text); - group_list->setCommitCallback(boost::bind(&LLPanelGroups::onGroupList,this)); - group_list->setSortChangedCallback(boost::bind(&LLPanelGroups::onGroupSortChanged,this)); //Force 'none' to always be first entry. - group_list->setDoubleClickCallback(boost::bind(LLGroupActions::startIM, boost::bind(&LLScrollListCtrl::getCurrentID, group_list))); + LLScrollListCtrl *list = getChild("group list"); + if (list) + { + init_group_list(list, gAgent.getGroupID()); + list->setCommitCallback(boost::bind(&LLPanelGroups::onGroupList, this)); + list->setSortChangedCallback(boost::bind(&LLPanelGroups::onGroupSortChanged,this)); //Force 'none' to always be first entry. + list->setDoubleClickCallback(boost::bind(LLGroupActions::startIM, boost::bind(&LLScrollListCtrl::getCurrentID, list))); + } - getChild("Activate")->setCommitCallback(boost::bind(LLGroupActions::activate, boost::bind(&LLScrollListCtrl::getCurrentID, group_list))); + getChild("Activate")->setCommitCallback(boost::bind(LLGroupActions::activate, boost::bind(&LLScrollListCtrl::getCurrentID, list))); - getChild("Info")->setCommitCallback(boost::bind(LLGroupActions::show, boost::bind(&LLScrollListCtrl::getCurrentID, group_list))); + getChild("Info")->setCommitCallback(boost::bind(LLGroupActions::show, boost::bind(&LLScrollListCtrl::getCurrentID, list))); - getChild("IM")->setCommitCallback(boost::bind(LLGroupActions::startIM, boost::bind(&LLScrollListCtrl::getCurrentID, group_list))); + getChild("IM")->setCommitCallback(boost::bind(LLGroupActions::startIM, boost::bind(&LLScrollListCtrl::getCurrentID, list))); - getChild("Leave")->setCommitCallback(boost::bind(LLGroupActions::leave, boost::bind(&LLScrollListCtrl::getCurrentID, group_list))); + getChild("Leave")->setCommitCallback(boost::bind(LLGroupActions::leave, boost::bind(&LLScrollListCtrl::getCurrentID, list))); getChild("Create")->setCommitCallback(boost::bind(LLGroupActions::createGroup)); getChild("Search...")->setCommitCallback(boost::bind(LLGroupActions::search)); - + childSetAction("Invite...", onBtnInvite, this); getChild("Titles...")->setCommitCallback(boost::bind(HBFloaterGroupTitles::toggle)); @@ -255,40 +240,26 @@ void LLPanelGroups::enableButtons() if(group_id != gAgent.getGroupID()) { - childEnable("Activate"); + getChildView("Activate")->setEnabled(TRUE); } else { - childDisable("Activate"); + getChildView("Activate")->setEnabled(FALSE); } if (group_id.notNull()) { - childEnable("Info"); - childEnable("IM"); - childEnable("Leave"); + getChildView("Info")->setEnabled(TRUE); + getChildView("IM")->setEnabled(TRUE); + getChildView("Leave")->setEnabled(TRUE); } else { - childDisable("Info"); - childDisable("IM"); - childDisable("Leave"); - } - if(gAgent.mGroups.count() < gHippoLimits->getMaxAgentGroups()) - { - childEnable("Create"); - } - else - { - childDisable("Create"); - } - if (group_id.notNull() && gAgent.hasPowerInGroup(group_id, GP_MEMBER_INVITE)) - { - LLPanelGroups::childEnable("Invite..."); - } - else - { - LLPanelGroups::childDisable("Invite..."); + getChildView("Info")->setEnabled(FALSE); + getChildView("IM")->setEnabled(FALSE); + getChildView("Leave")->setEnabled(FALSE); } + getChildView("Create")->setEnabled(gAgent.mGroups.count() < gHippoLimits->getMaxAgentGroups()); + getChildView("Invite...")->setEnabled(group_id.notNull() && gAgent.hasPowerInGroup(group_id, GP_MEMBER_INVITE)); } @@ -302,15 +273,11 @@ void LLPanelGroups::invite() { LLCtrlListInterface *group_list = childGetListInterface("group list"); LLUUID group_id; - - //if (group_list && (group_id = group_list->getCurrentID()).notNull()) - if (group_list) { group_id = group_list->getCurrentID(); } - - LLFloaterGroupInvite::showForGroup(group_id); + LLFloaterGroupInvite::showForGroup(group_id); } void LLPanelGroups::onGroupSortChanged() @@ -334,7 +301,7 @@ void LLPanelGroups::onGroupList() if(!item) return; - const LLUUID group_id = item->getValue().asUUID(); + const LLUUID group_id = item->getValue().asUUID(); if(group_id.isNull()) return; @@ -360,13 +327,13 @@ void LLPanelGroups::onGroupList() update_group_floaters(group_id); } -LLSD create_group_element(const LLGroupData *group_datap, const LLUUID &active_group, const std::string& none_text, const U64 &powers_mask) +LLSD create_group_element(const LLGroupData *group_datap, const LLUUID &active_group, const U64 &powers_mask) { if(group_datap && !((powers_mask == GP_ALL_POWERS) || ((group_datap->mPowers & powers_mask) != 0))) return LLSD(); const LLUUID &id = group_datap ? group_datap->mID : LLUUID::null; const bool enabled = !!group_datap; - + std::string style = (group_datap && group_datap->mListInProfile) ? "BOLD" : "NORMAL"; if(active_group == id) { @@ -376,7 +343,7 @@ LLSD create_group_element(const LLGroupData *group_datap, const LLUUID &active_g element["id"] = id; LLSD& name_column = element["columns"][0]; name_column["column"] = "name"; - name_column["value"] = group_datap ? group_datap->mName : none_text; + name_column["value"] = group_datap ? group_datap->mName : LLTrans::getString("GroupsNone"); name_column["font"] = "SANSSERIF"; name_column["font-style"] = style; @@ -401,7 +368,7 @@ LLSD create_group_element(const LLGroupData *group_datap, const LLUUID &active_g return element; } -void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const std::string& none_text, U64 powers_mask) +void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, U64 powers_mask) { S32 count = gAgent.mGroups.count(); LLUUID id; @@ -416,13 +383,13 @@ void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const s for(S32 i = 0; i < count; ++i) { - LLSD element = create_group_element(&gAgent.mGroups.get(i), highlight_id, none_text, powers_mask); + LLSD element = create_group_element(&gAgent.mGroups.get(i), highlight_id, powers_mask); if(element.size()) group_list->addElement(element, ADD_SORTED); } // add "none" to list at top - group_list->addElement(create_group_element(NULL, highlight_id, none_text, powers_mask), ADD_TOP); + group_list->addElement(create_group_element(NULL, highlight_id, powers_mask), ADD_TOP); if(selected_id.notNull()) group_list->selectByValue(selected_id); diff --git a/indra/newview/llfloatergroups.h b/indra/newview/llfloatergroups.h index b262b3f4a..8af8e03c3 100644 --- a/indra/newview/llfloatergroups.h +++ b/indra/newview/llfloatergroups.h @@ -46,20 +46,26 @@ #include "lluuid.h" #include "llfloater.h" +#include "llinstancetracker.h" #include +#include +#include class LLUICtrl; class LLTextBox; class LLScrollListCtrl; class LLButton; -class LLFloaterGroupPicker : public LLFloater, public LLUIFactory > +class LLFloaterGroupPicker : public LLFloater, public LLInstanceTracker { - friend class LLUIFactory; public: + static LLFloaterGroupPicker* showInstance(const LLSD& seed); + LLFloaterGroupPicker(const LLSD& seed); ~LLFloaterGroupPicker(); - void setSelectCallback( void (*callback)(LLUUID, void*), - void* userdata); + + // Note: Don't return connection; use boost::bind + boost::signals2::trackable to disconnect slots + typedef boost::signals2::signal signal_t; + void setSelectGroupCallback(const signal_t::slot_type& cb) { mGroupSelectSignal.connect(cb); } void setPowersMask(U64 powers_mask); BOOL postBuild(); @@ -67,8 +73,10 @@ public: static LLFloaterGroupPicker* findInstance(const LLSD& seed); static LLFloaterGroupPicker* createInstance(const LLSD& seed); + // for cases like inviting avatar to group we don't want the none option + void removeNoneOption(); + protected: - LLFloaterGroupPicker(const LLSD& seed); void ok(); static void onBtnOK(void* userdata); static void onBtnCancel(void* userdata); @@ -76,8 +84,7 @@ protected: protected: LLUUID mID; U64 mPowersMask; - void (*mSelectCallback)(LLUUID id, void* userdata); - void* mCallbackUserdata; + signal_t mGroupSelectSignal; typedef std::map instance_map_t; static instance_map_t sInstances; diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index 33d735f42..448e1bb37 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -32,31 +32,48 @@ #include "llviewerprecompiledheaders.h" -#include "llavataractions.h" #include "llfloaterinspect.h" + #include "llfloatertools.h" -#include "llcachename.h" +#include "llavataractions.h" +#include "llavatarnamecache.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "llselectmgr.h" #include "lltoolcomp.h" #include "lltoolmgr.h" +#include "lltrans.h" #include "llviewerobject.h" #include "lluictrlfactory.h" - -// [RLVa:KB] +// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) #include "rlvhandler.h" +#include "llagent.h" // [/RLVa:KB] -LLFloaterInspect* LLFloaterInspect::sInstance = NULL; +//LLFloaterInspect* LLFloaterInspect::sInstance = NULL; -LLFloaterInspect::LLFloaterInspect(void) : - LLFloater(std::string("Inspect Object")), +LLFloaterInspect::LLFloaterInspect() + : LLFloater(std::string("Inspect Object")), mDirty(FALSE) { - sInstance = this; + mCommitCallbackRegistrar.add("Inspect.OwnerProfile", boost::bind(&LLFloaterInspect::onClickOwnerProfile, this)); + mCommitCallbackRegistrar.add("Inspect.CreatorProfile", boost::bind(&LLFloaterInspect::onClickCreatorProfile, this)); + mCommitCallbackRegistrar.add("Inspect.SelectObject", boost::bind(&LLFloaterInspect::onSelectObject, this)); LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inspect.xml"); } +BOOL LLFloaterInspect::postBuild() +{ + mObjectList = getChild("object_list"); +// childSetAction("button owner",onClickOwnerProfile, this); +// childSetAction("button creator",onClickCreatorProfile, this); +// childSetCommitCallback("object_list", onSelectObject, this); + + refresh(); + + return TRUE; +} + LLFloaterInspect::~LLFloaterInspect(void) { if(!gFloaterTools->getVisible()) @@ -72,42 +89,30 @@ LLFloaterInspect::~LLFloaterInspect(void) { gFloaterTools->setFocus(TRUE); } - sInstance = NULL; + //sInstance = NULL; } -BOOL LLFloaterInspect::isVisible() +// static +void LLFloaterInspect::showInstance() { - return (!!sInstance); + getInstance()->open(); } -void LLFloaterInspect::show(void* ignored) +void LLFloaterInspect::onOpen() { - // setForceSelection ensures that the pie menu does not deselect things when it - // looses the focus (this can happen with "select own objects only" enabled - // VWR-1471 BOOL forcesel = LLSelectMgr::getInstance()->setForceSelection(TRUE); - - if (!sInstance) // first use - { - sInstance = new LLFloaterInspect; - } - - sInstance->open(); LLToolMgr::getInstance()->setTransientTool(LLToolCompInspect::getInstance()); LLSelectMgr::getInstance()->setForceSelection(forcesel); // restore previouis value - - sInstance->mObjectSelection = LLSelectMgr::getInstance()->getSelection(); - sInstance->refresh(); + mObjectSelection = LLSelectMgr::getInstance()->getSelection(); + refresh(); } - -void LLFloaterInspect::onClickCreatorProfile(void* ctrl) +void LLFloaterInspect::onClickCreatorProfile() { - if(sInstance->mObjectList->getAllSelected().size() == 0) + if(mObjectList->getAllSelected().size() == 0) { return; } - LLScrollListItem* first_selected = - sInstance->mObjectList->getFirstSelected(); + LLScrollListItem* first_selected =mObjectList->getFirstSelected(); if (first_selected) { @@ -120,19 +125,27 @@ void LLFloaterInspect::onClickCreatorProfile(void* ctrl) return (obj_id == node->getObject()->getID()); } } func(first_selected->getUUID()); - LLSelectNode* node = sInstance->mObjectSelection->getFirstNode(&func); + LLSelectNode* node = mObjectSelection->getFirstNode(&func); if(node) { - LLAvatarActions::showProfile(node->mPermissions->getCreator()); +// LLAvatarActions::showProfile(node->mPermissions->getCreator()); +// [RLVa:KB] - Checked: 2010-08-25 (RLVa-1.2.2a) | Modified: RLVa-1.0.0e + const LLUUID& idCreator = node->mPermissions->getCreator(); + if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && + ((node->mPermissions->getOwner() == idCreator) || (RlvUtil::isNearbyAgent(idCreator))) ) + { + return; + } + LLAvatarActions::showProfile(idCreator); +// [/RLVa:KB] } } } -void LLFloaterInspect::onClickOwnerProfile(void* ctrl) +void LLFloaterInspect::onClickOwnerProfile() { - if(sInstance->mObjectList->getAllSelected().size() == 0) return; - LLScrollListItem* first_selected = - sInstance->mObjectList->getFirstSelected(); + if(mObjectList->getAllSelected().size() == 0) return; + LLScrollListItem* first_selected =mObjectList->getFirstSelected(); if (first_selected) { @@ -146,66 +159,62 @@ void LLFloaterInspect::onClickOwnerProfile(void* ctrl) return (obj_id == node->getObject()->getID()); } } func(selected_id); - LLSelectNode* node = sInstance->mObjectSelection->getFirstNode(&func); + LLSelectNode* node = mObjectSelection->getFirstNode(&func); if(node) { const LLUUID& owner_id = node->mPermissions->getOwner(); -// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) - if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) - { - LLAvatarActions::showProfile(owner_id); - } +// [RLVa:KB] - Checked: 2010-08-25 (RLVa-1.2.2a) | Modified: RLVa-1.0.0e + if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) + return; // [/RLVa:KB] -// LLAvatarActions::showProfile(owner_id); + LLAvatarActions::showProfile(owner_id); } } } -BOOL LLFloaterInspect::postBuild() -{ - mObjectList = getChild("object_list"); - childSetAction("button owner",onClickOwnerProfile, this); - childSetAction("button creator",onClickCreatorProfile, this); - childSetCommitCallback("object_list", onSelectObject, this); - return TRUE; -} - -void LLFloaterInspect::onSelectObject(LLUICtrl* ctrl, void* user_data) +void LLFloaterInspect::onSelectObject() { if(LLFloaterInspect::getSelectedUUID() != LLUUID::null) { - //sInstance->childSetEnabled("button owner", true); -// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-1.0.0e - sInstance->childSetEnabled("button owner", !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)); +// getChildView("button owner")->setEnabled(true); +// getChildView("button creator")->setEnabled(true); +// [RLVa:KB] - Checked: 2010-08-25 (RLVa-1.2.2a) | Modified: RLVa-1.0.0e + getChildView("button owner")->setEnabled(!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)); + // TODO-RLVa: [RLVa-1.2.2] Is it worth checking the selected node just to selectively disable this button? + getChildView("button creator")->setEnabled(true); // [/RLVa:KB] - sInstance->childSetEnabled("button creator", true); } } LLUUID LLFloaterInspect::getSelectedUUID() { - if(sInstance) + if(mObjectList->getAllSelected().size() > 0) { - if(sInstance->mObjectList->getAllSelected().size() > 0) + LLScrollListItem* first_selected =mObjectList->getFirstSelected(); + if (first_selected) { - LLScrollListItem* first_selected = - sInstance->mObjectList->getFirstSelected(); - if (first_selected) - { - return first_selected->getUUID(); - } + return first_selected->getUUID(); } } return LLUUID::null; } +void LLFloaterInspect::onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name, void* FloaterPtr) +{ + if (FloaterPtr) + { + LLFloaterInspect* floater = (LLFloaterInspect*)FloaterPtr; + floater->dirty(); + } +} + void LLFloaterInspect::refresh() { LLUUID creator_id; std::string creator_name; S32 pos = mObjectList->getScrollPos(); - childSetEnabled("button owner", false); - childSetEnabled("button creator", false); + getChildView("button owner")->setEnabled(false); + getChildView("button creator")->setEnabled(false); LLUUID selected_uuid; S32 selected_index = mObjectList->getFirstSelectedIndex(); if(selected_index > -1) @@ -234,18 +243,67 @@ void LLFloaterInspect::refresh() time_t timestamp = (time_t) (obj->mCreationDate/1000000); timeToFormattedString(timestamp, gSavedSettings.getString("TimestampFormat"), time); - gCacheName->getFullName(obj->mPermissions->getOwner(), owner_name); -// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) - { - // TODO-RLVa: shouldn't filter if this is a group-owned prim (will show "(nobody)") - owner_name = RlvStrings::getAnonym(owner_name); - } -// [/RLVa:KB] - gCacheName->getFullName(obj->mPermissions->getCreator(), creator_name); + + const LLUUID& idOwner = obj->mPermissions->getOwner(); + const LLUUID& idCreator = obj->mPermissions->getCreator(); // - gCacheName->getFullName(obj->mPermissions->getLastOwner(), last_owner_name); + const LLUUID& idLastOwner = obj->mPermissions->getLastOwner(); // + LLAvatarName av_name; + + // Only work with the names if we actually get a result + // from the name cache. If not, defer setting the + // actual name and set a placeholder. + if (LLAvatarNameCache::get(idOwner, &av_name)) + { +// owner_name = av_name.getCompleteName(); +// [RLVa:KB] - Checked: 2010-11-01 (RLVa-1.2.2a) | Modified: RLVa-1.2.2a + bool fRlvFilterOwner = (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (idOwner != gAgent.getID()) && + (!obj->mPermissions->isGroupOwned()); + owner_name = (!fRlvFilterOwner) ? av_name.getCompleteName() : RlvStrings::getAnonym(av_name); +// [/RLVa:KB] + } + else + { + owner_name = LLTrans::getString("RetrievingData"); + LLAvatarNameCache::get(idOwner, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this)); + } + + if (LLAvatarNameCache::get(idCreator, &av_name)) + { +// creator_name = av_name.getCompleteName(); +// [RLVa:KB] - Checked: 2010-11-01 (RLVa-1.2.2a) | Modified: RLVa-1.2.2a + const LLUUID& idCreator = obj->mPermissions->getCreator(); + LLAvatarNameCache::get(idCreator, &av_name); + bool fRlvFilterCreator = (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (idCreator != gAgent.getID()) && + ( (obj->mPermissions->getOwner() == idCreator) || (RlvUtil::isNearbyAgent(idCreator)) ); + creator_name = (!fRlvFilterCreator) ? av_name.getCompleteName() : RlvStrings::getAnonym(av_name); +// [/RLVa:KB] + } + else + { + creator_name = LLTrans::getString("RetrievingData"); + LLAvatarNameCache::get(idCreator, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this)); + } + + // + if (LLAvatarNameCache::get(idLastOwner, &av_name)) + { +// last_owner_name = av_name.getCompleteName(); +// [RLVa:LF] - Copied from the above creator check Checked: 2010-11-01 (RLVa-1.2.2a) | Modified: RLVa-1.2.2a + LLAvatarNameCache::get(idLastOwner, &av_name); + bool fRlvFilterLastOwner = (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) && (idLastOwner != gAgent.getID()) && + ( (obj->mPermissions->getOwner() == idLastOwner) || (RlvUtil::isNearbyAgent(idLastOwner)) ); + last_owner_name = (!fRlvFilterLastOwner) ? av_name.getCompleteName() : RlvStrings::getAnonym(av_name); +// [/RLVa:LF] + } + else + { + last_owner_name = LLTrans::getString("RetrievingData"); + LLAvatarNameCache::get(idLastOwner, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this)); + } + // + row["id"] = obj->getObject()->getID(); row["columns"][0]["column"] = "object_name"; row["columns"][0]["type"] = "text"; @@ -259,28 +317,25 @@ void LLFloaterInspect::refresh() { row["columns"][0]["value"] = obj->mName; } + row["columns"][1]["column"] = "owner_name"; + row["columns"][1]["type"] = "text"; + row["columns"][1]["value"] = owner_name; // - int i = 1; - row["columns"][i]["column"] = "owner_name"; - row["columns"][i]["type"] = "text"; - row["columns"][i]["value"] = owner_name; - ++i; - row["columns"][i]["column"] = "last_owner_name"; - row["columns"][i]["type"] = "text"; - row["columns"][i]["value"] = last_owner_name; - ++i; - row["columns"][i]["column"] = "creator_name"; - row["columns"][i]["type"] = "text"; - row["columns"][i]["value"] = creator_name; - ++i; - row["columns"][i]["column"] = "face_num"; - row["columns"][i]["type"] = "text"; - row["columns"][i]["value"] = llformat("%d",obj->getObject()->getNumFaces()); - ++i; - row["columns"][i]["column"] = "vertex_num"; - row["columns"][i]["type"] = "text"; - row["columns"][i]["value"] = llformat("%d",obj->getObject()->getNumVertices()); - ++i; + row["columns"][2]["column"] = "last_owner_name"; + row["columns"][2]["type"] = "text"; + row["columns"][2]["value"] = last_owner_name; + // + row["columns"][3]["column"] = "creator_name"; + row["columns"][3]["type"] = "text"; + row["columns"][3]["value"] = creator_name; + // + row["columns"][4]["column"] = "face_num"; + row["columns"][4]["type"] = "text"; + row["columns"][4]["value"] = llformat("%d",obj->getObject()->getNumFaces()); + + row["columns"][5]["column"] = "vertex_num"; + row["columns"][5]["type"] = "text"; + row["columns"][5]["value"] = llformat("%d",obj->getObject()->getNumVertices()); // inventory silliness S32 scripts,total_inv; std::map >::iterator itr = mInventoryNums.find(obj->getObject()->getID()); @@ -300,18 +355,16 @@ void LLFloaterInspect::refresh() requestVOInventory(); } } - row["columns"][i]["column"] = "script_num"; - row["columns"][i]["type"] = "text"; - row["columns"][i]["value"] = llformat("%d",scripts); - ++i; - row["columns"][i]["column"] = "inv_num"; - row["columns"][i]["type"] = "text"; - row["columns"][i]["value"] = llformat("%d",total_inv); - ++i; - row["columns"][i]["column"] = "creation_date"; - row["columns"][i]["type"] = "text"; - row["columns"][i]["value"] = time; + row["columns"][6]["column"] = "script_num"; + row["columns"][6]["type"] = "text"; + row["columns"][6]["value"] = llformat("%d",scripts); + row["columns"][7]["column"] = "inv_num"; + row["columns"][7]["type"] = "text"; + row["columns"][7]["value"] = llformat("%d",total_inv); // + row["columns"][8]["column"] = "creation_date"; + row["columns"][8]["type"] = "text"; + row["columns"][8]["value"] = time; mObjectList->addElement(row, ADD_TOP); } if(selected_index > -1 && mObjectList->getItemIndex(selected_uuid) == selected_index) @@ -322,26 +375,23 @@ void LLFloaterInspect::refresh() { mObjectList->selectNthItem(0); } - onSelectObject(this, NULL); + onSelectObject(); mObjectList->setScrollPos(pos); } + // -void LLFloaterInspect::inventoryChanged(LLViewerObject* viewer_object, - LLInventoryObject::object_list_t* inv, - S32, - void* q_id) +void LLFloaterInspect::inventoryChanged(LLViewerObject* viewer_object, LLInventoryObject::object_list_t* inv, S32, void* q_id) { - S32 scripts = 0; std::vector::iterator iter = std::find(mQueue.begin(),mQueue.end(),viewer_object->getID()); if (viewer_object && inv && iter != mQueue.end() ) { - LLInventoryObject::object_list_t::const_iterator it = inv->begin(); + S32 scripts = 0; LLInventoryObject::object_list_t::const_iterator end = inv->end(); - for ( ; it != end; ++it) + for (LLInventoryObject::object_list_t::const_iterator it = inv->begin(); it != end; ++it) { if((*it)->getType() == LLAssetType::AT_LSL_TEXT) { - scripts++; + ++scripts; } } mInventoryNums[viewer_object->getID()] = std::make_pair(scripts,inv->size()); @@ -350,6 +400,7 @@ void LLFloaterInspect::inventoryChanged(LLViewerObject* viewer_object, } } // + void LLFloaterInspect::onFocusReceived() { LLToolMgr::getInstance()->setTransientTool(LLToolCompInspect::getInstance()); @@ -358,13 +409,11 @@ void LLFloaterInspect::onFocusReceived() void LLFloaterInspect::dirty() { - if(sInstance) - { - // - sInstance->mInventoryNums.clear(); - sInstance->mQueue.clear(); - sInstance->setDirty(); - } + // + mInventoryNums.clear(); + mQueue.clear(); + // + setDirty(); } void LLFloaterInspect::draw() diff --git a/indra/newview/llfloaterinspect.h b/indra/newview/llfloaterinspect.h index 29a2fce77..52e6a7f9a 100644 --- a/indra/newview/llfloaterinspect.h +++ b/indra/newview/llfloaterinspect.h @@ -35,6 +35,7 @@ #ifndef LL_LLFLOATERINSPECT_H #define LL_LLFLOATERINSPECT_H +#include "llavatarname.h" #include "llfloater.h" #include "llvoinventorylistener.h" @@ -43,41 +44,47 @@ class LLObjectSelection; class LLScrollListCtrl; class LLUICtrl; -class LLFloaterInspect : public LLFloater, public LLVOInventoryListener +class LLFloaterInspect : public LLFloater, public LLSingleton, public LLVOInventoryListener { + friend class LLSingleton; public: - virtual ~LLFloaterInspect(void); - static void show(void* ignored = NULL); + + static void showInstance(); +// static void show(void* ignored = NULL); + void onOpen(); virtual BOOL postBuild(); - static void dirty(); - static LLUUID getSelectedUUID(); + void dirty(); + LLUUID getSelectedUUID(); virtual void draw(); virtual void refresh(); - static BOOL isVisible(); +// static BOOL isVisible(); virtual void onFocusReceived(); - static void onClickCreatorProfile(void* ctrl); - static void onClickOwnerProfile(void* ctrl); - static void onSelectObject(LLUICtrl* ctrl, void* user_data); + void onClickCreatorProfile(); + void onClickOwnerProfile(); + void onSelectObject(); + + static void onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name, void* FloaterPtr); + LLScrollListCtrl* mObjectList; protected: // protected members - LLFloaterInspect(); void setDirty() { mDirty = TRUE; } bool mDirty; // - /*virtual*/ void inventoryChanged(LLViewerObject* obj, - LLInventoryObject::object_list_t* inv, - S32 serial_num, - void* queue); + /*virtual*/ void inventoryChanged(LLViewerObject* obj, LLInventoryObject::object_list_t* inv, S32, void* queue); + // private: + LLFloaterInspect(); + virtual ~LLFloaterInspect(void); // static data - static LLFloaterInspect* sInstance; +// static LLFloaterInspect* sInstance; LLSafeHandle mObjectSelection; // std::map > mInventoryNums; // std::vector mQueue; + // }; #endif //LL_LLFLOATERINSPECT_H diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 6aa386ffd..1911387df 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -43,29 +43,25 @@ #include "llnotificationsutil.h" #include "llparcel.h" #include "message.h" -#include "lluserauth.h" #include "llagent.h" #include "llagentaccess.h" #include "llavataractions.h" -#include "llavatarconstants.h" //For new Online check - HgB #include "llbutton.h" #include "llcheckboxctrl.h" -#include "llradiogroup.h" #include "llcombobox.h" #include "llfloaterauction.h" #include "llfloateravatarpicker.h" #include "llfloatergroups.h" -#include "llfloatergroupinfo.h" #include "llfloaterscriptlimits.h" #include "llgroupactions.h" #include "lllineeditor.h" #include "llnamelistctrl.h" -#include "llnotify.h" #include "llpanellandaudio.h" #include "llpanellandmedia.h" #include "llradiogroup.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "llselectmgr.h" #include "llspinctrl.h" #include "lltabcontainer.h" @@ -221,16 +217,15 @@ void LLFloaterLand::onClose(bool app_quitting) LLFloaterLand::LLFloaterLand(const LLSD& seed) : LLFloater(std::string("floaterland"), std::string("FloaterLandRect5"), std::string("About Land")) { - LLCallbackMap::map_t factory_map; - factory_map["land_general_panel"] = LLCallbackMap(createPanelLandGeneral, this); - factory_map["land_covenant_panel"] = LLCallbackMap(createPanelLandCovenant, this); - factory_map["land_objects_panel"] = LLCallbackMap(createPanelLandObjects, this); - factory_map["land_options_panel"] = LLCallbackMap(createPanelLandOptions, this); - factory_map["land_audio_panel"] = LLCallbackMap(createPanelLandAudio, this); - factory_map["land_media_panel"] = LLCallbackMap(createPanelLandMedia, this); - factory_map["land_access_panel"] = LLCallbackMap(createPanelLandAccess, this); + mFactoryMap["land_general_panel"] = LLCallbackMap(createPanelLandGeneral, this); + mFactoryMap["land_covenant_panel"] = LLCallbackMap(createPanelLandCovenant, this); + mFactoryMap["land_objects_panel"] = LLCallbackMap(createPanelLandObjects, this); + mFactoryMap["land_options_panel"] = LLCallbackMap(createPanelLandOptions, this); + mFactoryMap["land_audio_panel"] = LLCallbackMap(createPanelLandAudio, this); + mFactoryMap["land_media_panel"] = LLCallbackMap(createPanelLandMedia, this); + mFactoryMap["land_access_panel"] = LLCallbackMap(createPanelLandAccess, this); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about_land.xml", &factory_map, false); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about_land.xml", &getFactoryMap(), false); sObserver = new LLParcelSelectionObserver(); LLViewerParcelMgr::getInstance()->addObserver( sObserver ); @@ -796,7 +791,7 @@ void LLPanelLandGeneral::refreshNames() mTextOwner->setText(owner); std::string group; - if(!parcel->getGroupID().isNull()) + if (!parcel->getGroupID().isNull()) { gCacheName->getGroupName(parcel->getGroupID(), group); } @@ -822,7 +817,6 @@ void LLPanelLandGeneral::refreshNames() // virtual void LLPanelLandGeneral::draw() { - //refreshNames(); LLPanel::draw(); } @@ -833,7 +827,7 @@ void LLPanelLandGeneral::onClickSetGroup() LLFloaterGroupPicker* fg = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); if (fg) { - fg->setSelectCallback( cbGroupID, this); + fg->setSelectGroupCallback( boost::bind(&LLPanelLandGeneral::setGroup, this, _1 )); if (parent_floater) { LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg); @@ -867,13 +861,6 @@ void LLPanelLandGeneral::onClickProfile() } } -// static -void LLPanelLandGeneral::cbGroupID(LLUUID group_id, void* userdata) -{ - LLPanelLandGeneral* self = (LLPanelLandGeneral*)userdata; - self->setGroup(group_id); -} - // public void LLPanelLandGeneral::setGroup(const LLUUID& group_id) { @@ -1128,7 +1115,6 @@ BOOL LLPanelLandObjects::postBuild() mCleanOtherObjectsTime->setFocusLostCallback(boost::bind(&LLPanelLandObjects::onLostFocus, _1, this)); mCleanOtherObjectsTime->setCommitCallback(onCommitClean, this); - mCleanOtherObjectsTime->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32); mBtnRefresh = getChild("Refresh List"); @@ -1545,6 +1531,8 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo return; } + const std::string FONT = "SANSSERIF"; + // Extract all of the owners. S32 rows = msg->getNumberOfBlocksFast(_PREHASH_Data); //uuid_list_t return_ids; @@ -1585,64 +1573,41 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo BOOL in_sim = (std::find(avatar_ids.begin(), avatar_ids.end(), owner_id) != avatar_ids.end()); - LLSD item; - item["id"] = owner_id; - LLSD& row = item["columns"]; - LLSD icon_column; - LLSD status_column; - icon_column["type"] = "icon"; - icon_column["column"] = "type"; - status_column["font"] = "SANSSERIF"; - status_column["column"] = "online_status"; + LLNameListCtrl::NameItem item_params; + item_params.value = owner_id; + item_params.target = is_group_owned ? LLNameListCtrl::GROUP : LLNameListCtrl::INDIVIDUAL; if (is_group_owned) { - icon_column["value"] = self->mIconGroup->getName(); - status_column["value"] = OWNER_GROUP; + item_params.columns.add().type("icon").value(self->mIconGroup->getName()).column("type"); + item_params.columns.add().value(OWNER_GROUP).font(FONT).column("online_status"); } else if (in_sim) { - icon_column["value"] = self->mIconAvatarInSim->getName(); - status_column["value"] = OWNER_INSIM; + item_params.columns.add().type("icon").value(self->mIconAvatarInSim->getName()).column("type"); + item_params.columns.add().value(OWNER_INSIM).font(FONT).column("online_status"); } else if (is_online) { - icon_column["value"] = self->mIconAvatarOnline->getName(); - status_column["value"] = OWNER_ONLINE; + item_params.columns.add().type("icon").value(self->mIconAvatarOnline->getName()).column("type"); + item_params.columns.add().value(OWNER_ONLINE).font(FONT).column("online_status"); } else // offline { - icon_column["value"] = self->mIconAvatarOffline->getName(); - status_column["value"] = OWNER_OFFLINE; + item_params.columns.add().type("icon").value(self->mIconAvatarOffline->getName()).column("type"); + item_params.columns.add().value(OWNER_OFFLINE).font(FONT).column("online_status"); } - row.append(icon_column); - row.append(status_column); // Placeholder for name. LLAvatarName av_name; LLAvatarNameCache::get(owner_id, &av_name); - LLSD name_column; - name_column["value"] = av_name.getCompleteName(); - name_column["font"] = "SANSSERIF"; - name_column["column"] = "name"; - row.append(name_column); + item_params.columns.add().value(av_name.getCompleteName()).font(FONT).column("name"); - LLSD count_column; - count_column["value"] = llformat("%d", object_count); - count_column["font"] = "SANSSERIF"; - count_column["column"] = "count"; - row.append(count_column); - - LLSD time_column; - time_column["value"] = formatted_time((time_t)most_recent_time); - time_column["font"] = "SANSSERIF"; - time_column["column"] = "mostrecent"; - row.append(time_column); + object_count_str = llformat("%d", object_count); + item_params.columns.add().value(object_count_str).font(FONT).column("count"); + item_params.columns.add().value(LLDate((time_t)most_recent_time)).font(FONT).column("mostrecent").type("date"); - if( is_group_owned ) - self->mOwnerList->addGroupNameItem(item, ADD_BOTTOM); - else - self->mOwnerList->addNameItem(item, ADD_BOTTOM); + self->mOwnerList->addNameItemRow(item_params); lldebugs << "object owner " << owner_id << " (" << (is_group_owned ? "group" : "agent") << ") owns " << object_count << " objects." << llendl; @@ -1886,7 +1851,6 @@ BOOL LLPanelLandOptions::postBuild() childSetCommitCallback("check landmark", onCommitAny, this); mCheckLandmark->setVisible(!gHippoGridManager->getConnectedGrid()->isSecondLife()); - mCheckGroupScripts = getChild( "check group scripts"); childSetCommitCallback("check group scripts", onCommitAny, this); @@ -2452,11 +2416,15 @@ BOOL LLPanelLandAccess::postBuild() mListAccess = getChild("AccessList"); if (mListAccess) + { mListAccess->sortByColumnIndex(0, TRUE); // ascending + } mListBanned = getChild("BannedList"); if (mListBanned) + { mListBanned->sortByColumnIndex(0, TRUE); // ascending + } return TRUE; } @@ -2969,10 +2937,7 @@ void LLPanelLandCovenant::refresh() } LLTextBox* region_landtype = getChild("region_landtype_text"); - if (region_landtype) - { - region_landtype->setText(region->getLocalizedSimProductName()); - } + region_landtype->setText(region->getLocalizedSimProductName()); LLTextBox* region_maturity = getChild("region_maturity_text"); if (region_maturity) @@ -3022,11 +2987,8 @@ void LLPanelLandCovenant::updateCovenantText(const std::string &string) if (self) { LLViewerTextEditor* editor = self->getChild("covenant_editor"); - if (editor) - { - editor->setHandleEditKeysDirectly(TRUE); - editor->setText(string); - } + editor->setHandleEditKeysDirectly(TRUE); + editor->setText(string); } } diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 4dd7b962b..7c7316513 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -152,7 +152,6 @@ public: void onClickProfile(); void onClickSetGroup(); static void onClickInfoGroup(void*); - static void cbGroupID(LLUUID group_id, void* userdata); static void onClickDeed(void*); static void onClickBuyLand(void* data); static void onClickScriptLimits(void* data); diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp index 151ed53b6..f0f1f3869 100644 --- a/indra/newview/llfloatermediasettings.cpp +++ b/indra/newview/llfloatermediasettings.cpp @@ -52,7 +52,7 @@ LLFloaterMediaSettings::LLFloaterMediaSettings(const LLSD& key) mMultipleMedia(false), mMultipleValidMedia(false) { - LLUICtrlFactory::getInstance()->buildFloater(this,"floater_media_settings.xml"); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_media_settings.xml", NULL, false); } //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llfloatermessagelog.cpp b/indra/newview/llfloatermessagelog.cpp index 230a4b15a..8847ca2ca 100644 --- a/indra/newview/llfloatermessagelog.cpp +++ b/indra/newview/llfloatermessagelog.cpp @@ -1,19 +1,22 @@ // #include "llviewerprecompiledheaders.h" + #include "llfloatermessagelog.h" -#include "lluictrlfactory.h" -#include "llworld.h" -#include "llnotificationsutil.h" -#include "llviewerregion.h" -#include "llscrolllistctrl.h" -#include "lltexteditor.h" -#include "llviewerwindow.h" // alertXml -#include "llmessagetemplate.h" -#include -#include "llmenugl.h" + #include "lleventtimer.h" +#include "llmenugl.h" +#include "llmessagetemplate.h" +#include "llnotificationsutil.h" +#include "llscrolllistctrl.h" +#include "llscrolllistitem.h" +#include "lltexteditor.h" +#include "lluictrlfactory.h" #include "llagent.h" +#include "llviewerregion.h" +#include "llworld.h" +#include + //////////////////////////////// @@ -826,7 +829,7 @@ BOOL LLFloaterMessageLog::onClickCloseCircuit(void* user_data) // static bool LLFloaterMessageLog::onConfirmCloseCircuit(const LLSD& notification, const LLSD& response ) { - S32 option = LLNotification::getSelectedOption(notification, response); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); LLCircuitData* cdp = gMessageSystem->mCircuitInfo.findCircuit(LLHost(notification["payload"]["circuittoclose"].asString())); if(!cdp) return false; LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(cdp->getHost()); @@ -861,7 +864,7 @@ bool LLFloaterMessageLog::onConfirmCloseCircuit(const LLSD& notification, const // static bool LLFloaterMessageLog::onConfirmRemoveRegion(const LLSD& notification, const LLSD& response ) { - S32 option = LLNotification::getSelectedOption(notification, response); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if(option == 0) // yes LLWorld::getInstance()->removeRegion(LLHost(notification["payload"]["regionhost"].asString())); return false; diff --git a/indra/newview/llfloatermute.cpp b/indra/newview/llfloatermute.cpp index 624c244a4..b4ea23ef4 100644 --- a/indra/newview/llfloatermute.cpp +++ b/indra/newview/llfloatermute.cpp @@ -34,27 +34,15 @@ #include "llfloatermute.h" -#include "llfontgl.h" -#include "llrect.h" -#include "llerror.h" -#include "llstring.h" -#include "message.h" +#include "llavatarname.h" #include "llnotificationsutil.h" +#include "llscrolllistitem.h" +#include "lluictrlfactory.h" // project include -#include "llagent.h" -#include "llavatarnamecache.h" #include "llfloateravatarpicker.h" -#include "llbutton.h" -#include "lllineeditor.h" #include "llmutelist.h" #include "llnamelistctrl.h" -#include "llresizehandle.h" -#include "lltextbox.h" -#include "llviewertexteditor.h" -#include "llviewerwindow.h" -#include "lluictrlfactory.h" -#include "llfocusmgr.h" #include @@ -250,46 +238,48 @@ void LLFloaterMute::refreshMuteList() for (it = mutes.begin(); it != mutes.end(); ++it) { std::string display_name = it->mName; - LLSD element; + LLNameListCtrl::NameItem element; LLUUID entry_id; if(it->mType == LLMute::GROUP || it->mType == LLMute::AGENT) entry_id = it->mID; else entry_id.generate(boost::lexical_cast( count++ )); mMuteDict.insert(std::make_pair(entry_id,*it)); - element["id"] = entry_id; - element["name"] = display_name; + element.value = entry_id; + element.name = display_name; - LLSD& name_column = element["columns"][1]; - name_column["column"] = "name"; - name_column["type"] = "text"; - name_column["value"] = ""; + LLScrollListCell::Params name_column; + name_column.column = "name"; + name_column.type = "text"; + name_column.value = ""; - LLSD& icon_column = element["columns"][0]; - icon_column["column"] = "icon"; - icon_column["type"] = "icon"; + LLScrollListCell::Params icon_column; + icon_column.column = "icon"; + icon_column.type = "icon"; switch(it->mType) { case LLMute::GROUP: - icon_column["value"] = mGroupIcon->getName(); - element["target"] = LLNameListCtrl::GROUP; + icon_column.value = mGroupIcon->getName(); + element.target = LLNameListCtrl::GROUP; break; case LLMute::AGENT: - icon_column["value"] = mAvatarIcon->getName(); - element["target"] = LLNameListCtrl::INDIVIDUAL; + icon_column.value = mAvatarIcon->getName(); + element.target = LLNameListCtrl::INDIVIDUAL; break; case LLMute::OBJECT: - icon_column["value"] = mObjectIcon->getName(); - element["target"] = LLNameListCtrl::SPECIAL; + icon_column.value = mObjectIcon->getName(); + element.target = LLNameListCtrl::SPECIAL; break; case LLMute::BY_NAME: default: - icon_column["value"] = mNameIcon->getName(); - element["target"] = LLNameListCtrl::SPECIAL; + icon_column.value = mNameIcon->getName(); + element.target = LLNameListCtrl::SPECIAL; break; } + element.columns.add(icon_column); + element.columns.add(name_column); mMuteList->addNameItemRow(element); } mMuteList->updateSort(); diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp index d4133befe..dc03d8237 100644 --- a/indra/newview/llfloaternotificationsconsole.cpp +++ b/indra/newview/llfloaternotificationsconsole.cpp @@ -36,9 +36,9 @@ #include "lluictrlfactory.h" #include "llbutton.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "llpanel.h" #include "llcombobox.h" -#include "llviewertexteditor.h" const S32 NOTIFICATION_PANEL_HEADER_HEIGHT = 20; const S32 HEADER_PADDING = 38; @@ -59,7 +59,7 @@ private: }; LLNotificationChannelPanel::LLNotificationChannelPanel(const std::string& channel_name) - : LLLayoutPanel(NOTIFICATION_PANEL_HEADER_HEIGHT,true,true) +: LLLayoutPanel(NOTIFICATION_PANEL_HEADER_HEIGHT,true,true) { setName(channel_name); mChannelPtr = LLNotifications::instance().getChannel(channel_name); @@ -112,10 +112,15 @@ void LLNotificationChannelPanel::onClickNotification(void* user_data) { LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data; if (!self) return; - void* data = self->getChild("notifications_list")->getFirstSelected()->getUserdata(); - if (data) + LLScrollListItem* firstselected = self->getChild("notifications_list")->getFirstSelected(); + llassert(firstselected); + if (firstselected) { - gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE); + void* data = firstselected->getUserdata(); + if (data) + { + gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE); + } } } @@ -160,7 +165,9 @@ bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter) // LLFloaterNotificationConsole // LLFloaterNotificationConsole::LLFloaterNotificationConsole(const LLSD& key) +: LLFloater() { + mCommitCallbackRegistrar.add("ClickAdd", boost::bind(&LLFloaterNotificationConsole::onClickAdd, this)); LLUICtrlFactory::instance().buildFloater(this, "floater_notifications_console.xml"); } @@ -185,7 +192,7 @@ BOOL LLFloaterNotificationConsole::postBuild() addChannel("Notifications"); addChannel("NotificationTips"); - getChild("add_notification")->setClickedCallback(onClickAdd, this); +// getChild("add_notification")->setClickedCallback(onClickAdd, this); LLComboBox* notifications = getChild("notification_types"); LLNotificationTemplates::TemplateNames names = LLNotificationTemplates::instance().getTemplateNames(); @@ -232,21 +239,21 @@ void LLFloaterNotificationConsole::updateResizeLimits() setResizeLimits(getMinWidth(), LLFLOATER_HEADER_SIZE + HEADER_PADDING + ((NOTIFICATION_PANEL_HEADER_HEIGHT + 3) * stack.getNumPanels())); } -void LLFloaterNotificationConsole::onClickAdd(void* user_data) +void LLFloaterNotificationConsole::onClickAdd() { - LLFloaterNotificationConsole* floater = (LLFloaterNotificationConsole*)user_data; - - std::string message_name = floater->getChild("notification_types")->getValue().asString(); + std::string message_name = getChild("notification_types")->getValue().asString(); if (!message_name.empty()) { - LLNotifications::instance().add(message_name, LLSD()); + LLNotifications::instance().add(message_name, LLSD(), LLSD()); } } //=============== LLFloaterNotification ================ -LLFloaterNotification::LLFloaterNotification(LLNotification* note) : mNote(note) +LLFloaterNotification::LLFloaterNotification(LLNotification* note) +: LLFloater(), + mNote(note) { LLUICtrlFactory::instance().buildFloater(this, "floater_notification.xml"); } @@ -254,7 +261,7 @@ LLFloaterNotification::LLFloaterNotification(LLNotification* note) : mNote(note) BOOL LLFloaterNotification::postBuild() { setTitle(mNote->getName()); - getChild("payload")->setText(mNote->getMessage()); + getChild("payload")->setValue(mNote->getMessage()); LLComboBox* responses_combo = getChild("response"); LLCtrlListInterface* response_list = responses_combo->getListInterface(); diff --git a/indra/newview/llfloaternotificationsconsole.h b/indra/newview/llfloaternotificationsconsole.h index c4a361538..a1baea39f 100644 --- a/indra/newview/llfloaternotificationsconsole.h +++ b/indra/newview/llfloaternotificationsconsole.h @@ -35,7 +35,9 @@ #include "llfloater.h" #include "lllayoutstack.h" -#include "llnotifications.h" +//#include "llnotificationsutil.h" + +class LLNotification; class LLFloaterNotificationConsole : public LLFloater, @@ -55,7 +57,7 @@ public: void updateResizeLimits(); private: - static void onClickAdd(void* user_data); + void onClickAdd(); }; diff --git a/indra/newview/llfloaterpathfindinglinksets.cpp b/indra/newview/llfloaterpathfindinglinksets.cpp index 69b4bce60..35f6b9c1f 100644 --- a/indra/newview/llfloaterpathfindinglinksets.cpp +++ b/indra/newview/llfloaterpathfindinglinksets.cpp @@ -43,7 +43,7 @@ #include "llpathfindinglinkset.h" #include "llpathfindinglinksetlist.h" #include "llpathfindingmanager.h" -#include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "llsd.h" #include "lltextbox.h" #include "llui.h" @@ -114,26 +114,26 @@ BOOL LLFloaterPathfindingLinksets::postBuild() { mBeaconColor = LLUI::sColorsGroup->getColor("PathfindingLinksetBeaconColor"); - mFilterByName = getChild("filter_by_name"); + mFilterByName = findChild("filter_by_name"); llassert(mFilterByName != NULL); mFilterByName->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); mFilterByName->setSelectAllonFocusReceived(true); mFilterByName->setCommitOnFocusLost(true); - mFilterByDescription = getChild("filter_by_description"); + mFilterByDescription = findChild("filter_by_description"); llassert(mFilterByDescription != NULL); mFilterByDescription->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); mFilterByDescription->setSelectAllonFocusReceived(true); mFilterByDescription->setCommitOnFocusLost(true); - mFilterByLinksetUse = getChild("filter_by_linkset_use"); + mFilterByLinksetUse = findChild("filter_by_linkset_use"); llassert(mFilterByLinksetUse != NULL); mFilterByLinksetUse->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); childSetAction("apply_filters", boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); childSetAction("clear_filters", boost::bind(&LLFloaterPathfindingLinksets::onClearFiltersClicked, this)); - mEditLinksetUse = getChild("edit_linkset_use"); + mEditLinksetUse = findChild("edit_linkset_use"); llassert(mEditLinksetUse != NULL); mEditLinksetUse->clearRows(); @@ -160,54 +160,54 @@ BOOL LLFloaterPathfindingLinksets::postBuild() mEditLinksetUse->selectFirstItem(); - mLabelWalkabilityCoefficients = getChild("walkability_coefficients_label"); + mLabelWalkabilityCoefficients = findChild("walkability_coefficients_label"); llassert(mLabelWalkabilityCoefficients != NULL); - mLabelEditA = getChild("edit_a_label"); + mLabelEditA = findChild("edit_a_label"); llassert(mLabelEditA != NULL); - mLabelSuggestedUseA = getChild("suggested_use_a_label"); + mLabelSuggestedUseA = findChild("suggested_use_a_label"); llassert(mLabelSuggestedUseA != NULL); - mEditA = getChild("edit_a_value"); + mEditA = findChild("edit_a_value"); llassert(mEditA != NULL); mEditA->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32); mEditA->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueA)); - mLabelEditB = getChild("edit_b_label"); + mLabelEditB = findChild("edit_b_label"); llassert(mLabelEditB != NULL); - mLabelSuggestedUseB = getChild("suggested_use_b_label"); + mLabelSuggestedUseB = findChild("suggested_use_b_label"); llassert(mLabelSuggestedUseB != NULL); - mEditB = getChild("edit_b_value"); + mEditB = findChild("edit_b_value"); llassert(mEditB != NULL); mEditB->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32); mEditB->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueB)); - mLabelEditC = getChild("edit_c_label"); + mLabelEditC = findChild("edit_c_label"); llassert(mLabelEditC != NULL); - mLabelSuggestedUseC = getChild("suggested_use_c_label"); + mLabelSuggestedUseC = findChild("suggested_use_c_label"); llassert(mLabelSuggestedUseC != NULL); - mEditC = getChild("edit_c_value"); + mEditC = findChild("edit_c_value"); llassert(mEditC != NULL); mEditC->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32); mEditC->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueC)); - mLabelEditD = getChild("edit_d_label"); + mLabelEditD = findChild("edit_d_label"); llassert(mLabelEditD != NULL); - mLabelSuggestedUseD = getChild("suggested_use_d_label"); + mLabelSuggestedUseD = findChild("suggested_use_d_label"); llassert(mLabelSuggestedUseD != NULL); - mEditD = getChild("edit_d_value"); + mEditD = findChild("edit_d_value"); llassert(mEditD != NULL); mEditD->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32); mEditD->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueD)); - mApplyEditsButton = getChild("apply_edit_values"); + mApplyEditsButton = findChild("apply_edit_values"); llassert(mApplyEditsButton != NULL); mApplyEditsButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyChangesClicked, this)); diff --git a/indra/newview/llfloaterpathfindingobjects.cpp b/indra/newview/llfloaterpathfindingobjects.cpp index 017278719..8a606a07b 100644 --- a/indra/newview/llfloaterpathfindingobjects.cpp +++ b/indra/newview/llfloaterpathfindingobjects.cpp @@ -49,6 +49,7 @@ #include "llpathfindingmanager.h" #include "llresmgr.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "llselectmgr.h" #include "llsd.h" #include "llstring.h" @@ -205,46 +206,46 @@ BOOL LLFloaterPathfindingObjects::postBuild() mErrorTextColor = LLUI::sColorsGroup->getColor("PathfindingErrorColor"); mWarningTextColor = LLUI::sColorsGroup->getColor("PathfindingWarningColor"); - mObjectsScrollList = getChild("objects_scroll_list"); + mObjectsScrollList = findChild("objects_scroll_list"); llassert(mObjectsScrollList != NULL); mObjectsScrollList->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onScrollListSelectionChanged, this)); mObjectsScrollList->sortByColumnIndex(static_cast(getNameColumnIndex()), TRUE); - mMessagingStatus = getChild("messaging_status"); + mMessagingStatus = findChild("messaging_status"); llassert(mMessagingStatus != NULL); - mRefreshListButton = getChild("refresh_objects_list"); + mRefreshListButton = findChild("refresh_objects_list"); llassert(mRefreshListButton != NULL); mRefreshListButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onRefreshObjectsClicked, this)); - mSelectAllButton = getChild("select_all_objects"); + mSelectAllButton = findChild("select_all_objects"); llassert(mSelectAllButton != NULL); mSelectAllButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onSelectAllObjectsClicked, this)); - mSelectNoneButton = getChild("select_none_objects"); + mSelectNoneButton = findChild("select_none_objects"); llassert(mSelectNoneButton != NULL); mSelectNoneButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onSelectNoneObjectsClicked, this)); - mShowBeaconCheckBox = getChild("show_beacon"); + mShowBeaconCheckBox = findChild("show_beacon"); llassert(mShowBeaconCheckBox != NULL); - mTakeButton = getChild("take_objects"); + mTakeButton = findChild("take_objects"); llassert(mTakeButton != NULL); mTakeButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onTakeClicked, this)); - mTakeCopyButton = getChild("take_copy_objects"); + mTakeCopyButton = findChild("take_copy_objects"); llassert(mTakeCopyButton != NULL); mTakeCopyButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onTakeCopyClicked, this)); - mReturnButton = getChild("return_objects"); + mReturnButton = findChild("return_objects"); llassert(mReturnButton != NULL); mReturnButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onReturnClicked, this)); - mDeleteButton = getChild("delete_objects"); + mDeleteButton = findChild("delete_objects"); llassert(mDeleteButton != NULL); mDeleteButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onDeleteClicked, this)); - mTeleportButton = getChild("teleport_me_to_object"); + mTeleportButton = findChild("teleport_me_to_object"); llassert(mTeleportButton != NULL); mTeleportButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onTeleportClicked, this)); diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp index 5fcdc8bbf..46b67d1de 100644 --- a/indra/newview/llfloaterproperties.cpp +++ b/indra/newview/llfloaterproperties.cpp @@ -172,6 +172,8 @@ BOOL LLFloaterProperties::postBuild() getChild("BtnCreator")->setCommitCallback(boost::bind(&LLFloaterProperties::onClickCreator,this)); // owner information getChild("BtnOwner")->setCommitCallback(boost::bind(&LLFloaterProperties::onClickOwner,this)); + // last owner information + getChild("BtnLastOwner")->setCommitCallback(boost::bind(&LLFloaterProperties::onClickLastOwner,this)); // acquired date // owner permissions // Permissions debug text @@ -227,6 +229,8 @@ void LLFloaterProperties::refresh() "BtnCreator", "LabelOwnerName", "BtnOwner", + "LabelLastOwnerName", + "BtnLastOwner", "CheckOwnerModify", "CheckOwnerCopy", "CheckOwnerTransfer", @@ -341,6 +345,21 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) getChild("LabelCreatorName")->setValue(getString("unknown")); } + if (perm.getLastOwner().notNull()) + { + std::string name; + gCacheName->getFullName(perm.getLastOwner(), name); + getChildView("LabelLastOwnerTitle")->setEnabled(true); + getChildView("LabelLastOwnerName")->setEnabled(true); + getChild("LabelLastOwnerName")->setValue(name); + } + else + { + getChildView("LabelLastOwnerTitle")->setEnabled(false); + getChildView("LabelLastOwnerName")->setEnabled(false); + getChild("LabelLastOwnerName")->setValue(getString("unknown")); + } + //////////////// // OWNER NAME // //////////////// @@ -617,6 +636,11 @@ void LLFloaterProperties::onClickOwner() } } +void LLFloaterProperties::onClickLastOwner() +{ + if (const LLInventoryItem* item = findItem()) LLAvatarActions::showProfile(item->getPermissions().getLastOwner()); +} + // static void LLFloaterProperties::onCommitName() { diff --git a/indra/newview/llfloaterproperties.h b/indra/newview/llfloaterproperties.h index 69c5eead2..d2640f07d 100644 --- a/indra/newview/llfloaterproperties.h +++ b/indra/newview/llfloaterproperties.h @@ -76,6 +76,7 @@ protected: // ui callbacks void onClickCreator(); void onClickOwner(); + void onClickLastOwner(); void onCommitName(); void onCommitDescription(); void onCommitPermissions(); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 3a139d595..d8e7fadd4 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -37,7 +37,6 @@ #include #include -#include "llcachename.h" #include "lldir.h" #include "lldispatcher.h" #include "llglheaders.h" @@ -69,6 +68,7 @@ #include "llnotifications.h" #include "llnotificationsutil.h" #include "llregioninfomodel.h" +#include "llscrolllistitem.h" #include "llsliderctrl.h" #include "llspinctrl.h" #include "lltabcontainer.h" @@ -355,7 +355,7 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) // extract message std::string sim_name; std::string sim_type = LLTrans::getString("land_type_unknown"); - U32 region_flags; + U64 region_flags; U8 agent_limit; F32 object_bonus_factor; U8 sim_access; @@ -365,7 +365,6 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) BOOL use_estate_sun; F32 sun_hour; msg->getString("RegionInfo", "SimName", sim_name); - msg->getU32("RegionInfo", "RegionFlags", region_flags); msg->getU8("RegionInfo", "MaxAgents", agent_limit); msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor); msg->getU8("RegionInfo", "SimAccess", sim_access); @@ -384,6 +383,17 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) LLTrans::findString(sim_type, sim_type); // try localizing sim product name } + if (msg->has(_PREHASH_RegionInfo3)) + { + msg->getU64("RegionInfo3", "RegionFlagsExtended", region_flags); + } + else + { + U32 flags = 0; + msg->getU32("RegionInfo", "RegionFlags", flags); + region_flags = flags; + } + // Disable Environment Tab when not supported if (region) { @@ -1081,8 +1091,10 @@ void LLPanelRegionDebugInfo::onClickTopColliders(void* data) strings_t strings; strings.push_back("1"); // one physics step LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - LLFloaterTopObjects::show(); - LLFloaterTopObjects::clearList(); + LLFloaterTopObjects* instance = LLFloaterTopObjects::getInstance(); + if(!instance) return; + instance->open(); + instance->clearList(); self->sendEstateOwnerMessage(gMessageSystem, "colliders", invoice, strings); } @@ -1093,8 +1105,10 @@ void LLPanelRegionDebugInfo::onClickTopScripts(void* data) strings_t strings; strings.push_back("6"); // top 5 scripts LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - LLFloaterTopObjects::show(); - LLFloaterTopObjects::clearList(); + LLFloaterTopObjects* instance = LLFloaterTopObjects::getInstance(); + if(!instance) return; + instance->open(); + instance->clearList(); self->sendEstateOwnerMessage(gMessageSystem, "scripts", invoice, strings); } @@ -1493,7 +1507,8 @@ bool LLPanelEstateInfo::addAllowedGroup(const LLSD& notification, const LLSD& re LLFloaterGroupPicker* widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); if (widget) { - widget->setSelectCallback(addAllowedGroup2, NULL); + widget->removeNoneOption(); + widget->setSelectGroupCallback(boost::bind(&LLPanelEstateInfo::addAllowedGroup2, this, _1)); if (parent_floater) { LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget); @@ -1683,9 +1698,8 @@ struct LLEstateAccessChangeInfo uuid_vec_t mAgentOrGroupIDs; // List of agent IDs to apply to this change }; -// static // Special case callback for groups, since it has different callback format than names -void LLPanelEstateInfo::addAllowedGroup2(LLUUID id, void*) +void LLPanelEstateInfo::addAllowedGroup2(LLUUID id) { LLSD payload; payload["operation"] = (S32)ESTATE_ACCESS_ALLOWED_GROUP_ADD; @@ -2339,8 +2353,8 @@ public: // if we get an error response /*virtual*/ void error(U32 status, const std::string& reason) { - llinfos << "LLEstateChangeInfoResponder::error " - << status << ": " << reason << llendl; + llinfos << "LLEstateChangeInfoResponder::error [status:" + << status << "]: " << reason << llendl; } /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return estateChangeInfoResponder_timeout; } @@ -2698,7 +2712,7 @@ BOOL LLPanelEstateCovenant::sendUpdate() return TRUE; } -const std::string& LLPanelEstateCovenant::getEstateName() const +std::string LLPanelEstateCovenant::getEstateName() const { return mEstateNameText->getText(); } @@ -2749,7 +2763,7 @@ void LLPanelEstateCovenant::updateEstateOwnerName(const std::string& name) } } -const std::string& LLPanelEstateCovenant::getOwnerName() const +std::string LLPanelEstateCovenant::getOwnerName() const { return mEstateOwnerText->getText(); } diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index f81ec930b..00c672b9d 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -229,7 +229,7 @@ public: virtual BOOL postBuild(); // LLPanel virtual bool refreshFromRegion(LLViewerRegion* region); // refresh local settings from region update from simulator - + BOOL validateTextureSizes(); protected: @@ -273,7 +273,7 @@ public: // Group picker callback is different, can't use core methods below bool addAllowedGroup(const LLSD& notification, const LLSD& response); - static void addAllowedGroup2(LLUUID id, void*); + void addAllowedGroup2(LLUUID id); // Core methods for all above add/remove button clicks static void accessAddCore(U32 operation_flag, const std::string& dialog_name); @@ -309,7 +309,7 @@ public: virtual BOOL postBuild(); virtual void updateChild(LLUICtrl* child_ctrl); virtual void refresh(); - + void refreshFromEstate(); static bool isLindenEstate(); @@ -369,9 +369,9 @@ public: const LLUUID& getCovenantID() const { return mCovenantID; } void setCovenantID(const LLUUID& id) { mCovenantID = id; } - const std::string& getEstateName() const; + std::string getEstateName() const; void setEstateName(const std::string& name); - const std::string& getOwnerName() const; + std::string getOwnerName() const; void setOwnerName(const std::string& name); void setCovenantTextEditor(const std::string& text); diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index 70022a6e2..84c2ff953 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -26,7 +26,6 @@ */ #include "llviewerprecompiledheaders.h" -#include "llhttpclient.h" #include "llfloaterscriptlimits.h" // library includes @@ -39,7 +38,9 @@ #include "llfloateravatarpicker.h" #include "llfloaterland.h" #include "llregionhandle.h" +#include "llscrolllistcolumn.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "llparcel.h" #include "lltabcontainer.h" #include "lltracker.h" @@ -223,7 +224,7 @@ void fetchScriptLimitsRegionInfoResponder::result(const LLSD& content) void fetchScriptLimitsRegionInfoResponder::error(U32 status, const std::string& reason) { - llwarns << "Error from responder " << reason << llendl; + llwarns << "fetchScriptLimitsRegionInfoResponder error [status:" << status << "]: " << reason << llendl; } void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref) @@ -310,7 +311,7 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref) void fetchScriptLimitsRegionSummaryResponder::error(U32 status, const std::string& reason) { - llwarns << "Error from responder " << reason << llendl; + llwarns << "fetchScriptLimitsRegionSummaryResponder error [status:" << status << "]: " << reason << llendl; } void fetchScriptLimitsRegionDetailsResponder::result(const LLSD& content_ref) @@ -419,7 +420,7 @@ result (map) void fetchScriptLimitsRegionDetailsResponder::error(U32 status, const std::string& reason) { - llwarns << "Error from responder " << reason << llendl; + llwarns << "fetchScriptLimitsRegionDetailsResponder error [status:" << status << "]: " << reason << llendl; } void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref) @@ -515,7 +516,7 @@ void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref) void fetchScriptLimitsAttachmentInfoResponder::error(U32 status, const std::string& reason) { - llwarns << "Error from responder " << reason << llendl; + llwarns << "fetchScriptLimitsAttachmentInfoResponder error [status:" << status << "]: " << reason << llendl; } ///---------------------------------------------------------------------------- @@ -603,14 +604,7 @@ void LLPanelScriptLimitsRegionMemory::onNameCache( } std::string name; - if (LLAvatarNameCache::useDisplayNames()) - { - name = LLCacheName::buildUsername(full_name); - } - else - { - name = full_name; - } + LLAvatarNameCache::getPNSName(id, name); std::vector::iterator id_itor; for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor) diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp index f95e8b365..a382c016c 100644 --- a/indra/newview/llfloatersettingsdebug.cpp +++ b/indra/newview/llfloatersettingsdebug.cpp @@ -37,15 +37,15 @@ #include "llcolorswatch.h" //#include "llfirstuse.h" #include "llfloater.h" -#include "llfiltereditor.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "llspinctrl.h" #include "lltexteditor.h" #include "lluictrlfactory.h" #include "llviewercontrol.h" #include "llwindow.h" -// [RLVa:KB] +// [RLVa:KB] - Checked: 2010-03-18 (RLVa-1.2.0a) #include "rlvhandler.h" #include "rlvextensions.h" // [/RLVa:KB] @@ -56,6 +56,12 @@ LLFloaterSettingsDebug::LLFloaterSettingsDebug() , mOldControlVariable(NULL) , mOldSearchTerm(std::string("---")) { + mCommitCallbackRegistrar.add("SettingSelect", boost::bind(&LLFloaterSettingsDebug::onSettingSelect, this)); + mCommitCallbackRegistrar.add("CommitSettings", boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); + mCommitCallbackRegistrar.add("ClickDefault", boost::bind(&LLFloaterSettingsDebug::onClickDefault, this)); + mCommitCallbackRegistrar.add("UpdateFilter", boost::bind(&LLFloaterSettingsDebug::onUpdateFilter, this, _2)); + mCommitCallbackRegistrar.add("ClickCopy", boost::bind(&LLFloaterSettingsDebug::onCopyToClipboard, this)); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_settings_debug.xml"); } @@ -96,19 +102,9 @@ BOOL LLFloaterSettingsDebug::postBuild() } } mSettingsScrollList->sortByColumnIndex(0, true); - mSettingsScrollList->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onSettingSelect, this)); llinfos << mSettingsScrollList->getItemCount() << " total debug settings displayed." << llendl; - getChild("val_spinner_1")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); - getChild("val_spinner_2")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); - getChild("val_spinner_3")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); - getChild("val_spinner_4")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); - getChild("val_text")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); - getChild("boolean_combo")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); - getChild("copy_btn")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onCopyToClipboard, this)); - getChild("default_btn")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onClickDefault, this)); - getChild("search_settings_input")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onUpdateFilter, this, _2)); mComment = getChild("comment_text"); return TRUE; } diff --git a/indra/newview/llfloaterteleporthistory.cpp b/indra/newview/llfloaterteleporthistory.cpp index 173aaf5a7..27ad58de6 100644 --- a/indra/newview/llfloaterteleporthistory.cpp +++ b/indra/newview/llfloaterteleporthistory.cpp @@ -32,28 +32,19 @@ #include "llviewerprecompiledheaders.h" -#include "linden_common.h" - -#include - -//MK -#include "llworld.h" -#include "lleventpoll.h" -#include "llagent.h" -//mk -#include "llappviewer.h" #include "llfloaterteleporthistory.h" + +#include "llappviewer.h" #include "llfloaterworldmap.h" +#include "llscrolllistcolumn.h" +#include "llscrolllistitem.h" +#include "llsdserialize.h" #include "llslurl.h" -#include "lltimer.h" #include "lluictrlfactory.h" -#include "llurldispatcher.h" -#include "llviewercontrol.h" +#include "llurlaction.h" #include "llviewerwindow.h" #include "llwindow.h" #include "llweb.h" -#include "llsdserialize.h" -#include "llurlaction.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index 6b181433d..8c767e64b 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -34,16 +34,17 @@ #include "llfloatertopobjects.h" +// library includes #include "message.h" #include "llfontgl.h" #include "llagent.h" -#include "llavataractions.h" #include "llbutton.h" #include "llfloatergodtools.h" #include "llnotificationsutil.h" #include "llparcel.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "lllineeditor.h" #include "lltextbox.h" #include "lltracker.h" @@ -55,13 +56,13 @@ #include "llagentcamera.h" #include "llviewerobjectlist.h" -void cmdline_printchat(std::string message); +#include "llavataractions.h" -LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL; +//LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL; // Globals // const U32 TIME_STR_LENGTH = 30; - +/* // static void LLFloaterTopObjects::show() { @@ -72,89 +73,76 @@ void LLFloaterTopObjects::show() } sInstance = new LLFloaterTopObjects(); - LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_top_objects.xml"); sInstance->center(); } - +*/ LLFloaterTopObjects::LLFloaterTopObjects() : LLFloater(std::string("top_objects")), mInitialized(FALSE), mtotalScore(0.f) { - sInstance = this; + mCommitCallbackRegistrar.add("TopObjects.ShowBeacon", boost::bind(&LLFloaterTopObjects::onClickShowBeacon, this)); + mCommitCallbackRegistrar.add("TopObjects.ReturnSelected", boost::bind(&LLFloaterTopObjects::onReturnSelected, this)); + mCommitCallbackRegistrar.add("TopObjects.ReturnAll", boost::bind(&LLFloaterTopObjects::onReturnAll, this)); + mCommitCallbackRegistrar.add("TopObjects.DisableSelected", boost::bind(&LLFloaterTopObjects::onDisableSelected, this)); + mCommitCallbackRegistrar.add("TopObjects.DisableAll", boost::bind(&LLFloaterTopObjects::onDisableAll, this)); + mCommitCallbackRegistrar.add("TopObjects.Refresh", boost::bind(&LLFloaterTopObjects::onRefresh, this)); + mCommitCallbackRegistrar.add("TopObjects.GetByObjectName", boost::bind(&LLFloaterTopObjects::onGetByObjectName, this)); + mCommitCallbackRegistrar.add("TopObjects.GetByOwnerName", boost::bind(&LLFloaterTopObjects::onGetByOwnerName, this)); + mCommitCallbackRegistrar.add("TopObjects.GetByParcelName", boost::bind(&LLFloaterTopObjects::onGetByParcelName, this)); + mCommitCallbackRegistrar.add("TopObjects.CommitObjectsList",boost::bind(&LLFloaterTopObjects::onCommitObjectsList, this)); + + mCommitCallbackRegistrar.add("TopObjects.TeleportToObject", boost::bind(&LLFloaterTopObjects::onTeleportToObject, this)); + mCommitCallbackRegistrar.add("TopObjects.Kick", boost::bind(&LLFloaterTopObjects::onKick, this)); + mCommitCallbackRegistrar.add("TopObjects.Profile", boost::bind(&LLFloaterTopObjects::onProfile, this)); + + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_top_objects.xml"); } LLFloaterTopObjects::~LLFloaterTopObjects() { - sInstance = NULL; } // virtual BOOL LLFloaterTopObjects::postBuild() { - LLScrollListCtrl *objects_list = getChild("objects_list"); - if (objects_list) - { - objects_list->setCommitCallback(boost::bind(&LLFloaterTopObjects::onCommitObjectsList,_1,this)); - objects_list->setDoubleClickCallback(boost::bind(&LLFloaterTopObjects::onDoubleClickObjectsList,this)); - objects_list->setFocus(true); - objects_list->setCommitOnSelectionChange(TRUE); - } + getChild("objects_list")->setFocus(TRUE); + objects_list->setDoubleClickCallback(onDoubleClickObjectsList, this); + objects_list->setCommitOnSelectionChange(TRUE); - childSetAction("show_beacon_btn", onClickShowBeacon, this); setDefaultBtn("show_beacon_btn"); - childSetAction("return_selected_btn", onReturnSelected, this); - childSetAction("return_all_btn", onReturnAll, this); - childSetAction("disable_selected_btn", onDisableSelected, this); - childSetAction("disable_all_btn", onDisableAll, this); - childSetAction("refresh_btn", onRefresh, this); - - childSetAction("lagwarning", onLagWarningBtn, this); - childSetAction("profile", onProfileBtn, this); - childSetAction("kick", onKickBtn, this); - childSetAction("tpto", onTPBtn, this); - - - childSetAction("filter_object_btn", onGetByObjectNameClicked, this); - childSetAction("filter_owner_btn", onGetByOwnerNameClicked, this); - - - /* - LLLineEditor* line_editor = getChild("owner_name_editor"); - if (line_editor) - { - line_editor->setCommitOnFocusLost(FALSE); - line_editor->setCommitCallback(onGetByOwnerName, this); - } - - line_editor = getChild("object_name_editor"); - if (line_editor) - { - line_editor->setCommitOnFocusLost(FALSE); - line_editor->setCommitCallback(onGetByObjectName, this); - }*/ - mCurrentMode = STAT_REPORT_TOP_SCRIPTS; mFlags = 0; mFilter.clear(); + center(); return TRUE; } +// static +void LLFloaterTopObjects::setMode(U32 mode) +{ + LLFloaterTopObjects* instance = instanceExists() ? getInstance() : NULL; + if(!instance) return; + instance->mCurrentMode = mode; +} +// static void LLFloaterTopObjects::handle_land_reply(LLMessageSystem* msg, void** data) { + LLFloaterTopObjects* instance = instanceExists() ? getInstance() : NULL; + if(!instance) return; // Make sure dialog is on screen - show(); - sInstance->handleReply(msg, data); + instance->open(); + instance->handleReply(msg, data); //HACK: for some reason sometimes top scripts originally comes back //with no results even though they're there - if (!sInstance->mObjectListIDs.size() && !sInstance->mInitialized) + if (!instance->mObjectListIDs.size() && !instance->mInitialized) { - sInstance->onRefresh(NULL); - sInstance->mInitialized = TRUE; + instance->onRefresh(); + instance->mInitialized = TRUE; } } @@ -169,7 +157,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) msg->getU32Fast(_PREHASH_RequestData, _PREHASH_ReportType, mCurrentMode); LLScrollListCtrl *list = getChild("objects_list"); - + S32 block_count = msg->getNumberOfBlocks("ReportData"); for (S32 block = 0; block < block_count; ++block) { @@ -180,9 +168,11 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) F32 score; std::string name_buf; std::string owner_buf; + std::string parcel_buf("unknown"); F32 mono_score = 0.f; bool have_extended_data = false; S32 public_urls = 0; + F32 script_memory = 0.f; msg->getU32Fast(_PREHASH_ReportData, _PREHASH_TaskLocalID, task_local_id, block); msg->getUUIDFast(_PREHASH_ReportData, _PREHASH_TaskID, task_id, block); @@ -192,53 +182,66 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) msg->getF32Fast(_PREHASH_ReportData, _PREHASH_Score, score, block); msg->getStringFast(_PREHASH_ReportData, _PREHASH_TaskName, name_buf, block); msg->getStringFast(_PREHASH_ReportData, _PREHASH_OwnerName, owner_buf, block); + if(msg->has("DataExtended")) { have_extended_data = true; msg->getU32("DataExtended", "TimeStamp", time_stamp, block); msg->getF32("DataExtended", "MonoScore", mono_score, block); - msg->getS32(_PREHASH_ReportData,"PublicURLs",public_urls,block); + msg->getS32("DataExtended", "PublicURLs", public_urls, block); + if (msg->getSize("DataExtended", "ParcelName") > 0) + { + msg->getString("DataExtended", "ParcelName", parcel_buf, block); + msg->getF32("DataExtended", "Size", script_memory, block); + } } LLSD element; element["id"] = task_id; - element["object_name"] = name_buf; - element["owner_name"] = owner_buf; - element["columns"][0]["column"] = "score"; - element["columns"][0]["value"] = llformat("%0.3f", score); - element["columns"][0]["font"] = "SANSSERIF"; + + LLSD columns; + S32 column_num = 0; + columns[column_num]["column"] = "score"; + columns[column_num]["value"] = llformat("%0.3f", score); + columns[column_num++]["font"] = "SANSSERIF"; - element["columns"][1]["column"] = "name"; - element["columns"][1]["value"] = name_buf; - element["columns"][1]["font"] = "SANSSERIF"; - if (name_buf == owner_buf) - { - element["columns"][1]["color"] = LLColor4::red.getValue(); - } - element["columns"][2]["column"] = "owner"; - element["columns"][2]["value"] = owner_buf; - element["columns"][2]["font"] = "SANSSERIF"; - element["columns"][3]["column"] = "location"; - element["columns"][3]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z); - element["columns"][3]["font"] = "SANSSERIF"; - element["columns"][4]["column"] = "time"; - element["columns"][4]["value"] = formatted_time((time_t)time_stamp); - element["columns"][4]["font"] = "SANSSERIF"; + columns[column_num]["column"] = "name"; + columns[column_num]["value"] = name_buf; + columns[column_num++]["font"] = "SANSSERIF"; + + columns[column_num]["column"] = "owner"; + columns[column_num]["value"] = owner_buf; + columns[column_num++]["font"] = "SANSSERIF"; + + columns[column_num]["column"] = "location"; + columns[column_num]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z); + columns[column_num++]["font"] = "SANSSERIF"; + + columns[column_num]["column"] = "parcel"; + columns[column_num]["value"] = parcel_buf; + columns[column_num++]["font"] = "SANSSERIF"; + + columns[column_num]["column"] = "time"; + columns[column_num]["value"] = formatted_time((time_t)time_stamp); + columns[column_num++]["font"] = "SANSSERIF"; if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS && have_extended_data) { - element["columns"][5]["column"] = "mono_time"; - element["columns"][5]["value"] = llformat("%0.3f", mono_score); - element["columns"][5]["font"] = "SANSSERIF"; + columns[column_num]["column"] = "memory"; + columns[column_num]["value"] = llformat("%0.0f", (script_memory / 1000.f)); + columns[column_num++]["font"] = "SANSSERIF"; - element["columns"][6]["column"] = "URLs"; - element["columns"][6]["value"] = llformat("%d", public_urls); - element["columns"][6]["font"] = "SANSSERIF"; + columns[column_num]["column"] = "URLs"; + columns[column_num]["value"] = llformat("%d", public_urls); + columns[column_num++]["font"] = "SANSSERIF"; } - + element["columns"] = columns; + // Singu Note: We diverge slightly here to retain the legacy coloring of avatar names. when updating be sure that getColumn uses the same number as "name" + LLScrollListItem* item = list->addElement(element); + if (name_buf == owner_buf) item->getColumn(1)->setColor(LLColor4::red); mObjectListData.append(element); mObjectListIDs.push_back(task_id); @@ -259,30 +262,27 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) { setTitle(getString("top_scripts_title")); list->setColumnLabel("score", getString("scripts_score_label")); - list->setColumnLabel("mono_time", getString("scripts_mono_time_label")); LLUIString format = getString("top_scripts_text"); format.setArg("[COUNT]", llformat("%d", total_count)); - format.setArg("[TIME]", llformat("%0.1f", mtotalScore)); - childSetValue("title_text", LLSD(format)); + format.setArg("[TIME]", llformat("%0.3f", mtotalScore)); + getChild("title_text")->setValue(LLSD(format)); } else { setTitle(getString("top_colliders_title")); list->setColumnLabel("score", getString("colliders_score_label")); - list->setColumnLabel("mono_time", ""); + list->setColumnLabel("URLs", ""); + list->setColumnLabel("memory", ""); LLUIString format = getString("top_colliders_text"); format.setArg("[COUNT]", llformat("%d", total_count)); - childSetValue("title_text", LLSD(format)); + getChild("title_text")->setValue(LLSD(format)); } } -// static -void LLFloaterTopObjects::onCommitObjectsList(LLUICtrl* ctrl, void* data) +void LLFloaterTopObjects::onCommitObjectsList() { - LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; - - self->updateSelectionInfo(); + updateSelectionInfo(); } void LLFloaterTopObjects::updateSelectionInfo() @@ -296,9 +296,15 @@ void LLFloaterTopObjects::updateSelectionInfo() std::string object_id_string = object_id.asString(); - childSetValue("id_editor", LLSD(object_id_string)); - childSetValue("object_name_editor", list->getFirstSelected()->getColumn(1)->getValue().asString()); - childSetValue("owner_name_editor", list->getFirstSelected()->getColumn(2)->getValue().asString()); + getChild("id_editor")->setValue(LLSD(object_id_string)); + LLScrollListItem* sli = list->getFirstSelected(); + llassert(sli); + if (sli) + { + getChild("object_name_editor")->setValue(sli->getColumn(1)->getValue().asString()); + getChild("owner_name_editor")->setValue(sli->getColumn(2)->getValue().asString()); + getChild("parcel_name_editor")->setValue(sli->getColumn(4)->getValue().asString()); + } } // static @@ -306,36 +312,12 @@ void LLFloaterTopObjects::onDoubleClickObjectsList(void* data) { LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; self->showBeacon(); - self->lookAtAvatar(); -} - -void LLFloaterTopObjects::lookAtAvatar() -{ - LLScrollListCtrl* list = getChild("objects_list"); - if (!list) return; - LLScrollListItem* first_selected = list->getFirstSelected(); - if (!first_selected) return; - LLUUID taskid = first_selected->getUUID(); - - LLVOAvatar* voavatar = gObjectList.findAvatar(taskid); - if(voavatar) - { - gAgentCamera.setFocusOnAvatar(FALSE, FALSE); - gAgentCamera.changeCameraToThirdPerson(); - gAgentCamera.setFocusGlobal(voavatar->getPositionGlobal(),taskid); - gAgentCamera.setCameraPosAndFocusGlobal(voavatar->getPositionGlobal() - + LLVector3d(3.5,1.35,0.75) * voavatar->getRotation(), - voavatar->getPositionGlobal(), - taskid ); - } } // static -void LLFloaterTopObjects::onClickShowBeacon(void* data) +void LLFloaterTopObjects::onClickShowBeacon() { - LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; - if (!self) return; - self->showBeacon(); + showBeacon(); } void LLFloaterTopObjects::doToObjects(int action, bool all) @@ -345,10 +327,10 @@ void LLFloaterTopObjects::doToObjects(int action, bool all) LLViewerRegion* region = gAgent.getRegion(); if (!region) return; - LLCtrlListInterface *list = childGetListInterface("objects_list"); + LLCtrlListInterface *list = getChild("objects_list")->getListInterface(); if (!list || list->getItemCount() == 0) return; - std::vector::iterator id_itor; + uuid_vec_t::iterator id_itor; bool start_message = true; @@ -399,194 +381,76 @@ void LLFloaterTopObjects::doToObjects(int action, bool all) bool LLFloaterTopObjects::callbackReturnAll(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + LLFloaterTopObjects* instance = instanceExists() ? getInstance() : NULL; + if(!instance) return false; if (option == 0) { - sInstance->doToObjects(ACTION_RETURN, true); + instance->doToObjects(ACTION_RETURN, true); } return false; } -void LLFloaterTopObjects::onReturnAll(void* data) +void LLFloaterTopObjects::onReturnAll() { LLNotificationsUtil::add("ReturnAllTopObjects", LLSD(), LLSD(), &callbackReturnAll); } -void LLFloaterTopObjects::onReturnSelected(void* data) +void LLFloaterTopObjects::onReturnSelected() { - sInstance->doToObjects(ACTION_RETURN, false); + doToObjects(ACTION_RETURN, false); } -void LLFloaterTopObjects::onLagWarningBtn(void* data) -{ - LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; - - self->onLagWarning(data); -} - -void LLFloaterTopObjects::onLagWarning(void* data) -{ - LLScrollListCtrl* list = getChild("objects_list"); - if (!list) return; - LLScrollListItem* first_selected = list->getFirstSelected(); - if (!first_selected) return; - LLUUID taskid = first_selected->getUUID(); - - std::string name = first_selected->getColumn(1)->getValue().asString(); - std::string score = first_selected->getColumn(0)->getValue().asString(); - - std::istringstream stm; - stm.str(score); - F32 f_score; - stm >> f_score; - F32 percentage = 100.f * (f_score / 22); - - std::string message = llformat( - "Hello %s, you are receiving this automated message because you are wearing heavily scripted attachments/HUDs, " - "causing excessive script lag (%5.2f ms, that's ca. %5.2f%% of the region's resources.)\n\n" - "Please remove resizer scripts or attachments to reduce your script time, thank you.", - name.c_str(), - (F32)f_score, - (F32)percentage - ); - - std::string my_name; - gAgent.buildFullname(my_name); - - cmdline_printchat(llformat("Script time warning sent to %s: (%5.2f ms)", - name.c_str(),(F32)f_score)); - - send_improved_im(LLUUID(taskid), - my_name, - message, - IM_ONLINE, - IM_NOTHING_SPECIAL, - LLUUID::null, - NO_TIMESTAMP, - (U8*)EMPTY_BINARY_BUCKET, - EMPTY_BINARY_BUCKET_SIZE); -} - -void LLFloaterTopObjects::onProfileBtn(void* data) -{ - LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; - self->onProfile(data); -} - -void LLFloaterTopObjects::onProfile(void* data) -{ - LLScrollListCtrl* list = getChild("objects_list"); - if (!list) return; - LLScrollListItem* first_selected = list->getFirstSelected(); - if (!first_selected) return; - LLAvatarActions::showProfile(first_selected->getUUID()); -} - -void LLFloaterTopObjects::onKickBtn(void* data) -{ - LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; - self->onKick(data); -} - -void LLFloaterTopObjects::onKick(void* data) -{ - LLScrollListCtrl* list = getChild("objects_list"); - if (!list) return; - LLScrollListItem* first_selected = list->getFirstSelected(); - if (!first_selected) return; - LLUUID taskid = first_selected->getUUID(); - - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("EstateOwnerMessage"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used - msg->nextBlock("MethodData"); - msg->addString("Method", "kickestate"); - msg->addUUID("Invoice", LLUUID::null); - msg->nextBlock("ParamList"); - msg->addString("Parameter", taskid.asString().c_str()); - msg->sendReliable(gAgent.getRegionHost()); -} -void LLFloaterTopObjects::onTPBtn(void* data) -{ - LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; - self->onTP(data); -} - -void LLFloaterTopObjects::onTP(void* data) -{ - LLScrollListCtrl* list = getChild("objects_list"); - if (!list) return; - LLScrollListItem* first_selected = list->getFirstSelected(); - if (!first_selected) return; - - std::string name = first_selected->getColumn(1)->getValue().asString(); - std::string pos_string = first_selected->getColumn(3)->getValue().asString(); - - F32 x, y, z; - S32 matched = sscanf(pos_string.c_str(), "<%g,%g,%g>", &x, &y, &z); - if (matched != 3) return; - - LLVector3 pos_agent(x, y, z); - LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent); - - gAgent.teleportViaLocation( pos_global ); -} - - //static bool LLFloaterTopObjects::callbackDisableAll(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + LLFloaterTopObjects* instance = instanceExists() ? getInstance() : NULL; + if(!instance) return false; if (option == 0) { - sInstance->doToObjects(ACTION_DISABLE, true); + instance->doToObjects(ACTION_DISABLE, true); } return false; } -void LLFloaterTopObjects::onDisableAll(void* data) +void LLFloaterTopObjects::onDisableAll() { LLNotificationsUtil::add("DisableAllTopObjects", LLSD(), LLSD(), callbackDisableAll); } -void LLFloaterTopObjects::onDisableSelected(void* data) +void LLFloaterTopObjects::onDisableSelected() { - sInstance->doToObjects(ACTION_DISABLE, false); + doToObjects(ACTION_DISABLE, false); } -//static + void LLFloaterTopObjects::clearList() { - LLCtrlListInterface *list = sInstance->childGetListInterface("objects_list"); + LLCtrlListInterface *list = childGetListInterface("objects_list"); if (list) { list->operateOnAll(LLCtrlListInterface::OP_DELETE); } - sInstance->mObjectListData.clear(); - sInstance->mObjectListIDs.clear(); - sInstance->mtotalScore = 0.f; + mObjectListData.clear(); + mObjectListIDs.clear(); + mtotalScore = 0.f; } -//static -void LLFloaterTopObjects::onRefresh(void* data) + +void LLFloaterTopObjects::onRefresh() { U32 mode = STAT_REPORT_TOP_SCRIPTS; U32 flags = 0; std::string filter = ""; - if (sInstance) - { - mode = sInstance->mCurrentMode; - flags = sInstance->mFlags; - filter = sInstance->mFilter; - sInstance->clearList(); - } + mode = mCurrentMode; + flags = mFlags; + filter = mFilter; + clearList(); LLMessageSystem *msg = gMessageSystem; msg->newMessageFast(_PREHASH_LandStatRequest); @@ -601,35 +465,35 @@ void LLFloaterTopObjects::onRefresh(void* data) msg->sendReliable(gAgent.getRegionHost()); - if (sInstance) - { - sInstance->mFilter.clear(); - sInstance->mFlags = 0; - } + mFilter.clear(); + mFlags = 0; } -void LLFloaterTopObjects::onGetByObjectName(LLUICtrl* ctrl, void* data) +void LLFloaterTopObjects::onGetByObjectName() { - if (sInstance) - { - sInstance->mFlags = STAT_FILTER_BY_OBJECT; - sInstance->mFilter = sInstance->childGetText("object_name_editor"); - onRefresh(NULL); - } + mFlags = STAT_FILTER_BY_OBJECT; + mFilter = getChild("object_name_editor")->getValue().asString(); + onRefresh(); } -void LLFloaterTopObjects::onGetByOwnerName(LLUICtrl* ctrl, void* data) +void LLFloaterTopObjects::onGetByOwnerName() { - if (sInstance) - { - sInstance->mFlags = STAT_FILTER_BY_OWNER; - sInstance->mFilter = sInstance->childGetText("owner_name_editor"); - onRefresh(NULL); - } + mFlags = STAT_FILTER_BY_OWNER; + mFilter = getChild("owner_name_editor")->getValue().asString(); + onRefresh(); } + +void LLFloaterTopObjects::onGetByParcelName() +{ + mFlags = STAT_FILTER_BY_PARCEL_NAME; + mFilter = getChild("parcel_name_editor")->getValue().asString(); + onRefresh(); +} + + void LLFloaterTopObjects::showBeacon() -{ +{ LLScrollListCtrl* list = getChild("objects_list"); if (!list) return; @@ -647,4 +511,68 @@ void LLFloaterTopObjects::showBeacon() LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent); std::string tooltip(""); LLTracker::trackLocation(pos_global, name, tooltip, LLTracker::LOCATION_ITEM); + + const LLUUID& taskid = first_selected->getUUID(); + if(LLVOAvatar* voavatar = gObjectList.findAvatar(taskid)) + { + gAgentCamera.setFocusOnAvatar(FALSE, FALSE); + gAgentCamera.changeCameraToThirdPerson(); + gAgentCamera.setFocusGlobal(voavatar->getPositionGlobal(),taskid); + gAgentCamera.setCameraPosAndFocusGlobal(voavatar->getPositionGlobal() + LLVector3d(3.5,1.35,0.75) * voavatar->getRotation(), voavatar->getPositionGlobal(), taskid); + } +} + +void LLFloaterTopObjects::onTeleportToObject() +{ + LLScrollListCtrl* list = getChild("objects_list"); + if (!list) return; + + LLScrollListItem* first_selected = list->getFirstSelected(); + if (!first_selected) return; + + std::string pos_string = first_selected->getColumn(3)->getValue().asString(); + + F32 x, y, z; + S32 matched = sscanf(pos_string.c_str(), "<%g,%g,%g>", &x, &y, &z); + if (matched != 3) return; + + LLVector3 pos_agent(x, y, z); + LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent); + + gAgent.teleportViaLocation( pos_global ); +} + +void LLFloaterTopObjects::onKick() +{ + LLScrollListCtrl* list = getChild("objects_list"); + if (!list) return; + + LLScrollListItem* first_selected = list->getFirstSelected(); + if (!first_selected) return; + + const LLUUID& objectId = first_selected->getUUID(); + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + msg->nextBlock("MethodData"); + msg->addString("Method", "kickestate"); + msg->addUUID("Invoice", LLUUID::null); + msg->nextBlock("ParamList"); + msg->addString("Parameter", objectId.asString().c_str()); + msg->sendReliable(gAgent.getRegionHost()); +} + +void LLFloaterTopObjects::onProfile() +{ + LLScrollListCtrl* list = getChild("objects_list"); + if (!list) return; + + LLScrollListItem* first_selected = list->getFirstSelected(); + if (!first_selected) return; + + const LLUUID& objectId = first_selected->getUUID(); + LLAvatarActions::showProfile(objectId); } diff --git a/indra/newview/llfloatertopobjects.h b/indra/newview/llfloatertopobjects.h index 74a7ed611..a69de5fc9 100644 --- a/indra/newview/llfloatertopobjects.h +++ b/indra/newview/llfloatertopobjects.h @@ -37,29 +37,25 @@ class LLUICtrl; -class LLFloaterTopObjects : public LLFloater +class LLFloaterTopObjects : public LLFloater, public LLSingleton { + friend class LLSingleton; public: // Opens the floater on screen. - static void show(); +// static void show(); // Opens the floater if it's not on-screen. // Juggles the UI based on method = "scripts" or "colliders" static void handle_land_reply(LLMessageSystem* msg, void** data); void handleReply(LLMessageSystem* msg, void** data); - static void clearList(); + void clearList(); void updateSelectionInfo(); virtual BOOL postBuild(); - static void onRefresh(void* data); + void onRefresh(); - static void setMode(U32 mode) { if (sInstance) sInstance->mCurrentMode = mode; } - - void onProfile(void* data); - void onKick(void* data); - void onTP(void* data); - void onLagWarning(void* data); + static void setMode(U32 mode); private: LLFloaterTopObjects(); @@ -67,31 +63,27 @@ private: void initColumns(LLCtrlListInterface *list); - static void onCommitObjectsList(LLUICtrl* ctrl, void* data); + void onCommitObjectsList(); static void onDoubleClickObjectsList(void* data); - void lookAtAvatar(); - static void onClickShowBeacon(void* data); + void onClickShowBeacon(); void doToObjects(int action, bool all); - static void onReturnAll(void* data); - static void onReturnSelected(void* data); - static void onDisableAll(void* data); - static void onDisableSelected(void* data); + void onReturnAll(); + void onReturnSelected(); + void onDisableAll(); + void onDisableSelected(); + + void onTeleportToObject(); + void onKick(); + void onProfile(); - static void onProfileBtn(void* data); - static void onKickBtn(void* data); - static void onTPBtn(void* data); - static void onLagWarningBtn(void* data); - static bool callbackReturnAll(const LLSD& notification, const LLSD& response); static bool callbackDisableAll(const LLSD& notification, const LLSD& response); - static void onGetByOwnerName(LLUICtrl* ctrl, void* data); - static void onGetByObjectName(LLUICtrl* ctrl, void* data); - - static void onGetByOwnerNameClicked(void* data) { onGetByOwnerName(NULL, data); }; - static void onGetByObjectNameClicked(void* data) { onGetByObjectName(NULL, data); }; + void onGetByOwnerName(); + void onGetByObjectName(); + void onGetByParcelName(); void showBeacon(); @@ -99,7 +91,7 @@ private: std::string mMethod; LLSD mObjectListData; - std::vector mObjectListIDs; + uuid_vec_t mObjectListIDs; U32 mCurrentMode; U32 mFlags; diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp index 415798086..fc74c9e87 100644 --- a/indra/newview/llfloatervoiceeffect.cpp +++ b/indra/newview/llfloatervoiceeffect.cpp @@ -30,6 +30,7 @@ #include "llfloatervoiceeffect.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "lltexteditor.h" // For linked text hack #include "lltrans.h" #include "lluictrlfactory.h" diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp new file mode 100644 index 000000000..0648b902a --- /dev/null +++ b/indra/newview/llmaterialmgr.cpp @@ -0,0 +1,793 @@ +/** + * @file llmaterialmgr.cpp + * @brief Material manager + * + * $LicenseInfo:firstyear=2013&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llsdserialize.h" +#include "llsdutil.h" + +#include "llagent.h" +#include "llcallbacklist.h" +#include "llmaterialmgr.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llworld.h" + +/** + * Materials cap parameters + */ + +#define MATERIALS_CAPABILITY_NAME "RenderMaterials" + +#define MATERIALS_CAP_ZIP_FIELD "Zipped" + +#define MATERIALS_CAP_FULL_PER_FACE_FIELD "FullMaterialsPerFace" +#define MATERIALS_CAP_FACE_FIELD "Face" +#define MATERIALS_CAP_MATERIAL_FIELD "Material" +#define MATERIALS_CAP_OBJECT_ID_FIELD "ID" +#define MATERIALS_CAP_MATERIAL_ID_FIELD "MaterialID" + +#define MATERIALS_GET_MAX_ENTRIES 50 +#define MATERIALS_GET_TIMEOUT (60.f * 20) +#define MATERIALS_POST_MAX_ENTRIES 50 +#define MATERIALS_POST_TIMEOUT (60.f * 5) +#define MATERIALS_PUT_THROTTLE_SECS 1.f +#define MATERIALS_PUT_MAX_ENTRIES 50 + +/** + * LLMaterialsResponder helper class + */ + +extern AIHTTPTimeoutPolicy materialsResponder_timeout; + +class LLMaterialsResponder : public LLHTTPClient::ResponderWithResult +{ +public: + typedef boost::function CallbackFunction; + + LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback); + virtual ~LLMaterialsResponder(); + + virtual void result(const LLSD& pContent); + virtual void error(U32 pStatus, const std::string& pReason); + + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return materialsResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "LLMaterialsResponder"; } +private: + std::string mMethod; + std::string mCapabilityURL; + CallbackFunction mCallback; +}; + +LLMaterialsResponder::LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback) + : LLHTTPClient::ResponderWithResult() + , mMethod(pMethod) + , mCapabilityURL(pCapabilityURL) + , mCallback(pCallback) +{ +} + +LLMaterialsResponder::~LLMaterialsResponder() +{ +} + +void LLMaterialsResponder::result(const LLSD& pContent) +{ + LL_DEBUGS("Materials") << LL_ENDL; + mCallback(true, pContent); +} + +void LLMaterialsResponder::error(U32 pStatus, const std::string& pReason) +{ + LL_WARNS("Materials") + << "\n--------------------------------------------------------------------------\n" + << mMethod << " Error[" << pStatus << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME + << "'\n with url '" << mCapabilityURL << "' because " << pReason + << "\n--------------------------------------------------------------------------" + << LL_ENDL; + + LLSD emptyResult; + mCallback(false, emptyResult); +} + +/** + * LLMaterialMgr class + */ + +LLMaterialMgr::LLMaterialMgr() +{ + mMaterials.insert(std::pair(LLMaterialID::null, LLMaterialPtr(NULL))); + gIdleCallbacks.addFunction(&LLMaterialMgr::onIdle, NULL); + LLWorld::instance().setRegionRemovedCallback(boost::bind(&LLMaterialMgr::onRegionRemoved, this, _1)); +} + +LLMaterialMgr::~LLMaterialMgr() +{ + gIdleCallbacks.deleteFunction(&LLMaterialMgr::onIdle, NULL); +} + +bool LLMaterialMgr::isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const +{ + get_pending_map_t::const_iterator itPending = mGetPending.find(pending_material_t(region_id, material_id)); + return (mGetPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_POST_TIMEOUT); +} + +void LLMaterialMgr::markGetPending(const LLUUID& region_id, const LLMaterialID& material_id) +{ + get_pending_map_t::iterator itPending = mGetPending.find(pending_material_t(region_id, material_id)); + if (mGetPending.end() == itPending) + { + mGetPending.insert(std::pair(pending_material_t(region_id, material_id), LLFrameTimer::getTotalSeconds())); + } + else + { + itPending->second = LLFrameTimer::getTotalSeconds(); + } +} + +const LLMaterialPtr LLMaterialMgr::get(const LLUUID& region_id, const LLMaterialID& material_id) +{ + LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL; + LLMaterialPtr material; + material_map_t::const_iterator itMaterial = mMaterials.find(material_id); + if (mMaterials.end() != itMaterial) + { + material = itMaterial->second; + LL_DEBUGS("Materials") << " found material " << LL_ENDL; + } + else + { + if (!isGetPending(region_id, material_id)) + { + LL_DEBUGS("Materials") << " material pending " << material_id << LL_ENDL; + get_queue_t::iterator itQueue = mGetQueue.find(region_id); + if (mGetQueue.end() == itQueue) + { + LL_DEBUGS("Materials") << "mGetQueue add region " << region_id << " pending " << material_id << LL_ENDL; + std::pair ret = mGetQueue.insert(std::pair(region_id, material_queue_t())); + itQueue = ret.first; + } + itQueue->second.insert(material_id); + markGetPending(region_id, material_id); + } + LL_DEBUGS("Materials") << " returning empty material " << LL_ENDL; + material = LLMaterialPtr(); + } + return material; +} + +boost::signals2::connection LLMaterialMgr::get(const LLUUID& region_id, const LLMaterialID& material_id, LLMaterialMgr::get_callback_t::slot_type cb) +{ + boost::signals2::connection connection; + + material_map_t::const_iterator itMaterial = mMaterials.find(material_id); + if (itMaterial != mMaterials.end()) + { + LL_DEBUGS("Materials") << "region " << region_id << " found materialid " << material_id << LL_ENDL; + get_callback_t signal; + signal.connect(cb); + signal(material_id, itMaterial->second); + connection = boost::signals2::connection(); + } + else + { + if (!isGetPending(region_id, material_id)) + { + get_queue_t::iterator itQueue = mGetQueue.find(region_id); + if (mGetQueue.end() == itQueue) + { + LL_DEBUGS("Materials") << "mGetQueue inserting region "< ret = mGetQueue.insert(std::pair(region_id, material_queue_t())); + itQueue = ret.first; + } + LL_DEBUGS("Materials") << "adding material id " << material_id << LL_ENDL; + itQueue->second.insert(material_id); + markGetPending(region_id, material_id); + } + + get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id); + if (itCallback == mGetCallbacks.end()) + { + std::pair ret = mGetCallbacks.insert(std::pair(material_id, new get_callback_t())); + itCallback = ret.first; + } + connection = itCallback->second->connect(cb);; + } + + return connection; +} + +boost::signals2::connection LLMaterialMgr::getTE(const LLUUID& region_id, const LLMaterialID& material_id, U32 te, LLMaterialMgr::get_callback_te_t::slot_type cb) +{ + boost::signals2::connection connection; + + material_map_t::const_iterator itMaterial = mMaterials.find(material_id); + if (itMaterial != mMaterials.end()) + { + LL_DEBUGS("Materials") << "region " << region_id << " found materialid " << material_id << LL_ENDL; + get_callback_te_t signal; + signal.connect(cb); + signal(material_id, itMaterial->second, te); + connection = boost::signals2::connection(); + } + else + { + if (!isGetPending(region_id, material_id)) + { + get_queue_t::iterator itQueue = mGetQueue.find(region_id); + if (mGetQueue.end() == itQueue) + { + LL_DEBUGS("Materials") << "mGetQueue inserting region "< ret = mGetQueue.insert(std::pair(region_id, material_queue_t())); + itQueue = ret.first; + } + LL_DEBUGS("Materials") << "adding material id " << material_id << LL_ENDL; + itQueue->second.insert(material_id); + markGetPending(region_id, material_id); + } + + TEMaterialPair te_mat_pair; + te_mat_pair.te = te; + te_mat_pair.materialID = material_id; + + get_callback_te_map_t::iterator itCallback = mGetTECallbacks.find(te_mat_pair); + if (itCallback == mGetTECallbacks.end()) + { + std::pair ret = mGetTECallbacks.insert(std::pair(te_mat_pair, new get_callback_te_t())); + itCallback = ret.first; + } + connection = itCallback->second->connect(cb); + } + + return connection; +} + +bool LLMaterialMgr::isGetAllPending(const LLUUID& region_id) const +{ + getall_pending_map_t::const_iterator itPending = mGetAllPending.find(region_id); + return (mGetAllPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_GET_TIMEOUT); +} + +void LLMaterialMgr::getAll(const LLUUID& region_id) +{ + if (!isGetAllPending(region_id)) + { + LL_DEBUGS("Materials") << "queuing for region " << region_id << LL_ENDL; + mGetAllQueue.insert(region_id); + } + else + { + LL_DEBUGS("Materials") << "already pending for region " << region_id << LL_ENDL; + } +} + +boost::signals2::connection LLMaterialMgr::getAll(const LLUUID& region_id, LLMaterialMgr::getall_callback_t::slot_type cb) +{ + if (!isGetAllPending(region_id)) + { + mGetAllQueue.insert(region_id); + } + + getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id); + if (mGetAllCallbacks.end() == itCallback) + { + std::pair ret = mGetAllCallbacks.insert(std::pair(region_id, new getall_callback_t())); + itCallback = ret.first; + } + return itCallback->second->connect(cb);; +} + +void LLMaterialMgr::put(const LLUUID& object_id, const U8 te, const LLMaterial& material) +{ + put_queue_t::iterator itQueue = mPutQueue.find(object_id); + if (mPutQueue.end() == itQueue) + { + LL_DEBUGS("Materials") << "mPutQueue insert object " << object_id << LL_ENDL; + mPutQueue.insert(std::pair(object_id, facematerial_map_t())); + itQueue = mPutQueue.find(object_id); + } + + facematerial_map_t::iterator itFace = itQueue->second.find(te); + if (itQueue->second.end() == itFace) + { + itQueue->second.insert(std::pair(te, material)); + } + else + { + itFace->second = material; + } +} + +void LLMaterialMgr::remove(const LLUUID& object_id, const U8 te) +{ + put(object_id, te, LLMaterial::null); +} + +const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data) +{ + LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL; + material_map_t::const_iterator itMaterial = mMaterials.find(material_id); + if (mMaterials.end() == itMaterial) + { + LL_DEBUGS("Materials") << "new material" << LL_ENDL; + LLMaterialPtr newMaterial(new LLMaterial(material_data)); + std::pair ret = mMaterials.insert(std::pair(material_id, newMaterial)); + itMaterial = ret.first; + } + + // we may have cleared our queues on leaving a region before we recv'd our + // update for this material...too late now! + // + if (isGetPending(region_id, material_id)) + { + + TEMaterialPair te_mat_pair; + te_mat_pair.materialID = material_id; + + U32 i = 0; + while (i < LLTEContents::MAX_TES) + { + te_mat_pair.te = i++; + get_callback_te_map_t::iterator itCallbackTE = mGetTECallbacks.find(te_mat_pair); + if (itCallbackTE != mGetTECallbacks.end()) + { + (*itCallbackTE->second)(material_id, itMaterial->second, te_mat_pair.te); + delete itCallbackTE->second; + mGetTECallbacks.erase(itCallbackTE); + } + } + + get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id); + if (itCallback != mGetCallbacks.end()) + { + (*itCallback->second)(material_id, itMaterial->second); + + delete itCallback->second; + mGetCallbacks.erase(itCallback); + } + } + + mGetPending.erase(pending_material_t(region_id, material_id)); + + return itMaterial->second; +} + +void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUID& region_id) +{ + if (!success) + { + // *TODO: is there any kind of error handling we can do here? + LL_WARNS("Materials")<< "failed"<(content_binary.data()), content_binary.size()); + std::istringstream content_stream(content_string); + + LLSD response_data; + if (!unzip_llsd(response_data, content_stream, content_binary.size())) + { + LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL; + return; + } + + llassert(response_data.isArray()); + LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL; + for (LLSD::array_const_iterator itMaterial = response_data.beginArray(); itMaterial != response_data.endArray(); ++itMaterial) + { + const LLSD& material_data = *itMaterial; + llassert(material_data.isMap()); + + llassert(material_data.has(MATERIALS_CAP_OBJECT_ID_FIELD)); + llassert(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].isBinary()); + LLMaterialID material_id(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].asBinary()); + + llassert(material_data.has(MATERIALS_CAP_MATERIAL_FIELD)); + llassert(material_data[MATERIALS_CAP_MATERIAL_FIELD].isMap()); + + setMaterial(region_id, material_id, material_data[MATERIALS_CAP_MATERIAL_FIELD]); + } +} + +void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LLUUID& region_id) +{ + if (!success) + { + // *TODO: is there any kind of error handling we can do here? + LL_WARNS("Materials")<< "failed"<(content_binary.data()), content_binary.size()); + std::istringstream content_stream(content_string); + + LLSD response_data; + if (!unzip_llsd(response_data, content_stream, content_binary.size())) + { + LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL; + return; + } + + get_queue_t::iterator itQueue = mGetQueue.find(region_id); + material_map_t materials; + + llassert(response_data.isArray()); + LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL; + for (LLSD::array_const_iterator itMaterial = response_data.beginArray(); itMaterial != response_data.endArray(); ++itMaterial) + { + const LLSD& material_data = *itMaterial; + llassert(material_data.isMap()); + + llassert(material_data.has(MATERIALS_CAP_OBJECT_ID_FIELD)); + llassert(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].isBinary()); + LLMaterialID material_id(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].asBinary()); + if (mGetQueue.end() != itQueue) + { + itQueue->second.erase(material_id); + } + + llassert(material_data.has(MATERIALS_CAP_MATERIAL_FIELD)); + llassert(material_data[MATERIALS_CAP_MATERIAL_FIELD].isMap()); + LLMaterialPtr material = setMaterial(region_id, material_id, material_data[MATERIALS_CAP_MATERIAL_FIELD]); + + materials[material_id] = material; + } + + getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id); + if (itCallback != mGetAllCallbacks.end()) + { + (*itCallback->second)(region_id, materials); + + delete itCallback->second; + mGetAllCallbacks.erase(itCallback); + } + + if ( (mGetQueue.end() != itQueue) && (itQueue->second.empty()) ) + { + mGetQueue.erase(itQueue); + } + + LL_DEBUGS("Materials")<< "recording that getAll has been done for region id " << region_id << LL_ENDL; + mGetAllRequested.insert(region_id); // prevents subsequent getAll requests for this region + mGetAllPending.erase(region_id); // Invalidates region_id +} + +void LLMaterialMgr::onPutResponse(bool success, const LLSD& content) +{ + if (!success) + { + // *TODO: is there any kind of error handling we can do here? + LL_WARNS("Materials")<< "failed"<(content_binary.data()), content_binary.size()); + std::istringstream content_stream(content_string); + + LLSD response_data; + if (!unzip_llsd(response_data, content_stream, content_binary.size())) + { + LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL; + return; + } + else + { + llassert(response_data.isArray()); + LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL; + for (LLSD::array_const_iterator faceIter = response_data.beginArray(); faceIter != response_data.endArray(); ++faceIter) + { +# ifndef LL_RELEASE_FOR_DOWNLOAD + const LLSD& face_data = *faceIter; // conditional to avoid unused variable warning +# endif + llassert(face_data.isMap()); + + llassert(face_data.has(MATERIALS_CAP_OBJECT_ID_FIELD)); + llassert(face_data[MATERIALS_CAP_OBJECT_ID_FIELD].isInteger()); + // U32 local_id = face_data[MATERIALS_CAP_OBJECT_ID_FIELD].asInteger(); + + llassert(face_data.has(MATERIALS_CAP_FACE_FIELD)); + llassert(face_data[MATERIALS_CAP_FACE_FIELD].isInteger()); + // S32 te = face_data[MATERIALS_CAP_FACE_FIELD].asInteger(); + + llassert(face_data.has(MATERIALS_CAP_MATERIAL_ID_FIELD)); + llassert(face_data[MATERIALS_CAP_MATERIAL_ID_FIELD].isBinary()); + // LLMaterialID material_id(face_data[MATERIALS_CAP_MATERIAL_ID_FIELD].asBinary()); + + // *TODO: do we really still need to process this? + } + } +} + +static LLFastTimer::DeclareTimer FTM_MATERIALS_IDLE("Materials"); + +void LLMaterialMgr::onIdle(void*) +{ + LLFastTimer t(FTM_MATERIALS_IDLE); + + LLMaterialMgr* instancep = LLMaterialMgr::getInstance(); + + if (!instancep->mGetQueue.empty()) + { + instancep->processGetQueue(); + } + + if (!instancep->mGetAllQueue.empty()) + { + instancep->processGetAllQueue(); + } + + static LLFrameTimer mPutTimer; + if ( (!instancep->mPutQueue.empty()) && (mPutTimer.hasExpired()) ) + { + instancep->processPutQueue(); + mPutTimer.reset(MATERIALS_PUT_THROTTLE_SECS); + } +} + +void LLMaterialMgr::processGetQueue() +{ + get_queue_t::iterator loopRegionQueue = mGetQueue.begin(); + while (mGetQueue.end() != loopRegionQueue) + { + get_queue_t::iterator itRegionQueue = loopRegionQueue++; + + const LLUUID& region_id = itRegionQueue->first; + if (isGetAllPending(region_id)) + { + continue; + } + + const LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id); + if (!regionp) + { + LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL; + mGetQueue.erase(itRegionQueue); + continue; + } + else if (!regionp->capabilitiesReceived()) + { + continue; + } + else if (mGetAllRequested.end() == mGetAllRequested.find(region_id)) + { + LL_DEBUGS("Materials") << "calling getAll for " << regionp->getName() << LL_ENDL; + getAll(region_id); + continue; + } + + const std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME); + if (capURL.empty()) + { + LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME + << "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL; + mGetQueue.erase(itRegionQueue); + continue; + } + + LLSD materialsData = LLSD::emptyArray(); + + material_queue_t& materials = itRegionQueue->second; + material_queue_t::iterator loopMaterial = materials.begin(); + while ( (materials.end() != loopMaterial) && (materialsData.size() <= MATERIALS_GET_MAX_ENTRIES) ) + { + material_queue_t::iterator itMaterial = loopMaterial++; + materialsData.append((*itMaterial).asLLSD()); + materials.erase(itMaterial); + markGetPending(region_id, *itMaterial); + } + if (materials.empty()) + { + mGetQueue.erase(itRegionQueue); + } + + std::string materialString = zip_llsd(materialsData); + + S32 materialSize = materialString.size(); + if (materialSize <= 0) + { + LL_ERRS("Materials") << "cannot zip LLSD binary content" << LL_ENDL; + return; + } + + LLSD::Binary materialBinary; + materialBinary.resize(materialSize); + memcpy(materialBinary.data(), materialString.data(), materialSize); + + LLSD postData = LLSD::emptyMap(); + postData[MATERIALS_CAP_ZIP_FIELD] = materialBinary; + + LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("POST", capURL, boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id)); + LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials." + << "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL; + LLHTTPClient::post(capURL, postData, materialsResponder); + } +} + +void LLMaterialMgr::processGetAllQueue() +{ + getall_queue_t::iterator loopRegion = mGetAllQueue.begin(); + while (mGetAllQueue.end() != loopRegion) + { + getall_queue_t::iterator itRegion = loopRegion++; + + const LLUUID& region_id = *itRegion; + LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id); + if (regionp == NULL) + { + LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL; + clearGetQueues(region_id); // Invalidates region_id + continue; + } + else if (!regionp->capabilitiesReceived()) + { + continue; + } + + std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME); + if (capURL.empty()) + { + LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME + << "' is not defined on the current region '" << regionp->getName() << "'" << LL_ENDL; + clearGetQueues(region_id); // Invalidates region_id + continue; + } + + LL_DEBUGS("Materials") << "GET all for region " << region_id << "url " << capURL << LL_ENDL; + LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("GET", capURL, boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion)); + LLHTTPClient::get(capURL, materialsResponder); + mGetAllPending.insert(std::pair(region_id, LLFrameTimer::getTotalSeconds())); + mGetAllQueue.erase(itRegion); // Invalidates region_id + } +} + +void LLMaterialMgr::processPutQueue() +{ + typedef std::map regionput_request_map; + regionput_request_map requests; + + put_queue_t::iterator loopQueue = mPutQueue.begin(); + while (mPutQueue.end() != loopQueue) + { + put_queue_t::iterator itQueue = loopQueue++; + + const LLUUID& object_id = itQueue->first; + const LLViewerObject* objectp = gObjectList.findObject(object_id); + if ( (!objectp) || (!objectp->getRegion()) ) + { + LL_WARNS("Materials") << "Object or object region is NULL" << LL_ENDL; + + mPutQueue.erase(itQueue); + continue; + } + + const LLViewerRegion* regionp = objectp->getRegion(); + if (!regionp->capabilitiesReceived()) + { + continue; + } + + LLSD& facesData = requests[regionp]; + + facematerial_map_t& face_map = itQueue->second; + facematerial_map_t::iterator itFace = face_map.begin(); + while ( (face_map.end() != itFace) && (facesData.size() < MATERIALS_GET_MAX_ENTRIES) ) + { + LLSD faceData = LLSD::emptyMap(); + faceData[MATERIALS_CAP_FACE_FIELD] = static_cast(itFace->first); + faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast(objectp->getLocalID()); + if (!itFace->second.isNull()) + { + faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD(); + } + facesData.append(faceData); + face_map.erase(itFace++); + } + if (face_map.empty()) + { + mPutQueue.erase(itQueue); + } + } + + for (regionput_request_map::const_iterator itRequest = requests.begin(); itRequest != requests.end(); ++itRequest) + { + std::string capURL = itRequest->first->getCapability(MATERIALS_CAPABILITY_NAME); + if (capURL.empty()) + { + LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME + << "' is not defined on region '" << itRequest->first->getName() << "'" << LL_ENDL; + continue; + } + + LLSD materialsData = LLSD::emptyMap(); + materialsData[MATERIALS_CAP_FULL_PER_FACE_FIELD] = itRequest->second; + + std::string materialString = zip_llsd(materialsData); + + S32 materialSize = materialString.size(); + + if (materialSize > 0) + { + LLSD::Binary materialBinary; + materialBinary.resize(materialSize); + memcpy(materialBinary.data(), materialString.data(), materialSize); + + LLSD putData = LLSD::emptyMap(); + putData[MATERIALS_CAP_ZIP_FIELD] = materialBinary; + + LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL; + LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2)); + LLHTTPClient::put(capURL, putData, materialsResponder); + } + else + { + LL_ERRS("debugMaterials") << "cannot zip LLSD binary content" << LL_ENDL; + } + } +} + +void LLMaterialMgr::clearGetQueues(const LLUUID& region_id) +{ + mGetQueue.erase(region_id); + for (get_pending_map_t::iterator itPending = mGetPending.begin(); itPending != mGetPending.end();) + { + if (region_id == itPending->first.first) + { + mGetPending.erase(itPending++); + } + else + { + ++itPending; + } + } + + mGetAllQueue.erase(region_id); + mGetAllRequested.erase(region_id); + mGetAllPending.erase(region_id); + mGetAllCallbacks.erase(region_id); +} + +void LLMaterialMgr::onRegionRemoved(LLViewerRegion* regionp) +{ + clearGetQueues(regionp->getRegionID()); + // Put doesn't need clearing: objects that can't be found will clean up in processPutQueue() +} + diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h new file mode 100644 index 000000000..e317a791a --- /dev/null +++ b/indra/newview/llmaterialmgr.h @@ -0,0 +1,130 @@ +/** + * @file llmaterialmgr.h + * @brief Material manager + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLMATERIALMGR_H +#define LL_LLMATERIALMGR_H + +#include "llmaterial.h" +#include "llmaterialid.h" +#include "llsingleton.h" + +class LLViewerRegion; + +class LLMaterialMgr : public LLSingleton +{ + friend class LLSingleton; +protected: + LLMaterialMgr(); + virtual ~LLMaterialMgr(); + +public: + typedef std::map material_map_t; + + typedef boost::signals2::signal get_callback_t; + const LLMaterialPtr get(const LLUUID& region_id, const LLMaterialID& material_id); + boost::signals2::connection get(const LLUUID& region_id, const LLMaterialID& material_id, get_callback_t::slot_type cb); + + typedef boost::signals2::signal get_callback_te_t; + boost::signals2::connection getTE(const LLUUID& region_id, const LLMaterialID& material_id, U32 te, get_callback_te_t::slot_type cb); + + typedef boost::signals2::signal getall_callback_t; + void getAll(const LLUUID& region_id); + boost::signals2::connection getAll(const LLUUID& region_id, getall_callback_t::slot_type cb); + void put(const LLUUID& object_id, const U8 te, const LLMaterial& material); + void remove(const LLUUID& object_id, const U8 te); + +protected: + void clearGetQueues(const LLUUID& region_id); + bool isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const; + bool isGetAllPending(const LLUUID& region_id) const; + void markGetPending(const LLUUID& region_id, const LLMaterialID& material_id); + const LLMaterialPtr setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data); + + static void onIdle(void*); + void processGetQueue(); + void onGetResponse(bool success, const LLSD& content, const LLUUID& region_id); + void processGetAllQueue(); + void onGetAllResponse(bool success, const LLSD& content, const LLUUID& region_id); + void processPutQueue(); + void onPutResponse(bool success, const LLSD& content); + void onRegionRemoved(LLViewerRegion* regionp); + +protected: + typedef std::set material_queue_t; + typedef std::map get_queue_t; + get_queue_t mGetQueue; + typedef std::pair pending_material_t; + typedef std::map get_pending_map_t; + get_pending_map_t mGetPending; + typedef std::map get_callback_map_t; + get_callback_map_t mGetCallbacks; + + // struct for TE-specific material ID query + class TEMaterialPair + { + public: + + U32 te; + LLMaterialID materialID; + + bool operator==(const TEMaterialPair& b) const { return (materialID == b.materialID) && (te == b.te); } + }; + + friend inline bool operator<( + const LLMaterialMgr::TEMaterialPair& lhs, + const LLMaterialMgr::TEMaterialPair& rhs) + { + return (lhs.te < rhs.te) ? TRUE : + (lhs.materialID < rhs.materialID); + } + + struct TEMaterialPairHasher + { + enum { bucket_size = 8 }; + size_t operator()(const TEMaterialPair& key_value) const { return *((size_t*)key_value.materialID.get()); } // cheesy, but effective + bool operator()(const TEMaterialPair& left, const TEMaterialPair& right) const { return left < right; } + }; + + typedef boost::unordered_map get_callback_te_map_t; + get_callback_te_map_t mGetTECallbacks; + + typedef std::set getall_queue_t; + getall_queue_t mGetAllQueue; + getall_queue_t mGetAllRequested; + typedef std::map getall_pending_map_t; + getall_pending_map_t mGetAllPending; + typedef std::map getall_callback_map_t; + getall_callback_map_t mGetAllCallbacks; + + typedef std::map facematerial_map_t; + typedef std::map put_queue_t; + put_queue_t mPutQueue; + + material_map_t mMaterials; +}; + +#endif // LL_LLMATERIALMGR_H + diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 49f26ad4e..653b951d3 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -2,31 +2,25 @@ * @file llnamelistctrl.cpp * @brief A list of names, automatically refreshed from name cache. * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * 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 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * 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 + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * 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. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,59 +31,46 @@ #include #include "llavatarnamecache.h" - #include "llcachename.h" #include "llagent.h" #include "llinventory.h" +#include "llscrolllistitem.h" +#include "llscrolllistcolumn.h" +#include "llsdparam.h" #include "lltrans.h" static LLRegisterWidget r("name_list"); -// statics -std::set LLNameListCtrl::sInstances; -LLNameListCtrl::LLNameListCtrl(const std::string& name, - const LLRect& rect, - BOOL allow_multiple_selection, - BOOL draw_border, - bool draw_heading, - S32 name_column_index, - const std::string& tooltip) -: LLScrollListCtrl(name, rect, NULL, allow_multiple_selection, - draw_border,draw_heading), +void LLNameListCtrl::NameTypeNames::declareValues() +{ + declare("INDIVIDUAL", LLNameListCtrl::INDIVIDUAL); + declare("GROUP", LLNameListCtrl::GROUP); + declare("SPECIAL", LLNameListCtrl::SPECIAL); +} + +LLNameListCtrl::LLNameListCtrl(const std::string& name, const LLRect& rect, BOOL allow_multiple_selection, BOOL draw_border, bool draw_heading, S32 name_column_index, const std::string& tooltip) +: LLScrollListCtrl(name, rect, NULL, allow_multiple_selection, draw_border,draw_heading), mNameColumnIndex(name_column_index), - mAllowCallingCardDrop(FALSE), - mShortNames(FALSE) + mAllowCallingCardDrop(false), + mShortNames(false), + mAvatarNameCacheConnection() { setToolTip(tooltip); - LLNameListCtrl::sInstances.insert(this); } - -// virtual -LLNameListCtrl::~LLNameListCtrl() -{ - LLNameListCtrl::sInstances.erase(this); -} - - // public LLScrollListItem* LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos, BOOL enabled, const std::string& suffix) { //llinfos << "LLNameListCtrl::addNameItem " << agent_id << llendl; - LLSD item; - item["id"] = agent_id; - item["enabled"] = enabled; - item["target"] = INDIVIDUAL; - item["suffix"] = suffix; - LLSD& column = item["columns"][0]; - column["value"] = ""; - column["font"] = "SANSSERIF"; - column["column"] = "name"; + NameItem item; + item.value = agent_id; + item.enabled = enabled; + item.target = INDIVIDUAL; - return addNameItemRow(item, pos); + return addNameItemRow(item, pos, suffix); } // virtual, public @@ -145,46 +126,52 @@ BOOL LLNameListCtrl::handleDragAndDrop( void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos, BOOL enabled) { - LLSD item; - item["id"] = group_id; - item["enabled"] = enabled; - item["target"] = GROUP; - LLSD& column = item["columns"][0]; - column["value"] = ""; - column["font"] = "SANSSERIF"; - column["column"] = "name"; + NameItem item; + item.value = group_id; + item.enabled = enabled; + item.target = GROUP; addNameItemRow(item, pos); } // public -void LLNameListCtrl::addGroupNameItem(LLSD& item, EAddPosition pos) +void LLNameListCtrl::addGroupNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos) { - item["target"] = GROUP; + item.target = GROUP; addNameItemRow(item, pos); } -LLScrollListItem* LLNameListCtrl::addNameItem(LLSD& item, EAddPosition pos) +LLScrollListItem* LLNameListCtrl::addNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos) { - item["target"] = INDIVIDUAL; + item.target = INDIVIDUAL; return addNameItemRow(item, pos); } -LLScrollListItem* LLNameListCtrl::addElement(const LLSD& value, EAddPosition pos, void* userdata) +LLScrollListItem* LLNameListCtrl::addElement(const LLSD& element, EAddPosition pos, void* userdata) { - return addNameItemRow(value, pos, userdata); + LLNameListCtrl::NameItem item_params; + LLParamSDParser parser; + parser.readSD(element, item_params); + item_params.userdata = userdata; + return addNameItemRow(item_params, pos); } -LLScrollListItem* LLNameListCtrl::addNameItemRow(const LLSD& value, EAddPosition pos, void* userdata) -{ - LLScrollListItem* item = LLScrollListCtrl::addElement(value, pos, userdata); + +LLScrollListItem* LLNameListCtrl::addNameItemRow( + const LLNameListCtrl::NameItem& name_item, + EAddPosition pos, + const std::string& suffix) +{ + LLUUID id = name_item.value().asUUID(); + LLNameListItem* item = new LLNameListItem(name_item,name_item.target() == GROUP); + if (!item) return NULL; - LLUUID id = item->getUUID(); + LLScrollListCtrl::addRow(item, name_item, pos); // use supplied name by default - std::string fullname = value["name"].asString(); - switch(value["target"].asInteger()) + std::string fullname = name_item.name; + switch(name_item.target) { case GROUP: gCacheName->getGroupName(id, fullname); @@ -209,11 +196,14 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(const LLSD& value, EAddPosition } else { - fullname = " ( " + LLTrans::getString("LoadingData") + " ) "; // ...schedule a callback - LLAvatarNameCache::get(id, - boost::bind(&LLNameListCtrl::onAvatarNameCache, - this, _1, _2, item->getHandle())); + // This is not correct and will likely lead to partially populated lists in cases where avatar names are not cached. + // *TODO : Change this to have 2 callbacks : one callback per list item and one for the whole list. + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + mAvatarNameCacheConnection = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, item->getHandle())); } break; } @@ -222,14 +212,13 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(const LLSD& value, EAddPosition } // Append optional suffix. - std::string suffix = value["suffix"]; if(!suffix.empty()) { fullname.append(suffix); } LLScrollListCell* cell = item->getColumn(mNameColumnIndex); - if (cell && !fullname.empty() && cell->getValue().asString().empty()) + if (cell) { cell->setValue(fullname); } @@ -271,15 +260,17 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id) void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, - LLHandle item) + LLHandle item) { + mAvatarNameCacheConnection.disconnect(); + std::string name; if (mShortNames) name = av_name.mDisplayName; else name = av_name.getCompleteName(); - LLScrollListItem* list_item = item.get(); + LLNameListItem* list_item = item.get(); if (list_item && list_item->getUUID() == agent_id) { LLScrollListCell* cell = list_item->getColumn(mNameColumnIndex); @@ -334,13 +325,7 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto S32 name_column_index = 0; node->getAttributeS32("name_column_index", name_column_index); - LLNameListCtrl* name_list = new LLNameListCtrl("name_list", - rect, - multi_select, - draw_border, - draw_heading, - name_column_index - ); + LLNameListCtrl* name_list = new LLNameListCtrl("name_list", rect, multi_select, draw_border, draw_heading, name_column_index); if (node->hasAttribute("heading_height")) { S32 heading_height; @@ -360,7 +345,6 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto LLSD columns; S32 index = 0; - //S32 total_static = 0; LLXMLNodePtr child; for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) { @@ -372,21 +356,24 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto std::string columnname(labelname); child->getAttributeString("name", columnname); - BOOL columndynamicwidth = FALSE; - child->getAttributeBOOL("dynamicwidth", columndynamicwidth); - std::string sortname(columnname); child->getAttributeString("sort", sortname); - S32 columnwidth = -1; if (child->hasAttribute("relwidth")) { F32 columnrelwidth = 0.f; child->getAttributeF32("relwidth", columnrelwidth); columns[index]["relwidth"] = columnrelwidth; } + else if (child->hasAttribute("dynamicwidth")) + { + BOOL columndynamicwidth = FALSE; + child->getAttributeBOOL("dynamicwidth", columndynamicwidth); + columns[index]["dynamic_width"] = columndynamicwidth; + } else { + S32 columnwidth = -1; child->getAttributeS32("width", columnwidth); columns[index]["width"] = columnwidth; } @@ -394,12 +381,9 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto LLFontGL::HAlign h_align = LLFontGL::LEFT; h_align = LLView::selectFontHAlign(child); - //if(!columndynamicwidth) total_static += llmax(0, columnwidth); - columns[index]["name"] = columnname; columns[index]["label"] = labelname; columns[index]["halign"] = (S32)h_align; - columns[index]["dynamicwidth"] = columndynamicwidth; columns[index]["sort"] = sortname; index++; @@ -452,6 +436,3 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto return name_list; } - - - diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 9f672d1f1..451f1ae7c 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -2,31 +2,25 @@ * @file llnamelistctrl.h * @brief A list of names, automatically refreshing from the name cache. * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * 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 + * Copyright (C) 2010, Linden Research, Inc. * - * 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 + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * 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. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,6 +33,36 @@ class LLAvatarName; +/** + * LLNameListCtrl item + * + * We don't use LLScrollListItem to be able to override getUUID(), which is needed + * because the name list item value is not simply an UUID but a map (uuid, is_group). + */ +class LLNameListItem : public LLScrollListItem, public LLHandleProvider +{ +public: + bool isGroup() const { return mIsGroup; } + void setIsGroup(bool is_group) { mIsGroup = is_group; } + +protected: + friend class LLNameListCtrl; + + LLNameListItem( const LLScrollListItem::Params& p ) + : LLScrollListItem(p), mIsGroup(false) + { + } + + LLNameListItem( const LLScrollListItem::Params& p, bool is_group ) + : LLScrollListItem(p), mIsGroup(is_group) + { + } + +private: + bool mIsGroup; +}; + + class LLNameListCtrl : public LLScrollListCtrl, public LLInstanceTracker { @@ -50,33 +74,61 @@ public: SPECIAL } ENameType; - LLNameListCtrl(const std::string& name, - const LLRect& rect, - BOOL allow_multiple_selection, - BOOL draw_border = TRUE, - bool draw_heading = false, - S32 name_column_index = 0, - const std::string& tooltip = LLStringUtil::null); - virtual ~LLNameListCtrl(); + // provide names for enums + struct NameTypeNames : public LLInitParam::TypeValuesHelper + { + static void declareValues(); + }; + struct NameItem : public LLInitParam::Block + { + Optional name; + Optional target; + + NameItem() + : name("name"), + target("target", INDIVIDUAL) + {} + }; + + struct NameColumn : public LLInitParam::ChoiceBlock + { + Alternative column_index; + Alternative column_name; + NameColumn() + : column_name("name_column"), + column_index("name_column_index", 0) + {} + }; + +protected: + LLNameListCtrl(const std::string& name, const LLRect& rect, BOOL allow_multiple_selection, BOOL draw_border = TRUE, bool draw_heading = false, S32 name_column_index = 0, const std::string& tooltip = LLStringUtil::null); + virtual ~LLNameListCtrl() + { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + } + friend class LLUICtrlFactory; +public: virtual LLXMLNodePtr getXML(bool save_children = true) const; static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); // Add a user to the list by name. It will be added, the name // requested from the cache, and updated as necessary. LLScrollListItem* addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM, - BOOL enabled = TRUE, std::string const& suffix = LLStringUtil::null); - LLScrollListItem* addNameItem(LLSD& item, EAddPosition pos = ADD_BOTTOM); + BOOL enabled = TRUE, const std::string& suffix = LLStringUtil::null); + LLScrollListItem* addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM); /*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); - LLScrollListItem* addNameItemRow(const LLSD& value, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); + LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM, const std::string& suffix = LLStringUtil::null); // Add a user to the list by name. It will be added, the name // requested from the cache, and updated as necessary. void addGroupNameItem(const LLUUID& group_id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); - - void addGroupNameItem(LLSD& item, EAddPosition pos = ADD_BOTTOM); + void addGroupNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM); void removeNameItem(const LLUUID& agent_id); @@ -91,11 +143,14 @@ public: void sortByName(BOOL ascending); private: - static std::set sInstances; - void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, LLHandle item); + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, LLHandle item); + +private: S32 mNameColumnIndex; BOOL mAllowCallingCardDrop; bool mShortNames; // display name only, no SLID + boost::signals2::connection mAvatarNameCacheConnection; }; + #endif diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 26e2f356f..3eebe22c1 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -60,6 +60,7 @@ #include "llpreviewtexture.h" #include "llpluginclassmedia.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "lltabcontainer.h" #include "lluictrlfactory.h" #include "llviewerwindow.h" @@ -520,7 +521,7 @@ BOOL LLPanelAvatarSecondLife::postBuild(void) getChild("Add Friend...")->setCommitCallback(boost::bind(LLAvatarActions::requestFriendshipDialog, boost::bind(&LLPanelAvatar::getAvatarID, pa))); getChild("Pay...")->setCommitCallback(boost::bind(LLAvatarActions::pay, boost::bind(&LLPanelAvatar::getAvatarID, pa))); - childSetAction("Mute", LLPanelAvatar::onClickMute, pa); + getChild("Mute")->setCommitCallback(boost::bind(LLAvatarActions::toggleBlock, boost::bind(&LLPanelAvatar::getAvatarID, pa))); getChild("Offer Teleport...")->setCommitCallback(boost::bind(static_cast(LLAvatarActions::offerTeleport), boost::bind(&LLPanelAvatar::getAvatarID, pa))); @@ -1727,26 +1728,6 @@ void LLPanelAvatar::onClickGetKey(void *userdata) gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(agent_id.asString())); } -//----------------------------------------------------------------------------- -// onClickMute() -//----------------------------------------------------------------------------- -void LLPanelAvatar::onClickMute(void *userdata) -{ - LLPanelAvatar* self = (LLPanelAvatar*) userdata; - - LLUUID agent_id = self->getAvatarID(); - - LLFloaterMute::showInstance(); - if (LLAvatarActions::isBlocked(agent_id)) - { - LLFloaterMute::getInstance()->selectMute(agent_id); - } - else - { - LLAvatarActions::toggleBlock(agent_id); - } -} - // static void LLPanelAvatar::onClickOK(void *userdata) { diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index ef9841992..a7c18e796 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -40,23 +40,11 @@ #include "llavatarpropertiesprocessor.h" class LLAvatarName; -class LLButton; class LLCheckBoxCtrl; -class LLDropTarget; -class LLInventoryItem; class LLLineEditor; -class LLNameEditor; class LLPanelAvatar; -class LLScrollListCtrl; class LLTabContainer; -class LLTextBox; -class LLTextEditor; -class LLTextureCtrl; -class LLUICtrl; -class LLViewerTexture; class LLViewerObject; -class LLMessageSystem; -class LLIconCtrl; class LLMediaCtrl; class LLPanelPick; @@ -328,7 +316,6 @@ public: static void onClickGetKey(void *userdata); static void onClickOK( void *userdata); static void onClickCancel( void *userdata); - static void onClickMute( void *userdata); private: void enableOKIfReady(); diff --git a/indra/newview/llpaneldirbrowser.cpp b/indra/newview/llpaneldirbrowser.cpp index 929b5c6b8..bd0a7b3ed 100644 --- a/indra/newview/llpaneldirbrowser.cpp +++ b/indra/newview/llpaneldirbrowser.cpp @@ -641,9 +641,9 @@ void LLPanelDirBrowser::processDirPlacesReply(LLMessageSystem* msg, void**) content["name"] = name; std::string buffer = llformat("%.0f", (F64)dwell); - row["columns"][3]["column"] = "dwell"; - row["columns"][3]["value"] = buffer; - row["columns"][3]["font"] = "SANSSERIF_SMALL"; + row["columns"][2]["column"] = "dwell"; + row["columns"][2]["value"] = buffer; + row["columns"][2]["font"] = "SANSSERIF_SMALL"; list->addElement(row); self->mResultsContents[parcel_id.asString()] = content; @@ -1062,15 +1062,17 @@ void LLPanelDirBrowser::processDirLandReply(LLMessageSystem *msg, void**) buffer = llformat("%d", sale_price); non_auction_count++; } - row["columns"][3]["column"] = "price"; + row["columns"][2]["column"] = "price"; + row["columns"][2]["value"] = buffer; + row["columns"][2]["font"] = "SANSSERIF_SMALL"; + + buffer = llformat("%d", actual_area); + row["columns"][3]["column"] = "area"; row["columns"][3]["value"] = buffer; row["columns"][3]["font"] = "SANSSERIF_SMALL"; - buffer = llformat("%d", actual_area); - row["columns"][4]["column"] = "area"; - row["columns"][4]["value"] = buffer; + row["columns"][4]["column"] = "per_meter"; row["columns"][4]["font"] = "SANSSERIF_SMALL"; - if (!auction) { F32 price_per_meter; @@ -1084,21 +1086,17 @@ void LLPanelDirBrowser::processDirLandReply(LLMessageSystem *msg, void**) } // Prices are usually L$1 - L$10 / meter buffer = llformat("%.1f", price_per_meter); - row["columns"][5]["column"] = "per_meter"; - row["columns"][5]["value"] = buffer; - row["columns"][5]["font"] = "SANSSERIF_SMALL"; + row["columns"][4]["value"] = buffer; } else { // Auctions start at L$1 per meter - row["columns"][5]["column"] = "per_meter"; - row["columns"][5]["value"] = "1.0"; - row["columns"][5]["font"] = "SANSSERIF_SMALL"; + row["columns"][4]["value"] = "1.0"; } - row["columns"][6]["column"] = "landtype"; - row["columns"][6]["value"] = land_type; - row["columns"][6]["font"] = "SANSSERIF_SMALL"; + row["columns"][5]["column"] = "landtype"; + row["columns"][5]["value"] = land_type; + row["columns"][5]["font"] = "SANSSERIF_SMALL"; list->addElement(row); self->mResultsContents[parcel_id.asString()] = content; @@ -1144,35 +1142,31 @@ LLSD LLPanelDirBrowser::createLandSale(const LLUUID& parcel_id, BOOL is_auction, row["id"] = parcel_id; LLUUID image_id; + row["columns"][0]["column"] = "icon"; + row["columns"][0]["type"] = "icon"; // Icon and type if(is_auction) { - row["columns"][0]["column"] = "icon"; - row["columns"][0]["type"] = "icon"; row["columns"][0]["value"] = "icon_auction.tga"; *type = AUCTION_CODE; } else if (is_for_sale) { - row["columns"][0]["column"] = "icon"; - row["columns"][0]["type"] = "icon"; row["columns"][0]["value"] = "icon_for_sale.tga"; *type = FOR_SALE_CODE; } else { - row["columns"][0]["column"] = "icon"; - row["columns"][0]["type"] = "icon"; row["columns"][0]["value"] = "icon_place.tga"; *type = PLACE_CODE; } - row["columns"][2]["column"] = "name"; - row["columns"][2]["value"] = name; - row["columns"][2]["font"] = "SANSSERIF"; + row["columns"][1]["column"] = "name"; + row["columns"][1]["value"] = name; + row["columns"][1]["font"] = "SANSSERIF"; return row; } diff --git a/indra/newview/llpaneldirland.cpp b/indra/newview/llpaneldirland.cpp index 79c3a60a2..9c249a81d 100644 --- a/indra/newview/llpaneldirland.cpp +++ b/indra/newview/llpaneldirland.cpp @@ -46,6 +46,7 @@ #include "llcombobox.h" #include "lllineeditor.h" #include "llnotificationsutil.h" +#include "llscrolllistcolumn.h" #include "llscrolllistctrl.h" #include "llstatusbar.h" #include "lluiconstants.h" diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index c6ed7163f..78ae39dda 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -518,7 +518,6 @@ void LLPanelFace::getState() BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced(); // only turn on auto-adjust button if there is a media renderer and the media is loaded - getChildView("textbox autofix")->setEnabled(editable); getChildView("button align")->setEnabled(editable); //if ( LLMediaEngine::getInstance()->getMediaRenderer () ) @@ -579,7 +578,6 @@ void LLPanelFace::getState() if(LLViewerMedia::textureHasMedia(id)) { - getChildView("textbox autofix")->setEnabled(editable); getChildView("button align")->setEnabled(editable); } @@ -997,9 +995,6 @@ void LLPanelFace::getState() getChildView("tex gen")->setEnabled(FALSE); getChildView("label shininess")->setEnabled(FALSE); getChildView("label bumpiness")->setEnabled(FALSE); - - getChildView("textbox autofix")->setEnabled(FALSE); - getChildView("button align")->setEnabled(FALSE); getChildView("button apply")->setEnabled(FALSE); //getChildView("has media")->setEnabled(FALSE); diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 169da75a8..ac3ecd30e 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -34,11 +34,8 @@ #include "llpanelgroupgeneral.h" -#include "lluictrlfactory.h" #include "llagent.h" -#include "llavataractions.h" -#include "llfloatergroups.h" -#include "llgroupactions.h" +#include "lluictrlfactory.h" #include "roles_constants.h" // UI elements @@ -46,6 +43,8 @@ #include "llcheckboxctrl.h" #include "llcombobox.h" #include "lldbstrings.h" +#include "llavataractions.h" +#include "llgroupactions.h" #include "llimview.h" #include "lllineeditor.h" #include "llnamebox.h" @@ -57,7 +56,7 @@ #include "lltextbox.h" #include "lltexteditor.h" #include "lltexturectrl.h" -#include "llviewercontrol.h" +#include "lltrans.h" #include "llviewerwindow.h" #include "hippogridmanager.h" @@ -395,8 +394,7 @@ bool LLPanelGroupGeneral::apply(std::string& mesg) LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); if (!gdatap) { - // *TODO: Translate - mesg = std::string("No group data found for group "); + mesg = LLTrans::getString("NoGroupDataFound"); mesg.append(mGroupID.asString()); return false; } @@ -838,23 +836,17 @@ void LLPanelGroupGeneral::addMember(LLGroupMemberData* member) { style = "BOLD"; } - LLSD row; - row["id"] = member->getID(); + LLNameListCtrl::NameItem item_params; + item_params.value = member->getID(); - row["columns"][0]["column"] = "name"; - row["columns"][0]["font-style"] = style; - row["columns"][0]["font"] = "SANSSERIF_SMALL"; - row["columns"][1]["column"] = "title"; - row["columns"][1]["value"] = member->getTitle(); - row["columns"][1]["font-style"] = style; - row["columns"][1]["font"] = "SANSSERIF_SMALL"; + LLScrollListCell::Params column; + item_params.columns.add().column("name").font/*.name*/("SANSSERIF_SMALL").font_style(style); - row["columns"][2]["column"] = "online"; - row["columns"][2]["value"] = member->getOnlineStatus(); - row["columns"][2]["font-style"] = style; - row["columns"][1]["font"] = "SANSSERIF_SMALL"; + item_params.columns.add().column("title").value(member->getTitle()).font/*.name*/("SANSSERIF_SMALL").font_style(style); - mListVisibleMembers->addNameItemRow(row); + item_params.columns.add().column("online").value(member->getOnlineStatus()).font/*.name*/("SANSSERIF_SMALL").font_style(style); + + /*LLScrollListItem* member_row =*/ mListVisibleMembers->addNameItemRow(item_params); } void LLPanelGroupGeneral::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name) diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index 6b4d0e680..f16d4985c 100644 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -43,6 +43,7 @@ #include "llgroupmgr.h" #include "llnamelistctrl.h" #include "llnotificationsutil.h" +#include "llscrolllistitem.h" #include "llspinctrl.h" #include "lltextbox.h" #include "llviewerobject.h" @@ -148,7 +149,7 @@ void LLPanelGroupInvite::impl::addUsers(const std::vector& names, row["columns"][0]["column"] = "name"; row["columns"][0]["value"] = name; - mInvitees->addNameItem(row); + mInvitees->addElement(row); } } diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index 26e77c6ba..dec32551a 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -45,6 +45,7 @@ #include "lllineeditor.h" #include "llproductinforequest.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "lltextbox.h" #include "lltabcontainer.h" #include "lltexteditor.h" diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 3deb47999..87e237369 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -41,10 +41,9 @@ #include "llviewerinventory.h" #include "llinventorydefines.h" #include "llinventoryfunctions.h" -#include "llinventorymodel.h" #include "llinventoryicon.h" +#include "llinventorymodel.h" #include "llagent.h" -#include "lltooldraganddrop.h" #include "lllineeditor.h" #include "lltexteditor.h" @@ -52,11 +51,11 @@ #include "lliconctrl.h" #include "llcheckboxctrl.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "lltextbox.h" #include "roles_constants.h" #include "llviewerwindow.h" -#include "llviewercontrol.h" #include "llviewermessage.h" #include "llnotificationsutil.h" #include "llgiveinventory.h" @@ -86,16 +85,15 @@ public: EAcceptance* accept, std::string& tooltip_msg); static LLView* fromXML(LLXMLNodePtr node, LLView* parent, class LLUICtrlFactory* factory); + void setPanel(LLPanelGroupNotices* panel) { mGroupNoticesPanel = panel; } - void setGroupNoticesPanel(LLPanelGroupNotices* panel) { mGroupNoticesPanel = panel; } protected: LLPanelGroupNotices* mGroupNoticesPanel; }; LLGroupDropTarget::LLGroupDropTarget(const LLDropTarget::Params& p) : LLDropTarget(p) -{ -} +{} // static LLView* LLGroupDropTarget::fromXML(LLXMLNodePtr node, LLView* parent, LLUICtrlFactory* factory) @@ -144,6 +142,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, case DAD_BODYPART: case DAD_ANIMATION: case DAD_GESTURE: + case DAD_CALLINGCARD: { LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data; if(gInventory.getItem(inv_item->getUUID()) @@ -167,7 +166,6 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, break; } case DAD_CATEGORY: - case DAD_CALLINGCARD: default: *accept = ACCEPT_NO; break; @@ -269,9 +267,9 @@ BOOL LLPanelGroupNotices::postBuild() mPanelCreateNotice = getChild("panel_create_new_notice",recurse); mPanelViewNotice = getChild("panel_view_past_notice",recurse); - LLGroupDropTarget* group_drop_target = getChild("drop_target",recurse); - group_drop_target->setEntityID(mGroupID); - group_drop_target->setGroupNoticesPanel(this); + LLGroupDropTarget* target = getChild("drop_target",recurse); + target->setPanel(this); + target->setEntityID(mGroupID); arrangeNoticeView(VIEW_PAST_NOTICE); @@ -538,8 +536,7 @@ void LLPanelGroupNotices::showNotice(const std::string& subject, mInventoryOffer = inventory_offer; std::string icon_name = LLInventoryIcon::getIconName(mInventoryOffer->mType, - LLInventoryType::IT_TEXTURE, - 0, FALSE); + LLInventoryType::IT_TEXTURE); mViewInventoryIcon->setImage(icon_name); mViewInventoryIcon->setVisible(TRUE); diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 0b5acb543..2a540e1c1 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -46,6 +46,7 @@ #include "llnotificationsutil.h" #include "llpanelgrouproles.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "lltabcontainer.h" #include "lltextbox.h" #include "lltexteditor.h" @@ -503,13 +504,11 @@ void LLPanelGroupSubTab::setSearchFilter(const std::string& filter) void LLPanelGroupSubTab::activate() { - lldebugs << "LLPanelGroupSubTab::activate()" << llendl; setOthersVisible(TRUE); } void LLPanelGroupSubTab::deactivate() { - lldebugs << "LLPanelGroupSubTab::deactivate()" << llendl; setOthersVisible(FALSE); } @@ -519,19 +518,11 @@ void LLPanelGroupSubTab::setOthersVisible(BOOL b) { mHeader->setVisible( b ); } - else - { - llwarns << "LLPanelGroupSubTab missing header!" << llendl; - } if (mFooter) { mFooter->setVisible( b ); } - else - { - llwarns << "LLPanelGroupSubTab missing footer!" << llendl; - } } bool LLPanelGroupSubTab::matchesActionSearchFilter(std::string action) @@ -1068,7 +1059,7 @@ void LLPanelGroupMembersSubTab::onEjectMembers(void *userdata) void LLPanelGroupMembersSubTab::handleEjectMembers() { //send down an eject message - std::vector selected_members; + uuid_vec_t selected_members; std::vector selection = mMembersList->getAllSelected(); if (selection.empty()) return; @@ -1111,6 +1102,7 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id, for (std::vector::iterator itor = selection.begin() ; itor != selection.end(); ++itor) { + member_id = (*itor)->getUUID(); //see if we requested a change for this member before @@ -1403,7 +1395,7 @@ U64 LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges(const LLUUID& ag if ( role_change_datap ) { - std::vector roles_to_be_removed; + uuid_vec_t roles_to_be_removed; for (role_change_data_map_t::iterator role = role_change_datap->begin(); role != role_change_datap->end(); ++ role) @@ -1536,19 +1528,17 @@ void LLPanelGroupMembersSubTab::addMemberToList(LLGroupMemberData* data) LLUIString donated = getString("donation_area"); donated.setArg("[AREA]", llformat("%d", data->getContribution())); - LLSD row; - row["id"] = data->getID(); + LLNameListCtrl::NameItem item_params; + item_params.value = data->getID(); - row["columns"][0]["column"] = "name"; - row["columns"][0]["font"] = "SANSSERIF_SMALL"; + item_params.columns.add().column("name").font/*.name*/("SANSSERIF_SMALL")/*.style("NORMAL")*/; - row["columns"][1]["column"] = "donated"; - row["columns"][1]["value"] = donated.getString(); + item_params.columns.add().column("donated").value(donated.getString()) + .font/*.name*/("SANSSERIF_SMALL")/*.style("NORMAL")*/; - row["columns"][2]["column"] = "online"; - row["columns"][2]["value"] = data->getOnlineStatus(); - row["columns"][2]["font"] = "SANSSERIF_SMALL"; - mMembersList->addNameItemRow(row); + item_params.columns.add().column("online").value(data->getOnlineStatus()) + .font/*.name*/("SANSSERIF_SMALL")/*.style("NORMAL")*/; + mMembersList->addNameItemRow(item_params); mHasMatch = TRUE; } @@ -1678,6 +1668,7 @@ LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab(const std::string& name, const mMemberVisibleCheck(NULL), mDeleteRoleButton(NULL), mCreateRoleButton(NULL), + mHasRoleChange(FALSE) { } @@ -2084,8 +2075,8 @@ void LLPanelGroupRolesSubTab::buildMembersList() LLGroupRoleData* rdatap = (*rit).second; if (rdatap) { - std::vector::const_iterator mit = rdatap->getMembersBegin(); - std::vector::const_iterator end = rdatap->getMembersEnd(); + uuid_vec_t::const_iterator mit = rdatap->getMembersBegin(); + uuid_vec_t::const_iterator end = rdatap->getMembersEnd(); for ( ; mit != end; ++mit) { mAssignedMembersList->addNameItem((*mit)); @@ -2423,9 +2414,7 @@ BOOL LLPanelGroupActionsSubTab::postBuildSubTab(LLView* root) void LLPanelGroupActionsSubTab::activate() { LLPanelGroupSubTab::activate(); - lldebugs << "LLPanelGroupActionsSubTab::activate()" << llendl; - update(GC_ALL); } diff --git a/indra/newview/llpanelgroupvoting.cpp b/indra/newview/llpanelgroupvoting.cpp index 2b03523b8..f45cd2818 100644 --- a/indra/newview/llpanelgroupvoting.cpp +++ b/indra/newview/llpanelgroupvoting.cpp @@ -32,24 +32,19 @@ #include "llviewerprecompiledheaders.h" -#include "roles_constants.h" +#include "llpanelgroupvoting.h" -#include "lllineeditor.h" +#include "llbutton.h" #include "llnotificationsutil.h" +#include "llradiogroup.h" +#include "llscrolllistctrl.h" +#include "llscrolllistitem.h" +#include "llspinctrl.h" #include "lltextbox.h" #include "lltexteditor.h" -#include "llscrolllistctrl.h" -#include "llradiogroup.h" -#include "llspinctrl.h" -#include "llpanelgroupvoting.h" -#include "llnamelistctrl.h" -#include "llbutton.h" -#include "llnotify.h" #include "llagent.h" -#include "llfocusmgr.h" #include "llviewercontrol.h" -#include "llviewerwindow.h" #include "llviewerregion.h" class AIHTTPTimeoutPolicy; diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 3abb4c2b2..cbd78eb9e 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -90,9 +90,6 @@ #include "llstring.h" #include -class AIHTTPTimeoutPolicy; -extern AIHTTPTimeoutPolicy iamHereLogin_timeout; - const S32 BLACK_BORDER_HEIGHT = 160; const S32 MAX_PASSWORD = 16; diff --git a/indra/newview/llpanelmediasettingssecurity.cpp b/indra/newview/llpanelmediasettingssecurity.cpp index 509560b37..28422a4f8 100644 --- a/indra/newview/llpanelmediasettingssecurity.cpp +++ b/indra/newview/llpanelmediasettingssecurity.cpp @@ -32,6 +32,7 @@ #include "llcheckboxctrl.h" #include "llnotificationsutil.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "lluictrlfactory.h" #include "llwindow.h" #include "llviewerwindow.h" diff --git a/indra/newview/llpanelmsgs.cpp b/indra/newview/llpanelmsgs.cpp index 95bb24e0a..949dbb3b5 100644 --- a/indra/newview/llpanelmsgs.cpp +++ b/indra/newview/llpanelmsgs.cpp @@ -33,10 +33,12 @@ #include "llpanelmsgs.h" -#include "llscrolllistctrl.h" -#include "lluictrlfactory.h" -#include "llfirstuse.h" #include "llnotificationtemplate.h" +#include "llscrolllistctrl.h" +#include "llscrolllistitem.h" +#include "lluictrlfactory.h" + +#include "llfirstuse.h" LLPanelMsgs::LLPanelMsgs() { diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index 9438dfa79..c578c9a8d 100644 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -33,7 +33,9 @@ #include "llcombobox.h" #include "llresizebar.h" #include "llresizehandle.h" +#include "llscrolllistcolumn.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "llslider.h" #include "llsliderctrl.h" #include "llagent.h" @@ -84,10 +86,11 @@ LLPanelNearByMedia::LLPanelNearByMedia(bool standalone_panel) { mHoverTimer.stop(); - mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) && - gSavedSettings.getBOOL("MediaTentativeAutoPlay"); + mParcelAudioAutoStart = gSavedSettings.getBOOL("MediaTentativeAutoPlay"); + /*gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) && + gSavedSettings.getBOOL("MediaTentativeAutoPlay");*/ - gSavedSettings.getControl(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING)->getSignal()->connect(boost::bind(&LLPanelNearByMedia::handleMediaAutoPlayChanged, this, _2)); + //gSavedSettings.getControl(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING)->getSignal()->connect(boost::bind(&LLPanelNearByMedia::handleMediaAutoPlayChanged, this, _2)); mCommitCallbackRegistrar.add("MediaListCtrl.EnableAll", boost::bind(&LLPanelNearByMedia::onClickEnableAll, this)); mCommitCallbackRegistrar.add("MediaListCtrl.DisableAll", boost::bind(&LLPanelNearByMedia::onClickDisableAll, this)); @@ -474,7 +477,7 @@ void LLPanelNearByMedia::updateListItem(LLScrollListItem* item, { cell->setValue(name); } - item->setToolTip(item_tooltip); + cell->setToolTip(item_tooltip); // *TODO: Make these font styles/colors configurable via XUI U8 font_style = LLFontGL::NORMAL; @@ -909,7 +912,7 @@ void LLPanelNearByMedia::onClickParcelAudioPlay() } else { - gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL()); + LLViewerParcelMedia::playStreamingMusic(LLViewerParcelMgr::getInstance()->getAgentParcel()); } } @@ -1263,12 +1266,18 @@ void* createNearbyMediaPanel(void* userdata) return new LLPanelNearByMedia(false); } -LLFloaterNearbyMedia::LLFloaterNearbyMedia() +LLFloaterNearbyMedia::LLFloaterNearbyMedia() : mPanel(NULL) { mFactoryMap["nearby_media"] = LLCallbackMap(createNearbyMediaPanel, this); LLUICtrlFactory::getInstance()->buildFloater(this,"floater_nearby_media.xml",&mFactoryMap,false); } +/*virtual*/ BOOL LLFloaterNearbyMedia::postBuild() +{ + mPanel = getChild("nearby_media",false,false); + return LLFloater::postBuild(); +} + // static void LLFloaterNearbyMedia::updateClass() { diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h index e6d0a4d9b..410dfb48c 100644 --- a/indra/newview/llpanelnearbymedia.h +++ b/indra/newview/llpanelnearbymedia.h @@ -189,10 +189,15 @@ public: static void updateClass(); + /*virtual*/ BOOL postBuild(); /*virtual*/ void onClose(bool app_quitting); /*virtual*/ void onOpen(); virtual void handleReshape(const LLRect& new_rect, bool by_user); + + LLPanelNearByMedia* getMediaPanel() { return mPanel; } +private: + LLPanelNearByMedia* mPanel; }; #endif // LL_LLPANELNEARBYMEDIA_H diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 9d1df930c..9f3414448 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -381,16 +381,25 @@ void LLPanelPermissions::refresh() // Update creator text field getChildView("Creator:")->setEnabled(TRUE); +// [RLVa:KB] - Checked: 2010-11-02 (RLVa-1.2.2a) | Modified: RLVa-1.2.2a + BOOL creators_identical = FALSE; +// [/RLVa:KB] std::string creator_name; - bool creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_name); +// [RLVa:KB] - Checked: 2010-11-02 (RLVa-1.2.2a) | Modified: RLVa-1.2.2a + creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_name); +// [/RLVa:KB] +// LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_name); - getChild("Creator Name")->setValue(creator_name); - getChildView("Creator Name")->setEnabled(TRUE); - getChildView("button creator profile")->setEnabled(creators_identical && mCreatorID.notNull()); +// getChild("Creator Name")->setValue(creator_name); +// getChildView("Creator Name")->setEnabled(TRUE); +// [RLVa:KB] - Moved further down to avoid an annoying flicker when the text is set twice in a row // Update owner text field getChildView("Owner:")->setEnabled(TRUE); + // Update last owner text field + getChildView("Last Owner:")->setEnabled(TRUE); + std::string owner_name; const BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(mOwnerID, owner_name); @@ -419,31 +428,52 @@ void LLPanelPermissions::refresh() } } } +// getChild("Owner Name")->setValue(owner_name); +// getChildView("Owner Name")->setEnabled(TRUE); +// [RLVa:KB] - Moved further down to avoid an annoying flicker when the text is set twice in a row -// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) +// [RLVa:KB] - Checked: 2010-11-02 (RLVa-1.2.2a) | Modified: RLVa-1.2.2a bool fRlvEnableOwner = true; - if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ) + bool fRlvEnableCreator = true; + bool fRlvEnableLastOwner = true; + if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) { - // Only filter the owner name if: the selection is all owned by the same avie and not group owned - if ( (owners_identical) && (!LLSelectMgr::getInstance()->selectIsGroupOwned()) ) + // Only anonymize the creator if all of the selection was created by the same avie who's also the owner or they're a nearby avie + if ( (creators_identical) && (mCreatorID != gAgent.getID()) && ((mCreatorID == mOwnerID) || (RlvUtil::isNearbyAgent(mCreatorID))) ) + { + creator_name = RlvStrings::getAnonym(creator_name); + fRlvEnableOwner = false; + } + + // Only anonymize the owner name if all of the selection is owned by the same avie and isn't group owned + if ( (owners_identical) && (!LLSelectMgr::getInstance()->selectIsGroupOwned()) && (mOwnerID != gAgent.getID()) ) { owner_name = RlvStrings::getAnonym(owner_name); - fRlvEnableOwner = false; + fRlvEnableCreator = false; + } + + if (RlvUtil::isNearbyAgent(mLastOwnerID)) + { + creator_name = RlvStrings::getAnonym(creator_name); + fRlvEnableLastOwner = false; } } // [/RLVa:KB] + getChild("Creator Name")->setValue(creator_name); + getChildView("Creator Name")->setEnabled(TRUE); getChild("Owner Name")->setValue(owner_name); getChildView("Owner Name")->setEnabled(TRUE); // childSetEnabled("button owner profile",owners_identical && (mOwnerID.notNull() || LLSelectMgr::getInstance()->selectIsGroupOwned())); +// getChildView("button last owner profile")->setEnabled(owners_identical && mLastOwnerID.notNull()); // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) - childSetEnabled("button owner profile", - fRlvEnableOwner && owners_identical && (mOwnerID.notNull() || LLSelectMgr::getInstance()->selectIsGroupOwned())); + getChildView("button owner profile")->setEnabled(fRlvEnableOwner && owners_identical && (mOwnerID.notNull() || LLSelectMgr::getInstance()->selectIsGroupOwned())); + getChildView("button creator profile")->setEnabled(fRlvEnableCreator && creators_identical && mCreatorID.notNull()); + getChildView("button last owner profile")->setEnabled(fRlvEnableLastOwner && owners_identical && mLastOwnerID.notNull()); // [/RLVa:KB] getChild("Last Owner Name")->setValue(last_owner_name); getChildView("Last Owner Name")->setEnabled(TRUE); - getChildView("button last owner profile")->setEnabled(owners_identical && mLastOwnerID.notNull()); // update group text field getChildView("Group:")->setEnabled(TRUE); @@ -620,12 +650,10 @@ void LLPanelPermissions::refresh() BOOL valid_base_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_BASE, &base_mask_on, &base_mask_off); - //BOOL valid_owner_perms =// LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER, &owner_mask_on, &owner_mask_off); - BOOL valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_GROUP, &group_mask_on, &group_mask_off); @@ -1037,10 +1065,9 @@ void LLPanelPermissions::onClickGroup() if(owners_identical && (owner_id == gAgent.getID())) { LLFloaterGroupPicker* fg = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); - if (fg) { - fg->setSelectCallback( cbGroupID, this ); + fg->setSelectGroupCallback( boost::bind(&LLPanelPermissions::cbGroupID, this, _1) ); if (parent_floater) { @@ -1059,13 +1086,11 @@ void LLPanelPermissions::onClickOpenGroup() LLGroupActions::show(group_id); } -// static -void LLPanelPermissions::cbGroupID(LLUUID group_id, void* userdata) +void LLPanelPermissions::cbGroupID(LLUUID group_id) { - LLPanelPermissions* self = (LLPanelPermissions*)userdata; - if(self->mLabelGroupName) + if(mLabelGroupName) { - self->mLabelGroupName->setNameID(group_id, TRUE); + mLabelGroupName->setNameID(group_id, TRUE); } LLSelectMgr::getInstance()->sendGroup(group_id); } diff --git a/indra/newview/llpanelpermissions.h b/indra/newview/llpanelpermissions.h index da87e1196..58b6dbac9 100644 --- a/indra/newview/llpanelpermissions.h +++ b/indra/newview/llpanelpermissions.h @@ -63,7 +63,7 @@ protected: void onClickLastOwner(); void onClickGroup(); static void onClickOpenGroup(); - static void cbGroupID(LLUUID group_id, void* userdata); + void cbGroupID(LLUUID group_id); static void onClickDeedToGroup(void*); static void onClickCopyObjKey(); diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index ee27ead48..86db29ccb 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -31,6 +31,7 @@ #include "llmutelist.h" #include "llparticipantlist.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "llspeakers.h" #include "llviewerwindow.h" #include "llvoiceclient.h" diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index c5ffefffe..eb5a75972 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -31,49 +31,38 @@ */ #include "llviewerprecompiledheaders.h" - -#include - #include "llpreviewgesture.h" -// libraries -#include "lldatapacker.h" -#include "lldarray.h" -#include "llinventorydefines.h" -#include "llstring.h" -#include "lldir.h" -#include "llmultigesture.h" -#include "llvfile.h" -#include "lltrans.h" - -// newview -#include "llagent.h" // todo: remove +#include "llagent.h" +#include "llanimstatelabels.h" #include "llanimationstates.h" +#include "llappviewer.h" // gVFS #include "llassetuploadresponders.h" #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcombobox.h" +#include "lldatapacker.h" #include "lldelayedgestureerror.h" #include "llfloatergesture.h" // for some label constants #include "llgesturemgr.h" +#include "llinventorydefines.h" #include "llinventoryfunctions.h" #include "llinventorymodelbackgroundfetch.h" #include "llkeyboard.h" #include "lllineeditor.h" +#include "llmultigesture.h" #include "llnotificationsutil.h" #include "llradiogroup.h" +#include "llresmgr.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "lltextbox.h" +#include "lltrans.h" #include "lluictrlfactory.h" -#include "llviewerinventory.h" -#include "llviewerobject.h" +#include "llvfile.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llviewerstats.h" -#include "llviewerwindow.h" // busycount -#include "llappviewer.h" // gVFS -#include "llanimstatelabels.h" -#include "llresmgr.h" // *TODO: Translate? @@ -98,7 +87,7 @@ void LLInventoryGestureAvailable::done() { for(uuid_vec_t::iterator it = mComplete.begin(); it != mComplete.end(); ++it) { - LLPreview *preview = LLPreview::find((*it)); + LLPreview* preview = LLPreview::find((*it)); if(preview) { preview->refresh(); @@ -557,6 +546,7 @@ static const std::string valid_key_to_string(KEY key) void LLPreviewGesture::addKeys() { LLComboBox* combo = mKeyCombo; + combo->add( NONE_LABEL ); for (KEY key = ' '; key < KEY_NONE; key++) { @@ -686,7 +676,7 @@ void LLPreviewGesture::refresh() if (mPreviewGesture || !is_complete) { - childSetEnabled("desc", FALSE); + getChildView("desc")->setEnabled(FALSE); //mDescEditor->setEnabled(FALSE); mTriggerEditor->setEnabled(FALSE); mReplaceText->setEnabled(FALSE); @@ -720,7 +710,7 @@ void LLPreviewGesture::refresh() BOOL modifiable = item->getPermissions().allowModifyBy(gAgent.getID()); - childSetEnabled("desc", modifiable); + getChildView("desc")->setEnabled(modifiable); mTriggerEditor->setEnabled(TRUE); mLibraryList->setEnabled(modifiable); mStepList->setEnabled(modifiable); diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 6613a0055..c9f1adffc 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -40,28 +40,28 @@ #include "llcheckboxctrl.h" #include "llcombobox.h" #include "lldir.h" +#include "llexternaleditor.h" +#include "statemachine/aifilepicker.h" #include "llinventorydefines.h" #include "llinventorymodel.h" #include "llkeyboard.h" #include "lllineeditor.h" - #include "lllivefile.h" -#include "llexternaleditor.h" #include "llnotificationsutil.h" #include "llresmgr.h" #include "llscrollbar.h" #include "llscrollcontainer.h" #include "llscrolllistctrl.h" +#include "llscrolllistitem.h" #include "llslider.h" //#include "lscript_rt_interface.h" +//#include "lscript_library.h" //#include "lscript_export.h" #include "lltextbox.h" #include "lltooldraganddrop.h" #include "llvfile.h" -#include "statemachine/aifilepicker.h" #include "llagent.h" -#include "llnotify.h" #include "llmenugl.h" #include "roles_constants.h" #include "llselectmgr.h" @@ -80,7 +80,6 @@ #include "llslider.h" #include "lldir.h" #include "llcombobox.h" -//#include "llfloaterchat.h" #include "llfloatersearchreplace.h" #include "llviewerstats.h" #include "llviewertexteditor.h" @@ -91,7 +90,6 @@ #include "lltrans.h" #include "llviewercontrol.h" #include "llappviewer.h" -#include "llpanelobjectinventory.h" #include "llsdserialize.h" @@ -750,7 +748,7 @@ BOOL LLScriptEdCore::canClose() bool LLScriptEdCore::handleSaveChangesDialog(const LLSD& notification, const LLSD& response ) { - S32 option = LLNotification::getSelectedOption(notification, response); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); switch( option ) { case 0: // "Yes" @@ -782,7 +780,7 @@ bool LLScriptEdCore::handleSaveChangesDialog(const LLSD& notification, const LLS // static bool LLScriptEdCore::onHelpWebDialog(const LLSD& notification, const LLSD& response) { - S32 option = LLNotification::getSelectedOption(notification, response); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); switch(option) { @@ -1142,8 +1140,7 @@ void LLScriptEdCore::onErrorList(LLUICtrl*, void* user_data) LLScrollListItem* item = self->mErrorList->getFirstSelected(); if(item) { - // *FIX: This fucked up little hack is here because we don't - // have a grep library. This is very brittle code. + // *FIX: replace with boost grep S32 row = 0; S32 column = 0; const LLScrollListCell* cell = item->getColumn(0); @@ -1161,7 +1158,7 @@ void LLScriptEdCore::onErrorList(LLUICtrl*, void* user_data) bool LLScriptEdCore::handleReloadFromServerDialog(const LLSD& notification, const LLSD& response ) { - S32 option = LLNotification::getSelectedOption(notification, response); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); switch( option ) { case 0: // "Yes" @@ -1454,8 +1451,7 @@ void LLPreviewLSL::onSave(void* userdata, BOOL close_after_save) // Save needs to compile the text in the buffer. If the compile // succeeds, then save both assets out to the database. If the compile -// fails, go ahead and save the text anyway so that the user doesn't -// get too fucked. +// fails, go ahead and save the text anyway. void LLPreviewLSL::saveIfNeeded() { // llinfos << "LLPreviewLSL::saveIfNeeded()" << llendl; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 646f83f2e..7bd68ad4a 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -840,6 +840,7 @@ void LLSelectMgr::addAsFamily(std::vector& objects, BOOL add_to if (objectp->getNumTEs() > 0) { nodep->selectAllTEs(TRUE); + objectp->setAllTESelected(true); } else { @@ -897,10 +898,12 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab else if (face == SELECT_ALL_TES) { nodep->selectAllTEs(TRUE); + objectp->setAllTESelected(true); } else if (0 <= face && face < SELECT_MAX_TES) { nodep->selectTE(face, TRUE); + objectp->setTESelected(face, true); } else { @@ -1124,6 +1127,7 @@ LLObjectSelectionHandle LLSelectMgr::selectHighlightedObjects() // flag this object as selected objectp->setSelected(TRUE); + objectp->setAllTESelected(true); mSelectedObjects->mSelectType = getSelectTypeForObject(objectp); @@ -1351,6 +1355,7 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable) if (nodep->isTESelected(te)) { nodep->selectTE(te, FALSE); + objectp->setTESelected(te, false); } else { @@ -3292,6 +3297,7 @@ void LLSelectMgr::selectDelete() return; } // [/RLVa:KB] + S32 deleteable_count = 0; BOOL locked_but_deleteable_object = FALSE; @@ -4069,7 +4075,6 @@ void LLSelectMgr::deselectUnused() } } - void LLSelectMgr::convertTransient() { LLObjectSelection::iterator node_it; @@ -4080,23 +4085,23 @@ void LLSelectMgr::convertTransient() } } - void LLSelectMgr::deselectAllIfTooFar() { // [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c if ( (!mSelectedObjects->isEmpty()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_EDITOBJ))) ) { - struct NotTransientOrEditable : public LLSelectedNodeFunctor + struct NotTransientOrFocusedMediaOrEditable : public LLSelectedNodeFunctor { bool apply(LLSelectNode* pNode) { const LLViewerObject* pObj = pNode->getObject(); - return (!pNode->isTransient()) && (pObj) && (!gRlvHandler.canEdit(pObj)); - } - } f; - if (mSelectedObjects->getFirstRootNode(&f, TRUE)) - deselectAll(); - } + return (!pNode->isTransient()) && (pObj) && (!gRlvHandler.canEdit(pObj)) && + (pObj->getID() != LLViewerMediaFocus::getInstance()->getFocusedObjectID()); + } + } f; + if (mSelectedObjects->getFirstRootNode(&f, TRUE)) + deselectAll(); + } // [/RLVa:KB] if (mSelectedObjects->isEmpty() || mSelectedObjects->mSelectType == SELECT_TYPE_HUD) @@ -4123,9 +4128,8 @@ void LLSelectMgr::deselectAllIfTooFar() } LLVector3d selectionCenter = getSelectionCenterGlobal(); - // if (gSavedSettings.getBOOL("LimitSelectDistance") -// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f +// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Modified: RLVa-0.2.0f BOOL fRlvFartouch = gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH) && gFloaterTools->getVisible(); if ( (gSavedSettings.getBOOL("LimitSelectDistance") || (fRlvFartouch) ) // [/RLVa:KB] @@ -4135,7 +4139,7 @@ void LLSelectMgr::deselectAllIfTooFar() && !selectionCenter.isExactlyZero()) { // F32 deselect_dist = gSavedSettings.getF32("MaxSelectDistance"); -// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f +// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Modified: RLVa-0.2.0f F32 deselect_dist = (!fRlvFartouch) ? gSavedSettings.getF32("MaxSelectDistance") : 1.5f; // [/RLVa:KB] F32 deselect_dist_sq = deselect_dist * deselect_dist; @@ -4157,6 +4161,7 @@ void LLSelectMgr::deselectAllIfTooFar() } } + void LLSelectMgr::selectionSetObjectName(const std::string& name) { // we only work correctly if 1 object is selected. @@ -4334,6 +4339,7 @@ void LLSelectMgr::sendDelink() } sendfunc; getSelection()->applyToObjects(&sendfunc); + // Delink needs to send individuals so you can unlink a single object from // a linked set. sendListToRegions( @@ -5047,6 +5053,7 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data } } + // Iterate through nodes at end, since it can be on both the regular AND hover list struct f : public LLSelectedNodeFunctor { @@ -5059,7 +5066,11 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data } func(id); LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func); - if (node) + if (!node) + { + llwarns << "Couldn't find object " << id << " selected." << llendl; + } + else { if (node->mInventorySerial != inv_serial) { @@ -5570,13 +5581,18 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) } if (mSelectedObjects->getNumNodes()) { - LLUUID inspect_item_id = LLFloaterInspect::getSelectedUUID(); + LLUUID inspect_item_id= LLUUID::null; + LLFloaterInspect* inspect_instance = LLFloaterInspect::instanceExists() ? LLFloaterInspect::getInstance() : NULL; + if(inspect_instance && inspect_instance->getVisible()) + { + inspect_item_id = inspect_instance->getSelectedUUID(); + } LLUUID focus_item_id = LLViewerMediaFocus::getInstance()->getFocusedObjectID(); // //for (S32 pass = 0; pass < 2; pass++) - //{ // + { for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); iter != mSelectedObjects->end(); iter++) { @@ -5612,9 +5628,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) node->renderOneSilhouette(sSilhouetteChildColor); } } - // - //} - // + } } if (mHighlightedObjects->getNumNodes()) @@ -6271,7 +6285,6 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) // Update everyone who cares about the selection list void dialog_refresh_all() - { // This is the easiest place to fire the update signal, as it will // make cleaning up the functions below easier. Also, sometimes entities @@ -6300,7 +6313,12 @@ void dialog_refresh_all() } LLFloaterProperties::dirtyAll(); - LLFloaterInspect::dirty(); + + LLFloaterInspect* inspect_instance = LLFloaterInspect::instanceExists() ? LLFloaterInspect::getInstance() : NULL; + if(inspect_instance) + { + inspect_instance->dirty(); + } } S32 get_family_count(LLViewerObject *parent) diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index db1042031..fa4313ebd 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -111,7 +111,6 @@ LLSD LLSpeakerUpdateModeratorEvent::getValue() return ret; } - LLSpeakerTextModerationEvent::LLSpeakerTextModerationEvent(LLSpeaker* source) : LLEvent(source, "Speaker text moderation event") { @@ -254,15 +253,58 @@ bool LLSpeakersDelayActionsStorage::onTimerActionCallback(const LLUUID& speaker_ return true; } +// +// ModerationResponder +// + +class ModerationResponder : public LLHTTPClient::ResponderIgnoreBody +{ +public: + ModerationResponder(const LLUUID& session_id) + { + mSessionID = session_id; + } + + /*virtual*/ void error(U32 status, const std::string& reason) + { + llwarns << "ModerationResponder error [status:" << status << "]: " << reason << llendl; + + if ( gIMMgr ) + { + LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(mSessionID); + if (!floaterp) return; + + //403 == you're not a mod + //should be disabled if you're not a moderator + if ( 403 == status ) + { + floaterp->showSessionEventError( + "mute", + "not_a_mod_error"); + } + else + { + floaterp->showSessionEventError( + "mute", + "generic_request_error"); + } + } + } + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return moderationResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "ModerationResponder"; } + +private: + LLUUID mSessionID; +}; // // LLSpeakerMgr // LLSpeakerMgr::LLSpeakerMgr(LLVoiceChannel* channelp) : - mVoiceChannel(channelp) -, mVoiceModerated(false) -, mModerateModeHandledFirstTime(false) + mVoiceChannel(channelp), + mVoiceModerated(false), + mModerateModeHandledFirstTime(false) { static LLUICachedControl remove_delay ("SpeakerParticipantRemoveDelay", 10.0); @@ -276,7 +318,10 @@ LLSpeakerMgr::~LLSpeakerMgr() LLPointer LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::string& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type) { - if (id.isNull()) return NULL; + if (id.isNull()) + { + return NULL; + } LLPointer speakerp; if (mSpeakers.find(id) == mSpeakers.end()) @@ -358,13 +403,11 @@ void LLSpeakerMgr::update(BOOL resort_ok) // update status of all current speakers BOOL voice_channel_active = (!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive()); - for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end();) + for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); speaker_it++) { LLUUID speaker_id = speaker_it->first; LLSpeaker* speakerp = speaker_it->second; - speaker_it++; - if (voice_channel_active && LLVoiceClient::getInstance()->getVoiceEnabled(speaker_id)) { speakerp->mSpeechVolume = LLVoiceClient::getInstance()->getCurrentPower(speaker_id); @@ -461,22 +504,18 @@ void LLSpeakerMgr::update(BOOL resort_ok) void LLSpeakerMgr::updateSpeakerList() { - // are we bound to the currently active voice channel? + // Are we bound to the currently active voice channel? if ((!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive())) { std::set participants; LLVoiceClient::getInstance()->getParticipantList(participants); - // add new participants to our list of known speakers - for (std::set::iterator participant_it = participants.begin(); - participant_it != participants.end(); - ++participant_it) + // If we are, add all voice client participants to our list of known speakers + for (std::set::iterator participant_it = participants.begin(); participant_it != participants.end(); ++participant_it) { setSpeaker(*participant_it, LLVoiceClient::getInstance()->getDisplayName(*participant_it), LLSpeaker::STATUS_VOICE_ACTIVE, (LLVoiceClient::getInstance()->isParticipantAvatar(*participant_it)?LLSpeaker::SPEAKER_AGENT:LLSpeaker::SPEAKER_EXTERNAL)); - - } } } @@ -730,47 +769,10 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update) } } } - -class ModerationResponder : public LLHTTPClient::ResponderIgnoreBody -{ -public: - ModerationResponder(const LLUUID& session_id) - { - mSessionID = session_id; - } - - /*virtual*/ void error(U32 status, const std::string& reason) - { - llwarns << "ModerationResponder error [status:" << status << "]: " << reason << llendl; - - if ( gIMMgr ) - { - LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(mSessionID); - if (!floaterp) return; - - //403 == you're not a mod - //should be disabled if you're not a moderator - if ( 403 == status ) - { - floaterp->showSessionEventError( - "mute", - "not_a_mod_error"); - } - else - { - floaterp->showSessionEventError( - "mute", - "generic_request_error"); - } - } - } - /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return moderationResponder_timeout; } - /*virtual*/ char const* getName(void) const { return "ModerationResponder"; } - -private: - LLUUID mSessionID; -}; - +/*prep# + virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content) + llwarns << "ModerationResponder error [status:" << status << "]: " << content << llendl; + */ void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id) { LLPointer speakerp = findSpeaker(speaker_id); @@ -957,4 +959,3 @@ void LLLocalSpeakerMgr::updateSpeakerList() } } } - diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp index 791f8f248..2d07e1c05 100644 --- a/indra/newview/lltoolbar.cpp +++ b/indra/newview/lltoolbar.cpp @@ -35,41 +35,30 @@ #include "lltoolbar.h" -#include "imageids.h" -#include "llfontgl.h" -#include "llrect.h" -#include "llparcel.h" +#include "llbutton.h" +#include "llflyoutbutton.h" +#include "llscrolllistitem.h" +#include "llui.h" #include "llagent.h" #include "llagentcamera.h" #include "llagentwearables.h" -#include "llbutton.h" -#include "llfocusmgr.h" -#include "llviewercontrol.h" -#include "llmenucommands.h" -#include "llimview.h" -#include "lluiconstants.h" -#include "llvoavatarself.h" -#include "lltooldraganddrop.h" -#include "llfloaterchatterbox.h" -#include "llfloaterfriends.h" -#include "llfloaterinventory.h" -#include "llfloatersnapshot.h" -#include "llfloateravatarlist.h" -#include "lltoolmgr.h" -#include "llui.h" -#include "llviewermenu.h" #include "llfirstuse.h" #include "llviewerparcelmgr.h" -#include "lluictrlfactory.h" -#include "llviewerwindow.h" -#include "lltoolgrab.h" -#include "llcombobox.h" +#include "llfloateravatarlist.h" #include "llfloaterchat.h" -#include "llfloatermute.h" -#include "llimpanel.h" -#include "llscrolllistctrl.h" +#include "llfloaterchatterbox.h" #include "llfloatercustomize.h" +#include "llfloaterfriends.h" +#include "llfloaterinventory.h" +#include "llfloatermute.h" +#include "llfloatersnapshot.h" +#include "llimpanel.h" +#include "llimview.h" +#include "llmenucommands.h" +#include "lltoolmgr.h" +#include "lltoolgrab.h" +#include "llvoavatarself.h" // [RLVa:KB] #include "rlvhandler.h" @@ -78,6 +67,7 @@ #if LL_DARWIN #include "llresizehandle.h" + #include "llviewerwindow.h" // This class draws like an LLResizeHandle but has no interactivity. // It's just there to provide a cue to the user that the lower right corner of the window functions as a resize handle. @@ -343,7 +333,7 @@ void LLToolBar::refresh() mBuildBtn->setEnabled(!(gRlvHandler.hasBehaviour(RLV_BHVR_REZ) && gRlvHandler.hasBehaviour(RLV_BHVR_EDIT))); mMapBtn->setEnabled(!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWWORLDMAP)); - mRadarBtn->setEnabled(!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWMINIMAP)); + mRadarBtn->setEnabled(!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWMINIMAP) && !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)); mInventoryBtn->setEnabled(!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWINV)); } // [/RLVa:KB] diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index c34103b4d..6b3aa2a21 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -87,6 +87,7 @@ std::string getProfileURL(const std::string& agent_name); /*static*/ const char* LLViewerMedia::AUTO_PLAY_MEDIA_SETTING = "ParcelMediaAutoPlayEnable"; +/*static*/ const char* LLViewerMedia::AUTO_PLAY_PRIM_MEDIA_SETTING = "PrimMediaAutoPlayEnable"; /*static*/ const char* LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING = "MediaShowOnOthers"; /*static*/ const char* LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING = "MediaShowWithinParcel"; /*static*/ const char* LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING = "MediaShowOutsideParcel"; @@ -1103,7 +1104,7 @@ void LLViewerMedia::setAllMediaEnabled(bool val) } else { - gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL()); + LLViewerParcelMedia::playStreamingMusic(LLViewerParcelMgr::getInstance()->getAgentParcel()); } } } @@ -3861,9 +3862,19 @@ void LLViewerMediaImpl::setTextureID(LLUUID id) // bool LLViewerMediaImpl::isAutoPlayable() const { - return (mMediaAutoPlay && - gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) && - gSavedSettings.getBOOL("MediaTentativeAutoPlay")); + static const LLCachedControl media_tentative_auto_play("MediaTentativeAutoPlay",false); + static const LLCachedControl auto_play_parcel_media(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING,false); + static const LLCachedControl auto_play_prim_media(LLViewerMedia::AUTO_PLAY_PRIM_MEDIA_SETTING,false); + if(mMediaAutoPlay && media_tentative_auto_play) + { + if(getUsedInUI()) + return true; + else if(isParcelMedia() && auto_play_parcel_media) + return true; + else if(auto_play_prim_media) + return true; + } + return false; } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 8be43590c..902d7ae0f 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -84,6 +84,7 @@ public: // String to get/set media autoplay in gSavedSettings static const char* AUTO_PLAY_MEDIA_SETTING; + static const char* AUTO_PLAY_PRIM_MEDIA_SETTING; static const char* SHOW_MEDIA_ON_OTHERS_SETTING; static const char* SHOW_MEDIA_WITHIN_PARCEL_SETTING; static const char* SHOW_MEDIA_OUTSIDE_PARCEL_SETTING; diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp index 701d4981b..91a2dfafc 100644 --- a/indra/newview/llviewermediafocus.cpp +++ b/indra/newview/llviewermediafocus.cpp @@ -414,7 +414,7 @@ void LLViewerMediaFocus::update() normal = mHoverObjectNormal; } - if(media_impl && viewer_object) + if(media_impl && viewer_object && !media_impl->isForcedUnloaded()) { // We have an object and impl to point at. diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 7a79e3dc8..21d4226a6 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -171,7 +171,6 @@ #include "shfloatermediaticker.h" #include "llpacketring.h" #include "aihttpview.h" -#include "awavefront.h" // #include "scriptcounter.h" @@ -225,6 +224,8 @@ void handle_test_load_url(void*); class AIHTTPView; +void add_wave_listeners(); +void add_dae_listeners(); //extern BOOL gHideSelectedObjects; //extern BOOL gAllowSelectAvatar; //extern BOOL gDebugAvatarRotation; @@ -489,11 +490,6 @@ void handle_mesh_save_obj(void*); void handle_mesh_load_obj(void*); void handle_morph_save_obj(void*); void handle_morph_load_obj(void*); -void save_avatar_to_obj(LLVOAvatar *avatar); -void save_selected_avatar_to_obj(); -void save_selected_objects_to_obj(); -void save_wavefront_continued(WavefrontSaver* wfsaver, AIFilePicker* filepicker); -void handle_save_current_avatar_obj(void*); void handle_debug_avatar_textures(void*); void handle_dump_region_object_cache(void*); @@ -706,8 +702,6 @@ void init_menus() gAttachSubMenu = gMenuBarView->getChildMenuByName("Attach Object", TRUE); gDetachSubMenu = gMenuBarView->getChildMenuByName("Detach Object", TRUE); - LLMenuGL*menu; - // // Add in the pose stand ------------------------------------------- /*LLMenuGL* sub = new LLMenuGL("Pose Stand..."); @@ -722,6 +716,9 @@ void init_menus() sub->addChild(new LLMenuItemCallGL( "Stop Pose Stand", &handle_pose_stand_stop, NULL)); // ------------------------------------------------------*/ + // TomY TODO convert these two + LLMenuGL*menu; + menu = new LLMenuGL(CLIENT_MENU_NAME); menu->setCanTearOff(TRUE); init_client_menu(menu); @@ -1029,7 +1026,7 @@ void init_client_menu(LLMenuGL* menu) sub = new LLMenuGL("Media"); sub->setCanTearOff(TRUE); sub->addChild(new LLMenuItemCallGL("Reload MIME types", &LLMIMETypes::reload)); - sub->addChild(new LLMenuItemCallGL("Web Browser Test", &handle_web_browser_test)); + sub->addChild(new LLMenuItemCallGL("Web Browser Test", &handle_web_browser_test, NULL, NULL, KEY_F1)); menu->addChild( sub ); sub->createJumpKeys(); } @@ -2061,7 +2058,7 @@ class LLObjectInspect : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLFloaterInspect::show(); + LLFloaterInspect::showInstance(); return true; } }; @@ -6137,24 +6134,6 @@ class LLAvatarInviteToGroup : public view_listener_t } }; -class LLAvatarSaveAsOBJ : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - save_selected_avatar_to_obj(); - return true; - } -}; - -class LLSelectionSaveAsOBJ : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - save_selected_objects_to_obj(); - return true; - } -}; - class LLAvatarAddFriend : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -8538,104 +8517,6 @@ static void handle_morph_load_obj_continued(void* data, AIFilePicker* filepicker morph_data->setMorphFromMesh(&mesh); } -void handle_save_current_avatar_obj(void* data) -{ - if(gAgentAvatarp) - save_avatar_to_obj(gAgentAvatarp); -} - -void save_selected_avatar_to_obj() -{ - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); - if(avatar) - save_avatar_to_obj(avatar); -} - -void save_avatar_to_obj(LLVOAvatar *avatar) -{ - std::string file_name = llformat("%s.obj", avatar->getFullname().c_str()); - std::string full_path = gDirUtilp->getExpandedFilename(LL_PATH_NONE, file_name); - - WavefrontSaver* wfsaver = new WavefrontSaver(); - wfsaver->Add((LLVOAvatar*)avatar); - - AIFilePicker* filepicker = AIFilePicker::create(); - filepicker->open(full_path); - filepicker->run(boost::bind(&save_wavefront_continued, wfsaver, filepicker)); -} - -void save_selected_objects_to_obj() -{ - struct ff : public LLSelectedNodeFunctor - { - virtual bool apply(LLSelectNode* node) - { - return LLObjectBackup::getInstance()->validatePerms(node->mPermissions); - } - } func; - - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - - if(!selection) - return; - - if (!selection->applyToNodes(&func, false)) - { - llwarns << "Incorrect permissions: Wavefront OBJ export aborted" << llendl; - LLSD args; - args["REASON"] = "Insufficient Permissions"; - LLNotificationsUtil::add("WavefrontExportFailed", args); - return; - } - - std::string file_name = llformat("%s.obj", selection->getFirstNode()->mName.c_str()); - std::string full_path = gDirUtilp->getExpandedFilename(LL_PATH_NONE, file_name); - - WavefrontSaver* wfsaver = new WavefrontSaver(); - LLSelectNode* root_one = (LLSelectNode *)*selection->root_begin(); - wfsaver->offset = -root_one->getObject()->getRenderPosition(); - for (LLObjectSelection::iterator iter = selection->begin(); - iter != selection->end(); iter++) - { - LLSelectNode* node = *iter; - LLViewerObject* object = node->getObject(); - wfsaver->Add(object); - } - - AIFilePicker* filepicker = AIFilePicker::create(); - filepicker->open(full_path); - filepicker->run(boost::bind(&save_wavefront_continued, wfsaver, filepicker)); -} - -void save_wavefront_continued(WavefrontSaver* wfsaver, AIFilePicker* filepicker) -{ - if (!filepicker->hasFilename()) - { - llwarns << "No file; bailing" << llendl; - return; - } - std::string selected_filename = filepicker->getFilename(); - LLFILE* fp = LLFile::fopen(selected_filename, "wb"); - if (!fp) - { - llerrs << "can't open: " << selected_filename << llendl; - return; - } - try - { - wfsaver->saveFile(fp); - } - catch(int e) - { - llwarns << "An exception occurred while generating / saving OBJ file. Exception #" << e << llendl; - } - llinfos << "OBJ file saved to " << selected_filename << llendl; - LLSD args; - args["FILENAME"] = selected_filename; - LLNotificationsUtil::add("WavefrontExportSuccess", args); - fclose(fp); -} - // Returns a pointer to the avatar give the UUID of the avatar OR of an attachment the avatar is wearing. // Returns NULL on failure. LLVOAvatar* find_avatar_from_object( LLViewerObject* object ) @@ -9323,6 +9204,15 @@ class SinguVisibleDebugConsole : public view_listener_t } }; +class VisibleNotSecondLife : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + gMenuHolder->findControl(userdata["control"].asString())->setValue(!gHippoGridManager->getConnectedGrid()->isSecondLife()); + return true; + } +}; + void addMenu(view_listener_t *menu, const std::string& name) { sMenus.push_back(menu); @@ -9509,7 +9399,6 @@ void initialize_menus() addMenu(new LLAvatarEnableFreezeEject(), "Avatar.EnableFreezeEject"); addMenu(new LLAvatarCopyUUID(), "Avatar.CopyUUID"); addMenu(new LLAvatarClientUUID(), "Avatar.ClientID"); - addMenu(new LLAvatarSaveAsOBJ(), "Avatar.SaveAsOBJ"); // Object pie menu addMenu(new LLObjectOpen(), "Object.Open"); @@ -9529,6 +9418,8 @@ void initialize_menus() addMenu(new LLPowerfulWizard(), "Object.Explode"); addMenu(new LLCanIHasKillEmAll(), "Object.EnableDestroy"); addMenu(new LLOHGOD(), "Object.EnableExplode"); + add_wave_listeners(); + add_dae_listeners(); // addMenu(new LLObjectMute(), "Object.Mute"); addMenu(new LLObjectBuy(), "Object.Buy"); @@ -9541,7 +9432,6 @@ void initialize_menus() addMenu(new LLObjectExport(), "Object.Export"); addMenu(new LLObjectImport(), "Object.Import"); addMenu(new LLObjectImportUpload(), "Object.ImportUpload"); - addMenu(new LLSelectionSaveAsOBJ(), "Object.SaveAsOBJ"); addMenu(new LLObjectEnableOpen(), "Object.EnableOpen"); @@ -9624,6 +9514,8 @@ void initialize_menus() } // [/RLVa:KB] + addMenu(new VisibleNotSecondLife(), "VisibleNotSecondLife"); + LLToolMgr::getInstance()->initMenu(sMenus); } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index b55f28c82..b3dd4bd21 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -36,6 +36,7 @@ #include "llanimationstates.h" #include "llaudioengine.h" +#include "llavataractions.h" #include "llavatarnamecache.h" #include "../lscript/lscript_byteformat.h" //Need LSCRIPTRunTimePermissionBits and SCRIPT_PERMISSION_* #include "lleconomy.h" @@ -186,7 +187,10 @@ const std::string SCRIPT_QUESTIONS[SCRIPT_PERMISSION_EOF] = "TrackYourCamera", "ControlYourCamera", "TeleportYourAgent", - "OverrideAnimations" + "JoinAnExperience", + "SilentlyManageEstateAccess", + "OverrideYourAnimations", + "ScriptReturnObjects" }; const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] = @@ -203,7 +207,10 @@ const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] = FALSE, // TrackYourCamera, FALSE, // ControlYourCamera FALSE, // TeleportYourAgent - FALSE // OverrideAnimations + FALSE, // JoinAnExperience + FALSE, // SilentlyManageEstateAccess + FALSE, // OverrideYourAnimations + FALSE, // ScriptReturnObjects }; bool friendship_offer_callback(const LLSD& notification, const LLSD& response) @@ -244,6 +251,10 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response) msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]); msg->sendReliable(LLHost(payload["sender"].asString())); break; + case 3: + // profile + LLAvatarActions::showProfile(payload["from_id"]); + LLNotificationsUtil::add(notification["name"], notification["substitutions"], payload); //Respawn! default: // close button probably, possibly timed out break; @@ -254,11 +265,6 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response) static LLNotificationFunctorRegistration friendship_offer_callback_reg("OfferFriendship", friendship_offer_callback); static LLNotificationFunctorRegistration friendship_offer_callback_reg_nm("OfferFriendshipNoMessage", friendship_offer_callback); -//const char BUSY_AUTO_RESPONSE[] = "The Resident you messaged is in 'busy mode' which means they have " -// "requested not to be disturbed. Your message will still be shown in their IM " -// "panel for later viewing."; - -// // Functions // @@ -2219,8 +2225,39 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // [/RLVa:KB] // else if (offline == IM_ONLINE && !is_linden && is_busy && name != SYSTEM_FROM) // [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c - else if (offline == IM_ONLINE && !is_linden && (is_busy || is_autorespond || is_autorespond_nonfriends || is_autorespond_muted) && name != SYSTEM_FROM && gRlvHandler.canReceiveIM(from_id)) + else if (offline == IM_ONLINE && !is_linden && is_busy && !is_muted && name != SYSTEM_FROM && gRlvHandler.canReceiveIM(from_id)) // [/RLVa:KB] + { + if (!gIMMgr->hasSession(session_id) || gSavedPerAccountSettings.getBOOL("AscentInstantMessageResponseRepeat")) + { + if (to_id.notNull()) busy_message(msg, from_id); + } + + // now store incoming IM in chat history + buffer = separator_string + message.substr(message_offset); + + LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL; + // add to IM panel, but do not bother the user + gIMMgr->addMessage( + session_id, + from_id, + name, + buffer, + name, + dialog, + parent_estate_id, + region_id, + position, + true); + + // pretend this is chat generated by self, so it does not show up on screen + chat.mText = std::string("IM: ") + name + separator_string + message.substr(message_offset); + LLFloaterChat::addChat(chat, true, true); + } +// else if (to_id.notNull() && offline == IM_ONLINE && !is_linden && (is_autorespond || is_autorespond_nonfriends || is_autorespond_muted) && name != SYSTEM_FROM) +// [RLVa:LF] - Same as above: Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c + else if (to_id.notNull() && offline == IM_ONLINE && !is_linden && (is_autorespond || is_autorespond_nonfriends || is_autorespond_muted) && name != SYSTEM_FROM && gRlvHandler.canReceiveIM(from_id)) +// [/RLVa:LF] { // now store incoming IM in chat history @@ -2235,7 +2272,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) from_id, name, buffer, - LLStringUtil::null, + name, dialog, parent_estate_id, region_id, @@ -2264,13 +2301,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) itemid = static_cast(gSavedPerAccountSettings.getString("AutoresponseMutedItemID")); // We don't show that we've responded to mutes } - else if (is_busy) - { - response = gSavedPerAccountSettings.getString("BusyModeResponse"); - if (gSavedPerAccountSettings.getBOOL("BusyModeResponseItem")) - itemid = static_cast(gSavedPerAccountSettings.getString("BusyModeResponseItemID")); - show_autoresponded = gSavedPerAccountSettings.getBOOL("BusyModeResponseShow"); - } else if (is_autorespond_nonfriends) { response = gSavedPerAccountSettings.getString("AutoresponseNonFriendsMessage"); @@ -2302,14 +2332,14 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) if (!LLAvatarNameCache::getPNSName(from_id, pns_name)) pns_name = name; if (show_autoresponded) { - gIMMgr->addMessage(session_id, from_id, LLStringUtil::null, LLTrans::getString("IM_autoresponded_to") + " " + pns_name); + gIMMgr->addMessage(session_id, from_id, name, LLTrans::getString("IM_autoresponded_to") + " " + pns_name); } if (LLViewerInventoryItem* item = gInventory.getItem(itemid)) { LLGiveInventory::doGiveInventoryItem(from_id, item, computed_session_id); if (show_autoresponded) { - gIMMgr->addMessage(computed_session_id, from_id, LLStringUtil::null, + gIMMgr->addMessage(computed_session_id, from_id, name, llformat("%s %s \"%s\"", pns_name.c_str(), LLTrans::getString("IM_autoresponse_sent_item").c_str(), item->getName().c_str())); } } @@ -2380,7 +2410,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) from_id, name, buffer, - LLStringUtil::null, + name, dialog, parent_estate_id, region_id, @@ -2470,14 +2500,14 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) if (show_autoresponded) { - gIMMgr->addMessage(session_id, from_id, LLStringUtil::null, LLTrans::getString("IM_autoresponded_to") + " " + pns_name); + gIMMgr->addMessage(session_id, from_id, name, LLTrans::getString("IM_autoresponded_to") + " " + pns_name); } if (LLViewerInventoryItem* item = gInventory.getItem(itemid)) { LLGiveInventory::doGiveInventoryItem(from_id, item, computed_session_id); if (show_autoresponded) { - gIMMgr->addMessage(computed_session_id, from_id, LLStringUtil::null, + gIMMgr->addMessage(computed_session_id, from_id, name, llformat("%s %s \"%s\"", pns_name.c_str(), LLTrans::getString("IM_autoresponse_sent_item").c_str(), item->getName().c_str())); } } @@ -3286,6 +3316,9 @@ void busy_message (LLMessageSystem* msg, LLUUID from_id) { std::string my_name; LLAgentUI::buildFullname(my_name); + std::string from_name; + msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, from_name); + from_name = LLCacheName::cleanFullName(from_name); std::string response = gSavedPerAccountSettings.getText("BusyModeResponse"); pack_instant_message( gMessageSystem, @@ -3294,10 +3327,25 @@ void busy_message (LLMessageSystem* msg, LLUUID from_id) gAgent.getSessionID(), from_id, my_name, - response, + replace_wildcards(response, from_id, from_name), IM_ONLINE, IM_BUSY_AUTO_RESPONSE); gAgent.sendReliableMessage(); + std::string pns_name; + if (!LLAvatarNameCache::getPNSName(from_id, pns_name)) pns_name = from_name; + LLUUID session_id; + msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, session_id); + if (gSavedPerAccountSettings.getBOOL("BusyModeResponseShow")) gIMMgr->addMessage(session_id, from_id, from_name, LLTrans::getString("IM_autoresponded_to") + " " + pns_name); + if (!gSavedPerAccountSettings.getBOOL("BusyModeResponseItem")) return; // Not sending an item, finished + if (LLViewerInventoryItem* item = gInventory.getItem(static_cast(gSavedPerAccountSettings.getString("BusyModeResponseItemID")))) + { + U8 d; + msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Dialog, d); + LLUUID computed_session_id = LLIMMgr::computeSessionID(static_cast(d), from_id); + LLGiveInventory::doGiveInventoryItem(from_id, item, computed_session_id); + if (gSavedPerAccountSettings.getBOOL("BusyModeResponseShow")) + gIMMgr->addMessage(computed_session_id, from_id, from_name, llformat("%s %s \"%s\"", pns_name.c_str(), LLTrans::getString("IM_autoresponse_sent_item").c_str(), item->getName().c_str())); + } } } @@ -6669,7 +6717,7 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp // located in [REGIONNAME] at [REGIONPOS], // has been permission to: [PERMISSIONS]." - LLUIString notice(LLFloaterChat::getInstance()->getString(granted ? "ScriptQuestionCautionChatGranted" : "ScriptQuestionCautionChatDenied")); + LLUIString notice(LLTrans::getString(granted ? "ScriptQuestionCautionChatGranted" : "ScriptQuestionCautionChatDenied")); // always include the object name and owner name notice.setArg("[OBJECTNAME]", notification["payload"]["object_name"].asString()); @@ -6735,9 +6783,7 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp perms.append(", "); } - LLStringUtil::format_map_t args; - args["[CURRENCY]"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol(); - perms.append(LLFloaterChat::getInstance()->getString(SCRIPT_QUESTIONS[i], args)); + perms.append(LLTrans::getString(SCRIPT_QUESTIONS[i])); } } @@ -6913,14 +6959,11 @@ void process_script_question(LLMessageSystem *msg, void **user_data) { if (questions & LSCRIPTRunTimePermissionBits[i]) { - LLStringUtil::format_map_t args; - args["[CURRENCY]"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol(); - count++; - script_question += " " + LLFloaterChat::getInstance()->getString(SCRIPT_QUESTIONS[i], args) + "\n"; - // check whether permission question should cause special caution dialog caution |= (SCRIPT_QUESTION_IS_CAUTION[i]); + + script_question += " " + LLTrans::getString(SCRIPT_QUESTIONS[i]) + "\n"; } } args["QUESTIONS"] = script_question; diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 2a42b7661..5b7c7f274 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -55,6 +55,7 @@ #include "llfloaterbuyland.h" #include "llfloatergroups.h" //#include "llfloaterhtml.h" +#include "llpanelnearbymedia.h" #include "llfloatersellland.h" #include "llfloaterteleporthistory.h" #include "llfloatertools.h" @@ -1799,6 +1800,9 @@ void optionally_start_music(LLParcel* parcel) { if (gSavedSettings.getBOOL("AudioStreamingMusic")) { + + + // Make the user click the start button on the overlay bar. JC // llinfos << "Starting parcel music " << parcel->getMusicURL() << llendl; @@ -1806,8 +1810,19 @@ void optionally_start_music(LLParcel* parcel) // changed as part of SL-4878 if (gOverlayBar && gOverlayBar->musicPlaying()) { - LLViewerParcelMedia::playStreamingMusic(parcel); + LLPanelNearByMedia* nearby_media_panel = LLFloaterNearbyMedia::instanceExists() ? LLFloaterNearbyMedia::getInstance()->getMediaPanel() : NULL; + if ((nearby_media_panel && + nearby_media_panel->getParcelAudioAutoStart()) || + // or they have expressed no opinion in the UI, but have autoplay on... + (!nearby_media_panel && + /*gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&*/ + gSavedSettings.getBOOL("MediaTentativeAutoPlay"))) + { + LLViewerParcelMedia::playStreamingMusic(parcel); + return; + } } + gAudiop->startInternetStream(LLStringUtil::null); } } diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 7e9f8ea5e..9571837c7 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1671,6 +1671,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("ProductInfoRequest"); capabilityNames.append("ProvisionVoiceAccountRequest"); capabilityNames.append("RemoteParcelRequest"); + capabilityNames.append("RenderMaterials"); capabilityNames.append("RequestTextureDownload"); //capabilityNames.append("ResourceCostSelected"); //Object weights (llfloaterobjectweights.cpp) capabilityNames.append("RetrieveNavMeshSrc"); diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index 4ce04b028..1e4c68b79 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -964,4 +964,3 @@ void LLVoiceChannelP2P::setState(EState state) LLRecentPeople::instance().add(mOtherUserID); } }*/ - diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 40cdfa175..dd1b7c662 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -30,6 +30,7 @@ #include "llviewerwindow.h" #include "llvoicevivox.h" #include "llviewernetwork.h" +#include "llcommandhandler.h" #include "llhttpnode.h" #include "llnotificationsutil.h" #include "llsdserialize.h" @@ -42,6 +43,38 @@ const F32 LLVoiceClient::VOLUME_DEFAULT = 0.5f; const F32 LLVoiceClient::VOLUME_MAX = 1.0f; +// Support for secondlife:///app/voice SLapps +class LLVoiceHandler : public LLCommandHandler +{ +public: + // requests will be throttled from a non-trusted browser + LLVoiceHandler() : LLCommandHandler("voice", UNTRUSTED_THROTTLE) {} + + bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) + { + if (params[0].asString() == "effects") + { + LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); + // If the voice client doesn't support voice effects, we can't handle effects SLapps + if (!effect_interface) + { + return false; + } + + // Support secondlife:///app/voice/effects/refresh to update the voice effect list with new effects + if (params[1].asString() == "refresh") + { + effect_interface->refreshVoiceEffectLists(false); + return true; + } + } + return false; + } +}; +LLVoiceHandler gVoiceHandler; + + + std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserver::EStatusType inStatus) { std::string result = "UNKNOWN"; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index d74c3a061..45526cd96 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -330,6 +330,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : mCaptureDeviceDirty(false), mRenderDeviceDirty(false), mSpatialCoordsDirty(false), + mIsInitialized(false), mMuteMic(false), mMuteMicDirty(false), @@ -354,7 +355,9 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : mCaptureBufferRecording(false), mCaptureBufferRecorded(false), mCaptureBufferPlaying(false), - mPlayRequestCount(0) + mPlayRequestCount(0), + + mAvatarNameCacheConnection() { mSpeakerVolume = scale_speaker_volume(0); @@ -387,6 +390,10 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : LLVivoxVoiceClient::~LLVivoxVoiceClient() { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } } //--------------------------------------------------- @@ -568,7 +575,7 @@ void LLVivoxVoiceClient::requestVoiceAccountProvision(S32 retries) { LLViewerRegion *region = gAgent.getRegion(); - if ( region && mVoiceEnabled ) + if ( region && (mVoiceEnabled || !mIsInitialized)) { std::string url = region->getCapability("ProvisionVoiceAccountRequest"); @@ -739,7 +746,7 @@ void LLVivoxVoiceClient::stateMachine() setVoiceEnabled(false); } - if(mVoiceEnabled) + if(mVoiceEnabled || !mIsInitialized) { updatePosition(); } @@ -784,7 +791,7 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateDisabled case stateDisabled: - if(mTuningMode || (mVoiceEnabled && !mAccountName.empty())) + if(mTuningMode || ((mVoiceEnabled || !mIsInitialized) && !mAccountName.empty())) { setState(stateStart); } @@ -1039,7 +1046,7 @@ void LLVivoxVoiceClient::stateMachine() mTuningExitState = stateIdle; setState(stateMicTuningStart); } - else if(!mVoiceEnabled) + else if(!mVoiceEnabled && mIsInitialized) { // We never started up the connector. This will shut down the daemon. setState(stateConnectorStopped); @@ -1233,7 +1240,7 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateConnectorStart case stateConnectorStart: - if(!mVoiceEnabled) + if(!mVoiceEnabled && mIsInitialized) { // We were never logged in. This will shut down the connector. setState(stateLoggedOut); @@ -1251,7 +1258,7 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateConnectorStarted case stateConnectorStarted: // connector handle received - if(!mVoiceEnabled) + if(!mVoiceEnabled && mIsInitialized) { // We were never logged in. This will shut down the connector. setState(stateLoggedOut); @@ -1388,7 +1395,7 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateCreatingSessionGroup case stateCreatingSessionGroup: - if(mSessionTerminateRequested || !mVoiceEnabled) + if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized)) { // *TODO: Question: is this the right way out of this state setState(stateSessionTerminated); @@ -1404,7 +1411,7 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateRetrievingParcelVoiceInfo case stateRetrievingParcelVoiceInfo: // wait until parcel voice info is received. - if(mSessionTerminateRequested || !mVoiceEnabled) + if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized)) { // if a terminate request has been received, // bail and go to the stateSessionTerminated @@ -1424,7 +1431,7 @@ void LLVivoxVoiceClient::stateMachine() // Otherwise, if you log in but don't join a proximal channel (such as when your login location has voice disabled), your friends list won't sync. sendFriendsListUpdates(); - if(mSessionTerminateRequested || !mVoiceEnabled) + if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized)) { // TODO: Question: Is this the right way out of this state? setState(stateSessionTerminated); @@ -1505,7 +1512,7 @@ void LLVivoxVoiceClient::stateMachine() } // joinedAudioSession() will transition from here to stateSessionJoined. - if(!mVoiceEnabled) + if(!mVoiceEnabled && mIsInitialized) { // User bailed out during connect -- jump straight to teardown. setState(stateSessionTerminated); @@ -1552,7 +1559,7 @@ void LLVivoxVoiceClient::stateMachine() notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINED); } - else if(!mVoiceEnabled) + else if(!mVoiceEnabled && mIsInitialized) { // User bailed out during connect -- jump straight to teardown. setState(stateSessionTerminated); @@ -1572,7 +1579,7 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateRunning case stateRunning: // steady state // Disabling voice or disconnect requested. - if(!mVoiceEnabled || mSessionTerminateRequested) + if((!mVoiceEnabled && mIsInitialized) || mSessionTerminateRequested) { leaveAudioSession(); } @@ -1619,6 +1626,8 @@ void LLVivoxVoiceClient::stateMachine() mUpdateTimer.setTimerExpirySec(UPDATE_THROTTLE_SECONDS); sendPositionalUpdate(); } + + mIsInitialized = true; } break; @@ -1652,7 +1661,7 @@ void LLVivoxVoiceClient::stateMachine() // Always reset the terminate request flag when we get here. mSessionTerminateRequested = false; - if(mVoiceEnabled && !mRelogRequested) + if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested) { // Just leaving a channel, go back to stateNoChannel (the "logged in but have no channel" state). setState(stateNoChannel); @@ -1680,7 +1689,7 @@ void LLVivoxVoiceClient::stateMachine() mAccountHandle.clear(); cleanUp(); - if(mVoiceEnabled && !mRelogRequested) + if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested) { // User was logged out, but wants to be logged in. Send a new login request. setState(stateNeedsLogin); @@ -2804,29 +2813,15 @@ void LLVivoxVoiceClient::checkFriend(const LLUUID& id) LLAvatarName av_name; if(LLAvatarNameCache::get(id, &av_name)) { - // *NOTE: For now, we feed legacy names to Vivox because I don't know - // if their service can support a mix of new and old clients with - // different sorts of names. + // *NOTE: We feed legacy names to Vivox because we don't know if their service + // can support a mix of new and old clients with different sorts of names. std::string name = av_name.getLegacyName(); - const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id); - bool canSeeMeOnline = false; - if(relationInfo && relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS)) - canSeeMeOnline = true; - - // When we get here, mNeedsSend is true and mInSLFriends is false. Change them as necessary. - if(buddy) { - // This buddy is already in both lists. - - if(name != buddy->mDisplayName) - { - // The buddy is in the list with the wrong name. Update it with the correct name. - LL_WARNS("Voice") << "Buddy " << id << " has wrong name (\"" << buddy->mDisplayName << "\" should be \"" << name << "\"), updating."<< LL_ENDL; + // This buddy is already in both lists (vivox buddies and avatar cache). + // Trust the avatar cache more for the display name (vivox display name are notoriously wrong) buddy->mDisplayName = name; - buddy->mNeedsNameUpdate = true; // This will cause the buddy to be resent. - } } else { @@ -2835,20 +2830,19 @@ void LLVivoxVoiceClient::checkFriend(const LLUUID& id) buddy->mUUID = id; } - // In all the above cases, the buddy is in the SL friends list (which is how we got here). - buddy->mInSLFriends = true; - buddy->mCanSeeMeOnline = canSeeMeOnline; + const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id); + buddy->mCanSeeMeOnline = (relationInfo && relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS)); + // In all the above cases, the buddy is in the SL friends list and tha name has been resolved (which is how we got here). buddy->mNameResolved = true; - + buddy->mInSLFriends = true; } else { - // This name hasn't been looked up yet. Don't do anything with this buddy list entry until it has. + // This name hasn't been looked up yet in the avatar cache. Don't do anything with this buddy list entry until it has. if(buddy) { buddy->mNameResolved = false; } - // Initiate a lookup. // The "lookup completed" callback will ensure that the friends list is rechecked after it completes. lookupName(id); @@ -2956,13 +2950,12 @@ void LLVivoxVoiceClient::sendFriendsListUpdates() { std::ostringstream stream; - if(buddy->mInSLFriends && (!buddy->mInVivoxBuddies || buddy->mNeedsNameUpdate)) + if(buddy->mInSLFriends && !buddy->mInVivoxBuddies) { if(mNumberOfAliases > 0) { // Add (or update) this entry in the vivox buddy list buddy->mInVivoxBuddies = true; - buddy->mNeedsNameUpdate = false; LL_DEBUGS("Voice") << "add/update " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL; stream << "" @@ -3847,8 +3840,7 @@ void LLVivoxVoiceClient::participantUpdatedEvent( voice participant mIsModeratorMuted is changed after speakers are updated in Speaker Manager and event is not fired. - So, we have to call LLSpeakerMgr::update() here. In any case it is better than call it - in LLCallFloater::draw() + So, we have to call LLSpeakerMgr::update() here. */ LLVoiceChannel* voice_cnl = LLVoiceChannel::getCurrentVoiceChannel(); @@ -4078,7 +4070,7 @@ void LLVivoxVoiceClient::messageEvent( sessionState *session = findSession(sessionHandle); if(session) { - bool is_busy = gAgent.getBusy(); + bool is_do_not_disturb = gAgent.getBusy(); bool is_muted = LLMuteList::getInstance()->isMuted(session->mCallerID, session->mName, LLMute::flagTextChat); bool is_linden = LLMuteList::getInstance()->isLinden(session->mName); LLChat chat; @@ -4091,9 +4083,9 @@ void LLVivoxVoiceClient::messageEvent( chat.mFromName = session->mName; chat.mSourceType = CHAT_SOURCE_AGENT; - if(is_busy && !is_linden) + if(is_do_not_disturb && !is_linden) { - // TODO: Question: Return busy mode response here? Or maybe when session is started instead? + // TODO: Question: Return do not disturb mode response here? Or maybe when session is started instead? } LL_DEBUGS("Voice") << "adding message, name " << session->mName << " session " << session->mIMSessionID << ", target " << session->mCallerID << LL_ENDL; @@ -5985,7 +5977,6 @@ LLVivoxVoiceClient::buddyListEntry::buddyListEntry(const std::string &uri) : mNameResolved = false; mInVivoxBuddies = false; mInSLFriends = false; - mNeedsNameUpdate = false; } void LLVivoxVoiceClient::processBuddyListEntry(const std::string &uri, const std::string &displayName) @@ -6024,11 +6015,7 @@ LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::addBuddy(const std::stri result = new buddyListEntry(uri); result->mDisplayName = displayName; - if(IDFromName(uri, result->mUUID)) - { - // Extracted UUID from name successfully. - } - else + if (!IDFromName(uri, result->mUUID)) { LL_DEBUGS("Voice") << "Couldn't find ID for buddy " << uri << " (\"" << displayName << "\")" << LL_ENDL; } @@ -6328,18 +6315,19 @@ void LLVivoxVoiceClient::notifyFriendObservers() void LLVivoxVoiceClient::lookupName(const LLUUID &id) { - LLAvatarNameCache::get(id, - boost::bind(&LLVivoxVoiceClient::onAvatarNameCache, - this, _1, _2)); + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + mAvatarNameCacheConnection = LLAvatarNameCache::get(id, boost::bind(&LLVivoxVoiceClient::onAvatarNameCache, this, _1, _2)); } void LLVivoxVoiceClient::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) { - // For Vivox, we use the legacy name because I'm uncertain whether or - // not their service can tolerate switching to Username or Display Name - std::string legacy_name = av_name.getLegacyName(); - avatarNameResolved(agent_id, legacy_name); + mAvatarNameCacheConnection.disconnect(); + std::string display_name = av_name.mDisplayName; + avatarNameResolved(agent_id, display_name); } void LLVivoxVoiceClient::avatarNameResolved(const LLUUID &id, const std::string &name) @@ -7401,6 +7389,8 @@ void LLVivoxProtocolParser::EndTag(const char *tag) } else if (!stricmp("Buddy", tag)) { + // NOTE : Vivox does *not* give reliable display name for Buddy tags + // We don't take those very seriously as a result... LLVivoxVoiceClient::getInstance()->processBuddyListEntry(uriString, displayNameString); } else if (!stricmp("BlockRule", tag)) diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index a270c2315..49b2132ac 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -564,7 +564,6 @@ protected: bool mNameResolved; bool mInSLFriends; bool mInVivoxBuddies; - bool mNeedsNameUpdate; }; typedef std::map buddyListMap; @@ -623,6 +622,7 @@ protected: void lookupName(const LLUUID &id); void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); void avatarNameResolved(const LLUUID &id, const std::string &name); + boost::signals2::connection mAvatarNameCacheConnection; ///////////////////////////// // Voice fonts @@ -724,6 +724,8 @@ private: bool mCaptureDeviceDirty; bool mRenderDeviceDirty; + bool mIsInitialized; + bool checkParcelChanged(bool update = false); // This should be called when the code detects we have changed parcels. @@ -1014,3 +1016,4 @@ protected: #endif //LL_VIVOX_VOICE_CLIENT_H + diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index ae4ea1e9d..808d80d59 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -41,6 +41,7 @@ #include "lldir.h" #include "llflexibleobject.h" #include "llfloatertools.h" +#include "llmaterialid.h" #include "llmaterialtable.h" #include "llprimitive.h" #include "llvolume.h" @@ -81,6 +82,7 @@ #include "llviewershadermgr.h" #include "llvoavatar.h" #include "llvocache.h" +#include "llmaterialmgr.h" // [RLVa:KB] - Checked: 2010-04-04 (RLVa-1.2.0d) #include "rlvhandler.h" @@ -1942,6 +1944,62 @@ S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow) return res; } +void LLVOVolume::setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID &pMaterialID, const LLMaterialPtr pMaterialParams, U32 te) +{ + LLVOVolume* pVol = (LLVOVolume*)gObjectList.findObject(objectID); + if (pVol) + { + LL_DEBUGS("MaterialTEs") << "materialid " << pMaterialID.asString() << " to TE " << te << LL_ENDL; + if (te >= pVol->getNumTEs()) + return; + + LLTextureEntry* texture_entry = pVol->getTE(te); + if (texture_entry && (texture_entry->getMaterialID() == pMaterialID)) + { + pVol->setTEMaterialParams(te, pMaterialParams); + } + } +} + +S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) +{ + S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID); + LL_DEBUGS("MaterialTEs") << "te "<< (S32)te << " materialid " << pMaterialID.asString() << " res " << res + << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast(this), te) ? " selected" : " not selected" ) + << LL_ENDL; + + LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL; + if (res) + { + LLMaterialMgr::instance().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallbackTE, getID(), _1, _2, _3)); + + setChanged(ALL_CHANGED); + if (!mDrawable.isNull()) + { + gPipeline.markTextured(mDrawable); + gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); + } + mFaceMappingChanged = TRUE; + } + return res; +} + +S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) +{ + S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams); + LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res + << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast(this), te) ? " selected" : " not selected" ) + << LL_ENDL; + setChanged(ALL_CHANGED); + if (!mDrawable.isNull()) + { + gPipeline.markTextured(mDrawable); + gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); + } + mFaceMappingChanged = TRUE; + return TEM_CHANGE_TEXTURE; +} + S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t) { S32 res = LLViewerObject::setTEScale(te, s, t); @@ -3988,7 +4046,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) || (type == LLRenderPass::PASS_INVISIBLE) || - (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)); + (type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) || + (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) || + (facep->getTextureEntry()->getFullbright()); if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL)) { @@ -4026,6 +4086,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLViewerTexture* tex = facep->getTexture(); U8 index = facep->getTextureIndex(); + + LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID(); bool batchable = false; @@ -4371,66 +4433,104 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLViewerTexture* tex = facep->getTexture(); U32 type = gPipeline.getPoolTypeFromTE(te, tex); - if (type == LLDrawPool::POOL_ALPHA) - { - if (te->getColor().mV[3] > 0.f) - { - if (te->getFullbright()) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); - } - else - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); - } - } - } - else if (te->getShiny()) - { - if (te->getFullbright()) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY); - } - else - { - if (LLPipeline::sRenderDeferred) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); - } - else - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY); - } - } - } - else - { - if (te->getFullbright()) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); - } - else - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); - } - } if (te->getGlow()) { pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); } - if (LLPipeline::sRenderDeferred) + LLMaterial* mat = te->getMaterialParams().get(); + + if (mat) { - if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright()) + bool fullbright = te->getFullbright(); + bool is_alpha = type == LLDrawPool::POOL_ALPHA; + U8 mode = mat->getDiffuseAlphaMode(); + bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE || + mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE; + + if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && te->getColor().mV[3] >= 0.999f) { - if (te->getBumpmap()) + pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE); + } + else if (is_alpha || (te->getColor().mV[3] < 0.999f)) + { + if (te->getColor().mV[3] > 0.f) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); + pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA : LLDrawPoolAvatar::RIGGED_ALPHA); + } + } + else if (gPipeline.canUseVertexShaders() + && LLPipeline::sRenderBump + && te->getShiny() + && can_be_shiny) + { + pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY : LLDrawPoolAvatar::RIGGED_SHINY); + } + else + { + pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE); + } + } + else + { + if (type == LLDrawPool::POOL_ALPHA) + { + if (te->getColor().mV[3] > 0.f) + { + if (te->getFullbright()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); + } + } + } + else if (te->getShiny()) + { + if (te->getFullbright()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY); } else { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); + if (LLPipeline::sRenderDeferred) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY); + } + } + } + else + { + if (te->getFullbright()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + } + } + + + if (LLPipeline::sRenderDeferred) + { + if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright()) + { + if (te->getBumpmap()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); + } } } } @@ -5058,7 +5158,6 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: index_offset += facep->getGeomCount(); indices_index += facep->getIndicesCount(); - //append face to appropriate render batch BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA; @@ -5078,7 +5177,46 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE; - if (is_alpha) + LLMaterial* mat = te->getMaterialParams().get(); + + bool can_be_shiny = true; + if (mat) + { + U8 mode = mat->getDiffuseAlphaMode(); + can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE || + mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE; + } + + bool use_legacy_bump = te->getBumpmap(); + if (mat) + { + U8 mode = mat->getDiffuseAlphaMode(); + if (te->getColor().mV[3] < 0.999f) + { + mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; + } + + if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + { + registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK : LLRenderPass::PASS_ALPHA_MASK); + } + else if (is_alpha || (te->getColor().mV[3] < 0.999f)) + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA); + } + else if (gPipeline.canUseVertexShaders() + && LLPipeline::sRenderBump + && te->getShiny() + && can_be_shiny) + { + registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_SHINY); + } + else + { + registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT : LLRenderPass::PASS_SIMPLE); + } + } + else if (is_alpha) { // can we safely treat this as an alpha mask? if (facep->getFaceColor().mV[3] <= 0.f) @@ -5103,7 +5241,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } else if (gPipeline.canUseVertexShaders() && LLPipeline::sRenderBump - && te->getShiny()) + && te->getShiny() + && can_be_shiny) { //shiny if (tex->getPrimaryFormat() == GL_ALPHA) { //invisiprim+shiny @@ -5120,7 +5259,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); } } - else if (te->getBumpmap()) + else if (use_legacy_bump) { //register in deferred bump pass registerFace(group, facep, LLRenderPass::PASS_BUMP); } @@ -5147,25 +5286,40 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } else if (fullbright || bake_sunlight) { //fullbright - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); - if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && te->getBumpmap()) + if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); + } + else + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); + } + if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && use_legacy_bump) { //if this is the deferred render and a bump map is present, register in post deferred bump registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); } } else { - if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getBumpmap()) + if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && use_legacy_bump) { //non-shiny or fullbright deferred bump registerFace(group, facep, LLRenderPass::PASS_BUMP); } else { //all around simple llassert(mask & LLVertexBuffer::MAP_NORMAL); - registerFace(group, facep, LLRenderPass::PASS_SIMPLE); + if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + { //material alpha mask can be respected in non-deferred + registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK); + } + else + { + registerFace(group, facep, LLRenderPass::PASS_SIMPLE); + } } } + if (!gPipeline.canUseVertexShaders() && !is_alpha && te->getShiny() && @@ -5181,7 +5335,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright); facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE); - if (!force_simple && te->getBumpmap() && LLPipeline::sRenderBump) + if (!force_simple && LLPipeline::sRenderBump && use_legacy_bump) { registerFace(group, facep, LLRenderPass::PASS_BUMP); } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 86ebdf584..029096ef6 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -44,6 +44,7 @@ class LLViewerTextureAnim; class LLDrawPool; +class LLMaterialID; class LLSelectNode; class LLObjectMediaDataClient; class LLObjectMediaNavigateClient; @@ -191,6 +192,11 @@ public: /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump); /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags); /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow); + /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); + + static void setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te); + + /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams); /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t); /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s); /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 3bdb3ed59..5c8c8f4a8 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -293,6 +293,7 @@ void LLWorld::removeRegion(const LLHost &host) mCulledRegionList.remove(regionp); mVisibleRegionList.remove(regionp); + mRegionRemovedSignal(regionp); //double check all objects of this region are removed. gObjectList.clearAllMapObjectsInRegion(regionp) ; //llassert_always(!gObjectList.hasMapObjectInRegion(regionp)) ; @@ -420,6 +421,19 @@ LLViewerRegion* LLWorld::getRegionFromHandle(const U64 &handle) return NULL; } +LLViewerRegion* LLWorld::getRegionFromID(const LLUUID& region_id) +{ + for (region_list_t::iterator iter = mRegionList.begin(); + iter != mRegionList.end(); ++iter) + { + LLViewerRegion* regionp = *iter; + if (regionp->getRegionID() == region_id) + { + return regionp; + } + } + return NULL; +} void LLWorld::updateAgentOffset(const LLVector3d &offset_global) { @@ -1506,6 +1520,11 @@ bool LLWorld::isRegionListed(const LLViewerRegion* region) const return it != mRegionList.end(); } +boost::signals2::connection LLWorld::setRegionRemovedCallback(const region_remove_signal_t::slot_type& cb) +{ + return mRegionRemovedSignal.connect(cb); +} + LLHTTPRegistration gHTTPRegistrationEstablishAgentCommunication( "/message/EstablishAgentCommunication"); diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index a9b3f3b53..8cdaeae4e 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -82,6 +82,7 @@ public: LLViewerRegion* getRegionFromPosGlobal(const LLVector3d &pos); LLViewerRegion* getRegionFromPosAgent(const LLVector3 &pos); LLViewerRegion* getRegionFromHandle(const U64 &handle); + LLViewerRegion* getRegionFromID(const LLUUID& region_id); BOOL positionRegionValidGlobal(const LLVector3d& pos); // true if position is in valid region LLVector3d clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos); @@ -157,6 +158,8 @@ public: typedef std::list region_list_t; const region_list_t& getRegionList() const { return mActiveRegionList; } + typedef boost::signals2::signal region_remove_signal_t; + boost::signals2::connection setRegionRemovedCallback(const region_remove_signal_t::slot_type& cb); // Returns lists of avatar IDs and their world-space positions within a given distance of a point. // All arguments are optional. Given containers will be emptied and then filled. // Not supplying origin or radius input returns data on all avatars in the known regions. @@ -176,6 +179,8 @@ private: region_list_t mVisibleRegionList; region_list_t mCulledRegionList; + region_remove_signal_t mRegionRemovedSignal; + // Number of points on edge static const U32 mWidth; diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 3492d44ed..66c395bd6 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -67,14 +67,14 @@ #include "llappviewer.h" // Only for constants! #include "lltrans.h" -#include "llglheaders.h" - #include "hippogridmanager.h" -// [RLVa:KB] +// [RLVa:KB] - Checked: 2010-04-19 (RLVa-1.2.0f) #include "rlvhandler.h" // [/RLVa:KB] +#include "llglheaders.h" + // Basically a C++ implementation of the OCEAN_COLOR defined in mapstitcher.py // Please ensure consistency between those 2 files (TODO: would be better to get that color from an asset source...) // # Constants @@ -499,19 +499,7 @@ void LLWorldMapView::draw() { LLFontGL* font = LLFontGL::getFontSansSerifSmall(); std::string mesg; - - //mesg = llformat("%d / %s (%s)", - // info->mAgents, - // info->mName.c_str(), - // LLViewerRegion::accessToShortString(info->mAccess).c_str() ); - // [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-04 (RLVa-1.0.0a) - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) - { - if(!info->getName().empty()) - mesg = RlvStrings::getString(RLV_STRING_HIDDEN); - } - // [/RLVa:KB] - else if (info->isDown()) + if (info->isDown()) { if(info->getName().empty()) mesg = llformat( "(%s)", sStringsMap["offline"].c_str()); @@ -521,6 +509,10 @@ void LLWorldMapView::draw() else if(!info->getName().empty()) // Online sims should have names... { mesg = info->getName(); + + static const LLCachedControl show_avs("LiruMapShowAvCount"); + if (show_avs) mesg += llformat(" (%d)", info->getAgentCount()); + U8 access = info->getAccess(); switch(access) { @@ -541,7 +533,10 @@ void LLWorldMapView::draw() break; } } - if (!mesg.empty()) +// if (!mesg.empty()) +// [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5 + if ( (!mesg.empty()) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) +// [/RLVa:KB] { font->renderUTF8( mesg, 0, @@ -1375,7 +1370,7 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4& text_y = llclamp(text_y + vert_offset, TEXT_PADDING + vert_offset, getRect().getHeight() - llround(font->getLineHeight()) - TEXT_PADDING - vert_offset); //if (label != "") -// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-1.0.0a +// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.4.5) | Added: RLVa-1.0.0 if ( (label != "") && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) // [/RLVa:KB] { @@ -1436,12 +1431,12 @@ BOOL LLWorldMapView::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* stic { LLViewerRegion *region = gAgent.getRegion(); -// std::string message = llformat("%s (%s)", info->getName().c_str(), info->getAccessString().c_str()); -// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-04 (RLVa-1.0.0a) +// [RLVa:KB] - Checked: 2010-04-19 (RLVa-1.4.5) | Modified: RLVa-1.4.5 std::string message = llformat("%s (%s)", - (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? info->getName().c_str() : RlvStrings::getString(RLV_STRING_HIDDEN).c_str(), + (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? info->getName().c_str() : RlvStrings::getString(RLV_STRING_HIDDEN_REGION).c_str(), info->getAccessString().c_str()); // [/RLVa:KB] +// std::string message = llformat("%s (%s)", info->getName().c_str(), info->getAccessString().c_str()); if (!info->isDown()) { diff --git a/indra/newview/skins/Retro.xml b/indra/newview/skins/Retro.xml new file mode 100644 index 000000000..e1be2c211 --- /dev/null +++ b/indra/newview/skins/Retro.xml @@ -0,0 +1,14 @@ + + + skin_name + Retro + author_name + Thraxis Epsilon + additional_author_names + Linden Lab + skin_info + The Dazzle skin tweaked to look more Classic-like. + folder_name + Retro + + diff --git a/indra/newview/skins/apollo/keywords.ini b/indra/newview/skins/apollo/keywords.ini index 950a13126..cecc8631a 100644 --- a/indra/newview/skins/apollo/keywords.ini +++ b/indra/newview/skins/apollo/keywords.ini @@ -99,7 +99,9 @@ PERMISSION_CHANGE_LINKS Passed to llRequestPermissions library function to req PERMISSION_TRACK_CAMERA Passed to llRequestPermissions library function to request permission to track agent's camera PERMISSION_CONTROL_CAMERA Passed to llRequestPermissions library function to request permission to change agent's camera PERMISSION_TELEPORT Passed to llRequestPermissions library function to request permission to teleport agent -PERMISSION_OVERRIDE_ANIMATIONS Passed to llRequestPermissions library function to request permission to override agent's animations +SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT Passed to llRequestPermissions library function to request permission to silently modify estate access lists +PERMISSION_OVERRIDE_ANIMATIONS Passed to llRequestPermissions library function to request permission to override animations on agent +PERMISSION_RETURN_OBJECTS Passed to llRequestPermissions library function to request permission to return objects DEBUG_CHANNEL Chat channel reserved for debug and error messages from scripts PUBLIC_CHANNEL Chat channel that broadcasts to all nearby users @@ -132,6 +134,11 @@ PSYS_PART_END_ALPHA PSYS_PART_END_SCALE PSYS_PART_MAX_AGE +PSYS_PART_BLEND_FUNC_SOURCE +PSYS_PART_BLEND_FUNC_DEST +PSYS_PART_START_GLOW +PSYS_PART_END_GLOW + PSYS_PART_BOUNCE_MASK PSYS_PART_WIND_MASK PSYS_PART_INTERP_COLOR_MASK @@ -141,6 +148,16 @@ PSYS_PART_FOLLOW_VELOCITY_MASK PSYS_PART_TARGET_POS_MASK PSYS_PART_EMISSIVE_MASK PSYS_PART_TARGET_LINEAR_MASK +PSYS_PART_RIBBON_MASK + +PSYS_PART_BF_ONE +PSYS_PART_BF_ZERO +PSYS_PART_BF_DEST_COLOR +PSYS_PART_BF_SOURCE_COLOR +PSYS_PART_BF_ONE_MINUS_DEST_COLOR +PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR +PSYS_PART_BF_SOURCE_ALPHA +PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA PSYS_SRC_PATTERN PSYS_SRC_INNERANGLE Deprecated -- Use PSYS_SRC_ANGLE_BEGIN @@ -182,6 +199,13 @@ OBJECT_SERVER_COST Used with llGetObjectDetails to get the server cost. OBJECT_STREAMING_COST Used with llGetObjectDetails to get the streaming (download) cost. OBJECT_PHYSICS_COST Used with llGetObjectDetails to get the physics cost. OBJECT_PATHFINDING_TYPE Used with llGetObjectDetails to get an object's pathfinding settings. +OBJECT_CHARACTER_TIME Used with llGetObjectDetails to get an object's average CPU time (in seconds) used by the object for navigation, if the object is a pathfinding character. Returns 0 for non-characters. +OBJECT_ROOT Used with llGetObjectDetails to get an object's root prim ID. +OBJECT_ATTACHED_POINT Used with llGetObjectDetails to get an object's attachment point. +OBJECT_RETURN_PARCEL Used with llReturnObjectsByOwner to return all objects on the same parcel as the script which are owned by 'owner'. +OBJECT_RETURN_PARCEL_OWNER Used with llReturnObjectsByOwner to return all objects owned by 'owner' which are over parcels owned by the owner of the script. +OBJECT_RETURN_REGION Used with llReturnObjectsByOwner to return all objects in the region owned by 'owner' - only works when the script is owned by the estate owner or an estate manager. + OPT_UNKNOWN Returned object pathfinding type by llGetObjectDetails for attachments, Linden trees and grass. OPT_LEGACY_LINKSET Returned object pathfinding type by llGetObjectDetails for movable obstacles, movable phantoms, physical, and volumedetect objects. OPT_AVATAR Returned object pathfinding type by llGetObjectDetails for avatars. @@ -675,6 +699,7 @@ REQUIRE_LINE_OF_SIGHT Used with llPursue(). Define whether the character needs PURSUIT_FUZZ_FACTOR Used with llPursue(). Selects a random destination near the PURSUIT_OFFSET. The valid fuzz factor range is from 0 to 1, where 1 is most random. This option requires a nonzero PURSUIT_OFFSET. PURSUIT_INTERCEPT Used with llPursue(). Define whether the character attempts to predict the target's future location. PURSUIT_GOAL_TOLERANCE Used with llPursue(). Defines approximately how close the character must be to the current goal to consider itself to be at the desired position. The valid range is from 0.25 to 10m. +FORCE_DIRECT_PATH Used with llNavigateTo(). Makes character navigate in a straight line toward pos. May be set to TRUE or FALSE. VERTICAL Constant to indicate that the orientation of the capsule for a Pathfinding character is vertical. HORIZONTAL Constant to indicate that the orientation of the capsule for a Pathfinding character is horizontal. AVOID_CHARACTERS TODO: add documentation @@ -715,10 +740,37 @@ CHARACTER_TURN_SPEED_MULTIPLIER TODO: add documentation CHARACTER_DESIRED_TURN_SPEED The character's maximum speed while turning--note that this is only loosely enforced (i.e., a character may turn at higher speeds under certain conditions) CHARACTER_MAX_TURN_RADIUS The character's turn radius when traveling at CHARACTER_DESIRED_TURN_SPEED. CHARACTER_MAX_SPEED The character's maximum speed. Affects speed when avoiding dynamic obstacles and when traversing low-walkability objects in TRAVERSAL_TYPE_FAST mode. +CHARACTER_STAY_WITHIN_PARCEL Characters which have CHARACTER_STAY_WITHIN_PARCEL set to TRUE treat the parcel boundaries as one-way obstacles. PATROL_PAUSE_AT_WAYPOINTS Used with llPatrolPoints(). Defines if characters slow down and momentarily pause at each waypoint. WANDER_PAUSE_AT_WAYPOINTS Used with llWanderWithin(). Defines if characters should pause after reaching each wander waypoint. +CONTENT_TYPE_TEXT text/plain +CONTENT_TYPE_HTML text/html +CONTENT_TYPE_XML application/xml +CONTENT_TYPE_XHTML application/xhtml+xml +CONTENT_TYPE_ATOM application/atom+xml +CONTENT_TYPE_JSON application/json +CONTENT_TYPE_LLSD application/llsd+xml +CONTENT_TYPE_FORM application/x-www-form-urlencoded +CONTENT_TYPE_RSS application/rss+xml + +JSON_INVALID Returned by llJsonGetValue and llJsonValueType if the specifiers to do specify a valid in the json value. +JSON_OBJECT Represents a json datatype represented in LSL as a strided list of name/value pairs +JSON_ARRAY Represents a json datatype mappable to the LSL datatype "list" +JSON_NUMBER Represents a json datatype mappable to the LSL datatypes "integer" and "float" +JSON_STRING Represents a json datatype mappable to the LSL datatype "string" +JSON_TRUE Represents the constant "true" of a json value. +JSON_FALSE Represents the constant "false" of a json value. +JSON_NULL Represents the constant "null" of a json value. +JSON_APPEND Used with llJsonSetValue as a specifier to indicate appending the value to the end of the array at that level. + +ERR_GENERIC Returned by llReturnObjectsByID and llReturnObjectsByOwner in case of a general error. +ERR_PARCEL_PERMISSIONS Returned by llReturnObjectsByID and llReturnObjectsByOwner in case of a parcel owner permission error. +ERR_MALFORMED_PARAMS Returned by llReturnObjectsByID and llReturnObjectsByOwner in case of malformed parameters. +ERR_RUNTIME_PERMISSIONS Returned by llReturnObjectsByID and llReturnObjectsByOwner in case of a runtime permission error. +ERR_THROTTLED Returned by llReturnObjectsByID and llReturnObjectsByOwner in case of being throttled. + # --- OpenSim and Aurora-Sim constants Below --- # OpenSim Constants (\OpenSim\Region\ScriptEngine\Shared\Api\Runtime\LSL_Constants.cs) # Constants for cmWindlight (\OpenSim\Region\ScriptEngine\Shared\Api\Runtime\CM_Constants.cs) @@ -885,7 +937,7 @@ return Leave current function or event handler # Comment [one_sided_delimiter .457, .441, .367] // Comment:Non-functional commentary or disabled code -[two_sided_delimiter_esc .457, .441, .367] +[two_sided_delimiter .457, .441, .367] /* */ Comment:Non-functional commentary or disabled code # String literals diff --git a/indra/newview/skins/default/textures/menu_separator.png b/indra/newview/skins/default/textures/menu_separator.png new file mode 100644 index 000000000..89dcdcdff Binary files /dev/null and b/indra/newview/skins/default/textures/menu_separator.png differ diff --git a/indra/newview/skins/default/xui/de/floater_chat_history.xml b/indra/newview/skins/default/xui/de/floater_chat_history.xml index f369f9dcb..3bc3c630a 100644 --- a/indra/newview/skins/default/xui/de/floater_chat_history.xml +++ b/indra/newview/skins/default/xui/de/floater_chat_history.xml @@ -7,21 +7,6 @@ icn_voice-localchat.tga -- Instant-Message-Protokoll aktiviert -- -- Ende des Protokolls -- - Dem Objekt „[OBJECTNAME]“, ein Objekt von „[OWNERNAME]“, in [REGIONNAME] [REGIONPOS], wurde folgende Berechtigung erteilt: [PERMISSIONS]. - Dem Objekt „[OBJECTNAME]“, ein Objekt von „[OWNERNAME]“, in [REGIONNAME] [REGIONPOS], wurde folgende Berechtigung verweigert: [PERMISSIONS]. - Linden-Dollar (L$) von Ihnen nehmen - Steuerung festlegen - Steuerung neu zuweisen - Avatar animieren - An Avatar anhängen - Eigentum aufgeben und öffentlich machen - Mit Objekten verknüpfen und davon trennen - Verbindungen zu anderen Objekten hinzufügen und entfernen - Berechtigungen ändern - Kameraverfolgung aktivieren - Avatar teleportieren - Kamerasteuerung übernehmen - Überschreibe die Standard-Animationen diff --git a/indra/newview/skins/default/xui/de/floater_choose_group.xml b/indra/newview/skins/default/xui/de/floater_choose_group.xml index 0c6ae13f4..4dd2947a5 100644 --- a/indra/newview/skins/default/xui/de/floater_choose_group.xml +++ b/indra/newview/skins/default/xui/de/floater_choose_group.xml @@ -4,5 +4,4 @@ + mouse_opaque="true" name="check_all" scale_image="true" width="100" > + + + name="next_owner_copy" control_name="BulkChangeNextOwnerCopy" > + + + mouse_opaque="true" font="SansSerif" scale_image="true" halign="center" > + + Selection contains no editable contents. Setting permissions on [NAME] diff --git a/indra/newview/skins/default/xui/en-us/floater_chat_history.xml b/indra/newview/skins/default/xui/en-us/floater_chat_history.xml index 08f266608..83dbd7255 100644 --- a/indra/newview/skins/default/xui/en-us/floater_chat_history.xml +++ b/indra/newview/skins/default/xui/en-us/floater_chat_history.xml @@ -8,21 +8,6 @@ icn_voice-localchat.tga -- Instant message logging enabled -- -- End of Log -- - '[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS]. - '[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS]. - Take in-world money ([CURRENCY]) from you - Act on your control inputs - Remap your control inputs - Animate your avatar - Attach to your avatar - Release ownership and become public - Link and delink from other objects - Add and remove joints with other objects - Change its permissions - Track your camera - Teleport you - Control your camera - Override your default animations diff --git a/indra/newview/skins/default/xui/en-us/floater_choose_group.xml b/indra/newview/skins/default/xui/en-us/floater_choose_group.xml index f4382629a..02001e937 100644 --- a/indra/newview/skins/default/xui/en-us/floater_choose_group.xml +++ b/indra/newview/skins/default/xui/en-us/floater_choose_group.xml @@ -18,7 +18,4 @@ @@ -25,55 +31,97 @@ + max_length="63" mouse_opaque="true" name="region name" width="208"> + + + width="180"> + + + width="180"> + + + width="180"> + + + tool_tip="Set this to make the region visible to non-gods." width="180"> + + + width="180"> + + + tool_tip="Set this to make the region not compute traffic." width="180"> + + + tool_tip="Set this to disallow people terraforming their land" width="180"> + + - - + width="180"> + + + + + + + + + max_length="10" mouse_opaque="true" name="estate" width="50"> + + + tool_tip="This is the parent estate for this region" width="50"> + + + tool_tip="This is the grid x position for this region" width="50"> + + + tool_tip="This is the grid y position for this region" width="40"> + + + max_length="10" mouse_opaque="true" name="redirectx" width="50"> + + + max_length="10" mouse_opaque="true" name="redirecty" width="40"> + + + mouse_opaque="true" name="billable factor" width="80"> + + + name="land cost" width="80"> + + + tool_tip="Click here to refresh the above information." width="110"> + + @@ -175,24 +259,39 @@ + tool_tip="Set this to disable all scripts in this region" width="110"> + + + width="121"> + + + tool_tip="Set this to disable all physics in this region" width="130"> + + + width="380"> + + @@ -285,7 +402,10 @@ max_length="63" mouse_opaque="true" name="parameter" width="290" /> diff --git a/indra/newview/skins/default/xui/en-us/floater_inspect.xml b/indra/newview/skins/default/xui/en-us/floater_inspect.xml index 5999dd549..e10b2fe06 100644 --- a/indra/newview/skins/default/xui/en-us/floater_inspect.xml +++ b/indra/newview/skins/default/xui/en-us/floater_inspect.xml @@ -16,14 +16,22 @@ + diff --git a/indra/newview/skins/default/xui/en-us/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/en-us/floater_inventory_item_properties.xml index 91381a2c1..53ffa4342 100644 --- a/indra/newview/skins/default/xui/en-us/floater_inventory_item_properties.xml +++ b/indra/newview/skins/default/xui/en-us/floater_inventory_item_properties.xml @@ -1,74 +1,89 @@ Name: - Description: - Creator: Nicole Linden - + diff --git a/indra/newview/skins/default/xui/en-us/floater_radar.xml b/indra/newview/skins/default/xui/en-us/floater_radar.xml index 2f55b644a..568c9e884 100644 --- a/indra/newview/skins/default/xui/en-us/floater_radar.xml +++ b/indra/newview/skins/default/xui/en-us/floater_radar.xml @@ -361,6 +361,7 @@ + Out Of Range Moving Playing a gesture Playing a sound diff --git a/indra/newview/skins/default/xui/en-us/floater_settings_debug.xml b/indra/newview/skins/default/xui/en-us/floater_settings_debug.xml index 32487a53d..1f6f81634 100644 --- a/indra/newview/skins/default/xui/en-us/floater_settings_debug.xml +++ b/indra/newview/skins/default/xui/en-us/floater_settings_debug.xml @@ -2,8 +2,12 @@ - - + + + + + + False + - + + + + name="val_color_swatch" visible="false" width="37"> + + + name="val_spinner_1" visible="false" width="120"> + + + max_val="10000000" name="val_spinner_2" visible="false" width="120"> + + + max_val="10000000" name="val_spinner_3" visible="false" width="120"> + + + max_val="10000000" name="val_spinner_4" visible="false" width="120"> + + diff --git a/indra/newview/skins/default/xui/en-us/floater_top_objects.xml b/indra/newview/skins/default/xui/en-us/floater_top_objects.xml index 6b59ee391..ec4f7d736 100644 --- a/indra/newview/skins/default/xui/en-us/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/en-us/floater_top_objects.xml @@ -1,90 +1,299 @@ - - - Loading... - - - - - - - - - - - - Object ID: - - - + + Object name: + + + + + Owner: + + + + + Parcel: + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en-us/menu_pie_attachment.xml b/indra/newview/skins/default/xui/en-us/menu_pie_attachment.xml index 25ad9f023..03b0b0fdf 100644 --- a/indra/newview/skins/default/xui/en-us/menu_pie_attachment.xml +++ b/indra/newview/skins/default/xui/en-us/menu_pie_attachment.xml @@ -67,6 +67,14 @@ + + + + + + + + diff --git a/indra/newview/skins/default/xui/en-us/menu_pie_object.xml b/indra/newview/skins/default/xui/en-us/menu_pie_object.xml index a3015ed48..940729207 100644 --- a/indra/newview/skins/default/xui/en-us/menu_pie_object.xml +++ b/indra/newview/skins/default/xui/en-us/menu_pie_object.xml @@ -60,20 +60,21 @@ + + + + + + + + + + + + - - - - - diff --git a/indra/newview/skins/default/xui/en-us/menu_pie_self.xml b/indra/newview/skins/default/xui/en-us/menu_pie_self.xml index d787e16e0..9b35ae1f3 100644 --- a/indra/newview/skins/default/xui/en-us/menu_pie_self.xml +++ b/indra/newview/skins/default/xui/en-us/menu_pie_self.xml @@ -107,6 +107,9 @@ + + + diff --git a/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/indra/newview/skins/default/xui/en-us/menu_viewer.xml index 7134b4d2e..b55483aab 100644 --- a/indra/newview/skins/default/xui/en-us/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en-us/menu_viewer.xml @@ -740,7 +740,7 @@ + mouse_opaque="true" name="Edit Linked Parts" shortcut="control|shift|E"> @@ -893,10 +893,10 @@ - - + diff --git a/indra/newview/skins/default/xui/en-us/notifications.xml b/indra/newview/skins/default/xui/en-us/notifications.xml index 6cc8735e9..5445fc06f 100644 --- a/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/indra/newview/skins/default/xui/en-us/notifications.xml @@ -6791,6 +6791,7 @@ An object named [OBJECTFROMNAME] owned by (an unknown user) has given you a [OBJ index="2" name="Ignore" text="Ignore"/> +