diff options
Diffstat (limited to 'indra')
199 files changed, 4235 insertions, 2682 deletions
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index 66c8bcac6a..78aa6f4f37 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -80,27 +80,27 @@ LLAssetDictionary::LLAssetDictionary() { // DESCRIPTION TYPE NAME HUMAN NAME CATEGORY NAME DRAG&DROP CAN LINK? PROTECTED? // |--------------------|-----------|-------------------|-------------------|---------------|-----------|-----------| - addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", "Textures", DAD_TEXTURE, FALSE, TRUE)); - addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", "Sounds", DAD_SOUND, FALSE, TRUE)); - addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", "Calling Cards", DAD_CALLINGCARD, FALSE, TRUE)); - addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", "Landmarks", DAD_LANDMARK, FALSE, TRUE)); - addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", "Scripts", DAD_NONE, FALSE, TRUE)); + addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", "Textures", DAD_TEXTURE, TRUE, TRUE)); + addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", "Sounds", DAD_SOUND, TRUE, TRUE)); + addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", "Calling Cards", DAD_CALLINGCARD, TRUE, TRUE)); + addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", "Landmarks", DAD_LANDMARK, TRUE, TRUE)); + addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", "Scripts", DAD_NONE, TRUE, TRUE)); addEntry(LLAssetType::AT_CLOTHING, new AssetEntry("CLOTHING", "clothing", "clothing", "Clothing", DAD_CLOTHING, TRUE, TRUE)); addEntry(LLAssetType::AT_OBJECT, new AssetEntry("OBJECT", "object", "object", "Objects", DAD_OBJECT, TRUE, TRUE)); - addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", "Notecards", DAD_NOTECARD, FALSE, TRUE)); + addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", "Notecards", DAD_NOTECARD, TRUE, TRUE)); addEntry(LLAssetType::AT_CATEGORY, new AssetEntry("CATEGORY", "category", "folder", "New Folder", DAD_CATEGORY, TRUE, TRUE)); addEntry(LLAssetType::AT_ROOT_CATEGORY, new AssetEntry("ROOT_CATEGORY", "root", "root", "Inventory", DAD_ROOT_CATEGORY, TRUE, TRUE)); - addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", "Scripts", DAD_SCRIPT, FALSE, TRUE)); - addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", "Scripts", DAD_NONE, FALSE, TRUE)); - addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", "Uncompressed Images", DAD_NONE, FALSE, TRUE)); + addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", "Scripts", DAD_SCRIPT, TRUE, TRUE)); + addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", "Scripts", DAD_NONE, TRUE, TRUE)); + addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", "Uncompressed Images", DAD_NONE, TRUE, TRUE)); addEntry(LLAssetType::AT_BODYPART, new AssetEntry("BODYPART", "bodypart", "body part", "Body Parts", DAD_BODYPART, TRUE, TRUE)); addEntry(LLAssetType::AT_TRASH, new AssetEntry("TRASH", "trash", "trash", "Trash", DAD_NONE, FALSE, TRUE)); addEntry(LLAssetType::AT_SNAPSHOT_CATEGORY, new AssetEntry("SNAPSHOT_CATEGORY", "snapshot", "snapshot", "Photo Album", DAD_NONE, FALSE, TRUE)); addEntry(LLAssetType::AT_LOST_AND_FOUND, new AssetEntry("LOST_AND_FOUND", "lstndfnd", "lost and found", "Lost And Found", DAD_NONE, FALSE, TRUE)); - addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", "Uncompressed SoundS", DAD_NONE, FALSE, TRUE)); - addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", "Uncompressed Images", DAD_NONE, FALSE, TRUE)); - addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", "Uncompressed Images", DAD_NONE, FALSE, TRUE)); - addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", "Animations", DAD_ANIMATION, FALSE, TRUE)); + addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", "Uncompressed SoundS", DAD_NONE, TRUE, TRUE)); + addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", "Uncompressed Images", DAD_NONE, TRUE, TRUE)); + addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", "Uncompressed Images", DAD_NONE, TRUE, TRUE)); + addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", "Animations", DAD_ANIMATION, TRUE, TRUE)); addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", "Gestures", DAD_GESTURE, TRUE, TRUE)); addEntry(LLAssetType::AT_SIMSTATE, new AssetEntry("SIMSTATE", "simstate", "simstate", "New Folder", DAD_NONE, FALSE, TRUE)); addEntry(LLAssetType::AT_FAVORITE, new AssetEntry("FAVORITE", "favorite", "favorite", "favorite", DAD_NONE, FALSE, TRUE)); diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp index 41150ad057..7c0ac6c554 100644 --- a/indra/llcommon/lldate.cpp +++ b/indra/llcommon/lldate.cpp @@ -155,6 +155,37 @@ void LLDate::toStream(std::ostream& s) const s << 'Z'; } +bool LLDate::split(S32 *year, S32 *month, S32 *day, S32 *hour, S32 *min, S32 *sec) const +{ + apr_time_t time = (apr_time_t)(mSecondsSinceEpoch * LL_APR_USEC_PER_SEC); + + apr_time_exp_t exp_time; + if (apr_time_exp_gmt(&exp_time, time) != APR_SUCCESS) + { + return false; + } + + if (year) + *year = exp_time.tm_year + 1900; + + if (month) + *month = exp_time.tm_mon + 1; + + if (day) + *day = exp_time.tm_mday; + + if (hour) + *hour = exp_time.tm_hour; + + if (min) + *min = exp_time.tm_min; + + if (sec) + *sec = exp_time.tm_sec; + + return true; +} + bool LLDate::fromString(const std::string& iso8601_date) { std::istringstream stream(iso8601_date); diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h index 9dcce9117f..38c4c8cb60 100644 --- a/indra/llcommon/lldate.h +++ b/indra/llcommon/lldate.h @@ -84,6 +84,7 @@ public: std::string asString() const; std::string asRFC1123() const; void toStream(std::ostream&) const; + bool split(S32 *year, S32 *month = NULL, S32 *day = NULL, S32 *hour = NULL, S32 *min = NULL, S32 *sec = NULL) const; std::string toHTTPDateString (std::string fmt) const; static std::string toHTTPDateString (tm * gmt, std::string fmt); /** diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 78e835dc95..8052da2450 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -968,8 +968,13 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token, // special case to handle timezone if (code == "%Z") { - if (param == "utc") replacement = "GMT"; - else if (param != "local") replacement = LLStringOps::getDaylightSavings()? "PDT" : "PST"; + if (param == "utc") + replacement = "GMT"; + else if (param == "slt") + replacement = "SLT"; + else if (param != "local") // *TODO Vadim: not local? then what? + replacement = LLStringOps::getDaylightSavings() ? "PDT" : "PST"; + return true; } replacement = datetime->toHTTPDateString(code); diff --git a/indra/llrender/llfontbitmapcache.cpp b/indra/llrender/llfontbitmapcache.cpp index 052510e6ed..f01878642a 100644 --- a/indra/llrender/llfontbitmapcache.cpp +++ b/indra/llrender/llfontbitmapcache.cpp @@ -37,13 +37,13 @@ LLFontBitmapCache::LLFontBitmapCache(): mNumComponents(0), - mMaxCharWidth(0), - mMaxCharHeight(0), mBitmapWidth(0), mBitmapHeight(0), + mBitmapNum(-1), + mMaxCharWidth(0), + mMaxCharHeight(0), mCurrentOffsetX(1), - mCurrentOffsetY(1), - mCurrentBitmapNum(-1) + mCurrentOffsetY(1) { } @@ -160,10 +160,10 @@ void LLFontBitmapCache::reset() mImageRawVec.clear(); mImageGLVec.clear(); - mBitmapWidth = 0, - mBitmapHeight = 0, - mCurrentOffsetX = 0, - mCurrentOffsetY = 0, - mCurrentBitmapNum = -1; + mBitmapWidth = 0; + mBitmapHeight = 0; + mBitmapNum = -1; + mCurrentOffsetX = 1; + mCurrentOffsetY = 1; } diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h index 4a57052b91..b044ba2b16 100644 --- a/indra/llrender/llfontbitmapcache.h +++ b/indra/llrender/llfontbitmapcache.h @@ -71,7 +71,6 @@ private: S32 mMaxCharHeight; S32 mCurrentOffsetX; S32 mCurrentOffsetY; - S32 mCurrentBitmapNum; std::vector<LLPointer<LLImageRaw> > mImageRawVec; std::vector<LLPointer<LLImageGL> > mImageGLVec; }; diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 0be6bedbee..44e997340e 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -533,6 +533,7 @@ void LLFontFreetype::renderGlyph(U32 glyph_index) const void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi) { + resetBitmapCache(); if (!mIsFallback) { // This is the head of the list - need to rebuild ourself and all fallbacks. @@ -552,7 +553,6 @@ void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi) } } } - resetBitmapCache(); } void LLFontFreetype::resetBitmapCache() @@ -568,7 +568,7 @@ void LLFontFreetype::resetBitmapCache() } mFontBitmapCachep->reset(); - // Add the empty glyph`5 + // Add the empty glyph addGlyph(0, 0); } diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index 0520ef2cd6..5adaab3a88 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -188,193 +188,3 @@ private: }; #endif // LL_FONTFREETYPE_H -/** - * @file llfontfreetype.h - * @brief Font library wrapper - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLFONTFREETYPE_H -#define LL_LLFONTFREETYPE_H - -#include <map> -#include "llpointer.h" -#include "llstl.h" - -#include "llimagegl.h" -#include "llfontbitmapcache.h" - -// Hack. FT_Face is just a typedef for a pointer to a struct, -// but there's no simple forward declarations file for FreeType, -// and the main include file is 200K. -// We'll forward declare the struct here. JC -struct FT_FaceRec_; -typedef struct FT_FaceRec_* LLFT_Face; - -class LLFontManager -{ -public: - static void initClass(); - static void cleanupClass(); - -private: - LLFontManager(); - ~LLFontManager(); -}; - -class LLFontGlyphInfo -{ -public: - LLFontGlyphInfo(U32 index); - - U32 mGlyphIndex; - - // Metrics - S32 mWidth; // In pixels - S32 mHeight; // In pixels - F32 mXAdvance; // In pixels - F32 mYAdvance; // In pixels - BOOL mMetricsValid; // We have up-to-date metrics for this glyph - - // Information for actually rendering - BOOL mIsRendered; // We actually have rendered this glyph - S32 mXBitmapOffset; // Offset to the origin in the bitmap - S32 mYBitmapOffset; // Offset to the origin in the bitmap - S32 mXBearing; // Distance from baseline to left in pixels - S32 mYBearing; // Distance from baseline to top in pixels - S32 mBitmapNum; // Which bitmap in the bitmap cache contains this glyph -}; - -extern LLFontManager *gFontManagerp; - -class LLFontFreetype : public LLRefCount -{ -public: - LLFontFreetype(); - ~LLFontFreetype(); - - // is_fallback should be true for fallback fonts that aren't used - // to render directly (Unicode backup, primarily) - BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback); - - typedef std::vector<LLPointer<LLFontFreetype> > font_vector_t; - - void setFallbackFonts(const font_vector_t &font); - const font_vector_t &getFallbackFonts() const; - - // Global font metrics - in units of pixels - F32 getLineHeight() const; - F32 getAscenderHeight() const; - F32 getDescenderHeight() const; - - -// For a lowercase "g": -// -// ------------------------------ -// ^ ^ -// | | -// xxx x |Ascender -// x x v | -// --------- xxxx-------------- Baseline -// ^ x | -// | Descender x | -// v xxxx |LineHeight -// ----------------------- | -// v -// ------------------------------ - - enum - { - FIRST_CHAR = 32, - NUM_CHARS = 127 - 32, - LAST_CHAR_BASIC = 127, - - // Need full 8-bit ascii range for spanish - NUM_CHARS_FULL = 255 - 32, - LAST_CHAR_FULL = 255 - }; - - F32 getXAdvance(llwchar wc) const; - F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters - - BOOL hasGlyph(llwchar wch) const; // Has a glyph for this character - BOOL addChar(llwchar wch) const; // Add a new character to the font if necessary - BOOL addGlyph(llwchar wch, U32 glyph_index) const; // Add a new glyph to the existing font - BOOL addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found) - - LLFontGlyphInfo* getGlyphInfo(llwchar wch) const; - - void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const; - void renderGlyph(U32 glyph_index) const; - - void reset(F32 vert_dpi, F32 horz_dpi); - void resetBitmapCache(); - - void destroyGL(); - - BOOL getIsFallback() const; - - const std::string& getName() const; - - F32 getPointSize() const; - - const LLPointer<LLFontBitmapCache> getFontBitmapCache() const; - - void setStyle(U8 style); - U8 getStyle() const; - -private: - void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const; - - std::string mName; - - U8 mStyle; - - F32 mPointSize; - F32 mAscender; - F32 mDescender; - F32 mLineHeight; - - LLFT_Face mFTFace; - - BOOL mIsFallback; - font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars) - - BOOL mValid; - - typedef std::map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t; - mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap - - mutable LLPointer<LLFontBitmapCache> mFontBitmapCachep; - - mutable S32 mRenderGlyphCount; - mutable S32 mAddGlyphCount; -}; - -#endif // LL_FONTFREETYPE_H diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index cc9362a252..fce6b759a4 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -40,6 +40,7 @@ set(llui_SOURCE_FILES lleditmenuhandler.cpp llf32uictrl.cpp llfiltereditor.cpp + llflatlistview.cpp llfloater.cpp llfloaterreg.cpp llflyoutbutton.cpp @@ -122,6 +123,7 @@ set(llui_HEADER_FILES lleditmenuhandler.h llf32uictrl.h llfiltereditor.h + llflatlistview.h llfloater.h llfloaterreg.h llflyoutbutton.h diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp index 29f78f6290..ed15d9d922 100644 --- a/indra/llui/lldockablefloater.cpp +++ b/indra/llui/lldockablefloater.cpp @@ -35,7 +35,7 @@ #include "lldockablefloater.h" //static -LLDockableFloater* LLDockableFloater::instance = NULL; +LLHandle<LLFloater> LLDockableFloater::instanceHandle; LLDockableFloater::LLDockableFloater(LLDockControl* dockControl, const LLSD& key, const Params& params) : @@ -57,21 +57,21 @@ BOOL LLDockableFloater::postBuild() void LLDockableFloater::resetInstance() { - if (instance != this) + if (instanceHandle.get() != this) { - if (instance != NULL && instance->isDocked()) + if (instanceHandle.get() != NULL && instanceHandle.get()->isDocked()) { //closeFloater() is not virtual - if (instance->canClose()) + if (instanceHandle.get()->canClose()) { - instance->closeFloater(); + instanceHandle.get()->closeFloater(); } else { - instance->setVisible(FALSE); + instanceHandle.get()->setVisible(FALSE); } } - instance = this; + instanceHandle = getHandle(); } } diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h index b977888803..1d0e89cef5 100644 --- a/indra/llui/lldockablefloater.h +++ b/indra/llui/lldockablefloater.h @@ -69,7 +69,7 @@ protected: private: std::auto_ptr<LLDockControl> mDockControl; LLUIImagePtr mDockTongue; - static LLDockableFloater* instance; + static LLHandle<LLFloater> instanceHandle; }; #endif /* LL_DOCKABLEFLOATER_H */ diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp index bec7f04cc0..d666f2be56 100644 --- a/indra/llui/lldockcontrol.cpp +++ b/indra/llui/lldockcontrol.cpp @@ -48,12 +48,25 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater, { off(); } + + if (dockWidget != NULL) { + repositionDockable(); + } } LLDockControl::~LLDockControl() { } +void LLDockControl::setDock(LLView* dockWidget) +{ + mDockWidget = dockWidget; + if (mDockWidget != NULL) + { + repositionDockable(); + } +} + void LLDockControl::repositionDockable() { if (mEnabled) @@ -65,11 +78,14 @@ void LLDockControl::repositionDockable() void LLDockControl::calculateDockablePosition() { LLRect dockRect = mDockWidget->calcScreenRect(); - if (mPrevDockRect != dockRect || mRecalculateDocablePosition) + LLRect rootRect = mDockableFloater->getRootView()->getRect(); + + // recalculate dockable position if dock position changed + // or root view rect changed or recalculation is forced + if (mPrevDockRect != dockRect || mRootRect != rootRect + || mRecalculateDocablePosition) { LLRect dockableRect = mDockableFloater->calcScreenRect(); - LLRect rootRect = mDockableFloater->getRootView()->getRect(); - S32 x = 0; S32 y = 0; switch (mDockAt) @@ -100,6 +116,7 @@ void LLDockControl::calculateDockablePosition() mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY, &mDockTongueX, &mDockTongueY); mPrevDockRect = dockRect; + mRootRect = rootRect; mRecalculateDocablePosition = false; } } diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h index 0e1f4c8e64..7d8d5c7653 100644 --- a/indra/llui/lldockcontrol.h +++ b/indra/llui/lldockcontrol.h @@ -60,8 +60,7 @@ public: public: void on(); void off(); - void setDock(LLView* dockWidget) - { mDockWidget = dockWidget;}; + void setDock(LLView* dockWidget); void repositionDockable(); void drawToungue(); protected: @@ -72,6 +71,7 @@ private: DocAt mDockAt; LLView* mDockWidget; LLRect mPrevDockRect; + LLRect mRootRect; LLFloater* mDockableFloater; LLUIImagePtr mDockTongue; S32 mDockTongueX; diff --git a/indra/llui/llfiltereditor.cpp b/indra/llui/llfiltereditor.cpp index 26b5f2e182..390504234d 100644 --- a/indra/llui/llfiltereditor.cpp +++ b/indra/llui/llfiltereditor.cpp @@ -37,81 +37,15 @@ #include "llfiltereditor.h" LLFilterEditor::LLFilterEditor(const LLFilterEditor::Params& p) -: LLUICtrl(p) +: LLSearchEditor(p) { - LLLineEditor::Params line_editor_p(p); - line_editor_p.name("filter edit box"); - line_editor_p.rect(getLocalRect()); - line_editor_p.follows.flags(FOLLOWS_ALL); - line_editor_p.text_pad_right(getRect().getHeight()); - line_editor_p.revert_on_esc(false); - line_editor_p.keystroke_callback(boost::bind(&LLUICtrl::onCommit, this)); - - mFilterEditor = LLUICtrlFactory::create<LLLineEditor>(line_editor_p); - addChild(mFilterEditor); - - S32 btn_width = getRect().getHeight(); // button is square, and as tall as search editor - LLRect clear_btn_rect(getRect().getWidth() - btn_width, getRect().getHeight(), getRect().getWidth(), 0); - LLButton::Params button_params(p.clear_filter_button); - button_params.name(std::string("clear filter")); - button_params.rect(clear_btn_rect) ; - button_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP); - button_params.tab_stop(false); - button_params.click_callback.function(boost::bind(&LLFilterEditor::onClearFilter, this, _2)); - - mClearFilterButton = LLUICtrlFactory::create<LLButton>(button_params); - mFilterEditor->addChild(mClearFilterButton); -} - -//virtual -void LLFilterEditor::setValue(const LLSD& value ) -{ - mFilterEditor->setValue(value); -} - -//virtual -LLSD LLFilterEditor::getValue() const -{ - return mFilterEditor->getValue(); -} - -//virtual -BOOL LLFilterEditor::setTextArg( const std::string& key, const LLStringExplicit& text ) -{ - return mFilterEditor->setTextArg(key, text); } -//virtual -BOOL LLFilterEditor::setLabelArg( const std::string& key, const LLStringExplicit& text ) -{ - return mFilterEditor->setLabelArg(key, text); -} - -//virtual -void LLFilterEditor::setLabel( const LLStringExplicit &new_label ) -{ - mFilterEditor->setLabel(new_label); -} - -//virtual -void LLFilterEditor::clear() -{ - if (mFilterEditor) - { - mFilterEditor->clear(); - } -} -void LLFilterEditor::draw() +void LLFilterEditor::handleKeystroke() { - mClearFilterButton->setVisible(!mFilterEditor->getWText().empty()); - - LLUICtrl::draw(); -} + this->LLSearchEditor::handleKeystroke(); -void LLFilterEditor::onClearFilter(const LLSD& data) -{ - setText(LLStringUtil::null); + // Commit on every keystroke. onCommit(); } - diff --git a/indra/llui/llfiltereditor.h b/indra/llui/llfiltereditor.h index fceb82af8d..c43a76b130 100644 --- a/indra/llui/llfiltereditor.h +++ b/indra/llui/llfiltereditor.h @@ -42,18 +42,14 @@ #ifndef LL_FILTEREDITOR_H #define LL_FILTEREDITOR_H -#include "lllineeditor.h" -#include "llbutton.h" +#include "llsearcheditor.h" -class LLFilterEditor : public LLUICtrl +class LLFilterEditor : public LLSearchEditor { public: - struct Params : public LLInitParam::Block<Params, LLLineEditor::Params> + struct Params : public LLInitParam::Block<Params, LLSearchEditor::Params> { - Optional<LLButton::Params> clear_filter_button; - Params() - : clear_filter_button("clear_filter_button") { name = "filter_editor"; } @@ -62,26 +58,8 @@ public: protected: LLFilterEditor(const Params&); friend class LLUICtrlFactory; -public: - virtual ~LLFilterEditor() {} - - /*virtual*/ void draw(); - - void setText(const LLStringExplicit &new_text) { mFilterEditor->setText(new_text); } - - // LLUICtrl interface - virtual void setValue(const LLSD& value ); - virtual LLSD getValue() const; - virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text ); - virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); - virtual void setLabel( const LLStringExplicit &new_label ); - virtual void clear(); - -private: - void onClearFilter(const LLSD& data); - LLLineEditor* mFilterEditor; - LLButton* mClearFilterButton; + /*virtual*/ void handleKeystroke(); }; #endif // LL_FILTEREDITOR_H diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp new file mode 100644 index 0000000000..75334acb39 --- /dev/null +++ b/indra/llui/llflatlistview.cpp @@ -0,0 +1,494 @@ +/** + * @file llflatlistview.cpp + * @brief LLFlatListView base class + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llpanel.h" + +#include "llflatlistview.h" + +static const LLDefaultChildRegistry::Register<LLFlatListView> flat_list_view("flat_list_view"); + +const LLSD SELECTED_EVENT = LLSD().insert("selected", true); +const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false); + +LLFlatListView::Params::Params() +: item_pad("item_pad"), + allow_select("allow_select"), + multi_select("multi_select"), + keep_one_selected("keep_one_selected") +{}; + +void LLFlatListView::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */) +{ + LLScrollContainer::reshape(width, height, called_from_parent); + setItemsNoScrollWidth(width); + rearrangeItems(); +} + +bool LLFlatListView::addItem(LLPanel* item, LLSD value /* = LLUUID::null*/, EAddPosition pos /*= ADD_BOTTOM*/) +{ + if (!item) return false; + if (value.isUndefined()) return false; + + //force uniqueness of items, easiest check but unreliable + if (item->getParent() == mItemsPanel) return false; + + item_pair_t* new_pair = new item_pair_t(item, value); + switch (pos) + { + case ADD_TOP: + mItemPairs.push_front(new_pair); + //in LLView::draw() children are iterated in backorder + mItemsPanel->addChildInBack(item); + break; + case ADD_BOTTOM: + mItemPairs.push_back(new_pair); + mItemsPanel->addChild(item); + break; + default: + break; + } + + //_4 is for MASK + item->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4)); + item->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4)); + + rearrangeItems(); + return true; +} + + +bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, LLSD value /*= LLUUID::null*/) +{ + if (!after_item) return false; + if (!item_to_add) return false; + if (value.isUndefined()) return false; + + if (mItemPairs.empty()) return false; + + //force uniqueness of items, easiest check but unreliable + if (item_to_add->getParent() == mItemsPanel) return false; + + item_pair_t* after_pair = getItemPair(after_item); + if (!after_pair) return false; + + item_pair_t* new_pair = new item_pair_t(item_to_add, value); + if (after_pair == mItemPairs.back()) + { + mItemPairs.push_back(new_pair); + mItemsPanel->addChild(item_to_add); + } + else + { + pairs_iterator_t it = mItemPairs.begin(); + ++it; + while (it != mItemPairs.end()) + { + if (*it == after_pair) + { + mItemPairs.insert(++it, new_pair); + mItemsPanel->addChild(item_to_add); + break; + } + } + } + + //_4 is for MASK + item_to_add->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4)); + item_to_add->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4)); + + rearrangeItems(); + return true; +} + + +bool LLFlatListView::removeItem(LLPanel* item) +{ + if (!item) return false; + if (item->getParent() != mItemsPanel) return false; + + item_pair_t* item_pair = getItemPair(item); + if (!item_pair) return false; + + return removeItemPair(item_pair); +} + +bool LLFlatListView::removeItemByValue(const LLSD& value) +{ + if (value.isUndefined()) return false; + + item_pair_t* item_pair = getItemPair(value); + if (!item_pair) return false; + + return removeItemPair(item_pair); +} + +bool LLFlatListView::removeItemByUUID(LLUUID& uuid) +{ + return removeItemByValue(LLSD(uuid)); +} + +LLPanel* LLFlatListView::getItemByValue(LLSD& value) const +{ + if (value.isDefined()) return NULL; + + item_pair_t* pair = getItemPair(value); + if (pair) return pair->first; + return NULL; +} + +bool LLFlatListView::selectItem(LLPanel* item, bool select /*= true*/) +{ + if (!item) return false; + if (item->getParent() != mItemsPanel) return false; + + item_pair_t* item_pair = getItemPair(item); + if (!item_pair) return false; + + return selectItemPair(item_pair, select); +} + +bool LLFlatListView::selectItemByValue(const LLSD& value, bool select /*= true*/) +{ + if (value.isUndefined()) return false; + + item_pair_t* item_pair = getItemPair(value); + if (!item_pair) return false; + + return selectItemPair(item_pair, select); +} + +bool LLFlatListView::selectItemByUUID(LLUUID& uuid, bool select /* = true*/) +{ + return selectItemByValue(LLSD(uuid), select); +} + + +LLSD LLFlatListView::getSelectedValue() const +{ + if (mSelectedItemPairs.empty()) return LLSD(); + + item_pair_t* first_selected_pair = mSelectedItemPairs.front(); + return first_selected_pair->second; +} + +void LLFlatListView::getSelectedValues(std::vector<LLSD>& selected_values) const +{ + if (mSelectedItemPairs.empty()) return; + + for (pairs_const_iterator_t it = mSelectedItemPairs.begin(); it != mSelectedItemPairs.end(); ++it) + { + selected_values.push_back((*it)->second); + } +} + +LLUUID LLFlatListView::getSelectedUUID() const +{ + const LLSD& value = getSelectedValue(); + if (value.isDefined() && value.isUUID()) + { + return value.asUUID(); + } + else + { + return LLUUID::null; + } +} + +void LLFlatListView::getSelectedUUIDs(std::vector<LLUUID>& selected_uuids) const +{ + if (mSelectedItemPairs.empty()) return; + + for (pairs_const_iterator_t it = mSelectedItemPairs.begin(); it != mSelectedItemPairs.end(); ++it) + { + selected_uuids.push_back((*it)->second.asUUID()); + } +} + +LLPanel* LLFlatListView::getSelectedItem() const +{ + if (mSelectedItemPairs.empty()) return NULL; + + return mSelectedItemPairs.front()->first; +} + +void LLFlatListView::getSelectedItems(std::vector<LLPanel*>& selected_items) const +{ + if (mSelectedItemPairs.empty()) return; + + for (pairs_const_iterator_t it = mSelectedItemPairs.begin(); it != mSelectedItemPairs.end(); ++it) + { + selected_items.push_back((*it)->first); + } +} + +void LLFlatListView::resetSelection() +{ + if (mSelectedItemPairs.empty()) return; + + for (pairs_iterator_t it= mSelectedItemPairs.begin(); it != mSelectedItemPairs.end(); ++it) + { + item_pair_t* pair_to_deselect = *it; + LLPanel* item = pair_to_deselect->first; + item->setValue(UNSELECTED_EVENT); + } + + mSelectedItemPairs.clear(); +} + +void LLFlatListView::clear() +{ + // do not use LLView::deleteAllChildren to avoid removing nonvisible items. drag-n-drop for ex. + for (pairs_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it) + { + mItemsPanel->removeChild((*it)->first); + delete (*it)->first; + delete *it; + } + mItemPairs.clear(); + mSelectedItemPairs.clear(); +} + + +////////////////////////////////////////////////////////////////////////// +// PROTECTED STUFF +////////////////////////////////////////////////////////////////////////// + + +LLFlatListView::LLFlatListView(const LLFlatListView::Params& p) +: LLScrollContainer(p), + mItemsPanel(NULL), + mItemPad(p.item_pad), + mAllowSelection(p.allow_select), + mMultipleSelection(p.multi_select), + mKeepOneItemSelected(p.keep_one_selected) +{ + mBorderThickness = getBorderWidth(); + + LLRect scroll_rect = getRect(); + LLRect items_rect; + + setItemsNoScrollWidth(scroll_rect.getWidth()); + items_rect.setLeftTopAndSize(mBorderThickness, scroll_rect.getHeight() - mBorderThickness, mItemsNoScrollWidth, 0); + + LLPanel::Params pp; + pp.rect(items_rect); + mItemsPanel = LLUICtrlFactory::create<LLPanel> (pp); + addChild(mItemsPanel); + + //we don't need to stretch in vertical direction on reshaping by a parent + //no bottom following! + mItemsPanel->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_TOP); +}; + +void LLFlatListView::rearrangeItems() +{ + static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); + + if (mItemPairs.empty()) return; + + //calculating required height - assuming items can be of different height + //list should accommodate all its items + S32 height = 0; + + pairs_iterator_t it = mItemPairs.begin(); + for (; it != mItemPairs.end(); ++it) + { + LLPanel* item = (*it)->first; + height += item->getRect().getHeight(); + } + height += mItemPad * (mItemPairs.size() - 1); + + LLRect rc = mItemsPanel->getRect(); + S32 width = mItemsNoScrollWidth; + + // update width to avoid horizontal scrollbar + if (height > getRect().getHeight() - 2 * mBorderThickness) + width -= scrollbar_size; + + //changes the bottom, end of the list goes down in the scroll container + rc.setLeftTopAndSize(rc.mLeft, rc.mTop, width, height); + mItemsPanel->setRect(rc); + + //reshaping items + S32 item_new_top = height; + pairs_iterator_t it2, first_it = mItemPairs.begin(); + for (it2 = first_it; it2 != mItemPairs.end(); ++it2) + { + LLPanel* item = (*it2)->first; + LLRect rc = item->getRect(); + if(it2 != first_it) + { + item_new_top -= (rc.getHeight() + mItemPad); + } + rc.setLeftTopAndSize(rc.mLeft, item_new_top, width, rc.getHeight()); + item->reshape(rc.getWidth(), rc.getHeight()); + item->setRect(rc); + } +} + +void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask) +{ + if (!item_pair) return; + + bool select_item = !isSelected(item_pair); + + //*TODO find a better place for that enforcing stuff + if (mKeepOneItemSelected && numSelected() == 1 && !select_item) return; + + if (!(mask & MASK_CONTROL) || !mMultipleSelection) resetSelection(); + selectItemPair(item_pair, select_item); +} + +LLFlatListView::item_pair_t* LLFlatListView::getItemPair(LLPanel* item) const +{ + llassert(item); + + for (pairs_const_iterator_t it= mItemPairs.begin(); it != mItemPairs.end(); ++it) + { + item_pair_t* item_pair = *it; + if (item_pair->first == item) return item_pair; + } + return NULL; +} + +//compares two LLSD's +bool llsds_are_equal(const LLSD& llsd_1, const LLSD& llsd_2) +{ + llassert(llsd_1.isDefined()); + llassert(llsd_2.isDefined()); + + if (llsd_1.type() != llsd_2.type()) return false; + + if (!llsd_1.isMap()) + { + if (llsd_1.isUUID()) return llsd_1.asUUID() == llsd_2.asUUID(); + + //assumptions that string representaion is enough for other types + return llsd_1.asString() == llsd_2.asString(); + } + + if (llsd_1.size() != llsd_2.size()) return false; + + LLSD::map_const_iterator llsd_1_it = llsd_1.beginMap(); + LLSD::map_const_iterator llsd_2_it = llsd_2.beginMap(); + for (S32 i = 0; i < llsd_1.size(); ++i) + { + if ((*llsd_1_it).first != (*llsd_2_it).first) return false; + if (!llsds_are_equal((*llsd_1_it).second, (*llsd_2_it).second)) return false; + ++llsd_1_it; + ++llsd_2_it; + } + return true; +} + +LLFlatListView::item_pair_t* LLFlatListView::getItemPair(const LLSD& value) const +{ + llassert(value.isDefined()); + + for (pairs_const_iterator_t it= mItemPairs.begin(); it != mItemPairs.end(); ++it) + { + item_pair_t* item_pair = *it; + if (llsds_are_equal(item_pair->second, value)) return item_pair; + } + return NULL; +} + +bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select) +{ + llassert(item_pair); + + if (!mAllowSelection && select) return false; + + if (isSelected(item_pair) == select) return true; //already in specified selection state + if (select) + { + mSelectedItemPairs.push_back(item_pair); + } + else + { + mSelectedItemPairs.remove(item_pair); + } + + //a way of notifying panel of selection state changes + LLPanel* item = item_pair->first; + item->setValue(select ? SELECTED_EVENT : UNSELECTED_EVENT); + return true; +} + +bool LLFlatListView::isSelected(item_pair_t* item_pair) const +{ + llassert(item_pair); + + pairs_const_iterator_t it_end = mSelectedItemPairs.end(); + return std::find(mSelectedItemPairs.begin(), it_end, item_pair) != it_end; +} + +bool LLFlatListView::removeItemPair(item_pair_t* item_pair) +{ + llassert(item_pair); + + bool deleted = false; + for (pairs_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it) + { + item_pair_t* _item_pair = *it; + if (_item_pair == item_pair) + { + mItemPairs.erase(it); + deleted = true; + break; + } + } + + if (!deleted) return false; + + for (pairs_iterator_t it = mSelectedItemPairs.begin(); it != mSelectedItemPairs.end(); ++it) + { + item_pair_t* selected_item_pair = *it; + if (selected_item_pair == item_pair) + { + it = mSelectedItemPairs.erase(it); + break; + } + } + + mItemsPanel->removeChild(item_pair->first); + delete item_pair->first; + delete item_pair; + + rearrangeItems(); + + return true; +} + + diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h new file mode 100644 index 0000000000..bd0b419f4f --- /dev/null +++ b/indra/llui/llflatlistview.h @@ -0,0 +1,262 @@ +/** + * @file llflatlistview.h + * @brief LLFlatListView base class + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLATLISTVIEW_H +#define LL_LLFLATLISTVIEW_H + +#include "llscrollcontainer.h" + + +class LLPanel; + +/** + * LLFlatListView represents a flat list ui control that operates on items in a form of LLPanel's. + * LLSD can be associated with each added item, it can keep data from an item in digested form. + * Associated LLSD's can be of any type (singular, a map etc.). + * Items (LLPanel's subclasses) can be of different height. + * The list is LLPanel created in itself and grows in height while new items are added. + * + * The control can manage selection of its items when the flag "allow_select" is set. Also ability to select + * multiple items (by using CTRL) is enabled through setting the flag "multi_select" - if selection is not allowed that flag + * is ignored. The option "keep_one_selected" forces at least one item to be selected at any time (only for mouse events on items) + * since any item of the list was selected. + * + * Examples of using this control are presented in Picks panel (Me Profile and Profile View), where this control is used to + * manage the list of pick items. + * + * ASSUMPTIONS AND STUFF + * - NULL pointers and undefined LLSD's are not accepted by any method of this class unless specified otherwise + * - Order of returned selected items are not guaranteed + * - The control assumes that all items being added are unique. + */ +class LLFlatListView : public LLScrollContainer +{ +public: + + struct Params : public LLInitParam::Block<Params, LLScrollContainer::Params> + { + /** turning on/off selection support */ + Optional<bool> allow_select; + + /** turning on/off multiple selection (works while clicking and holding CTRL)*/ + Optional<bool> multi_select; + + /** don't allow to deselect all selected items (for mouse events on items only) */ + Optional<bool> keep_one_selected; + + /** padding between items */ + Optional<U32> item_pad; + + Params(); + }; + + virtual ~LLFlatListView() { clear(); }; + + + /** Overridden LLPanel's reshape, height is ignored, the list sets its height to accommodate all items */ + virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + + + /** + * Adds and item and LLSD value associated with it to the list at specified position + * @return true if the item was added, false otherwise + */ + virtual bool addItem(LLPanel* item, LLSD value = LLUUID::null, EAddPosition pos = ADD_BOTTOM); + + /** + * Insert item_to_add along with associated value to the list right after the after_item. + * @return true if the item was successfully added, false otherwise + */ + virtual bool insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, LLSD value = LLUUID::null); + + /** + * Remove specified item + * @return true if the item was removed, false otherwise + */ + virtual bool removeItem(LLPanel* item); + + /** + * Remove an item specified by value + * @return true if the item was removed, false otherwise + */ + virtual bool removeItemByValue(const LLSD& value); + + /** + * Remove an item specified by uuid + * @return true if the item was removed, false otherwise + */ + virtual bool removeItemByUUID(LLUUID& uuid); + + /** + * Get an item by value + * @return the item as LLPanel if associated with value, NULL otherwise + */ + virtual LLPanel* getItemByValue(LLSD& value) const; + + /** + * Select or deselect specified item based on select + * @return true if succeed, false otherwise + */ + virtual bool selectItem(LLPanel* item, bool select = true); + + /** + * Select or deselect an item by associated value based on select + * @return true if succeed, false otherwise + */ + virtual bool selectItemByValue(const LLSD& value, bool select = true); + + /** + * Select or deselect an item by associated uuid based on select + * @return true if succeed, false otherwise + */ + virtual bool selectItemByUUID(LLUUID& uuid, bool select = true); + + + + /** + * Get LLSD associated with the first selected item + */ + virtual LLSD getSelectedValue() const; + + /** + * Get LLSD's associated with selected items. + * @param selected_values std::vector being populated with LLSD associated with selected items + */ + virtual void getSelectedValues(std::vector<LLSD>& selected_values) const; + + + /** + * Get LLUUID associated with selected item + * @return LLUUID if such was associated with selected item + */ + virtual LLUUID getSelectedUUID() const; + + /** + * Get LLUUIDs associated with selected items + * @param selected_uuids An std::vector being populated with LLUUIDs associated with selected items + */ + virtual void getSelectedUUIDs(std::vector<LLUUID>& selected_uuids) const; + + /** Get the top selected item */ + virtual LLPanel* getSelectedItem() const; + + /** + * Get selected items + * @param selected_items An std::vector being populated with pointers to selected items + */ + virtual void getSelectedItems(std::vector<LLPanel*>& selected_items) const; + + + /** Resets selection of items */ + virtual void resetSelection(); + + + /** Turn on/off multiple selection support */ + void setAllowMultipleSelection(bool allow) { mMultipleSelection = allow; } + + /** Turn on/off selection support */ + void setAllowSelection(bool can_select) { mAllowSelection = can_select; } + + + /** Get number of selected items in the list */ + U32 numSelected() const {return mSelectedItemPairs.size(); } + + /** Get number of items in the list */ + U32 size() const { return mItemPairs.size(); } + + + /** Removes all items from the list */ + virtual void clear(); + + +protected: + + /** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */ + typedef std::pair<LLPanel*, LLSD> item_pair_t; + + typedef std::list<item_pair_t*> pairs_list_t; + typedef pairs_list_t::iterator pairs_iterator_t; + typedef pairs_list_t::const_iterator pairs_const_iterator_t; + + + friend class LLUICtrlFactory; + LLFlatListView(const LLFlatListView::Params& p); + + /** Manage selection on mouse events */ + void onItemMouseClick(item_pair_t* item_pair, MASK mask); + + /** Updates position of items */ + virtual void rearrangeItems(); + + virtual item_pair_t* getItemPair(LLPanel* item) const; + + virtual item_pair_t* getItemPair(const LLSD& value) const; + + virtual bool selectItemPair(item_pair_t* item_pair, bool select); + + virtual bool isSelected(item_pair_t* item_pair) const; + + virtual bool removeItemPair(item_pair_t* item_pair); + + +private: + + void setItemsNoScrollWidth(S32 new_width) {mItemsNoScrollWidth = new_width - 2 * mBorderThickness;} + + +private: + + LLPanel* mItemsPanel; + + S32 mItemsNoScrollWidth; + + S32 mBorderThickness; + + /** Items padding */ + U32 mItemPad; + + /** Selection support flag */ + bool mAllowSelection; + + /** Multiselection support flag, ignored if selection is not supported */ + bool mMultipleSelection; + + bool mKeepOneItemSelected; + + /** All pairs of the list */ + pairs_list_t mItemPairs; + + /** Selected pairs for faster access */ + pairs_list_t mSelectedItemPairs; +}; + +#endif diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index c027b59c71..228e23b67e 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1491,7 +1491,8 @@ LLFloater* LLFloater::getClosableFloaterFromFocus() // The focused floater may not be closable, // Find and close a parental floater that is closeable, if any. - for(LLFloater* floater_to_close = focused_floater; + LLFloater* prev_floater = NULL; + for(LLFloater* floater_to_close = focused_floater; NULL != floater_to_close; floater_to_close = gFloaterView->getParentFloater(floater_to_close)) { @@ -1499,6 +1500,14 @@ LLFloater* LLFloater::getClosableFloaterFromFocus() { return floater_to_close; } + + // If floater has as parent root view + // gFloaterView->getParentFloater(floater_to_close) returns + // the same floater_to_close, so we need to check this. + if (prev_floater == floater_to_close) { + break; + } + prev_floater = floater_to_close; } return NULL; diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index a024f48cc6..339aad30fb 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -189,6 +189,7 @@ public: // Selects characters 'start' to 'end'. void setSelection(S32 start, S32 end); + virtual void getSelectionRange(S32 *position, S32 *length) const; void setCommitOnFocusLost( BOOL b ) { mCommitOnFocusLost = b; } void setRevertOnEsc( BOOL b ) { mRevertOnEsc = b; } @@ -277,7 +278,6 @@ private: const segment_lengths_t &preedit_segment_lengths, const standouts_t &preedit_standouts, S32 caret_position); virtual void markAsPreedit(S32 position, S32 length); virtual void getPreeditRange(S32 *position, S32 *length) const; - virtual void getSelectionRange(S32 *position, S32 *length) const; virtual BOOL getPreeditLocation(S32 query_position, LLCoordGL *coord, LLRect *bounds, LLRect *control) const; virtual S32 getPreeditFontSize() const; diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp index fbcbb55b85..b87f645f3f 100644 --- a/indra/llui/llsearcheditor.cpp +++ b/indra/llui/llsearcheditor.cpp @@ -38,30 +38,68 @@ LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p) : LLUICtrl(p) + , mSearchButton(NULL) + , mClearButton(NULL) { - S32 btn_top = p.search_button.top_pad + p.search_button.rect.height; - S32 btn_right = p.search_button.rect.width + p.search_button.left_pad; - LLRect search_btn_rect(p.search_button.left_pad, btn_top, btn_right, p.search_button.top_pad); + S32 srch_btn_top = p.search_button.top_pad + p.search_button.rect.height; + S32 srch_btn_right = p.search_button.rect.width + p.search_button.left_pad; + LLRect srch_btn_rect(p.search_button.left_pad, srch_btn_top, srch_btn_right, p.search_button.top_pad); + S32 text_pad_left = p.text_pad_left; + if (p.search_button_visible) + text_pad_left += srch_btn_rect.getWidth(); + + // Set up line editor. LLLineEditor::Params line_editor_params(p); line_editor_params.name("filter edit box"); line_editor_params.rect(getLocalRect()); line_editor_params.follows.flags(FOLLOWS_ALL); - line_editor_params.text_pad_left(p.text_pad_left + search_btn_rect.getWidth()); + line_editor_params.text_pad_left(text_pad_left); + line_editor_params.revert_on_esc(false); line_editor_params.commit_callback.function(boost::bind(&LLUICtrl::onCommit, this)); + line_editor_params.keystroke_callback(boost::bind(&LLSearchEditor::handleKeystroke, this)); mSearchEditor = LLUICtrlFactory::create<LLLineEditor>(line_editor_params); addChild(mSearchEditor); - LLButton::Params button_params(p.search_button); - button_params.name(std::string("clear filter")); - button_params.rect(search_btn_rect) ; - button_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP); - button_params.tab_stop(false); - button_params.click_callback.function(boost::bind(&LLUICtrl::onCommit, this)); + if (p.search_button_visible) + { + // Set up search button. + LLButton::Params srch_btn_params(p.search_button); + srch_btn_params.name(std::string("search button")); + srch_btn_params.rect(srch_btn_rect) ; + srch_btn_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP); + srch_btn_params.tab_stop(false); + srch_btn_params.click_callback.function(boost::bind(&LLUICtrl::onCommit, this)); + + mSearchButton = LLUICtrlFactory::create<LLButton>(srch_btn_params); + mSearchEditor->addChild(mSearchButton); + } + + if (p.clear_button_visible) + { + // Set up clear button. + S32 clr_btn_width = getRect().getHeight(); // button is square, and as tall as search editor + LLRect clear_btn_rect(getRect().getWidth() - clr_btn_width, getRect().getHeight(), getRect().getWidth(), 0); + LLButton::Params clr_btn_params(p.clear_button); + clr_btn_params.name(std::string("clear button")); + clr_btn_params.rect(clear_btn_rect) ; + clr_btn_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP); + clr_btn_params.tab_stop(false); + clr_btn_params.click_callback.function(boost::bind(&LLSearchEditor::onClearButtonClick, this, _2)); + + mClearButton = LLUICtrlFactory::create<LLButton>(clr_btn_params); + mSearchEditor->addChild(mClearButton); + } +} + +//virtual +void LLSearchEditor::draw() +{ + if (mClearButton) + mClearButton->setVisible(!mSearchEditor->getWText().empty()); - mSearchButton = LLUICtrlFactory::create<LLButton>(button_params); - mSearchEditor->addChild(mSearchButton); + LLUICtrl::draw(); } //virtual @@ -89,6 +127,12 @@ BOOL LLSearchEditor::setLabelArg( const std::string& key, const LLStringExplicit } //virtual +void LLSearchEditor::setLabel( const LLStringExplicit &new_label ) +{ + mSearchEditor->setLabel(new_label); +} + +//virtual void LLSearchEditor::clear() { if (mSearchEditor) @@ -96,3 +140,17 @@ void LLSearchEditor::clear() mSearchEditor->clear(); } } + +void LLSearchEditor::onClearButtonClick(const LLSD& data) +{ + setText(LLStringUtil::null); + mSearchEditor->doDelete(); // force keystroke callback +} + +void LLSearchEditor::handleKeystroke() +{ + if (mKeystrokeCallback) + { + mKeystrokeCallback(this, getValue()); + } +} diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h index cd2867b493..f395e7e816 100644 --- a/indra/llui/llsearcheditor.h +++ b/indra/llui/llsearcheditor.h @@ -50,10 +50,15 @@ class LLSearchEditor : public LLUICtrl public: struct Params : public LLInitParam::Block<Params, LLLineEditor::Params> { - Optional<LLButton::Params> search_button; + Optional<LLButton::Params> search_button, clear_button; + Optional<bool> search_button_visible, clear_button_visible; + Optional<commit_callback_t> keystroke_callback; Params() : search_button("search_button") + , search_button_visible("search_button_visible") + , clear_button("clear_button") + , clear_button_visible("clear_button_visible") { name = "search_editor"; } @@ -66,26 +71,29 @@ protected: public: virtual ~LLSearchEditor() {} + /*virtual*/ void draw(); + void setText(const LLStringExplicit &new_text) { mSearchEditor->setText(new_text); } const std::string& getText() const { return mSearchEditor->getText(); } - // LLUICtrl interface virtual void setValue(const LLSD& value ); virtual LLSD getValue() const; virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text ); virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); + virtual void setLabel( const LLStringExplicit &new_label ); virtual void clear(); - void setKeystrokeCallback(LLLineEditor::callback_t callback, void* user_data) - { - if(mSearchEditor) - mSearchEditor->setKeystrokeCallback(callback,user_data); - } + void setKeystrokeCallback( commit_callback_t cb ) { mKeystrokeCallback = cb; } + +protected: + void onClearButtonClick(const LLSD& data); + virtual void handleKeystroke(); -private: + commit_callback_t mKeystrokeCallback; LLLineEditor* mSearchEditor; LLButton* mSearchButton; + LLButton* mClearButton; }; #endif // LL_SEARCHEDITOR_H diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index cabd0be522..720ca692f7 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -306,7 +306,7 @@ void LLTabContainer::draw() setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(0.08f))); - BOOL has_scroll_arrows = (mMaxScrollPos > 0) || (mScrollPosPixels > 0); + BOOL has_scroll_arrows = !getTabsHidden() && ((mMaxScrollPos > 0) || (mScrollPosPixels > 0)); if (!mIsVertical) { mJumpPrevArrowBtn->setVisible( has_scroll_arrows ); @@ -429,7 +429,7 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask ) { static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0); BOOL handled = FALSE; - BOOL has_scroll_arrows = (getMaxScrollPos() > 0); + BOOL has_scroll_arrows = (getMaxScrollPos() > 0) && !getTabsHidden(); if (has_scroll_arrows) { @@ -498,7 +498,7 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask ) BOOL LLTabContainer::handleHover( S32 x, S32 y, MASK mask ) { BOOL handled = FALSE; - BOOL has_scroll_arrows = (getMaxScrollPos() > 0); + BOOL has_scroll_arrows = (getMaxScrollPos() > 0) && !getTabsHidden(); if (has_scroll_arrows) { @@ -540,7 +540,7 @@ BOOL LLTabContainer::handleHover( S32 x, S32 y, MASK mask ) BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask ) { BOOL handled = FALSE; - BOOL has_scroll_arrows = (getMaxScrollPos() > 0); + BOOL has_scroll_arrows = (getMaxScrollPos() > 0) && !getTabsHidden(); if (has_scroll_arrows) { @@ -1840,12 +1840,11 @@ void LLTabContainer::updateMaxScrollPos() void LLTabContainer::commitHoveredButton(S32 x, S32 y) { - if (hasMouseCapture()) + if (!getTabsHidden() && hasMouseCapture()) { for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) { LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( TRUE ); S32 local_x = x - tuple->mButton->getRect().mLeft; S32 local_y = y - tuple->mButton->getRect().mBottom; if (tuple->mButton->pointInView(local_x, local_y) && tuple->mButton->getEnabled() && !tuple->mTabPanel->getVisible()) diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 85f9064115..c20212c375 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -339,54 +339,75 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa } /// -/// LLUrlEntryEvent Describes a Second Life event Url, e.g., -/// secondlife:///app/event/700727/about +/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g., +/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about /// -LLUrlEntryEvent::LLUrlEntryEvent() +LLUrlEntryParcel::LLUrlEntryParcel() { - mPattern = boost::regex("secondlife:///app/event/[\\da-f-]+/about", + mPattern = boost::regex("secondlife:///app/parcel/[\\da-f-]+/about", boost::regex::perl|boost::regex::icase); - mMenuName = "menu_url_event.xml"; - mTooltip = LLTrans::getString("TooltipEventUrl"); + mMenuName = "menu_url_parcel.xml"; + mTooltip = LLTrans::getString("TooltipParcelUrl"); } -std::string LLUrlEntryEvent::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +std::string LLUrlEntryParcel::getLabel(const std::string &url, const LLUrlLabelCallback &cb) { return unescapeUrl(url); } -/// -/// LLUrlEntryClassified Describes a Second Life classified Url, e.g., -/// secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about -/// -LLUrlEntryClassified::LLUrlEntryClassified() +// +// LLUrlEntryPlace Describes secondlife:///<location> URLs +// +LLUrlEntryPlace::LLUrlEntryPlace() { - mPattern = boost::regex("secondlife:///app/classified/[\\da-f-]+/about", + mPattern = boost::regex("secondlife://\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?", boost::regex::perl|boost::regex::icase); - mMenuName = "menu_url_classified.xml"; - mTooltip = LLTrans::getString("TooltipClassifiedUrl"); + mMenuName = "menu_url_slurl.xml"; + mTooltip = LLTrans::getString("TooltipSLURL"); } -std::string LLUrlEntryClassified::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +std::string LLUrlEntryPlace::getLabel(const std::string &url, const LLUrlLabelCallback &cb) { - return unescapeUrl(url); -} + // + // we handle SLURLs in the following formats: + // - secondlife://Place/X/Y/Z + // - secondlife://Place/X/Y + // + LLURI uri(url); + std::string location = unescapeUrl(uri.hostName()); + LLSD path_array = uri.pathArray(); + S32 path_parts = path_array.size(); + if (path_parts == 3) + { + // handle slurl with (X,Y,Z) coordinates + std::string x = path_array[0]; + std::string y = path_array[1]; + std::string z = path_array[2]; + return location + " (" + x + "," + y + "," + z + ")"; + } + else if (path_parts == 2) + { + // handle slurl with (X,Y) coordinates + std::string x = path_array[0]; + std::string y = path_array[1]; + return location + " (" + x + "," + y + ")"; + } -/// -/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g., -/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about -/// -LLUrlEntryParcel::LLUrlEntryParcel() -{ - mPattern = boost::regex("secondlife:///app/parcel/[\\da-f-]+/about", - boost::regex::perl|boost::regex::icase); - mMenuName = "menu_url_parcel.xml"; - mTooltip = LLTrans::getString("TooltipParcelUrl"); + return url; } -std::string LLUrlEntryParcel::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +std::string LLUrlEntryPlace::getLocation(const std::string &url) const { - return unescapeUrl(url); + // return the part of the Url after secondlife:// part + const std::string search_string = "://"; + size_t pos = url.find(search_string); + if (pos == std::string::npos) + { + return ""; + } + + pos += search_string.size(); + return url.substr(pos, url.size() - pos); } // diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index f3e76dbec0..54053872df 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -170,36 +170,26 @@ private: }; /// -/// LLUrlEntryEvent Describes a Second Life event Url, e.g., -/// secondlife:///app/event/700727/about -/// -class LLUrlEntryEvent : public LLUrlEntryBase -{ -public: - LLUrlEntryEvent(); - /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); -}; - -/// -/// LLUrlEntryClassified Describes a Second Life classified Url, e.g., -/// secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about +/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g., +/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about /// -class LLUrlEntryClassified : public LLUrlEntryBase +class LLUrlEntryParcel : public LLUrlEntryBase { public: - LLUrlEntryClassified(); + LLUrlEntryParcel(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); }; /// -/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g., -/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about +/// LLUrlEntryPlace Describes a Second Life location Url, e.g., +/// secondlife:///Ahern/50/50/50 /// -class LLUrlEntryParcel : public LLUrlEntryBase +class LLUrlEntryPlace : public LLUrlEntryBase { public: - LLUrlEntryParcel(); + LLUrlEntryPlace(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + /*virtual*/ std::string getLocation(const std::string &url) const; }; /// diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 938375ad13..f2d340deb7 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -49,11 +49,10 @@ LLUrlRegistry::LLUrlRegistry() registerUrl(new LLUrlEntryHTTPLabel()); registerUrl(new LLUrlEntryAgent()); registerUrl(new LLUrlEntryGroup()); - registerUrl(new LLUrlEntryEvent()); - registerUrl(new LLUrlEntryClassified()); registerUrl(new LLUrlEntryParcel()); registerUrl(new LLUrlEntryTeleport()); registerUrl(new LLUrlEntryObjectIM()); + registerUrl(new LLUrlEntryPlace()); registerUrl(new LLUrlEntrySL()); registerUrl(new LLUrlEntrySLLabel()); } @@ -118,8 +117,8 @@ static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &en bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb) { - // test for the trivial case of no text and get out fast - if (text.empty()) + // avoid costly regexes if there is clearly no URL in the text + if (text.find("://") == std::string::npos) { return false; } diff --git a/indra/llui/llview.h b/indra/llui/llview.h index d80c2af568..1f7e5afaae 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -633,7 +633,7 @@ template <class T> T* LLView::getChild(const std::string& name, BOOL recurse) co // did we find *something* with that name? if (child) { - llwarns << "Found child named " << name << " but of wrong type " << typeid(child).name() << ", expecting " << typeid(T*).name() << llendl; + llwarns << "Found child named " << name << " but of wrong type " << typeid(*child).name() << ", expecting " << typeid(T*).name() << llendl; } result = getDefaultWidget<T>(name); if (!result) diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 610ee3349b..1e7a0f7f2c 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -308,56 +308,52 @@ namespace tut void object::test<6>() { // - // test LLUrlEntryEvent - secondlife://app/event Urls + // test LLUrlEntryPlace - secondlife://<location> URLs // - LLUrlEntryEvent url; + LLUrlEntryPlace url; boost::regex r = url.getPattern(); - testRegex("Invalid Event Url", r, - "secondlife:///app/event/FOO/about", + testRegex("no valid slurl [1]", r, + "secondlife://Ahern/FOO/50/", ""); - testRegex("Event Url ", r, - "secondlife:///app/event/700727/about", - "secondlife:///app/event/700727/about"); + testRegex("Ahern (50,50,50) [1]", r, + "secondlife://Ahern/50/50/50/", + "secondlife://Ahern/50/50/50/"); - testRegex("Event Url in text", r, - "XXX secondlife:///app/event/700727/about XXX", - "secondlife:///app/event/700727/about"); + testRegex("Ahern (50,50,50) [2]", r, + "XXX secondlife://Ahern/50/50/50/ XXX", + "secondlife://Ahern/50/50/50/"); - testRegex("Event Url multicase", r, - "XXX secondlife:///APP/Event/700727/about XXX", - "secondlife:///APP/Event/700727/about"); - } + testRegex("Ahern (50,50,50) [3]", r, + "XXX secondlife://Ahern/50/50/50 XXX", + "secondlife://Ahern/50/50/50"); - template<> template<> - void object::test<7>() - { - // - // test LLUrlEntryClassified - secondlife://app/classified Urls - // - LLUrlEntryClassified url; - boost::regex r = url.getPattern(); + testRegex("Ahern (50,50,50) multicase", r, + "XXX SecondLife://Ahern/50/50/50/ XXX", + "SecondLife://Ahern/50/50/50/"); - testRegex("Invalid Classified Url", r, - "secondlife:///app/classified/00128854-XXXX-5649-7ca6-5dfaa7514ab2/about", - ""); + testRegex("Ahern (50,50) [1]", r, + "XXX secondlife://Ahern/50/50/ XXX", + "secondlife://Ahern/50/50/"); - testRegex("Classified Url ", r, - "secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about", - "secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about"); + testRegex("Ahern (50,50) [2]", r, + "XXX secondlife://Ahern/50/50 XXX", + "secondlife://Ahern/50/50"); - testRegex("Classified Url in text", r, - "XXX secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about XXX", - "secondlife:///app/classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/about"); + // DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat + testRegex("SLURL with brackets", r, + "XXX secondlife://Burning%20Life%20(Hyper)/27/210/30 XXX", + "secondlife://Burning%20Life%20(Hyper)/27/210/30"); - testRegex("Classified Url multicase", r, - "XXX secondlife:///APP/Classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/About XXX", - "secondlife:///APP/Classified/00128854-c36a-5649-7ca6-5dfaa7514ab2/About"); + // DEV-35459: SLURLs and teleport Links not parsed properly + testRegex("SLURL with quote", r, + "XXX secondlife://A'ksha%20Oasis/41/166/701 XXX", + "secondlife://A'ksha%20Oasis/41/166/701"); } template<> template<> - void object::test<8>() + void object::test<7>() { // // test LLUrlEntryParcel - secondlife://app/parcel Urls @@ -382,7 +378,7 @@ namespace tut "secondlife:///APP/Parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/About"); } template<> template<> - void object::test<9>() + void object::test<8>() { // // test LLUrlEntryTeleport - secondlife://app/teleport URLs @@ -458,7 +454,7 @@ namespace tut } template<> template<> - void object::test<10>() + void object::test<9>() { // // test LLUrlEntrySL - general secondlife:// URLs @@ -496,7 +492,7 @@ namespace tut } template<> template<> - void object::test<11>() + void object::test<10>() { // // test LLUrlEntrySLLabel - general secondlife:// URLs with labels diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index cd20648f74..2e210e41c9 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -74,6 +74,7 @@ set(viewer_SOURCE_FILES llagentui.cpp llagentwearables.cpp llanimstatelabels.cpp + llappearancemgr.cpp llappviewer.cpp llassetuploadresponders.cpp llassetuploadqueue.cpp @@ -532,6 +533,7 @@ set(viewer_HEADER_FILES llassetuploadresponders.h llassetuploadqueue.h llaudiosourcevo.h + llappearancemgr.h llavataractions.h llavatariconctrl.h llavatarlist.h diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 0f735282cb..c4e01808f7 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -45,6 +45,7 @@ #include "llwearable.h" #include "llwearablelist.h" #include "llgesturemgr.h" +#include "llappearancemgr.h" #include <boost/scoped_ptr.hpp> @@ -76,11 +77,9 @@ public: initial_wearable_data_vec_t mAgentInitialWearables; // Wearables from the old agent wearables msg protected: - void processInitialWearables(); + void processWearablesMessage(); }; - - LLAgentWearables gAgentWearables; BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE; @@ -312,7 +311,15 @@ void LLAgentWearables::sendAgentWearablesUpdate() if (wearable) { //llinfos << "Sending wearable " << wearable->getName() << llendl; - gMessageSystem->addUUIDFast(_PREHASH_ItemID, wearable->getItemID()); + LLUUID item_id = wearable->getItemID(); + const LLViewerInventoryItem *item = gInventory.getItem(item_id); + if (item && item->getIsLinkType()) + { + // Get the itemID that this item points to. i.e. make sure + // we are storing baseitems, not their links, in the database. + item_id = item->getLinkedUUID(); + } + gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id); } else { @@ -737,7 +744,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs gAgentWearables.mItemsAwaitingWearableUpdate.clear(); for (S32 i=0; i < num_wearables; i++) { - // Parse initial werables data from message system + // Parse initial wearables data from message system U8 type_u8 = 0; gMessageSystem->getU8Fast(_PREHASH_WearableData, _PREHASH_WearableType, type_u8, i); if (type_u8 >= WT_COUNT) @@ -1195,7 +1202,7 @@ LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name, if (!item) continue; LLPointer<LLInventoryCallback> cb = NULL; link_inventory_item(gAgent.getID(), - item->getUUID(), + item->getLinkedUUID(), folder_id, item->getName(), LLAssetType::AT_LINK, @@ -1226,7 +1233,7 @@ LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name, LLPointer<LLInventoryCallback> cb = NULL; link_inventory_item(gAgent.getID(), - item->getUUID(), + item->getLinkedUUID(), folder_id, item->getName(), LLAssetType::AT_LINK, @@ -1781,6 +1788,57 @@ void LLAgentWearables::userRemoveAllAttachments(void* userdata) gMessageSystem->sendReliable(gAgent.getRegionHost()); } +void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array) +{ + // Build a compound message to send all the objects that need to be rezzed. + S32 obj_count = obj_item_array.count(); + + // Limit number of packets to send + const S32 MAX_PACKETS_TO_SEND = 10; + const S32 OBJECTS_PER_PACKET = 4; + const S32 MAX_OBJECTS_TO_SEND = MAX_PACKETS_TO_SEND * OBJECTS_PER_PACKET; + if( obj_count > MAX_OBJECTS_TO_SEND ) + { + obj_count = MAX_OBJECTS_TO_SEND; + } + + // Create an id to keep the parts of the compound message together + LLUUID compound_msg_id; + compound_msg_id.generate(); + LLMessageSystem* msg = gMessageSystem; + + for(S32 i = 0; i < obj_count; ++i) + { + if( 0 == (i % OBJECTS_PER_PACKET) ) + { + // Start a new message chunk + msg->newMessageFast(_PREHASH_RezMultipleAttachmentsFromInv); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_HeaderData); + msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id ); + msg->addU8Fast(_PREHASH_TotalObjects, obj_count ); + msg->addBOOLFast(_PREHASH_FirstDetachAll, true ); + } + + const LLInventoryItem* item = obj_item_array.get(i).get(); + msg->nextBlockFast(_PREHASH_ObjectData ); + msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID()); + msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner()); + msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point + pack_permissions_slam(msg, item->getFlags(), item->getPermissions()); + msg->addStringFast(_PREHASH_Name, item->getName()); + msg->addStringFast(_PREHASH_Description, item->getDescription()); + + if( (i+1 == obj_count) || ((OBJECTS_PER_PACKET-1) == (i % OBJECTS_PER_PACKET)) ) + { + // End of message chunk + msg->sendReliable( gAgent.getRegion()->getHost() ); + } + } +} + void LLAgentWearables::checkWearablesLoaded() const { #ifdef SHOW_ASSERT @@ -1812,69 +1870,29 @@ void LLAgentWearables::updateServer() void LLInitialWearablesFetch::done() { - // Get the complete information on the items in the library, - // and set up an observer that will wait for that to happen. - LLInventoryModel::cat_array_t cat_array; - LLInventoryModel::item_array_t item_array; + // No longer need this observer hanging around. + gInventory.removeObserver(this); + // Fetch the wearable items from the Current Outfit Folder + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t wearable_array; LLFindWearables is_wearable; - gInventory.collectDescendentsIf(mCompleteFolders.front(), - cat_array, - item_array, - LLInventoryModel::EXCLUDE_TRASH, - is_wearable); - S32 count = item_array.count(); - mCOFInitialWearables.reserve(count); + gInventory.collectDescendentsIf(mCompleteFolders.front(), cat_array, wearable_array, + LLInventoryModel::EXCLUDE_TRASH, is_wearable); - for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin(); - iter != item_array.end(); - iter++) - { - const LLViewerInventoryItem *item = (*iter).get(); - // We're only concerned with linked items in the COF. Ignore - // any non-link items or links to folders. - if (item->getActualType() != LLAssetType::AT_LINK) - { - continue; - } - EWearableType type = (EWearableType) (item->getFlags() & LLInventoryItem::II_FLAGS_WEARABLES_MASK); - // MULTI-WEARABLE: update - InitialWearableData wearable_data(type, 0, item->getUUID(), item->getAssetUUID()); - mCOFInitialWearables.push_back(wearable_data); + if (wearable_array.count() > 0) + { + LLAppearanceManager::instance().updateAppearanceFromCOF(); + } + else + { + processWearablesMessage(); } - - gInventory.removeObserver(this); - processInitialWearables(); delete this; } -// This will either grab the contents of the Current Outfit Folder if they exist, -// or use the old-style initial agent wearables message. -void LLInitialWearablesFetch::processInitialWearables() +void LLInitialWearablesFetch::processWearablesMessage() { -#ifdef USE_CURRENT_OUTFIT_FOLDER - if (!mCOFInitialWearables.empty()) - { - for (U8 i = 0; i < mCOFInitialWearables.size(); ++i) - { - // Fetch the wearables in the current outfit folder - InitialWearableData *wearable_data = new InitialWearableData(mCOFInitialWearables[i]); // This will be deleted in the callback. - if (wearable_data->mAssetID.notNull()) - { - LLWearableList::instance().getAsset(wearable_data->mAssetID, - LLStringUtil::null, - LLWearableDictionary::getAssetType(wearable_data->mType), - LLAgentWearables::onInitialWearableAssetArrived, (void*)(wearable_data)); - } - else - { - llinfos << "Invalid wearable, type " << wearable_data->mType << " itemID " - << wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl; - } - } - } - else -#endif if (!mAgentInitialWearables.empty()) // We have an empty current outfit folder, use the message data instead. { LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT); @@ -1882,7 +1900,7 @@ void LLInitialWearablesFetch::processInitialWearables() { // Populate the current outfit folder with links to the wearables passed in the message InitialWearableData *wearable_data = new InitialWearableData(mAgentInitialWearables[i]); // This will be deleted in the callback. - + if (wearable_data->mAssetID.notNull()) { #ifdef USE_CURRENT_OUTFIT_FOLDER @@ -1899,7 +1917,7 @@ void LLInitialWearablesFetch::processInitialWearables() else { llinfos << "Invalid wearable, type " << wearable_data->mType << " itemID " - << wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl; + << wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl; } } } @@ -1908,3 +1926,5 @@ void LLInitialWearablesFetch::processInitialWearables() LL_WARNS("Wearables") << "No current outfit folder items found and no initial wearables fallback message received." << LL_ENDL; } } + + diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index b415ef9eb3..cb4de555d5 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -182,6 +182,7 @@ public: static void userRemoveWearable(void* userdata); // userdata is EWearableType static void userRemoveAllClothes(void* userdata); // userdata is NULL static void userRemoveAllAttachments(void* userdata); // userdata is NULL + static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array); BOOL itemUpdatePending(const LLUUID& item_id) const; U32 itemUpdatePendingCount() const; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp new file mode 100644 index 0000000000..6c234f23fe --- /dev/null +++ b/indra/newview/llappearancemgr.cpp @@ -0,0 +1,793 @@ +/** + * @file llappearancemgr.cpp + * @brief Manager for initiating appearance changes on the viewer + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llappearancemgr.h" +#include "llinventorymodel.h" +#include "llnotifications.h" +#include "llgesturemgr.h" +#include "llinventorybridge.h" +#include "llwearablelist.h" +#include "llagentwearables.h" +#include "llagent.h" +#include "llvoavatar.h" +#include "llvoavatarself.h" +#include "llviewerregion.h" +#include "llfloatercustomize.h" + +class LLWearInventoryCategoryCallback : public LLInventoryCallback +{ +public: + LLWearInventoryCategoryCallback(const LLUUID& cat_id, bool append) + { + mCatID = cat_id; + mAppend = append; + } + void fire(const LLUUID& item_id) + { + /* + * Do nothing. We only care about the destructor + * + * The reason for this is that this callback is used in a hack where the + * same callback is given to dozens of items, and the destructor is called + * after the last item has fired the event and dereferenced it -- if all + * the events actually fire! + */ + } + +protected: + ~LLWearInventoryCategoryCallback() + { + // Is the destructor called by ordinary dereference, or because the app's shutting down? + // If the inventory callback manager goes away, we're shutting down, no longer want the callback. + if( LLInventoryCallbackManager::is_instantiated() ) + { + LLAppearanceManager::wearInventoryCategoryOnAvatar(gInventory.getCategory(mCatID), mAppend); + } + else + { + llwarns << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl; + } + } + +private: + LLUUID mCatID; + bool mAppend; +}; + +class LLOutfitObserver : public LLInventoryFetchObserver +{ +public: + LLOutfitObserver(const LLUUID& cat_id, bool copy_items, bool append) : + mCatID(cat_id), + mCopyItems(copy_items), + mAppend(append) + {} + ~LLOutfitObserver() {} + virtual void done(); //public + +protected: + LLUUID mCatID; + bool mCopyItems; + bool mAppend; +}; + +void LLOutfitObserver::done() +{ + // We now have an outfit ready to be copied to agent inventory. Do + // it, and wear that outfit normally. + if(mCopyItems) + { + LLInventoryCategory* cat = gInventory.getCategory(mCatID); + std::string name; + if(!cat) + { + // should never happen. + name = "New Outfit"; + } + else + { + name = cat->getName(); + } + LLViewerInventoryItem* item = NULL; + item_ref_t::iterator it = mComplete.begin(); + item_ref_t::iterator end = mComplete.end(); + LLUUID pid; + for(; it < end; ++it) + { + item = (LLViewerInventoryItem*)gInventory.getItem(*it); + if(item) + { + if(LLInventoryType::IT_GESTURE == item->getInventoryType()) + { + pid = gInventory.findCategoryUUIDForType(LLAssetType::AT_GESTURE); + } + else + { + pid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING); + } + break; + } + } + if(pid.isNull()) + { + pid = gInventory.getRootFolderID(); + } + + LLUUID cat_id = gInventory.createNewCategory( + pid, + LLAssetType::AT_NONE, + name); + mCatID = cat_id; + LLPointer<LLInventoryCallback> cb = new LLWearInventoryCategoryCallback(mCatID, mAppend); + it = mComplete.begin(); + for(; it < end; ++it) + { + item = (LLViewerInventoryItem*)gInventory.getItem(*it); + if(item) + { + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + cat_id, + std::string(), + cb); + } + } + } + else + { + // Wear the inventory category. + LLAppearanceManager::wearInventoryCategoryOnAvatar(gInventory.getCategory(mCatID), mAppend); + } +} + +class LLOutfitFetch : public LLInventoryFetchDescendentsObserver +{ +public: + LLOutfitFetch(bool copy_items, bool append) : mCopyItems(copy_items), mAppend(append) {} + ~LLOutfitFetch() {} + virtual void done(); +protected: + bool mCopyItems; + bool mAppend; +}; + +void LLOutfitFetch::done() +{ + // What we do here is get the complete information on the items in + // the library, and set up an observer that will wait for that to + // happen. + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + gInventory.collectDescendents(mCompleteFolders.front(), + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH); + S32 count = item_array.count(); + if(!count) + { + llwarns << "Nothing fetched in category " << mCompleteFolders.front() + << llendl; + //dec_busy_count(); + gInventory.removeObserver(this); + delete this; + return; + } + + LLOutfitObserver* outfit_observer = new LLOutfitObserver(mCompleteFolders.front(), mCopyItems, mAppend); + LLInventoryFetchObserver::item_ref_t ids; + for(S32 i = 0; i < count; ++i) + { + ids.push_back(item_array.get(i)->getUUID()); + } + + // clean up, and remove this as an observer since the call to the + // outfit could notify observers and throw us into an infinite + // loop. + //dec_busy_count(); + gInventory.removeObserver(this); + delete this; + + // increment busy count and either tell the inventory to check & + // call done, or add this object to the inventory for observation. + //inc_busy_count(); + + // do the fetch + outfit_observer->fetchItems(ids); + if(outfit_observer->isEverythingComplete()) + { + // everything is already here - call done. + outfit_observer->done(); + } + else + { + // it's all on it's way - add an observer, and the inventory + // will call done for us when everything is here. + gInventory.addObserver(outfit_observer); + } +} + +class LLUpdateAppearanceOnCount: public LLInventoryCallback +{ +public: + LLUpdateAppearanceOnCount(S32 count): + mCount(count) + { + } + + virtual ~LLUpdateAppearanceOnCount() + { + } + + /* virtual */ void fire(const LLUUID& inv_item) + { + mCount--; + if (mCount==0) + { + done(); + } + } + + void done() + { + LLAppearanceManager::updateAppearanceFromCOF(); + } +private: + S32 mCount; +}; + +struct LLFoundData +{ + LLFoundData(const LLUUID& item_id, + const LLUUID& asset_id, + const std::string& name, + LLAssetType::EType asset_type) : + mItemID(item_id), + mAssetID(asset_id), + mName(name), + mAssetType(asset_type), + mWearable( NULL ) {} + + LLUUID mItemID; + LLUUID mAssetID; + std::string mName; + LLAssetType::EType mAssetType; + LLWearable* mWearable; +}; + + +struct LLWearableHoldingPattern +{ + LLWearableHoldingPattern() : mResolved(0) {} + ~LLWearableHoldingPattern() + { + for_each(mFoundList.begin(), mFoundList.end(), DeletePointer()); + mFoundList.clear(); + } + typedef std::list<LLFoundData*> found_list_t; + found_list_t mFoundList; + S32 mResolved; + bool append; +}; + + +void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventoryModel::item_array_t& src) +{ + LLInventoryModel::item_array_t new_dst; + std::set<LLUUID> mark_inventory; + std::set<LLUUID> mark_asset; + + S32 inventory_dups = 0; + S32 asset_dups = 0; + + for (LLInventoryModel::item_array_t::const_iterator src_pos = src.begin(); + src_pos != src.end(); + ++src_pos) + { + LLUUID src_item_id = (*src_pos)->getLinkedUUID(); + mark_inventory.insert(src_item_id); + LLUUID src_asset_id = (*src_pos)->getAssetUUID(); + mark_asset.insert(src_asset_id); + } + + for (LLInventoryModel::item_array_t::const_iterator dst_pos = dst.begin(); + dst_pos != dst.end(); + ++dst_pos) + { + LLUUID dst_item_id = (*dst_pos)->getLinkedUUID(); + + if (mark_inventory.find(dst_item_id) == mark_inventory.end()) + { + } + else + { + inventory_dups++; + } + + LLUUID dst_asset_id = (*dst_pos)->getAssetUUID(); + + if (mark_asset.find(dst_asset_id) == mark_asset.end()) + { + // Item is not already present in COF. + new_dst.put(*dst_pos); + mark_asset.insert(dst_item_id); + } + else + { + asset_dups++; + } + } + llinfos << "removeDups, original " << dst.count() << " final " << new_dst.count() + << " inventory dups " << inventory_dups << " asset_dups " << asset_dups << llendl; + + dst = new_dst; +} + + +/* static */ LLUUID LLAppearanceManager::getCOF() +{ + return gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT); +} + +// Update appearance from outfit folder. +/* static */ void LLAppearanceManager::changeOutfit(bool proceed, const LLUUID& category, bool append, bool follow_folder_links) +{ + if (!proceed) + return; + + updateCOFFromOutfit(category, append, follow_folder_links); +} + +// Update COF contents from outfit folder. +/* static */ void LLAppearanceManager::updateCOFFromOutfit(const LLUUID& category, bool append, bool follow_folder_links) +{ + // BAP consolidate into one "get all 3 types of descendents" function, use both places. + LLInventoryModel::item_array_t wear_items; + LLInventoryModel::item_array_t obj_items; + LLInventoryModel::item_array_t gest_items; + getUserDescendents(category, wear_items, obj_items, gest_items, follow_folder_links); + + // Find all the wearables that are in the category's subtree. + lldebugs << "updateCOFFromOutfit()" << llendl; + if( !wear_items.count() && !obj_items.count() && !gest_items.count()) + { + LLNotifications::instance().add("CouldNotPutOnOutfit"); + return; + } + + const LLUUID ¤t_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT); + // Processes that take time should show the busy cursor + //inc_busy_count(); + + LLInventoryModel::cat_array_t cof_cats; + LLInventoryModel::item_array_t cof_items; + gInventory.collectDescendents(current_outfit_id, cof_cats, cof_items, + LLInventoryModel::EXCLUDE_TRASH); + if (append) + { + // Remove duplicates + removeDuplicateItems(wear_items, cof_items); + removeDuplicateItems(obj_items, cof_items); + removeDuplicateItems(gest_items, cof_items); + } + + + if (wear_items.count() > 0 || obj_items.count() > 0) + { + if (!append) + { + // Remove all current outfit folder links if we're now replacing the contents. + for (S32 i = 0; i < cof_items.count(); ++i) + { + gInventory.purgeObject(cof_items.get(i)->getUUID()); + } + } + } + + // BAP should we just link all contents, rather than restricting to these 3 types? + + S32 total_links = gest_items.count() + wear_items.count() + obj_items.count(); + LLPointer<LLUpdateAppearanceOnCount> link_waiter = new LLUpdateAppearanceOnCount(total_links); + + // Link all gestures in this folder + if (gest_items.count() > 0) + { + llinfos << "Linking " << gest_items.count() << " gestures" << llendl; + for (S32 i = 0; i < gest_items.count(); ++i) + { + const LLInventoryItem* gest_item = gest_items.get(i).get(); + link_inventory_item(gAgent.getID(), gest_item->getLinkedUUID(), current_outfit_id, + gest_item->getName(), + LLAssetType::AT_LINK, link_waiter); + } + } + + // Link all wearables + if(wear_items.count() > 0) + { + llinfos << "Linking " << wear_items.count() << " wearables" << llendl; + for(S32 i = 0; i < wear_items.count(); ++i) + { + // Populate the current outfit folder with links to the newly added wearables + const LLInventoryItem* wear_item = wear_items.get(i).get(); + link_inventory_item(gAgent.getID(), + wear_item->getLinkedUUID(), // If this item is a link, then we'll use the linked item's UUID. + current_outfit_id, + wear_item->getName(), + LLAssetType::AT_LINK, + link_waiter); + } + } + + // Link all attachments. + if( obj_items.count() > 0 ) + { + llinfos << "Linking " << obj_items.count() << " attachments" << llendl; + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if( avatar ) + { + for(S32 i = 0; i < obj_items.count(); ++i) + { + const LLInventoryItem* obj_item = obj_items.get(i).get(); + link_inventory_item(gAgent.getID(), + obj_item->getLinkedUUID(), // If this item is a link, then we'll use the linked item's UUID. + current_outfit_id, + obj_item->getName(), + LLAssetType::AT_LINK, link_waiter); + } + } + } + + // In the particular case that we're switching to a different outfit, + // create a link to the folder that we wore. + LLViewerInventoryCategory* catp = gInventory.getCategory(category); + if (!append && catp && catp->getPreferredType() == LLAssetType::AT_OUTFIT) + { + link_inventory_item(gAgent.getID(), category, current_outfit_id, catp->getName(), + LLAssetType::AT_LINK_FOLDER, LLPointer<LLInventoryCallback>(NULL)); + } +} + +/* static */ +void LLAppearanceManager::onWearableAssetFetch(LLWearable* wearable, void* data) +{ + LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data; + bool append = holder->append; + + if(wearable) + { + for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin(); + iter != holder->mFoundList.end(); ++iter) + { + LLFoundData* data = *iter; + if(wearable->getAssetID() == data->mAssetID) + { + data->mWearable = wearable; + break; + } + } + } + holder->mResolved += 1; + if(holder->mResolved >= (S32)holder->mFoundList.size()) + { + LLAppearanceManager::updateAgentWearables(holder, append); + } +} + +/* static */ +void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder, bool append) +{ + lldebugs << "updateAgentWearables()" << llendl; + LLInventoryItem::item_array_t items; + LLDynamicArray< LLWearable* > wearables; + + // For each wearable type, find the first instance in the category + // that we recursed through. + for( S32 i = 0; i < WT_COUNT; i++ ) + { + for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin(); + iter != holder->mFoundList.end(); ++iter) + { + LLFoundData* data = *iter; + LLWearable* wearable = data->mWearable; + if( wearable && ((S32)wearable->getType() == i) ) + { + LLViewerInventoryItem* item; + item = (LLViewerInventoryItem*)gInventory.getItem(data->mItemID); + if( item && (item->getAssetUUID() == wearable->getAssetID()) ) + { + items.put(item); + wearables.put(wearable); + } + break; + } + } + } + + if(wearables.count() > 0) + { + gAgentWearables.setWearableOutfit(items, wearables, !append); + gInventory.notifyObservers(); + } + + delete holder; + +// dec_busy_count(); +} + +/* static */ void LLAppearanceManager::updateAppearanceFromCOF() +{ + bool follow_folder_links = true; + LLUUID current_outfit_id = getCOF(); + + // Find all the wearables that are in the COF's subtree. + lldebugs << "LLAppearanceManager::updateFromCOF()" << llendl; + LLInventoryModel::item_array_t wear_items; + LLInventoryModel::item_array_t obj_items; + LLInventoryModel::item_array_t gest_items; + getUserDescendents(current_outfit_id, wear_items, obj_items, gest_items, follow_folder_links); + + if( !wear_items.count() && !obj_items.count() && !gest_items.count()) + { + LLNotifications::instance().add("CouldNotPutOnOutfit"); + return; + } + + // Processes that take time should show the busy cursor + //inc_busy_count(); // BAP this is currently a no-op in llinventorybridge.cpp - do we need it? + + // Activate all gestures in this folder + if (gest_items.count() > 0) + { + llinfos << "Activating " << gest_items.count() << " gestures" << llendl; + + LLGestureManager::instance().activateGestures(gest_items); + + // Update the inventory item labels to reflect the fact + // they are active. + LLViewerInventoryCategory* catp = gInventory.getCategory(current_outfit_id); + if (catp) + { + gInventory.updateCategory(catp); + gInventory.notifyObservers(); + } + } + + if(wear_items.count() > 0) + { + // Note: can't do normal iteration, because if all the + // wearables can be resolved immediately, then the + // callback will be called (and this object deleted) + // before the final getNextData(). + LLWearableHoldingPattern* holder = new LLWearableHoldingPattern; + LLFoundData* found; + LLDynamicArray<LLFoundData*> found_container; + for(S32 i = 0; i < wear_items.count(); ++i) + { + found = new LLFoundData(wear_items.get(i)->getUUID(), + wear_items.get(i)->getAssetUUID(), + wear_items.get(i)->getName(), + wear_items.get(i)->getType()); + holder->mFoundList.push_front(found); + found_container.put(found); + } + for(S32 i = 0; i < wear_items.count(); ++i) + { + holder->append = false; + found = found_container.get(i); + + // Fetch the wearables about to be worn. + LLWearableList::instance().getAsset(found->mAssetID, + found->mName, + found->mAssetType, + LLAppearanceManager::onWearableAssetFetch, + (void*)holder); + } + } + + + //If the folder doesn't contain only gestures, take off all attachments. + if (!(wear_items.count() == 0 && obj_items.count() == 0 && gest_items.count() > 0) ) + { + LLAgentWearables::userRemoveAllAttachments(NULL); + } + + if( obj_items.count() > 0 ) + { + // We've found some attachments. Add these. + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if( avatar ) + { + LLAgentWearables::userAttachMultipleAttachments(obj_items); + } + } +} + +/* static */ void LLAppearanceManager::getUserDescendents(const LLUUID& category, + LLInventoryModel::item_array_t& wear_items, + LLInventoryModel::item_array_t& obj_items, + LLInventoryModel::item_array_t& gest_items, + bool follow_folder_links) +{ + LLInventoryModel::cat_array_t wear_cats; + LLFindWearables is_wearable; + gInventory.collectDescendentsIf(category, + wear_cats, + wear_items, + LLInventoryModel::EXCLUDE_TRASH, + is_wearable, + follow_folder_links); + + LLInventoryModel::cat_array_t obj_cats; + LLIsType is_object( LLAssetType::AT_OBJECT ); + gInventory.collectDescendentsIf(category, + obj_cats, + obj_items, + LLInventoryModel::EXCLUDE_TRASH, + is_object, + follow_folder_links); + + // Find all gestures in this folder + LLInventoryModel::cat_array_t gest_cats; + LLIsType is_gesture( LLAssetType::AT_GESTURE ); + gInventory.collectDescendentsIf(category, + gest_cats, + gest_items, + LLInventoryModel::EXCLUDE_TRASH, + is_gesture, + follow_folder_links); +} + +void LLAppearanceManager::wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append) +{ + if(!category) return; + + lldebugs << "wearInventoryCategory( " << category->getName() + << " )" << llendl; + // What we do here is get the complete information on the items in + // the inventory, and set up an observer that will wait for that to + // happen. + LLOutfitFetch* outfit_fetcher = new LLOutfitFetch(copy, append); + LLInventoryFetchDescendentsObserver::folder_ref_t folders; + folders.push_back(category->getUUID()); + outfit_fetcher->fetchDescendents(folders); + //inc_busy_count(); + if(outfit_fetcher->isEverythingComplete()) + { + // everything is already here - call done. + outfit_fetcher->done(); + } + else + { + // it's all on it's way - add an observer, and the inventory + // will call done for us when everything is here. + gInventory.addObserver(outfit_fetcher); + } +} + +// *NOTE: hack to get from avatar inventory to avatar +/* static */ +void LLAppearanceManager::wearInventoryCategoryOnAvatar( LLInventoryCategory* category, bool append ) +{ + // Avoid unintentionally overwriting old wearables. We have to do + // this up front to avoid having to deal with the case of multiple + // wearables being dirty. + if(!category) return; + lldebugs << "wearInventoryCategoryOnAvatar( " << category->getName() + << " )" << llendl; + + bool follow_folder_links = (category->getPreferredType() == LLAssetType::AT_CURRENT_OUTFIT || category->getPreferredType() == LLAssetType::AT_OUTFIT ); + if( gFloaterCustomize ) + { + gFloaterCustomize->askToSaveIfDirty(boost::bind(LLAppearanceManager::changeOutfit, _1, category->getUUID(), append, follow_folder_links)); + } + else + { + LLAppearanceManager::changeOutfit(TRUE, category->getUUID(), append, follow_folder_links ); + } +} + +/* static */ +void LLAppearanceManager::wearOutfitByName(const std::string& name) +{ + llinfos << "Wearing category " << name << llendl; + //inc_busy_count(); + + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + LLNameCategoryCollector has_name(name); + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH, + has_name); + bool copy_items = false; + LLInventoryCategory* cat = NULL; + if (cat_array.count() > 0) + { + // Just wear the first one that matches + cat = cat_array.get(0); + } + else + { + gInventory.collectDescendentsIf(LLUUID::null, + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH, + has_name); + if(cat_array.count() > 0) + { + cat = cat_array.get(0); + copy_items = true; + } + } + + if(cat) + { + LLAppearanceManager::wearInventoryCategory(cat, copy_items, false); + } + else + { + llwarns << "Couldn't find outfit " <<name<< " in wearOutfitByName()" + << llendl; + } + + //dec_busy_count(); +} + +void LLAppearanceManager::wearItem( LLInventoryItem* item, bool do_update ) +{ + // BAP add check for already in COF. + LLPointer<LLInventoryCallback> cb = do_update ? new ModifiedCOFCallback : 0; + link_inventory_item( gAgent.getID(), + item->getLinkedUUID(), + getCOF(), + item->getName(), + LLAssetType::AT_LINK, + cb); +} + +void LLAppearanceManager::wearEnsemble( LLInventoryCategory* cat, bool do_update ) +{ + // BAP add check for already in COF. + LLPointer<LLInventoryCallback> cb = do_update ? new ModifiedCOFCallback : 0; + link_inventory_item( gAgent.getID(), + cat->getLinkedUUID(), + getCOF(), + cat->getName(), + LLAssetType::AT_LINK_FOLDER, + cb); +} + diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h new file mode 100644 index 0000000000..89b95833d7 --- /dev/null +++ b/indra/newview/llappearancemgr.h @@ -0,0 +1,70 @@ +/** + * @file llappearancemgr.h + * @brief Manager for initiating appearance changes on the viewer + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLAPPEARANCEMGR_H +#define LL_LLAPPEARANCEMGR_H + +#include "llsingleton.h" +#include "llinventorymodel.h" + +class LLWearable; +struct LLWearableHoldingPattern; + +class LLAppearanceManager: public LLSingleton<LLAppearanceManager> +{ +public: + static void updateAppearanceFromCOF(); + static bool needToSaveCOF(); + static void changeOutfit(bool proceed, const LLUUID& category, bool append, bool follow_folder_links); + static void updateCOFFromOutfit(const LLUUID& category, bool append, bool follow_folder_links); + static void wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append); + static void wearInventoryCategoryOnAvatar(LLInventoryCategory* category, bool append); + static void wearOutfitByName(const std::string& name); + + // Add COF link to individual item. + static void wearItem(LLInventoryItem* item, bool do_update = true); + + // Add COF link to ensemble folder. + static void wearEnsemble(LLInventoryCategory* item, bool do_update = true); + +private: + static LLUUID getCOF(); + static void getUserDescendents(const LLUUID& category, + LLInventoryModel::item_array_t& wear_items, + LLInventoryModel::item_array_t& obj_items, + LLInventoryModel::item_array_t& gest_items, + bool follow_folder_links); + static void onWearableAssetFetch(LLWearable* wearable, void* data); + static void updateAgentWearables(LLWearableHoldingPattern* holder, bool append); +}; + +#endif diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 9fe02a8ead..19e1273dc6 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -34,8 +34,7 @@ #include "llappviewer.h" -#include "llprimitive.h" - +// Viewer includes #include "llversionviewer.h" #include "llfeaturemanager.h" #include "lluictrlfactory.h" @@ -80,7 +79,10 @@ // Linden library includes #include "llmemory.h" +#include "llprimitive.h" #include "llurlaction.h" +#include "llvfsthread.h" +#include "llvolumemgr.h" // Third party library includes #include <boost/bind.hpp> diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 5f71b6e3f6..4819703e72 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -41,6 +41,7 @@ #include "llagent.h" #include "llappviewer.h" // for gLastVersionChannel +#include "llcachename.h" #include "llcallingcard.h" // for LLAvatarTracker #include "llinventorymodel.h" // for gInventory.findCategoryUUIDForType #include "llimview.h" // for gIMMgr diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index a121d327f7..2e64c10bb2 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -41,6 +41,9 @@ #include "llvoiceclient.h" static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list"); +static LLDefaultChildRegistry::Register<LLAvatarListTmp> r_tmp("avatar_list_tmp"); + +static const std::string COMMENT_TEXTBOX = "comment_text"; LLAvatarList::Params::Params() : @@ -302,3 +305,213 @@ void LLAvatarList::updateVolume() icon_cell->setValue(getVolumeIcon(speaker_id)); } } + + + + +#include "llavatarlistitem.h" + +LLAvatarListTmp::Params::Params() +: +volume_column_width("volume_column_width", 0) +, online_go_first("online_go_first", true) +{ +} + + + +LLAvatarListTmp::LLAvatarListTmp(const Params& p) +: LLFlatListView(p) +, mHaveVolumeColumn(p.volume_column_width > 0) +, mOnlineGoFirst(p.online_go_first) +{ + LLRect item_list_rect = getLocalRect(); + item_list_rect.stretch( -getBorderWidth()); + + LLTextBox::Params text_p; + text_p.name(COMMENT_TEXTBOX); + text_p.border_visible(false); + text_p.rect(item_list_rect); + text_p.follows.flags(FOLLOWS_ALL); + addChild(LLUICtrlFactory::create<LLTextBox>(text_p)); +} + +// virtual +void LLAvatarListTmp::draw() +{ + LLFlatListView::draw(); + if (mHaveVolumeColumn) + { + updateVolume(); + } +} + +std::vector<LLUUID> LLAvatarListTmp::getSelectedIDs() +{ + LLUUID selected_id; + std::vector<LLUUID> avatar_ids; + + getSelectedUUIDs(avatar_ids); + + return avatar_ids; +} + +void LLAvatarListTmp::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos) +{ + LLAvatarListItem* item = new LLAvatarListItem(); + item->showStatus(true); + item->showInfoBtn(true); + item->showSpeakingIndicator(true); + item->setName(name); + item->setAvatarId(id); + + item->childSetVisible("info_btn", false); + + addItem(item, id, pos); + + setCommentVisible(false); +} + +BOOL LLAvatarListTmp::update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter) +{ + BOOL have_names = TRUE; + + // Save selection. + std::vector<LLUUID> selected_ids = getSelectedIDs(); + LLUUID current_id = getSelectedUUID(); + LLRect pos = getScrolledViewRect(); + + std::vector<LLUUID>::const_iterator buddy_it = all_buddies.begin(); + clear(); + for(; buddy_it != all_buddies.end(); ++buddy_it) + { + std::string name; + const LLUUID& buddy_id = *buddy_it; + have_names &= gCacheName->getFullName(buddy_id, name); + if (name_filter != LLStringUtil::null && !findInsensitive(name, name_filter)) + continue; + addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id)); + } + + // Changed item in place, need to request sort and update columns + // because we might have changed data in a column on which the user + // has already sorted. JC + // updateSort(); // TODO: implement sorting + + // re-select items + // selectMultiple(selected_ids); // TODO: implement in LLFlatListView if need + selectItemByUUID(current_id); + + scrollToShowRect(pos); + + + setCommentVisible(false); + + return have_names; +} + + +const LLUUID LLAvatarListTmp::getCurrentID() const +{ + return getSelectedUUID(); +} + +void LLAvatarListTmp::setCommentText(const std::string& comment_text) +{ + getChild<LLTextBox>(COMMENT_TEXTBOX)->setValue(comment_text); +} + + +////////////////////////////////////////////////////////////////////////// +// PROTECTED SECTION +////////////////////////////////////////////////////////////////////////// + +// virtual overridden +bool LLAvatarListTmp::removeItemPair(item_pair_t* item_pair) +{ + bool removed = LLFlatListView::removeItemPair(item_pair); + setCommentVisible(size() == 0); + return removed; +} + + +////////////////////////////////////////////////////////////////////////// +// PRIVATE SECTION +////////////////////////////////////////////////////////////////////////// + +// static +std::string LLAvatarListTmp::getVolumeIcon(const LLUUID& id) +{ + // + // Determine icon appropriate for the current avatar volume. + // + // *TODO: remove this in favor of LLOutputMonitorCtrl + // when ListView widget is implemented + // which is capable of containing arbitrary widgets. + // + static LLOutputMonitorCtrl::Params default_monitor_params(LLUICtrlFactory::getDefaultParams<LLOutputMonitorCtrl>()); + bool muted = gVoiceClient->getIsModeratorMuted(id) || gVoiceClient->getOnMuteList(id); + F32 power = gVoiceClient->getCurrentPower(id); + std::string icon; + + if (muted) + { + icon = default_monitor_params.image_mute.name; + } + else if (power == 0.f) + { + icon = default_monitor_params.image_off.name; + } + else if (power < LLVoiceClient::OVERDRIVEN_POWER_LEVEL) + { + S32 icon_image_idx = llmin(2, llfloor((power / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f)); + switch(icon_image_idx) + { + default: + case 0: + icon = default_monitor_params.image_on.name; + break; + case 1: + icon = default_monitor_params.image_level_1.name; + break; + case 2: + icon = default_monitor_params.image_level_2.name; + break; + } + } + else + { + // overdriven + icon = default_monitor_params.image_level_3.name; + } + + return icon; +} + +// Update volume column for all list rows. +void LLAvatarListTmp::updateVolume() +{ + // TODO: implement via Listener + /* + item_list& items = getItemList(); + + for (item_list::iterator item_it = items.begin(); + item_it != items.end(); + ++item_it) + { + LLScrollListItem* itemp = (*item_it); + LLUUID speaker_id = itemp->getUUID(); + + LLScrollListCell* icon_cell = itemp->getColumn(COL_VOLUME); + if (icon_cell) + icon_cell->setValue(getVolumeIcon(speaker_id)); + } + */ +} + +void LLAvatarListTmp::setCommentVisible(bool visible) const +{ + getChildView(COMMENT_TEXTBOX)->setVisible(visible); +} + +// EOF diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index 8b419dbb57..639ed83ada 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -75,4 +75,46 @@ private: bool mOnlineGoFirst; }; + +#include "llflatlistview.h" + +class LLAvatarListTmp : public LLFlatListView +{ + LOG_CLASS(LLAvatarListTmp); +public: + struct Params : public LLInitParam::Block<Params, LLFlatListView::Params> + { + Optional<S32> volume_column_width; + Optional<bool> online_go_first; + Params(); + }; + + LLAvatarListTmp(const Params&); + virtual ~LLAvatarListTmp() {} + + /*virtual*/ void draw(); + + BOOL update(const std::vector<LLUUID>& all_buddies, + const std::string& name_filter = LLStringUtil::null); + + const LLUUID getCurrentID() const; + void setCommentText( const std::string& comment_text); + +protected: + std::vector<LLUUID> getSelectedIDs(); + void addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM); + /*virtual*/ bool removeItemPair(item_pair_t* item_pair); + +private: + static std::string getVolumeIcon(const LLUUID& id); /// determine volume icon from current avatar volume + void updateVolume(); // update volume for all avatars + void setCommentVisible(bool visible) const; + + bool mHaveVolumeColumn; + bool mOnlineGoFirst; + +}; + + + #endif // LL_LLAVATARLIST_H diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 253c2ee9a6..feae8202bc 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -2,9 +2,9 @@ * @file llavatarlistitem.cpp * @avatar list item source file * - * $LicenseInfo:firstyear=2004&license=viewergpl$ + * $LicenseInfo:firstyear=2009&license=viewergpl$ * - * Copyright (c) 2004-2009, Linden Research, Inc. + * Copyright (c) 2009, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -33,70 +33,39 @@ #include "llviewerprecompiledheaders.h" -#include "llfloaterreg.h" #include "llavatarlistitem.h" -#include "llagent.h" - - -//--------------------------------------------------------------------------------- -LLAvatarListItem::LLAvatarListItem(const Params& p) : LLPanel() +#include "llfloaterreg.h" +#include "llagent.h" +#include "lloutputmonitorctrl.h" +#include "llavatariconctrl.h" +#include "llbutton.h" + + +LLAvatarListItem::LLAvatarListItem() +: LLPanel(), + mAvatarIcon(NULL), + mAvatarName(NULL), + mStatus(NULL), + mSpeakingIndicator(NULL), + mInfoBtn(NULL) { - mNeedsArrange = false; LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_list_item.xml"); - - mStatus = NULL; - mInfo = NULL; - mProfile = NULL; - mInspector = NULL; - - mAvatar = getChild<LLAvatarIconCtrl>("avatar_icon"); - //mAvatar->setValue(p.avatar_icon); - mName = getChild<LLTextBox>("name"); - //mName->setText(p.user_name); - - init(p); - - } -//--------------------------------------------------------------------------------- -void LLAvatarListItem::init(const Params& p) +BOOL LLAvatarListItem::postBuild() { - mLocator = getChild<LLIconCtrl>("locator"); - - mStatus = getChild<LLTextBox>("user_status"); - - mInfo = getChild<LLButton>("info_btn"); - mInfo->setVisible(false); - - mProfile = getChild<LLButton>("profile_btn"); - mProfile->setVisible(false); - - if(!p.buttons.locator) - { - mLocator->setVisible(false); - delete mLocator; - mLocator = NULL; - } + mAvatarIcon = getChild<LLAvatarIconCtrl>("avatar_icon"); + mAvatarName = getChild<LLTextBox>("avatar_name"); + mStatus = getChild<LLTextBox>("avatar_status"); - if(!p.buttons.status) - { - mStatus->setVisible(false); - delete mStatus; - mStatus = NULL; - } + mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator"); + mInfoBtn = getChild<LLButton>("info_btn"); - if(!p.buttons.info) - { - delete mInfo; - mInfo = NULL; - } - else - { - mInfo->setClickedCallback(boost::bind(&LLAvatarListItem::onInfoBtnClick, this)); - } + mInfoBtn->setVisible(false); + mInfoBtn->setClickedCallback(boost::bind(&LLAvatarListItem::onInfoBtnClick, this)); +/* if(!p.buttons.profile) { delete mProfile; @@ -125,150 +94,72 @@ void LLAvatarListItem::init(const Params& p) mInfo->setRect(rect); } } - +*/ + return TRUE; } -//--------------------------------------------------------------------------------- -void LLAvatarListItem::reshape(S32 width, S32 height, BOOL called_from_parent) -{ - if(!mNeedsArrange) - { - LLView::reshape(width, height, called_from_parent); - return; - } - - LLRect rect; - S32 profile_delta = 0; - S32 width_delta = getRect().getWidth() - width; - - if(!mProfile) - { - profile_delta = 30; - } - else - { - rect.setLeftTopAndSize(mProfile->getRect().mLeft - width_delta, mProfile->getRect().mTop, mProfile->getRect().getWidth(), mProfile->getRect().getHeight()); - mProfile->setRect(rect); - } - - width_delta += profile_delta; - - if(mInfo) - { - rect.setLeftTopAndSize(mInfo->getRect().mLeft - width_delta, mInfo->getRect().mTop, mInfo->getRect().getWidth(), mInfo->getRect().getHeight()); - mInfo->setRect(rect); - } - - if(mLocator) - { - rect.setLeftTopAndSize(mLocator->getRect().mLeft - width_delta, mLocator->getRect().mTop, mLocator->getRect().getWidth(), mLocator->getRect().getHeight()); - mLocator->setRect(rect); - } - - if(mStatus) - { - rect.setLeftTopAndSize(mStatus->getRect().mLeft - width_delta, mStatus->getRect().mTop, mStatus->getRect().getWidth(), mStatus->getRect().getHeight()); - mStatus->setRect(rect); - } - - mNeedsArrange = false; - LLView::reshape(width, height, called_from_parent); -} - -//--------------------------------------------------------------------------------- -LLAvatarListItem::~LLAvatarListItem() -{ -} -//--------------------------------------------------------------------------------- - -//--------------------------------------------------------------------------------- -BOOL LLAvatarListItem::handleHover(S32 x, S32 y, MASK mask) -{ - mYPos = y; - mXPos = x; - - return true; -} - -//--------------------------------------------------------------------------------- void LLAvatarListItem::onMouseEnter(S32 x, S32 y, MASK mask) { - setTransparentColor( *(new LLColor4((F32)0.4, (F32)0.4, (F32)0.4)) ); + childSetVisible("hovered_icon", true); + mInfoBtn->setVisible(true); - if(mInfo) - mInfo->setVisible(true); - - if(mProfile) - mProfile->setVisible(true); + LLPanel::onMouseEnter(x, y, mask); } -//--------------------------------------------------------------------------------- void LLAvatarListItem::onMouseLeave(S32 x, S32 y, MASK mask) { - if(mInfo) - { - if( mInfo->getRect().pointInRect(x, y) ) - return; - - mInfo->setVisible(false); - } - - if(mProfile) - { - if( mProfile->getRect().pointInRect(x, y) ) - return; - - mProfile->setVisible(false); - } + childSetVisible("hovered_icon", false); + mInfoBtn->setVisible(false); - setTransparentColor( *(new LLColor4((F32)0.3, (F32)0.3, (F32)0.3)) ); + LLPanel::onMouseLeave(x, y, mask); } -//--------------------------------------------------------------------------------- -void LLAvatarListItem::setStatus(int status) +void LLAvatarListItem::setStatus(const std::string& status) { + mStatus->setValue(status); } -//--------------------------------------------------------------------------------- -void LLAvatarListItem::setName(std::string name) +void LLAvatarListItem::setName(const std::string& name) { + mAvatarName->setValue(name); + mAvatarName->setToolTip(name); } -//--------------------------------------------------------------------------------- -void LLAvatarListItem::setAvatar(LLSD& data) +void LLAvatarListItem::setAvatarId(const LLUUID& id) { + mAvatarIcon->setValue(id); + mSpeakingIndicator->setSpeakerId(id); } -//--------------------------------------------------------------------------------- void LLAvatarListItem::onInfoBtnClick() { - mInspector = LLFloaterReg::showInstance("inspect_avatar", gAgent.getID()); - - if (!mInspector) - return; + LLFloaterReg::showInstance("inspect_avatar", mAvatarIcon->getValue()); - LLRect rect; + /* TODO fix positioning of inspector localPointToScreen(mXPos, mYPos, &mXPos, &mYPos); + + LLRect rect; // *TODO Vadim: rewrite this. "+= -" looks weird. - S32 delta = mYPos - mInspector->getRect().getHeight(); + S32 delta = mYPos - inspector->getRect().getHeight(); if(delta < 0) { mYPos += -delta; } - + rect.setLeftTopAndSize(mXPos, mYPos, - mInspector->getRect().getWidth(), mInspector->getRect().getHeight()); - mInspector->setRect(rect); - mInspector->setFrontmost(true); - mInspector->setVisible(true); - + inspector->getRect().getWidth(), inspector->getRect().getHeight()); + inspector->setRect(rect); + inspector->setFrontmost(true); + inspector->setVisible(true); + */ } -//--------------------------------------------------------------------------------- -void LLAvatarListItem::onProfileBtnClick() +void LLAvatarListItem::setValue( const LLSD& value ) { + if (!value.isMap()) return;; + if (!value.has("selected")) return; + childSetVisible("selected_icon", value["selected"]); } -//--------------------------------------------------------------------------------- diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index b41e0ff209..dc5606e4c2 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -2,9 +2,9 @@ * @file llavatarlistitem.h * @avatar list item header file * - * $LicenseInfo:firstyear=2004&license=viewergpl$ + * $LicenseInfo:firstyear=2009&license=viewergpl$ * - * Copyright (c) 2004-2009, Linden Research, Inc. + * Copyright (c) 2009, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -30,75 +30,45 @@ * $/LicenseInfo$ */ -#include "llavatariconctrl.h" -#include <llview.h> -#include <llpanel.h> -#include <llfloater.h> -#include <lltextbox.h> -#include <llbutton.h> -#include <lluuid.h> +#ifndef LL_LLAVATARLISTITEM_H +#define LL_LLAVATARLISTITEM_H -//#include "llfloaterminiinspector.h" +#include "llpanel.h" +#include "lloutputmonitorctrl.h" +#include "llbutton.h" +#include "lltextbox.h" -class LLAvatarListItem : public LLPanel +class LLAvatarIconCtrl; + +class LLAvatarListItem : public LLPanel { public: - struct Params : public LLInitParam::Block<Params, LLPanel::Params> - { - Optional<LLUUID> avatar_icon; - Optional<std::string> user_name; - struct avatar_list_item_buttons - { - bool status; - bool info; - bool profile; - bool locator; - avatar_list_item_buttons() : status(true), info(true), profile(true), locator(true) - {}; - } buttons; - - Params() - : avatar_icon("avatar_icon"), - user_name("user_name") - {}; - }; - - - LLAvatarListItem(const Params& p); - virtual ~LLAvatarListItem(); - - void reshape(S32 width, S32 height, BOOL called_from_parent); - - //interface - void setStatus(int status); - void setName(std::string name); - void setAvatar(LLSD& data); - void needsArrange( void ) {mNeedsArrange = true;} - + LLAvatarListItem(); + virtual ~LLAvatarListItem() {}; - //event handlers - //mouse - virtual BOOL handleHover(S32 x, S32 y, MASK mask); + virtual BOOL postBuild(); virtual void onMouseLeave(S32 x, S32 y, MASK mask); virtual void onMouseEnter(S32 x, S32 y, MASK mask); - //buttons - void onInfoBtnClick(); - void onProfileBtnClick(); + virtual void setValue(const LLSD& value); -private: - LLAvatarIconCtrl* mAvatar; - LLIconCtrl* mLocator; - LLTextBox* mName; - LLTextBox* mStatus; - LLButton* mInfo; - LLButton* mProfile; + void setStatus(const std::string& status); + void setName(const std::string& name); + void setAvatarId(const LLUUID& id); + + void onInfoBtnClick(); - S32 mYPos; - S32 mXPos; + void showSpeakingIndicator(bool show) { mSpeakingIndicator->setVisible(show); } + void showInfoBtn(bool show_info_btn) {mInfoBtn->setVisible(show_info_btn); } + void showStatus(bool show_status) {mStatus->setVisible(show_status); } - LLFloater* mInspector; - bool mNeedsArrange; - // - void init(const Params& p); +private: + LLAvatarIconCtrl*mAvatarIcon; + LLTextBox* mAvatarName; + LLTextBox* mStatus; + + LLOutputMonitorCtrl* mSpeakingIndicator; + LLButton* mInfoBtn; }; + +#endif //LL_LLAVATARLISTITEM_H diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index d166715038..06f9a86d8d 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -224,11 +224,14 @@ void LLBottomTray::setVisible(BOOL visible) BOOL LLBottomTray::handleRightMouseDown(S32 x, S32 y, MASK mask) { - if (mShowCamMoveCtrlsContextMenu) + if (!LLPanel::handleRightMouseDown(x, y, mask)) { - mShowCamMoveCtrlsContextMenu->buildDrawLabels(); - mShowCamMoveCtrlsContextMenu->updateParent(LLMenuGL::sMenuContainer); - LLMenuGL::showPopup(this, mShowCamMoveCtrlsContextMenu, x, y); + if (mShowCamMoveCtrlsContextMenu) + { + mShowCamMoveCtrlsContextMenu->buildDrawLabels(); + mShowCamMoveCtrlsContextMenu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(this, mShowCamMoveCtrlsContextMenu, x, y); + } } return TRUE; diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 3ee2c93961..96c707b08f 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -674,7 +674,7 @@ class LLChatHandler : public LLCommandHandler { public: // not allowed from outside the app - LLChatHandler() : LLCommandHandler("chat", true) { } + LLChatHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { } // Your code here bool handle(const LLSD& tokens, const LLSD& query_map, diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 9ce194c712..42ed783f94 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -670,6 +670,10 @@ LLChicletPanel::LLChicletPanel(const Params&p) LLPanel::Params panel_params; mScrollArea = LLUICtrlFactory::create<LLPanel>(panel_params,this); + + // important for Show/Hide Camera and Move controls menu in bottom tray to work properly + mScrollArea->setMouseOpaque(false); + addChild(mScrollArea); } @@ -1136,6 +1140,8 @@ LLTalkButton::LLTalkButton(const Params& p) LLOutputMonitorCtrl::Params monitor_params = p.monitor; monitor_params.draw_border(false); monitor_params.rect(monitor_rect); + monitor_params.auto_update(true); + monitor_params.speaker_id(gAgentID); mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_params); mSpeakBtn->addChild(mOutputMonitor); @@ -1147,17 +1153,6 @@ LLTalkButton::~LLTalkButton() { } -void LLTalkButton::draw() -{ - // Always provide speaking feedback. User can trigger speaking - // with keyboard or middle-mouse shortcut. - mOutputMonitor->setPower(gVoiceClient->getCurrentPower(gAgent.getID())); - mOutputMonitor->setIsTalking( gVoiceClient->getUserPTTState() ); - mSpeakBtn->setToggleState( gVoiceClient->getUserPTTState() ); - - LLUICtrl::draw(); -} - void LLTalkButton::setSpeakBtnToggleState(bool state) { mSpeakBtn->setToggleState(state); @@ -1194,13 +1189,14 @@ void LLTalkButton::onClick_ShowBtn() rect.setLeftTopAndSize(x, y, mPrivateCallPanel->getRect().getWidth(), mPrivateCallPanel->getRect().getHeight()); mPrivateCallPanel->setRect(rect); - LLAvatarListItem::Params p; - p.buttons.status = true; - p.buttons.info = true; - p.buttons.profile = false; - p.buttons.locator = true; - mPrivateCallPanel->addItem(new LLAvatarListItem(p)); + LLAvatarListItem* item = new LLAvatarListItem(); + item->showStatus(true); + item->showInfoBtn(true); + item->showSpeakingIndicator(true); + item->reshape(mPrivateCallPanel->getRect().getWidth(), item->getRect().getHeight(), FALSE); + + mPrivateCallPanel->addItem(item); mPrivateCallPanel->setVisible(TRUE); mPrivateCallPanel->setFrontmost(TRUE); diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index 91f55915ed..52bd7dbc31 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -780,7 +780,6 @@ public: /*virtual*/ ~LLTalkButton(); - /*virtual*/ void draw(); void setSpeakBtnToggleState(bool state); protected: diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp index a04182a910..af6488388a 100644 --- a/indra/newview/llcommandhandler.cpp +++ b/indra/newview/llcommandhandler.cpp @@ -38,12 +38,14 @@ // system includes #include <boost/tokenizer.hpp> +#define THROTTLE_PERIOD 15 // required secs between throttled commands + //--------------------------------------------------------------------------- // Underlying registry for command handlers, not directly accessible. //--------------------------------------------------------------------------- struct LLCommandHandlerInfo { - bool mRequireTrustedBrowser; + LLCommandHandler::EUntrustedAccess mUntrustedBrowserAccess; LLCommandHandler* mHandler; // safe, all of these are static objects }; @@ -51,7 +53,9 @@ class LLCommandHandlerRegistry { public: static LLCommandHandlerRegistry& instance(); - void add(const char* cmd, bool require_trusted_browser, LLCommandHandler* handler); + void add(const char* cmd, + LLCommandHandler::EUntrustedAccess untrusted_access, + LLCommandHandler* handler); bool dispatch(const std::string& cmd, const LLSD& params, const LLSD& query_map, @@ -72,10 +76,12 @@ LLCommandHandlerRegistry& LLCommandHandlerRegistry::instance() return instance; } -void LLCommandHandlerRegistry::add(const char* cmd, bool require_trusted_browser, LLCommandHandler* handler) +void LLCommandHandlerRegistry::add(const char* cmd, + LLCommandHandler::EUntrustedAccess untrusted_access, + LLCommandHandler* handler) { LLCommandHandlerInfo info; - info.mRequireTrustedBrowser = require_trusted_browser; + info.mUntrustedBrowserAccess = untrusted_access; info.mHandler = handler; mMap[cmd] = info; @@ -87,15 +93,37 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd, LLMediaCtrl* web, bool trusted_browser) { + static F64 last_throttle_time = 0.0; + F64 cur_time = 0.0; std::map<std::string, LLCommandHandlerInfo>::iterator it = mMap.find(cmd); if (it == mMap.end()) return false; const LLCommandHandlerInfo& info = it->second; - if (!trusted_browser && info.mRequireTrustedBrowser) + if (!trusted_browser) { - // block request from external browser, but report as - // "handled" because it was well formatted. - LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL; - return true; + switch (info.mUntrustedBrowserAccess) + { + case LLCommandHandler::UNTRUSTED_ALLOW: + // fall through and let the command be handled + break; + + case LLCommandHandler::UNTRUSTED_BLOCK: + // block request from external browser, but report as + // "handled" because it was well formatted. + LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL; + return true; + + case LLCommandHandler::UNTRUSTED_THROTTLE: + cur_time = LLTimer::getElapsedSeconds(); + if (cur_time < last_throttle_time + THROTTLE_PERIOD) + { + // block request from external browser if it happened + // within THROTTLE_PERIOD secs of the last command + LL_WARNS_ONCE("SLURL") << "Throttled SLURL command from untrusted browser" << LL_ENDL; + return true; + } + last_throttle_time = cur_time; + break; + } } if (!info.mHandler) return false; return info.mHandler->handle(params, query_map, web); @@ -106,10 +134,9 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd, //--------------------------------------------------------------------------- LLCommandHandler::LLCommandHandler(const char* cmd, - bool require_trusted_browser) + EUntrustedAccess untrusted_access) { - LLCommandHandlerRegistry::instance().add( - cmd, require_trusted_browser, this); + LLCommandHandlerRegistry::instance().add(cmd, untrusted_access, this); } LLCommandHandler::~LLCommandHandler() diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h index 5cb3ee73d4..1bae6d9414 100644 --- a/indra/newview/llcommandhandler.h +++ b/indra/newview/llcommandhandler.h @@ -43,7 +43,7 @@ public: // Inform the system you handle commands starting // with "foo" and they are only allowed from // "trusted" (pointed at Linden content) browsers - LLFooHandler() : LLCommandHandler("foo", true) { } + LLFooHandler() : LLCommandHandler("foo", UNTRUSTED_BLOCK) { } // Your code here bool handle(const LLSD& tokens, const LLSD& query_map, @@ -65,7 +65,14 @@ class LLMediaCtrl; class LLCommandHandler { public: - LLCommandHandler(const char* command, bool allow_from_untrusted_browser); + enum EUntrustedAccess + { + UNTRUSTED_ALLOW, // allow commands from untrusted browsers + UNTRUSTED_BLOCK, // ignore commands from untrusted browsers + UNTRUSTED_THROTTLE // allow untrusted, but only a few per min. + }; + + LLCommandHandler(const char* command, EUntrustedAccess untrusted_access); // Automatically registers object to get called when // command is executed. All commands can be processed // in links from LLMediaCtrl, but some (like teleport) diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index 94ea20893a..f4c4f38008 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -77,21 +77,11 @@ bool LLFloaterCamera::inAvatarViewMode() return mCurrMode == CAMERA_CTRL_MODE_AVATAR_VIEW; } -void LLFloaterCamera::resetFreeCameraMode() +void LLFloaterCamera::resetCameraMode() { - if (mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA) - { - /* Camera Tool can be deselected when we are mouse wheel scrolling into Mouse Look - In such case we are unable to determine that we will be into Mouse Look view */ - if (mPrevMode == CAMERA_CTRL_MODE_AVATAR_VIEW) - { - setMode(CAMERA_CTRL_MODE_ORBIT); - } - else - { - setMode(mPrevMode); - } - } + LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance(); + if (!floater_camera) return; + floater_camera->switchMode(CAMERA_CTRL_MODE_ORBIT); } void LLFloaterCamera::update() diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h index 04554c6493..1181c443bf 100644 --- a/indra/newview/llfloatercamera.h +++ b/indra/newview/llfloatercamera.h @@ -62,9 +62,8 @@ public: static void toPrevModeIfInAvatarViewMode(); - /* resets free camera mode to the previous mode */ - //*TODO remove, if it won't be used by LLToolCamera::handleDeselect() - void resetFreeCameraMode(); + /** resets current camera mode to orbit mode */ + static void resetCameraMode(); /* determines actual mode and updates ui */ void update(); diff --git a/indra/newview/llfloaterhandler.h b/indra/newview/llfloaterhandler.h index 31ea80c12c..cd9d8b5377 100644 --- a/indra/newview/llfloaterhandler.h +++ b/indra/newview/llfloaterhandler.h @@ -38,7 +38,7 @@ class LLFloaterHandler : public LLCommandHandler { public: - LLFloaterHandler() : LLCommandHandler("floater", true) { } + LLFloaterHandler() : LLCommandHandler("floater", UNTRUSTED_BLOCK) { } bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web); }; diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h index f007697e88..4a12543650 100644 --- a/indra/newview/llfloaterimagepreview.h +++ b/indra/newview/llfloaterimagepreview.h @@ -35,6 +35,7 @@ #include "llfloaternamedesc.h" #include "lldynamictexture.h" +#include "llpointer.h" #include "llquaternion.h" class LLComboBox; @@ -43,6 +44,7 @@ class LLViewerJointMesh; class LLVOAvatar; class LLTextBox; class LLVertexBuffer; +class LLVolume; class LLImagePreviewSculpted : public LLViewerDynamicTexture { diff --git a/indra/newview/llfloaterparcel.cpp b/indra/newview/llfloaterparcel.cpp index 44270683a0..88a39a495f 100644 --- a/indra/newview/llfloaterparcel.cpp +++ b/indra/newview/llfloaterparcel.cpp @@ -53,7 +53,7 @@ class LLParcelHandler : public LLCommandHandler { public: // requires trusted browser to trigger - LLParcelHandler() : LLCommandHandler("parcel", true) { } + LLParcelHandler() : LLCommandHandler("parcel", UNTRUSTED_THROTTLE) { } bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) { diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index e2e9734012..2dc96d1fb3 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -522,6 +522,34 @@ void LLFloaterPreference::cancel() void LLFloaterPreference::onOpen(const LLSD& key) { gAgent.sendAgentUserInfoRequest(); + /////////////////////////// From LLPanelGeneral ////////////////////////// + // if we have no agent, we can't let them choose anything + // if we have an agent, then we only let them choose if they have a choice + bool canChoose = gAgent.getID().notNull() && + (gAgent.isMature() || gAgent.isGodlike()); + + if (canChoose) + { + + // if they're not adult or a god, they shouldn't see the adult selection, so delete it + if (!gAgent.isAdult() && !gAgent.isGodlike()) + { + LLComboBox* pMaturityCombo = getChild<LLComboBox>("maturity_desired_combobox"); + // we're going to remove the adult entry from the combo. This obviously depends + // on the order of items in the XML file, but there doesn't seem to be a reasonable + // way to depend on the field in XML called 'name'. + pMaturityCombo->remove(0); + } + childSetVisible("maturity_desired_combobox", true); + childSetVisible("maturity_desired_prompt", true); + + } + else + { + childSetVisible("maturity_desired_prompt", false); + childSetVisible("maturity_desired_combobox", false); + } + LLPanelLogin::setAlwaysRefresh(true); refresh(); } @@ -1351,37 +1379,7 @@ static void applyUIColor(const std::string& color_name, LLUICtrl* ctrl, const LL //virtual BOOL LLPanelPreference::postBuild() { - if (hasChild("maturity_desired_combobox")) - { - /////////////////////////// From LLPanelGeneral ////////////////////////// - // if we have no agent, we can't let them choose anything - // if we have an agent, then we only let them choose if they have a choice - bool canChoose = gAgent.getID().notNull() && - (gAgent.isMature() || gAgent.isGodlike()); - - if (canChoose) - { - // if they're not adult or a god, they shouldn't see the adult selection, so delete it - if (!gAgent.isAdult() && !gAgent.isGodlike()) - { - LLComboBox* pMaturityCombo = getChild<LLComboBox>("maturity_desired_combobox"); - // we're going to remove the adult entry from the combo. This obviously depends - // on the order of items in the XML file, but there doesn't seem to be a reasonable - // way to depend on the field in XML called 'name'. - pMaturityCombo->remove(0); - } - childSetVisible("maturity_desired_combobox", true); - childSetVisible("maturity_desired_textbox", false); - } - else - { - childSetVisible("maturity_desired_combobox", false); - std::string selectedItemLabel = getChild<LLComboBox>("maturity_desired_combobox")->getSelectedItemLabel(); - childSetValue("maturity_desired_textbox", selectedItemLabel); - childSetVisible("maturity_desired_textbox", true); - } - } ////////////////////// PanelVoice /////////////////// if(hasChild("voice_unavailable")) { diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index f1e499e14b..490929e5a6 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -1183,6 +1183,8 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter) // you will automatically fail this time, so we only // check against items that have passed the filter S32 must_pass_generation = filter.getMustPassGeneration(); + + bool autoopen_folders = (filter.hasFilterString()); // if we have already been filtered against this generation, skip out if (getCompletedFilterGeneration() >= filter_generation) @@ -1255,7 +1257,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter) if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter.getMinRequiredGeneration())) { mMostFilteredDescendantGeneration = filter_generation; - if (getRoot()->needsAutoSelect()) + if (getRoot()->needsAutoSelect() && autoopen_folders) { (*fit)->setOpenArrangeRecursively(TRUE); } @@ -1271,7 +1273,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter) if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter_generation)) { mMostFilteredDescendantGeneration = filter_generation; - if (getRoot()->needsAutoSelect()) + if (getRoot()->needsAutoSelect() && autoopen_folders) { (*fit)->setOpenArrangeRecursively(TRUE); } diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index 31866c83c8..eec885fd29 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -33,6 +33,7 @@ #define LLFOLDERVIEWITEM_H #include "llview.h" +#include "lldarray.h" // *TODO: Eliminate, forward declare class LLFontGL; class LLFolderView; diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index 10a17476d9..d1cbe96906 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -51,7 +51,7 @@ class LLGroupHandler : public LLCommandHandler { public: // requires trusted browser to trigger - LLGroupHandler() : LLCommandHandler("group", true) { } + LLGroupHandler() : LLCommandHandler("group", UNTRUSTED_THROTTLE) { } bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) { diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp index 0262e40803..a47477c446 100644 --- a/indra/newview/llimhandler.cpp +++ b/indra/newview/llimhandler.cpp @@ -35,6 +35,7 @@ #include "llnotificationhandler.h" +#include "llagentdata.h" #include "llbottomtray.h" #include "llviewercontrol.h" #include "lltoastimpanel.h" @@ -77,9 +78,15 @@ void LLIMHandler::processNotification(const LLSD& notify) { LLSD substitutions = notification->getSubstitutions(); + // According to comments in LLIMMgr::addMessage(), if we get message + // from ourselves, the sender id is set to null. This fixes EXT-875. + LLUUID avatar_id = substitutions["FROM_ID"].asUUID(); + if (avatar_id.isNull()) + avatar_id = gAgentID; + LLToastIMPanel::Params im_p; im_p.notification = notification; - im_p.avatar_id = substitutions["FROM_ID"].asUUID(); + im_p.avatar_id = avatar_id; im_p.from = substitutions["FROM"].asString(); im_p.time = substitutions["TIME"].asString(); im_p.message = substitutions["MESSAGE"].asString(); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 901b3351c8..9ef98afe94 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -101,7 +101,8 @@ void toast_callback(const LLSD& msg){ args["FROM_ID"] = msg["from_id"]; args["SESSION_ID"] = msg["session_id"]; - LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLFloaterChatterBox::onOpen, LLFloaterChatterBox::getInstance(), msg["session_id"].asUUID())); + //LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLFloaterChatterBox::onOpen, LLFloaterChatterBox::getInstance(), msg["session_id"].asUUID())); + LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::toggle, msg["session_id"].asUUID())); } } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index adc73111e0..eb07078402 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -92,6 +92,7 @@ #include "llsidetray.h" #include "llfloateropenobject.h" #include "lltrans.h" +#include "llappearancemgr.h" using namespace LLOldEvents; @@ -111,12 +112,7 @@ void dec_busy_count() } // Function declarations -struct LLWearableHoldingPattern; void wear_add_inventory_item_on_avatar(LLInventoryItem* item); -void wear_inventory_category_on_avatar(LLInventoryCategory* category, BOOL append); -void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOOL append, BOOL follow_folder_links); -void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void*); -void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, BOOL append); void remove_inventory_category_from_avatar(LLInventoryCategory* category); void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id); bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*); @@ -161,8 +157,6 @@ std::string ICON_NAME[ICON_NAME_COUNT] = "inv_item_linkfolder.tga" }; -BOOL gAddToOutfit = FALSE; - // +=================================================+ // | LLInventoryPanelObserver | @@ -474,7 +468,7 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const { return FALSE; } - LLInventoryModel* model = getInventoryModel(); + const LLInventoryModel* model = getInventoryModel(); if (!model) { return FALSE; @@ -485,7 +479,7 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const S32 count = objects.count(); for(S32 i = 0; i < count; i++) { - LLInventoryItem *item = model->getItem(objects.get(i)); + const LLInventoryItem *item = model->getItem(objects.get(i)); if (item) { if (!LLAssetType::lookupCanLink(item->getActualType())) @@ -665,7 +659,7 @@ BOOL LLInvFVBridge::isInTrash() const { LLInventoryModel* model = getInventoryModel(); if(!model) return FALSE; - const LLUUID& trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); + const LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); return model->isObjectDescendentOf(mUUID, trash_id); } @@ -673,12 +667,12 @@ BOOL LLInvFVBridge::isLinkedObjectInTrash() const { if (isInTrash()) return TRUE; - LLInventoryObject *obj = getInventoryObject(); + const LLInventoryObject *obj = getInventoryObject(); if (obj && obj->getIsLinkType()) { LLInventoryModel* model = getInventoryModel(); if(!model) return FALSE; - const LLUUID& trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); + const LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); return model->isObjectDescendentOf(obj->getLinkedUUID(), trash_id); } return FALSE; @@ -686,12 +680,24 @@ BOOL LLInvFVBridge::isLinkedObjectInTrash() const BOOL LLInvFVBridge::isAgentInventory() const { - LLInventoryModel* model = getInventoryModel(); + const LLInventoryModel* model = getInventoryModel(); if(!model) return FALSE; if(gInventory.getRootFolderID() == mUUID) return TRUE; return model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()); } +BOOL LLInvFVBridge::isCOFFolder() const +{ + const LLInventoryModel* model = getInventoryModel(); + if(!model) return TRUE; + const LLUUID cof_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT); + if (mUUID == cof_id || model->isObjectDescendentOf(mUUID, cof_id)) + { + return TRUE; + } + return FALSE; +} + BOOL LLInvFVBridge::isItemPermissive() const { return FALSE; @@ -993,7 +999,7 @@ void LLItemBridge::restoreItem() if(item) { LLInventoryModel* model = getInventoryModel(); - LLUUID new_parent = model->findCategoryUUIDForType(item->getType()); + const LLUUID new_parent = model->findCategoryUUIDForType(item->getType()); // do not restamp on restore. LLInvFVBridge::changeItemParent(model, item, new_parent, FALSE); } @@ -1026,8 +1032,7 @@ void LLItemBridge::restoreToWorld() } // Check if it's in the trash. (again similar to the normal rez logic) - LLUUID trash_id; - trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH); + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH); if(gInventory.isObjectDescendentOf(itemp->getUUID(), trash_id)) { remove_from_inventory = TRUE; @@ -1423,6 +1428,46 @@ BOOL LLFolderBridge::copyToClipboard() const return FALSE; } +BOOL LLFolderBridge::isClipboardPasteableAsLink() const +{ + // Check normal paste-as-link permissions + if (!LLInvFVBridge::isClipboardPasteableAsLink()) + { + return FALSE; + } + + const LLInventoryModel* model = getInventoryModel(); + if (!model) + { + return FALSE; + } + + const LLViewerInventoryCategory *current_cat = getCategory(); + if (current_cat) + { + const LLUUID ¤t_cat_id = current_cat->getUUID(); + LLDynamicArray<LLUUID> objects; + LLInventoryClipboard::instance().retrieve(objects); + S32 count = objects.count(); + for(S32 i = 0; i < count; i++) + { + const LLInventoryCategory *cat = model->getCategory(objects.get(i)); + if (cat) + { + const LLUUID &cat_id = cat->getUUID(); + // Don't allow recursive pasting + if ((cat_id == current_cat_id) || + model->isObjectDescendentOf(current_cat_id, cat_id)) + { + return FALSE; + } + } + } + } + return TRUE; + +} + BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, BOOL drop) { @@ -1436,8 +1481,8 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); if(!avatar) return FALSE; - // cannot drag into library - if(!isAgentInventory()) + // cannot drag categories into library or COF + if(!isAgentInventory() || isCOFFolder()) { return FALSE; } @@ -1456,14 +1501,14 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, const LLUUID& cat_id = inv_cat->getUUID(); // Is the destination the trash? - LLUUID trash_id; - trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); + const LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id); BOOL is_movable = (!LLAssetType::lookupIsProtectedCategoryType(inv_cat->getPreferredType())); LLUUID current_outfit_id = model->findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT); BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); - if (move_is_into_current_outfit) + BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLAssetType::AT_OUTFIT); + if (move_is_into_current_outfit || move_is_into_outfit) { // BAP - restrictions? is_movable = true; @@ -1533,16 +1578,25 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } } } - - if (current_outfit_id == mUUID) // if target is current outfit folder we use link + // if target is an outfit or current outfit folder we use link + if (move_is_into_current_outfit || move_is_into_outfit) { - link_inventory_item( - gAgent.getID(), - inv_cat->getUUID(), - mUUID, - inv_cat->getName(), - LLAssetType::AT_LINK_FOLDER, - LLPointer<LLInventoryCallback>(NULL)); + // BAP - should skip if dup. + if (move_is_into_current_outfit) + { + LLAppearanceManager::wearEnsemble(inv_cat); + } + else + { + LLPointer<LLInventoryCallback> cb = NULL; + link_inventory_item( + gAgent.getID(), + inv_cat->getUUID(), + mUUID, + inv_cat->getName(), + LLAssetType::AT_LINK_FOLDER, + cb); + } } else { @@ -1856,7 +1910,7 @@ void LLInventoryCopyAndWearObserver::changed(U32 mask) mContentsCount) { gInventory.removeObserver(this); - wear_inventory_category(category, FALSE, TRUE); + LLAppearanceManager::wearInventoryCategory(category, FALSE, TRUE); delete this; } } @@ -2117,8 +2171,7 @@ BOOL LLFolderBridge::removeItem() LLInventoryModel* model = getInventoryModel(); if(!model) return FALSE; - LLUUID trash_id; - trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); + LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); // Look for any gestures and deactivate them LLInventoryModel::cat_array_t descendent_categories; @@ -2176,7 +2229,7 @@ void LLFolderBridge::pasteFromClipboard() void LLFolderBridge::pasteLinkFromClipboard() { - LLInventoryModel* model = getInventoryModel(); + const LLInventoryModel* model = getInventoryModel(); if(model) { LLDynamicArray<LLUUID> objects; @@ -2224,7 +2277,7 @@ void LLFolderBridge::folderOptionsMenu() if(!model) return; const LLInventoryCategory* category = model->getCategory(mUUID); - bool is_default_folder = category && + const bool is_default_folder = category && (LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType())); // calling card related functionality for folders. @@ -2262,10 +2315,6 @@ void LLFolderBridge::folderOptionsMenu() } mItems.push_back(std::string("Take Off Items")); } - if (LLAssetType::AT_CURRENT_OUTFIT == category->getPreferredType()) - { - mItems.push_back(std::string("Replace Outfit")); - } hideContextEntries(*mMenu, mItems, disabled_items); } @@ -2321,26 +2370,40 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { LLViewerInventoryCategory *cat = getCategory(); - // Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694. - if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat)) - mItems.push_back(std::string("New Folder")); - mItems.push_back(std::string("New Script")); - mItems.push_back(std::string("New Note")); - mItems.push_back(std::string("New Gesture")); - mItems.push_back(std::string("New Clothes")); - mItems.push_back(std::string("New Body Parts")); - mItems.push_back(std::string("Change Type")); - - if (cat && LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType())) + if (!isCOFFolder() && cat && + LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType())) + { + // Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694. + if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat)) + mItems.push_back(std::string("New Folder")); + mItems.push_back(std::string("New Script")); + mItems.push_back(std::string("New Note")); + mItems.push_back(std::string("New Gesture")); + mItems.push_back(std::string("New Clothes")); + mItems.push_back(std::string("New Body Parts")); + mItems.push_back(std::string("Change Type")); + + LLViewerInventoryCategory *cat = getCategory(); + if (cat && LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType())) + { + mDisabledItems.push_back(std::string("Change Type")); + } + + getClipboardEntries(false, mItems, mDisabledItems, flags); + } + else { - mDisabledItems.push_back(std::string("Change Type")); + // Want some but not all of the items from getClipboardEntries for outfits. + if (cat && cat->getPreferredType()==LLAssetType::AT_OUTFIT) + { + mItems.push_back(std::string("Rename")); + mItems.push_back(std::string("Delete")); + } } - - getClipboardEntries(false, mItems, mDisabledItems, flags); //Added by spatters to force inventory pull on right-click to display folder options correctly. 07-17-06 mCallingCards = mWearables = FALSE; - + LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD); if (checkFolderForContentsOfType(model, is_callingcard)) { @@ -2350,7 +2413,7 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) LLFindWearables is_wearable; LLIsType is_object( LLAssetType::AT_OBJECT ); LLIsType is_gesture( LLAssetType::AT_GESTURE ); - + if (checkFolderForContentsOfType(model, is_wearable) || checkFolderForContentsOfType(model, is_object) || checkFolderForContentsOfType(model, is_gesture) ) @@ -2364,7 +2427,10 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) LLInventoryFetchDescendentsObserver::folder_ref_t folders; LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID); - folders.push_back(category->getUUID()); + if (category) + { + folders.push_back(category->getUUID()); + } fetch->fetchDescendents(folders); inc_busy_count(); if(fetch->isEverythingComplete()) @@ -2570,7 +2636,7 @@ void LLFolderBridge::modifyOutfit(BOOL append) // BAP - was: // wear_inventory_category_on_avatar( cat, append ); - wear_inventory_category( cat, FALSE, append ); + LLAppearanceManager::wearInventoryCategory( cat, FALSE, append ); } // helper stuff @@ -2650,6 +2716,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id); + LLUUID current_outfit_id = model->findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT); + BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); + BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLAssetType::AT_OUTFIT); + if(is_movable && move_is_into_trash) { switch(inv_item->getType()) @@ -2700,6 +2770,25 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, std::string(), LLPointer<LLInventoryCallback>(NULL)); } + else if (move_is_into_current_outfit || move_is_into_outfit) + { + // BAP - should skip if dup. + if (move_is_into_current_outfit) + { + LLAppearanceManager::wearItem(inv_item); + } + else + { + LLPointer<LLInventoryCallback> cb = NULL; + link_inventory_item( + gAgent.getID(), + inv_item->getUUID(), + mUUID, + std::string(), + LLAssetType::AT_LINK, + cb); + } + } else { // restamp if the move is into the trash. @@ -3856,12 +3945,8 @@ void wear_inventory_item_on_avatar( LLInventoryItem* item ) { lldebugs << "wear_inventory_item_on_avatar( " << item->getName() << " )" << llendl; - - LLWearableList::instance().getAsset(item->getAssetUUID(), - item->getName(), - item->getType(), - LLWearableBridge::onWearOnAvatarArrived, - new LLUUID(item->getUUID())); + + LLAppearanceManager::wearItem(item); } } @@ -3880,667 +3965,6 @@ void wear_add_inventory_item_on_avatar( LLInventoryItem* item ) } } - -struct LLFoundData -{ - LLFoundData(const LLUUID& item_id, - const LLUUID& asset_id, - const std::string& name, - LLAssetType::EType asset_type) : - mItemID(item_id), - mAssetID(asset_id), - mName(name), - mAssetType(asset_type), - mWearable( NULL ) {} - - LLUUID mItemID; - LLUUID mAssetID; - std::string mName; - LLAssetType::EType mAssetType; - LLWearable* mWearable; -}; - -struct LLWearableHoldingPattern -{ - LLWearableHoldingPattern() : mResolved(0) {} - ~LLWearableHoldingPattern() - { - for_each(mFoundList.begin(), mFoundList.end(), DeletePointer()); - mFoundList.clear(); - } - typedef std::list<LLFoundData*> found_list_t; - found_list_t mFoundList; - S32 mResolved; -}; - - -class LLOutfitObserver : public LLInventoryFetchObserver -{ -public: - LLOutfitObserver(const LLUUID& cat_id, bool copy_items, bool append) : - mCatID(cat_id), - mCopyItems(copy_items), - mAppend(append) - {} - ~LLOutfitObserver() {} - virtual void done(); //public - -protected: - LLUUID mCatID; - bool mCopyItems; - bool mAppend; -}; - -class LLWearInventoryCategoryCallback : public LLInventoryCallback -{ -public: - LLWearInventoryCategoryCallback(const LLUUID& cat_id, bool append) - { - mCatID = cat_id; - mAppend = append; - } - void fire(const LLUUID& item_id) - { - /* - * Do nothing. We only care about the destructor - * - * The reason for this is that this callback is used in a hack where the - * same callback is given to dozens of items, and the destructor is called - * after the last item has fired the event and dereferenced it -- if all - * the events actually fire! - */ - } - -protected: - ~LLWearInventoryCategoryCallback() - { - // Is the destructor called by ordinary dereference, or because the app's shutting down? - // If the inventory callback manager goes away, we're shutting down, no longer want the callback. - if( LLInventoryCallbackManager::is_instantiated() ) - { - wear_inventory_category_on_avatar(gInventory.getCategory(mCatID), mAppend); - } - else - { - llwarns << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl; - } - } - -private: - LLUUID mCatID; - bool mAppend; -}; - -void LLOutfitObserver::done() -{ - // We now have an outfit ready to be copied to agent inventory. Do - // it, and wear that outfit normally. - if(mCopyItems) - { - LLInventoryCategory* cat = gInventory.getCategory(mCatID); - std::string name; - if(!cat) - { - // should never happen. - name = "New Outfit"; - } - else - { - name = cat->getName(); - } - LLViewerInventoryItem* item = NULL; - item_ref_t::iterator it = mComplete.begin(); - item_ref_t::iterator end = mComplete.end(); - LLUUID pid; - for(; it < end; ++it) - { - item = (LLViewerInventoryItem*)gInventory.getItem(*it); - if(item) - { - if(LLInventoryType::IT_GESTURE == item->getInventoryType()) - { - pid = gInventory.findCategoryUUIDForType(LLAssetType::AT_GESTURE); - } - else - { - pid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING); - } - break; - } - } - if(pid.isNull()) - { - pid = gInventory.getRootFolderID(); - } - - LLUUID cat_id = gInventory.createNewCategory( - pid, - LLAssetType::AT_NONE, - name); - mCatID = cat_id; - LLPointer<LLInventoryCallback> cb = new LLWearInventoryCategoryCallback(mCatID, mAppend); - it = mComplete.begin(); - for(; it < end; ++it) - { - item = (LLViewerInventoryItem*)gInventory.getItem(*it); - if(item) - { - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - cat_id, - std::string(), - cb); - } - } - } - else - { - // Wear the inventory category. - wear_inventory_category_on_avatar(gInventory.getCategory(mCatID), mAppend); - } -} - -class LLOutfitFetch : public LLInventoryFetchDescendentsObserver -{ -public: - LLOutfitFetch(bool copy_items, bool append) : mCopyItems(copy_items), mAppend(append) {} - ~LLOutfitFetch() {} - virtual void done(); -protected: - bool mCopyItems; - bool mAppend; -}; - -void LLOutfitFetch::done() -{ - // What we do here is get the complete information on the items in - // the library, and set up an observer that will wait for that to - // happen. - LLInventoryModel::cat_array_t cat_array; - LLInventoryModel::item_array_t item_array; - gInventory.collectDescendents(mCompleteFolders.front(), - cat_array, - item_array, - LLInventoryModel::EXCLUDE_TRASH); - S32 count = item_array.count(); - if(!count) - { - llwarns << "Nothing fetched in category " << mCompleteFolders.front() - << llendl; - dec_busy_count(); - gInventory.removeObserver(this); - delete this; - return; - } - - LLOutfitObserver* outfit; - outfit = new LLOutfitObserver(mCompleteFolders.front(), mCopyItems, mAppend); - LLInventoryFetchObserver::item_ref_t ids; - for(S32 i = 0; i < count; ++i) - { - ids.push_back(item_array.get(i)->getUUID()); - } - - // clean up, and remove this as an observer since the call to the - // outfit could notify observers and throw us into an infinite - // loop. - dec_busy_count(); - gInventory.removeObserver(this); - delete this; - - // increment busy count and either tell the inventory to check & - // call done, or add this object to the inventory for observation. - inc_busy_count(); - - // do the fetch - outfit->fetchItems(ids); - if(outfit->isEverythingComplete()) - { - // everything is already here - call done. - outfit->done(); - } - else - { - // it's all on it's way - add an observer, and the inventory - // will call done for us when everything is here. - gInventory.addObserver(outfit); - } -} - -void wear_outfit_by_name(const std::string& name) -{ - llinfos << "Wearing category " << name << llendl; - inc_busy_count(); - - LLInventoryModel::cat_array_t cat_array; - LLInventoryModel::item_array_t item_array; - LLNameCategoryCollector has_name(name); - gInventory.collectDescendentsIf(gInventory.getRootFolderID(), - cat_array, - item_array, - LLInventoryModel::EXCLUDE_TRASH, - has_name); - bool copy_items = false; - LLInventoryCategory* cat = NULL; - if (cat_array.count() > 0) - { - // Just wear the first one that matches - cat = cat_array.get(0); - } - else - { - gInventory.collectDescendentsIf(LLUUID::null, - cat_array, - item_array, - LLInventoryModel::EXCLUDE_TRASH, - has_name); - if(cat_array.count() > 0) - { - cat = cat_array.get(0); - copy_items = true; - } - } - - if(cat) - { - wear_inventory_category(cat, copy_items, false); - } - else - { - llwarns << "Couldn't find outfit " <<name<< " in wear_outfit_by_name()" - << llendl; - } - - dec_busy_count(); -} - -void wear_inventory_category(LLInventoryCategory* category, bool copy, bool append) -{ - if(!category) return; - - lldebugs << "wear_inventory_category( " << category->getName() - << " )" << llendl; - // What we do here is get the complete information on the items in - // the inventory, and set up an observer that will wait for that to - // happen. - LLOutfitFetch* outfit; - outfit = new LLOutfitFetch(copy, append); - LLInventoryFetchDescendentsObserver::folder_ref_t folders; - folders.push_back(category->getUUID()); - outfit->fetchDescendents(folders); - inc_busy_count(); - if(outfit->isEverythingComplete()) - { - // everything is already here - call done. - outfit->done(); - } - else - { - // it's all on it's way - add an observer, and the inventory - // will call done for us when everything is here. - gInventory.addObserver(outfit); - } -} - -// *NOTE: hack to get from avatar inventory to avatar -void wear_inventory_category_on_avatar( LLInventoryCategory* category, BOOL append ) -{ - // Avoid unintentionally overwriting old wearables. We have to do - // this up front to avoid having to deal with the case of multiple - // wearables being dirty. - if(!category) return; - lldebugs << "wear_inventory_category_on_avatar( " << category->getName() - << " )" << llendl; - - BOOL follow_folder_links = (category->getPreferredType() == LLAssetType::AT_CURRENT_OUTFIT || category->getPreferredType() == LLAssetType::AT_OUTFIT ); - if( gFloaterCustomize ) - { - gFloaterCustomize->askToSaveIfDirty(boost::bind(wear_inventory_category_on_avatar_step2, _1, category->getUUID(), append, follow_folder_links)); - } - else - { - wear_inventory_category_on_avatar_step2(TRUE, category->getUUID(), append, follow_folder_links ); - } -} - -void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventoryModel::item_array_t& src) -{ - LLInventoryModel::item_array_t new_dst; - std::set<LLUUID> mark_inventory; - std::set<LLUUID> mark_asset; - - S32 inventory_dups = 0; - S32 asset_dups = 0; - - for (LLInventoryModel::item_array_t::const_iterator src_pos = src.begin(); - src_pos != src.end(); - ++src_pos) - { - LLUUID src_item_id = (*src_pos)->getLinkedUUID(); - mark_inventory.insert(src_item_id); - LLUUID src_asset_id = (*src_pos)->getAssetUUID(); - mark_asset.insert(src_asset_id); - } - - for (LLInventoryModel::item_array_t::const_iterator dst_pos = dst.begin(); - dst_pos != dst.end(); - ++dst_pos) - { - LLUUID dst_item_id = (*dst_pos)->getLinkedUUID(); - - if (mark_inventory.find(dst_item_id) == mark_inventory.end()) - { - } - else - { - inventory_dups++; - } - - LLUUID dst_asset_id = (*dst_pos)->getAssetUUID(); - - if (mark_asset.find(dst_asset_id) == mark_asset.end()) - { - // Item is not already present in COF. - new_dst.put(*dst_pos); - mark_asset.insert(dst_item_id); - } - else - { - asset_dups++; - } - } - llinfos << "removeDups, original " << dst.count() << " final " << new_dst.count() - << " inventory dups " << inventory_dups << " asset_dups " << asset_dups << llendl; - - dst = new_dst; -} - -void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOOL append, BOOL follow_folder_links ) -{ - // Find all the wearables that are in the category's subtree. - lldebugs << "wear_inventory_category_on_avatar_step2()" << llendl; - if(proceed) - { - LLInventoryModel::cat_array_t cat_array; - LLInventoryModel::item_array_t item_array; - LLFindWearables is_wearable; - gInventory.collectDescendentsIf(category, - cat_array, - item_array, - LLInventoryModel::EXCLUDE_TRASH, - is_wearable, - follow_folder_links); - S32 i; - S32 wearable_count = item_array.count(); - - LLInventoryModel::cat_array_t obj_cat_array; - LLInventoryModel::item_array_t obj_item_array; - LLIsType is_object( LLAssetType::AT_OBJECT ); - gInventory.collectDescendentsIf(category, - obj_cat_array, - obj_item_array, - LLInventoryModel::EXCLUDE_TRASH, - is_object, - follow_folder_links); - S32 obj_count = obj_item_array.count(); - - // Find all gestures in this folder - LLInventoryModel::cat_array_t gest_cat_array; - LLInventoryModel::item_array_t gest_item_array; - LLIsType is_gesture( LLAssetType::AT_GESTURE ); - gInventory.collectDescendentsIf(category, - gest_cat_array, - gest_item_array, - LLInventoryModel::EXCLUDE_TRASH, - is_gesture, - follow_folder_links); - S32 gest_count = gest_item_array.count(); - - if( !wearable_count && !obj_count && !gest_count) - { - LLNotifications::instance().add("CouldNotPutOnOutfit"); - return; - } - - const LLUUID ¤t_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT); - // Processes that take time should show the busy cursor - inc_busy_count(); - - LLInventoryModel::cat_array_t co_cat_array; - LLInventoryModel::item_array_t co_item_array; - gInventory.collectDescendents(current_outfit_id, co_cat_array, co_item_array, - LLInventoryModel::EXCLUDE_TRASH); - if (append) - { - // Remove duplicates and update counts. - removeDuplicateItems(item_array,co_item_array); - wearable_count = item_array.count(); - - removeDuplicateItems(obj_item_array,co_item_array); - obj_count = obj_item_array.count(); - - removeDuplicateItems(gest_item_array,co_item_array); - gest_count = gest_item_array.count(); - } - - - if (wearable_count > 0 || obj_count > 0) - { - if (!append) - { - // Remove all current outfit folder links if we're now replacing the contents. - for (i = 0; i < co_item_array.count(); ++i) - { - gInventory.purgeObject(co_item_array.get(i)->getUUID()); - } - } - } - - // Activate all gestures in this folder - if (gest_count > 0) - { - llinfos << "Activating " << gest_count << " gestures" << llendl; - - LLGestureManager::instance().activateGestures(gest_item_array); - - // Update the inventory item labels to reflect the fact - // they are active. - LLViewerInventoryCategory* catp = gInventory.getCategory(category); - if (catp) - { - gInventory.updateCategory(catp); - gInventory.notifyObservers(); - } - } - - if(wearable_count > 0) - { - // Note: can't do normal iteration, because if all the - // wearables can be resolved immediately, then the - // callback will be called (and this object deleted) - // before the final getNextData(). - LLWearableHoldingPattern* holder = new LLWearableHoldingPattern; - LLFoundData* found; - LLDynamicArray<LLFoundData*> found_container; - for(i = 0; i < wearable_count; ++i) - { - found = new LLFoundData(item_array.get(i)->getUUID(), - item_array.get(i)->getAssetUUID(), - item_array.get(i)->getName(), - item_array.get(i)->getType()); - holder->mFoundList.push_front(found); - found_container.put(found); - } - for(i = 0; i < wearable_count; ++i) - { - gAddToOutfit = append; - found = found_container.get(i); - - // Populate the current outfit folder with links to the newly added wearables - std::string link_name = "WearableLink"; - link_inventory_item(gAgent.getID(), found->mItemID, current_outfit_id, link_name, - LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL)); - - // Fetch the wearables about to be worn. - LLWearableList::instance().getAsset(found->mAssetID, - found->mName, - found->mAssetType, - wear_inventory_category_on_avatar_loop, - (void*)holder); - } - } - - - //If not appending and the folder doesn't contain only gestures, take off all attachments. - if (!append - && !(wearable_count == 0 && obj_count == 0 && gest_count > 0) ) - { - LLAgentWearables::userRemoveAllAttachments(NULL); - } - - if( obj_count > 0 ) - { - // We've found some attachements. Add these. - - LLVOAvatar* avatar = gAgent.getAvatarObject(); - if( avatar ) - { - // Build a compound message to send all the objects that need to be rezzed. - - // Limit number of packets to send - const S32 MAX_PACKETS_TO_SEND = 10; - const S32 OBJECTS_PER_PACKET = 4; - const S32 MAX_OBJECTS_TO_SEND = MAX_PACKETS_TO_SEND * OBJECTS_PER_PACKET; - if( obj_count > MAX_OBJECTS_TO_SEND ) - { - obj_count = MAX_OBJECTS_TO_SEND; - } - - // Create an id to keep the parts of the compound message together - LLUUID compound_msg_id; - compound_msg_id.generate(); - LLMessageSystem* msg = gMessageSystem; - - for(i = 0; i < obj_count; ++i) - { - if( 0 == (i % OBJECTS_PER_PACKET) ) - { - // Start a new message chunk - msg->newMessageFast(_PREHASH_RezMultipleAttachmentsFromInv); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_HeaderData); - msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id ); - msg->addU8Fast(_PREHASH_TotalObjects, obj_count ); - msg->addBOOLFast(_PREHASH_FirstDetachAll, !append ); - } - - const LLInventoryItem* item = obj_item_array.get(i).get(); - msg->nextBlockFast(_PREHASH_ObjectData ); - msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID()); - msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner()); - msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point - pack_permissions_slam(msg, item->getFlags(), item->getPermissions()); - msg->addStringFast(_PREHASH_Name, item->getName()); - msg->addStringFast(_PREHASH_Description, item->getDescription()); - - if( (i+1 == obj_count) || ((OBJECTS_PER_PACKET-1) == (i % OBJECTS_PER_PACKET)) ) - { - // End of message chunk - msg->sendReliable( gAgent.getRegion()->getHost() ); - } - - } - - for(i = 0; i < obj_count; ++i) - { - const std::string link_name = "AttachmentLink"; - const LLInventoryItem* item = obj_item_array.get(i).get(); - link_inventory_item(gAgent.getID(), item->getLinkedUUID(), current_outfit_id, link_name, - LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL)); - } - } - } - - // In the particular case that we're switching to a different outfit, - // create a link to the folder that we wore. - LLViewerInventoryCategory* catp = gInventory.getCategory(category); - if (!append && catp && catp->getPreferredType() == LLAssetType::AT_OUTFIT) - { - link_inventory_item(gAgent.getID(), category, current_outfit_id, catp->getName(), - LLAssetType::AT_LINK_FOLDER, LLPointer<LLInventoryCallback>(NULL)); - } - } -} - -void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void* data) -{ - LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data; - BOOL append= gAddToOutfit; - - if(wearable) - { - for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin(); - iter != holder->mFoundList.end(); ++iter) - { - LLFoundData* data = *iter; - if(wearable->getAssetID() == data->mAssetID) - { - data->mWearable = wearable; - break; - } - } - } - holder->mResolved += 1; - if(holder->mResolved >= (S32)holder->mFoundList.size()) - { - wear_inventory_category_on_avatar_step3(holder, append); - } -} - -void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, BOOL append) -{ - lldebugs << "wear_inventory_category_on_avatar_step3()" << llendl; - LLInventoryItem::item_array_t items; - LLDynamicArray< LLWearable* > wearables; - - // For each wearable type, find the first instance in the category - // that we recursed through. - for( S32 i = 0; i < WT_COUNT; i++ ) - { - for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin(); - iter != holder->mFoundList.end(); ++iter) - { - LLFoundData* data = *iter; - LLWearable* wearable = data->mWearable; - if( wearable && ((S32)wearable->getType() == i) ) - { - LLViewerInventoryItem* item; - item = (LLViewerInventoryItem*)gInventory.getItem(data->mItemID); - if( item && (item->getAssetUUID() == wearable->getAssetID()) ) - { - items.put(item); - wearables.put(wearable); - } - break; - } - } - } - - if(wearables.count() > 0) - { - gAgentWearables.setWearableOutfit(items, wearables, !append); - gInventory.notifyObservers(); - } - - delete holder; - - dec_busy_count(); -} - void remove_inventory_category_from_avatar( LLInventoryCategory* category ) { if(!category) return; @@ -4945,6 +4369,7 @@ void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userda } // static +// BAP remove the "add" code path once everything is fully COF-ified. void LLWearableBridge::onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata ) { LLUUID* item_id = (LLUUID*) userdata; @@ -5304,15 +4729,15 @@ void LLWearableBridgeAction::wearOnAvatar() } //virtual -void LLWearableBridgeAction::doIt() +void LLWearableBridgeAction::doIt() { - if( isInTrash() ) + if(isInTrash()) { LLNotifications::instance().add("CannotWearTrash"); } else if(isAgentInventory()) { - if( !gAgentWearables.isWearingItem( mUUID ) ) + if(!gAgentWearables.isWearingItem(mUUID)) { wearOnAvatar(); } diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 25859b7f73..bc950520aa 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -200,9 +200,8 @@ protected: BOOL isInTrash() const; BOOL isLinkedObjectInTrash() const; // Is this obj or its baseobj in the trash? - // return true if the item is in agent inventory. if false, it - // must be lost or in the inventory library. - BOOL isAgentInventory() const; + BOOL isAgentInventory() const; // false if lost or in the inventory library + BOOL isCOFFolder() const; // true if COF or descendent of. virtual BOOL isItemPermissive() const; static void changeItemParent(LLInventoryModel* model, LLViewerInventoryItem* item, @@ -295,6 +294,7 @@ public: virtual BOOL isItemMovable(); virtual BOOL isUpToDate() const; virtual BOOL isItemCopyable() const; + virtual BOOL isClipboardPasteableAsLink() const; virtual BOOL copyToClipboard() const; static void createWearable(LLFolderBridge* bridge, EWearableType type); @@ -769,8 +769,6 @@ protected: }; void wear_inventory_item_on_avatar(LLInventoryItem* item); -void wear_outfit_by_name(const std::string& name); -void wear_inventory_category(LLInventoryCategory* category, bool copy, bool append); class LLViewerJointAttachment; void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment); @@ -787,4 +785,5 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, void teleport_via_landmark(const LLUUID& asset_id); + #endif // LL_LLINVENTORYBRIDGE_H diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index 670b1f000b..b803df110b 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -94,6 +94,7 @@ public: BOOL isModified(); BOOL isModifiedAndClear(); BOOL isSinceLogoff(); + bool hasFilterString() { return mFilterSubString.size() > 0; } void clearModified() { mModified = FALSE; mFilterBehavior = FILTER_NONE; } const std::string getName() const { return mName; } std::string getFilterText(); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 8062da0dfe..4cbf3e169b 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -187,9 +187,9 @@ LLInventoryModel::~LLInventoryModel() // This is a convenience function to check if one object has a parent // chain up to the category specified by UUID. BOOL LLInventoryModel::isObjectDescendentOf(const LLUUID& obj_id, - const LLUUID& cat_id) + const LLUUID& cat_id) const { - LLInventoryObject* obj = getObject(obj_id); + const LLInventoryObject* obj = getObject(obj_id); while(obj) { const LLUUID& parent_id = obj->getParentUUID(); @@ -307,13 +307,13 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id) // inventory category on the fly if one does not exist. LLUUID LLInventoryModel::findCategoryUUIDForType(LLAssetType::EType t, bool create_folder) { - LLUUID rv = findCatUUID(t); + const LLUUID &rv = findCatUUID(t); if(rv.isNull() && isInventoryUsable() && create_folder) { - LLUUID root_id = gInventory.getRootFolderID(); + const LLUUID &root_id = gInventory.getRootFolderID(); if(root_id.notNull()) { - rv = createNewCategory(root_id, t, LLStringUtil::null); + return createNewCategory(root_id, t, LLStringUtil::null); } } return rv; @@ -321,9 +321,9 @@ LLUUID LLInventoryModel::findCategoryUUIDForType(LLAssetType::EType t, bool crea // Internal method which looks for a category with the specified // preferred type. Returns LLUUID::null if not found. -LLUUID LLInventoryModel::findCatUUID(LLAssetType::EType preferred_type) +const LLUUID &LLInventoryModel::findCatUUID(LLAssetType::EType preferred_type) const { - LLUUID root_id = gInventory.getRootFolderID(); + const LLUUID &root_id = gInventory.getRootFolderID(); if(LLAssetType::AT_CATEGORY == preferred_type) { return root_id; @@ -440,7 +440,7 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id, // Start with categories if(!include_trash) { - LLUUID trash_id(findCatUUID(LLAssetType::AT_TRASH)); + const LLUUID trash_id = findCategoryUUIDForType(LLAssetType::AT_TRASH); if(trash_id.notNull() && (trash_id == id)) return; } @@ -473,8 +473,7 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id, item = item_array->get(i); if (item->getActualType() == LLAssetType::AT_LINK_FOLDER) { - // BAP either getLinkedCategory() should return non-const, or the functor should take const. - LLViewerInventoryCategory *linked_cat = const_cast<LLViewerInventoryCategory*>(item->getLinkedCategory()); + LLViewerInventoryCategory *linked_cat = item->getLinkedCategory(); if (linked_cat) { if(add(linked_cat,NULL)) @@ -548,10 +547,10 @@ void LLInventoryModel::collectLinkedItems(const LLUUID& id, // Generates a string containing the path to the item specified by // item_id. -void LLInventoryModel::appendPath(const LLUUID& id, std::string& path) +void LLInventoryModel::appendPath(const LLUUID& id, std::string& path) const { std::string temp; - LLInventoryObject* obj = getObject(id); + const LLInventoryObject* obj = getObject(id); LLUUID parent_id; if(obj) parent_id = obj->getParentUUID(); std::string forward_slash("/"); @@ -567,7 +566,7 @@ void LLInventoryModel::appendPath(const LLUUID& id, std::string& path) path.append(temp); } -bool LLInventoryModel::isInventoryUsable() +bool LLInventoryModel::isInventoryUsable() const { bool result = false; if(gInventory.getRootFolderID().notNull() && mIsAgentInvUsable) @@ -1086,7 +1085,7 @@ void LLInventoryModel::removeObserver(LLInventoryObserver* observer) mObservers.erase(observer); } -BOOL LLInventoryModel::containsObserver(LLInventoryObserver* observer) +BOOL LLInventoryModel::containsObserver(LLInventoryObserver* observer) const { return mObservers.find(observer) != mObservers.end(); } @@ -1791,6 +1790,7 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) if (item->getIsBrokenLink()) { llwarns << "Add link item without baseobj present ( name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << llendl; +// llassert_always(FALSE); // DO NOT MERGE THIS IN. This is an AVP debugging line. If this line triggers, it means that you just loaded in a broken link. Unless that happens because you actually deleted a baseobj without deleting the link, it's indicative of a serious problem (likely with your inventory) and should be diagnosed. } mItemMap[item->getUUID()] = item; //mInventory[item->getUUID()] = item; @@ -1817,7 +1817,7 @@ void LLInventoryModel::empty() //mInventory.clear(); } -void LLInventoryModel::accountForUpdate(const LLCategoryUpdate& update) +void LLInventoryModel::accountForUpdate(const LLCategoryUpdate& update) const { LLViewerInventoryCategory* cat = getCategory(update.mCategoryID); if(cat) @@ -2177,7 +2177,8 @@ bool LLInventoryModel::loadSkeleton( update_map_t::const_iterator the_count = child_counts.find(cat->getUUID()); if(the_count != no_child_counts) { - cat->setDescendentCount((*the_count).second.mValue); + const S32 num_descendents = (*the_count).second.mValue; + cat->setDescendentCount(num_descendents); } else { @@ -2481,7 +2482,7 @@ void LLInventoryModel::buildParentChildMap() } } - LLUUID agent_inv_root_id = gInventory.getRootFolderID(); + const LLUUID &agent_inv_root_id = gInventory.getRootFolderID(); if (agent_inv_root_id.notNull()) { cat_array_t* catsp = get_ptr_in_map(mParentChildCategoryTree, agent_inv_root_id); @@ -3324,7 +3325,7 @@ void LLInventoryModel::emptyFolderType(const std::string notification, LLAssetTy void LLInventoryModel::removeItem(const LLUUID& item_id) { LLViewerInventoryItem* item = getItem(item_id); - const LLUUID& new_parent = findCategoryUUIDForType(LLAssetType::AT_TRASH); + const LLUUID new_parent = findCategoryUUIDForType(LLAssetType::AT_TRASH); if (item && item->getParentUUID() != new_parent) { LLInventoryModel::update_list_t update; @@ -3342,7 +3343,7 @@ void LLInventoryModel::removeItem(const LLUUID& item_id) } } -LLUUID LLInventoryModel::getRootFolderID() const +const LLUUID &LLInventoryModel::getRootFolderID() const { return mRootFolderID; } @@ -3352,7 +3353,7 @@ void LLInventoryModel::setRootFolderID(const LLUUID& val) mRootFolderID = val; } -LLUUID LLInventoryModel::getLibraryRootFolderID() const +const LLUUID &LLInventoryModel::getLibraryRootFolderID() const { return mLibraryRootFolderID; } @@ -3362,7 +3363,7 @@ void LLInventoryModel::setLibraryRootFolderID(const LLUUID& val) mLibraryRootFolderID = val; } -LLUUID LLInventoryModel::getLibraryOwnerID() const +const LLUUID &LLInventoryModel::getLibraryOwnerID() const { return mLibraryOwnerID; } @@ -3375,13 +3376,13 @@ void LLInventoryModel::setLibraryOwnerID(const LLUUID& val) //---------------------------------------------------------------------------- // *NOTE: DEBUG functionality -void LLInventoryModel::dumpInventory() +void LLInventoryModel::dumpInventory() const { llinfos << "\nBegin Inventory Dump\n**********************:" << llendl; - llinfos << "mCategroy[] contains " << mCategoryMap.size() << " items." << llendl; - for(cat_map_t::iterator cit = mCategoryMap.begin(); cit != mCategoryMap.end(); ++cit) + llinfos << "mCategory[] contains " << mCategoryMap.size() << " items." << llendl; + for(cat_map_t::const_iterator cit = mCategoryMap.begin(); cit != mCategoryMap.end(); ++cit) { - LLViewerInventoryCategory* cat = cit->second; + const LLViewerInventoryCategory* cat = cit->second; if(cat) { llinfos << " " << cat->getUUID() << " '" << cat->getName() << "' " @@ -3394,9 +3395,9 @@ void LLInventoryModel::dumpInventory() } } llinfos << "mItemMap[] contains " << mItemMap.size() << " items." << llendl; - for(item_map_t::iterator iit = mItemMap.begin(); iit != mItemMap.end(); ++iit) + for(item_map_t::const_iterator iit = mItemMap.begin(); iit != mItemMap.end(); ++iit) { - LLViewerInventoryItem* item = iit->second; + const LLViewerInventoryItem* item = iit->second; if(item) { llinfos << " " << item->getUUID() << " " diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 2ddc35b9ef..e3e4f6aca0 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -99,12 +99,12 @@ class LLInventoryCollectFunctor; class LLInventoryModel { public: - typedef enum e_has_children + enum EHasChildren { CHILDREN_NO, CHILDREN_YES, CHILDREN_MAYBE - }EHasChildren; + }; // These are used a lot... typedef LLDynamicArray<LLPointer<LLViewerInventoryCategory> > cat_array_t; @@ -133,7 +133,7 @@ public: // This is a convenience function to check if one object has a // parent chain up to the category specified by UUID. - BOOL isObjectDescendentOf(const LLUUID& obj_id, const LLUUID& cat_id); + BOOL isObjectDescendentOf(const LLUUID& obj_id, const LLUUID& cat_id) const; // Get the object by id. Returns NULL if not found. // * WARNING: use the pointer returned for read operations - do @@ -197,7 +197,7 @@ public: // The inventory model usage is sensitive to the initial construction of the // model. - bool isInventoryUsable(); + bool isInventoryUsable() const; // // Mutators @@ -261,7 +261,7 @@ public: // to remove it. void addObserver(LLInventoryObserver* observer); void removeObserver(LLInventoryObserver* observer); - BOOL containsObserver(LLInventoryObserver* observer); + BOOL containsObserver(LLInventoryObserver* observer) const; // // Misc Methods @@ -312,7 +312,7 @@ public: // Generates a string containing the path to the item specified by // item_id. - void appendPath(const LLUUID& id, std::string& path); + void appendPath(const LLUUID& id, std::string& path) const; // message handling functionality static void registerCallbacks(LLMessageSystem* msg); @@ -370,7 +370,7 @@ public: // Call these methods when there are category updates, but call // them *before* the actual update so the method can do descendent // accounting correctly. - void accountForUpdate(const LLCategoryUpdate& update); + void accountForUpdate(const LLCategoryUpdate& update) const; void accountForUpdate(const update_list_t& updates); void accountForUpdate(const update_map_t& updates); @@ -404,9 +404,9 @@ public: // gInventory is a singleton and represents the agent's inventory. // The "library" is actually the inventory of a special agent, // usually Alexandria Linden. - LLUUID getRootFolderID() const; - LLUUID getLibraryOwnerID() const; - LLUUID getLibraryRootFolderID() const; + const LLUUID &getRootFolderID() const; + const LLUUID &getLibraryOwnerID() const; + const LLUUID &getLibraryRootFolderID() const; // These are set during login with data from the server void setRootFolderID(const LLUUID& id); @@ -422,9 +422,13 @@ protected: void addCategory(LLViewerInventoryCategory* category); void addItem(LLViewerInventoryItem* item); + // ! DEPRECRATE ! Remove this and add it into findCategoryUUIDForType, + // since that's the only function that uses this. It's too confusing + // having both methods. + // // Internal method which looks for a category with the specified // preferred type. Returns LLUUID::null if not found - LLUUID findCatUUID(LLAssetType::EType preferred_type); + const LLUUID &findCatUUID(LLAssetType::EType preferred_type) const; // Empty the entire contents void empty(); @@ -515,7 +519,7 @@ protected: public: // *NOTE: DEBUG functionality - void dumpInventory(); + void dumpInventory() const; static bool isBulkFetchProcessingComplete(); static void stopBackgroundFetch(); // stop fetch process diff --git a/indra/newview/llloginhandler.h b/indra/newview/llloginhandler.h index 0844b80c7c..d36ceaf3cc 100644 --- a/indra/newview/llloginhandler.h +++ b/indra/newview/llloginhandler.h @@ -39,7 +39,7 @@ class LLLoginHandler : public LLCommandHandler { public: // allow from external browsers - LLLoginHandler() : LLCommandHandler("login", false) { } + LLLoginHandler() : LLCommandHandler("login", UNTRUSTED_ALLOW) { } /*virtual*/ bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web); // Fill in our internal fields from a SLURL like diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 62b38f2b4a..09a7edaa43 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -916,15 +916,8 @@ void LLMediaCtrl::onClickLinkHref( LLPluginClassMedia* self ) // void LLMediaCtrl::onClickLinkNoFollow( LLPluginClassMedia* self ) { + // let the dispatcher handle blocking/throttling of SLURLs std::string url = self->getClickURL(); - if (LLSLURL::isSLURLCommand(url) - && !mTrusted) - { - // block handling of this secondlife:///app/ URL - LLNotifications::instance().add("UnableToOpenCommandURL"); - return; - } - LLURLDispatcher::dispatch(url, this, mTrusted); } diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 69cebcfb5e..b1db51dd26 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -298,7 +298,7 @@ void LLNavigationBar::onHomeButtonClicked() void LLNavigationBar::onSearchCommit() { - std::string search_query = mSearchComboBox->getValue().asString(); + std::string search_query = mSearchComboBox->getSimple(); if(!search_query.empty()) { LLSearchHistory::getInstance()->addEntry(search_query); diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index d4a9be0355..e348189ea9 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -32,6 +32,9 @@ #include "llviewerprecompiledheaders.h" +#include "llfloaterreg.h" +#include "lltrans.h" + #include "llnearbychatbar.h" #include "llbottomtray.h" #include "llagent.h" @@ -45,7 +48,7 @@ S32 LLNearbyChatBar::sLastSpecialChatChannel = 0; -// legacy calllback glue +// legacy callback glue void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); static LLDefaultChildRegistry::Register<LLGestureComboBox> r("gesture_combo_box"); @@ -64,6 +67,7 @@ LLGestureComboBox::LLGestureComboBox(const LLGestureComboBox::Params& p) : LLComboBox(p) , mGestureLabelTimer() , mLabel(p.label) + , mViewAllItemIndex(0) { setCommitCallback(boost::bind(&LLGestureComboBox::onCommitGesture, this)); @@ -102,6 +106,11 @@ void LLGestureComboBox::refreshGestures() } sortByName(); + + // store index followed by the last added Gesture and add View All item at bottom + mViewAllItemIndex = idx; + addSimpleElement(LLTrans::getString("ViewAllGestures"), ADD_BOTTOM, LLSD(mViewAllItemIndex)); + // Insert label after sorting, at top, with separator below it addSeparator(ADD_TOP); addSimpleElement(mLabel, ADD_TOP); @@ -128,6 +137,15 @@ void LLGestureComboBox::onCommitGesture() } index = gestures->getSelectedValue().asInteger(); + + if (mViewAllItemIndex == index) + { + // The same behavior as Ctrl+G. EXT-823 + LLFloaterReg::toggleInstance("gestures"); + gestures->selectFirstItem(); + return; + } + LLMultiGesture* gesture = mGestures.at(index); if(gesture) { @@ -598,7 +616,7 @@ class LLChatHandler : public LLCommandHandler { public: // not allowed from outside the app - LLChatHandler() : LLCommandHandler("chat", true) { } + LLChatHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { } // Your code here bool handle(const LLSD& tokens, const LLSD& query_map, diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index 19177e37b3..f310740f42 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -63,6 +63,7 @@ protected: LLFrameTimer mGestureLabelTimer; std::vector<LLMultiGesture*> mGestures; std::string mLabel; + LLSD::Integer mViewAllItemIndex; }; class LLNearbyChatBar diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp index d088c45710..49b48f5a8e 100644 --- a/indra/newview/lloutputmonitorctrl.cpp +++ b/indra/newview/lloutputmonitorctrl.cpp @@ -38,6 +38,8 @@ // viewer includes #include "llvoiceclient.h" +#include "llmutelist.h" +#include "llagent.h" // default options set in output_monitor.xml static LLDefaultChildRegistry::Register<LLOutputMonitorCtrl> r("output_monitor"); @@ -58,7 +60,9 @@ LLOutputMonitorCtrl::Params::Params() image_on("image_on"), image_level_1("image_level_1"), image_level_2("image_level_2"), - image_level_3("image_level_3") + image_level_3("image_level_3"), + auto_update("auto_update"), + speaker_id("speaker_id") { draw_border = true; name = "output_monitor"; @@ -69,14 +73,14 @@ LLOutputMonitorCtrl::Params::Params() LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p) : LLView(p), mPower(0), - mIsMuted(true), - mIsTalking(false), mImageMute(p.image_mute), mImageOff(p.image_off), mImageOn(p.image_on), mImageLevel1(p.image_level_1), mImageLevel2(p.image_level_2), - mImageLevel3(p.image_level_3) + mImageLevel3(p.image_level_3), + mAutoUpdate(p.auto_update), + mSpeakerId(p.speaker_id) { //static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange); //static LLUIColor output_monitor_overdriven_color = LLUIColorTable::instance().getColor("OutputMonitorOverdrivenColor", LLColor4::red); @@ -99,10 +103,14 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p) //sRectHeightRatio = output_monitor_rect_height_ratio; mBorder = p.draw_border; + + //with checking mute state + setSpeakerId(mSpeakerId); } LLOutputMonitorCtrl::~LLOutputMonitorCtrl() { + LLMuteList::getInstance()->removeObserver(this); } void LLOutputMonitorCtrl::setPower(F32 val) @@ -121,6 +129,12 @@ void LLOutputMonitorCtrl::draw() const F32 LEVEL_1 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL * 2.f / 3.f; const F32 LEVEL_2 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL; + if (getVisible() && mAutoUpdate && !mIsMuted && mSpeakerId.notNull()) + { + setPower(gVoiceClient->getCurrentPower(mSpeakerId)); + setIsTalking(gVoiceClient->getUserPTTState()); + } + LLPointer<LLUIImage> icon; if (mIsMuted) { @@ -205,3 +219,29 @@ void LLOutputMonitorCtrl::draw() if(mBorder) gl_rect_2d(0, monh, monw, 0, sColorBound, FALSE); } + +void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id) +{ + if (speaker_id.isNull()) return; + + mSpeakerId = speaker_id; + + //mute management + if (mAutoUpdate) + { + if (speaker_id == gAgentID) + { + setIsMuted(false); + } + else + { + setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId)); + LLMuteList::getInstance()->addObserver(this); + } + } +} + +void LLOutputMonitorCtrl::onChange() +{ + setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId)); +} diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h index 98b2fe9dc6..7a7b8bc3a1 100644 --- a/indra/newview/lloutputmonitorctrl.h +++ b/indra/newview/lloutputmonitorctrl.h @@ -35,6 +35,7 @@ #include "v4color.h" #include "llview.h" +#include "llmutelist.h" class LLTextBox; class LLUICtrlFactory; @@ -44,7 +45,7 @@ class LLUICtrlFactory; // class LLOutputMonitorCtrl -: public LLView +: public LLView, LLMuteListObserver { public: struct Params : public LLInitParam::Block<Params, LLView::Params> @@ -56,6 +57,8 @@ public: image_level_1, image_level_2, image_level_3; + Optional<bool> auto_update; + Optional<LLUUID> speaker_id; Params(); }; @@ -80,6 +83,11 @@ public: // correct button image. void setIsTalking(bool val) { mIsTalking = val; } + void setSpeakerId(const LLUUID& speaker_id); + + //called by mute list + virtual void onChange(); + private: //static LLColor4 sColorMuted; //static LLColor4 sColorNormal; @@ -89,6 +97,8 @@ private: //static F32 sRectWidthRatio; //static F32 sRectHeightRatio; + + F32 mPower; bool mIsMuted; bool mIsTalking; @@ -98,6 +108,12 @@ private: LLPointer<LLUIImage> mImageLevel1; LLPointer<LLUIImage> mImageLevel2; LLPointer<LLUIImage> mImageLevel3; + + /** whether to deal with gVoiceClient directly */ + bool mAutoUpdate; + + /** uuid of a speaker being monitored */ + LLUUID mSpeakerId; }; #endif diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index ba383a8dee..b7f2f67a9a 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -446,7 +446,7 @@ void LLPanelAvatarProfile::processGroupProperties(const LLAvatarGroups* avatar_g void LLPanelAvatarProfile::fillCommonData(const LLAvatarData* avatar_data) { - childSetValue("register_date", avatar_data->born_on); + childSetValue("register_date", LLAvatarPropertiesProcessor::ageFromDate(avatar_data->born_on)); childSetValue("sl_description_edit", avatar_data->about_text); childSetValue("fl_description_edit",avatar_data->fl_about_text); childSetValue("2nd_life_pic", avatar_data->image_id); @@ -556,8 +556,6 @@ BOOL LLPanelAvatarMeProfile::postBuild() childSetCommitCallback("status_combo", boost::bind(&LLPanelAvatarMeProfile::onStatusChanged, this), NULL); childSetCommitCallback("status_me_message_text", boost::bind(&LLPanelAvatarMeProfile::onStatusMessageChanged, this), NULL); - childSetTextArg("partner_edit_link", "[URL]", getString("partner_edit_link_url")); - resetControls(); resetData(); diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index c77d089af7..ee5d265220 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -119,7 +119,7 @@ class LLClassifiedTeleportHandler : public LLCommandHandler { public: // don't allow from external browsers because it moves you immediately - LLClassifiedTeleportHandler() : LLCommandHandler("classifiedteleport", true) { } + LLClassifiedTeleportHandler() : LLCommandHandler("classifiedteleport", UNTRUSTED_BLOCK) { } bool handle(const LLSD& tokens, const LLSD& queryMap) { diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 48c9c16780..378a09e315 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -36,6 +36,7 @@ #include "llagent.h" #include "llbutton.h" +#include "llfiltereditor.h" #include "llfloatergroupinvite.h" #include "llavataractions.h" #include "lliconctrl.h" @@ -49,7 +50,6 @@ #include "lltabcontainer.h" #include "lltextbox.h" #include "lltexteditor.h" -#include "llsearcheditor.h" #include "llviewertexturelist.h" #include "llviewerwindow.h" #include "llfocusmgr.h" @@ -477,14 +477,12 @@ BOOL LLPanelGroupSubTab::postBuild() { // Hook up the search widgets. bool recurse = true; - mSearchEditor = getChild<LLSearchEditor>("filter_input", recurse); + mSearchEditor = getChild<LLFilterEditor>("filter_input", recurse); if (!mSearchEditor) return FALSE; - mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::onClickSearch, this)); - mSearchEditor->setKeystrokeCallback(onSearchKeystroke, this); - + mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::setSearchFilter, this, _2)); // Get icons for later use. mActionIcons.clear(); @@ -517,26 +515,6 @@ void LLPanelGroupSubTab::setGroupID(const LLUUID& id) } } -// static -void LLPanelGroupSubTab::onSearchKeystroke(LLLineEditor* caller, void* user_data) -{ - LLPanelGroupSubTab* self = static_cast<LLPanelGroupSubTab*>(user_data); - self->handleSearchKeystroke(caller); - -} - -void LLPanelGroupSubTab::handleSearchKeystroke(LLLineEditor* caller) -{ - setSearchFilter( caller->getText() ); -} - -// static -void LLPanelGroupSubTab::onClickSearch() -{ - setSearchFilter( mSearchEditor->getText() ); -} - - void LLPanelGroupSubTab::setSearchFilter(const std::string& filter) { lldebugs << "LLPanelGroupSubTab::setSearchFilter() ==> '" << filter << "'" << llendl; diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index 2a0f31fa0f..bd5fc1d235 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -35,6 +35,7 @@ #include "llpanelgroup.h" +class LLFilterEditor; class LLNameListCtrl; class LLPanelGroupSubTab; class LLPanelGroupMembersSubTab; @@ -43,7 +44,6 @@ class LLPanelGroupActionsSubTab; class LLScrollListCtrl; class LLScrollListItem; class LLTextEditor; -class LLSearchEditor; // Forward declare for friend usage. //virtual BOOL LLPanelGroupSubTab::postBuildSubTab(LLView*); @@ -111,11 +111,6 @@ public: // This allows sub-tabs to collect child widgets from a higher level in the view hierarchy. virtual BOOL postBuildSubTab(LLView* root) { return TRUE; } - static void onSearchKeystroke(LLLineEditor* caller, void* user_data); - void handleSearchKeystroke(LLLineEditor* caller); - - void onClickSearch(); - virtual void setSearchFilter( const std::string& filter ); virtual void activate(); @@ -148,7 +143,7 @@ protected: LLPanel* mHeader; LLPanel* mFooter; - LLSearchEditor* mSearchEditor; + LLFilterEditor* mSearchEditor; std::string mSearchFilter; diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index ef830d5f03..9caa751854 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -87,7 +87,7 @@ class LLLoginRefreshHandler : public LLCommandHandler { public: // don't allow from external browsers - LLLoginRefreshHandler() : LLCommandHandler("login_refresh", true) { } + LLLoginRefreshHandler() : LLCommandHandler("login_refresh", UNTRUSTED_BLOCK) { } bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) { if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 9ec9874384..6a61e0f02f 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -39,9 +39,11 @@ #include "lleconomy.h" #include "llerror.h" #include "llfontgl.h" +#include "llmaterialtable.h" #include "llpermissionsflags.h" #include "llstring.h" #include "llvolume.h" +#include "material_codes.h" #include "m3math.h" // project includes diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 42aa21c13e..309a97a9f2 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -401,6 +401,19 @@ LLPanelPeople::~LLPanelPeople() LLView::deleteViewByHandle(mRecentViewSortMenuHandle); } +void onAvatarListTmpDoubleClicked(LLAvatarListTmp* list) +{ + LLUUID clicked_id = list->getCurrentID(); + + if (clicked_id.isNull()) + return; + +#if 0 // SJB: Useful for testing, but not currently functional or to spec + LLAvatarActions::showProfile(clicked_id); +#else // spec says open IM window + LLAvatarActions::startIM(clicked_id); +#endif +} BOOL LLPanelPeople::postBuild() { @@ -417,7 +430,7 @@ BOOL LLPanelPeople::postBuild() mNearbyList = getChild<LLPanel>(NEARBY_TAB_NAME)->getChild<LLAvatarList>("avatar_list"); - mRecentList = getChild<LLPanel>(RECENT_TAB_NAME)->getChild<LLAvatarList>("avatar_list"); + mRecentList = getChild<LLPanel>(RECENT_TAB_NAME)->getChild<LLAvatarListTmp>("avatar_list"); mGroupList = getChild<LLGroupList>("group_list"); LLPanel* groups_panel = getChild<LLPanel>(GROUP_TAB_NAME); @@ -432,11 +445,11 @@ BOOL LLPanelPeople::postBuild() mOnlineFriendList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mOnlineFriendList)); mAllFriendList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mAllFriendList)); mNearbyList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mNearbyList)); - mRecentList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mRecentList)); + mRecentList->setDoubleClickCallback(boost::bind(onAvatarListTmpDoubleClicked, mRecentList)); mOnlineFriendList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mOnlineFriendList)); mAllFriendList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mAllFriendList)); mNearbyList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mNearbyList)); - mRecentList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mRecentList)); + mRecentList->setCommitCallback(boost::bind(&LLPanelPeople::updateButtons, this)); mGroupList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onGroupInfoButtonClicked, this)); mGroupList->setCommitCallback(boost::bind(&LLPanelPeople::updateButtons, this)); diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 3358a70bac..c0c2f70614 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -40,6 +40,7 @@ class LLFilterEditor; class LLTabContainer; class LLAvatarList; +class LLAvatarListTmp; class LLGroupList; class LLPanelPeople : public LLPanel @@ -118,7 +119,7 @@ private: LLAvatarList* mOnlineFriendList; LLAvatarList* mAllFriendList; LLAvatarList* mNearbyList; - LLAvatarList* mRecentList; + LLAvatarListTmp* mRecentList; LLGroupList* mGroupList; LLHandle<LLView> mGroupPlusMenuHandle; diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp index bde6d1cf6c..9ae58d1cb6 100644 --- a/indra/newview/llpanelpick.cpp +++ b/indra/newview/llpanelpick.cpp @@ -134,11 +134,13 @@ BOOL LLPanelPick::postBuild() childSetAction("teleport_btn", boost::bind(&LLPanelPick::onClickTeleport, this)); childSetAction("show_on_map_btn", boost::bind(&LLPanelPick::onClickMap, this)); - if (!mBackCb.empty()) - { - LLButton* button = findChild<LLButton>("back_btn"); - if (button) button->setClickedCallback(mBackCb); - } + } + + // EXT-822. We have to process "Back" button click in both Edit & View Modes + if (!mBackCb.empty()) + { + LLButton* button = findChild<LLButton>("back_btn"); + if (button) button->setClickedCallback(mBackCb); } return TRUE; @@ -435,11 +437,8 @@ void LLPanelPick::updateButtons() void LLPanelPick::setExitCallback(commit_callback_t cb) { mBackCb = cb; - if (!mEditMode) - { - LLButton* button = findChild<LLButton>("back_btn"); - if (button) button->setClickedCallback(mBackCb); - } + LLButton* button = findChild<LLButton>("back_btn"); + if (button) button->setClickedCallback(mBackCb); } //static diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index 457109f869..7a19b8877e 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -68,7 +68,6 @@ LLPanelPlaceInfo::LLPanelPlaceInfo() : LLPanel(), mParcelID(), mRequestedID(), - mPosRegion(), mLandmarkID(), mMinHeight(0), mScrollingPanel(NULL), @@ -82,8 +81,6 @@ LLPanelPlaceInfo::~LLPanelPlaceInfo() { LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelID, this); } - - LLViewerParcelMgr::getInstance()->removeObserver(this); } BOOL LLPanelPlaceInfo::postBuild() @@ -254,7 +251,6 @@ void LLPanelPlaceInfo::resetLocation() mParcelID.setNull(); mRequestedID.setNull(); mLandmarkID.setNull(); - mPosRegion.clearVec(); std::string not_available = getString("not_available"); mMaturityRatingText->setValue(not_available); mParcelOwner->setValue(not_available); @@ -330,8 +326,6 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type) getChild<LLAccordionCtrl>("advanced_info_accordion")->setVisible(is_info_type_agent); - LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); - switch(type) { case CREATE_LANDMARK: @@ -339,15 +333,6 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type) break; case AGENT: - if (parcel_mgr) - { - // If information is requested for current agent location - // start using LLViewerParcelMgr for land selection. - parcel_mgr->addObserver(this); - parcel_mgr->selectParcelAt(gAgent.getPositionGlobal()); - } - - // Fall through to PLACE case case PLACE: mCurrentTitle = getString("title_place"); @@ -366,16 +351,7 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type) break; } - if (type != AGENT && parcel_mgr != NULL) - { - if (!parcel_mgr->selectionEmpty()) - { - parcel_mgr->deselectUnused(); - } - parcel_mgr->removeObserver(this); - } - - if (type != PLACE) + if (type != AGENT) toggleMediaPanel(FALSE); mInfoType = type; @@ -442,12 +418,16 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data) mSnapshotCtrl->setImageAssetID(parcel_data.snapshot_id); } - if( !parcel_data.name.empty()) + if(!parcel_data.name.empty()) { mParcelName->setText(parcel_data.name); } + else + { + mParcelName->setText(LLStringUtil::null); + } - if( !parcel_data.desc.empty()) + if(!parcel_data.desc.empty()) { mDescEditor->setText(parcel_data.desc); } @@ -471,21 +451,12 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data) //because we deal with remote parcel response format bool isForSale = (parcel_data.flags & DFQ_FOR_SALE)? TRUE : FALSE; getChild<LLIconCtrl>("icon_for_sale")->setVisible(isForSale); - - // Just use given region position for display - S32 region_x = llround(mPosRegion.mV[0]); - S32 region_y = llround(mPosRegion.mV[1]); - S32 region_z = llround(mPosRegion.mV[2]); - // If the region position is zero, grab position from the global - if(mPosRegion.isExactlyZero()) - { - region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS; - region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS; - region_z = llround(parcel_data.global_z); - } + S32 region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS; + S32 region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS; + S32 region_z = llround(parcel_data.global_z); - std::string name; + std::string name = getString("not_available"); if (!parcel_data.sim_name.empty()) { name = llformat("%s (%d, %d, %d)", @@ -495,17 +466,23 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data) if (mInfoType == CREATE_LANDMARK) { - mTitleEditor->setText(parcel_data.name); + + if (parcel_data.name.empty()) + { + mTitleEditor->setText(name); + } + else + { + mTitleEditor->setText(parcel_data.name); + } + mNotesEditor->setText(LLStringUtil::null); } } -void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region, - const LLUUID& region_id, - const LLVector3d& pos_global) +void LLPanelPlaceInfo::displayParcelInfo(const LLUUID& region_id, + const LLVector3d& pos_global) { - mPosRegion = pos_region; - LLViewerRegion* region = gAgent.getRegion(); if (!region) return; @@ -514,6 +491,10 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region, std::string url = region->getCapability("RemoteParcelRequest"); if (!url.empty()) { + F32 region_x = (F32)fmod(pos_global.mdV[VX], (F64)REGION_WIDTH_METERS); + F32 region_y = (F32)fmod(pos_global.mdV[VY], (F64)REGION_WIDTH_METERS); + LLVector3 pos_region(region_x, region_y, (F32)pos_global.mdV[VZ]); + body["location"] = ll_sd_from_vector3(pos_region); if (!region_id.isNull()) { @@ -532,12 +513,10 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region, } } -void LLPanelPlaceInfo::displayAgentParcelInfo() +void LLPanelPlaceInfo::displaySelectedParcelInfo(LLParcel* parcel, + LLViewerRegion* region, + const LLVector3d& pos_global) { - mParcel = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection(); - - LLParcel* parcel = mParcel->getParcel(); - LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); if (!region || !parcel) return; @@ -568,14 +547,9 @@ void LLPanelPlaceInfo::displayAgentParcelInfo() parcel_data.name = parcel->getName(); parcel_data.sim_name = gAgent.getRegion()->getName(); parcel_data.snapshot_id = parcel->getSnapshotID(); - LLVector3d global_pos = gAgent.getPositionGlobal(); - parcel_data.global_x = global_pos.mdV[0]; - parcel_data.global_y = global_pos.mdV[1]; - parcel_data.global_z = global_pos.mdV[2]; - - mPosRegion = gAgent.getPositionAgent(); - - processParcelInfo(parcel_data); + parcel_data.global_x = pos_global.mdV[0]; + parcel_data.global_y = pos_global.mdV[1]; + parcel_data.global_z = pos_global.mdV[2]; std::string on = getString("on"); std::string off = getString("off"); @@ -589,7 +563,7 @@ void LLPanelPlaceInfo::displayAgentParcelInfo() { mVoiceText->setText(off); } - + if (!region->getBlockFly() && parcel->getAllowFly()) { mFlyText->setText(on); @@ -769,14 +743,9 @@ void LLPanelPlaceInfo::displayAgentParcelInfo() } } - getChild<LLAccordionCtrlTab>("sales_tab")->setVisible(for_sale); -} + processParcelInfo(parcel_data); -// virtual -void LLPanelPlaceInfo::changed() -{ - resetLocation(); - displayAgentParcelInfo(); + getChild<LLAccordionCtrlTab>("sales_tab")->setVisible(for_sale); } void LLPanelPlaceInfo::updateEstateName(const std::string& name) @@ -835,7 +804,10 @@ void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type) } } - if (item_value != current_value && + LLStringUtil::trim(current_value); + + if (!current_value.empty() && + item_value != current_value && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)) { LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); @@ -867,11 +839,17 @@ void LLPanelPlaceInfo::createLandmark(const LLUUID& folder_id) if (name.empty()) { name = mParcelName->getText(); + + // If no parcel exists use the region name instead. + if (name.empty()) + { + name = mRegionName->getText(); + } } LLStringUtil::replaceChar(desc, '\n', ' '); // If no folder chosen use the "Landmarks" folder. - LLLandmarkActions::createLandmarkHere(name, desc, + LLLandmarkActions::createLandmarkHere(name, desc, folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK)); } @@ -884,10 +862,14 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& global_pos) pick_data.pick_id = LLUUID::generateNewID(); pick_data.creator_id = gAgentID; - //legacy var need to be deleted + //legacy var needs to be deleted pick_data.top_pick = FALSE; pick_data.parcel_id = mParcelID; pick_data.name = mParcelName->getText(); + if (pick_data.name.empty()) + { + pick_data.name = mRegionName->getText(); + } pick_data.desc = mDescEditor->getText(); pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID(); pick_data.pos_global = global_pos; diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index 60f35cd0c1..32ae4334aa 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -42,17 +42,17 @@ #include "llpanelmedia.h" #include "llremoteparcelrequest.h" -#include "llviewerparcelmgr.h" class LLButton; class LLInventoryItem; class LLLineEditor; -class LLParcelSelection; +class LLParcel; class LLTextBox; class LLTextEditor; class LLTextureCtrl; +class LLViewerRegion; -class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver, LLParcelObserver +class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver { public: enum INFO_TYPE @@ -99,16 +99,14 @@ public: // Displays information about a remote parcel. // Sends a request to the server. - void displayParcelInfo(const LLVector3& pos_region, - const LLUUID& region_id, + void displayParcelInfo(const LLUUID& region_id, const LLVector3d& pos_global); - // Displays information about the parcel the agent is currently on + // Displays information about the currently selected parcel // without sending a request to the server. - void displayAgentParcelInfo(); - - // Called on parcel selection change by LLViewerParcelMgr. - /*virtual*/ void changed(); + void displaySelectedParcelInfo(LLParcel* parcel, + LLViewerRegion* region, + const LLVector3d& pos_global); void updateEstateName(const std::string& name); void updateEstateOwnerName(const std::string& name); @@ -135,7 +133,6 @@ private: LLUUID mParcelID; LLUUID mRequestedID; LLUUID mLandmarkID; - LLVector3 mPosRegion; std::string mCurrentTitle; S32 mMinHeight; INFO_TYPE mInfoType; @@ -186,8 +183,6 @@ private: LLPanel* mScrollingPanel; LLPanel* mInfoPanel; LLMediaPanel* mMediaPanel; - - LLSafeHandle<LLParcelSelection> mParcel; }; #endif // LL_LLPANELPLACEINFO_H diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index bc740bd865..11ddc3dd9a 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -31,10 +31,14 @@ #include "llviewerprecompiledheaders.h" +#include "llpanelplaces.h" + #include "llassettype.h" #include "llwindow.h" +#include "llinventory.h" #include "lllandmark.h" +#include "llparcel.h" #include "llfloaterreg.h" #include "llnotifications.h" @@ -44,10 +48,11 @@ #include "lluictrlfactory.h" #include "llagent.h" +#include "llfloaterworldmap.h" +#include "llinventorymodel.h" #include "lllandmarkactions.h" #include "lllandmarklist.h" -#include "llfloaterworldmap.h" -#include "llpanelplaces.h" +#include "llpanelplaceinfo.h" #include "llpanellandmarks.h" #include "llpanelteleporthistory.h" #include "llsidetray.h" @@ -57,6 +62,7 @@ #include "llviewermenu.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" +#include "llviewerwindow.h" static const S32 LANDMARK_FOLDERS_MENU_WIDTH = 250; static const std::string AGENT_INFO_TYPE = "agent"; @@ -69,9 +75,41 @@ static const std::string TELEPORT_HISTORY_INFO_TYPE = "teleport_history"; static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right); static std::string getFullFolderName(const LLViewerInventoryCategory* cat); static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats); -static const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global); static void onSLURLBuilt(std::string& slurl); +//Observer classes +class LLPlacesParcelObserver : public LLParcelObserver +{ +public: + LLPlacesParcelObserver(LLPanelPlaces* places_panel) + : mPlaces(places_panel) {} + + /*virtual*/ void changed() + { + if (mPlaces) + mPlaces->changedParcelSelection(); + } + +private: + LLPanelPlaces* mPlaces; +}; + +class LLPlacesInventoryObserver : public LLInventoryObserver +{ +public: + LLPlacesInventoryObserver(LLPanelPlaces* places_panel) + : mPlaces(places_panel) {} + + /*virtual*/ void changed(U32 mask) + { + if (mPlaces) + mPlaces->changedInventory(mask); + } + +private: + LLPanelPlaces* mPlaces; +}; + static LLRegisterPanelClassWrapper<LLPanelPlaces> t_places("panel_places"); LLPanelPlaces::LLPanelPlaces() @@ -82,11 +120,14 @@ LLPanelPlaces::LLPanelPlaces() mPlaceInfo(NULL), mItem(NULL), mPlaceMenu(NULL), - mLandmarkMenu(NULL), + mLandmarkMenu(NULL), mLandmarkFoldersMenuHandle(), mPosGlobal() { - gInventory.addObserver(this); + mParcelObserver = new LLPlacesParcelObserver(this); + mInventoryObserver = new LLPlacesInventoryObserver(this); + + gInventory.addObserver(mInventoryObserver); LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback( boost::bind(&LLPanelPlaces::onAgentParcelChange, this)); @@ -96,10 +137,15 @@ LLPanelPlaces::LLPanelPlaces() LLPanelPlaces::~LLPanelPlaces() { - if (gInventory.containsObserver(this)) - gInventory.removeObserver(this); - + if (gInventory.containsObserver(mInventoryObserver)) + gInventory.removeObserver(mInventoryObserver); + + LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver); + LLView::deleteViewByHandle(mLandmarkFoldersMenuHandle); + + delete mInventoryObserver; + delete mParcelObserver; } BOOL LLPanelPlaces::postBuild() @@ -173,15 +219,10 @@ void LLPanelPlaces::onOpen(const LLSD& key) if (mPlaceInfoType == AGENT_INFO_TYPE) { mPlaceInfo->setInfoType(LLPanelPlaceInfo::AGENT); - - mPosGlobal = gAgent.getPositionGlobal(); } else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE) { mPlaceInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK); - mPlaceInfo->displayAgentParcelInfo(); - - mPosGlobal = gAgent.getPositionGlobal(); } else if (mPlaceInfoType == LANDMARK_INFO_TYPE) { @@ -189,7 +230,7 @@ void LLPanelPlaces::onOpen(const LLSD& key) LLInventoryItem* item = gInventory.getItem(item_uuid); if (!item) return; - + setItem(item); } else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE) @@ -204,9 +245,7 @@ void LLPanelPlaces::onOpen(const LLSD& key) key["z"].asReal()); mPlaceInfo->setInfoType(LLPanelPlaceInfo::PLACE); - mPlaceInfo->displayParcelInfo(get_pos_local_from_global(mPosGlobal), - LLUUID(), - mPosGlobal); + mPlaceInfo->displayParcelInfo(LLUUID(), mPosGlobal); } else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) { @@ -219,9 +258,30 @@ void LLPanelPlaces::onOpen(const LLSD& key) mPlaceInfo->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY); mPlaceInfo->updateLastVisitedText(hist_items[index].mDate); - mPlaceInfo->displayParcelInfo(get_pos_local_from_global(mPosGlobal), - LLUUID(), - mPosGlobal); + mPlaceInfo->displayParcelInfo(LLUUID(), mPosGlobal); + } + + LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); + if (!parcel_mgr) + return; + + // Start using LLViewerParcelMgr for land selection if + // information about nearby land is requested. + // Otherwise stop using land selection and deselect land. + if (mPlaceInfoType == AGENT_INFO_TYPE || + mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE) + { + parcel_mgr->addObserver(mParcelObserver); + parcel_mgr->selectParcelAt(gAgent.getPositionGlobal()); + } + else + { + parcel_mgr->removeObserver(mParcelObserver); + + if (!parcel_mgr->selectionEmpty()) + { + parcel_mgr->deselectLand(); + } } } @@ -259,9 +319,7 @@ void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark) LLUUID region_id; landmark->getRegionID(region_id); landmark->getGlobalPos(mPosGlobal); - mPlaceInfo->displayParcelInfo(landmark->getRegionPos(), - region_id, - mPosGlobal); + mPlaceInfo->displayParcelInfo(region_id, mPosGlobal); } void LLPanelPlaces::onFilterEdit(const std::string& search_string) @@ -382,7 +440,7 @@ void LLPanelPlaces::onOverflowButtonClicked() mPlaceInfoType == "teleport_history") && mPlaceMenu != NULL) { menu = mPlaceMenu; - + // Enable adding a landmark only for agent current parcel and if // there is no landmark already pointing to that parcel in agent's inventory. menu->getChild<LLMenuItemCallGL>("landmark")->setEnabled(is_agent_place_info_visible && @@ -505,8 +563,40 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) } } -//virtual -void LLPanelPlaces::changed(U32 mask) +void LLPanelPlaces::changedParcelSelection() +{ + if (!mPlaceInfo) + return; + + mParcel = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection(); + LLParcel* parcel = mParcel->getParcel(); + LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); + if (!region || !parcel) + return; + + // If agent is inside the selected parcel show agent's region<X, Y, Z>, + // otherwise show region<X, Y, Z> of agent's selection point. + if (region == gAgent.getRegion() && + parcel->getLocalID() == LLViewerParcelMgr::getInstance()->getAgentParcel()->getLocalID()) + { + mPosGlobal = gAgent.getPositionGlobal(); + } + else + { + LLVector3d pos_global = gViewerWindow->getLastPick().mPosGlobal; + if (!pos_global.isExactlyZero()) + { + mPosGlobal = pos_global; + } + } + + mPlaceInfo->resetLocation(); + mPlaceInfo->displaySelectedParcelInfo(parcel, region, mPosGlobal); + + updateVerbs(); +} + +void LLPanelPlaces::changedInventory(U32 mask) { if (!(gInventory.isInventoryUsable() && LLTeleportHistory::getInstance())) return; @@ -541,7 +631,7 @@ void LLPanelPlaces::changed(U32 mask) // we don't need to monitor inventory changes anymore, // so remove the observer - gInventory.removeObserver(this); + gInventory.removeObserver(mInventoryObserver); } void LLPanelPlaces::onAgentParcelChange() @@ -549,11 +639,7 @@ void LLPanelPlaces::onAgentParcelChange() if (!mPlaceInfo) return; - if (mPlaceInfo->getVisible() && mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE) - { - onOpen(LLSD().insert("type", mPlaceInfoType)); - } - else if (mPlaceInfo->isMediaPanelVisible()) + if (mPlaceInfo->isMediaPanelVisible()) { onOpen(LLSD().insert("type", AGENT_INFO_TYPE)); } @@ -800,15 +886,6 @@ static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats) } } -static const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global) -{ - F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS ); - F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS ); - - LLVector3 pos_local(region_x, region_y, (F32)pos_global.mdV[VZ]); - return pos_local; -} - static void onSLURLBuilt(std::string& slurl) { LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(slurl)); diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 057c430230..54bc2b9003 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -32,33 +32,35 @@ #ifndef LL_LLPANELPLACES_H #define LL_LLPANELPLACES_H -#include "lltimer.h" - #include "llpanel.h" -#include "llinventory.h" - -#include "llinventorymodel.h" -#include "llpanelplaceinfo.h" - class LLInventoryItem; +class LLFilterEditor; class LLLandmark; +class LLPanelPlaceInfo; class LLPanelPlacesTab; -class LLFilterEditor; +class LLParcelSelection; +class LLPlacesInventoryObserver; +class LLPlacesParcelObserver; class LLTabContainer; +class LLToggleableMenu; typedef std::pair<LLUUID, std::string> folder_pair_t; -class LLPanelPlaces : public LLPanel, LLInventoryObserver +class LLPanelPlaces : public LLPanel { public: LLPanelPlaces(); virtual ~LLPanelPlaces(); /*virtual*/ BOOL postBuild(); - /*virtual*/ void changed(U32 mask); /*virtual*/ void onOpen(const LLSD& key); + // Called on parcel selection change to update place information. + void changedParcelSelection(); + // Called on agent inventory change to find out when inventory gets usable. + void changedInventory(U32 mask); + void setItem(LLInventoryItem* item); private: @@ -96,9 +98,12 @@ private: LLButton* mShareBtn; LLButton* mOverflowBtn; + LLPlacesInventoryObserver* mInventoryObserver; + LLPlacesParcelObserver* mParcelObserver; + // Pointer to a landmark item or to a linked landmark LLPointer<LLInventoryItem> mItem; - + // Absolute position of the location for teleport, may not // be available (hence zero) LLVector3d mPosGlobal; @@ -118,11 +123,13 @@ private: // List of folders to choose from when creating a landmark folder_vec_t mLandmarkFoldersCache; - + // If root view width or height is changed // the pop-up menu must be updated S32 mRootViewWidth; S32 mRootViewHeight; + + LLSafeHandle<LLParcelSelection> mParcel; }; #endif //LL_LLPANELPLACES_H diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 6d3d307526..ce01568e99 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -46,7 +46,7 @@ class LLAgentHandler : public LLCommandHandler { public: // requires trusted browser to trigger - LLAgentHandler() : LLCommandHandler("agent", true) { } + LLAgentHandler() : LLCommandHandler("agent", UNTRUSTED_THROTTLE) { } bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index df48ee5d08..1fd7928bfc 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -38,6 +38,8 @@ #include "llsidetray.h" #include "llworldmap.h" #include "llteleporthistorystorage.h" +#include "llaccordionctrl.h" +#include "llaccordionctrltab.h" // Not yet implemented; need to remove buildPanel() from constructor when we switch //static LLRegisterPanelClassWrapper<LLTeleportHistoryPanel> t_teleport_history("panel_teleport_history"); @@ -46,7 +48,8 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel() : LLPanelPlacesTab(), mFilterSubString(LLStringUtil::null), mTeleportHistory(NULL), - mHistoryItems(NULL) + mHistoryAccordeon(NULL), + mLastSelectedScrollList(NULL) { LLUICtrlFactory::getInstance()->buildPanel(this, "panel_teleport_history.xml"); } @@ -63,12 +66,28 @@ BOOL LLTeleportHistoryPanel::postBuild() mTeleportHistory->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryPanel::showTeleportHistory, this)); } - mHistoryItems = getChild<LLScrollListCtrl>("history_items"); - if (mHistoryItems) + mHistoryAccordeon = getChild<LLAccordionCtrl>("history_accordion"); + + if (mHistoryAccordeon) { - mHistoryItems->setDoubleClickCallback(onDoubleClickItem, this); - mHistoryItems->setCommitOnSelectionChange(FALSE); - mHistoryItems->setCommitCallback(boost::bind(&LLTeleportHistoryPanel::handleItemSelect, this, _2)); + + for (child_list_const_iter_t iter = mHistoryAccordeon->beginChild(); iter != mHistoryAccordeon->endChild(); iter++) + { + if (dynamic_cast<LLAccordionCtrlTab*>(*iter)) + { + LLAccordionCtrlTab* tab = (LLAccordionCtrlTab*)*iter; + mItemContainers.put(tab); + + LLScrollListCtrl* sl = getScrollListFromTab(tab); + if (sl) + { + sl->setDoubleClickCallback(onDoubleClickItem, this); + sl->setCommitOnSelectionChange(FALSE); + sl->setCommitCallback(boost::bind(&LLTeleportHistoryPanel::handleItemSelect, this, sl)); + } + + } + } } return TRUE; @@ -87,13 +106,16 @@ void LLTeleportHistoryPanel::onSearchEdit(const std::string& string) // virtual void LLTeleportHistoryPanel::onShowOnMap() { - LLScrollListItem* itemp = mHistoryItems->getFirstSelected(); + if (!mLastSelectedScrollList) + return; + + LLScrollListItem* itemp = mLastSelectedScrollList->getFirstSelected(); if(!itemp) return; S32 index = itemp->getColumn(LIST_INDEX)->getValue().asInteger(); - LLVector3d global_pos = mTeleportHistory->getItems()[index].mGlobalPos; + LLVector3d global_pos = mTeleportHistory->getItems()[mTeleportHistory->getItems().size() - 1 - index].mGlobalPos; if (!global_pos.isExactlyZero()) { @@ -105,14 +127,17 @@ void LLTeleportHistoryPanel::onShowOnMap() // virtual void LLTeleportHistoryPanel::onTeleport() { - LLScrollListItem* itemp = mHistoryItems->getFirstSelected(); + if (!mLastSelectedScrollList) + return; + + LLScrollListItem* itemp = mLastSelectedScrollList->getFirstSelected(); if(!itemp) return; S32 index = itemp->getColumn(LIST_INDEX)->getValue().asInteger(); // teleport to existing item in history, so we don't add it again - mTeleportHistory->goToItem(index); + mTeleportHistory->goToItem(mTeleportHistory->getItems().size() - 1 - index); } /* @@ -145,28 +170,41 @@ void LLTeleportHistoryPanel::updateVerbs() if (!isTabVisible()) return; - S32 index = 0; - S32 cur_item = 0; - - LLScrollListItem* itemp = mHistoryItems->getFirstSelected(); - if (itemp) + if (!mLastSelectedScrollList) { - index = itemp->getColumn(LIST_INDEX)->getValue().asInteger(); - cur_item = mTeleportHistory->getItems().size() - 1; + mTeleportBtn->setEnabled(false); + mShowOnMapBtn->setEnabled(false); + return; } - mTeleportBtn->setEnabled(index != cur_item); - mShowOnMapBtn->setEnabled(itemp != NULL); + LLScrollListItem* itemp = mLastSelectedScrollList->getFirstSelected(); + + mTeleportBtn->setEnabled(NULL != itemp && 0 < itemp->getColumn(LIST_INDEX)->getValue().asInteger()); + mShowOnMapBtn->setEnabled(NULL != itemp); } void LLTeleportHistoryPanel::showTeleportHistory() { + if (!mHistoryAccordeon) + return; + const LLTeleportHistoryStorage::slurl_list_t& hist_items = mTeleportHistory->getItems(); - mHistoryItems->deleteAllItems(); + const U32 seconds_in_day = 24 * 60 * 60; + LLDate curr_date = LLDate::now(); + + curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() + seconds_in_day); + + S32 curr_tab = -1; + S32 tabs_cnt = mItemContainers.size(); + S32 curr_year = 0, curr_month = 0, curr_day = 0; + + LLScrollListCtrl *curr_scroll_list = NULL; - for (LLTeleportHistoryStorage::slurl_list_t::const_iterator iter = hist_items.begin(); - iter != hist_items.end(); ++iter) + S32 index = 0; + + for (LLTeleportHistoryStorage::slurl_list_t::const_reverse_iterator iter = hist_items.rbegin(); + iter != hist_items.rend(); ++iter) { std::string landmark_title = (*iter).mTitle; LLStringUtil::toUpper(landmark_title); @@ -176,45 +214,83 @@ void LLTeleportHistoryPanel::showTeleportHistory() if (!passed) continue; + + if (curr_tab < tabs_cnt - 1) + { + const LLDate &date = (*iter).mDate; + + S32 year, month, day; + if (!date.split(&year, &month, &day)) + { + llwarns << "Failed to split date: " << date << llendl; + continue; + } + + if (day != curr_day || month != curr_month || year != curr_year) + { + LLAccordionCtrlTab* tab = NULL; + while (curr_tab < tabs_cnt - 1 && (day != curr_day || month != curr_month || year != curr_year)) + { + curr_tab++; + + tab = mItemContainers.get(mItemContainers.size() - 1 - curr_tab); + tab->setVisible(false); + + curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day); + curr_date.split(&curr_year, &curr_month, &curr_day); + } + + tab->setVisible(true); + + curr_scroll_list = getScrollListFromTab(tab); + if (curr_scroll_list) + { + curr_scroll_list->deleteAllItems(); + } + } + } - S32 index = iter - hist_items.begin(); LLSD row; row["id"] = index; - LLSD& icon_column = row["columns"][LIST_ICON]; - icon_column["column"] = "landmark_icon"; - icon_column["type"] = "icon"; - icon_column["value"] = "inv_item_landmark.tga"; + if (curr_scroll_list) + { + LLSD& icon_column = row["columns"][LIST_ICON]; + icon_column["column"] = "landmark_icon"; + icon_column["type"] = "icon"; + icon_column["value"] = "inv_item_landmark.tga"; + + LLSD& region_column = row["columns"][LIST_ITEM_TITLE]; + region_column["column"] = "region"; + region_column["type"] = "text"; + region_column["value"] = (*iter).mTitle; - LLSD& region_column = row["columns"][LIST_ITEM_TITLE]; - region_column["column"] = "region"; - region_column["type"] = "text"; - region_column["value"] = (*iter).mTitle; + LLSD& index_column = row["columns"][LIST_INDEX]; + index_column["column"] = "index"; + index_column["type"] = "text"; + index_column["value"] = index; - LLSD& index_column = row["columns"][LIST_INDEX]; - index_column["column"] = "index"; - index_column["type"] = "text"; - index_column["value"] = index; + index++; - mHistoryItems->addElement(row, ADD_TOP); + curr_scroll_list->addElement(row); + } } - // Consider last item (most recent) as current - LLScrollListItem* itemp = mHistoryItems->getItem((S32)hist_items.size() - 1); - ((LLScrollListText*)itemp->getColumn(LIST_ITEM_TITLE))->setFontStyle(LLFontGL::BOLD); + mHistoryAccordeon->arrange(); updateVerbs(); } -void LLTeleportHistoryPanel::handleItemSelect(const LLSD& data) +void LLTeleportHistoryPanel::handleItemSelect(LLScrollListCtrl* sl) { + mLastSelectedScrollList = sl; updateVerbs(); } //static void LLTeleportHistoryPanel::onDoubleClickItem(void* user_data) { - LLTeleportHistoryPanel* self = (LLTeleportHistoryPanel*)user_data; + /*LLTeleportHistoryPanel* self = (LLTeleportHistoryPanel*)user_data; LLScrollListItem* itemp = self->mHistoryItems->getFirstSelected(); if(!itemp) @@ -224,5 +300,18 @@ void LLTeleportHistoryPanel::onDoubleClickItem(void* user_data) key["type"] = "teleport_history"; key["id"] = itemp->getColumn(LIST_INDEX)->getValue().asInteger(); - LLSideTray::getInstance()->showPanel("panel_places", key); + LLSideTray::getInstance()->showPanel("panel_places", key);*/ +} + +LLScrollListCtrl* LLTeleportHistoryPanel::getScrollListFromTab(LLAccordionCtrlTab *tab) +{ + for (child_list_const_iter_t iter = tab->beginChild(); iter != tab->endChild(); iter++) + { + if (dynamic_cast<LLScrollListCtrl*>(*iter)) + { + return (LLScrollListCtrl*)*iter; // There should be one scroll list per tab. + } + } + + return NULL; } diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h index 023b04c3fa..a1c15d087b 100644 --- a/indra/newview/llpanelteleporthistory.h +++ b/indra/newview/llpanelteleporthistory.h @@ -40,6 +40,8 @@ #include "llteleporthistory.h" class LLTeleportHistoryStorage; +class LLAccordionCtrl; +class LLAccordionCtrlTab; class LLTeleportHistoryPanel : public LLPanelPlacesTab { @@ -53,13 +55,14 @@ public: /*virtual*/ void onTeleport(); ///*virtual*/ void onCopySLURL(); /*virtual*/ void updateVerbs(); - - void showTeleportHistory(); - void handleItemSelect(const LLSD& data); + +private: static void onDoubleClickItem(void* user_data); + void showTeleportHistory(); + void handleItemSelect(LLScrollListCtrl* ); + LLScrollListCtrl* getScrollListFromTab(LLAccordionCtrlTab *); -private: enum TELEPORT_HISTORY_COLUMN_ORDER { LIST_ICON, @@ -68,8 +71,12 @@ private: }; LLTeleportHistoryStorage* mTeleportHistory; - LLScrollListCtrl* mHistoryItems; + LLAccordionCtrl* mHistoryAccordeon; + LLScrollListCtrl* mLastSelectedScrollList; std::string mFilterSubString; + + typedef LLDynamicArray<LLAccordionCtrlTab*> item_containers_t; + item_containers_t mItemContainers; }; #endif //LL_LLPANELTELEPORTHISTORY_H diff --git a/indra/newview/llrecentpeople.cpp b/indra/newview/llrecentpeople.cpp index 0c16cea004..04abe36878 100644 --- a/indra/newview/llrecentpeople.cpp +++ b/indra/newview/llrecentpeople.cpp @@ -43,7 +43,8 @@ bool LLRecentPeople::add(const LLUUID& id) if (contains(id) || id == gAgent.getID()) return false; - mList.insert(id); + LLDate date_added = LLDate::now(); + mList.insert(std::make_pair(id, date_added)); mChangedSignal(); return true; } @@ -56,8 +57,8 @@ bool LLRecentPeople::contains(const LLUUID& id) const void LLRecentPeople::get(std::vector<LLUUID>& result) const { result.clear(); - for (std::set<LLUUID>::const_iterator pos = mList.begin(); pos != mList.end(); ++pos) - result.push_back(*pos); + for (recent_people_t::const_iterator pos = mList.begin(); pos != mList.end(); ++pos) + result.push_back((*pos).first); } // virtual diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h index 40ac80e8bc..c18116b4e5 100644 --- a/indra/newview/llrecentpeople.h +++ b/indra/newview/llrecentpeople.h @@ -41,6 +41,8 @@ #include <set> #include <boost/signals2.hpp> +class LLDate; + /** * List of people the agent recently interacted with. * @@ -62,7 +64,7 @@ public: * Add specified avatar to the list if it's not there already. * * @param id avatar to add. - * @return false if the avatar is in the list already, true otherwisr + * @return false if the avatar is in the list already, true otherwise */ bool add(const LLUUID& id); @@ -94,7 +96,8 @@ public: /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); private: - std::set<LLUUID> mList; + typedef std::map<LLUUID, LLDate> recent_people_t; + recent_people_t mList; signal_t mChangedSignal; }; diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 1fbe359295..2157f1af74 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -64,6 +64,7 @@ LLScreenChannel::LLScreenChannel(LLUUID& id): mOverflowToastPanel(NULL), mStartU setMouseOpaque( false ); } +//-------------------------------------------------------------------------- void LLScreenChannel::init(S32 channel_left, S32 channel_right) { S32 channel_top = getRootView()->getRect().getHeight() - gSavedSettings.getS32("NavBarMargin"); @@ -326,6 +327,7 @@ void LLScreenChannel::showToastsBottom() mHiddenToastsNum = 0; for(; it != mToastList.rend(); it++) { + (*it).toast->stopTimer(); mHiddenToastsNum++; } createOverflowToast(bottom, gSavedSettings.getS32("NotificationToastTime")); diff --git a/indra/newview/llsearchcombobox.cpp b/indra/newview/llsearchcombobox.cpp index 29d31e8b56..0b7621daa5 100644 --- a/indra/newview/llsearchcombobox.cpp +++ b/indra/newview/llsearchcombobox.cpp @@ -83,6 +83,7 @@ LLSearchComboBox::LLSearchComboBox(const Params&p) mTextEntry->setKeystrokeCallback(boost::bind(&LLComboBox::onTextEntry, this, _1), NULL); setSelectionCallback(boost::bind(&LLSearchComboBox::onSelectionCommit, this)); setPrearrangeCallback(boost::bind(&LLSearchComboBox::onSearchPrearrange, this, _2)); + mSearchButton->setCommitCallback(boost::bind(&LLSearchComboBox::onTextCommit, this, _2)); } void LLSearchComboBox::rebuildSearchHistory(const std::string& filter) @@ -153,16 +154,16 @@ void LLSearchComboBox::onSelectionCommit() std::string search_query = getSimple(); LLStringUtil::trim(search_query); - mTextEntry->setText(search_query); - setControlValue(search_query); - + // Order of add() and mTextEntry->setText does matter because add() will select first item + // in drop down list and its label will be copied to text box rewriting mTextEntry->setText() call if(!search_query.empty()) { remove(search_query); add(search_query, ADD_TOP); } - LLUICtrl::onCommit(); + mTextEntry->setText(search_query); + setControlValue(search_query); } BOOL LLSearchComboBox::remove(const std::string& name) @@ -187,6 +188,23 @@ void LLSearchComboBox::clearHistory() setTextEntry(LLStringUtil::null); } +BOOL LLSearchComboBox::handleKeyHere(KEY key,MASK mask ) +{ + if(mTextEntry->hasFocus() && MASK_NONE == mask && KEY_DOWN == key) + { + S32 first = 0; + S32 size = 0; + + // get entered text (without auto-complete part) + mTextEntry->getSelectionRange(&first, &size); + std::string search_query = mTextEntry->getText(); + search_query.erase(first, size); + + onSearchPrearrange(search_query); + } + return LLComboBox::handleKeyHere(key, mask); +} + LLSearchHistoryBuilder::LLSearchHistoryBuilder(LLSearchComboBox* combo_box, const std::string& filter) : mComboBox(combo_box) , mFilter(filter) diff --git a/indra/newview/llsearchcombobox.h b/indra/newview/llsearchcombobox.h index 38f9a5a26b..c23ebc8923 100644 --- a/indra/newview/llsearchcombobox.h +++ b/indra/newview/llsearchcombobox.h @@ -63,6 +63,8 @@ public: */ void clearHistory(); + /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); + ~LLSearchComboBox(); protected: diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 8fb0f201cb..44e76a0bc1 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -188,6 +188,7 @@ #include "llagentlanguage.h" #include "llwearable.h" #include "llinventorybridge.h" +#include "llappearancemgr.h" #if LL_WINDOWS #include "llwindebug.h" @@ -3345,10 +3346,10 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, } else { - wear_outfit_by_name(outfit_folder_name); + LLAppearanceManager::wearOutfitByName(outfit_folder_name); } - wear_outfit_by_name(gestures); - wear_outfit_by_name(COMMON_GESTURES_FOLDER); + LLAppearanceManager::wearOutfitByName(gestures); + LLAppearanceManager::wearOutfitByName(COMMON_GESTURES_FOLDER); // This is really misnamed -- it means we have started loading // an outfit/shape that will give the avatar a gender eventually. JC diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index c724fb5315..40b8445dcf 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -623,7 +623,7 @@ class LLBalanceHandler : public LLCommandHandler { public: // Requires "trusted" browser/URL source - LLBalanceHandler() : LLCommandHandler("balance", true) { } + LLBalanceHandler() : LLCommandHandler("balance", UNTRUSTED_BLOCK) { } bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) { if (tokens.size() == 1 diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 85814a98c9..fb7574d68b 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -84,11 +84,7 @@ LLToast::LLToast(LLToast::Params p) : LLFloater(LLSD()), //-------------------------------------------------------------------------- BOOL LLToast::postBuild() { - if(mCanFade) - { - mTimer.start(); - } - else + if(!mCanFade) { mTimer.stop(); } @@ -209,6 +205,10 @@ void LLToast::setVisible(BOOL show) if(show) { setBackgroundOpaque(TRUE); + if(!mTimer.getStarted()) + { + mTimer.start(); + } } LLPanel::setVisible(show); if(mPanel) diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp index 913e46e05e..d401943020 100644 --- a/indra/newview/lltoastimpanel.cpp +++ b/indra/newview/lltoastimpanel.cpp @@ -55,8 +55,21 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif mUserName->setValue(p.from); mTime->setValue(p.time); mSessionID = p.session_id; + mNotification = p.notification; - mReplyBtn->setClickedCallback(boost::bind(&LLToastIMPanel::onClickReplyBtn, this)); + // if message comes from the system - there shouldn't be a reply btn + if(p.from == "Second Life") + { + mReplyBtn->setVisible(FALSE); + S32 btn_height = mReplyBtn->getRect().getHeight(); + LLRect msg_rect = mMessage->getRect(); + msg_rect.setLeftTopAndSize(msg_rect.mLeft, msg_rect.mTop, msg_rect.getWidth(), msg_rect.getHeight() + btn_height); + mMessage->setRect(msg_rect); + } + else + { + mReplyBtn->setClickedCallback(boost::bind(&LLToastIMPanel::onClickReplyBtn, this)); + } S32 maxLinesCount; std::istringstream ss( getString("message_max_lines_count") ); @@ -75,7 +88,9 @@ LLToastIMPanel::~LLToastIMPanel() //-------------------------------------------------------------------------- void LLToastIMPanel::onClickReplyBtn() { - LLIMFloater::toggle(mSessionID); + LLSD response = mNotification->getResponseTemplate(); + response["respondbutton"] = true; + mNotification->respond(response); } //-------------------------------------------------------------------------- diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h index 11f489c12f..b51ce23364 100644 --- a/indra/newview/lltoastimpanel.h +++ b/indra/newview/lltoastimpanel.h @@ -63,6 +63,7 @@ private: void onClickReplyBtn(); + LLNotificationPtr mNotification; LLUUID mSessionID; LLAvatarIconCtrl* mAvatar; LLTextBox* mUserName; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index b35208cd03..08040cfaa5 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -73,6 +73,7 @@ #include "llimview.h" #include "llrootview.h" #include "llagentui.h" +#include "llappearancemgr.h" // MAX ITEMS is based on (sizeof(uuid)+2) * count must be < MTUBYTES // or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a @@ -2508,7 +2509,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory( if(drop) { BOOL append = ( (mask & MASK_SHIFT) ? TRUE : FALSE ); - wear_inventory_category(category, false, append); + LLAppearanceManager::wearInventoryCategory(category, false, append); } return ACCEPT_YES_MULTI; } @@ -2516,7 +2517,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory( { if(drop) { - wear_inventory_category(category, true, false); + LLAppearanceManager::wearInventoryCategory(category, true, false); } return ACCEPT_YES_MULTI; } diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index de68dd6153..a7f4cb558e 100644 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -65,6 +65,7 @@ // linden library headers #include "llprimitive.h" #include "llwindow.h" // incBusyCount() +#include "material_codes.h" const LLVector3 DEFAULT_OBJECT_SCALE(0.5f, 0.5f, 0.5f); diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index cb68045310..901d0594f1 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -158,7 +158,8 @@ bool LLURLDispatcherImpl::dispatchApp(const std::string& url, LLMediaCtrl* web, bool trusted_browser) { - if (!LLSLURL::isSLURL(url)) + // ensure the URL is in the secondlife:///app/ format + if (!LLSLURL::isSLURLCommand(url)) { return false; } @@ -170,7 +171,14 @@ bool LLURLDispatcherImpl::dispatchApp(const std::string& url, pathArray.erase(0); // erase "cmd" bool handled = LLCommandDispatcher::dispatch( cmd, pathArray, uri.queryMap(), web, trusted_browser); - return handled; + + // alert if we didn't handle this secondlife:///app/ SLURL + // (but still return true because it is a valid app SLURL) + if (! handled) + { + LLNotifications::instance().add("UnsupportedCommandSLURL"); + } + return true; } // static @@ -323,7 +331,7 @@ public: // Teleport requests *must* come from a trusted browser // inside the app, otherwise a malicious web page could // cause a constant teleport loop. JC - LLTeleportHandler() : LLCommandHandler("teleport", true) { } + LLTeleportHandler() : LLCommandHandler("teleport", UNTRUSTED_BLOCK) { } bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index ec20af46a1..f3557bb8f7 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -53,6 +53,7 @@ #include "llpreviewgesture.h" #include "llviewerwindow.h" #include "lltrans.h" +#include "llappearancemgr.h" ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs @@ -760,6 +761,11 @@ void WearOnAvatarCallback::fire(const LLUUID& inv_item) } } +void ModifiedCOFCallback::fire(const LLUUID& inv_item) +{ + LLAppearanceManager::instance().updateAppearanceFromCOF(); +} + RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp) { mAttach = attachmentp; @@ -874,6 +880,27 @@ void link_inventory_item( const LLAssetType::EType asset_type, LLPointer<LLInventoryCallback> cb) { + const LLInventoryObject *baseobj = gInventory.getObject(item_id); + if (!baseobj) + { + llwarns << "attempt to link to unknown item, linked-to-item's itemID " << item_id << llendl; + return; + } + if (baseobj && baseobj->getIsLinkType()) + { + llwarns << "attempt to create a link to a link, linked-to-item's itemID " << item_id << llendl; + return; + } + + if (baseobj && !LLAssetType::lookupCanLink(baseobj->getType())) + { + // Fail if item can be found but is of a type that can't be linked. + // Arguably should fail if the item can't be found too, but that could + // be a larger behavioral change. + llwarns << "attempt to link an unlinkable item, type = " << baseobj->getActualType() << llendl; + return; + } + LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_LinkInventoryItem); msg->nextBlockFast(_PREHASH_AgentData); @@ -1291,21 +1318,26 @@ bool LLViewerInventoryItem::getIsBrokenLink() const return LLAssetType::lookupIsLinkType(getType()); } -const LLViewerInventoryItem *LLViewerInventoryItem::getLinkedItem() const +LLViewerInventoryItem *LLViewerInventoryItem::getLinkedItem() const { if (mType == LLAssetType::AT_LINK) { - const LLViewerInventoryItem *linked_item = gInventory.getItem(mAssetUUID); + LLViewerInventoryItem *linked_item = gInventory.getItem(mAssetUUID); + if (linked_item && linked_item->getIsLinkType()) + { + llwarns << "Warning: Accessing link to link" << llendl; + return NULL; + } return linked_item; } return NULL; } -const LLViewerInventoryCategory *LLViewerInventoryItem::getLinkedCategory() const +LLViewerInventoryCategory *LLViewerInventoryItem::getLinkedCategory() const { if (mType == LLAssetType::AT_LINK_FOLDER) { - const LLViewerInventoryCategory *linked_category = gInventory.getCategory(mAssetUUID); + LLViewerInventoryCategory *linked_category = gInventory.getCategory(mAssetUUID); return linked_category; } return NULL; diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index c4ff30bbfc..d5b99ac160 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -37,6 +37,8 @@ #include "llframetimer.h" #include "llwearable.h" +#include <boost/signals2.hpp> // boost::signals2::trackable + class LLFolderView; class LLFolderBridge; class LLViewerInventoryCategory; @@ -149,8 +151,8 @@ public: LLTransactionID getTransactionID() const { return mTransactionID; } bool getIsBrokenLink() const; // true if the baseitem this points to doesn't exist in memory. - const LLViewerInventoryItem *getLinkedItem() const; - const LLViewerInventoryCategory *getLinkedCategory() const; + LLViewerInventoryItem *getLinkedItem() const; + LLViewerInventoryCategory *getLinkedCategory() const; // callback void onCallingCardNameLookup(const LLUUID& id, const std::string& first_name, const std::string& last_name); @@ -234,6 +236,11 @@ class WearOnAvatarCallback : public LLInventoryCallback void fire(const LLUUID& inv_item); }; +class ModifiedCOFCallback : public LLInventoryCallback +{ + void fire(const LLUUID& inv_item); +}; + class LLViewerJointAttachment; class RezAttachmentCallback : public LLInventoryCallback diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 338bb7ad7c..12d5687877 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -100,7 +100,6 @@ #include "llfloaterdirectory.h" #include "llfloaterchatterbox.h" #include "llfloaterfonttest.h" -#include "llfloatergesture.h" #include "llfloatergodtools.h" #include "llfloatergroupinvite.h" #include "llfloatergroups.h" @@ -183,7 +182,6 @@ #include "lluuid.h" #include "llviewercamera.h" #include "llviewergenericmessage.h" -#include "llviewergesture.h" #include "llviewertexturelist.h" // gTextureList #include "llviewerinventory.h" #include "llviewermenufile.h" // init_menu_file() @@ -210,8 +208,10 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llfloaternotificationsconsole.h" +#include "llfloatercamera.h" #include "lltexlayer.h" +#include "llappearancemgr.h" using namespace LLVOAvatarDefines; @@ -3767,6 +3767,7 @@ void handle_reset_view() else { reset_view_final( TRUE ); + LLFloaterCamera::resetCameraMode(); } } @@ -6375,13 +6376,13 @@ void handle_selected_texture_info(void*) void handle_test_male(void*) { - wear_outfit_by_name("Male Shape & Outfit"); + LLAppearanceManager::wearOutfitByName("Male Shape & Outfit"); //gGestureList.requestResetFromServer( TRUE ); } void handle_test_female(void*) { - wear_outfit_by_name("Female Shape & Outfit"); + LLAppearanceManager::wearOutfitByName("Female Shape & Outfit"); //gGestureList.requestResetFromServer( FALSE ); } diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index 8bf7364714..21d4c72428 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -207,6 +207,8 @@ #include "patch_dct.h" #include "sound_ids.h" +// Builds work with all headers below commented out as of 2009-09-10 JC + // Library includes from llprimitive #include "imageids.h" #include "legacy_object_types.h" diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index e5d0e3ebb2..f7fbe96aa7 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2364,7 +2364,7 @@ void LLViewerWindow::updateUI() updateWorldViewRect(); - //updateBottomTrayRect(); + updateBottomTrayRect(); LLView::sMouseHandlerMessage.clear(); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index c3c9d7021e..e4f6240fc7 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -51,6 +51,9 @@ #include "llcursortypes.h" #include "llhandle.h" +#include <boost/function.hpp> +#include <boost/signals2.hpp> + class LLView; class LLViewerObject; class LLUUID; diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Avatar_Off.png b/indra/newview/skins/default/textures/bottomtray/Cam_Avatar_Off.png Binary files differnew file mode 100644 index 0000000000..6b725e153a --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Cam_Avatar_Off.png diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_FreeCam_Off.png b/indra/newview/skins/default/textures/bottomtray/Cam_FreeCam_Off.png Binary files differnew file mode 100644 index 0000000000..9f22080d13 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Cam_FreeCam_Off.png diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Orbit_Off.png b/indra/newview/skins/default/textures/bottomtray/Cam_Orbit_Off.png Binary files differnew file mode 100644 index 0000000000..5b2a8eb339 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Cam_Orbit_Off.png diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Pan_Off.png b/indra/newview/skins/default/textures/bottomtray/Cam_Pan_Off.png Binary files differnew file mode 100644 index 0000000000..9acf7053d5 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Cam_Pan_Off.png diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Pan_Over.png b/indra/newview/skins/default/textures/bottomtray/Cam_Pan_Over.png Binary files differnew file mode 100644 index 0000000000..b5781718ec --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Cam_Pan_Over.png diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_In.png b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_In.png Binary files differnew file mode 100644 index 0000000000..c8560c0869 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_In.png diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Out.png b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Out.png Binary files differnew file mode 100644 index 0000000000..b09f7c64d3 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Out.png diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_In.png b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_In.png Binary files differnew file mode 100644 index 0000000000..ae2c57c207 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_In.png diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Out.png b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Out.png Binary files differnew file mode 100644 index 0000000000..c5cd8cca92 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Out.png diff --git a/indra/newview/skins/default/textures/bottomtray/CameraView_Press.png b/indra/newview/skins/default/textures/bottomtray/CameraView_Press.png Binary files differnew file mode 100644 index 0000000000..5a9346fd39 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/CameraView_Press.png diff --git a/indra/newview/skins/default/textures/bottomtray/Move_Fly_Off.png b/indra/newview/skins/default/textures/bottomtray/Move_Fly_Off.png Binary files differnew file mode 100644 index 0000000000..28ff6ba976 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Move_Fly_Off.png diff --git a/indra/newview/skins/default/textures/bottomtray/Move_Run_Off.png b/indra/newview/skins/default/textures/bottomtray/Move_Run_Off.png Binary files differnew file mode 100644 index 0000000000..e2eb38e12d --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Move_Run_Off.png diff --git a/indra/newview/skins/default/textures/bottomtray/Move_Walk_Off.png b/indra/newview/skins/default/textures/bottomtray/Move_Walk_Off.png Binary files differnew file mode 100644 index 0000000000..f314d4e001 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Move_Walk_Off.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Backward_Off.png b/indra/newview/skins/default/textures/bottomtray/Movement_Backward_Off.png Binary files differnew file mode 100644 index 0000000000..4dddc2b391 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Movement_Backward_Off.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Backward_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Backward_On.png Binary files differnew file mode 100644 index 0000000000..9f31d461b5 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Movement_Backward_On.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Down_Off.png b/indra/newview/skins/default/textures/bottomtray/Movement_Down_Off.png Binary files differnew file mode 100644 index 0000000000..1b0192e685 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Movement_Down_Off.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Down_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Down_On.png Binary files differnew file mode 100644 index 0000000000..9f42b7d5b2 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Movement_Down_On.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Forward_Off.png b/indra/newview/skins/default/textures/bottomtray/Movement_Forward_Off.png Binary files differnew file mode 100644 index 0000000000..80d227b6a7 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Movement_Forward_Off.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Forward_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Forward_On.png Binary files differnew file mode 100644 index 0000000000..d0a825a682 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Movement_Forward_On.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_Off.png b/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_Off.png Binary files differnew file mode 100644 index 0000000000..282e8d62de --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_Off.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_On.png Binary files differnew file mode 100644 index 0000000000..b211371e64 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_On.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_Off.png b/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_Off.png Binary files differnew file mode 100644 index 0000000000..5039e57c32 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_Off.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_On.png Binary files differnew file mode 100644 index 0000000000..e937c3f012 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_On.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Up_Off.png b/indra/newview/skins/default/textures/bottomtray/Movement_Up_Off.png Binary files differnew file mode 100644 index 0000000000..9b9837cec1 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Movement_Up_Off.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Up_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Up_On.png Binary files differnew file mode 100644 index 0000000000..c71d4a7854 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Movement_Up_On.png diff --git a/indra/newview/skins/default/textures/bottomtray/Snapshot_Off.png b/indra/newview/skins/default/textures/bottomtray/Snapshot_Off.png Binary files differnew file mode 100644 index 0000000000..6f2726c3e6 --- /dev/null +++ b/indra/newview/skins/default/textures/bottomtray/Snapshot_Off.png diff --git a/indra/newview/skins/default/textures/icons/AddItem_Disabled.png b/indra/newview/skins/default/textures/icons/AddItem_Disabled.png Binary files differnew file mode 100644 index 0000000000..cf88c89ae5 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/AddItem_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/DragHandle.png b/indra/newview/skins/default/textures/icons/DragHandle.png Binary files differnew file mode 100644 index 0000000000..c3cbc07a33 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/DragHandle.png diff --git a/indra/newview/skins/default/textures/icons/Generic_Group.png b/indra/newview/skins/default/textures/icons/Generic_Group.png Binary files differnew file mode 100644 index 0000000000..909334d862 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Generic_Group.png diff --git a/indra/newview/skins/default/textures/icons/Generic_Group_Large.png b/indra/newview/skins/default/textures/icons/Generic_Group_Large.png Binary files differnew file mode 100644 index 0000000000..4d4f1e1bee --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Generic_Group_Large.png diff --git a/indra/newview/skins/default/textures/icons/Generic_Person.png b/indra/newview/skins/default/textures/icons/Generic_Person.png Binary files differnew file mode 100644 index 0000000000..01618ce2c0 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Generic_Person.png diff --git a/indra/newview/skins/default/textures/icons/Generic_Person_Large.png b/indra/newview/skins/default/textures/icons/Generic_Person_Large.png Binary files differnew file mode 100644 index 0000000000..65b0ce8b67 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Generic_Person_Large.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Animation.png b/indra/newview/skins/default/textures/icons/Inv_Animation.png Binary files differnew file mode 100644 index 0000000000..8b69434066 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Animation.png diff --git a/indra/newview/skins/default/textures/icons/Inv_BodyShape.png b/indra/newview/skins/default/textures/icons/Inv_BodyShape.png Binary files differnew file mode 100644 index 0000000000..9d98bfaa7d --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_BodyShape.png diff --git a/indra/newview/skins/default/textures/icons/Inv_CallingCard.png b/indra/newview/skins/default/textures/icons/Inv_CallingCard.png Binary files differnew file mode 100644 index 0000000000..1de96475f7 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_CallingCard.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Clothing.png b/indra/newview/skins/default/textures/icons/Inv_Clothing.png Binary files differnew file mode 100644 index 0000000000..49a54b82e1 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Clothing.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Eye.png b/indra/newview/skins/default/textures/icons/Inv_Eye.png Binary files differnew file mode 100644 index 0000000000..6d0321dde9 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Eye.png diff --git a/indra/newview/skins/default/textures/icons/Inv_FolderClosed.png b/indra/newview/skins/default/textures/icons/Inv_FolderClosed.png Binary files differnew file mode 100644 index 0000000000..30aa6e04ac --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_FolderClosed.png diff --git a/indra/newview/skins/default/textures/icons/Inv_FolderOpen.png b/indra/newview/skins/default/textures/icons/Inv_FolderOpen.png Binary files differnew file mode 100644 index 0000000000..792ef446e8 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_FolderOpen.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Gesture.png b/indra/newview/skins/default/textures/icons/Inv_Gesture.png Binary files differnew file mode 100644 index 0000000000..c49ae523c8 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Gesture.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Gloves.png b/indra/newview/skins/default/textures/icons/Inv_Gloves.png Binary files differnew file mode 100644 index 0000000000..d81bc961d4 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Gloves.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Hair.png b/indra/newview/skins/default/textures/icons/Inv_Hair.png Binary files differnew file mode 100644 index 0000000000..5e68f1ffea --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Hair.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Jacket.png b/indra/newview/skins/default/textures/icons/Inv_Jacket.png Binary files differnew file mode 100644 index 0000000000..0e28f45f19 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Jacket.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Landmark.png b/indra/newview/skins/default/textures/icons/Inv_Landmark.png Binary files differnew file mode 100644 index 0000000000..6648a23393 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Landmark.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Notecard.png b/indra/newview/skins/default/textures/icons/Inv_Notecard.png Binary files differnew file mode 100644 index 0000000000..830a71311f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Notecard.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Object.png b/indra/newview/skins/default/textures/icons/Inv_Object.png Binary files differnew file mode 100644 index 0000000000..a88d0dc4b3 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Object.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Pants.png b/indra/newview/skins/default/textures/icons/Inv_Pants.png Binary files differnew file mode 100644 index 0000000000..2527f7f9c3 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Pants.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Script.png b/indra/newview/skins/default/textures/icons/Inv_Script.png Binary files differnew file mode 100644 index 0000000000..e9c9b163fd --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Script.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Shirt.png b/indra/newview/skins/default/textures/icons/Inv_Shirt.png Binary files differnew file mode 100644 index 0000000000..7cc880a124 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Shirt.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Shoe.png b/indra/newview/skins/default/textures/icons/Inv_Shoe.png Binary files differnew file mode 100644 index 0000000000..0b148647eb --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Shoe.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Skin.png b/indra/newview/skins/default/textures/icons/Inv_Skin.png Binary files differnew file mode 100644 index 0000000000..8e20638bba --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Skin.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Skirt.png b/indra/newview/skins/default/textures/icons/Inv_Skirt.png Binary files differnew file mode 100644 index 0000000000..40860a3599 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Skirt.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Snapshot.png b/indra/newview/skins/default/textures/icons/Inv_Snapshot.png Binary files differnew file mode 100644 index 0000000000..17e710a843 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Snapshot.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Socks.png b/indra/newview/skins/default/textures/icons/Inv_Socks.png Binary files differnew file mode 100644 index 0000000000..b8169dcb36 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Socks.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Sound.png b/indra/newview/skins/default/textures/icons/Inv_Sound.png Binary files differnew file mode 100644 index 0000000000..1a50dd17da --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Sound.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Texture.png b/indra/newview/skins/default/textures/icons/Inv_Texture.png Binary files differnew file mode 100644 index 0000000000..2d6d1b54bb --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Texture.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Underpants.png b/indra/newview/skins/default/textures/icons/Inv_Underpants.png Binary files differnew file mode 100644 index 0000000000..77f56c574f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Underpants.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Undershirt.png b/indra/newview/skins/default/textures/icons/Inv_Undershirt.png Binary files differnew file mode 100644 index 0000000000..954eab7660 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Undershirt.png diff --git a/indra/newview/skins/default/textures/icons/Lock.png b/indra/newview/skins/default/textures/icons/Lock.png Binary files differnew file mode 100644 index 0000000000..eb5b5ae7a9 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Lock.png diff --git a/indra/newview/skins/default/textures/icons/OptionsMenu_Disabled.png b/indra/newview/skins/default/textures/icons/OptionsMenu_Disabled.png Binary files differnew file mode 100644 index 0000000000..fb341e9c83 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OptionsMenu_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/Refresh_Off.png b/indra/newview/skins/default/textures/icons/Refresh_Off.png Binary files differnew file mode 100644 index 0000000000..a8acfda741 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Refresh_Off.png diff --git a/indra/newview/skins/default/textures/icons/TrashItem_Disabled.png b/indra/newview/skins/default/textures/icons/TrashItem_Disabled.png Binary files differnew file mode 100644 index 0000000000..caaf45a99f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/TrashItem_Disabled.png diff --git a/indra/newview/skins/default/textures/navbar/BuyArrow_Over.png b/indra/newview/skins/default/textures/navbar/BuyArrow_Over.png Binary files differnew file mode 100644 index 0000000000..428da506f3 --- /dev/null +++ b/indra/newview/skins/default/textures/navbar/BuyArrow_Over.png diff --git a/indra/newview/skins/default/textures/navbar/BuyArrow_Press.png b/indra/newview/skins/default/textures/navbar/BuyArrow_Press.png Binary files differnew file mode 100644 index 0000000000..9d7716c6de --- /dev/null +++ b/indra/newview/skins/default/textures/navbar/BuyArrow_Press.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index e32ea0944e..136c092afc 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -7,17 +7,19 @@ <texture name="Accordion_Off" file_name="containers/Accordion_Off.png" preload="false" /> <texture name="Accordion_Press" file_name="containers/Accordion_Press.png" preload="false" /> + <texture name="AddItem_Disabled" file_name="icons/AddItem_Disabled.png" preload="false" /> <texture name="AddItem_Off" file_name="icons/AddItem_Off.png" preload="false" /> <texture name="AddItem_Press" file_name="icons/AddItem_Press.png" preload="false" /> - <texture name="Arrow_Left_Off" file_name="navbar/Arrow_Left_Off.png" preload="true"/> - <texture name="Arrow_Left_Press" file_name="navbar/Arrow_Left_Press.png" preload="true"/> - <texture name="Arrow_Right_Off" file_name="navbar/Arrow_Right_Off.png" preload="true"/> - <texture name="Arrow_Right_Press" file_name="navbar/Arrow_Right_Press.png" preload="true"/> + <texture name="Arrow_Left_Off" file_name="navbar/Arrow_Left_Off.png" preload="true" /> + <texture name="Arrow_Left_Press" file_name="navbar/Arrow_Left_Press.png" preload="true" /> + <texture name="Arrow_Right_Off" file_name="navbar/Arrow_Right_Off.png" preload="true" /> + <texture name="Arrow_Right_Press" file_name="navbar/Arrow_Right_Press.png" preload="true" /> <texture name="Arrow_Up" file_name="widgets/Arrow_Up.png" preload="true" /> <texture name="Arrow_Down" file_name="widgets/Arrow_Down.png" preload="true" /> + <texture name="BackArrow_Disabled" file_name="icons/BackArrow_Disabled.png" preload="false" /> <texture name="BackArrow_Off" file_name="icons/BackArrow_Off.png" preload="false" /> <texture name="BackArrow_Press" file_name="icons/BackArrow_Press.png" preload="false" /> @@ -54,7 +56,7 @@ <texture name="Favorite_Star_Active" file_name="navbar/Favorite_Star_Active.png" preload="false" /> <texture name="Favorite_Star_Off" file_name="navbar/Favorite_Star_Off.png" preload="false" /> <texture name="Favorite_Star_Press" file_name="navbar/Favorite_Star_Press.png" preload="false" /> - <texture name="Favorite_Star_Over" file_name="navbar/Favorite_Star_Over.png" preload="false"/> + <texture name="Favorite_Star_Over" file_name="navbar/Favorite_Star_Over.png" preload="false" /> <texture name="FileMenu_BarSelect" file_name="navbar/FileMenu_BarSelect.png" preload="false" /> <texture name="FileMenu_BG" file_name="navbar/FileMenu_BG.png" preload="false" /> @@ -62,13 +64,13 @@ <texture name="ForwardArrow_Off" file_name="icons/ForwardArrow_Off.png" preload="false" /> <texture name="ForwardArrow_Press" file_name="icons/ForwardArrow_Press.png" preload="false" /> - <texture name="Help_Off" file_name="navbar/Help_Off.png" preload="false"/> - <texture name="Help_Press" file_name="navbar/Help_Press.png" preload="false"/> + <texture name="Help_Off" file_name="navbar/Help_Off.png" preload="false" /> + <texture name="Help_Press" file_name="navbar/Help_Press.png" preload="false" /> - <texture name="History_Arrow" file_name="navbar/History_Arrow.png" preload="true"/> + <texture name="History_Arrow" file_name="navbar/History_Arrow.png" preload="true" /> - <texture name="Home_Off" file_name="navbar/Home_Off.png" preload="false"/> - <texture name="Home_Press" file_name="navbar/Home_Press.png" preload="false"/> + <texture name="Home_Off" file_name="navbar/Home_Off.png" preload="false" /> + <texture name="Home_Press" file_name="navbar/Home_Press.png" preload="false" /> <texture name="Icon_Close_Background" file_name="windows/Icon_Close_Background.png" preload="true" /> <texture name="Icon_Close_Foreground" file_name="windows/Icon_Close_Foreground.png" preload="true" /> @@ -79,22 +81,35 @@ <texture name="Icon_Dock_Foreground" file_name="windows/Icon_Dock_Foreground.png" preload="true" /> <texture name="Icon_Dock_Press" file_name="windows/Icon_Dock_Press.png" preload="true" /> - <texture name="Icon_Gear_Background" file_name="windows/Icon_Gear_Background.png" preload="false"/> - <texture name="Icon_Gear_Foreground" file_name="windows/Icon_Gear_Foreground.png" preload="false"/> - <texture name="Icon_Gear_Press" file_name="windows/Icon_Gear_Press.png" preload="false"/> + <texture name="Icon_Gear_Background" file_name="windows/Icon_Gear_Background.png" preload="false" /> + <texture name="Icon_Gear_Foreground" file_name="windows/Icon_Gear_Foreground.png" preload="false" /> + <texture name="Icon_Gear_Press" file_name="windows/Icon_Gear_Press.png" preload="false" /> - <texture name="Icon_Undock_Background" file_name="windows/Icon_Undock_Background.png" preload="true" /> - <texture name="Icon_Undock_Foreground" file_name="windows/Icon_Undock_Foreground.png" preload="true" /> - <texture name="Icon_Undock_Press" file_name="windows/Icon_Undock_Press.png" preload="true" /> + <texture name="Icon_Help_Background" file_name="windows/Icon_Help_Background.png" preload="false" /> + <texture name="Icon_Help_Foreground" file_name="windows/Icon_Help_Foreground.png" preload="false" /> + <texture name="Icon_Help_Press" file_name="windows/Icon_Help_Press.png" preload="false" /> + <texture name="Icon_Info" file_name="windows/Icon_Info.png" preload="false" /> + + <texture name="Icon_Minimize_Background" file_name="windows/Icon_Minimize_Background.png" preload="true" /> + <texture name="Icon_Minimize_Foreground" file_name="windows/Icon_Minimize_Foreground.png" preload="true" /> + <texture name="Icon_Minimize_Press" file_name="windows/Icon_Minimize_Press.png" preload="true" /> + + <texture name="Icon_Undock_Background" file_name="windows/Icon_Undock_Background.png" preload="false" /> + <texture name="Icon_Undock_Foreground" file_name="windows/Icon_Undock_Foreground.png" preload="false" /> + <texture name="Icon_Undock_Press" file_name="windows/Icon_Undock_Press.png" preload="false" /> <texture name="Info" file_name="icons/Info.png" preload="false" /> + <texture name="Info_Off" file_name="navbar/Info_Off.png" preload="false" /> + <texture name="Info_Press" file_name="navbar/Info_Press.png" preload="false" /> - <texture name="Info_Off" file_name="navbar/Info_Off.png" preload="false"/> - <texture name="Info_Press" file_name="navbar/Info_Press.png" preload="false"/> + <texture name="Inspector_Background" file_name="windows/Inspector_Background.png" preload="false" /> + <texture name="Inspector_Hover" file_name="windows/Inspector_Hover.png" preload="false" /> <texture name="ListItem_Select" file_name="widgets/ListItem_Select.png" preload="true" /> <texture name="ListItem_Over" file_name="widgets/ListItem_Over.png" preload="true" /> + <texture name="Lock" file_name="icons/Lock.png" preload="false" /> + <texture name="menu_separator" file_name="navbar/FileMenu_Divider.png" scale.left="4" scale.top="166" scale.right="0" scale.bottom="0" /> <texture name="NavBar_BG_NoFav" file_name="navbar/NavBar_BG_NoFav.png" preload="false" /> @@ -105,6 +120,7 @@ <texture name="NearbyVoice_Lvl3" file_name="bottomtray/NearbyVoice_Lvl3.png" preload="false" /> <texture name="NearbyVoice_On" file_name="bottomtray/NearbyVoice_On.png" preload="false" /> + <texture name="OptionsMenu_Disabled" file_name="icons/OptionsMenu_Disabled.png" preload="false" /> <texture name="OptionsMenu_Off" file_name="icons/OptionsMenu_Off.png" preload="false" /> <texture name="OptionsMenu_Press" file_name="icons/OptionsMenu_Press.png" preload="false" /> @@ -117,7 +133,7 @@ <texture name="PushButton_Selected" file_name="widgets/PushButton_Selected.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> <texture name="PushButton_Selected_Press" file_name="widgets/PushButton_Selected_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> <texture name="PushButton_Selected_Disabled" file_name="widgets/PushButton_Selected_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> - + <texture name="RadioButton_Press" file_name="widgets/RadioButton_Press.png" preload="true" /> <texture name="RadioButton_On_Press" file_name="widgets/RadioButton_On_Press.png" preload="true" /> <texture name="RadioButton_Off" file_name="widgets/RadioButton_Off.png" preload="true" /> @@ -125,7 +141,7 @@ <texture name="RadioButton_Disabled" file_name="widgets/RadioButton_Disabled.png" preload="true" /> <texture name="RadioButton_On_Disabled" file_name="widgets/RadioButton_On_Disabled.png" preload="true" /> - <texture name="Resize_Corner" file_name="windows/Resize_Corner.png" preload="true"/> + <texture name="Resize_Corner" file_name="windows/Resize_Corner.png" preload="true" /> <texture name="Row_Selection" file_name="navbar/Row_Selection.png" preload="false" /> @@ -139,7 +155,7 @@ <texture name="ScrollTrack_Vert" file_name="widgets/ScrollTrack_Vert.png" preload="true" scale.left="2" scale.top="40" scale.bottom="13" scale.right="0" /> <texture name="ScrollTrack_Horiz" file_name="widgets/ScrollTrack_Horiz.png" preload="true" scale.left="4" scale.top="0" scale.bottom="0" scale.right="2" /> - <texture name="Search" file_name="navbar/Search.png" preload="false"/> + <texture name="Search" file_name="navbar/Search.png" preload="false" /> <texture name="SegmentedBtn_Left_Off" file_name="widgets/SegmentedBtn_Left_Off.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> <texture name="SegmentedBtn_Left_Press" file_name="widgets/SegmentedBtn_Left_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> @@ -168,35 +184,35 @@ <texture name="SliderThumb_Disabled" file_name="widgets/SliderThumb_Disabled.png" /> <texture name="SliderThumb_Press" file_name="widgets/SliderThumb_Press.png" /> - <texture name="Stepper_Down_Disabled" file_name="widgets/Stepper_Down_Disabled.png" preload="true"/> - <texture name="Stepper_Down_Off" file_name="widgets/Stepper_Down_Off.png" preload="true"/> - <texture name="Stepper_Down_Press" file_name="widgets/Stepper_Down_Press.png" preload="true"/> - <texture name="Stepper_Up_Disabled" file_name="widgets/Stepper_Up_Disabled.png" preload="true"/> - <texture name="Stepper_Up_Off" file_name="widgets/Stepper_Up_Off.png" preload="true"/> - <texture name="Stepper_Up_Press" file_name="widgets/Stepper_Up_Press.png" preload="true"/> + <texture name="Stepper_Down_Disabled" file_name="widgets/Stepper_Down_Disabled.png" preload="true" /> + <texture name="Stepper_Down_Off" file_name="widgets/Stepper_Down_Off.png" preload="true" /> + <texture name="Stepper_Down_Press" file_name="widgets/Stepper_Down_Press.png" preload="true" /> + <texture name="Stepper_Up_Disabled" file_name="widgets/Stepper_Up_Disabled.png" preload="true" /> + <texture name="Stepper_Up_Off" file_name="widgets/Stepper_Up_Off.png" preload="true" /> + <texture name="Stepper_Up_Press" file_name="widgets/Stepper_Up_Press.png" preload="true" /> <texture name="TabIcon_Appearance_Off" file_name="taskpanel/TabIcon_Appearance_Off.png" preload="false" /> - <texture name="TabIcon_Appearance_Over" file_name="taskpanel/TabIcon_Appearance_Over.png" preload="false"/> + <texture name="TabIcon_Appearance_Over" file_name="taskpanel/TabIcon_Appearance_Over.png" preload="false" /> <texture name="TabIcon_Appearance_Selected" file_name="taskpanel/TabIcon_Appearance_Selected.png" preload="false" /> <texture name="TabIcon_Close_Off" file_name="taskpanel/TabIcon_Close_Off.png" preload="false" /> - <texture name="TabIcon_Close_Over" file_name="taskpanel/TabIcon_Close_Over.png" preload="false"/> + <texture name="TabIcon_Close_Over" file_name="taskpanel/TabIcon_Close_Over.png" preload="false" /> <texture name="TabIcon_Home_Off" file_name="taskpanel/TabIcon_Home_Off.png" preload="false" /> - <texture name="TabIcon_Home_Over" file_name="taskpanel/TabIcon_Home_Over.png" preload="false"/> + <texture name="TabIcon_Home_Over" file_name="taskpanel/TabIcon_Home_Over.png" preload="false" /> <texture name="TabIcon_Home_Selected" file_name="taskpanel/TabIcon_Home_Selected.png" preload="false" /> <texture name="TabIcon_Me_Off" file_name="taskpanel/TabIcon_Me_Off.png" preload="false" /> - <texture name="TabIcon_Me_Over" file_name="taskpanel/TabIcon_Me_Over.png" preload="false"/> + <texture name="TabIcon_Me_Over" file_name="taskpanel/TabIcon_Me_Over.png" preload="false" /> <texture name="TabIcon_Me_Selected" file_name="taskpanel/TabIcon_Me_Selected.png" preload="false" /> <texture name="TabIcon_Open_Off" file_name="taskpanel/TabIcon_Open_Off.png" preload="false" /> - <texture name="TabIcon_Open_Over" file_name="taskpanel/TabIcon_Open_Over.png" preload="false"/> + <texture name="TabIcon_Open_Over" file_name="taskpanel/TabIcon_Open_Over.png" preload="false" /> <texture name="TabIcon_People_Off" file_name="taskpanel/TabIcon_People_Off.png" preload="false" /> - <texture name="TabIcon_People_Over" file_name="taskpanel/TabIcon_People_Over.png" preload="false"/> + <texture name="TabIcon_People_Over" file_name="taskpanel/TabIcon_People_Over.png" preload="false" /> <texture name="TabIcon_People_Selected" file_name="taskpanel/TabIcon_People_Selected.png" preload="false" /> - <texture name="TabIcon_Places_Over" file_name="taskpanel/TabIcon_Places_Over.png" preload="false"/> + <texture name="TabIcon_Places_Over" file_name="taskpanel/TabIcon_Places_Over.png" preload="false" /> <texture name="TabIcon_Places_Off" file_name="taskpanel/TabIcon_Places_Off.png" preload="false" /> <texture name="TabIcon_Places_Selected" file_name="taskpanel/TabIcon_Places_Selected.png" preload="false" /> <texture name="TabIcon_Things_Off" file_name="taskpanel/TabIcon_Things_Off.png" preload="false" /> <texture name="TabIcon_Things_Selected" file_name="taskpanel/TabIcon_Things_Selected.png" preload="false" /> - <texture name="TabIcon_Things_Over" file_name="taskpanel/TabIcon_Things_Over.png" preload="false"/> + <texture name="TabIcon_Things_Over" file_name="taskpanel/TabIcon_Things_Over.png" preload="false" /> <texture name="TabTop_Divider" file_name="containers/TabTop_Divider.png" preload="false" /> <texture name="TabTop_Left_Press" file_name="containers/TabTop_Left_Press.png" preload="false" /> @@ -206,8 +222,8 @@ <texture name="TabTop_Right_Selected" file_name="containers/TabTop_Right_Selected.png" preload="false" /> <texture name="TabTop_Middle_Off" file_name="containers/TabTop_Middle_Off.png" preload="false" scale.left="8" scale.top="8" scale.right="120" scale.bottom="9" /> <texture name="TabTop_Middle_Selected" file_name="containers/TabTop_Middle_Selected.png" preload="false" scale.left="8" scale.top="8" scale.right="96" scale.bottom="9" /> - <texture name="TabTop_Left_Off" file_name="containers/TabTop_Left_Off.png" preload="false" scale.left="8" scale.top="8" scale.right="120" scale.bottom="9"/> - <texture name="TabTop_Left_Selected" file_name="containers/TabTop_Left_Selected.png" preload="false" scale.left="8" scale.top="8" scale.right="96" scale.bottom="9"/> + <texture name="TabTop_Left_Off" file_name="containers/TabTop_Left_Off.png" preload="false" scale.left="8" scale.top="8" scale.right="120" scale.bottom="9" /> + <texture name="TabTop_Left_Selected" file_name="containers/TabTop_Left_Selected.png" preload="false" scale.left="8" scale.top="8" scale.right="96" scale.bottom="9" /> <texture name="TaskPanel_Tab_Off" file_name="taskpanel/TaskPanel_Tab_Off.png" preload="false" scale.left="4" scale.top="29" scale.right="36" scale.bottom="4" /> <texture name="TaskPanel_Tab_Selected" file_name="taskpanel/TaskPanel_Tab_Selected.png" preload="false" scale.left="5" scale.top="30" scale.right="36" scale.bottom="5" /> @@ -235,6 +251,7 @@ <texture name="Toolbar_Right_Press" file_name="containers/Toolbar_Right_Press.png" preload="false" /> <texture name="Toolbar_Right_Selected" file_name="containers/Toolbar_Right_Selected.png" preload="false" /> + <texture name="TrashItem_Disabled" file_name="icons/TrashItem_Disabled.png" preload="false" /> <texture name="TrashItem_Off" file_name="icons/TrashItem_Off.png" preload="false" /> <texture name="TrashItem_Press" file_name="icons/TrashItem_Press.png" preload="false" /> @@ -256,297 +273,297 @@ - <!--There are still references to this old textfield art in the code somewhere -erica--> + <!--WARNING OLD ART *do not use*--> - <texture name="btn_chatbar.tga" scale.left="20" scale.top="24" scale.right="44" scale.bottom="0"/> - <texture name="btn_chatbar_selected.tga" scale.left="20" scale.top="24" scale.right="44" scale.bottom="0"/> + <texture name="btn_chatbar.tga" scale.left="20" scale.top="24" scale.right="44" scale.bottom="0" /> + <texture name="btn_chatbar_selected.tga" scale.left="20" scale.top="24" scale.right="44" scale.bottom="0" /> - <texture name="cam_rotate_out.tga" preload="false"/> - <texture name="cam_rotate_in.tga" preload="false"/> - <texture name="cam_zoom_out.tga" preload="false"/> - <texture name="cam_zoom_plus_in.tga" preload="false"/> - <texture name="cam_zoom_minus_in.tga" preload="false"/> + <texture name="cam_rotate_out.tga" preload="false" /> + <texture name="cam_rotate_in.tga" preload="false" /> + <texture name="cam_zoom_out.tga" preload="false" /> + <texture name="cam_zoom_plus_in.tga" preload="false" /> + <texture name="cam_zoom_minus_in.tga" preload="false" /> - <texture name="close_inactive_blue.tga"/> - <texture name="closebox.tga"/> + <texture name="close_inactive_blue.tga" /> + <texture name="closebox.tga" /> <texture name="icn_clear_lineeditor.tga" /> - <texture name="icn_chatbar.tga"/> - <texture name="icn_media-pause.tga"/> - <texture name="icn_media-play.tga"/> - <texture name="icn_music-play.tga"/> - <texture name="icn_music-pause.tga"/> - <texture name="icn_media_web.tga" preload="true"/> - <texture name="icn_media_movie.tga" preload="true"/> - - <texture name="icn_speaker-muted_dark.tga"/> - <texture name="icn_speaker_dark.tga"/> - - <texture name="icn_voice-localchat.tga"/> - <texture name="icn_voice-groupfocus.tga"/> - <texture name="icn_voice-pvtfocus.tga"/> - - <texture name="jump_left_out.tga"/> - <texture name="jump_left_in.tga"/> - <texture name="jump_right_out.tga"/> - <texture name="jump_right_in.tga"/> - - <texture name="move_forward_out.tga" preload="false"/> - <texture name="move_forward_in.tga" preload="false"/> - <texture name="move_left_out.tga" preload="false"/> - <texture name="move_left_in.tga" preload="false"/> - <texture name="move_turn_left_out.tga" preload="false"/> - <texture name="move_turn_left_in.tga" preload="false"/> - <texture name="move_turn_right_out.tga" preload="false"/> - <texture name="move_turn_right_in.tga" preload="false"/> - <texture name="move_right_out.tga" preload="false"/> - <texture name="move_right_in.tga" preload="false"/> - <texture name="move_up_in.tga" preload="false"/> - <texture name="move_up_out.tga" preload="false"/> - <texture name="move_down_in.tga" preload="false"/> - <texture name="move_down_out.tga" preload="false"/> - - <texture name="tool_grab.tga"/> - <texture name="tool_grab_active.tga"/> - - <texture name="tool_face.tga"/> - <texture name="tool_face_active.tga"/> - - <texture name="tool_create.tga"/> - <texture name="tool_create_active.tga"/> - - <texture name="up_arrow.tga" file_name="up_arrow.png"/> - <texture name="down_arrow.tga" file_name="down_arrow.png"/> - - <texture name="restore_inactive.tga"/> - <texture name="restore.tga"/> - <texture name="restore_pressed.tga"/> - - <texture name="tearoffbox.tga"/> - <texture name="tearoff_pressed.tga"/> - - <texture name="icn_label_music.tga"/> - <texture name="icn_label_media.tga"/> - <texture name="arrow_down.tga"/> - <texture name="cloud-particle.j2c" use_mips="true"/> + <texture name="icn_chatbar.tga" /> + <texture name="icn_media-pause.tga" /> + <texture name="icn_media-play.tga" /> + <texture name="icn_music-play.tga" /> + <texture name="icn_music-pause.tga" /> + <texture name="icn_media_web.tga" preload="true" /> + <texture name="icn_media_movie.tga" preload="true" /> + + <texture name="icn_speaker-muted_dark.tga" /> + <texture name="icn_speaker_dark.tga" /> + + <texture name="icn_voice-localchat.tga" /> + <texture name="icn_voice-groupfocus.tga" /> + <texture name="icn_voice-pvtfocus.tga" /> + + <texture name="jump_left_out.tga" /> + <texture name="jump_left_in.tga" /> + <texture name="jump_right_out.tga" /> + <texture name="jump_right_in.tga" /> + + <texture name="move_forward_out.tga" preload="false" /> + <texture name="move_forward_in.tga" preload="false" /> + <texture name="move_left_out.tga" preload="false" /> + <texture name="move_left_in.tga" preload="false" /> + <texture name="move_turn_left_out.tga" preload="false" /> + <texture name="move_turn_left_in.tga" preload="false" /> + <texture name="move_turn_right_out.tga" preload="false" /> + <texture name="move_turn_right_in.tga" preload="false" /> + <texture name="move_right_out.tga" preload="false" /> + <texture name="move_right_in.tga" preload="false" /> + <texture name="move_up_in.tga" preload="false" /> + <texture name="move_up_out.tga" preload="false" /> + <texture name="move_down_in.tga" preload="false" /> + <texture name="move_down_out.tga" preload="false" /> + + <texture name="tool_grab.tga" /> + <texture name="tool_grab_active.tga" /> + + <texture name="tool_face.tga" /> + <texture name="tool_face_active.tga" /> + + <texture name="tool_create.tga" /> + <texture name="tool_create_active.tga" /> + + <texture name="up_arrow.tga" file_name="up_arrow.png" /> + <texture name="down_arrow.tga" file_name="down_arrow.png" /> + + <texture name="restore_inactive.tga" /> + <texture name="restore.tga" /> + <texture name="restore_pressed.tga" /> + + <texture name="tearoffbox.tga" /> + <texture name="tearoff_pressed.tga" /> + + <texture name="icn_label_music.tga" /> + <texture name="icn_label_media.tga" /> + <texture name="arrow_down.tga" /> + <texture name="cloud-particle.j2c" use_mips="true" /> <texture name="skin_thumbnail_default.png" preload="false" /> - <texture name="icn_textfield_enabled.tga" scale.left="5" scale.top="5" scale.bottom="5" scale.right="5"/> - <texture name="icn_rounded-text-field.tga" scale.left="14" scale.bottom="16" scale.top="16" scale.right="114"/> + <texture name="icn_textfield_enabled.tga" scale.left="5" scale.top="5" scale.bottom="5" scale.right="5" /> + <texture name="icn_rounded-text-field.tga" scale.left="14" scale.bottom="16" scale.top="16" scale.right="114" /> <texture name="toolbar_btn_enabled.tga" scale.left="7" scale.top="32" scale.right="121" scale.bottom="0" /> <texture name="toolbar_btn_disabled.tga" scale.left="7" scale.top="32" scale.right="121" scale.bottom="0" /> <texture name="toolbar_btn_selected.tga" scale.left="7" scale.top="32" scale.right="121" scale.bottom="0" /> - <texture name="minimize_inactive.tga" preload="true"/> +<!--TODO: REPLACE CODE REFERENCE TO THIS ART WITH Icon_Minimize_Background above --> + <texture name="minimize_inactive.tga" preload="true" /> <texture name="minimize.tga" preload="true" /> - <texture name="minimize_pressed.tga" preload="true"/> + <texture name="minimize_pressed.tga" preload="true" /> - <texture name="sm_rounded_corners_simple.tga" scale.left="4" scale.top="4" scale.bottom="4" scale.right="4"/> + <texture name="sm_rounded_corners_simple.tga" scale.left="4" scale.top="4" scale.bottom="4" scale.right="4" /> <texture name="rounded_square.tga" file_name="rounded_square.j2c" preload="true" scale.left="16" scale.top="16" scale.right="112" scale.bottom="16" /> - <texture name="rounded_square_soft.tga" file_name="rounded_square_soft.j2c" preload="true" scale.left="16" scale.top="16" scale.right="112" scale.bottom="16"/> - - <texture name="toolbar_tab.tga" preload="true" scale.left="6" scale.top="42" scale.right="104" scale.bottom="8"/> - <texture name="toolbar_bg.tga" preload="true" scale.left="6" scale.top="42" scale.right="96" scale.bottom="16"/> - - <texture name="tab_top_blue.tga" preload="false" scale.left="8" scale.top="8" scale.right="120" scale.bottom="9"/> - <texture name="tab_top_selected_blue.tga" preload="false" scale.left="8" scale.top="8" scale.right="96" scale.bottom="9"/> - - <texture name="startup_logo.j2c" preload="true"/> - <texture name="color_swatch_alpha.tga" preload="true"/> - - <texture name="active_voice_tab.tga"/> - <texture name="button_anim_pause.tga"/> - <texture name="button_anim_pause_selected.tga"/> - <texture name="button_anim_play.tga"/> - <texture name="button_anim_play_selected.tga"/> - <texture name="button_anim_stop.tga"/> - <texture name="button_anim_stop_selected.tga"/> - <texture name="crosshairs.tga"/> - <texture name="direction_arrow.tga"/> - <texture name="foot_shadow.j2c" use_mips="true"/> - - <texture name="icon_auction.tga"/> - <texture name="icon_avatar_offline.tga"/> - <texture name="icon_avatar_online.tga"/> - <texture name="icon_day_cycle.tga"/> - <texture name="icon_diurnal.tga"/> - <texture name="icon_event.tga"/> - <texture name="icon_event_mature.tga"/> - <texture name="icon_for_sale.tga"/> - <texture name="icon_group.tga"/> - <texture name="icon_groupnotice.tga"/> - <texture name="icon_groupnoticeinventory.tga"/> - <texture name="icon_lock.tga"/> - <texture name="icon_place.tga"/> - <texture name="icon_place_for_sale.tga"/> - <texture name="icon_popular.tga"/> - <texture name="icon_top_pick.tga"/> - - <texture name="inv_folder_animation.tga"/> - <texture name="inv_folder_bodypart.tga"/> - <texture name="inv_folder_callingcard.tga"/> - <texture name="inv_folder_clothing.tga"/> - <texture name="inv_folder_current_outfit.tga"/> - <texture name="inv_folder_gesture.tga"/> - <texture name="inv_folder_landmark.tga"/> - <texture name="inv_folder_lostandfound.tga"/> - <texture name="inv_folder_my_outfits.tga"/> - <texture name="inv_folder_notecard.tga"/> - <texture name="inv_folder_object.tga"/> - <texture name="inv_folder_outfit.tga"/> - <texture name="inv_folder_plain_closed.tga"/> - <texture name="inv_folder_script.tga"/> - <texture name="inv_folder_snapshot.tga"/> - <texture name="inv_folder_sound.tga"/> - <texture name="inv_folder_texture.tga"/> - <texture name="inv_folder_trash.tga"/> - - <texture name="inv_item_animation.tga"/> - <texture name="inv_item_skin.tga"/> - <texture name="inv_item_callingcard_offline.tga"/> - <texture name="inv_item_callingcard_online.tga"/> - <texture name="inv_item_eyes.tga"/> - <texture name="inv_item_gesture.tga"/> - <texture name="inv_item_gloves.tga"/> - <texture name="inv_item_hair.tga"/> - <texture name="inv_item_jacket.tga"/> - <texture name="inv_item_landmark.tga"/> - <texture name="inv_item_landmark_visited.tga"/> - <texture name="inv_item_linkitem.tga"/> - <texture name="inv_item_linkfolder.tga"/> - <texture name="inv_item_notecard.tga"/> - <texture name="inv_item_object.tga"/> - <texture name="inv_item_object_multi.tga"/> - <texture name="inv_item_pants.tga"/> - <texture name="inv_item_script.tga"/> - <texture name="inv_item_shape.tga"/> - <texture name="inv_item_shirt.tga"/> - <texture name="inv_item_shoes.tga"/> - <texture name="inv_item_skirt.tga"/> - <texture name="inv_item_snapshot.tga"/> - <texture name="inv_item_socks.tga"/> - <texture name="inv_item_sound.tga"/> - <texture name="inv_item_texture.tga"/> - <texture name="inv_item_underpants.tga"/> - <texture name="inv_item_undershirt.tga"/> - - <texture name="lag_status_critical.tga"/> - <texture name="lag_status_good.tga"/> - <texture name="lag_status_warning.tga"/> - - <texture name="legend.tga"/> - - <texture name="map_avatar_16.tga"/> - <texture name="map_avatar_8.tga"/> - <texture name="map_avatar_you_8.tga"/> - <texture name="map_event.tga"/> - <texture name="map_event_mature.tga"/> - <texture name="map_home.tga"/> - <texture name="map_infohub.tga"/> - <texture name="map_telehub.tga"/> - <texture name="map_track_16.tga"/> + <texture name="rounded_square_soft.tga" file_name="rounded_square_soft.j2c" preload="true" scale.left="16" scale.top="16" scale.right="112" scale.bottom="16" /> + + <texture name="toolbar_tab.tga" preload="true" scale.left="6" scale.top="42" scale.right="104" scale.bottom="8" /> + <texture name="toolbar_bg.tga" preload="true" scale.left="6" scale.top="42" scale.right="96" scale.bottom="16" /> + + <texture name="tab_top_blue.tga" preload="false" scale.left="8" scale.top="8" scale.right="120" scale.bottom="9" /> + <texture name="tab_top_selected_blue.tga" preload="false" scale.left="8" scale.top="8" scale.right="96" scale.bottom="9" /> + + <texture name="startup_logo.j2c" preload="true" /> + <texture name="color_swatch_alpha.tga" preload="true" /> + + <texture name="active_voice_tab.tga" /> + <texture name="button_anim_pause.tga" /> + <texture name="button_anim_pause_selected.tga" /> + <texture name="button_anim_play.tga" /> + <texture name="button_anim_play_selected.tga" /> + <texture name="button_anim_stop.tga" /> + <texture name="button_anim_stop_selected.tga" /> + <texture name="crosshairs.tga" /> + <texture name="direction_arrow.tga" /> + <texture name="foot_shadow.j2c" use_mips="true" /> + + <texture name="icon_auction.tga" /> + <texture name="icon_avatar_offline.tga" /> + <texture name="icon_avatar_online.tga" /> + <texture name="icon_day_cycle.tga" /> + <texture name="icon_diurnal.tga" /> + <texture name="icon_event.tga" /> + <texture name="icon_event_mature.tga" /> + <texture name="icon_for_sale.tga" /> + <texture name="icon_group.tga" /> + <texture name="icon_groupnotice.tga" /> + <texture name="icon_groupnoticeinventory.tga" /> + <texture name="icon_place.tga" /> + <texture name="icon_place_for_sale.tga" /> + <texture name="icon_popular.tga" /> + <texture name="icon_top_pick.tga" /> + + <texture name="inv_folder_animation.tga" /> + <texture name="inv_folder_bodypart.tga" /> + <texture name="inv_folder_callingcard.tga" /> + <texture name="inv_folder_clothing.tga" /> + <texture name="inv_folder_current_outfit.tga" /> + <texture name="inv_folder_gesture.tga" /> + <texture name="inv_folder_landmark.tga" /> + <texture name="inv_folder_lostandfound.tga" /> + <texture name="inv_folder_my_outfits.tga" /> + <texture name="inv_folder_notecard.tga" /> + <texture name="inv_folder_object.tga" /> + <texture name="inv_folder_outfit.tga" /> + <texture name="inv_folder_plain_closed.tga" /> + <texture name="inv_folder_script.tga" /> + <texture name="inv_folder_snapshot.tga" /> + <texture name="inv_folder_sound.tga" /> + <texture name="inv_folder_texture.tga" /> + <texture name="inv_folder_trash.tga" /> + + <texture name="inv_item_animation.tga" /> + <texture name="inv_item_skin.tga" /> + <texture name="inv_item_callingcard_offline.tga" /> + <texture name="inv_item_callingcard_online.tga" /> + <texture name="inv_item_eyes.tga" /> + <texture name="inv_item_gesture.tga" /> + <texture name="inv_item_gloves.tga" /> + <texture name="inv_item_hair.tga" /> + <texture name="inv_item_jacket.tga" /> + <texture name="inv_item_landmark.tga" /> + <texture name="inv_item_landmark_visited.tga" /> + <texture name="inv_item_linkitem.tga" /> + <texture name="inv_item_linkfolder.tga" /> + <texture name="inv_item_notecard.tga" /> + <texture name="inv_item_object.tga" /> + <texture name="inv_item_object_multi.tga" /> + <texture name="inv_item_pants.tga" /> + <texture name="inv_item_script.tga" /> + <texture name="inv_item_shape.tga" /> + <texture name="inv_item_shirt.tga" /> + <texture name="inv_item_shoes.tga" /> + <texture name="inv_item_skirt.tga" /> + <texture name="inv_item_snapshot.tga" /> + <texture name="inv_item_socks.tga" /> + <texture name="inv_item_sound.tga" /> + <texture name="inv_item_texture.tga" /> + <texture name="inv_item_underpants.tga" /> + <texture name="inv_item_undershirt.tga" /> + + <texture name="lag_status_critical.tga" /> + <texture name="lag_status_good.tga" /> + <texture name="lag_status_warning.tga" /> + + <texture name="legend.tga" /> + + <texture name="map_avatar_16.tga" /> + <texture name="map_avatar_8.tga" /> + <texture name="map_avatar_you_8.tga" /> + <texture name="map_event.tga" /> + <texture name="map_event_mature.tga" /> + <texture name="map_home.tga" /> + <texture name="map_infohub.tga" /> + <texture name="map_telehub.tga" /> + <texture name="map_track_16.tga" /> <texture name="media_icon.tga" file_name="icn_label_media.tga" /> <texture name="music_icon.tga" file_name="icn_label_music.tga" /> <texture name="NoEntryLines" file_name="world/NoEntryLines.png" use_mips="true" preload="false" /> <texture name="NoEntryPassLines" file_name="world/NoEntryPassLines.png" use_mips="true" preload="false" /> - <texture name="notify_tip_icon.tga"/> - <texture name="notify_caution_icon.tga"/> - <texture name="notify_next.png" preload="true"/> - <texture name="notify_box_icon.tga"/> - - <texture name="object_cone.tga"/> - <texture name="object_cone_active.tga"/> - <texture name="object_cube.tga"/> - <texture name="object_cube_active.tga"/> - <texture name="object_cylinder.tga"/> - <texture name="object_cylinder_active.tga"/> - <texture name="object_grass.tga"/> - <texture name="object_grass_active.tga"/> - <texture name="object_hemi_cone.tga"/> - <texture name="object_hemi_cone_active.tga"/> - <texture name="object_hemi_cylinder.tga"/> - <texture name="object_hemi_cylinder_active.tga"/> - <texture name="object_hemi_sphere.tga"/> - <texture name="object_hemi_sphere_active.tga"/> - <texture name="object_prism.tga"/> - <texture name="object_prism_active.tga"/> - <texture name="object_pyramid.tga"/> - <texture name="object_pyramid_active.tga"/> - <texture name="object_ring.tga"/> - <texture name="object_ring_active.tga"/> - <texture name="object_sphere.tga"/> - <texture name="object_sphere_active.tga"/> - <texture name="object_tetrahedron.tga"/> - <texture name="object_tetrahedron_active.tga"/> - <texture name="object_torus.tga"/> - <texture name="object_torus_active.tga"/> - <texture name="object_tree.tga"/> - <texture name="object_tree_active.tga"/> - <texture name="object_tube.tga"/> - <texture name="object_tube_active.tga"/> - - <texture name="pixiesmall.j2c" use_mips="true"/> - <texture name="script_error.j2c" use_mips="true"/> - <texture name="silhouette.j2c" use_mips="true"/> - - <texture name="status_no_build.tga"/> - <texture name="status_voice.tga"/> - <texture name="status_buy_currency.tga"/> - <texture name="status_buy_currency_pressed.tga"/> - <texture name="status_buy_land.tga"/> - <texture name="status_buy_land_pressed.tga"/> - <texture name="status_no_fly.tga"/> - <texture name="status_health.tga"/> - <texture name="status_no_push.tga"/> - <texture name="status_no_scripts.tga"/> - - <texture name="tool_dozer.tga"/> - <texture name="tool_dozer_active.tga"/> - <texture name="tool_zoom.tga"/> - <texture name="tool_zoom_active.tga"/> - - <texture name="icn_active-speakers-dot-lvl0.tga"/> - <texture name="icn_active-speakers-dot-lvl1.tga"/> - <texture name="icn_active-speakers-dot-lvl2.tga"/> - <texture name="icn_active-speakers-typing1.tga"/> - <texture name="icn_active-speakers-typing2.tga"/> - <texture name="icn_active-speakers-typing3.tga"/> - - <texture name="icn_voice_ptt-off.tga"/> - <texture name="icn_voice_ptt-on.tga"/> - <texture name="icn_voice_ptt-on-lvl1.tga"/> - <texture name="icn_voice_ptt-on-lvl2.tga"/> - <texture name="icn_voice_ptt-on-lvl3.tga"/> - <texture name="icn_voice-call-end.tga"/> - <texture name="icn_voice-call-start.tga"/> - - <texture name="mute_icon.tga"/> - - <texture name="default_land_picture.j2c"/> - <texture name="default_profile_picture.j2c"/> - <texture name="locked_image.j2c"/> - - <texture name="media_btn_back.png"/> - <texture name="media_btn_done.png"/> - <texture name="media_btn_forward.png"/> - <texture name="media_btn_home.png"/> - <texture name="media_btn_newwindow.png"/> - <texture name="media_btn_optimalzoom.png"/> - <texture name="media_btn_reload.png"/> - <texture name="media_btn_scrolldown.png"/> - <texture name="media_btn_scrollleft.png"/> - <texture name="media_btn_scrollright.png"/> - <texture name="media_btn_scrollup.png"/> - <texture name="media_btn_stoploading.png"/> - <texture name="media_panel_divider.png"/> - - <texture name="media_floater_border_16.png" scale_top="12" scale_left="4" scale_bottom="4" scale_right="12"/> + <texture name="notify_tip_icon.tga" /> + <texture name="notify_caution_icon.tga" /> + <texture name="notify_next.png" preload="true" /> + <texture name="notify_box_icon.tga" /> + + <texture name="object_cone.tga" /> + <texture name="object_cone_active.tga" /> + <texture name="object_cube.tga" /> + <texture name="object_cube_active.tga" /> + <texture name="object_cylinder.tga" /> + <texture name="object_cylinder_active.tga" /> + <texture name="object_grass.tga" /> + <texture name="object_grass_active.tga" /> + <texture name="object_hemi_cone.tga" /> + <texture name="object_hemi_cone_active.tga" /> + <texture name="object_hemi_cylinder.tga" /> + <texture name="object_hemi_cylinder_active.tga" /> + <texture name="object_hemi_sphere.tga" /> + <texture name="object_hemi_sphere_active.tga" /> + <texture name="object_prism.tga" /> + <texture name="object_prism_active.tga" /> + <texture name="object_pyramid.tga" /> + <texture name="object_pyramid_active.tga" /> + <texture name="object_ring.tga" /> + <texture name="object_ring_active.tga" /> + <texture name="object_sphere.tga" /> + <texture name="object_sphere_active.tga" /> + <texture name="object_tetrahedron.tga" /> + <texture name="object_tetrahedron_active.tga" /> + <texture name="object_torus.tga" /> + <texture name="object_torus_active.tga" /> + <texture name="object_tree.tga" /> + <texture name="object_tree_active.tga" /> + <texture name="object_tube.tga" /> + <texture name="object_tube_active.tga" /> + + <texture name="pixiesmall.j2c" use_mips="true" /> + <texture name="script_error.j2c" use_mips="true" /> + <texture name="silhouette.j2c" use_mips="true" /> + + <texture name="status_no_build.tga" /> + <texture name="status_voice.tga" /> + <texture name="status_buy_currency.tga" /> + <texture name="status_buy_currency_pressed.tga" /> + <texture name="status_buy_land.tga" /> + <texture name="status_buy_land_pressed.tga" /> + <texture name="status_no_fly.tga" /> + <texture name="status_health.tga" /> + <texture name="status_no_push.tga" /> + <texture name="status_no_scripts.tga" /> + + <texture name="tool_dozer.tga" /> + <texture name="tool_dozer_active.tga" /> + <texture name="tool_zoom.tga" /> + <texture name="tool_zoom_active.tga" /> + + <texture name="icn_active-speakers-dot-lvl0.tga" /> + <texture name="icn_active-speakers-dot-lvl1.tga" /> + <texture name="icn_active-speakers-dot-lvl2.tga" /> + <texture name="icn_active-speakers-typing1.tga" /> + <texture name="icn_active-speakers-typing2.tga" /> + <texture name="icn_active-speakers-typing3.tga" /> + + <texture name="icn_voice_ptt-off.tga" /> + <texture name="icn_voice_ptt-on.tga" /> + <texture name="icn_voice_ptt-on-lvl1.tga" /> + <texture name="icn_voice_ptt-on-lvl2.tga" /> + <texture name="icn_voice_ptt-on-lvl3.tga" /> + <texture name="icn_voice-call-end.tga" /> + <texture name="icn_voice-call-start.tga" /> + + <texture name="mute_icon.tga" /> + + <texture name="default_land_picture.j2c" /> + <texture name="default_profile_picture.j2c" /> + <texture name="locked_image.j2c" /> + + <texture name="media_btn_back.png" /> + <texture name="media_btn_done.png" /> + <texture name="media_btn_forward.png" /> + <texture name="media_btn_home.png" /> + <texture name="media_btn_newwindow.png" /> + <texture name="media_btn_optimalzoom.png" /> + <texture name="media_btn_reload.png" /> + <texture name="media_btn_scrolldown.png" /> + <texture name="media_btn_scrollleft.png" /> + <texture name="media_btn_scrollright.png" /> + <texture name="media_btn_scrollup.png" /> + <texture name="media_btn_stoploading.png" /> + <texture name="media_panel_divider.png" /> + + <texture name="media_floater_border_16.png" scale_top="12" scale_left="4" scale_bottom="4" scale_right="12" /> <texture name="media_panel_bg.png" preload="true" scale_left="9" scale_top="9" scale_right="9" scale_bottom="9" /> <texture name="media_panel_hoverrectangle.png" preload="true" scale_left="9" scale_top="9" scale_right="9" scale_bottom="9" /> diff --git a/indra/newview/skins/default/textures/windows/Icon_Help_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Help_Foreground.png Binary files differnew file mode 100644 index 0000000000..350a62c0ae --- /dev/null +++ b/indra/newview/skins/default/textures/windows/Icon_Help_Foreground.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Help_Press.png b/indra/newview/skins/default/textures/windows/Icon_Help_Press.png Binary files differnew file mode 100644 index 0000000000..c2d401b131 --- /dev/null +++ b/indra/newview/skins/default/textures/windows/Icon_Help_Press.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Minimize_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Minimize_Foreground.png Binary files differnew file mode 100644 index 0000000000..a164edb62d --- /dev/null +++ b/indra/newview/skins/default/textures/windows/Icon_Minimize_Foreground.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Minimize_Press.png b/indra/newview/skins/default/textures/windows/Icon_Minimize_Press.png Binary files differnew file mode 100644 index 0000000000..990e03e2b2 --- /dev/null +++ b/indra/newview/skins/default/textures/windows/Icon_Minimize_Press.png diff --git a/indra/newview/skins/default/textures/windows/Inspector_Background.png b/indra/newview/skins/default/textures/windows/Inspector_Background.png Binary files differnew file mode 100644 index 0000000000..807e8e553c --- /dev/null +++ b/indra/newview/skins/default/textures/windows/Inspector_Background.png diff --git a/indra/newview/skins/default/textures/windows/Inspector_Hover.png b/indra/newview/skins/default/textures/windows/Inspector_Hover.png Binary files differnew file mode 100644 index 0000000000..feeee78033 --- /dev/null +++ b/indra/newview/skins/default/textures/windows/Inspector_Hover.png diff --git a/indra/newview/skins/default/xui/en/floater_customize.xml b/indra/newview/skins/default/xui/en/floater_customize.xml index 824df082d8..4463d44049 100644 --- a/indra/newview/skins/default/xui/en/floater_customize.xml +++ b/indra/newview/skins/default/xui/en/floater_customize.xml @@ -35,14 +35,14 @@ width="389"> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="333" mouse_opaque="true" name="square" top="5" - width="16" /> + width="18" /> <icon height="16" layout="topleft" @@ -331,14 +331,14 @@ scratch and wear it. width="389"> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="333" mouse_opaque="true" name="square" top="5" - width="16" /> + width="18" /> <icon height="16" layout="topleft" @@ -586,14 +586,14 @@ scratch and wear it. width="389"> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="333" mouse_opaque="true" name="square" top="5" - width="16" /> + width="18" /> <icon height="16" layout="topleft" @@ -814,14 +814,14 @@ scratch and wear it. width="389"> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="333" mouse_opaque="true" name="square" top="5" - width="16" /> + width="18" /> <icon height="16" layout="topleft" @@ -1002,14 +1002,14 @@ scratch and wear it. width="389"> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="333" mouse_opaque="true" name="square" top="5" - width="16" /> + width="18" /> <icon height="16" layout="topleft" @@ -1223,14 +1223,14 @@ scratch and wear it. width="389"> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="333" mouse_opaque="true" name="square" top="5" - width="16" /> + width="18" /> <icon height="16" layout="topleft" @@ -1444,14 +1444,14 @@ scratch and wear it. width="389"> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="333" mouse_opaque="true" name="square" top="5" - width="16" /> + width="18" /> <icon height="16" layout="topleft" @@ -1665,14 +1665,14 @@ scratch and wear it. width="389"> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="333" mouse_opaque="true" name="square" top="5" - width="16" /> + width="18" /> <icon height="16" layout="topleft" @@ -1886,14 +1886,14 @@ scratch and wear it. width="389"> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="333" mouse_opaque="true" name="square" top="5" - width="16" /> + width="18" /> <icon height="16" layout="topleft" @@ -2119,14 +2119,14 @@ scratch and wear it. width="389"> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="333" mouse_opaque="true" name="square" top="5" - width="16" /> + width="18" /> <icon height="16" layout="topleft" @@ -2340,14 +2340,14 @@ scratch and wear it. width="389"> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="333" mouse_opaque="true" name="square" top="5" - width="16" /> + width="18" /> <icon height="16" layout="topleft" @@ -2561,14 +2561,14 @@ scratch and wear it. width="389"> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="333" mouse_opaque="true" name="square" top="5" - width="16" /> + width="18" /> <icon height="16" layout="topleft" @@ -2782,14 +2782,14 @@ scratch and wear it. width="389"> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="333" mouse_opaque="true" name="square" top="5" - width="16" /> + width="18" /> <icon height="16" layout="topleft" @@ -3003,14 +3003,14 @@ scratch and wear it. width="389"> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="333" mouse_opaque="true" name="square" top="5" - width="16" /> + width="18" /> <icon height="16" layout="topleft" @@ -3305,14 +3305,14 @@ scratch and wear it. width="389"> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="333" mouse_opaque="true" name="square" top="5" - width="16" /> + width="18" /> <icon height="16" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_inventory.xml b/indra/newview/skins/default/xui/en/floater_inventory.xml index 37c6cbf391..e94ca1b30b 100644 --- a/indra/newview/skins/default/xui/en/floater_inventory.xml +++ b/indra/newview/skins/default/xui/en/floater_inventory.xml @@ -25,6 +25,8 @@ Fetched </floater.string> <filter_editor + search_button_visible="false" + text_pad_left="12" follows="left|top|right" height="16" label="Type here to search" diff --git a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml index 467168ebd8..10bcee7c85 100644 --- a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml +++ b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml @@ -29,14 +29,14 @@ </floater.string> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="294" mouse_opaque="true" name="IconLocked" top="5" - width="16" /> + width="18" /> <text type="string" length="1" @@ -410,7 +410,7 @@ width="330"> Mark Item: </text--> - + <!--radio_group draw_border="false" @@ -438,7 +438,7 @@ top_delta="0" width="70" /> </radio_group--> - + <!--text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml index a767b40b03..3e2045e1f7 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml @@ -29,14 +29,14 @@ </floater.string> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="340" mouse_opaque="true" name="lock" top="1" - width="16" /> + width="18" /> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/floater_script_preview.xml b/indra/newview/skins/default/xui/en/floater_script_preview.xml index cb3ff92363..ef68478460 100644 --- a/indra/newview/skins/default/xui/en/floater_script_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_script_preview.xml @@ -26,14 +26,14 @@ width="497" /> <icon follows="top|right" - height="16" - image_name="icon_lock.tga" + height="18" + image_name="Lock" layout="topleft" left="444" mouse_opaque="true" name="lock" top="3" - width="16" /> + width="18" /> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml index d76ea398d5..76b2e5c811 100644 --- a/indra/newview/skins/default/xui/en/floater_sys_well.xml +++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml @@ -1,9 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater - background_opaque="false" - background_visible="true" bevel_style="in" - bg_alpha_color="0.0 0.0 0.0 0.0" left="0" top="0" follows="right|bottom" diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index b53f4fb99c..e373da300c 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -283,6 +283,7 @@ label_selected="Options" layout="topleft" name="Options..." + tool_tip="Set the Grid Options" width="26" height="22" /> <button @@ -959,15 +960,15 @@ mouse_opaque="true" name="sale type" intial_value="2"> - <combo_item + <combo_box.item name="Copy" label="Copy" value="2" /> - <combo_item + <combo_box.item name="Contents" label="Contents" value="3" /> - <combo_item + <combo_box.item name="Original" label="Original" value="1" /> @@ -2685,16 +2686,17 @@ layout="topleft" left_delta="0" name="checkbox show owners" - tool_tip="Color parcels by owner" + tool_tip="Colorize the parcels according to the type of owner" top_pad="8" width="205" /> - <button - image_overlay="Arrow_Right_Off" - picture_style="true" + <button + image_overlay="Arrow_Right_Off" + picture_style="true" left_pad="5" name="button show owners help" - width="26" - height="22" /> + tool_tip="See an explanation of colors" + width="26" + height="22" /> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 9ad9a87f95..9306f83dde 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1504,6 +1504,17 @@ </menu_item_check> <menu_item_separator layout="topleft" /> + <menu_item_check + label="Avatar Rendering Cost" + layout="topleft" + name="Avatar Rendering Cost"> + <menu_item_check.on_check + function="Advanced.CheckInfoDisplay" + parameter="shame" /> + <menu_item_check.on_click + function="Advanced.ToggleInfoDisplay" + parameter="shame" /> + </menu_item_check> <menu create_jump_keys="true" label="Rendering Types" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 8b20918700..7ede45a080 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6495,10 +6495,10 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block <notification icon="notifytip.tga" - name="UnableToOpenCommandURL" + name="UnsupportedCommandSLURL" priority="high" type="notifytip"> - The link you clicked cannot be opened from this web browser. + The SLurl you clicked on is not supported. </notification> <notification name="IMToast" type="notifytoast"> diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml index 3de3365539..f211ae0ad6 100644 --- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml @@ -1,65 +1,89 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- All our XML is utf-8 encoded. --> - +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - name="avatar_list_item" - title="avatar_list_item" - visible="true" - width="314" - height="30" - left="0" - top="100" - follows="bottom|right|left" - min_width="150" - max_height="30" - - background_opaque="false" - background_visible="true" - bevel_style="in" - bg_alpha_color="0.3 0.3 0.3 1.0"> - - <avatar_icon - bottom="5" left="5" width="20" height="20" follows="top|left" - color="1 1 1 1" enabled="true" image_name="smile.png" - mouse_opaque="true" name="avatar_icon" - /> - - <text - bottom="4" left="35" width="160" height="20" follows="right|left" - font="SansSerifBigBold" text_color="white" - mouse_opaque="true" name="user_name" > - Boris Linden - </text> - - <text - bottom="3" left="190" width="40" height="20" follows="right" - font="SansSerif" text_color="0.5 0.5 0.5 1.0" - mouse_opaque="true" name="user_status" > - Away - </text> - - <icon - bottom="5" left="230" width="20" height="20" follows="right" - color="1 1 1 1" enabled="true" image_name="speaking_indicator.tga" - mouse_opaque="true" name="locator" - /> - - <button - bottom="5" left="260" width="20" height="20" follows="right" - name="info_btn" label="" - image_unselected="avatar_info_btn.tga" image_disabled="avatar_info_btn.tga" - image_selected="avatar_info_btn_active.tga" image_hover_selected="avatar_info_btn_active.tga" - image_disabled_selected="avatar_info_btn.tga" font="SansSerifBigBold" - /> - - <button - bottom="5" left="290" width="20" height="20" follows="right" - name="profile_btn" label="" - image_unselected="profile_chevron_btn.tga" image_disabled="profile_chevron_btn.tga" - image_selected="profile_chevron_btn_active.tga" image_hover_selected="profile_chevron_btn_active.tga" - image_disabled_selected="profile_chevron_btn.tga" font="SansSerifBigBold" - /> - - - -</panel> + follows="top|right|left" + height="24" + layout="topleft" + left="0" + name="avatar_list_item" + top="0" + width="320"> + <icon + follows="top|right|left" + height="24" + image_name="ListItem_Over" + layout="topleft" + left="0" + name="hovered_icon" + top="0" + visible="false" + width="320" /> + <icon + height="24" + follows="top|right|left" + image_name="ListItem_Select" + layout="topleft" + left="0" + name="selected_icon" + top="0" + visible="false" + width="320" /> + <avatar_icon + follows="top|left" + height="20" + image_name="smile.png" + layout="topleft" + left="5" + mouse_opaque="true" + top="2" + width="20" /> + <text + follows="left|right" + font="SansSerifBigBold" + height="20" + layout="topleft" + left_pad="5" + name="avatar_name" + text_color="white" + top="4" + use_ellipses="true" + value="Unknown" + width="180" /> + <text + follows="right" + font="SansSerif" + height="20" + layout="topleft" + left_pad="10" + name="avatar_status" + text_color="0.5 0.5 0.5 1" + value="Away" + width="50" /> + <output_monitor + auto_update="true" + follows="right" + draw_border="false" + halign="left" + height="16" + layout="topleft" + left_pad="3" + mouse_opaque="true" + name="speaking_indicator" + top="4" + visible="true" + width="20" /> + <button + follows="right" + font="SansSerifBigBold" + height="18" + image_disabled="Info" + image_disabled_selected="Info" + image_hover_selected="Info" + image_selected="Info" + image_unselected="Info" + layout="topleft" + left_pad="2" + name="info_btn" + picture_style="true" + top="2" + width="18" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index df91920721..6449059ef0 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel + mouse_opaque="false" background_visible="true" bg_alpha_color="0.25 0.25 0.25 1" bg_opaque_color="0.25 0.25 0.25 1" @@ -12,6 +13,7 @@ border_visible="true" width="1000"> <layout_stack + mouse_opaque="false" border_size="0" clip="false" follows="left|right|bottom|top" @@ -33,6 +35,7 @@ top="0" width="5"/> <layout_panel + mouse_opaque="false" auto_resize="false" follows="left|right" height="28" @@ -57,6 +60,7 @@ top="0" width="3"/> <layout_panel + mouse_opaque="false" auto_resize="false" follows="right" height="28" @@ -96,6 +100,7 @@ top="0" width="8"/> <layout_panel + mouse_opaque="false" auto_resize="false" follows="right" height="28" @@ -188,6 +193,7 @@ top="0" width="5"/> <layout_panel + mouse_opaque="false" follows="left|right" height="28" layout="topleft" @@ -197,6 +203,7 @@ width="150" user_resize="false"> <chiclet_panel + mouse_opaque="false" follows="left|right" height="25" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml index 6ba4d13117..311caa4866 100644 --- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml @@ -16,28 +16,28 @@ name="want_apply_text"> Do you want to apply these changes? </panel.string> - - <button - layout="topleft" - name="back" - right="-9" - top="0" - width="25" - height="25" + + <button + layout="topleft" + name="back" + right="-9" + top="0" + width="25" + height="25" label="" follows="top|left" image_overlay="BackArrow_Off" tab_stop="false" /> - <text - layout="topleft" - top="0" - left="10" - width="250" - height="20" - font="SansSerifHugeBold" - text_color="white" + <text + layout="topleft" + top="0" + left="10" + width="250" + height="20" + font="SansSerifHugeBold" + text_color="white" follows="top|left|right" - mouse_opaque="true" + mouse_opaque="true" name="group_name">(Loading...)</text> <texture_picker follows="left|top" @@ -81,15 +81,15 @@ left="5" width="65" /> <button - top="632" - left="75" - height="20" - font="SansSerifSmall" - label="Refresh" - label_selected="Refresh" + follows="top|left" + height="20" + image_overlay="Refresh_Off" + layout="topleft" name="btn_refresh" - follows="top|left" - width="65" /> + picture_style="true" + top="632" + left="75" + width="20" /> <button top="632" height="20" diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml index 9ae165cbb9..7b8bd8b337 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -185,7 +185,7 @@ Select multiple Members by holding the Ctrl key and clicking on their names. </panel.string> - <search_editor + <filter_editor layout="topleft" top="10" left="4" @@ -193,17 +193,9 @@ clicking on their names. height="20" follows="left|top|right" max_length="250" - label="Filter People" + label="Filter Members" name="filter_input" - font="SansSerif" - background_image="TextField_Search_Off" - text_pad_left="10" - text_color="black"> - <search_button label="" - top_pad="4" - left_pad="6" - /> - </search_editor> + font="SansSerif" /> <!--<line_editor border_style="line" border_thickness="1" @@ -318,7 +310,7 @@ including the Everyone and Owner Roles. name="power_partial_icon"> checkbox_enabled_false.tga </panel.string> - <search_editor + <filter_editor layout="topleft" top="10" left="4" @@ -328,15 +320,7 @@ including the Everyone and Owner Roles. max_length="250" label="Filter Roles" name="filter_input" - font="SansSerif" - background_image="TextField_Search_Off" - text_pad_left="10" - text_color="black"> - <search_button label="" - top_pad="4" - left_pad="6" - /> - </search_editor> + font="SansSerif" /> <!--<line_editor border_style="line" border_thickness="1" @@ -426,7 +410,7 @@ including the Everyone and Owner Roles. Abilities allow Members in Roles to do specific things in this group. There's a broad variety of Abilities. </panel.string> - <search_editor + <filter_editor layout="topleft" top="10" left="4" @@ -436,15 +420,7 @@ things in this group. There's a broad variety of Abilities. max_length="250" label="Filter Abilities" name="filter_input" - font="SansSerif" - background_image="TextField_Search_Off" - text_pad_left="10" - text_color="black"> - <search_button label="" - top_pad="4" - left_pad="6" - /> - </search_editor> + font="SansSerif" /> <!--<line_editor border_style="line" border_thickness="1" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index e5a417e3d0..310e3908ca 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -1,14 +1,17 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - background_visible="true" +background_visible="true" +color="DkGray" follows="all" - height="400" + height="570" label="People" layout="topleft" min_height="350" - min_width="240" name="people_panel" - width="305"> + top="0" + left="0" + bevel_style="none" + width="333"> <string name="no_people" value="No people" /> @@ -31,103 +34,95 @@ name="groups_filter_label" value="Filter Groups" /> <filter_editor - background_image="TextField_Search_Off" follows="left|top|right" font="SansSerif" height="23" layout="topleft" left="15" - max_length="270" + max_length="300" name="filter_input" text_color="black" - text_pad_left="26" top="3" - width="256" /> - <button - follows="left|top|right" - height="13" - image_selected="Search" - image_unselected="Search" - layout="topleft" - left="20" - name="people_search" - picture_style="true" - scale_image="false" - top="8" - width="13" /> + width="300" /> <tab_container - follows="left|top|right|bottom" - height="326" + follows="all" + height="488" layout="topleft" - left="9" + left="10" name="tabs" + bevel_style="in" tab_position="top" top_pad="15" - width="285"> + width="313"> <panel - bevel_style="none" - follows="left|top|right|bottom" - height="390" + follows="all" + height="488" label="Nearby" layout="topleft" + left="0" name="nearby_panel" - width="285"> + top="0" + width="313"> <avatar_list - follows="left|top|right|bottom" - height="357" + follows="all" + height="430" layout="topleft" left="0" name="avatar_list" - top="2" + top="0" volume_column_width="20" - width="285" /> + width="313" /> <panel background_visible="true" bevel_style="none" - bottom="390" + top_pad="0" follows="left|right|bottom" height="30" label="bottom_panel" layout="topleft" left="0" name="bottom_panel" - width="285"> - <button - follows="bottom|left" - font="SansSerifBigBold" - height="18" - image_selected="OptionsMenu_Press" - image_unselected="OptionsMenu_Off" - layout="topleft" - left="20" - name="nearby_view_sort_btn" - picture_style="true" - tool_tip="Change sort and view of Residents list" - top="7" - width="18" /> + width="313"> + <button + follows="bottom|left" + font="SansSerifBigBold" + tool_tip="Change sort and view of Residents list" + height="18" + image_disabled="OptionsMenu_Disabled" + image_selected="OptionsMenu_Press" + image_unselected="OptionsMenu_Off" + layout="topleft" + left="10" + name="nearby_view_sort_btn" + picture_style="true" + top="5" + width="18" /> </panel> </panel> <panel background_visible="true" bevel_style="none" - follows="left|top|right|bottom" - height="390" + follows="all" + color="DkGray2" + height="460" + left="0" + top="0" label="Friends" layout="topleft" name="friends_panel" - width="285"> + width="313"> <accordion - follows="left|top|right|bottom" - height="357" + follows="all" + height="430" layout="topleft" left="0" name="friends_accordion" top="2" - width="285"> + width="313"> <accordion_tab can_resize="false" layout="topleft" - min_height="100" + min_height="150" name="tab_online" title="Online"> <avatar_list @@ -138,29 +133,29 @@ left="0" name="avatars_online" top="0" - width="285" /> + width="313" /> </accordion_tab> <accordion_tab can_resize="false" layout="topleft" - min_height="100" + height="230" name="tab_all" title="All"> <avatar_list draw_heading="false" follows="all" - height="255" + height="230" layout="topleft" left="0" name="avatars_all" top="0" - width="285" /> + width="313" /> </accordion_tab> </accordion> <panel background_visible="true" bevel_style="none" - bottom="390" + top_pad="0" follows="left|right|bottom" height="30" label="bottom_panel" @@ -168,25 +163,27 @@ left="0" name="bottom_panel" width="285"> - <button - follows="bottom|left" - font="SansSerifBigBold" - height="18" - image_selected="OptionsMenu_Press" - image_unselected="OptionsMenu_Off" - layout="topleft" - left="20" - name="friends_viewsort_btn" - picture_style="true" - tool_tip="Change sort and view of Friends list" - top="7" - width="18" /> + <button + follows="bottom|left" + font="SansSerifBigBold" + tool_tip="Change sort and view of Friends list" + height="18" + image_disabled="OptionsMenu_Disabled" + image_selected="OptionsMenu_Press" + image_unselected="OptionsMenu_Off" + layout="topleft" + left="10" + name="friends_viewsort_btn" + picture_style="true" + top="5" + width="18" /> <button follows="bottom|left" font="SansSerifBigBold" height="18" image_selected="AddItem_Press" image_unselected="AddItem_Off" + image_disabled="AddItem_Disabled" layout="topleft" left_pad="5" name="add_btn" @@ -200,6 +197,7 @@ height="18" image_selected="TrashItem_Press" image_unselected="TrashItem_Off" + image_disabled="TrashItem_Disabled" layout="topleft" left_pad="180" name="del_btn" @@ -215,13 +213,16 @@ follows="left|top|right|bottom" height="390" label="Groups" + top="0" layout="topleft" name="groups_panel" width="285"> <group_list + draw_heading="false" follows="left|top|right|bottom" height="357" layout="topleft" + color="DkGray2" left="0" name="group_list" top="2" @@ -229,7 +230,7 @@ <panel background_visible="true" bevel_style="none" - bottom="390" + top_pad="0" follows="left|right|bottom" height="30" label="bottom_panel" @@ -237,26 +238,28 @@ left="0" name="bottom_panel" width="285"> - <button - enabled="false" - follows="bottom|left" - font="SansSerifBigBold" - height="18" - image_selected="OptionsMenu_Press" - image_unselected="OptionsMenu_Off" - layout="topleft" - left="20" - name="gear_btn" - picture_style="true" - tool_tip="Change sort and view of Groups list" - top="7" - width="18" /> + <button + enabled="false" + follows="bottom|left" + font="SansSerifBigBold" + tool_tip="Change sort and view of Groups list" + height="18" + image_disabled="OptionsMenu_Disabled" + image_selected="OptionsMenu_Press" + image_unselected="OptionsMenu_Off" + layout="topleft" + left="10" + name="gear_btn" + picture_style="true" + top="5" + width="18" /> <button follows="bottom|left" font="SansSerifBigBold" height="18" image_selected="AddItem_Press" image_unselected="AddItem_Off" + image_disabled="AddItem_Disabled" layout="topleft" left_pad="5" name="plus_btn" @@ -296,13 +299,15 @@ <panel background_visible="true" bevel_style="none" + top="0" follows="left|top|right|bottom" height="390" label="Recent" layout="topleft" name="recent_panel" width="285"> - <avatar_list + <avatar_list_tmp + color="DkGray2" follows="left|top|right|bottom" height="357" layout="topleft" @@ -313,7 +318,7 @@ <panel background_visible="true" bevel_style="none" - bottom="390" + top_pad="0" follows="left|right|bottom" height="30" label="bottom_panel" @@ -321,19 +326,20 @@ left="0" name="bottom_panel" width="285"> - <button - follows="bottom|left" - font="SansSerifBigBold" - height="18" - image_selected="OptionsMenu_Press" - image_unselected="OptionsMenu_Off" - layout="topleft" - left="20" - name="recent_viewsort_btn" - picture_style="true" - tool_tip="Change sort and view of Residents list" - top="7" - width="18" /> + <button + follows="bottom|left" + font="SansSerifBigBold" + tool_tip="Change sort and view of Recent Residents list" + height="18" + image_disabled="OptionsMenu_Disabled" + image_selected="OptionsMenu_Press" + image_unselected="OptionsMenu_Off" + layout="topleft" + left="10" + name="recent_viewsort_btn" + picture_style="true" + top="5" + width="18" /> </panel> </panel> </tab_container> @@ -346,7 +352,7 @@ left="10" name="button_bar" orientation="horizontal" - width="295"> + width="313"> <layout_panel default_tab_group="1" follows="left|top|right" diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml index c330116702..9edd14ce49 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml @@ -2,111 +2,100 @@ <panel bevel_style="in" follows="left|top|right|bottom" - height="420" + height="570" layout="topleft" left="0" name="panel_pick_info" top="0" - width="255"> + width="333"> + <button + follows="top|left" + height="25" + width="25" + image_overlay="BackArrow_Off" + layout="topleft" + name="back_btn" + picture_style="true" + left="10" + top="7" /> <text - follows="top" + follows="top|left" font="SansSerifHugeBold" - height="15" + height="22" layout="topleft" - left="10" + left_pad="15" name="title" text_color="white" - top="5" value="Pick Info" - width="150" /> - <button - follows="top|right" - height="20" - image_overlay="BackArrow_Off" - layout="topleft" - name="back_btn" - picture_style="true" - right="-20" - top="7" - width="20" /> + width="270" /> <scroll_container color="DkGray2" - follows="left|top|right|bottom" - height="300" + opaque="true" + follows="left|top|bottom" + height="490" layout="topleft" - left="0" + left="10" + top_pad="10" name="profile_scroll" reserve_scroll_corner="true" - opaque="true" - width="255"> + width="313"> <panel name="scroll_content_panel" - follows="left|top|right" + follows="left|top|right|bottom" + min_height="300" layout="topleft" top="0" + background_visible="false" + height="488" left="0" - width="240" - height="575"> - <panel - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|right|top|bottom" - height="550" - layout="topleft" - left="0" - min_height="300" - top="0" - width="220"> + width="311"> <texture_picker enabled="false" - follows="left|top|right" - height="190" + follows="left|top" + height="197" layout="topleft" left="10" name="pick_snapshot" top="20" - width="220" /> + width="290" /> <text follows="left|top|right" height="20" + width="291" layout="topleft" - font="SansSerif" + font="SansSerifBig" font.style="BOLD" left="10" + top_pad="10" name="pick_name" text_color="white" value="[name]" word_wrap="true" /> <text follows="left|top" - height="30" + height="25" layout="topleft" left="10" name="pick_location" - text_color="white" - top_pad="10" - width="255" + width="291" word_wrap="true" value="[loading...]" /> <text follows="left|top|right" - height="150" + height="400" layout="topleft" left="10" - top_pad="20" name="pick_desc" - text_color="white" - width="225" + width="290" value="[description]" word_wrap="true" /> - </panel> </panel> </scroll_container> <panel follows="left|right|bottom" height="30" layout="topleft" - top_pad="2" + top_pad="5" left="10" name="buttons"> <button @@ -125,7 +114,7 @@ height="25" label="Teleport" layout="topleft" - left_pad="3" + left_pad="5" name="teleport_btn" top="0" width="80" /> @@ -135,7 +124,7 @@ height="25" label="Map" layout="topleft" - left_pad="3" + left_pad="5" name="show_on_map_btn" top="0" width="80" /> diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml index 4c8c4efbe7..37e873b6a8 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml @@ -7,27 +7,27 @@ left="0" name="picture_item" top="0" - width="275"> + width="305"> <icon - height="120" + height="120" image_name="ListItem_Over" - left="0" + left="0" mouse_opaque="false" - name="hovered_icon" + name="hovered_icon" top="0" - scale_image="true" + scale_image="true" visible="false" - width="270"/> + width="305"/> <icon - height="120" + height="120" image_name="ListItem_Select" - left="0" + left="0" mouse_opaque="false" name="selected_icon" top="0" scale_image="true" visible="false" - width="270"/> + width="305"/> <texture_picker allow_no_texture="true" default_image_name="None" @@ -40,6 +40,7 @@ name="picture" tab_stop="false" top="5" + top_pad="5" width="120" /> <text follows="top|left|right" @@ -50,7 +51,7 @@ text_color="white" top="5" use_ellipses="true" - width="120" + width="130" word_wrap="true" /> <text follows="top|left|right" @@ -70,8 +71,8 @@ layout="topleft" name="info_chevron" picture_style="true" - right="262" + right="290" tab_stop="false" - top="3" + top="5" width="16" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml index c56bb32feb..bceaedcdb4 100644 --- a/indra/newview/skins/default/xui/en/panel_picks.xml +++ b/indra/newview/skins/default/xui/en/panel_picks.xml @@ -1,40 +1,30 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel follows="left|top|right|bottom" - height="420" + height="515" label="Picks" layout="topleft" left="0" name="panel_picks" top="0" - width="285"> - <layout_stack - name="layout" - orientation="vertical" - follows="all" - layout="topleft" - left="0" - top="0" - height="420" - width="284" - border_size="0"> + width="313"> <scroll_container color="DkGray2" follows="left|top|right|bottom" - height="350" + height="495" layout="topleft" - left="2" + left="0" name="profile_scroll" opaque="true" top="0" - width="284"> + width="313"> <list - height="115" + height="120" layout="topleft" left="0" name="picks_list" top="0" - width="284" /> + width="305" /> </scroll_container> <panel background_visible="true" @@ -42,12 +32,13 @@ enabled="false" auto_resize="false" follows="bottom" - height="30" + left="0" + height="23" label="bottom_panel" layout="topleft" name="edit_panel" - top_pad="5" - width="284"> + top_pad="0" + width="313"> <button enabled="false" follows="bottom|left" @@ -55,6 +46,7 @@ height="18" image_selected="OptionsMenu_Press" image_unselected="OptionsMenu_Off" + image_disabled="OptionsMenu_Disabled" layout="topleft" left="10" name="gear_menu_btn" @@ -65,8 +57,7 @@ follows="bottom|left" font="SansSerifBigBold" height="18" - image_disabled="AddItem_Off" - image_disabled_selected="AddItem_Press" + image_disabled="AddItem_Disabled" image_selected="AddItem_Press" image_unselected="AddItem_Off" layout="topleft" @@ -80,8 +71,7 @@ follows="bottom|right" font="SansSerifBigBold" height="18" - image_disabled="TrashItem_Off" - image_disabled_selected="TrashItem_Press" + image_disabled="TrashItem_Disabled" image_selected="TrashItem_Press" image_unselected="TrashItem_Off" layout="topleft" @@ -93,11 +83,11 @@ </panel> <panel follows="bottom" - height="30" auto_resize="false" layout="topleft" + height="30" name="buttons_cucks" - width="284"> + width="313"> <button enabled="false" follows="bottom|left" @@ -108,5 +98,4 @@ name="show_on_map_btn" width="85" /> </panel> - </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index bff28718a7..b379ad2276 100644 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -16,7 +16,6 @@ name="teleport_history_tab_title" value="Teleport History" /> <filter_editor - background_image="TextField_Search_Off" follows="left|top|right" font="SansSerif" height="23" @@ -24,22 +23,8 @@ layout="topleft" left="15" name="Filter" - text_color="black" - text_pad_left="26" top="3" width="256" /> - <button - follows="left|top|right" - height="13" - image_selected="Search" - image_unselected="Search" - layout="topleft" - left="20" - name="landmark_search" - picture_style="true" - scale_image="false" - top="8" - width="13" /> <tab_container follows="all" height="326" diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml index 41de34fbed..2a800f809b 100644 --- a/indra/newview/skins/default/xui/en/panel_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_profile.xml @@ -1,14 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - bevel_style="out" - follows="left|top|right|bottom" - height="420" + follows="all" + height="515" label="Profile" layout="topleft" left="0" name="panel_profile" top="0" - width="255"> + width="313"> <string name="CaptionTextAcctInfo"> [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION] @@ -21,30 +20,27 @@ name="my_account_link_url" value="http://secondlife.com/account" /> <string - name="partner_edit_link_url"> - http://www.secondlife.com/account/partners.php?lang=en - </string> - <string name="no_partner_text" value="None" /> <scroll_container color="DkGray2" follows="left|top|right|bottom" - height="300" + height="515" + min_height="300" layout="topleft" - left="0" name="profile_scroll" reserve_scroll_corner="true" opaque="true" - width="255"> + top="0" + width="313"> <panel name="scroll_content_panel" follows="left|top|right" layout="topleft" top="0" left="0" - width="240" - height="780"> + width="284" + height="700"> <panel follows="left|top" height="117" @@ -52,7 +48,7 @@ left="10" name="second_life_image_panel" top="10" - width="260"> + width="280"> <texture_picker allow_no_texture="true" default_image_name="None" @@ -75,13 +71,13 @@ text_color="white" top_delta="0" value="[SECOND_LIFE]:" - width="130" /> + width="170" /> <text follows="left|top|right" - height="70" + height="90" layout="topleft" name="sl_description_edit" - width="130" + width="170" word_wrap="true"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. </text> @@ -93,7 +89,7 @@ top_pad="10" left="10" name="first_life_image_panel" - width="260"> + width="280"> <texture_picker allow_no_texture="true" default_image_name="None" @@ -115,13 +111,13 @@ text_color="white" top_delta="0" value="Real World:" - width="130" /> + width="175" /> <text follows="left|top|right" - height="70" + height="90" layout="topleft" name="fl_description_edit" - width="130" + width="180" word_wrap="true"> Lorem ipsum dolor sit amet, consectetur adlkjpiscing elit moose moose. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet. adipiscing elit. Aenean rigviverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet sorbet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. </text> @@ -137,18 +133,17 @@ name="me_homepage_text" text_color="white" top_pad="10" - width="255"> + width="280"> Homepage: </text> <text - follows="left|top|right" + follows="left|top" height="15" layout="topleft" left="10" name="homepage_edit" - top_pad="5" value="http://librarianavengers.org" - width="225" + width="280" word_wrap="false" /> <text follows="left|top" @@ -161,16 +156,16 @@ text_color="white" top_pad="20" value="Member Since:" - width="255" /> + width="280" /> <text - follows="left|top|right" + follows="left|top" height="15" layout="topleft" left="10" name="register_date" top_pad="5" value="05/31/1976" - width="160" + width="280" word_wrap="true" /> <text follows="left|top" @@ -183,7 +178,7 @@ text_color="white" top_pad="15" value="Account Status:" - width="100" /> + width="280" /> <!-- <text type="string" follows="left|top" @@ -196,14 +191,14 @@ value="Go to Dashboard" width="100"/> --> <text - follows="left|top|right" + follows="left|top" height="15" layout="topleft" left="10" name="acc_status_text" top_pad="5" value="Resident. No payment info on file." - width="255" + width="280" word_wrap="true" /> <text follows="left|top" @@ -216,33 +211,24 @@ text_color="white" top_pad="15" value="Partner:" - width="100" /> - <text - follows="left|top" - height="15" - layout="topleft" - left_pad="10" - name="partner_edit_link" - top_delta="0" - value="[[URL] Edit]" - width="100" /> + width="280" /> <panel - follows="left|top|right" + follows="left|top" height="15" layout="topleft" left="10" name="partner_data_panel" top_pad="5" - width="255"> + width="280"> <text - follows="left|top|right" + follows="left|top" height="15" layout="topleft" left="0" name="partner_text" top="0" value="[FIRST] [LAST]" - width="240" + width="280" word_wrap="true" /> </panel> <text @@ -256,28 +242,28 @@ text_color="white" top_pad="15" value="Groups:" - width="255" /> + width="280" /> <text - follows="left|top|right|bottom" + follows="left|top|bottom" height="160" layout="topleft" left="10" name="sl_groups" top_pad="5" - width="130" + width="280" word_wrap="true"> Lorem ipsum dolor sit amet, consectetur adlkjpiscing elit moose moose. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet. adipiscing elit. Aenean rigviverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet sorbet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. </text> </panel> </scroll_container> + <panel follows="bottom|left" - height="30" layout="topleft" - left="10" + left="0" name="profile_buttons_panel" - top_pad="5" - width="280"> + top_pad="0" + width="313"> <button follows="bottom|left" font="SansSerifSmallBold" @@ -322,13 +308,13 @@ width="75" /> </panel> <panel - height="30" + follows="bottom|left" layout="topleft" - left="10" + left="0" name="profile_me_buttons_panel" - top_pad="5" + top_pad="0" visible="false" - width="280"> + width="313"> <button follows="bottom|left" font="SansSerifSmallBold" diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml index e166675364..200c67b321 100644 --- a/indra/newview/skins/default/xui/en/panel_side_tray.xml +++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml @@ -3,14 +3,14 @@ name="sidebar" background_visible="false" mouse_opaque="true" - width="305" + width="333" collapsed="true" > <sidetray_tab name="sidebar_home" tab_title="Home" description="Home." - image="icn_voice-groupfocus.tga" + image="BackArrow_Off" mouse_opaque="false" background_opaque="false" background_visible="true" @@ -50,17 +50,17 @@ border="true" font="SansSerifBold" /> - <panel - class="panel_group_info_sidetray" - name="panel_group_info_sidetray" - filename="panel_group_info_sidetray.xml" - label="Group Info" + <panel + class="panel_group_info_sidetray" + name="panel_group_info_sidetray" + filename="panel_group_info_sidetray.xml" + label="Group Info" border="true" /> - <panel + <panel class="panel_block_list_sidetray" - name="panel_block_list_sidetray" - filename="panel_block_list_sidetray.xml" + name="panel_block_list_sidetray" + filename="panel_block_list_sidetray.xml" label="Blocked Residents & Objects" border="true" /> @@ -87,7 +87,7 @@ <sidetray_tab name="sidebar_me" - tab_title="My Profile" + tab_title="Me" description="Change your profile, your look and quick links to your outfits." image="TabIcon_Me_Off" mouse_opaque="false" @@ -97,7 +97,7 @@ class="panel_me_profile_view" name="panel_me_profile" filename="panel_me_profile.xml" - label="My Profile" + label="Me" border="true" font="SansSerifBold" /> @@ -108,16 +108,15 @@ tab_title="Appearance" description="Change your looks and appearance." image="TabIcon_Appearance_Off" - mouse_opaque="false" - background_opaque="false" - background_visible="true" - bg_opaque_color="0.5 0.5 0.5 1.0" + mouse_opaque="false" + background_opaque="false" + background_visible="true" > - <panel + <panel class="panel_appearance" - name="panel_appearance" - filename="panel_appearance.xml" - border="true" + name="panel_appearance" + filename="panel_appearance.xml" + border="true" /> </sidetray_tab> diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml index 82d6945e0f..70198dc626 100644 --- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml +++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml @@ -1,12 +1,162 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel name="Teleport History" bottom="0" height="326" left="0" width="380" - border="true" follows="left|top|right|bottom"> - <scroll_list bottom="0" column_padding="0" draw_heading="false" - draw_stripes="false" follows="left|top|bottom|right" left="0" - multi_select="false" name="history_items" search_column="1" - sort_column="1" height="326" width="380" > + border="true" follows="left|top|right|bottom"> + <accordion + follows="left|top|right|bottom" + height="326" + layout="topleft" + left="0" + top="0" + name="history_accordion" + width="380"> + + <accordion_tab + can_resize="false" + layout="topleft" + min_height="100" + name="today" + title="Today"> + <scroll_list + draw_heading="false" + follows="all" + height="150" + layout="topleft" + left="0" + name="today_items" + top="0" + width="285"> <column name="landmark_icon" width="20" /> <column dynamic_width="true" label="Region" name="region" /> <column name="index" width="0" /> - </scroll_list> + </scroll_list> + </accordion_tab> + + <accordion_tab + can_resize="false" + layout="topleft" + min_height="100" + name="yesterday" + title="Yesterday"> + <scroll_list + draw_heading="false" + follows="all" + height="150" + layout="topleft" + left="0" + name="yesterday_items" + top="0" + width="285"> + <column name="landmark_icon" width="20" /> + <column dynamic_width="true" label="Region" name="region" /> + <column name="index" width="0" /> + </scroll_list> + </accordion_tab> + + <accordion_tab + can_resize="false" + layout="topleft" + min_height="100" + name="3_days_ago" + title="3 days ago"> + <scroll_list + draw_heading="false" + follows="all" + height="150" + layout="topleft" + left="0" + name="3_days_ago" + top="0" + width="285"> + <column name="landmark_icon" width="20" /> + <column dynamic_width="true" label="Region" name="region" /> + <column name="index" width="0" /> + </scroll_list> + </accordion_tab> + + <accordion_tab + can_resize="false" + layout="topleft" + min_height="100" + name="4_days_ago" + title="4 days ago"> + <scroll_list + draw_heading="false" + follows="all" + height="150" + layout="topleft" + left="0" + name="4_days_ago" + top="0" + width="285"> + <column name="landmark_icon" width="20" /> + <column dynamic_width="true" label="Region" name="region" /> + <column name="index" width="0" /> + </scroll_list> + </accordion_tab> + + <accordion_tab + can_resize="false" + layout="topleft" + min_height="100" + name="5_days_ago" + title="5 days ago"> + <scroll_list + draw_heading="false" + follows="all" + height="150" + layout="topleft" + left="0" + name="5_days_ago_items" + top="0" + width="285"> + <column name="landmark_icon" width="20" /> + <column dynamic_width="true" label="Region" name="region" /> + <column name="index" width="0" /> + </scroll_list> + </accordion_tab> + + <accordion_tab + can_resize="false" + layout="topleft" + min_height="100" + name="6_days_ago" + title="6 days ago"> + <scroll_list + draw_heading="false" + follows="all" + height="150" + layout="topleft" + left="0" + name="6_days_ago" + top="0" + width="285"> + <column name="landmark_icon" width="20" /> + <column dynamic_width="true" label="Region" name="region" /> + <column name="index" width="0" /> + </scroll_list> + </accordion_tab> + + <accordion_tab + can_resize="false" + layout="topleft" + min_height="100" + name="older_than_6_days" + title="Older than 6 days"> + <scroll_list + draw_heading="false" + follows="all" + height="150" + layout="topleft" + left="0" + name="older_than_6_days_items" + top="0" + width="285"> + <column name="landmark_icon" width="20" /> + <column dynamic_width="true" label="Region" name="region" /> + <column name="index" width="0" /> + </scroll_list> + </accordion_tab> + + </accordion> + </panel> diff --git a/indra/newview/skins/default/xui/en/panel_toast.xml b/indra/newview/skins/default/xui/en/panel_toast.xml index 441caffa28..01fd84e09d 100644 --- a/indra/newview/skins/default/xui/en/panel_toast.xml +++ b/indra/newview/skins/default/xui/en/panel_toast.xml @@ -11,8 +11,6 @@ left="100" top="500" follows="right|bottom" - background_opaque="true" - background_visible="true" bevel_style="in" can_minimize="false" can_tear_off="false" @@ -20,7 +18,7 @@ can_drag_on_left="false" can_close="false" can_dock="false" - bg_alpha_color="0.3 0.3 0.3 1.0"> + > <text visible="false" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index faed615bdd..4206b87c2b 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -1818,6 +1818,7 @@ this texture in your inventory <string name="AnimFlagStart" value=" Start Animation : " /> <string name="Wave" value=" Wave " /> <string name="HelloAvatar" value=" Hello, avatar! " /> + <string name="ViewAllGestures" value=" View All >>" /> <!-- inventory filter --> <!-- use value="" because they have preceding spaces --> diff --git a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml index a34b005448..ada258fbec 100644 --- a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml +++ b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml @@ -1,8 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<filter_editor select_on_focus="true" - background_image_disabled="TextField_Search_Disabled" - background_image_focused="TextField_Search_Active"> - <clear_filter_button label="" - image_unselected="Icon_Close_Foreground" - image_selected="Icon_Close_Press" /> +<filter_editor + clear_button_visible="true" + search_button_visible="true" + text_pad_left="4" + select_on_focus="true" + background_image="TextField_Search_Off" + background_image_disabled="TextField_Search_Disabled" + background_image_focused="TextField_Search_Active" > + <search_button label="" + top_pad="4" + left_pad="4" + width="13" + height="13" + image_unselected="Search" + image_selected="Search" /> + <clear_button label="" + image_unselected="Icon_Close_Foreground" + image_selected="Icon_Close_Press" /> </filter_editor> diff --git a/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml b/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml new file mode 100644 index 0000000000..24d072a573 --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<flat_list_view + allow_select="true" + item_pad="5" + keep_one_selected="true" + multi_select="false" + opaque="true" />
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/widgets/search_editor.xml b/indra/newview/skins/default/xui/en/widgets/search_editor.xml index 15b23ea9b3..f482ff3b89 100644 --- a/indra/newview/skins/default/xui/en/widgets/search_editor.xml +++ b/indra/newview/skins/default/xui/en/widgets/search_editor.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <search_editor + clear_button_visible="false" + search_button_visible="true" text_pad_left="4" select_on_focus="true" background_image="TextField_Search_Off" @@ -12,4 +14,7 @@ height="13" image_unselected="Search" image_selected="Search" /> + <clear_button label="" + image_unselected="Icon_Close_Foreground" + image_selected="Icon_Close_Press" /> </search_editor> |