diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 6633c653179f3315658c807881ba08477f36bb83..20ff7bab34dc9c3451c57f37633547d38854fabe 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -180,9 +180,11 @@ void LLCharacter::requestStopMotion( LLMotion* motion) //----------------------------------------------------------------------------- // updateMotions() //----------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_UPDATE_ANIMATION("Update Animation"); + void LLCharacter::updateMotions(e_update_t update_type) { - LLFastTimer t(LLFastTimer::FTM_UPDATE_ANIMATION); + LLFastTimer t(FTM_UPDATE_ANIMATION); if (update_type == HIDDEN_UPDATE) { mMotionController.updateMotionsMinimal(); diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 612068b20213f551b294fffc6befa3f442b2a1fd..0d89353deea6faf448d38e23046500f39c04ae73 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -69,13 +69,13 @@ class LLFastTimer std::vector<NamedTimer*>& getChildren(); void setCollapsed(bool collapsed) { mCollapsed = collapsed; } - bool getCollapsed() { return mCollapsed; } + bool getCollapsed() const { return mCollapsed; } - U64 getCountAverage() { return mCountAverage; } - U64 getCallAverage() { return mCallAverage; } + U64 getCountAverage() const { return mCountAverage; } + U64 getCallAverage() const { return mCallAverage; } - U64 getHistoricalCount(S32 history_index = 0); - U64 getHistoricalCalls(S32 history_index = 0); + U64 getHistoricalCount(S32 history_index = 0) const; + U64 getHistoricalCalls(S32 history_index = 0) const; static NamedTimer& getRootNamedTimer(); @@ -162,117 +162,6 @@ class LLFastTimer NamedTimer& mNamedTimer; }; - static DeclareTimer FTM_ARRANGE; - static DeclareTimer FTM_ATTACHMENT_UPDATE; - static DeclareTimer FTM_AUDIO_UPDATE; - static DeclareTimer FTM_AUTO_SELECT; - static DeclareTimer FTM_AVATAR_UPDATE; - static DeclareTimer FTM_CLEANUP; - static DeclareTimer FTM_CLIENT_COPY; - static DeclareTimer FTM_CREATE_OBJECT; - static DeclareTimer FTM_CULL; - static DeclareTimer FTM_CULL_REBOUND; - static DeclareTimer FTM_FILTER; - static DeclareTimer FTM_FLEXIBLE_UPDATE; - static DeclareTimer FTM_FRAME; - static DeclareTimer FTM_FRUSTUM_CULL; - static DeclareTimer FTM_GEN_FLEX; - static DeclareTimer FTM_GEN_TRIANGLES; - static DeclareTimer FTM_GEN_VOLUME; - static DeclareTimer FTM_GEO_SKY; - static DeclareTimer FTM_GEO_UPDATE; - static DeclareTimer FTM_HUD_EFFECTS; - static DeclareTimer FTM_HUD_UPDATE; - static DeclareTimer FTM_IDLE; - static DeclareTimer FTM_IDLE_CB; - static DeclareTimer FTM_IDLE_NETWORK; - static DeclareTimer FTM_IMAGE_CREATE; - static DeclareTimer FTM_IMAGE_MARK_DIRTY; - static DeclareTimer FTM_IMAGE_UPDATE; - static DeclareTimer FTM_INVENTORY; - static DeclareTimer FTM_JOINT_UPDATE; - static DeclareTimer FTM_KEYHANDLER; - static DeclareTimer FTM_LOAD_AVATAR; - static DeclareTimer FTM_LOD_UPDATE; - static DeclareTimer FTM_MESSAGES; - static DeclareTimer FTM_MOUSEHANDLER; - static DeclareTimer FTM_NETWORK; - static DeclareTimer FTM_OBJECTLIST_UPDATE; - static DeclareTimer FTM_OCCLUSION_READBACK; - static DeclareTimer FTM_OCTREE_BALANCE; - static DeclareTimer FTM_PICK; - static DeclareTimer FTM_PIPELINE; - static DeclareTimer FTM_POOLRENDER; - static DeclareTimer FTM_POOLS; - static DeclareTimer FTM_PROCESS_IMAGES; - static DeclareTimer FTM_PROCESS_MESSAGES; - static DeclareTimer FTM_PROCESS_OBJECTS; - static DeclareTimer FTM_PUMP; - static DeclareTimer FTM_REBUILD_GRASS_VB; - static DeclareTimer FTM_REBUILD_PARTICLE_VB; - static DeclareTimer FTM_REBUILD_TERRAIN_VB; - static DeclareTimer FTM_REBUILD_VBO; - static DeclareTimer FTM_REBUILD_VOLUME_VB; - static DeclareTimer FTM_REFRESH; - static DeclareTimer FTM_REGION_UPDATE; - static DeclareTimer FTM_RENDER; - static DeclareTimer FTM_RENDER_ALPHA; - static DeclareTimer FTM_RENDER_BLOOM; - static DeclareTimer FTM_RENDER_BLOOM_FBO; - static DeclareTimer FTM_RENDER_BUMP; - static DeclareTimer FTM_RENDER_CHARACTERS; - static DeclareTimer FTM_RENDER_FAKE_VBO_UPDATE; - static DeclareTimer FTM_RENDER_FONTS; - static DeclareTimer FTM_RENDER_FULLBRIGHT; - static DeclareTimer FTM_RENDER_GEOMETRY; - static DeclareTimer FTM_RENDER_GLOW; - static DeclareTimer FTM_RENDER_GRASS; - static DeclareTimer FTM_RENDER_INVISIBLE; - static DeclareTimer FTM_RENDER_OCCLUSION; - static DeclareTimer FTM_RENDER_SHINY; - static DeclareTimer FTM_RENDER_SIMPLE; - static DeclareTimer FTM_RENDER_TERRAIN; - static DeclareTimer FTM_RENDER_TREES; - static DeclareTimer FTM_RENDER_UI; - static DeclareTimer FTM_RENDER_WATER; - static DeclareTimer FTM_RENDER_WL_SKY; - static DeclareTimer FTM_RESET_DRAWORDER; - static DeclareTimer FTM_SHADOW_ALPHA; - static DeclareTimer FTM_SHADOW_AVATAR; - static DeclareTimer FTM_SHADOW_RENDER; - static DeclareTimer FTM_SHADOW_SIMPLE; - static DeclareTimer FTM_SHADOW_TERRAIN; - static DeclareTimer FTM_SHADOW_TREE; - static DeclareTimer FTM_SIMULATE_PARTICLES; - static DeclareTimer FTM_SLEEP; - static DeclareTimer FTM_SORT; - static DeclareTimer FTM_STATESORT; - static DeclareTimer FTM_STATESORT_DRAWABLE; - static DeclareTimer FTM_STATESORT_POSTSORT; - static DeclareTimer FTM_SWAP; - static DeclareTimer FTM_TEMP1; - static DeclareTimer FTM_TEMP2; - static DeclareTimer FTM_TEMP3; - static DeclareTimer FTM_TEMP4; - static DeclareTimer FTM_TEMP5; - static DeclareTimer FTM_TEMP6; - static DeclareTimer FTM_TEMP7; - static DeclareTimer FTM_TEMP8; - static DeclareTimer FTM_UPDATE_ANIMATION; - static DeclareTimer FTM_UPDATE_AVATAR; - static DeclareTimer FTM_UPDATE_CLOUDS; - static DeclareTimer FTM_UPDATE_GRASS; - static DeclareTimer FTM_UPDATE_MOVE; - static DeclareTimer FTM_UPDATE_PARTICLES; - static DeclareTimer FTM_UPDATE_PRIMITIVES; - static DeclareTimer FTM_UPDATE_SKY; - static DeclareTimer FTM_UPDATE_TERRAIN; - static DeclareTimer FTM_UPDATE_TEXTURES; - static DeclareTimer FTM_UPDATE_TREE; - static DeclareTimer FTM_UPDATE_WATER; - static DeclareTimer FTM_UPDATE_WLPARAM; - static DeclareTimer FTM_VFILE_WAIT; - static DeclareTimer FTM_WORLD_UPDATE; public: enum RootTimerMarker { ROOT }; @@ -287,6 +176,7 @@ class LLFastTimer LLFastTimer(NamedTimer::FrameState& timer) : mFrameState(&timer) { +#if FAST_TIMER_ON NamedTimer::FrameState* frame_state = mFrameState; frame_state->mLastStartTime = get_cpu_clock_count(); mStartSelfTime = frame_state->mLastStartTime; @@ -298,6 +188,7 @@ class LLFastTimer mLastTimer = sCurTimer; sCurTimer = this; +#endif } ~LLFastTimer() @@ -332,6 +223,7 @@ class LLFastTimer static S32 getCurFrameIndex() { return sCurFrameIndex; } static void writeLog(std::ostream& os); + static const NamedTimer* getTimerByName(const std::string& name); public: static bool sPauseHistory; diff --git a/indra/llcommon/llmetrics.cpp b/indra/llcommon/llmetrics.cpp index 8db3284c420c466daddde0b230e1b00ff44fb7ac..30e5d435ae78f8e39c1711fa56c64c6617da9775 100644 --- a/indra/llcommon/llmetrics.cpp +++ b/indra/llcommon/llmetrics.cpp @@ -71,7 +71,7 @@ void LLMetricsImpl::recordEventDetails(const std::string& location, metrics["location"] = location; metrics["stats"] = stats; - llinfos << "LLMETRICS: " << LLSDNotationStreamer(metrics) << llendl; + llinfos << "LLMETRICS: " << (LLSDNotationStreamer(metrics)) << llendl; } // Store this: diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h index 540a18b8a0b0d28731d125ca37231cbc6f66172b..d3597b454c87885f8fa449bd2c6651ba75feaab7 100644 --- a/indra/llcommon/llrefcount.h +++ b/indra/llcommon/llrefcount.h @@ -32,6 +32,8 @@ #ifndef LLREFCOUNT_H #define LLREFCOUNT_H +#include <boost/noncopyable.hpp> + //---------------------------------------------------------------------------- // RefCount objects should generally only be accessed by way of LLPointer<>'s // see llthread.h for LLThreadSafeRefCount @@ -40,10 +42,9 @@ class LLRefCount { protected: - LLRefCount(const LLRefCount&); // not implemented + LLRefCount(const LLRefCount& other); // no implementation private: - LLRefCount&operator=(const LLRefCount&); // not implemented - + LLRefCount& operator=(const LLRefCount&); // no implementation protected: virtual ~LLRefCount(); // use unref() diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index ba0f798dbbed9224ee69337dd5a37d1f06e8edda..9140ebb3f334957d7792ff91f91cb9bad0d293b1 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -819,9 +819,15 @@ static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat) { std::ostringstream out; if (useXMLFormat) - out << LLSDXMLStreamer(llsd); + { + LLSDXMLStreamer xml_streamer(llsd); + out << xml_streamer; + } else - out << LLSDNotationStreamer(llsd); + { + LLSDNotationStreamer notation_streamer(llsd); + out << notation_streamer; + } out_string = out.str(); } int len = out_string.length(); diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index ec1718a8cbfde3bbf949c68e7eb1d227f7ab9380..d7da40d64597e9e9eb26cd089a15edd5749c24db 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -42,6 +42,9 @@ #include <winnls.h> // for WideCharToMultiByte #endif +LLFastTimer::DeclareTimer STRING_LOCALIZATION("String Localization"); + + std::string ll_safe_string(const char* in) { if(in) return std::string(in); diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index f6bb0e0fe29a8394014846f11e115a092e1481f5..a15d6a9a14d0e29a13986e95641196f7ff0758dc 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -38,6 +38,7 @@ #include <iomanip> #include <boost/regex.hpp> #include "llsd.h" +#include "llfasttimer.h" #if LL_LINUX || LL_SOLARIS #include <wctype.h> @@ -337,6 +338,9 @@ class LLStringUtilBase // Copies src into dst at a given offset. static void copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset); + static bool isPartOfWord(T c) { return (c == (T)'_') || LLStringOps::isAlnum(c); } + + #ifdef _DEBUG static void testHarness(); #endif @@ -617,10 +621,13 @@ void LLStringUtilBase<T>::getTokens (std::basic_string<T> input, std::vector<std } } +extern LLFastTimer::DeclareTimer STRING_LOCALIZATION; + // static template<class T> S32 LLStringUtilBase<T>::format(std::basic_string<T>& s, const format_map_t& substitutions) { + LLFastTimer ft(STRING_LOCALIZATION); S32 res = 0; std::basic_ostringstream<T> output; @@ -695,6 +702,8 @@ S32 LLStringUtilBase<T>::format(std::basic_string<T>& s, const format_map_t& sub template<class T> S32 LLStringUtilBase<T>::format(std::basic_string<T>& s, const LLSD& substitutions) { + LLFastTimer ft(STRING_LOCALIZATION); + S32 res = 0; if (!substitutions.isMap()) diff --git a/indra/llmath/llrect.h b/indra/llmath/llrect.h index 894f0a7ed0d182abce98ee047bd0ee234681c13d..c03a331aff0a7878f2f273006f328d9a8ad843e5 100644 --- a/indra/llmath/llrect.h +++ b/indra/llmath/llrect.h @@ -141,10 +141,20 @@ template <class Type> class LLRectBase // Note: Does NOT follow GL_QUAD conventions: the top and right edges ARE considered part of the rect // returns TRUE if any part of rect is is inside this LLRect - BOOL rectInRect(const LLRectBase* rect) const + BOOL overlaps(const LLRectBase& rect) const { - return mLeft <= rect->mRight && rect->mLeft <= mRight && - mBottom <= rect->mTop && rect->mBottom <= mTop ; + return !(mLeft > rect.mRight + || mRight < rect.mLeft + || mBottom > rect.mTop + || mTop < rect.mBottom); + } + + BOOL contains(const LLRectBase& rect) const + { + return mLeft <= rect.mLeft + && mRight >= rect.mRight + && mBottom <= rect.mBottom + && mTop >= rect.mTop; } LLRectBase& set(Type left, Type top, Type right, Type bottom) @@ -223,26 +233,25 @@ template <class Type> class LLRectBase return mLeft <= mRight && mBottom <= mTop; } - bool isNull() const + bool isEmpty() const { return mLeft == mRight || mBottom == mTop; } - bool notNull() const + bool notEmpty() const { - return !isNull(); + return !isEmpty(); } - LLRectBase& unionWith(const LLRectBase &other) + void unionWith(const LLRectBase &other) { mLeft = llmin(mLeft, other.mLeft); mRight = llmax(mRight, other.mRight); mBottom = llmin(mBottom, other.mBottom); mTop = llmax(mTop, other.mTop); - return *this; } - LLRectBase& intersectWith(const LLRectBase &other) + void intersectWith(const LLRectBase &other) { mLeft = llmax(mLeft, other.mLeft); mRight = llmin(mRight, other.mRight); @@ -256,7 +265,6 @@ template <class Type> class LLRectBase { mBottom = mTop; } - return *this; } friend std::ostream &operator<<(std::ostream &s, const LLRectBase &rect) diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index 3e3f0b37a7d7bd1eec43cff04c1e9d611eca83eb..5e9dfd81faa48e30175eeace6ed6e66af36d7ca1 100644 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -444,11 +444,13 @@ void LLPumpIO::pump() pump(DEFAULT_POLL_TIMEOUT); } +static LLFastTimer::DeclareTimer FTM_PUMP("Pump"); + //timeout is in microseconds void LLPumpIO::pump(const S32& poll_timeout) { LLMemType m1(LLMemType::MTYPE_IO_PUMP); - LLFastTimer t1(LLFastTimer::FTM_PUMP); + LLFastTimer t1(FTM_PUMP); //llinfos << "LLPumpIO::pump()" << llendl; // Run any pending runners. diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp index 80ea6ce96b091ba4005434ec3c83b45d18a856f4..8c9eb7ed4229ab872e822876d9abe7f88ac1da3c 100644 --- a/indra/llmessage/lltemplatemessagereader.cpp +++ b/indra/llmessage/lltemplatemessagereader.cpp @@ -531,6 +531,8 @@ void LLTemplateMessageReader::logRanOffEndOfPacket( const LLHost& host, const S3 gMessageSystem->callExceptionFunc(MX_RAN_OFF_END_OF_PACKET); } +static LLFastTimer::DeclareTimer FTM_PROCESS_MESSAGES("Process Messages"); + // decode a given message BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender ) { @@ -714,7 +716,7 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender } { - LLFastTimer t(LLFastTimer::FTM_PROCESS_MESSAGES); + LLFastTimer t(FTM_PROCESS_MESSAGES); if( !mCurrentRMessageTemplate->callHandlerFunc(gMessageSystem) ) { llwarns << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << llendl; diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 62534969b7b07332308fc15197ba368be4981d22..0be6bedbeece4c9d14484bc734db8c5e61f06c56 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -33,6 +33,7 @@ #include "linden_common.h" #include "llfontfreetype.h" +#include "llfontgl.h" // Freetype stuff #include <ft2build.h> @@ -204,6 +205,19 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v mName = filename; mPointSize = point_size; + mStyle = LLFontGL::NORMAL; + if(mFTFace->style_flags & FT_STYLE_FLAG_BOLD) + { + mStyle |= LLFontGL::BOLD; + mStyle &= ~LLFontGL::NORMAL; + } + + if(mFTFace->style_flags & FT_STYLE_FLAG_ITALIC) + { + mStyle |= LLFontGL::ITALIC; + mStyle &= ~LLFontGL::NORMAL; + } + return TRUE; } diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 177e13e27c87b639d5dbc155ba3d500ab46d7c86..d76b23248d6f66ef6069988473ac074beb1ce725 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -89,12 +89,10 @@ static F32 llfont_round_y(F32 y) LLFontGL::LLFontGL() { - clearEmbeddedChars(); } LLFontGL::~LLFontGL() { - clearEmbeddedChars(); } void LLFontGL::reset() @@ -117,8 +115,10 @@ BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dp return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback); } +static LLFastTimer::DeclareTimer FTM_RENDER_FONTS("Fonts"); + S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, - ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_embedded, BOOL use_ellipses) const + ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const { if(!sDisplayFont) //do not display texts { @@ -159,7 +159,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons F32 pixel_offset_y = llround((F32)sCurOrigin.mY) - (sCurOrigin.mY); gGL.translatef(-pixel_offset_x, -pixel_offset_y, 0.f); - LLFastTimer t(LLFastTimer::FTM_RENDER_FONTS); + LLFastTimer t(FTM_RENDER_FONTS); gGL.color4fv( color.mV ); @@ -251,135 +251,69 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons { llwchar wch = wstr[i]; - // Handle embedded characters first, if they're enabled. - // Embedded characters are a hack for notecards - const embedded_data_t* ext_data = use_embedded ? getEmbeddedCharData(wch) : NULL; - if (ext_data) + if (!mFontFreetype->hasGlyph(wch)) { - LLImageGL* ext_image = ext_data->mImage; - const LLWString& label = ext_data->mLabel; - - F32 ext_height = (F32)ext_image->getHeight() * sScaleY; - - F32 ext_width = (F32)ext_image->getWidth() * sScaleX; - F32 ext_advance = (EXT_X_BEARING * sScaleX) + ext_width; - - if (!label.empty()) - { - ext_advance += (EXT_X_BEARING + getFontExtChar()->getWidthF32( label.c_str() )) * sScaleX; - } - - if (start_x + scaled_max_pixels < cur_x + ext_advance) - { - // Not enough room for this character. - break; - } - - if (last_bound_texture != ext_image) - { - gGL.getTexUnit(0)->bind(ext_image); - last_bound_texture = ext_image; - } - - // snap origin to whole screen pixel - const F32 ext_x = (F32)llround(cur_render_x + (EXT_X_BEARING * sScaleX)); - const F32 ext_y = (F32)llround(cur_render_y + (EXT_Y_BEARING * sScaleY + mFontFreetype->getAscenderHeight() - mFontFreetype->getLineHeight())); - - LLRectf uv_rect(0.f, 1.f, 1.f, 0.f); - LLRectf screen_rect(ext_x, ext_y + ext_height, ext_x + ext_width, ext_y); - drawGlyph(screen_rect, uv_rect, LLColor4::white, style_to_add, shadow, drop_shadow_strength); - - if (!label.empty()) - { - gGL.pushMatrix(); - //glLoadIdentity(); - //gGL.translatef(sCurOrigin.mX, sCurOrigin.mY, 0.0f); - //glScalef(sScaleX, sScaleY, 1.f); - getFontExtChar()->render(label, 0, - /*llfloor*/((ext_x + (F32)ext_image->getWidth() + EXT_X_BEARING) / sScaleX), - /*llfloor*/(cur_y / sScaleY), - color, - halign, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, - TRUE ); - gGL.popMatrix(); - } - - gGL.color4fv(color.mV); + addChar(wch); + } - chars_drawn++; - cur_x += ext_advance; - if (((i + 1) < length) && wstr[i+1]) - { - cur_x += EXT_KERNING * sScaleX; - } - cur_render_x = cur_x; + const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch); + if (!fgi) + { + llerrs << "Missing Glyph Info" << llendl; + break; } - else + // Per-glyph bitmap texture. + LLImageGL *image_gl = mFontFreetype->getFontBitmapCache()->getImageGL(fgi->mBitmapNum); + if (last_bound_texture != image_gl) { - if (!mFontFreetype->hasGlyph(wch)) - { - addChar(wch); - } - - const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch); - if (!fgi) - { - llerrs << "Missing Glyph Info" << llendl; - break; - } - // Per-glyph bitmap texture. - LLImageGL *image_gl = mFontFreetype->getFontBitmapCache()->getImageGL(fgi->mBitmapNum); - if (last_bound_texture != image_gl) - { - gGL.getTexUnit(0)->bind(image_gl); - last_bound_texture = image_gl; - } + gGL.getTexUnit(0)->bind(image_gl); + last_bound_texture = image_gl; + } - if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth)) - { - // Not enough room for this character. - break; - } + if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth)) + { + // Not enough room for this character. + break; + } - // Draw the text at the appropriate location - //Specify vertices and texture coordinates - LLRectf uv_rect((fgi->mXBitmapOffset) * inv_width, - (fgi->mYBitmapOffset + fgi->mHeight + PAD_UVY) * inv_height, - (fgi->mXBitmapOffset + fgi->mWidth) * inv_width, - (fgi->mYBitmapOffset - PAD_UVY) * inv_height); - // snap glyph origin to whole screen pixel - LLRectf screen_rect(llround(cur_render_x + (F32)fgi->mXBearing), - llround(cur_render_y + (F32)fgi->mYBearing), - llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth, - llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight); - - drawGlyph(screen_rect, uv_rect, color, style_to_add, shadow, drop_shadow_strength); + // Draw the text at the appropriate location + //Specify vertices and texture coordinates + LLRectf uv_rect((fgi->mXBitmapOffset) * inv_width, + (fgi->mYBitmapOffset + fgi->mHeight + PAD_UVY) * inv_height, + (fgi->mXBitmapOffset + fgi->mWidth) * inv_width, + (fgi->mYBitmapOffset - PAD_UVY) * inv_height); + // snap glyph origin to whole screen pixel + LLRectf screen_rect(llround(cur_render_x + (F32)fgi->mXBearing), + llround(cur_render_y + (F32)fgi->mYBearing), + llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth, + llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight); + + drawGlyph(screen_rect, uv_rect, color, style_to_add, shadow, drop_shadow_strength); - chars_drawn++; - cur_x += fgi->mXAdvance; - cur_y += fgi->mYAdvance; + chars_drawn++; + cur_x += fgi->mXAdvance; + cur_y += fgi->mYAdvance; - llwchar next_char = wstr[i+1]; - if (next_char && (next_char < LAST_CHARACTER)) + llwchar next_char = wstr[i+1]; + if (next_char && (next_char < LAST_CHARACTER)) + { + // Kern this puppy. + if (!mFontFreetype->hasGlyph(next_char)) { - // Kern this puppy. - if (!mFontFreetype->hasGlyph(next_char)) - { - addChar(next_char); - } - cur_x += mFontFreetype->getXKerning(wch, next_char); + addChar(next_char); } + cur_x += mFontFreetype->getXKerning(wch, next_char); + } - // Round after kerning. - // Must do this to cur_x, not just to cur_render_x, otherwise you - // will squish sub-pixel kerned characters too close together. - // For example, "CCCCC" looks bad. - cur_x = (F32)llfloor(cur_x + 0.5f); - //cur_y = (F32)llfloor(cur_y + 0.5f); + // Round after kerning. + // Must do this to cur_x, not just to cur_render_x, otherwise you + // will squish sub-pixel kerned characters too close together. + // For example, "CCCCC" looks bad. + cur_x = (F32)llfloor(cur_x + 0.5f); + //cur_y = (F32)llfloor(cur_y + 0.5f); - cur_render_x = cur_x; - cur_render_y = cur_y; - } + cur_render_x = cur_x; + cur_render_y = cur_y; } if (right_x) @@ -427,12 +361,12 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons S32 LLFontGL::render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const { - return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE, FALSE); + return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE); } S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const { - return render(utf8str_to_wstring(text), begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, FALSE, use_ellipses); + return render(utf8str_to_wstring(text), begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, use_ellipses); } S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const @@ -478,9 +412,9 @@ S32 LLFontGL::getWidth(const std::string& utf8text, S32 begin_offset, S32 max_ch return getWidth(wtext.c_str(), begin_offset, max_chars); } -S32 LLFontGL::getWidth(const llwchar* wchars, S32 begin_offset, S32 max_chars, BOOL use_embedded) const +S32 LLFontGL::getWidth(const llwchar* wchars, S32 begin_offset, S32 max_chars) const { - F32 width = getWidthF32(wchars, begin_offset, max_chars, use_embedded); + F32 width = getWidthF32(wchars, begin_offset, max_chars); return llround(width); } @@ -501,7 +435,7 @@ F32 LLFontGL::getWidthF32(const std::string& utf8text, S32 begin_offset, S32 max return getWidthF32(wtext.c_str(), begin_offset, max_chars); } -F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars, BOOL use_embedded) const +F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars) const { const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL; @@ -509,34 +443,21 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars const S32 max_index = begin_offset + max_chars; for (S32 i = begin_offset; i < max_index; i++) { - const llwchar wch = wchars[i]; + llwchar wch = wchars[i]; if (wch == 0) { break; // done } - const embedded_data_t* ext_data = use_embedded ? getEmbeddedCharData(wch) : NULL; - if (ext_data) - { - // Handle crappy embedded hack - cur_x += getEmbeddedCharAdvance(ext_data); - if( ((i+1) < max_chars) && (i+1 < max_index)) - { - cur_x += EXT_KERNING * sScaleX; - } - } - else - { - cur_x += mFontFreetype->getXAdvance(wch); - llwchar next_char = wchars[i+1]; + cur_x += mFontFreetype->getXAdvance(wch); + llwchar next_char = wchars[i+1]; - if (((i + 1) < max_chars) - && next_char - && (next_char < LAST_CHARACTER)) - { - // Kern this puppy. - cur_x += mFontFreetype->getXKerning(wch, next_char); - } + if (((i + 1) < begin_offset + max_chars) + && next_char + && (next_char < LAST_CHARACTER)) + { + // Kern this puppy. + cur_x += mFontFreetype->getXKerning(wch, next_char); } // Round after kerning. cur_x = (F32)llfloor(cur_x + 0.5f); @@ -546,7 +467,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars } // Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels -S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, BOOL end_on_word_boundary, BOOL use_embedded, F32* drawn_pixels) const +S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, BOOL end_on_word_boundary) const { if (!wchars || !wchars[0] || max_chars == 0) { @@ -576,83 +497,51 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch break; } - const embedded_data_t* ext_data = use_embedded ? getEmbeddedCharData(wch) : NULL; - if (ext_data) + if (in_word) { - if (in_word) - { - in_word = FALSE; - } - else - { - start_of_last_word = i; - } - cur_x += getEmbeddedCharAdvance(ext_data); - - if (scaled_max_pixels < cur_x) - { - clip = TRUE; - break; - } - - if (((i+1) < max_chars) && wchars[i+1]) + if (iswspace(wch)) { - cur_x += EXT_KERNING * sScaleX; - } - - if( scaled_max_pixels < cur_x ) - { - clip = TRUE; - break; + if(wch !=(0x00A0)) + { + in_word = FALSE; + } } - } - else - { - if (in_word) + if (iswindividual(wch)) { - if (iswspace(wch)) + if (iswpunct(wchars[i+1])) { - if(wch !=(0x00A0)) - { - in_word = FALSE; - } + in_word=TRUE; } - if (iswindividual(wch)) + else { - if (iswpunct(wchars[i+1])) - { - in_word=TRUE; - } - else - { - in_word=FALSE; - start_of_last_word = i; - } + in_word=FALSE; + start_of_last_word = i; } } - else + } + else + { + start_of_last_word = i; + if (!iswspace(wch)||!iswindividual(wch)) { - start_of_last_word = i; - if (!iswspace(wch)||!iswindividual(wch)) - { - in_word = TRUE; - } + in_word = TRUE; } + } - cur_x += mFontFreetype->getXAdvance(wch); - - if (scaled_max_pixels < cur_x) - { - clip = TRUE; - break; - } + cur_x += mFontFreetype->getXAdvance(wch); + + if (scaled_max_pixels < cur_x) + { + clip = TRUE; + break; + } - if (((i+1) < max_chars) && wchars[i+1]) - { - // Kern this puppy. - cur_x += mFontFreetype->getXKerning(wch, wchars[i+1]); - } + if (((i+1) < max_chars) && wchars[i+1]) + { + // Kern this puppy. + cur_x += mFontFreetype->getXKerning(wch, wchars[i+1]); } + // Round after kerning. cur_x = (F32)llfloor(cur_x + 0.5f); drawn_x = cur_x; @@ -662,10 +551,6 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch { i = start_of_last_word; } - if (drawn_pixels) - { - *drawn_pixels = drawn_x; - } return i; } @@ -686,8 +571,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_ { llwchar wch = wchars[i]; - const embedded_data_t* ext_data = getEmbeddedCharData(wch); - F32 char_width = ext_data ? getEmbeddedCharAdvance(ext_data) : mFontFreetype->getXAdvance(wch); + F32 char_width = mFontFreetype->getXAdvance(wch); if( scaled_max_pixels < (total_width + char_width) ) { @@ -705,7 +589,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_ if ( i > 0 ) { // kerning - total_width += ext_data ? (EXT_KERNING * sScaleX) : mFontFreetype->getXKerning(wchars[i-1], wch); + total_width += mFontFreetype->getXKerning(wchars[i-1], wch); } // Round after kerning. @@ -715,7 +599,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_ return start_pos - drawable_chars; } -S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round, BOOL use_embedded) const +S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round) const { if (!wchars || !wchars[0] || max_chars == 0) { @@ -723,7 +607,6 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t } F32 cur_x = 0; - S32 pos = 0; target_x *= sScaleX; @@ -732,113 +615,50 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t F32 scaled_max_pixels = max_pixels * sScaleX; - for (S32 i = begin_offset; (i < max_index); i++) + S32 pos; + for (pos = begin_offset; pos < max_index; pos++) { - llwchar wch = wchars[i]; + llwchar wch = wchars[pos]; if (!wch) { break; // done } - const embedded_data_t* ext_data = use_embedded ? getEmbeddedCharData(wch) : NULL; - if (ext_data) - { - F32 ext_advance = getEmbeddedCharAdvance(ext_data); - - if (round) - { - // Note: if the mouse is on the left half of the character, the pick is to the character's left - // If it's on the right half, the pick is to the right. - if (target_x < cur_x + ext_advance/2) - { - break; - } - } - else - { - if (target_x < cur_x + ext_advance) - { - break; - } - } + F32 char_width = mFontFreetype->getXAdvance(wch); - if (scaled_max_pixels < cur_x + ext_advance) + if (round) + { + // Note: if the mouse is on the left half of the character, the pick is to the character's left + // If it's on the right half, the pick is to the right. + if (target_x < cur_x + char_width*0.5f) { break; } - - pos++; - cur_x += ext_advance; - - if (((i + 1) < max_index) - && (wchars[(i + 1)])) - { - cur_x += EXT_KERNING * sScaleX; - } - // Round after kerning. - cur_x = (F32)llfloor(cur_x + 0.5f); } - else + else if (target_x < cur_x + char_width) { - F32 char_width = mFontFreetype->getXAdvance(wch); - - if (round) - { - // Note: if the mouse is on the left half of the character, the pick is to the character's left - // If it's on the right half, the pick is to the right. - if (target_x < cur_x + char_width*0.5f) - { - break; - } - } - else if (target_x < cur_x + char_width) - { - break; - } - - if (scaled_max_pixels < cur_x + char_width) - { - break; - } - - pos++; - cur_x += char_width; - - if (((i + 1) < max_index) - && (wchars[(i + 1)])) - { - llwchar next_char = wchars[i + 1]; - // Kern this puppy. - cur_x += mFontFreetype->getXKerning(wch, next_char); - } - - // Round after kerning. - cur_x = (F32)llfloor(cur_x + 0.5f); + break; } - } - return pos; -} + if (scaled_max_pixels < cur_x + char_width) + { + break; + } -void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label ) const -{ - LLWString wlabel = utf8str_to_wstring(label); - addEmbeddedChar(wc, image, wlabel); -} + cur_x += char_width; -void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& wlabel ) const -{ - embedded_data_t* ext_data = new embedded_data_t(image->getGLTexture(), wlabel); - mEmbeddedChars[wc] = ext_data; -} + if (((pos + 1) < max_index) + && (wchars[(pos + 1)])) + { + llwchar next_char = wchars[pos + 1]; + // Kern this puppy. + cur_x += mFontFreetype->getXKerning(wch, next_char); + } -void LLFontGL::removeEmbeddedChar(llwchar wc) const -{ - embedded_map_t::iterator iter = mEmbeddedChars.find(wc); - if (iter != mEmbeddedChars.end()) - { - delete iter->second; - mEmbeddedChars.erase(wc); + // Round after kerning. + cur_x = (F32)llfloor(cur_x + 0.5f); } + + return llmin(max_chars, pos - begin_offset); } BOOL LLFontGL::addChar(llwchar wch) const @@ -1154,38 +974,6 @@ LLFontGL &LLFontGL::operator=(const LLFontGL &source) return *this; } -const LLFontGL::embedded_data_t* LLFontGL::getEmbeddedCharData(llwchar wch) const -{ - // Handle crappy embedded hack - embedded_map_t::const_iterator iter = mEmbeddedChars.find(wch); - if (iter != mEmbeddedChars.end()) - { - return iter->second; - } - return NULL; -} - -F32 LLFontGL::getEmbeddedCharAdvance(const embedded_data_t* ext_data) const -{ - const LLWString& label = ext_data->mLabel; - LLImageGL* ext_image = ext_data->mImage; - - F32 ext_width = (F32)ext_image->getWidth(); - if( !label.empty() ) - { - ext_width += (EXT_X_BEARING + getFontExtChar()->getWidthF32(label.c_str())) * sScaleX; - } - - return (EXT_X_BEARING * sScaleX) + ext_width; -} - -void LLFontGL::clearEmbeddedChars() -{ - for_each(mEmbeddedChars.begin(), mEmbeddedChars.end(), DeletePairedPointer()); - mEmbeddedChars.clear(); -} - - void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const { gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 42ed7a381fd104166ca53e0226bacf2ced0f3d5b..af8e0909afab869e8f79d94b4361a7216b2850c8 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -97,7 +97,7 @@ class LLFontGL BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback); S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign = LEFT, VAlign valign = BASELINE, U8 style = NORMAL, - ShadowType shadow = NO_SHADOW, S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x=NULL, BOOL use_embedded = FALSE, BOOL use_ellipses = FALSE) const; + ShadowType shadow = NO_SHADOW, S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x=NULL, BOOL use_ellipses = FALSE) const; S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const; // renderUTF8 does a conversion, so is slower! @@ -113,28 +113,24 @@ class LLFontGL S32 getWidth(const std::string& utf8text) const; S32 getWidth(const llwchar* wchars) const; S32 getWidth(const std::string& utf8text, S32 offset, S32 max_chars ) const; - S32 getWidth(const llwchar* wchars, S32 offset, S32 max_chars, BOOL use_embedded = FALSE) const; + S32 getWidth(const llwchar* wchars, S32 offset, S32 max_chars) const; F32 getWidthF32(const std::string& utf8text) const; F32 getWidthF32(const llwchar* wchars) const; F32 getWidthF32(const std::string& text, S32 offset, S32 max_chars ) const; - F32 getWidthF32(const llwchar* wchars, S32 offset, S32 max_chars, BOOL use_embedded = FALSE ) const; + F32 getWidthF32(const llwchar* wchars, S32 offset, S32 max_chars) const; // The following are called often, frequently with large buffers, so do not use a string interface // Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels - S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, BOOL end_on_word_boundary = FALSE, BOOL use_embedded = FALSE, F32* drawn_pixels = NULL) const; + S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, BOOL end_on_word_boundary = FALSE) const; // Returns the index of the first complete characters from text that can be drawn in max_pixels // given that the character at start_pos should be the last character (or as close to last as possible). S32 firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const; // Returns the index of the character closest to pixel position x (ignoring text to the right of max_pixels and max_chars) - S32 charFromPixelOffset(const llwchar* wchars, S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE, BOOL use_embedded = FALSE) const; - - void addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label) const; - void addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& label) const; - void removeEmbeddedChar( llwchar wc ) const; + S32 charFromPixelOffset(const llwchar* wchars, S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE) const; BOOL addChar(const llwchar wch) const; @@ -199,19 +195,6 @@ class LLFontGL LLFontDescriptor mFontDescriptor; LLPointer<LLFontFreetype> mFontFreetype; - struct embedded_data_t - { - embedded_data_t(LLImageGL* image, const LLWString& label) : mImage(image), mLabel(label) {} - LLPointer<LLImageGL> mImage; - LLWString mLabel; - }; - - typedef std::map<llwchar,embedded_data_t*> embedded_map_t; - mutable embedded_map_t mEmbeddedChars; - - const embedded_data_t* getEmbeddedCharData(llwchar wch) const; - F32 getEmbeddedCharAdvance(const embedded_data_t* ext_data) const; - void clearEmbeddedChars(); void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const; void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const; diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index 553e7b8f9dcf49890d557610c915e7d3be45ed32..99f364a5899351a2788c316512427fad2b54d685 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -477,7 +477,6 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) if (result) { - result->mFontFreetype->setStyle(match_desc->getStyle()); result->mFontDescriptor = desc; } else diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index c3d1d9e894cb8e0df547d78686434e7df0641f93..3669b49e51c0544747ef866729b87469edbe532c 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -516,7 +516,6 @@ void LLImageGL::setImage(const LLImageRaw* imageraw) void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) { -// LLFastTimer t1(LLFastTimer::FTM_TEMP1); llpushcallstacks ; bool is_compressed = false; if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) @@ -524,12 +523,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) is_compressed = true; } -// LLFastTimer t2(LLFastTimer::FTM_TEMP2); gGL.getTexUnit(0)->bind(this); if (mUseMipMaps) { -// LLFastTimer t2(LLFastTimer::FTM_TEMP3); if (data_hasmips) { // NOTE: data_in points to largest image; smaller images @@ -546,14 +543,13 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } if (is_compressed) { -// LLFastTimer t2(LLFastTimer::FTM_TEMP4); S32 tex_size = dataFormatBytes(mFormatPrimary, w, h); glCompressedTexImage2DARB(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in); stop_glerror(); } else { -// LLFastTimer t2(LLFastTimer::FTM_TEMP4); +// LLFastTimer t2(FTM_TEMP4); if(mFormatSwapBytes) { @@ -586,7 +582,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE); stop_glerror(); { -// LLFastTimer t2(LLFastTimer::FTM_TEMP4); +// LLFastTimer t2(FTM_TEMP4); if(mFormatSwapBytes) { @@ -646,7 +642,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } llassert(w > 0 && h > 0 && cur_mip_data); { -// LLFastTimer t1(LLFastTimer::FTM_TEMP4); +// LLFastTimer t1(FTM_TEMP4); if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); @@ -988,7 +984,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ LLImageGL::generateTextures(1, &mTexName); stop_glerror(); { -// LLFastTimer t1(LLFastTimer::FTM_TEMP6); llverify(gGL.getTexUnit(0)->bind(this)); glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel-discard_level); diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index c566282befc14c7a177d9c64fcdb761fb6d9dff6..b13b250c75272578c9d5b0215d00896245b090e0 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -419,8 +419,16 @@ BOOL LLButton::handleRightMouseDown(S32 x, S32 y, MASK mask) { setFocus(TRUE); } - } +// if (pointInView(x, y)) +// { +// } + } + // send the mouse down signal + LLUICtrl::handleRightMouseDown(x,y,mask); + // *TODO: Return result of LLUICtrl call above? Should defer to base class + // but this might change the mouse handling of existing buttons in a bad way + // if they are not mouse opaque. return TRUE; } @@ -432,15 +440,20 @@ BOOL LLButton::handleRightMouseUp(S32 x, S32 y, MASK mask) // Always release the mouse gFocusMgr.setMouseCapture( NULL ); - if (pointInView(x, y)) - { - mRightClickSignal(this, x,y,mask); - } +// if (pointInView(x, y)) +// { +// mRightMouseUpSignal(this, x,y,mask); +// } } else { childrenHandleRightMouseUp(x, y, mask); } + // send the mouse up signal + LLUICtrl::handleRightMouseUp(x,y,mask); + // *TODO: Return result of LLUICtrl call above? Should defer to base class + // but this might change the mouse handling of existing buttons in a bad way. + // if they are not mouse opaque. return TRUE; } @@ -788,7 +801,7 @@ void LLButton::draw() LLFontGL::NORMAL, mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NO_SHADOW, S32_MAX, text_width, - NULL, FALSE, mUseEllipses); + NULL, mUseEllipses); } LLUICtrl::draw(); diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index b3c3a2e6985b8b7d93a7e65d526ba9b1f256fea9..ac56d15d1b823e8197783e9702ba1a6931a1c3a4 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -191,6 +191,7 @@ void LLComboBox::clear() mButton->setLabelSelected(LLStringUtil::null); mButton->setLabelUnselected(LLStringUtil::null); mList->deselectAllItems(); + mLastSelectedIndex = -1; } void LLComboBox::onCommit() @@ -296,6 +297,7 @@ BOOL LLComboBox::setSimple(const LLStringExplicit& name) if (found) { setLabel(name); + mLastSelectedIndex = mList->getFirstSelectedIndex(); } return found; @@ -312,6 +314,7 @@ void LLComboBox::setValue(const LLSD& value) { setLabel( mList->getSelectedItemLabel() ); } + mLastSelectedIndex = mList->getFirstSelectedIndex(); } } @@ -359,6 +362,7 @@ void LLComboBox::setLabel(const LLStringExplicit& name) if (mList->selectItemByLabel(name, FALSE)) { mTextEntry->setTentative(FALSE); + mLastSelectedIndex = mList->getFirstSelectedIndex(); } else { @@ -384,6 +388,7 @@ BOOL LLComboBox::remove(const std::string& name) { mList->deleteSingleItem(mList->getItemIndex(item)); } + mLastSelectedIndex = mList->getFirstSelectedIndex(); } return found; @@ -436,6 +441,7 @@ BOOL LLComboBox::setCurrentByIndex( S32 index ) if (found) { setLabel(mList->getSelectedItemLabel()); + mLastSelectedIndex = index; } return found; } @@ -607,9 +613,6 @@ void LLComboBox::showList() mList->setVisible(TRUE); setUseBoundingRect(TRUE); - - mList->sortItems(); - mLastSelectedIndex = mList->getFirstSelectedIndex(); } void LLComboBox::hideList() @@ -819,11 +822,13 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor) if (mList->selectItemByLabel(line_editor->getText(), FALSE)) { line_editor->setTentative(FALSE); + mLastSelectedIndex = mList->getFirstSelectedIndex(); } else { line_editor->setTentative(mTextEntryTentative); mList->deselectAllItems(); + mLastSelectedIndex = -1; } return; } @@ -890,6 +895,7 @@ void LLComboBox::updateSelection() if (mList->selectItemByLabel(full_string, FALSE)) { mTextEntry->setTentative(FALSE); + mLastSelectedIndex = mList->getFirstSelectedIndex(); } else if (mList->selectItemByPrefix(left_wstring, FALSE)) { @@ -900,6 +906,7 @@ void LLComboBox::updateSelection() mTextEntry->endSelection(); mTextEntry->setTentative(FALSE); mHasAutocompletedText = TRUE; + mLastSelectedIndex = mList->getFirstSelectedIndex(); } else // no matching items found { @@ -907,6 +914,7 @@ void LLComboBox::updateSelection() mTextEntry->setText(wstring_to_utf8str(user_wstring)); // removes text added by autocompletion mTextEntry->setTentative(mTextEntryTentative); mHasAutocompletedText = FALSE; + mLastSelectedIndex = -1; } } @@ -994,6 +1002,7 @@ BOOL LLComboBox::setCurrentByID(const LLUUID& id) if (found) { setLabel(mList->getSelectedItemLabel()); + mLastSelectedIndex = mList->getFirstSelectedIndex(); } return found; diff --git a/indra/llui/llcontainerview.cpp b/indra/llui/llcontainerview.cpp index 7e7d6ac11102427518a084a5c9f13b5bb7ab2345..51ef80f4b981ec49a1d1b48ea3dbbfc5a9a3eaf8 100644 --- a/indra/llui/llcontainerview.cpp +++ b/indra/llui/llcontainerview.cpp @@ -132,35 +132,31 @@ void LLContainerView::draw() void LLContainerView::reshape(S32 width, S32 height, BOOL called_from_parent) { - S32 desired_width = width; - S32 desired_height = height; + LLRect scroller_rect; + scroller_rect.setOriginAndSize(0, 0, width, height); if (mScrollContainer) { - BOOL dum_bool; - mScrollContainer->calcVisibleSize(&desired_width, &desired_height, &dum_bool, &dum_bool); + scroller_rect = mScrollContainer->getContentWindowRect(); } else { // if we're uncontained - make height as small as possible - desired_height = 0; + scroller_rect.mTop = 0; } - arrange(desired_width, desired_height, called_from_parent); + arrange(scroller_rect.getWidth(), scroller_rect.getHeight(), called_from_parent); // sometimes, after layout, our container will change size (scrollbars popping in and out) // if so, attempt another layout if (mScrollContainer) { - S32 new_container_width; - S32 new_container_height; - BOOL dum_bool; - mScrollContainer->calcVisibleSize(&new_container_width, &new_container_height, &dum_bool, &dum_bool); + LLRect new_container_rect = mScrollContainer->getContentWindowRect(); - if ((new_container_width != desired_width) || - (new_container_height != desired_height)) // the container size has changed, attempt to arrange again + if ((new_container_rect.getWidth() != scroller_rect.getWidth()) || + (new_container_rect.getHeight() != scroller_rect.getHeight())) // the container size has changed, attempt to arrange again { - arrange(new_container_width, new_container_height, called_from_parent); + arrange(new_container_rect.getWidth(), new_container_rect.getHeight(), called_from_parent); } } } diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index d420d1141e890bba3b85dd55d91b87a1113631e9..2679143bbcbbd6af547485e5fe8642d1e61542ee 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -711,10 +711,7 @@ void LLFloater::releaseFocus() gFocusMgr.setTopCtrl(NULL); } - if( gFocusMgr.childHasKeyboardFocus( this ) ) - { - gFocusMgr.setKeyboardFocus(NULL); - } + setFocus(FALSE); if( gFocusMgr.childHasMouseCapture( this ) ) { @@ -1074,7 +1071,7 @@ void LLFloater::setFocus( BOOL b ) } LLUICtrl* last_focus = gFocusMgr.getLastFocusForGroup(this); // a descendent already has focus - BOOL child_had_focus = gFocusMgr.childHasKeyboardFocus(this); + BOOL child_had_focus = hasFocus(); // give focus to first valid descendent LLPanel::setFocus(b); @@ -1948,7 +1945,7 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF if (sibling && sibling != neighbor && sibling->getVisible() && - expanded_base_rect.rectInRect(&sibling->getRect())) + expanded_base_rect.overlaps(sibling->getRect())) { base_rect.unionWith(sibling->getRect()); } @@ -2593,6 +2590,8 @@ void LLFloater::initFromParams(const LLFloater::Params& p) initCommitCallback(p.close_callback, mCloseSignal); } +LLFastTimer::DeclareTimer POST_BUILD("Floater Post Build"); + void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) { Params params(LLUICtrlFactory::getDefaultParams<LLFloater>()); @@ -2626,7 +2625,12 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr o LLFloater::setFloaterHost(last_host); } - BOOL result = postBuild(); + BOOL result; + { + LLFastTimer ft(POST_BUILD); + + result = postBuild(); + } if (!result) { diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp index 30796a5ab97f1eb61f50bfc0fe75dc8036de19fc..db1611abb5eea936aa00386c1207e72881cc6275 100644 --- a/indra/llui/llkeywords.cpp +++ b/indra/llui/llkeywords.cpp @@ -231,11 +231,13 @@ LLColor3 LLKeywords::readColor( const std::string& s ) return LLColor3( r, g, b ); } +LLFastTimer::DeclareTimer FTM_SYNTAX_COLORING("Syntax Coloring"); + // Walk through a string, applying the rules specified by the keyword token list and // create a list of color segments. -void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWString& wtext, const LLColor4 &defaultColor) +void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLWString& wtext, const LLColor4 &defaultColor, LLTextEditor& editor) { - std::for_each(seg_list->begin(), seg_list->end(), DeletePointer()); + LLFastTimer ft(FTM_SYNTAX_COLORING); seg_list->clear(); if( wtext.empty() ) @@ -245,7 +247,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS S32 text_len = wtext.size(); - seg_list->push_back( new LLTextSegment( LLColor3(defaultColor), 0, text_len ) ); + seg_list->push_back( new LLNormalTextSegment( defaultColor, 0, text_len, editor ) ); const llwchar* base = wtext.c_str(); const llwchar* cur = base; @@ -296,9 +298,9 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS } S32 seg_end = cur - base; - LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end ); + LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, seg_end, editor ); text_segment->setToken( cur_token ); - insertSegment( seg_list, text_segment, text_len, defaultColor); + insertSegment( seg_list, text_segment, text_len, defaultColor, editor); line_done = TRUE; // to break out of second loop. break; } @@ -405,9 +407,9 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS } - LLTextSegment* text_segment = new LLTextSegment( cur_delimiter->getColor(), seg_start, seg_end ); + LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_delimiter->getColor(), seg_start, seg_end, editor ); text_segment->setToken( cur_delimiter ); - insertSegment( seg_list, text_segment, text_len, defaultColor); + insertSegment( seg_list, text_segment, text_len, defaultColor, editor); // Note: we don't increment cur, since the end of one delimited seg may be immediately // followed by the start of another one. @@ -438,9 +440,9 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS // llinfos << "Seg: [" << word.c_str() << "]" << llendl; - LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end ); + LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, seg_end, editor ); text_segment->setToken( cur_token ); - insertSegment( seg_list, text_segment, text_len, defaultColor); + insertSegment( seg_list, text_segment, text_len, defaultColor, editor); } cur += seg_len; continue; @@ -455,25 +457,24 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS } } -void LLKeywords::insertSegment(std::vector<LLTextSegment*>* seg_list, LLTextSegment* new_segment, S32 text_len, const LLColor4 &defaultColor ) +void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>* seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, LLTextEditor& editor ) { - LLTextSegment* last = seg_list->back(); + LLTextSegmentPtr last = seg_list->back(); S32 new_seg_end = new_segment->getEnd(); if( new_segment->getStart() == last->getStart() ) { - *last = *new_segment; - delete new_segment; + seg_list->pop_back(); } else { last->setEnd( new_segment->getStart() ); - seg_list->push_back( new_segment ); } + seg_list->push_back( new_segment ); if( new_seg_end < text_len ) { - seg_list->push_back( new LLTextSegment( defaultColor, new_seg_end, text_len ) ); + seg_list->push_back( new LLNormalTextSegment( defaultColor, new_seg_end, text_len, editor ) ); } } diff --git a/indra/llui/llkeywords.h b/indra/llui/llkeywords.h index 38f5e993c2809eebe661116bf8b83d7305e624fd..53377869ca4c3588853fa602a83d17c4efa20d7b 100644 --- a/indra/llui/llkeywords.h +++ b/indra/llui/llkeywords.h @@ -39,9 +39,10 @@ #include <map> #include <list> #include <deque> +#include "llpointer.h" class LLTextSegment; - +typedef LLPointer<LLTextSegment> LLTextSegmentPtr; class LLKeywordToken { @@ -84,7 +85,7 @@ class LLKeywords BOOL loadFromFile(const std::string& filename); BOOL isLoaded() const { return mLoaded; } - void findSegments(std::vector<LLTextSegment *> *seg_list, const LLWString& text, const LLColor4 &defaultColor ); + void findSegments(std::vector<LLTextSegmentPtr> *seg_list, const LLWString& text, const LLColor4 &defaultColor, class LLTextEditor& editor ); // Add the token as described void addToken(LLKeywordToken::TOKEN_TYPE type, @@ -103,7 +104,7 @@ class LLKeywords private: LLColor3 readColor(const std::string& s); - void insertSegment(std::vector<LLTextSegment *> *seg_list, LLTextSegment* new_segment, S32 text_len, const LLColor4 &defaultColor); + void insertSegment(std::vector<LLTextSegmentPtr> *seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, class LLTextEditor& editor); BOOL mLoaded; word_token_map_t mWordTokenMap; diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 702d8e4a39c5d742ab6847d6f33a9c2423bc8971..f98edec1f324c5719e3eeb177c61c023541e7526 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -167,7 +167,7 @@ void LLLayoutStack::draw() LLLocalClipRect clip(clip_rect, mClip); // only force drawing invisible children if visible amount is non-zero - drawChild(panelp, 0, 0, !clip_rect.isNull()); + drawChild(panelp, 0, 0, !clip_rect.isEmpty()); } } diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 42a1b9ad9c5029377168810eecc94bc9614d612a..6926415c6df4b87b802b257307b8583a093c98ee 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -494,19 +494,19 @@ BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask) BOOL doSelectAll = TRUE; // Select the word we're on - if( LLTextEditor::isPartOfWord( wtext[mCursorPos] ) ) + if( LLWStringUtil::isPartOfWord( wtext[mCursorPos] ) ) { S32 old_selection_start = mLastSelectionStart; S32 old_selection_end = mLastSelectionEnd; // Select word the cursor is over - while ((mCursorPos > 0) && LLTextEditor::isPartOfWord( wtext[mCursorPos-1] )) + while ((mCursorPos > 0) && LLWStringUtil::isPartOfWord( wtext[mCursorPos-1] )) { // Find the start of the word mCursorPos--; } startSelection(); - while ((mCursorPos < (S32)wtext.length()) && LLTextEditor::isPartOfWord( wtext[mCursorPos] ) ) + while ((mCursorPos < (S32)wtext.length()) && LLWStringUtil::isPartOfWord( wtext[mCursorPos] ) ) { // Find the end of the word mCursorPos++; } @@ -840,7 +840,7 @@ S32 LLLineEditor::prevWordPos(S32 cursorPos) const { cursorPos--; } - while( (cursorPos > 0) && LLTextEditor::isPartOfWord( wtext[cursorPos-1] ) ) + while( (cursorPos > 0) && LLWStringUtil::isPartOfWord( wtext[cursorPos-1] ) ) { cursorPos--; } @@ -850,7 +850,7 @@ S32 LLLineEditor::prevWordPos(S32 cursorPos) const S32 LLLineEditor::nextWordPos(S32 cursorPos) const { const LLWString& wtext = mText.getWString(); - while( (cursorPos < getLength()) && LLTextEditor::isPartOfWord( wtext[cursorPos] ) ) + while( (cursorPos < getLength()) && LLWStringUtil::isPartOfWord( wtext[cursorPos] ) ) { cursorPos++; } @@ -1732,11 +1732,11 @@ void LLLineEditor::draw() #endif // If we're editing... - if( gFocusMgr.getKeyboardFocus() == this) + if( hasFocus()) { //mBorder->setVisible(TRUE); // ok, programmer art just this once. // (Flash the cursor every half second) - if (gShowTextEditCursor && !mReadOnly) + if (!mReadOnly && gFocusMgr.getAppHasFocus()) { F32 elapsed = mKeystrokeTimer.getElapsedTimeF32(); if( (elapsed < CURSOR_FLASH_DELAY ) || (S32(elapsed * 2) & 1) ) diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 5be53e6afc981c64dff57c772b0cbab1d66a0759..b6c3ffc61c70b6d5b80a0da4bbd0d11b82a80231 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -184,6 +184,13 @@ LLMenuItemGL::LLMenuItemGL(const LLMenuItemGL::Params& p) << LL_ENDL; } +//virtual +void LLMenuItemGL::setValue(const LLSD& value) +{ + setLabel(value.asString()); +} + +//virtual BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask) { if( getEnabled() && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) ) @@ -201,6 +208,26 @@ BOOL LLMenuItemGL::handleHover(S32 x, S32 y, MASK mask) return TRUE; } +//virtual +BOOL LLMenuItemGL::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + return LLUICtrl::handleRightMouseDown(x,y,mask); +} + +//virtual +BOOL LLMenuItemGL::handleRightMouseUp(S32 x, S32 y, MASK mask) +{ + // If this event came from a right-click context menu spawn, + // process as a left-click to allow menu items to be hit + if (LLMenuHolderGL::sContextMenuSpawnPos.mX != S32_MAX + || LLMenuHolderGL::sContextMenuSpawnPos.mY != S32_MAX) + { + BOOL handled = handleMouseUp(x, y, mask); + return handled; + } + return LLUICtrl::handleRightMouseUp(x,y,mask); +} + // This function checks to see if the accelerator key is already in use; // if not, it will be added to the list BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp) @@ -306,6 +333,17 @@ U32 LLMenuItemGL::getNominalHeight( void ) const return llround(mFont->getLineHeight()) + MENU_ITEM_PADDING; } +//virtual +void LLMenuItemGL::setBriefItem(BOOL brief) +{ + mBriefItem = brief; +} + +//virtual +BOOL LLMenuItemGL::isBriefItem() const +{ + return mBriefItem; +} // Get the parent menu for this item LLMenuGL* LLMenuItemGL::getMenu() const @@ -800,15 +838,8 @@ BOOL LLMenuItemCallGL::handleAcceleratorKey( KEY key, MASK mask ) return FALSE; } -BOOL LLMenuItemCallGL::handleRightMouseUp(S32 x, S32 y, MASK mask) -{ - if (pointInView(x, y)) - { - mRightClickSignal(this,x,y, mask); - } - - return TRUE; -} +// handleRightMouseUp moved into base class LLMenuItemGL so clicks are +// handled for all menu item types ///============================================================================ /// Class LLMenuItemCheckGL @@ -898,24 +929,38 @@ LLMenuItemBranchGL::~LLMenuItemBranchGL() } // virtual -LLView* LLMenuItemBranchGL::getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const +LLView* LLMenuItemBranchGL::getChildView(const std::string& name, BOOL recurse) const { LLMenuGL* branch = getBranch(); - if (!branch) - return LLView::getChildView(name, recurse, create_if_missing); - - // richard: this is redundant with parent, remove - if (branch->getName() == name) + if (branch) { - return branch; + if (branch->getName() == name) + { + return branch; + } + + // Always recurse on branches + return branch->getChildView(name, recurse); } - // Always recurse on branches - LLView* child = branch->getChildView(name, recurse, FALSE); - if (!child) + + return LLView::getChildView(name, recurse); +} + +LLView* LLMenuItemBranchGL::findChildView(const std::string& name, BOOL recurse) const +{ + LLMenuGL* branch = getBranch(); + if (branch) { - child = LLView::getChildView(name, recurse, create_if_missing); + if (branch->getName() == name) + { + return branch; + } + + // Always recurse on branches + return branch->findChildView(name, recurse); } - return child; + + return LLView::findChildView(name, recurse); } // virtual @@ -1123,6 +1168,18 @@ BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask ) return LLMenuItemGL::handleKeyHere(key, mask); } +//virtual +BOOL LLMenuItemBranchGL::isActive() const +{ + return isOpen() && getBranch() && getBranch()->getHighlightedItem(); +} + +//virtual +BOOL LLMenuItemBranchGL::isOpen() const +{ + return getBranch() && getBranch()->isOpen(); +} + void LLMenuItemBranchGL::openMenu() { LLMenuGL* branch = getBranch(); @@ -1298,6 +1355,9 @@ void LLMenuItemBranchDownGL::setHighlight( BOOL highlight ) { if (highlight == getHighlight()) return; + LLMenuGL* branch = getBranch(); + if (!branch) return; + //NOTE: Purposely calling all the way to the base to bypass auto-open. LLMenuItemGL::setHighlight(highlight); if( !highlight) @@ -2803,9 +2863,9 @@ void LLMenuGL::setVisible(BOOL visible) } } -LLMenuGL* LLMenuGL::getChildMenuByName(const std::string& name, BOOL recurse) const +LLMenuGL* LLMenuGL::findChildMenuByName(const std::string& name, BOOL recurse) const { - LLView* view = getChildView(name, recurse, FALSE); + LLView* view = findChildView(name, recurse); if (view) { LLMenuItemBranchGL* branch = dynamic_cast<LLMenuItemBranchGL*>(view); @@ -2844,9 +2904,19 @@ void hide_top_view( LLView* view ) } +// x and y are the desired location for the popup, NOT necessarily the +// mouse location // static void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) { + // Save click point for detecting cursor moves before mouse-up. + // Must be in local coords to compare with mouseUp events. + // If the mouse doesn't move, the menu will stay open ala the Mac. + // See also LLContextMenu::show() + S32 mouse_x, mouse_y; + LLUI::getCursorPositionLocal(menu->getParent(), &mouse_x, &mouse_y); + LLMenuHolderGL::sContextMenuSpawnPos.set(mouse_x,mouse_y); + const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect(); const S32 HPAD = 2; @@ -2857,9 +2927,6 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) spawning_view->localPointToOtherView(left, top, &left, &top, menu->getParent()); rect.setLeftTopAndSize( left, top, rect.getWidth(), rect.getHeight() ); - - - //rect.setLeftTopAndSize(x + HPAD, y, rect.getWidth(), rect.getHeight()); menu->setRect( rect ); // Resetting scrolling position @@ -2871,18 +2938,16 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) menu->arrangeAndClear(); // Fix menu rect if needed. rect = menu->getRect(); + // Adjust context menu to fit onscreen S32 bottom; left = rect.mLeft; bottom = rect.mBottom; - //menu->getParent()->localPointToScreen( rect.mLeft, rect.mBottom, - // &left, &bottom ); S32 delta_x = 0; S32 delta_y = 0; if( bottom < menu_region_rect.mBottom ) { // At this point, we need to move the context menu to the // other side of the mouse. - //delta_y = menu_region_rect.mBottom - bottom; delta_y = (rect.getHeight() + 2 * HPAD); } @@ -2890,7 +2955,6 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) { // At this point, we need to move the context menu to the // other side of the mouse. - //delta_x = (window_width - rect.getWidth()) - x; delta_x = -(rect.getWidth() + 2 * HPAD); } menu->translate( delta_x, delta_y ); @@ -3633,6 +3697,7 @@ void LLContextMenu::show(S32 x, S32 y) // Save click point for detecting cursor moves before mouse-up. // Must be in local coords to compare with mouseUp events. // If the mouse doesn't move, the menu will stay open ala the Mac. + // See also LLMenuGL::showPopup() LLMenuHolderGL::sContextMenuSpawnPos.set(x,y); arrangeAndClear(); diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index d39a02da28faa79532770d08fb5e36f170d26fc7..2e7f61c2dd3c6488e724060b5575fcf50b4b7475 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -105,10 +105,15 @@ class LLMenuItemGL : public LLUICtrl LLMenuItemGL(const Params&); friend class LLUICtrlFactory; public: - virtual void setValue(const LLSD& value) { setLabel(value.asString()); } + // LLView overrides /*virtual*/ void handleVisibilityChange(BOOL new_visibility); + /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); + + // LLUICtrl overrides + /*virtual*/ void setValue(const LLSD& value); - virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleAcceleratorKey(KEY key, MASK mask); LLColor4 getHighlightBgColor() { return mHighlightBackground.get(); } @@ -124,8 +129,8 @@ class LLMenuItemGL : public LLUICtrl virtual U32 getNominalHeight( void ) const; // Marks item as not needing space for check marks or accelerator keys - virtual void setBriefItem(BOOL brief) { mBriefItem = brief; } - virtual BOOL isBriefItem() const { return mBriefItem; } + virtual void setBriefItem(BOOL brief); + virtual BOOL isBriefItem() const; virtual BOOL addToAcceleratorList(std::list<LLKeyBinding*> *listp); void setAllowKeyRepeat(BOOL allow) { mAllowKeyRepeat = allow; } @@ -283,7 +288,6 @@ class LLMenuItemCallGL : public LLMenuItemGL virtual BOOL handleAcceleratorKey(KEY key, MASK mask); virtual BOOL handleKeyHere(KEY key, MASK mask); - virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); //virtual void draw(); @@ -427,7 +431,7 @@ class LLMenuGL virtual BOOL handleAcceleratorKey(KEY key, MASK mask); - LLMenuGL* getChildMenuByName(const std::string& name, BOOL recurse) const; + LLMenuGL* findChildMenuByName(const std::string& name, BOOL recurse) const; BOOL clearHoverItem(); @@ -610,9 +614,9 @@ class LLMenuItemBranchGL : public LLMenuItemGL virtual BOOL handleKeyHere(KEY key, MASK mask); - virtual BOOL isActive() const { return isOpen() && getBranch() && getBranch()->getHighlightedItem(); } + virtual BOOL isActive() const; - virtual BOOL isOpen() const { return getBranch() && getBranch()->isOpen(); } + virtual BOOL isOpen() const; LLMenuGL* getBranch() const { return (LLMenuGL*)mBranchHandle.get(); } @@ -627,7 +631,8 @@ class LLMenuItemBranchGL : public LLMenuItemGL virtual void openMenu(); - virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const; + virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE) const; + virtual LLView* findChildView(const std::string& name, BOOL recurse = TRUE) const; private: LLHandle<LLView> mBranchHandle; diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp index 11fa290de11efdc928f2ad6e68ba6ea7070d2ab6..c8162fe46619f81e382ed683e9751dd00c9185de 100644 --- a/indra/llui/llmodaldialog.cpp +++ b/indra/llui/llmodaldialog.cpp @@ -279,10 +279,7 @@ void LLModalDialog::onAppFocusLost() gFocusMgr.setMouseCapture( NULL ); } - if( gFocusMgr.childHasKeyboardFocus( instance ) ) - { - gFocusMgr.setKeyboardFocus( NULL ); - } + instance->setFocus(FALSE); } } diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp index 9f9e3aecac291bae5bcebddd98ea400ad368f44a..e8ce1a8d97977634b342fa82c6af03b94649b2a6 100644 --- a/indra/llui/llmultifloater.cpp +++ b/indra/llui/llmultifloater.cpp @@ -454,14 +454,8 @@ BOOL LLMultiFloater::postBuild() return TRUE; } - requires<LLTabContainer>("Preview Tabs"); - if (checkRequirements()) - { - mTabContainer = getChild<LLTabContainer>("Preview Tabs"); - return TRUE; - } - - return FALSE; + mTabContainer = getChild<LLTabContainer>("Preview Tabs"); + return TRUE; } void LLMultiFloater::updateResizeLimits() diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index da55ababab4b18cde1adc79a5b21192b09aa776e..667a3e10c4755dee9a19c3451d8f591d61bb1001 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -192,10 +192,6 @@ void LLPanel::draw() void LLPanel::updateDefaultBtn() { - // This method does not call LLView::draw() so callers will need - // to take care of that themselves at the appropriate place in - // their rendering sequence - if( mDefaultBtn) { if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled()) @@ -254,7 +250,7 @@ BOOL LLPanel::handleKeyHere( KEY key, MASK mask ) // handle user hitting ESC to defocus if (key == KEY_ESCAPE) { - gFocusMgr.setKeyboardFocus(NULL); + setFocus(FALSE); return TRUE; } else if( (mask == MASK_SHIFT) && (KEY_TAB == key)) @@ -315,53 +311,18 @@ void LLPanel::handleVisibilityChange ( BOOL new_visibility ) mVisibleSignal(this, LLSD(new_visibility) ); // Pass BOOL as LLSD } -BOOL LLPanel::checkRequirements() -{ - if (!mRequirementsError.empty()) - { - LLSD args; - args["COMPONENTS"] = mRequirementsError; - args["FLOATER"] = getName(); - - llwarns << getName() << " failed requirements check on: \n" - << mRequirementsError << llendl; - - LLNotifications::instance().add(LLNotification::Params("FailedRequirementsCheck").payload(args)); - mRequirementsError.clear(); - return FALSE; - } - - return TRUE; -} - void LLPanel::setFocus(BOOL b) { - if( b ) + if( b && !hasFocus()) { - if (!gFocusMgr.childHasKeyboardFocus(this)) - { - // give ourselves focus preemptively, to avoid infinite loop - LLUICtrl::setFocus(TRUE); - // then try to pass to first valid child - focusFirstItem(); - } + // give ourselves focus preemptively, to avoid infinite loop + LLUICtrl::setFocus(TRUE); + // then try to pass to first valid child + focusFirstItem(); } else { - if( this == gFocusMgr.getKeyboardFocus() ) - { - gFocusMgr.setKeyboardFocus( NULL ); - } - else - { - //RN: why is this here? - LLView::ctrl_list_t ctrls = getCtrlList(); - for (LLView::ctrl_list_t::iterator ctrl_it = ctrls.begin(); ctrl_it != ctrls.end(); ++ctrl_it) - { - LLUICtrl* ctrl = *ctrl_it; - ctrl->setFocus( FALSE ); - } - } + LLUICtrl::setFocus(b); } } @@ -704,7 +665,6 @@ BOOL LLPanel::childHasFocus(const std::string& id) } else { - childNotFound(id); return FALSE; } } @@ -881,58 +841,3 @@ void LLPanel::childSetControlName(const std::string& id, const std::string& cont view->setControlName(control_name, NULL); } } - -//virtual -LLView* LLPanel::getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const -{ - // just get child, don't try to create a dummy one - LLView* view = LLUICtrl::getChildView(name, recurse, FALSE); - if (!view && !recurse) - { - childNotFound(name); - } - if (!view && create_if_missing) - { - view = getDefaultWidget<LLView>(name); - if (!view) - { - // create LLViews explicitly, as they are not registered widget types - view = LLUICtrlFactory::createDefaultWidget<LLView>(name); - } - } - return view; -} - -void LLPanel::childNotFound(const std::string& id) const -{ - if (mExpectedMembers.find(id) == mExpectedMembers.end()) - { - mNewExpectedMembers.insert(id); - } -} - -void LLPanel::childDisplayNotFound() -{ - if (mNewExpectedMembers.empty()) - { - return; - } - std::string msg; - expected_members_list_t::iterator itor; - for (itor=mNewExpectedMembers.begin(); itor!=mNewExpectedMembers.end(); ++itor) - { - msg.append(*itor); - msg.append("\n"); - mExpectedMembers.insert(*itor); - } - mNewExpectedMembers.clear(); - LLSD args; - args["CONTROLS"] = msg; - LLNotifications::instance().add("FloaterNotFound", args); -} - -void LLPanel::requires(const std::string& name) -{ - requires<LLView>(name); -} - diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index 2a70467ffc34718ae995848d7b575c38b2c5aed6..3ee11483c3a91c374010ddc0df3cf95c3262241b 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -115,9 +115,6 @@ class LLPanel : public LLUICtrl /*virtual*/ BOOL handleKeyHere( KEY key, MASK mask ); /*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); - // Override to set not found list: - /*virtual*/ LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const; - // From LLFocusableElement /*virtual*/ void setFocus( BOOL b ); @@ -132,19 +129,6 @@ class LLPanel : public LLUICtrl BOOL hasBorder() const { return mBorder != NULL; } void setBorderVisible( BOOL b ); - template <class T> void requires(const std::string& name) - { - // check for widget with matching type and name - if (LLView::getChild<T>(name) == NULL) - { - mRequirementsError += name + "\n"; - } - } - - // requires LLView by default - void requires(const std::string& name); - BOOL checkRequirements(); - void setBackgroundColor( const LLColor4& color ) { mBgColorOpaque = color; } const LLColor4& getBackgroundColor() const { return mBgColorOpaque; } void setTransparentColor(const LLColor4& color) { mBgColorAlpha = color; } @@ -241,10 +225,6 @@ class LLPanel : public LLUICtrl void childSetControlName(const std::string& id, const std::string& control_name); - // Error reporting - void childNotFound(const std::string& id) const; - void childDisplayNotFound(); - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL); //call onOpen to let panel know when it's about to be shown or activated @@ -279,8 +259,6 @@ class LLPanel : public LLUICtrl typedef std::map<std::string, std::string> ui_string_map_t; ui_string_map_t mUIStrings; - std::string mRequirementsError; - // for setting the xml filename when building panel in context dependent cases std::string mXMLFilename; diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index 30adbb023cf9163ec50b9338c348dddf8fa9c223..c66b9bde2b138da01033c7db9b658f78128c7384 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -90,18 +90,6 @@ BOOL LLRadioGroup::postBuild() return TRUE; } -// virtual -void LLRadioGroup::setEnabled(BOOL enabled) -{ - for (child_list_const_iter_t child_iter = getChildList()->begin(); - child_iter != getChildList()->end(); ++child_iter) - { - LLView *child = *child_iter; - child->setEnabled(enabled); - } - LLView::setEnabled(enabled); -} - void LLRadioGroup::setIndexEnabled(S32 index, BOOL enabled) { S32 count = 0; diff --git a/indra/llui/llradiogroup.h b/indra/llui/llradiogroup.h index d04473fa448d767759026b539379b61814df7b19..b5516307fd45568260c83237a24463df62567408 100644 --- a/indra/llui/llradiogroup.h +++ b/indra/llui/llradiogroup.h @@ -106,9 +106,7 @@ class LLRadioGroup virtual BOOL handleKeyHere(KEY key, MASK mask); - virtual void setEnabled(BOOL enabled); void setIndexEnabled(S32 index, BOOL enabled); - // return the index value of the selected item S32 getSelectedIndex() const { return mSelectedIndex; } diff --git a/indra/llui/llresizehandle.h b/indra/llui/llresizehandle.h index 1560a03796fa3ea69b0fbb9df79051e58dfb51cd..1c09cbb1bd0333d5695a95963ba375e9945cec29 100644 --- a/indra/llui/llresizehandle.h +++ b/indra/llui/llresizehandle.h @@ -76,8 +76,8 @@ class LLResizeHandle : public LLView const ECorner mCorner; }; -const S32 RESIZE_HANDLE_HEIGHT = 16; -const S32 RESIZE_HANDLE_WIDTH = 16; +const S32 RESIZE_HANDLE_HEIGHT = 11; +const S32 RESIZE_HANDLE_WIDTH = 11; #endif // LL_RESIZEHANDLE_H diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index 566825ff3b7ed18ed74fdbc9c4488097d9935217..b46915b379db21f1602c1229a7fe7c74ade2ca33 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -394,7 +394,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask) } else { - handled = childrenHandleMouseUp( x, y, mask ) != NULL; + handled = childrenHandleHover( x, y, mask ) != NULL; } // Opaque diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h index 5522e5d0fa44a582f7a2b46949eb5ce2095065a1..30d906e04cda06cf9aad2b6a4a800ee313742b29 100644 --- a/indra/llui/llscrollbar.h +++ b/indra/llui/llscrollbar.h @@ -127,11 +127,6 @@ class LLScrollbar void onLineUpBtnPressed(const LLSD& data); void onLineDownBtnPressed(const LLSD& data); - void setTrackColor( const LLColor4& color ) { mTrackColor = color; } - void setThumbColor( const LLColor4& color ) { mThumbColor = color; } - - void setOnScrollEndCallback(void (*callback)(void*), void* userdata) { mOnScrollEndCallback = callback; mOnScrollEndData = userdata;} - private: void updateThumbRect(); void changeLine(S32 delta, BOOL update_thumb ); diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 0b455f8e17669961a4eb0483d8a475609fc170e8..13f862f3af54d04e596a48487efb726830cd7ab2 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -55,8 +55,6 @@ static const S32 HORIZONTAL_MULTIPLE = 8; static const S32 VERTICAL_MULTIPLE = 16; -static const F32 MIN_AUTO_SCROLL_RATE = 120.f; -static const F32 MAX_AUTO_SCROLL_RATE = 500.f; static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f; ///---------------------------------------------------------------------------- @@ -75,6 +73,9 @@ static ScrollContainerRegistry::Register<LLPanel> r3("panel", &LLPanel::fromXML) LLScrollContainer::Params::Params() : is_opaque("opaque"), bg_color("color"), + border_visible("border_visible"), + min_auto_scroll_rate("min_auto_scroll_rate", 100), + max_auto_scroll_rate("max_auto_scroll_rate", 1000), reserve_scroll_corner("reserve_scroll_corner", false) { name = "scroll_container"; @@ -91,6 +92,8 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p) mBackgroundColor(p.bg_color()), mIsOpaque(p.is_opaque), mReserveScrollCorner(p.reserve_scroll_corner), + mMinAutoScrollRate(p.min_auto_scroll_rate), + mMaxAutoScrollRate(p.max_auto_scroll_rate), mScrolledView(NULL) { static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); @@ -98,6 +101,7 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p) LLViewBorder::Params params; params.name("scroll border"); params.rect(border_rect); + params.visible(p.border_visible); params.bevel_style(LLViewBorder::BEVEL_IN); mBorder = LLUICtrlFactory::create<LLViewBorder> (params); LLView::addChild( mBorder ); @@ -115,12 +119,11 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p) sbparams.doc_pos(0); sbparams.page_size(mInnerRect.getHeight()); sbparams.step_size(VERTICAL_MULTIPLE); + sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM); + sbparams.visible(false); + sbparams.change_callback(p.scroll_callback); mScrollbar[VERTICAL] = LLUICtrlFactory::create<LLScrollbar> (sbparams); LLView::addChild( mScrollbar[VERTICAL] ); - mScrollbar[VERTICAL]->setVisible( FALSE ); - mScrollbar[VERTICAL]->setFollowsRight(); - mScrollbar[VERTICAL]->setFollowsTop(); - mScrollbar[VERTICAL]->setFollowsBottom(); LLRect horizontal_scroll_rect = mInnerRect; horizontal_scroll_rect.mTop = horizontal_scroll_rect.mBottom + scrollbar_size; @@ -131,11 +134,11 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p) sbparams.doc_pos(0); sbparams.page_size(mInnerRect.getWidth()); sbparams.step_size(VERTICAL_MULTIPLE); + sbparams.visible(false); + sbparams.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT); + sbparams.change_callback(p.scroll_callback); mScrollbar[HORIZONTAL] = LLUICtrlFactory::create<LLScrollbar> (sbparams); LLView::addChild( mScrollbar[HORIZONTAL] ); - mScrollbar[HORIZONTAL]->setVisible( FALSE ); - mScrollbar[HORIZONTAL]->setFollowsLeft(); - mScrollbar[HORIZONTAL]->setFollowsRight(); } // Destroys the object @@ -181,7 +184,7 @@ void LLScrollContainer::reshape(S32 width, S32 height, { LLUICtrl::reshape( width, height, called_from_parent ); - mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 ); + mInnerRect = getLocalRect(); mInnerRect.stretch( -mBorder->getBorderWidth() ); if (mScrolledView) @@ -192,13 +195,14 @@ void LLScrollContainer::reshape(S32 width, S32 height, S32 visible_height = 0; BOOL show_v_scrollbar = FALSE; BOOL show_h_scrollbar = FALSE; - calcVisibleSize( scrolled_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); + calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() ); mScrollbar[VERTICAL]->setPageSize( visible_height ); mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() ); mScrollbar[HORIZONTAL]->setPageSize( visible_width ); + updateScroll(); } } @@ -217,6 +221,7 @@ BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask) { if( mScrollbar[i]->handleKeyHere(key, mask) ) { + updateScroll(); return TRUE; } } @@ -233,6 +238,7 @@ BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks ) // Pretend the mouse is over the scrollbar if( mScrollbar[i]->handleScrollWheel( 0, 0, clicks ) ) { + updateScroll(); return TRUE; } } @@ -241,28 +247,6 @@ BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks ) return TRUE; } -BOOL LLScrollContainer::needsToScroll(S32 x, S32 y, LLScrollContainer::SCROLL_ORIENTATION axis) const -{ - if(mScrollbar[axis]->getVisible()) - { - LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 ); - const S32 AUTOSCROLL_SIZE = 10; - if(mScrollbar[axis]->getVisible()) - { - static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); - inner_rect_local.mRight -= scrollbar_size; - inner_rect_local.mTop += AUTOSCROLL_SIZE; - inner_rect_local.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE; - } - if( inner_rect_local.pointInRect( x, y ) && (mScrollbar[axis]->getDocPos() > 0) ) - { - return TRUE; - } - - } - return FALSE; -} - BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, @@ -273,12 +257,27 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); // Scroll folder view if needed. Never accepts a drag or drop. *accept = ACCEPT_NO; - BOOL handled = FALSE; + BOOL handled = autoScroll(x, y); + + if( !handled ) + { + handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, + cargo_data, accept, tooltip_msg) != NULL; + } + + return TRUE; +} + +bool LLScrollContainer::autoScroll(S32 x, S32 y) +{ + static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); + + bool scrolling = false; if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() ) { - const S32 AUTOSCROLL_SIZE = 10; - S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32()); - + LLRect screen_local_extents; + screenRectToLocal(getRootView()->getLocalRect(), &screen_local_extents); + LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 ); if( mScrollbar[HORIZONTAL]->getVisible() ) { @@ -289,65 +288,61 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, inner_rect_local.mRight -= scrollbar_size; } + // clip rect against root view + inner_rect_local.intersectWith(screen_local_extents); + + S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32()); + // autoscroll region should take up no more than one third of visible scroller area + S32 auto_scroll_region_width = llmin(inner_rect_local.getWidth() / 3, 10); + S32 auto_scroll_region_height = llmin(inner_rect_local.getHeight() / 3, 10); + if( mScrollbar[HORIZONTAL]->getVisible() ) { - LLRect left_scroll_rect = inner_rect_local; - left_scroll_rect.mRight = AUTOSCROLL_SIZE; + LLRect left_scroll_rect = screen_local_extents; + left_scroll_rect.mRight = inner_rect_local.mLeft + auto_scroll_region_width; if( left_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() > 0) ) { mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() - auto_scroll_speed ); mAutoScrolling = TRUE; - handled = TRUE; + scrolling = true; } - LLRect right_scroll_rect = inner_rect_local; - right_scroll_rect.mLeft = inner_rect_local.mRight - AUTOSCROLL_SIZE; + LLRect right_scroll_rect = screen_local_extents; + right_scroll_rect.mLeft = inner_rect_local.mRight - auto_scroll_region_width; if( right_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() < mScrollbar[HORIZONTAL]->getDocPosMax()) ) { mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() + auto_scroll_speed ); mAutoScrolling = TRUE; - handled = TRUE; + scrolling = true; } } if( mScrollbar[VERTICAL]->getVisible() ) { - LLRect bottom_scroll_rect = inner_rect_local; - bottom_scroll_rect.mTop = AUTOSCROLL_SIZE + bottom_scroll_rect.mBottom; + LLRect bottom_scroll_rect = screen_local_extents; + bottom_scroll_rect.mTop = inner_rect_local.mBottom + auto_scroll_region_height; if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() < mScrollbar[VERTICAL]->getDocPosMax()) ) { mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() + auto_scroll_speed ); mAutoScrolling = TRUE; - handled = TRUE; + scrolling = true; } - LLRect top_scroll_rect = inner_rect_local; - top_scroll_rect.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE; + LLRect top_scroll_rect = screen_local_extents; + top_scroll_rect.mBottom = inner_rect_local.mTop - auto_scroll_region_height; if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() > 0) ) { mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() - auto_scroll_speed ); mAutoScrolling = TRUE; - handled = TRUE; + scrolling = true; } } } - - if( !handled ) - { - handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, - cargo_data, accept, tooltip_msg) != NULL; - } - - return TRUE; + return scrolling; } void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const { - const LLRect& rect = getScrolledViewRect(); - calcVisibleSize(rect, visible_width, visible_height, show_h_scrollbar, show_v_scrollbar); -} - -void LLScrollContainer::calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const -{ + const LLRect& doc_rect = getScrolledViewRect(); static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); S32 doc_width = doc_rect.getWidth(); S32 doc_height = doc_rect.getHeight(); @@ -384,20 +379,20 @@ void LLScrollContainer::draw() if (mAutoScrolling) { // add acceleration to autoscroll - mAutoScrollRate = llmin(mAutoScrollRate + (LLFrameTimer::getFrameDeltaTimeF32() * AUTO_SCROLL_RATE_ACCEL), MAX_AUTO_SCROLL_RATE); + mAutoScrollRate = llmin(mAutoScrollRate + (LLFrameTimer::getFrameDeltaTimeF32() * AUTO_SCROLL_RATE_ACCEL), mMaxAutoScrollRate); } else { - // reset to minimum - mAutoScrollRate = MIN_AUTO_SCROLL_RATE; + // reset to minimum for next time + mAutoScrollRate = mMinAutoScrollRate; } - // clear this flag to be set on next call to handleDragAndDrop + // clear this flag to be set on next call to autoScroll mAutoScrolling = FALSE; // auto-focus when scrollbar active // this allows us to capture user intent (i.e. stop automatically scrolling the view/etc) - if (!gFocusMgr.childHasKeyboardFocus(this) && - (mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture())) + if (!hasFocus() + && (mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture())) { focusFirstItem(); } @@ -424,7 +419,7 @@ void LLScrollContainer::draw() S32 visible_height = 0; BOOL show_v_scrollbar = FALSE; BOOL show_h_scrollbar = FALSE; - calcVisibleSize( mScrolledView->getRect(), &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); + calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); LLLocalClipRect clip(LLRect(mInnerRect.mLeft, mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) + visible_height, @@ -506,7 +501,7 @@ void LLScrollContainer::updateScroll() S32 visible_height = 0; BOOL show_v_scrollbar = FALSE; BOOL show_h_scrollbar = FALSE; - calcVisibleSize( doc_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); + calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); S32 border_width = mBorder->getBorderWidth(); if( show_v_scrollbar ) @@ -584,71 +579,73 @@ void LLScrollContainer::setBorderVisible(BOOL b) mBorder->setVisible( b ); } -// Scroll so that as much of rect as possible is showing (where rect is defined in the space of scroller view, not scrolled) -void LLScrollContainer::scrollToShowRect(const LLRect& rect, const LLCoordGL& desired_offset) +LLRect LLScrollContainer::getVisibleContentRect() { - if (!mScrolledView) - { - llwarns << "LLScrollContainer::scrollToShowRect with no view!" << llendl; - return; - } + updateScroll(); + LLRect visible_rect = getContentWindowRect(); + LLRect contents_rect = mScrolledView->getRect(); + visible_rect.translate(-contents_rect.mLeft, -contents_rect.mBottom); + return visible_rect; +} +LLRect LLScrollContainer::getContentWindowRect() const +{ + LLRect scroller_view_rect; S32 visible_width = 0; S32 visible_height = 0; - BOOL show_v_scrollbar = FALSE; BOOL show_h_scrollbar = FALSE; - const LLRect& scrolled_rect = mScrolledView->getRect(); - calcVisibleSize( scrolled_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); - - // can't be so far left that right side of rect goes off screen, or so far right that left side does - S32 horiz_offset = llclamp(desired_offset.mX, llmin(0, -visible_width + rect.getWidth()), 0); - // can't be so high that bottom of rect goes off screen, or so low that top does - S32 vert_offset = llclamp(desired_offset.mY, 0, llmax(0, visible_height - rect.getHeight())); - - // Vertical - // 1. First make sure the top is visible - // 2. Then, if possible without hiding the top, make the bottom visible. - S32 vert_pos = mScrollbar[VERTICAL]->getDocPos(); - - // find scrollbar position to get top of rect on screen (scrolling up) - S32 top_offset = scrolled_rect.mTop - rect.mTop - vert_offset; - // find scrollbar position to get bottom of rect on screen (scrolling down) - S32 bottom_offset = vert_offset == 0 ? scrolled_rect.mTop - rect.mBottom - visible_height : top_offset; - // scroll up far enough to see top or scroll down just enough if item is bigger than visual area - if( vert_pos >= top_offset || visible_height < rect.getHeight()) - { - vert_pos = top_offset; - } - // else scroll down far enough to see bottom - else - if( vert_pos <= bottom_offset ) + BOOL show_v_scrollbar = FALSE; + calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar ); + S32 border_width = mBorder->getBorderWidth(); + scroller_view_rect.setOriginAndSize(border_width, + show_h_scrollbar ? mScrollbar[HORIZONTAL]->getRect().mTop : border_width, + visible_width, + visible_height); + return scroller_view_rect; +} + +// rect is in document coordinates, constraint is in display coordinates relative to content window rect +void LLScrollContainer::scrollToShowRect(const LLRect& rect, const LLRect& constraint) +{ + if (!mScrolledView) { - vert_pos = bottom_offset; + llwarns << "LLScrollContainer::scrollToShowRect with no view!" << llendl; + return; } + LLRect content_window_rect = getContentWindowRect(); + // get document rect + LLRect scrolled_rect = mScrolledView->getRect(); + + // shrink target rect to fit within constraint region, biasing towards top left + LLRect rect_to_constrain = rect; + rect_to_constrain.mBottom = llmax(rect_to_constrain.mBottom, rect_to_constrain.mTop - constraint.getHeight()); + rect_to_constrain.mRight = llmin(rect_to_constrain.mRight, rect_to_constrain.mLeft + constraint.getWidth()); + + // calculate allowable positions for scroller window in document coordinates + LLRect allowable_scroll_rect(rect_to_constrain.mRight - constraint.mRight, + rect_to_constrain.mBottom - constraint.mBottom, + rect_to_constrain.mLeft - constraint.mLeft, + rect_to_constrain.mTop - constraint.mTop); + + // translate from allowable region for lower left corner to upper left corner + allowable_scroll_rect.translate(0, content_window_rect.getHeight()); + + S32 vert_pos = llclamp(mScrollbar[VERTICAL]->getDocPos(), + mScrollbar[VERTICAL]->getDocSize() - allowable_scroll_rect.mTop, // min vertical scroll + mScrollbar[VERTICAL]->getDocSize() - allowable_scroll_rect.mBottom); // max vertical scroll + mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() ); - mScrollbar[VERTICAL]->setPageSize( visible_height ); + mScrollbar[VERTICAL]->setPageSize( content_window_rect.getHeight() ); mScrollbar[VERTICAL]->setDocPos( vert_pos ); - // Horizontal - // 1. First make sure left side is visible - // 2. Then, if possible without hiding the left side, make the right side visible. - S32 horiz_pos = mScrollbar[HORIZONTAL]->getDocPos(); - S32 left_offset = rect.mLeft - scrolled_rect.mLeft + horiz_offset; - S32 right_offset = horiz_offset == 0 ? rect.mRight - scrolled_rect.mLeft - visible_width : left_offset; + S32 horizontal_pos = llclamp(mScrollbar[HORIZONTAL]->getDocPos(), + allowable_scroll_rect.mLeft, + allowable_scroll_rect.mRight); - if( horiz_pos >= left_offset || visible_width < rect.getWidth() ) - { - horiz_pos = left_offset; - } - else if( horiz_pos <= right_offset ) - { - horiz_pos = right_offset; - } - mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() ); - mScrollbar[HORIZONTAL]->setPageSize( visible_width ); - mScrollbar[HORIZONTAL]->setDocPos( horiz_pos ); + mScrollbar[HORIZONTAL]->setPageSize( content_window_rect.getWidth() ); + mScrollbar[HORIZONTAL]->setDocPos( horizontal_pos ); // propagate scroll to document updateScroll(); @@ -657,21 +654,25 @@ void LLScrollContainer::scrollToShowRect(const LLRect& rect, const LLCoordGL& de void LLScrollContainer::pageUp(S32 overlap) { mScrollbar[VERTICAL]->pageUp(overlap); + updateScroll(); } void LLScrollContainer::pageDown(S32 overlap) { mScrollbar[VERTICAL]->pageDown(overlap); + updateScroll(); } void LLScrollContainer::goToTop() { mScrollbar[VERTICAL]->setDocPos(0); + updateScroll(); } void LLScrollContainer::goToBottom() { mScrollbar[VERTICAL]->setDocPos(mScrollbar[VERTICAL]->getDocSize()); + updateScroll(); } S32 LLScrollContainer::getBorderWidth() const diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index 912d126f233db0221aab292beb5cebb4b6a0536b..8385bca02fb0ad61757c86d343fae54c5c86f3cb 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -66,9 +66,13 @@ class LLScrollContainer : public LLUICtrl struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> { - Optional<bool> is_opaque; + Optional<bool> is_opaque, + reserve_scroll_corner, + border_visible; + Optional<F32> min_auto_scroll_rate, + max_auto_scroll_rate; Optional<LLUIColor> bg_color; - Optional<bool> reserve_scroll_corner; + Optional<LLScrollbar::callback_t> scroll_callback; Params(); }; @@ -84,21 +88,23 @@ class LLScrollContainer : public LLUICtrl virtual void setValue(const LLSD& value) { mInnerRect.setValue(value); } - void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const; - void calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const; void setBorderVisible( BOOL b ); - void scrollToShowRect( const LLRect& rect, const LLCoordGL& desired_offset ); + void scrollToShowRect( const LLRect& rect, const LLRect& constraint); + void scrollToShowRect( const LLRect& rect) { scrollToShowRect(rect, LLRect(0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0)); } + void setReserveScrollCorner( BOOL b ) { mReserveScrollCorner = b; } + LLRect getVisibleContentRect(); + LLRect getContentWindowRect() const; const LLRect& getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; } void pageUp(S32 overlap = 0); void pageDown(S32 overlap = 0); void goToTop(); void goToBottom(); + bool isAtTop() { return mScrollbar[VERTICAL]->isAtBeginning(); } + bool isAtBottom() { return mScrollbar[VERTICAL]->isAtEnd(); } S32 getBorderWidth() const; - BOOL needsToScroll(S32 x, S32 y, SCROLL_ORIENTATION axis) const; - // LLView functionality virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); virtual BOOL handleKeyHere(KEY key, MASK mask); @@ -111,12 +117,15 @@ class LLScrollContainer : public LLUICtrl virtual void draw(); virtual bool addChild(LLView* view, S32 tab_group = 0); + + bool autoScroll(S32 x, S32 y); private: // internal scrollbar handlers virtual void scrollHorizontal( S32 new_pos ); virtual void scrollVertical( S32 new_pos ); void updateScroll(); + void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const; LLScrollbar* mScrollbar[SCROLLBAR_COUNT]; LLView* mScrolledView; @@ -128,6 +137,8 @@ class LLScrollContainer : public LLUICtrl BOOL mReserveScrollCorner; BOOL mAutoScrolling; F32 mAutoScrollRate; + F32 mMinAutoScrollRate; + F32 mMaxAutoScrollRate; }; diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index cd43e194d299ebb436f8531c37f2d57289582f3d..e28da91305d16232e72bf2e4aa4d5b8b8cce15b7 100644 --- a/indra/llui/llscrolllistcell.cpp +++ b/indra/llui/llscrolllistcell.cpp @@ -310,17 +310,16 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col break; } mFont->render(mText.getWString(), 0, - start_x, 2.f, - display_color, - mFontAlignment, - LLFontGL::BOTTOM, - 0, - LLFontGL::NO_SHADOW, - string_chars, - getWidth(), - &right_x, - FALSE, - TRUE); + start_x, 2.f, + display_color, + mFontAlignment, + LLFontGL::BOTTOM, + 0, + LLFontGL::NO_SHADOW, + string_chars, + getWidth(), + &right_x, + TRUE); } // diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 3041773fb22f86c3667735e326fc0d9a02b567a8..637642cdcd1f5df0e9cebd8bc617be4ba96d4f04 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -160,7 +160,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mNumDynamicWidthColumns(0), mTotalStaticColumnWidth(0), mTotalColumnPadding(0), - mSorted(FALSE), + mSorted(false), mDirty(FALSE), mOriginalSelection(-1), mLastSelected(NULL), @@ -374,6 +374,10 @@ std::vector<LLScrollListItem*> LLScrollListCtrl::getAllSelected() const S32 LLScrollListCtrl::getFirstSelectedIndex() const { S32 CurSelectedIndex = 0; + + // make sure sort is up to date before returning an index + updateSort(); + item_list::const_iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { @@ -507,7 +511,7 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r { case ADD_TOP: mItemList.push_front(item); - setSorted(FALSE); + setNeedsSort(); break; case ADD_SORTED: @@ -524,18 +528,18 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r // ADD_SORTED just sorts by first column... // this might not match user sort criteria, so flag list as being in unsorted state - setSorted(FALSE); + setNeedsSort(); break; } case ADD_BOTTOM: mItemList.push_back(item); - setSorted(FALSE); + setNeedsSort(); break; default: llassert(0); mItemList.push_back(item); - setSorted(FALSE); + setNeedsSort(); break; } @@ -759,6 +763,9 @@ BOOL LLScrollListCtrl::selectItemRange( S32 first_index, S32 last_index ) return FALSE; } + // make sure sort is up to date + updateSort(); + S32 listlen = (S32)mItemList.size(); first_index = llclamp(first_index, 0, listlen-1); @@ -812,6 +819,7 @@ void LLScrollListCtrl::swapWithNext(S32 index) // At end of list, doesn't do anything return; } + updateSort(); LLScrollListItem *cur_itemp = mItemList[index]; mItemList[index] = mItemList[index + 1]; mItemList[index + 1] = cur_itemp; @@ -825,6 +833,7 @@ void LLScrollListCtrl::swapWithPrevious(S32 index) // At beginning of list, don't do anything } + updateSort(); LLScrollListItem *cur_itemp = mItemList[index]; mItemList[index] = mItemList[index - 1]; mItemList[index - 1] = cur_itemp; @@ -838,6 +847,8 @@ void LLScrollListCtrl::deleteSingleItem(S32 target_index) return; } + updateSort(); + LLScrollListItem *itemp; itemp = mItemList[target_index]; if (itemp == mLastSelected) @@ -939,6 +950,8 @@ S32 LLScrollListCtrl::selectMultiple( std::vector<LLUUID> ids ) S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) const { + updateSort(); + S32 index = 0; item_list::const_iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) @@ -955,6 +968,8 @@ S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) const S32 LLScrollListCtrl::getItemIndex( const LLUUID& target_id ) const { + updateSort(); + S32 index = 0; item_list::const_iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) @@ -980,6 +995,8 @@ void LLScrollListCtrl::selectPrevItem( BOOL extend_selection) } else { + updateSort(); + item_list::iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { @@ -1022,6 +1039,8 @@ void LLScrollListCtrl::selectNextItem( BOOL extend_selection) } else { + updateSort(); + item_list::reverse_iterator iter; for (iter = mItemList.rbegin(); iter != mItemList.rend(); iter++) { @@ -1436,7 +1455,7 @@ void LLScrollListCtrl::draw() LLLocalClipRect clip(getLocalRect()); // if user specifies sort, make sure it is maintained - sortItems(); + updateSort(); if (mNeedsScroll) { @@ -1463,7 +1482,7 @@ void LLScrollListCtrl::draw() if (mBorder) { - mBorder->setKeyboardFocusHighlight(gFocusMgr.getKeyboardFocus() == this); + mBorder->setKeyboardFocusHighlight(hasFocus()); } LLUICtrl::draw(); @@ -1754,6 +1773,8 @@ LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y ) // Excludes disabled items. LLScrollListItem* hit_item = NULL; + updateSort(); + LLRect item_rect; item_rect.setLeftTopAndSize( mItemListRect.mLeft, @@ -2199,7 +2220,7 @@ BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending) sort_column_t new_sort_column(column_idx, ascending); - setSorted(FALSE); + setNeedsSort(); if (mSortColumns.empty()) { @@ -2241,10 +2262,10 @@ void LLScrollListCtrl::sortByColumn(const std::string& name, BOOL ascending) void LLScrollListCtrl::sortByColumnIndex(U32 column, BOOL ascending) { setSort(column, ascending); - sortItems(); + updateSort(); } -void LLScrollListCtrl::sortItems() +void LLScrollListCtrl::updateSort() const { if (hasSortOrder() && !isSorted()) { @@ -2254,7 +2275,7 @@ void LLScrollListCtrl::sortItems() mItemList.end(), SortScrollListItem(mSortColumns)); - setSorted(TRUE); + mSorted = true; } } @@ -2311,7 +2332,7 @@ void LLScrollListCtrl::scrollToShowSelected() return; } - sortItems(); + updateSort(); S32 index = getFirstSelectedIndex(); if (index < 0) @@ -2552,7 +2573,7 @@ std::string LLScrollListCtrl::getSortColumnName() else return ""; } -BOOL LLScrollListCtrl::hasSortOrder() +BOOL LLScrollListCtrl::hasSortOrder() const { return !mSortColumns.empty(); } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index e699711bd4589f6c61aa8e3a02a9232c80c45644..253a58ab73226438c95c8de7520fd04a8c71a5b5 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -329,15 +329,16 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, std::string getSortColumnName(); BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; } - BOOL hasSortOrder(); + BOOL hasSortOrder() const; S32 selectMultiple( std::vector<LLUUID> ids ); - void sortItems(); + // conceptually const, but mutates mItemList + void updateSort() const; // sorts a list without affecting the permanent sort order (so further list insertions can be unsorted, for example) void sortOnce(S32 column, BOOL ascending); // manually call this whenever editing list items in place to flag need for resorting - void setSorted(BOOL sorted) { mSorted = sorted; } + void setNeedsSort() { mSorted = false; } void dirtyColumns(); // some operation has potentially affected column layout or ordering protected: @@ -390,7 +391,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, const BOOL mDisplayColumnHeaders; BOOL mColumnsDirty; - item_list mItemList; + mutable item_list mItemList; LLScrollListItem *mLastSelected; @@ -429,7 +430,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, S32 mTotalStaticColumnWidth; S32 mTotalColumnPadding; - BOOL mSorted; + mutable bool mSorted; typedef std::map<std::string, LLScrollListColumn> column_map_t; column_map_t mColumns; diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp index 432d54dfee7f4f34c4b9e5fc51485610f43e2219..929a809d88ed518b0e59912173680cc651afbd5f 100644 --- a/indra/llui/llstyle.cpp +++ b/indra/llui/llstyle.cpp @@ -38,119 +38,34 @@ #include "llstring.h" #include "llui.h" - -LLStyle::LLStyle() -{ - init(TRUE, LLColor4(0,0,0,1),LLStringUtil::null); -} - -LLStyle::LLStyle(const LLStyle &style) -{ - if (this != &style) - { - init(style.isVisible(),style.getColor(),style.getFontString()); - if (style.isLink()) - { - setLinkHREF(style.getLinkHREF()); - } - mItalic = style.mItalic; - mBold = style.mBold; - mUnderline = style.mUnderline; - mDropShadow = style.mDropShadow; - mImageHeight = style.mImageHeight; - mImageWidth = style.mImageWidth; - mImagep = style.mImagep; - mIsEmbeddedItem = style.mIsEmbeddedItem; - } - else - { - init(TRUE, LLColor4(0,0,0,1),LLStringUtil::null); - } -} - -LLStyle::LLStyle(BOOL is_visible, const LLColor4 &color, const std::string& font_name) -{ - init(is_visible, color, font_name); -} - -void LLStyle::init(BOOL is_visible, const LLColor4 &color, const std::string& font_name) +LLStyle::Params::Params() +: visible("visible", true), + drop_shadow("drop_shadow", false), + color("color", LLColor4::black), + font("font", LLFontGL::getFontMonospace()), + image("image"), + link_href("href") +{} + + +LLStyle::LLStyle(const LLStyle::Params& p) +: mVisible(p.visible), + mColor(p.color()), + mFont(p.font()), + mLink(p.link_href), + mDropShadow(p.drop_shadow), + mImageHeight(0), + mImageWidth(0), + mImagep(p.image()) +{} + +void LLStyle::setFont(const LLFontGL* font) { - mVisible = is_visible; - mColor = color; - setFontName(font_name); - setLinkHREF(LLStringUtil::null); - mItalic = FALSE; - mBold = FALSE; - mUnderline = FALSE; - mDropShadow = FALSE; - mImageHeight = 0; - mImageWidth = 0; - mIsEmbeddedItem = FALSE; -} - - -// Copy assignment -LLStyle &LLStyle::operator=(const LLStyle &rhs) -{ - if (this != &rhs) - { - setVisible(rhs.isVisible()); - setColor(rhs.getColor()); - this->mFontName = rhs.getFontString(); - this->mLink = rhs.getLinkHREF(); - mImagep = rhs.mImagep; - mImageHeight = rhs.mImageHeight; - mImageWidth = rhs.mImageWidth; - mItalic = rhs.mItalic; - mBold = rhs.mBold; - mUnderline = rhs.mUnderline; - mDropShadow = rhs.mDropShadow; - mIsEmbeddedItem = rhs.mIsEmbeddedItem; - } - - return *this; + mFont = font; } -//virtual -const std::string& LLStyle::getFontString() const -{ - return mFontName; -} - -//virtual -void LLStyle::setFontName(const std::string& fontname) -{ - mFontName = fontname; - - std::string fontname_lc = fontname; - LLStringUtil::toLower(fontname_lc); - - // cache the font pointer for speed when rendering text - if ((fontname_lc == "sansserif") || (fontname_lc == "sans-serif")) - { - mFont = LLFontGL::getFontSansSerif(); - } - else if ((fontname_lc == "serif")) - { - // *TODO: Do we have a real serif font? - mFont = LLFontGL::getFontMonospace(); - } - else if ((fontname_lc == "sansserifbig")) - { - mFont = LLFontGL::getFontSansSerifBig(); - } - else if (fontname_lc == "small") - { - mFont = LLFontGL::getFontSansSerifSmall(); - } - else - { - mFont = LLFontGL::getFontMonospace(); - } -} -//virtual -LLFontGL* LLStyle::getFont() const +const LLFontGL* LLStyle::getFont() const { return mFont; } diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h index 32ddded2c8666fdbf19d191609207bc4d4e5f53e..dcf274a651346234537bf5a31612dc3b1c72a31d 100644 --- a/indra/llui/llstyle.h +++ b/indra/llui/llstyle.h @@ -35,59 +35,59 @@ #include "v4color.h" #include "llui.h" +#include "llinitparam.h" class LLFontGL; class LLStyle : public LLRefCount { public: - LLStyle(); - LLStyle(const LLStyle &style); - LLStyle(BOOL is_visible, const LLColor4 &color, const std::string& font_name); - - LLStyle &operator=(const LLStyle &rhs); - - virtual void init (BOOL is_visible, const LLColor4 &color, const std::string& font_name); - - virtual const LLColor4& getColor() const { return mColor; } - virtual void setColor(const LLColor4 &color) { mColor = color; } - - virtual BOOL isVisible() const; - virtual void setVisible(BOOL is_visible); + struct Params : public LLInitParam::Block<Params> + { + Optional<bool> visible, + drop_shadow; + Optional<LLUIColor> color; + Optional<const LLFontGL*> font; + Optional<LLUIImage*> image; + Optional<std::string> link_href; + Params(); + }; + LLStyle(const Params& p = Params()); +public: + const LLColor4& getColor() const { return mColor; } + void setColor(const LLColor4 &color) { mColor = color; } - virtual const std::string& getFontString() const; - virtual void setFontName(const std::string& fontname); - virtual LLFontGL* getFont() const; + BOOL isVisible() const; + void setVisible(BOOL is_visible); - virtual const std::string& getLinkHREF() const { return mLink; } - virtual void setLinkHREF(const std::string& href); - virtual BOOL isLink() const; + void setFont(const LLFontGL* font); + const LLFontGL* getFont() const; - virtual LLUIImagePtr getImage() const; - virtual void setImage(const LLUUID& src); + const std::string& getLinkHREF() const { return mLink; } + void setLinkHREF(const std::string& href); + BOOL isLink() const; - virtual BOOL isImage() const { return ((mImageWidth != 0) && (mImageHeight != 0)); } - virtual void setImageSize(S32 width, S32 height); + LLUIImagePtr getImage() const; + void setImage(const LLUUID& src); - BOOL getIsEmbeddedItem() const { return mIsEmbeddedItem; } - void setIsEmbeddedItem( BOOL b ) { mIsEmbeddedItem = b; } + BOOL isImage() const { return ((mImageWidth != 0) && (mImageHeight != 0)); } + void setImageSize(S32 width, S32 height); // inlined here to make it easier to compare to member data below. -MG bool operator==(const LLStyle &rhs) const { return - mVisible == rhs.isVisible() - && mColor == rhs.getColor() - && mFontName == rhs.getFontString() - && mLink == rhs.getLinkHREF() + mVisible == rhs.mVisible + && mColor == rhs.mColor + && mFont == rhs.mFont + && mLink == rhs.mLink && mImagep == rhs.mImagep && mImageHeight == rhs.mImageHeight && mImageWidth == rhs.mImageWidth && mItalic == rhs.mItalic && mBold == rhs.mBold && mUnderline == rhs.mUnderline - && mDropShadow == rhs.mDropShadow - && mIsEmbeddedItem == rhs.mIsEmbeddedItem; + && mDropShadow == rhs.mDropShadow; } bool operator!=(const LLStyle& rhs) const { return !(*this == rhs); } @@ -101,16 +101,15 @@ class LLStyle : public LLRefCount S32 mImageHeight; protected: - virtual ~LLStyle() { } + ~LLStyle() { } private: BOOL mVisible; LLUIColor mColor; std::string mFontName; - LLFontGL* mFont; // cached for performance + const LLFontGL* mFont; // cached for performance std::string mLink; LLUIImagePtr mImagep; - BOOL mIsEmbeddedItem; }; typedef LLPointer<LLStyle> LLStyleSP; diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 29c30004ef3bced313c063b70b94c2abc9db3bc2..ee3631810789f56ee80711f9ac82a21c41a912a1 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -190,7 +190,7 @@ void LLTabContainer::reshape(S32 width, S32 height, BOOL called_from_parent) } //virtual -LLView* LLTabContainer::getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const +LLView* LLTabContainer::getChildView(const std::string& name, BOOL recurse) const { tuple_list_t::const_iterator itor; for (itor = mTabList.begin(); itor != mTabList.end(); ++itor) @@ -207,14 +207,42 @@ LLView* LLTabContainer::getChildView(const std::string& name, BOOL recurse, BOOL for (itor = mTabList.begin(); itor != mTabList.end(); ++itor) { LLPanel *panel = (*itor)->mTabPanel; - LLView *child = panel->getChildView(name, recurse, FALSE); + LLView *child = panel->getChildView(name, recurse); if (child) { return child; } } } - return LLView::getChildView(name, recurse, create_if_missing); + return LLView::getChildView(name, recurse); +} + +//virtual +LLView* LLTabContainer::findChildView(const std::string& name, BOOL recurse) const +{ + tuple_list_t::const_iterator itor; + for (itor = mTabList.begin(); itor != mTabList.end(); ++itor) + { + LLPanel *panel = (*itor)->mTabPanel; + if (panel->getName() == name) + { + return panel; + } + } + + if (recurse) + { + for (itor = mTabList.begin(); itor != mTabList.end(); ++itor) + { + LLPanel *panel = (*itor)->mTabPanel; + LLView *child = panel->findChildView(name, recurse); + if (child) + { + return child; + } + } + } + return LLView::findChildView(name, recurse); } bool LLTabContainer::addChild(LLView* view, S32 tab_group) @@ -457,7 +485,7 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask ) index = llclamp(index, 0, tab_count-1); LLButton* tab_button = getTab(index)->mButton; gFocusMgr.setMouseCapture(this); - gFocusMgr.setKeyboardFocus(tab_button); + tab_button->setFocus(TRUE); } } return handled; diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index 78592a0f9a2f8b34d2b1909a624ce5023fd2f98b..ebe76af9668e4e88542506dda9718b5b3fb0a83b 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -104,7 +104,8 @@ class LLTabContainer : public LLPanel /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType type, void* cargo_data, EAcceptance* accept, std::string& tooltip); - /*virtual*/ LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const; + /*virtual*/ LLView* getChildView(const std::string& name, BOOL recurse = TRUE) const; + /*virtual*/ LLView* findChildView(const std::string& name, BOOL recurse = TRUE) const; /*virtual*/ void initFromParams(const LLPanel::Params& p); /*virtual*/ bool addChild(LLView* view, S32 tab_group = 0); /*virtual*/ BOOL postBuild(); diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index f9bcb685b89328dba9ca9ae22f9581ec1470f2ec..96e72487b85d8af9575a9760cba7a3898ca5f80f 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -389,7 +389,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) mHAlign, mVAlign, 0, mShadowType, - S32_MAX, getRect().getWidth(), NULL, TRUE, mUseEllipses); + S32_MAX, getRect().getWidth(), NULL, mUseEllipses); } else { @@ -402,7 +402,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) mHAlign, mVAlign, 0, mShadowType, - line_length, getRect().getWidth(), NULL, TRUE, mUseEllipses ); + line_length, getRect().getWidth(), NULL, mUseEllipses ); cur_pos += line_length + 1; y -= llfloor(mFontGL->getLineHeight()) + mLineSpacing; } diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 48816e4b9e5136fac9093b6ae9c306715ae054af..7d13220c94778b2d4aec529d1f648dddc820a755 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -58,7 +58,10 @@ #include "llcontrol.h" #include "llwindow.h" #include "lltextparser.h" +#include "llscrollcontainer.h" +#include "llpanel.h" #include <queue> +#include "llcombobox.h" // // Globals @@ -75,19 +78,73 @@ const S32 CURSOR_THICKNESS = 2; const S32 SPACES_PER_TAB = 4; -LLUIColor LLTextEditor::mLinkColor = LLColor4::blue; -void (* LLTextEditor::mURLcallback)(const std::string&) = NULL; -bool (* LLTextEditor::mSecondlifeURLcallback)(const std::string&) = NULL; -bool (* LLTextEditor::mSecondlifeURLcallbackRightClick)(const std::string&) = NULL; +void (* LLTextEditor::sURLcallback)(const std::string&) = NULL; +bool (* LLTextEditor::sSecondlifeURLcallback)(const std::string&) = NULL; +bool (* LLTextEditor::sSecondlifeURLcallbackRightClick)(const std::string&) = NULL; +// helper functors +struct LLTextEditor::compare_bottom +{ + bool operator()(const S32& a, const LLTextEditor::line_info& b) const + { + return a > b.mBottom; // bottom of a is higher than bottom of b + } + + bool operator()(const LLTextEditor::line_info& a, const S32& b) const + { + return a.mBottom > b; // bottom of a is higher than bottom of b + } +}; + +// helper functors +struct LLTextEditor::compare_top +{ + bool operator()(const S32& a, const LLTextEditor::line_info& b) const + { + return a > b.mTop; // top of a is higher than top of b + } + + bool operator()(const LLTextEditor::line_info& a, const S32& b) const + { + return a.mTop > b; // top of a is higher than top of b + } +}; + +struct LLTextEditor::line_end_compare +{ + bool operator()(const S32& pos, const LLTextEditor::line_info& info) const + { + return (pos < info.mDocIndexEnd); + } + + bool operator()(const LLTextEditor::line_info& info, const S32& pos) const + { + return (info.mDocIndexEnd < pos); + } + +}; + +// +// DocumentPanel +// + +class DocumentPanel : public LLPanel +{ +public: + DocumentPanel(const Params&); +}; + +DocumentPanel::DocumentPanel(const Params& p) +: LLPanel(p) +{} /////////////////////////////////////////////////////////////////// class LLTextEditor::LLTextCmdInsert : public LLTextEditor::LLTextCmd { public: - LLTextCmdInsert(S32 pos, BOOL group_with_next, const LLWString &ws) - : LLTextCmd(pos, group_with_next), mWString(ws) + LLTextCmdInsert(S32 pos, BOOL group_with_next, const LLWString &ws, LLTextSegmentPtr segment) + : LLTextCmd(pos, group_with_next, segment), mWString(ws) { } virtual ~LLTextCmdInsert() {} @@ -117,8 +174,8 @@ class LLTextEditor::LLTextCmdInsert : public LLTextEditor::LLTextCmd class LLTextEditor::LLTextCmdAddChar : public LLTextEditor::LLTextCmd { public: - LLTextCmdAddChar( S32 pos, BOOL group_with_next, llwchar wc) - : LLTextCmd(pos, group_with_next), mWString(1, wc), mBlockExtensions(FALSE) + LLTextCmdAddChar( S32 pos, BOOL group_with_next, llwchar wc, LLTextSegmentPtr segment) + : LLTextCmd(pos, group_with_next, segment), mWString(1, wc), mBlockExtensions(FALSE) { } virtual void blockExtensions() @@ -127,6 +184,9 @@ class LLTextEditor::LLTextCmdAddChar : public LLTextEditor::LLTextCmd } virtual BOOL canExtend(S32 pos) const { + // cannot extend text with custom segments + if (!mSegments.empty()) return FALSE; + return !mBlockExtensions && (pos == getPosition() + (S32)mWString.length()); } virtual BOOL execute( LLTextEditor* editor, S32* delta ) @@ -201,9 +261,10 @@ class LLTextEditor::LLTextCmdOverwriteChar : public LLTextEditor::LLTextCmd class LLTextEditor::LLTextCmdRemove : public LLTextEditor::LLTextCmd { public: - LLTextCmdRemove( S32 pos, BOOL group_with_next, S32 len ) : + LLTextCmdRemove( S32 pos, BOOL group_with_next, S32 len, segment_vec_t& segments ) : LLTextCmd(pos, group_with_next), mLen(len) { + std::swap(mSegments, segments); } virtual BOOL execute( LLTextEditor* editor, S32* delta ) { @@ -213,7 +274,7 @@ class LLTextEditor::LLTextCmdRemove : public LLTextEditor::LLTextCmd } virtual S32 undo( LLTextEditor* editor ) { - insert(editor, getPosition(), mWString ); + insert(editor, getPosition(), mWString); return getPosition() + mWString.length(); } virtual S32 redo( LLTextEditor* editor ) @@ -233,12 +294,13 @@ LLTextEditor::Params::Params() max_text_length("max_length", 255), read_only("read_only", false), embedded_items("embedded_items", false), - hide_scrollbar("hide_scrollbar", false), + hide_scrollbar("hide_scrollbar"), hide_border("hide_border", false), word_wrap("word_wrap", false), ignore_tab("ignore_tab", true), track_bottom("track_bottom", false), - takes_non_scroll_clicks("takes_non_scroll_clicks", true), + handle_edit_keys_directly("handle_edit_keys_directly", false), + show_line_numbers("show_line_numbers", false), cursor_color("cursor_color"), default_color("default_color"), text_color("text_color"), @@ -246,6 +308,8 @@ LLTextEditor::Params::Params() bg_readonly_color("bg_readonly_color"), bg_writeable_color("bg_writeable_color"), bg_focus_color("bg_focus_color"), + link_color("link_color"), + commit_on_focus_lost("commit_on_focus_lost", false), length("length"), // ignored type("type"), // ignored is_unicode("is_unicode")// ignored @@ -261,8 +325,6 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) mIsSelecting( FALSE ), mSelectionStart( 0 ), mSelectionEnd( 0 ), - mScrolledToBottom( TRUE ), - mOnScrollEndCallback( NULL ), mOnScrollEndData( NULL ), mCursorColor( p.cursor_color() ), mFgColor( p.text_color() ), @@ -271,15 +333,14 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) mWriteableBgColor( p.bg_writeable_color() ), mReadOnlyBgColor( p.bg_readonly_color() ), mFocusBgColor( p.bg_focus_color() ), + mLinkColor( p.link_color() ), mReadOnly(p.read_only), mWordWrap( p.word_wrap ), - mShowLineNumbers ( FALSE ), - mCommitOnFocusLost( FALSE ), - mHideScrollbarForShortDocs( FALSE ), - mTakesNonScrollClicks( p.takes_non_scroll_clicks ), + mShowLineNumbers ( p.show_line_numbers ), + mCommitOnFocusLost( p.commit_on_focus_lost), mTrackBottom( p.track_bottom ), mAllowEmbeddedItems( p.embedded_items ), - mHandleEditKeysDirectly( FALSE ), + mHandleEditKeysDirectly( p.handle_edit_keys_directly ), mMouseDownX(0), mMouseDownY(0), mLastSelectionX(-1), @@ -289,7 +350,8 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) mParseHTML(FALSE), mParseHighlights(FALSE), mTabsToNextField(p.ignore_tab), - mGLFont(p.font) + mDefaultFont(p.font), + mScrollIndex(-1) { static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); @@ -298,44 +360,42 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) // reset desired x cursor position mDesiredXPixel = -1; - updateTextRect(); + LLScrollContainer::Params scroll_params; + scroll_params.name = "text scroller"; + scroll_params.rect = getLocalRect(); + scroll_params.follows.flags = FOLLOWS_ALL; + scroll_params.is_opaque = false; + scroll_params.mouse_opaque = false; + scroll_params.min_auto_scroll_rate = 200; + scroll_params.max_auto_scroll_rate = 800; + mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroll_params); + addChild(mScroller); + + LLPanel::Params panel_params; + panel_params.name = "text_contents"; + panel_params.rect = LLRect(0, 500, 500, 0); + panel_params.background_visible = true; + panel_params.background_opaque = true; + panel_params.mouse_opaque = false; + + mDocumentPanel = LLUICtrlFactory::create<DocumentPanel>(panel_params); + mScroller->addChild(mDocumentPanel); - S32 line_height = llround( mGLFont->getLineHeight() ); - S32 page_size = mTextRect.getHeight() / line_height; - - // Init the scrollbar - LLRect scroll_rect; - scroll_rect.setOriginAndSize( - getRect().getWidth() - scrollbar_size, - 1, - scrollbar_size, - getRect().getHeight() - 1); - S32 lines_in_doc = getLineCount(); - LLScrollbar::Params sbparams; - sbparams.name("Scrollbar"); - sbparams.rect(scroll_rect); - sbparams.orientation(LLScrollbar::VERTICAL); - sbparams.doc_size(lines_in_doc); - sbparams.doc_pos(0); - sbparams.page_size(page_size); - sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM); - mScrollbar = LLUICtrlFactory::create<LLScrollbar> (sbparams); - mScrollbar->setOnScrollEndCallback(mOnScrollEndCallback, mOnScrollEndData); - addChild(mScrollbar); + updateTextRect(); static LLUICachedControl<S32> text_editor_border ("UITextEditorBorder", 0); LLViewBorder::Params params; - params.name("text ed border"); - params.rect(getLocalRect()); - params.bevel_style(LLViewBorder::BEVEL_IN); - params.border_thickness(text_editor_border); + params.name = "text ed border"; + params.rect = getLocalRect(); + params.bevel_style = LLViewBorder::BEVEL_IN; + params.border_thickness = text_editor_border; mBorder = LLUICtrlFactory::create<LLViewBorder> (params); addChild( mBorder ); mBorder->setVisible(!p.hide_border); - appendText(p.default_text, FALSE, FALSE); + createDefaultSegment(); - setHideScrollbarForShortDocs(p.hide_scrollbar); + appendText(p.default_text, FALSE, FALSE); mHTML.clear(); } @@ -350,16 +410,23 @@ void LLTextEditor::initFromParams( const LLTextEditor::Params& p) if (p.read_only.isProvided()) { mReadOnly = p.read_only; - updateSegments(); - updateAllowingLanguageInput(); } + + if (p.commit_on_focus_lost.isProvided()) + { + mCommitOnFocusLost = p.commit_on_focus_lost; + } + + updateSegments(); + updateAllowingLanguageInput(); + // HACK: text editors always need to be enabled so that we can scroll LLView::setEnabled(true); } LLTextEditor::~LLTextEditor() { - gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() + gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() while LLTextEditor still valid // Route menu back to the default if( gEditMenuHandler == this ) @@ -369,8 +436,6 @@ LLTextEditor::~LLTextEditor() // Scrollbar is deleted by LLView mHoverSegment = NULL; - std::for_each(mSegments.begin(), mSegments.end(), DeletePointer()); - std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); } @@ -379,117 +444,183 @@ LLTextViewModel* LLTextEditor::getViewModel() const return (LLTextViewModel*)mViewModel.get(); } -void LLTextEditor::setTrackColor( const LLColor4& color ) -{ - mScrollbar->setTrackColor(color); -} - -void LLTextEditor::setThumbColor( const LLColor4& color ) -{ - mScrollbar->setThumbColor(color); -} - -void LLTextEditor::updateLineStartList(S32 startpos) +static LLFastTimer::DeclareTimer FTM_TEXT_REFLOW ("Text Reflow"); +void LLTextEditor::reflow(S32 start_index) { - updateSegments(); - - bindEmbeddedChars(mGLFont); + if (!mReflowNeeded) return; - S32 seg_num = mSegments.size(); - S32 seg_idx = 0; - S32 seg_offset = 0; + LLFastTimer ft(FTM_TEXT_REFLOW); + static LLUICachedControl<S32> texteditor_vpad_top ("UITextEditorVPadTop", 0); + updateSegments(); - if (!mLineStartList.empty()) + while(mReflowNeeded) { - getSegmentAndOffset(startpos, &seg_idx, &seg_offset); - line_info t(seg_idx, seg_offset); - line_list_t::iterator iter = std::upper_bound(mLineStartList.begin(), mLineStartList.end(), t, line_info_compare()); - if (iter != mLineStartList.begin()) --iter; - seg_idx = iter->mSegment; - seg_offset = iter->mOffset; - mLineStartList.erase(iter, mLineStartList.end()); - } + bool scrolled_to_bottom = mScroller->isAtBottom(); + mReflowNeeded = FALSE; - LLWString text(getWText()); - while( seg_idx < seg_num ) - { - mLineStartList.push_back(line_info(seg_idx,seg_offset)); - BOOL line_ended = FALSE; - S32 start_x = mShowLineNumbers ? UI_TEXTEDITOR_LINE_NUMBER_MARGIN : 0; - S32 line_width = start_x; - while(!line_ended && seg_idx < seg_num) + LLRect old_cursor_rect = getLocalRectFromDocIndex(mCursorPos); + bool follow_selection = mTextRect.overlaps(old_cursor_rect); // cursor is visible + S32 first_line = getFirstVisibleLine(); + // if scroll anchor not on first line, update it to first character of first line + if (!mLineInfoList.empty() + && (mScrollIndex < mLineInfoList[first_line].mDocIndexStart + || mScrollIndex >= mLineInfoList[first_line].mDocIndexEnd)) + { + mScrollIndex = mLineInfoList[first_line].mDocIndexStart; + } + LLRect first_char_rect = getLocalRectFromDocIndex(mScrollIndex); + //first_char_rect.intersectWith(mTextRect); + + S32 cur_top = -texteditor_vpad_top; + + if (getLength()) { - LLTextSegment* segment = mSegments[seg_idx]; - S32 start_idx = segment->getStart() + seg_offset; - S32 end_idx = start_idx; - while (end_idx < segment->getEnd() && text[end_idx] != '\n') + segment_set_t::iterator seg_iter = mSegments.begin(); + S32 seg_offset = 0; + S32 line_start_index = 0; + S32 text_width = mTextRect.getWidth(); // optionally reserve room for margin + S32 remaining_pixels = text_width; + LLWString text(getWText()); + S32 line_count = 0; + + // find and erase line info structs starting at start_index and going to end of document + if (!mLineInfoList.empty()) { - end_idx++; + // find first element whose end comes after start_index + line_list_t::iterator iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), start_index, line_end_compare()); + line_start_index = iter->mDocIndexStart; + line_count = iter->mLineNum; + getSegmentAndOffset(iter->mDocIndexStart, &seg_iter, &seg_offset); + mLineInfoList.erase(iter, mLineInfoList.end()); } - if (start_idx == end_idx) + + // reserve enough space for line numbers + S32 line_height = mShowLineNumbers ? (S32)(LLFontGL::getFontMonospace()->getLineHeight()) : 0; + + while(seg_iter != mSegments.end()) { - if (end_idx >= segment->getEnd()) - { - // empty segment - seg_idx++; - seg_offset = 0; - } - else - { - // empty line - line_ended = TRUE; - seg_offset++; - } - } - else - { - const llwchar* str = text.c_str() + start_idx; - S32 drawn = mGLFont->maxDrawableChars(str, (F32)abs(mTextRect.getWidth()) - line_width, - end_idx - start_idx, mWordWrap, mAllowEmbeddedItems ); - if( 0 == drawn && line_width == start_x) + LLTextSegmentPtr segment = *seg_iter; + + // track maximum height of any segment on this line + line_height = llmax(line_height, segment->getMaxHeight()); + S32 cur_index = segment->getStart() + seg_offset; + // find run of text from this segment that we can display on one line + S32 end_index = cur_index; + while(end_index < segment->getEnd() && text[end_index] != '\n') { - // If at the beginning of a line, draw at least one character, even if it doesn't all fit. - drawn = 1; + ++end_index; } - seg_offset += drawn; - line_width += mGLFont->getWidth(str, 0, drawn, mAllowEmbeddedItems); - end_idx = segment->getStart() + seg_offset; - if (end_idx < segment->getEnd()) + + // ask segment how many character fit in remaining space + S32 max_characters = end_index - cur_index; + S32 character_count = segment->getNumChars(llmax(0, remaining_pixels), seg_offset, cur_index - line_start_index, max_characters); + + seg_offset += character_count; + + S32 last_segment_char_on_line = segment->getStart() + seg_offset; + + // if we didn't finish the current segment... + if (last_segment_char_on_line < segment->getEnd()) { - line_ended = TRUE; - if (text[end_idx] == '\n') + // set up index for next line + // ...skip newline, we don't want to draw + S32 next_line_count = line_count; + if (text[last_segment_char_on_line] == '\n') { - seg_offset++; // skip newline + seg_offset++; + last_segment_char_on_line++; + next_line_count++; } + + // add line info and keep going + mLineInfoList.push_back(line_info(line_start_index, last_segment_char_on_line, cur_top, cur_top - line_height, line_count)); + + line_start_index = segment->getStart() + seg_offset; + cur_top -= line_height; + remaining_pixels = text_width; + line_height = 0; + line_count = next_line_count; + } + // ...just consumed last segment.. + else if (++segment_set_t::iterator(seg_iter) == mSegments.end()) + { + mLineInfoList.push_back(line_info(line_start_index, last_segment_char_on_line, cur_top, cur_top - line_height, line_count)); + cur_top -= line_height; + break; } + // finished a segment and there are segments remaining on this line else { - // finished with segment - seg_idx++; + // subtract pixels used and increment segment + remaining_pixels -= segment->getWidth(seg_offset, character_count); + ++seg_iter; seg_offset = 0; } } } - } - - unbindEmbeddedChars(mGLFont); - mScrollbar->setDocSize( getLineCount() ); + // change mDocumentPanel document size to accomodate reflowed text + LLRect document_rect; + document_rect.setOriginAndSize(1, 1, + mScroller->getContentWindowRect().getWidth(), + llmax(mScroller->getContentWindowRect().getHeight(), -cur_top)); + mDocumentPanel->setShape(document_rect); - if (mHideScrollbarForShortDocs) - { - BOOL short_doc = (mScrollbar->getDocSize() <= mScrollbar->getPageSize()); - mScrollbar->setVisible(!short_doc); - } + // after making document big enough to hold all the text, move the text to fit in the document + if (!mLineInfoList.empty()) + { + S32 delta_pos = mDocumentPanel->getRect().getHeight() - mLineInfoList.begin()->mTop - texteditor_vpad_top; + // move line segments to fit new document rect + for (line_list_t::iterator it = mLineInfoList.begin(); it != mLineInfoList.end(); ++it) + { + it->mTop += delta_pos; + it->mBottom += delta_pos; + } + } - // if scrolled to bottom, stay at bottom - // unless user is selecting text - // do this after updating page size - if (mScrolledToBottom && mTrackBottom && !hasMouseCapture()) - { - endOfDoc(); + // calculate visible region for diplaying text + updateTextRect(); + + for (segment_set_t::iterator segment_it = mSegments.begin(); + segment_it != mSegments.end(); + ++segment_it) + { + LLTextSegmentPtr segmentp = *segment_it; + segmentp->updateLayout(*this); + + } + + // apply scroll constraints after reflowing text + if (!hasMouseCapture()) + { + LLRect visible_content_rect = mScroller->getVisibleContentRect(); + if (scrolled_to_bottom && mTrackBottom) + { + // keep bottom of text buffer visible + endOfDoc(); + } + else if (hasSelection() && follow_selection) + { + // keep cursor in same vertical position on screen when selecting text + LLRect new_cursor_rect_doc = getLocalRectFromDocIndex(mCursorPos); + new_cursor_rect_doc.translate(visible_content_rect.mLeft, visible_content_rect.mBottom); + mScroller->scrollToShowRect(new_cursor_rect_doc, old_cursor_rect); + //llassert_always(getLocalRectFromDocIndex(mCursorPos).mBottom == old_cursor_rect.mBottom); + } + else + { + // keep first line of text visible + LLRect new_first_char_rect = getLocalRectFromDocIndex(mScrollIndex); + new_first_char_rect.translate(visible_content_rect.mLeft, visible_content_rect.mBottom); + mScroller->scrollToShowRect(new_first_char_rect, first_char_rect); + //llassert_always(getLocalRectFromDocIndex(mScrollIndex).mBottom == first_char_rect.mBottom); + } + } } + + // reset desired x cursor position + updateCursorXPos(); } //////////////////////////////////////////////////////////// @@ -519,35 +650,53 @@ BOOL LLTextEditor::truncate() return did_truncate; } +void LLTextEditor::clearSegments() +{ + mHoverSegment = NULL; + mSegments.clear(); +} + void LLTextEditor::setText(const LLStringExplicit &utf8str) { + clearSegments(); + // LLStringUtil::removeCRLF(utf8str); - mViewModel->setValue(utf8str_removeCRLF(utf8str)); + getViewModel()->setValue(utf8str_removeCRLF(utf8str)); truncate(); blockUndo(); - setCursorPos(0); + createDefaultSegment(); + + startOfDoc(); deselect(); needsReflow(); resetDirty(); + + onValueChange(0, getLength()); } void LLTextEditor::setWText(const LLWString &wtext) { + clearSegments(); + getViewModel()->setDisplay(wtext); truncate(); blockUndo(); - setCursorPos(0); + createDefaultSegment(); + + startOfDoc(); deselect(); needsReflow(); resetDirty(); + + onValueChange(0, getLength()); } // virtual @@ -562,39 +711,7 @@ std::string LLTextEditor::getText() const { llwarns << "getText() called on text with embedded items (not supported)" << llendl; } - return mViewModel->getValue().asString(); -} - -void LLTextEditor::setWordWrap(BOOL b) -{ - mWordWrap = b; - - setCursorPos(0); - deselect(); - - needsReflow(); -} - - -void LLTextEditor::setBorderVisible(BOOL b) -{ - mBorder->setVisible(b); -} - -BOOL LLTextEditor::isBorderVisible() const -{ - return mBorder->getVisible(); -} - -void LLTextEditor::setHideScrollbarForShortDocs(BOOL b) -{ - mHideScrollbarForShortDocs = b; - - if (mHideScrollbarForShortDocs) - { - BOOL short_doc = (mScrollbar->getDocSize() <= mScrollbar->getPageSize()); - mScrollbar->setVisible(!short_doc); - } + return getViewModel()->getValue().asString(); } void LLTextEditor::selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap) @@ -619,7 +736,7 @@ void LLTextEditor::selectNext(const std::string& search_text_in, BOOL case_insen if (selected_text == search_text) { // We already have this word selected, we are searching for the next. - mCursorPos += search_text.size(); + setCursorPos(mCursorPos + search_text.size()); } } @@ -682,9 +799,7 @@ BOOL LLTextEditor::replaceText(const std::string& search_text_in, const std::str void LLTextEditor::replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive) { - S32 cur_pos = mScrollbar->getDocPos(); - - setCursorPos(0); + startOfDoc(); selectNext(search_text, case_insensitive, FALSE); BOOL replaced = TRUE; @@ -692,14 +807,12 @@ void LLTextEditor::replaceTextAll(const std::string& search_text, const std::str { replaced = replaceText(search_text,replace_text, case_insensitive, FALSE); } - - mScrollbar->setDocPos(cur_pos); } // Picks a new cursor position based on the screen size of text being drawn. -void LLTextEditor::setCursorAtLocalPos( S32 local_x, S32 local_y, BOOL round ) +void LLTextEditor::setCursorAtLocalPos( S32 local_x, S32 local_y, bool round, bool keep_cursor_offset ) { - setCursorPos(getCursorPosFromLocalCoord(local_x, local_y, round)); + setCursorPos(getDocIndexFromLocalCoord(local_x, local_y, round), keep_cursor_offset); } S32 LLTextEditor::prevWordPos(S32 cursorPos) const @@ -709,7 +822,7 @@ S32 LLTextEditor::prevWordPos(S32 cursorPos) const { cursorPos--; } - while( (cursorPos > 0) && isPartOfWord( wtext[cursorPos-1] ) ) + while( (cursorPos > 0) && LLWStringUtil::isPartOfWord( wtext[cursorPos-1] ) ) { cursorPos--; } @@ -719,7 +832,7 @@ S32 LLTextEditor::prevWordPos(S32 cursorPos) const S32 LLTextEditor::nextWordPos(S32 cursorPos) const { LLWString wtext(getWText()); - while( (cursorPos < getLength()) && isPartOfWord( wtext[cursorPos] ) ) + while( (cursorPos < getLength()) && LLWStringUtil::isPartOfWord( wtext[cursorPos] ) ) { cursorPos++; } @@ -739,171 +852,331 @@ S32 LLTextEditor::getLineStart( S32 line ) const } line = llclamp(line, 0, num_lines-1); - S32 segidx = mLineStartList[line].mSegment; - S32 segoffset = mLineStartList[line].mOffset; - LLTextSegment* seg = mSegments[segidx]; - S32 res = seg->getStart() + segoffset; - if (res > seg->getEnd()) llerrs << "wtf" << llendl; - return res; + return mLineInfoList[line].mDocIndexStart; +} + +S32 LLTextEditor::getLineHeight( S32 line ) const +{ + S32 num_lines = getLineCount(); + if (num_lines == 0) + { + return 0; + } + + line = llclamp(line, 0, num_lines-1); + return mLineInfoList[line].mTop - mLineInfoList[line].mBottom; } // Given an offset into text (pos), find the corresponding line (from the start of the doc) and an offset into the line. -void LLTextEditor::getLineAndOffset( S32 startpos, S32* linep, S32* offsetp ) const +void LLTextEditor::getLineAndOffset( S32 startpos, S32* linep, S32* offsetp, bool include_wordwrap) const { - if (mLineStartList.empty()) + if (mLineInfoList.empty()) { *linep = 0; *offsetp = startpos; } else { - S32 seg_idx, seg_offset; - getSegmentAndOffset( startpos, &seg_idx, &seg_offset ); + line_list_t::const_iterator iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), startpos, line_end_compare()); + if (include_wordwrap) + { + *linep = iter - mLineInfoList.begin(); + } + else + { + if (iter == mLineInfoList.end()) + { + *linep = mLineInfoList.back().mLineNum; + } + else + { + *linep = iter->mLineNum; + } + } + *offsetp = startpos - iter->mDocIndexStart; + } +} - line_info tline(seg_idx, seg_offset); - line_list_t::const_iterator iter = std::upper_bound(mLineStartList.begin(), mLineStartList.end(), tline, line_info_compare()); - if (iter != mLineStartList.begin()) --iter; - *linep = iter - mLineStartList.begin(); - S32 line_start = mSegments[iter->mSegment]->getStart() + iter->mOffset; - *offsetp = startpos - line_start; +void LLTextEditor::getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const +{ + *seg_iter = getSegIterContaining(startpos); + if (*seg_iter == mSegments.end()) + { + *offsetp = 0; + } + else + { + *offsetp = startpos - (**seg_iter)->getStart(); } } -void LLTextEditor::getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ) const +void LLTextEditor::getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp ) { - if (mSegments.empty()) + *seg_iter = getSegIterContaining(startpos); + if (*seg_iter == mSegments.end()) { - *segidxp = -1; - *offsetp = startpos; + *offsetp = 0; + } + else + { + *offsetp = startpos - (**seg_iter)->getStart(); } - - LLTextSegment tseg(startpos); - segment_list_t::const_iterator seg_iter; - seg_iter = std::upper_bound(mSegments.begin(), mSegments.end(), &tseg, LLTextSegment::compare()); - if (seg_iter != mSegments.begin()) --seg_iter; - *segidxp = seg_iter - mSegments.begin(); - *offsetp = startpos - (*seg_iter)->getStart(); } -const LLTextSegment* LLTextEditor::getPreviousSegment() const +const LLTextSegmentPtr LLTextEditor::getPreviousSegment() const { // find segment index at character to left of cursor (or rightmost edge of selection) - S32 idx = llmax(0, getSegmentIdxAtOffset(mCursorPos) - 1); - return idx >= 0 ? mSegments[idx] : NULL; + segment_set_t::const_iterator it = mSegments.lower_bound(new LLIndexSegment(mCursorPos)); + + if (it != mSegments.end()) + { + return *it; + } + else + { + return LLTextSegmentPtr(); + } } -void LLTextEditor::getSelectedSegments(std::vector<const LLTextSegment*>& segments) const +void LLTextEditor::getSelectedSegments(LLTextEditor::segment_vec_t& segments) const { S32 left = hasSelection() ? llmin(mSelectionStart, mSelectionEnd) : mCursorPos; S32 right = hasSelection() ? llmax(mSelectionStart, mSelectionEnd) : mCursorPos; - S32 first_idx = llmax(0, getSegmentIdxAtOffset(left)); - S32 last_idx = llmax(0, first_idx, getSegmentIdxAtOffset(right)); - for (S32 idx = first_idx; idx <= last_idx; ++idx) - { - segments.push_back(mSegments[idx]); - } + return getSegmentsInRange(segments, left, right, true); } -S32 LLTextEditor::getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const +void LLTextEditor::getSegmentsInRange(LLTextEditor::segment_vec_t& segments_out, S32 start, S32 end, bool include_partial) const { - if(mShowLineNumbers) + segment_set_t::const_iterator first_it = getSegIterContaining(start); + segment_set_t::const_iterator end_it = getSegIterContaining(end - 1); + if (end_it != mSegments.end()) ++end_it; + + for (segment_set_t::const_iterator it = first_it; it != end_it; ++it) { - local_x -= UI_TEXTEDITOR_LINE_NUMBER_MARGIN; + LLTextSegmentPtr segment = *it; + if (include_partial + || (segment->getStart() >= start + && segment->getEnd() <= end)) + { + segments_out.push_back(segment); + } } +} - // If round is true, if the position is on the right half of a character, the cursor - // will be put to its right. If round is false, the cursor will always be put to the - // character's left. +// If round is true, if the position is on the right half of a character, the cursor +// will be put to its right. If round is false, the cursor will always be put to the +// character's left. +S32 LLTextEditor::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const +{ // Figure out which line we're nearest to. - S32 total_lines = getLineCount(); - S32 line_height = llround( mGLFont->getLineHeight() ); - S32 max_visible_lines = mTextRect.getHeight() / line_height; - S32 scroll_lines = mScrollbar->getDocPos(); - S32 visible_lines = llmin( total_lines - scroll_lines, max_visible_lines ); // Lines currently visible + LLRect visible_region = mScroller->getVisibleContentRect(); + + // binary search for line that starts before local_y + line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), local_y - mTextRect.mBottom + visible_region.mBottom, compare_bottom()); - //S32 line = S32( 0.5f + ((mTextRect.mTop - local_y) / mGLFont->getLineHeight()) ); - S32 line = (mTextRect.mTop - 1 - local_y) / line_height; - if (line >= total_lines) + if (line_iter == mLineInfoList.end()) { return getLength(); // past the end } - line = llclamp( line, 0, visible_lines ) + scroll_lines; + S32 pos = getLength(); + S32 start_x = mTextRect.mLeft; + + segment_set_t::iterator line_seg_iter; + S32 line_seg_offset; + for(getSegmentAndOffset(line_iter->mDocIndexStart, &line_seg_iter, &line_seg_offset); + line_seg_iter != mSegments.end(); + ++line_seg_iter, line_seg_offset = 0) + { + const LLTextSegmentPtr segmentp = *line_seg_iter; + + S32 segment_line_start = segmentp->getStart() + line_seg_offset; + S32 segment_line_length = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd - 1) - segment_line_start; + S32 text_width = segmentp->getWidth(line_seg_offset, segment_line_length); + if (local_x < start_x + text_width // cursor to left of right edge of text + || segmentp->getEnd() >= line_iter->mDocIndexEnd - 1) // or this segment wraps to next line + { + // Figure out which character we're nearest to. + S32 offset; + if (!segmentp->canEdit()) + { + S32 segment_width = segmentp->getWidth(0, segmentp->getEnd() - segmentp->getStart()); + if (round && local_x - start_x > segment_width / 2) + { + offset = segment_line_length; + } + else + { + offset = 0; + } + } + else + { + offset = segmentp->getOffset(local_x - start_x, line_seg_offset, segment_line_length, round); + } + pos = segment_line_start + offset; + break; + } + start_x += text_width; + } - S32 line_start = getLineStart(line); - S32 next_start = getLineStart(line+1); - S32 line_end = (next_start != line_start) ? next_start - 1 : getLength(); + return pos; +} - if(line_start == -1) - { - return 0; +LLRect LLTextEditor::getLocalRectFromDocIndex(S32 pos) const +{ + LLRect local_rect(mTextRect); + local_rect.mBottom = local_rect.mTop - (S32)(mDefaultFont->getLineHeight()); + if (mLineInfoList.empty()) + { + return local_rect; } - else + + // clamp pos to valid values + pos = llclamp(pos, 0, mLineInfoList.back().mDocIndexEnd - 1); + + + // find line that contains cursor + line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare()); + + LLRect scrolled_view_rect = mScroller->getVisibleContentRect(); + local_rect.mLeft = mTextRect.mLeft - scrolled_view_rect.mLeft; + local_rect.mBottom = mTextRect.mBottom + (line_iter->mBottom - scrolled_view_rect.mBottom); + local_rect.mTop = mTextRect.mBottom + (line_iter->mTop - scrolled_view_rect.mBottom); + + segment_set_t::iterator line_seg_iter; + S32 line_seg_offset; + segment_set_t::iterator cursor_seg_iter; + S32 cursor_seg_offset; + getSegmentAndOffset(line_iter->mDocIndexStart, &line_seg_iter, &line_seg_offset); + getSegmentAndOffset(pos, &cursor_seg_iter, &cursor_seg_offset); + + while(line_seg_iter != mSegments.end()) { - S32 line_len = line_end - line_start; - S32 pos; - LLWString text(getWText()); + const LLTextSegmentPtr segmentp = *line_seg_iter; - if (mAllowEmbeddedItems) + if (line_seg_iter == cursor_seg_iter) { - // Figure out which character we're nearest to. - bindEmbeddedChars(mGLFont); - pos = mGLFont->charFromPixelOffset(text.c_str(), line_start, - (F32)(local_x - mTextRect.mLeft), - (F32)(mTextRect.getWidth()), - line_len, - round, TRUE); - unbindEmbeddedChars(mGLFont); + // cursor advanced to right based on difference in offset of cursor to start of line + local_rect.mLeft += segmentp->getWidth(line_seg_offset, cursor_seg_offset - line_seg_offset); + + break; } else { - pos = mGLFont->charFromPixelOffset(text.c_str(), line_start, - (F32)(local_x - mTextRect.mLeft), - (F32)mTextRect.getWidth(), - line_len, - round); + // add remainder of current text segment to cursor position + local_rect.mLeft += segmentp->getWidth(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset); + // offset will be 0 for all segments after the first + line_seg_offset = 0; + // go to next text segment on this line + ++line_seg_iter; } - - return line_start + pos; } + + local_rect.mRight = local_rect.mLeft; + + return local_rect; +} + +void LLTextEditor::addDocumentChild(LLView* view) +{ + mDocumentPanel->addChild(view); } -void LLTextEditor::setCursor(S32 row, S32 column) +void LLTextEditor::removeDocumentChild(LLView* view) +{ + mDocumentPanel->removeChild(view); +} + +bool LLTextEditor::setCursor(S32 row, S32 column) { - LLWString text(getWText()); - const llwchar* doc = text.c_str(); - const char CR = 10; - while(row--) + if (0 <= row && row < (S32)mLineInfoList.size()) { - while (CR != *doc++); + S32 doc_pos = mLineInfoList[row].mDocIndexStart; + column = llclamp(column, 0, mLineInfoList[row].mDocIndexEnd - mLineInfoList[row].mDocIndexStart - 1); + doc_pos += column; + updateCursorXPos(); + + return setCursorPos(doc_pos); } - doc += column; - setCursorPos(doc - text.c_str()); + return false; } -void LLTextEditor::setCursorPos(S32 offset) +bool LLTextEditor::setCursorPos(S32 cursor_pos, bool keep_cursor_offset) { - mCursorPos = llclamp(offset, 0, (S32)getLength()); + S32 new_cursor_pos = cursor_pos; + if (new_cursor_pos != mCursorPos) + { + new_cursor_pos = getEditableIndex(new_cursor_pos, new_cursor_pos >= mCursorPos); + } + + mCursorPos = llclamp(new_cursor_pos, 0, (S32)getLength()); needsScroll(); - // reset desired x cursor position - mDesiredXPixel = -1; + if (!keep_cursor_offset) + updateCursorXPos(); + // did we get requested position? + return new_cursor_pos == cursor_pos; } -// virtual -BOOL LLTextEditor::canDeselect() const +void LLTextEditor::updateCursorXPos() { - return hasSelection(); + // reset desired x cursor position + mDesiredXPixel = getLocalRectFromDocIndex(mCursorPos).mLeft; } - -void LLTextEditor::deselect() +// constraint cursor to editable segments of document +S32 LLTextEditor::getEditableIndex(S32 index, bool increasing_direction) { - mSelectionStart = 0; - mSelectionEnd = 0; - mIsSelecting = FALSE; -} + //// always allow editable position at end of doc + //if (index == getLength()) + //{ + // return index; + //} + + segment_set_t::iterator segment_iter; + S32 offset; + getSegmentAndOffset(index, &segment_iter, &offset); + + LLTextSegmentPtr segmentp = *segment_iter; + + if (segmentp->canEdit()) + { + return segmentp->getStart() + offset; + } + else if (segmentp->getStart() < index && index < segmentp->getEnd()) + { + // bias towards document end + if (increasing_direction) + { + return segmentp->getEnd(); + } + // bias towards document start + else + { + return segmentp->getStart(); + } + } + else + { + return index; + } +} + +// virtual +BOOL LLTextEditor::canDeselect() const +{ + return hasSelection(); +} + + +void LLTextEditor::deselect() +{ + mSelectionStart = 0; + mSelectionEnd = 0; + mIsSelecting = FALSE; +} void LLTextEditor::startSelection() @@ -1029,7 +1302,7 @@ void LLTextEditor::indentSelectedLines( S32 spaces ) } right += delta_spaces; - //text = mWText; + text = getWText(); // Find the next new line while( (cur < right) && (text[cur] != '\n') ) @@ -1055,7 +1328,7 @@ void LLTextEditor::indentSelectedLines( S32 spaces ) mSelectionStart = right; mSelectionEnd = left; } - mCursorPos = mSelectionEnd; + setCursorPos(mSelectionEnd); } } @@ -1070,7 +1343,7 @@ void LLTextEditor::selectAll() { mSelectionStart = getLength(); mSelectionEnd = 0; - mCursorPos = mSelectionEnd; + setCursorPos(mSelectionEnd); } @@ -1088,12 +1361,7 @@ BOOL LLTextEditor::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_ } } - if( mSegments.empty() ) - { - return TRUE; - } - - const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); + const LLTextSegmentPtr cur_segment = getSegmentAtLocalPos( x, y ); if( cur_segment ) { BOOL has_tool_tip = FALSE; @@ -1114,12 +1382,6 @@ BOOL LLTextEditor::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_ return TRUE; } -BOOL LLTextEditor::handleScrollWheel(S32 x, S32 y, S32 clicks) -{ - // Pretend the mouse is over the scrollbar - return mScrollbar->handleScrollWheel( 0, 0, clicks ); -} - BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; @@ -1127,7 +1389,7 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) // Let scrollbar have first dibs handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL; - if( !handled && mTakesNonScrollClicks) + if( !handled ) { if (!(mask & MASK_SHIFT)) { @@ -1141,31 +1403,10 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) if (mask & MASK_SHIFT) { S32 old_cursor_pos = mCursorPos; - setCursorAtLocalPos( x, y, TRUE ); + setCursorAtLocalPos( x, y, true ); if (hasSelection()) { - /* Mac-like behavior - extend selection towards the cursor - if (mCursorPos < mSelectionStart - && mCursorPos < mSelectionEnd) - { - // ...left of selection - mSelectionStart = llmax(mSelectionStart, mSelectionEnd); - mSelectionEnd = mCursorPos; - } - else if (mCursorPos > mSelectionStart - && mCursorPos > mSelectionEnd) - { - // ...right of selection - mSelectionStart = llmin(mSelectionStart, mSelectionEnd); - mSelectionEnd = mCursorPos; - } - else - { - mSelectionEnd = mCursorPos; - } - */ - // Windows behavior mSelectionEnd = mCursorPos; } else @@ -1178,7 +1419,7 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) } else { - setCursorAtLocalPos( x, y, TRUE ); + setCursorAtLocalPos( x, y, true ); startSelection(); } gFocusMgr.setMouseCapture( this ); @@ -1202,11 +1443,17 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLTextEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask) { - setFocus( TRUE ); - if( canPastePrimary() ) + BOOL handled = FALSE; + handled = childrenHandleMiddleMouseDown(x, y, mask) != NULL; + + if (!handled) { - setCursorAtLocalPos( x, y, TRUE ); - pastePrimary(); + setFocus( TRUE ); + if( canPastePrimary() ) + { + setCursorAtLocalPos( x, y, true ); + pastePrimary(); + } } return TRUE; } @@ -1217,7 +1464,12 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask) static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); BOOL handled = FALSE; + if (mHoverSegment) + { + mHoverSegment->setHasMouseHover(false); + } mHoverSegment = NULL; + if(hasMouseCapture() ) { if( mIsSelecting ) @@ -1228,17 +1480,11 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask) mLastSelectionY = y; } - if( y > mTextRect.mTop ) - { - mScrollbar->setDocPos( mScrollbar->getDocPos() - 1 ); - } - else - if( y < mTextRect.mBottom ) - { - mScrollbar->setDocPos( mScrollbar->getDocPos() + 1 ); - } + mScroller->autoScroll(x, y); - setCursorAtLocalPos( x, y, TRUE ); + S32 clamped_x = llclamp(x, mTextRect.mLeft, mTextRect.mRight); + S32 clamped_y = llclamp(y, mTextRect.mBottom, mTextRect.mTop); + setCursorAtLocalPos( clamped_x, clamped_y, true ); mSelectionEnd = mCursorPos; } @@ -1260,51 +1506,43 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask) } // Opaque - if( !handled && mTakesNonScrollClicks) + if( !handled ) { // Check to see if we're over an HTML-style link - if( !mSegments.empty() ) + LLTextSegmentPtr cur_segment = getSegmentAtLocalPos( x, y ); + if( cur_segment ) { - const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); - if( cur_segment ) + if(cur_segment->getStyle()->isLink()) { - if(cur_segment->getStyle()->isLink()) - { - lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over link, inactive)" << llendl; - getWindow()->setCursor(UI_CURSOR_HAND); - handled = TRUE; - } - else - if(cur_segment->getStyle()->getIsEmbeddedItem()) - { - lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over embedded item, inactive)" << llendl; - getWindow()->setCursor(UI_CURSOR_HAND); - //getWindow()->setCursor(UI_CURSOR_ARROW); - handled = TRUE; - } - mHoverSegment = cur_segment; + lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over link, inactive)" << llendl; + getWindow()->setCursor(UI_CURSOR_HAND); + handled = TRUE; } + //else + //if(cur_segment->getStyle()->getIsEmbeddedItem()) + //{ + // lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over embedded item, inactive)" << llendl; + // getWindow()->setCursor(UI_CURSOR_HAND); + // //getWindow()->setCursor(UI_CURSOR_ARROW); + // handled = TRUE; + //} + if (mHoverSegment) + { + mHoverSegment->setHasMouseHover(false); + } + cur_segment->setHasMouseHover(true); + mHoverSegment = cur_segment; + mHTML = mHoverSegment->getStyle()->getLinkHREF(); } if( !handled ) { lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl; - if (!mScrollbar->getVisible() || x < getRect().getWidth() - scrollbar_size) - { - getWindow()->setCursor(UI_CURSOR_IBEAM); - } - else - { - getWindow()->setCursor(UI_CURSOR_ARROW); - } + getWindow()->setCursor(UI_CURSOR_IBEAM); handled = TRUE; } } - if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax())) - { - mOnScrollEndCallback(mOnScrollEndData); - } return handled; } @@ -1316,22 +1554,14 @@ BOOL LLTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) // let scrollbar have first dibs handled = LLView::childrenHandleMouseUp(x, y, mask) != NULL; - if( !handled && mTakesNonScrollClicks) + if( !handled ) { if( mIsSelecting ) { - // Finish selection - if( y > mTextRect.mTop ) - { - mScrollbar->setDocPos( mScrollbar->getDocPos() - 1 ); - } - else - if( y < mTextRect.mBottom ) - { - mScrollbar->setDocPos( mScrollbar->getDocPos() + 1 ); - } - - setCursorAtLocalPos( x, y, TRUE ); + mScroller->autoScroll(x, y); + S32 clamped_x = llclamp(x, mTextRect.mLeft, mTextRect.mRight); + S32 clamped_y = llclamp(y, mTextRect.mBottom, mTextRect.mTop); + setCursorAtLocalPos( clamped_x, clamped_y, true ); endSelection(); } @@ -1367,25 +1597,25 @@ BOOL LLTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) // let scrollbar have first dibs handled = LLView::childrenHandleDoubleClick(x, y, mask) != NULL; - if( !handled && mTakesNonScrollClicks) + if( !handled ) { - setCursorAtLocalPos( x, y, FALSE ); + setCursorAtLocalPos( x, y, false ); deselect(); LLWString text = getWText(); - if( isPartOfWord( text[mCursorPos] ) ) + if( LLWStringUtil::isPartOfWord( text[mCursorPos] ) ) { // Select word the cursor is over - while ((mCursorPos > 0) && isPartOfWord(text[mCursorPos-1])) + while ((mCursorPos > 0) && LLWStringUtil::isPartOfWord(text[mCursorPos-1])) { - mCursorPos--; + if (!setCursorPos(mCursorPos - 1)) break; } startSelection(); - while ((mCursorPos < (S32)text.length()) && isPartOfWord( text[mCursorPos] ) ) + while ((mCursorPos < (S32)text.length()) && LLWStringUtil::isPartOfWord( text[mCursorPos] ) ) { - mCursorPos++; + if (!setCursorPos(mCursorPos + 1)) break; } mSelectionEnd = mCursorPos; @@ -1394,7 +1624,7 @@ BOOL LLTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) { // Select the character the cursor is over startSelection(); - mCursorPos++; + setCursorPos(mCursorPos + 1); mSelectionEnd = mCursorPos; } @@ -1457,19 +1687,25 @@ S32 LLTextEditor::execute( LLTextCmd* cmd ) return delta; } -S32 LLTextEditor::insert(const S32 pos, const LLWString &wstr, const BOOL group_with_next_op) +S32 LLTextEditor::insert(S32 pos, const LLWString &wstr, bool group_with_next_op, LLTextSegmentPtr segment) { - return execute( new LLTextCmdInsert( pos, group_with_next_op, wstr ) ); + return execute( new LLTextCmdInsert( pos, group_with_next_op, wstr, segment ) ); } -S32 LLTextEditor::remove(const S32 pos, const S32 length, const BOOL group_with_next_op) +S32 LLTextEditor::remove(S32 pos, S32 length, bool group_with_next_op) { - return execute( new LLTextCmdRemove( pos, group_with_next_op, length ) ); + S32 end_pos = getEditableIndex(pos + length, true); + + segment_vec_t segments_to_remove; + // store text segments + getSegmentsInRange(segments_to_remove, pos, pos + length, false); + + return execute( new LLTextCmdRemove( pos, group_with_next_op, end_pos - pos, segments_to_remove ) ); } -S32 LLTextEditor::append(const LLWString &wstr, const BOOL group_with_next_op) +S32 LLTextEditor::append(const LLWString &wstr, bool group_with_next_op, LLTextSegmentPtr segment) { - return insert(getLength(), wstr, group_with_next_op); + return insert(getLength(), wstr, group_with_next_op, segment); } S32 LLTextEditor::overwriteChar(S32 pos, llwchar wc) @@ -1575,7 +1811,7 @@ S32 LLTextEditor::addChar(S32 pos, llwchar wc) } else { - return execute(new LLTextCmdAddChar(pos, FALSE, wc)); + return execute(new LLTextCmdAddChar(pos, FALSE, wc, LLTextSegmentPtr())); } } @@ -1612,10 +1848,10 @@ BOOL LLTextEditor::handleSelectionKey(const KEY key, const MASK mask) if( 0 < mCursorPos ) { startSelection(); - mCursorPos--; + setCursorPos(mCursorPos - 1); if( mask & MASK_CONTROL ) { - mCursorPos = prevWordPos(mCursorPos); + setCursorPos(prevWordPos(mCursorPos)); } mSelectionEnd = mCursorPos; } @@ -1625,10 +1861,10 @@ BOOL LLTextEditor::handleSelectionKey(const KEY key, const MASK mask) if( mCursorPos < getLength() ) { startSelection(); - mCursorPos++; + setCursorPos(mCursorPos + 1); if( mask & MASK_CONTROL ) { - mCursorPos = nextWordPos(mCursorPos); + setCursorPos(nextWordPos(mCursorPos)); } mSelectionEnd = mCursorPos; } @@ -1650,7 +1886,7 @@ BOOL LLTextEditor::handleSelectionKey(const KEY key, const MASK mask) startSelection(); if( mask & MASK_CONTROL ) { - mCursorPos = 0; + setCursorPos(0); } else { @@ -1675,7 +1911,7 @@ BOOL LLTextEditor::handleSelectionKey(const KEY key, const MASK mask) startSelection(); if( mask & MASK_CONTROL ) { - mCursorPos = getLength(); + setCursorPos(getLength()); } else { @@ -1726,14 +1962,7 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask) switch( key ) { case KEY_UP: - if (mReadOnly) - { - mScrollbar->setDocPos(mScrollbar->getDocPos() - 1); - } - else - { - changeLine( -1 ); - } + changeLine( -1 ); break; case KEY_PAGE_UP: @@ -1741,25 +1970,11 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask) break; case KEY_HOME: - if (mReadOnly) - { - mScrollbar->setDocPos(0); - } - else - { - startOfLine(); - } + startOfLine(); break; case KEY_DOWN: - if (mReadOnly) - { - mScrollbar->setDocPos(mScrollbar->getDocPos() + 1); - } - else - { - changeLine( 1 ); - } + changeLine( 1 ); break; case KEY_PAGE_DOWN: @@ -1767,21 +1982,10 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask) break; case KEY_END: - if (mReadOnly) - { - mScrollbar->setDocPos(mScrollbar->getDocPosMax()); - } - else - { - endOfLine(); - } + endOfLine(); break; case KEY_LEFT: - if (mReadOnly) - { - break; - } if( hasSelection() ) { setCursorPos(llmin( mCursorPos - 1, mSelectionStart, mSelectionEnd )); @@ -1800,10 +2004,6 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask) break; case KEY_RIGHT: - if (mReadOnly) - { - break; - } if( hasSelection() ) { setCursorPos(llmax( mCursorPos + 1, mSelectionStart, mSelectionEnd )); @@ -1827,10 +2027,6 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask) } } - if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax())) - { - mOnScrollEndCallback(mOnScrollEndData); - } return handled; } @@ -1967,7 +2163,7 @@ void LLTextEditor::pasteHelper(bool is_primary) } // Insert the new text into the existing text. - setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE)); + setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE, LLTextSegmentPtr())); deselect(); needsReflow(); @@ -2014,7 +2210,7 @@ BOOL LLTextEditor::handleControlKey(const KEY key, const MASK mask) if( mask & MASK_SHIFT ) { startSelection(); - mCursorPos = 0; + setCursorPos(0); mSelectionEnd = mCursorPos; } else @@ -2022,7 +2218,7 @@ BOOL LLTextEditor::handleControlKey(const KEY key, const MASK mask) // Ctrl-Home, Ctrl-Left, Ctrl-Right, Ctrl-Down // all move the cursor as if clicking, so should deselect. deselect(); - setCursorPos(0); + startOfDoc(); } break; @@ -2251,42 +2447,87 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask ) BOOL return_key_hit = FALSE; BOOL text_may_have_changed = TRUE; - if ( gFocusMgr.getKeyboardFocus() == this ) + // Special case for TAB. If want to move to next field, report + // not handled and let the parent take care of field movement. + if (KEY_TAB == key && mTabsToNextField) { - // Special case for TAB. If want to move to next field, report - // not handled and let the parent take care of field movement. - if (KEY_TAB == key && mTabsToNextField) - { - return FALSE; - } + return FALSE; + } + /* + if (KEY_F10 == key) + { + LLComboBox::Params cp; + cp.name = "combo box"; + cp.label = "my combo"; + cp.rect.width = 100; + cp.rect.height = 20; + cp.items.add().label = "item 1"; + cp.items.add().label = "item 2"; + cp.items.add().label = "item 3"; + + appendWidget(LLUICtrlFactory::create<LLComboBox>(cp), "combo", true, false); + } + if (KEY_F11 == key) + { + LLButton::Params bp; + bp.name = "text button"; + bp.label = "Click me"; + bp.rect.width = 100; + bp.rect.height = 20; + appendWidget(LLUICtrlFactory::create<LLButton>(bp), "button", true, false); + } + */ + if (mReadOnly) + { + handled = mScroller->handleKeyHere( key, mask ); + } + else + { + // handle navigation keys ourself handled = handleNavigationKey( key, mask ); + } + + + if( handled ) + { + text_may_have_changed = FALSE; + } + + if( !handled ) + { + handled = handleSelectionKey( key, mask ); if( handled ) { - text_may_have_changed = FALSE; + selection_modified = TRUE; } - - if( !handled ) + } + + if( !handled ) + { + handled = handleControlKey( key, mask ); + if( handled ) { - handled = handleSelectionKey( key, mask ); - if( handled ) - { - selection_modified = TRUE; - } + selection_modified = TRUE; } - - if( !handled ) + } + + if( !handled && mHandleEditKeysDirectly ) + { + handled = handleEditKey( key, mask ); + if( handled ) { - handled = handleControlKey( key, mask ); - if( handled ) - { - selection_modified = TRUE; - } + selection_modified = TRUE; + text_may_have_changed = TRUE; } + } - if( !handled && mHandleEditKeysDirectly ) + // Handle most keys only if the text editor is writeable. + if( !mReadOnly ) + { + if( !handled ) { - handled = handleEditKey( key, mask ); + handled = handleSpecialKey( key, mask, &return_key_hit ); if( handled ) { selection_modified = TRUE; @@ -2294,41 +2535,27 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask ) } } - // Handle most keys only if the text editor is writeable. - if( !mReadOnly ) - { - if( !handled ) - { - handled = handleSpecialKey( key, mask, &return_key_hit ); - if( handled ) - { - selection_modified = TRUE; - text_may_have_changed = TRUE; - } - } + } - } + if( handled ) + { + resetKeystrokeTimer(); - if( handled ) + // Most keystrokes will make the selection box go away, but not all will. + if( !selection_modified && + KEY_SHIFT != key && + KEY_CONTROL != key && + KEY_ALT != key && + KEY_CAPSLOCK ) { - resetKeystrokeTimer(); - - // Most keystrokes will make the selection box go away, but not all will. - if( !selection_modified && - KEY_SHIFT != key && - KEY_CONTROL != key && - KEY_ALT != key && - KEY_CAPSLOCK ) - { - deselect(); - } + deselect(); + } - if(text_may_have_changed) - { - needsReflow(); - } - needsScroll(); + if(text_may_have_changed) + { + needsReflow(); } + needsScroll(); } return handled; @@ -2344,34 +2571,31 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char) BOOL handled = FALSE; - if ( gFocusMgr.getKeyboardFocus() == this ) + // Handle most keys only if the text editor is writeable. + if( !mReadOnly ) { - // Handle most keys only if the text editor is writeable. - if( !mReadOnly ) + if( '}' == uni_char ) { - if( '}' == uni_char ) - { - unindentLineBeforeCloseBrace(); - } + unindentLineBeforeCloseBrace(); + } - // TODO: KLW Add auto show of tool tip on ( - addChar( uni_char ); + // TODO: KLW Add auto show of tool tip on ( + addChar( uni_char ); - // Keys that add characters temporarily hide the cursor - getWindow()->hideCursorUntilMouseMove(); + // Keys that add characters temporarily hide the cursor + getWindow()->hideCursorUntilMouseMove(); - handled = TRUE; - } + handled = TRUE; + } - if( handled ) - { - resetKeystrokeTimer(); + if( handled ) + { + resetKeystrokeTimer(); - // Most keystrokes will make the selection box go away, but not all will. - deselect(); + // Most keystrokes will make the selection box go away, but not all will. + deselect(); - needsReflow(); - } + needsReflow(); } return handled; @@ -2544,6 +2768,12 @@ void LLTextEditor::onFocusLost() LLUICtrl::onFocusLost(); } +void LLTextEditor::onCommit() +{ + setControlValue(getValue()); + LLUICtrl::onCommit(); +} + void LLTextEditor::setEnabled(BOOL enabled) { // just treat enabled as read-only flag @@ -2560,300 +2790,187 @@ void LLTextEditor::drawBackground() { S32 left = 0; S32 top = getRect().getHeight(); - S32 right = getRect().getWidth(); S32 bottom = 0; LLColor4 bg_color = mReadOnly ? mReadOnlyBgColor.get() - : gFocusMgr.getKeyboardFocus() == this ? mFocusBgColor.get() : mWriteableBgColor.get(); + : hasFocus() ? mFocusBgColor.get() : mWriteableBgColor.get(); if( mShowLineNumbers ) { gl_rect_2d(left, top, UI_TEXTEDITOR_LINE_NUMBER_MARGIN, bottom, mReadOnlyBgColor.get() ); // line number area always read-only - gl_rect_2d(UI_TEXTEDITOR_LINE_NUMBER_MARGIN, top, right, bottom, bg_color); // body text area to the right of line numbers gl_rect_2d(UI_TEXTEDITOR_LINE_NUMBER_MARGIN, top, UI_TEXTEDITOR_LINE_NUMBER_MARGIN-1, bottom, LLColor4::grey3); // separator - } else { - gl_rect_2d(left, top, right, bottom, bg_color); // body text area - } - - LLView::draw(); + } } // Draws the black box behind the selected text void LLTextEditor::drawSelectionBackground() { // Draw selection even if we don't have keyboard focus for search/replace - if( hasSelection() ) + if( hasSelection() && !mLineInfoList.empty()) { LLWString text = getWText(); - const S32 text_len = getLength(); - std::queue<S32> line_endings; - - S32 line_height = llround( mGLFont->getLineHeight() ); + std::vector<LLRect> selection_rects; S32 selection_left = llmin( mSelectionStart, mSelectionEnd ); S32 selection_right = llmax( mSelectionStart, mSelectionEnd ); - S32 selection_left_x = mTextRect.mLeft; - S32 selection_left_y = mTextRect.mTop - line_height; - S32 selection_right_x = mTextRect.mRight; - S32 selection_right_y = mTextRect.mBottom; - - BOOL selection_left_visible = FALSE; - BOOL selection_right_visible = FALSE; + LLRect selection_rect = mTextRect; // Skip through the lines we aren't drawing. - S32 cur_line = mScrollbar->getDocPos(); - - S32 left_line_num = cur_line; - S32 num_lines = getLineCount(); - S32 right_line_num = num_lines - 1; - - S32 line_start = -1; - if (cur_line >= num_lines) - { - return; - } + LLRect content_display_rect = mScroller->getVisibleContentRect(); - line_start = getLineStart(cur_line); + // binary search for line that starts before top of visible buffer + line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom()); + line_list_t::const_iterator end_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top()); - S32 left_visible_pos = line_start; - S32 right_visible_pos = line_start; - - S32 text_y = mTextRect.mTop - line_height; + bool done = false; // Find the coordinates of the selected area - while((cur_line < num_lines)) + for (;line_iter != end_iter && !done; ++line_iter) { - S32 next_line = -1; - S32 line_end = text_len; - - if ((cur_line + 1) < num_lines) + // is selection visible on this line? + if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right) { - next_line = getLineStart(cur_line + 1); - line_end = next_line; - - line_end = ( (line_end - line_start)==0 || text[next_line-1] == '\n' || text[next_line-1] == '\0' || text[next_line-1] == ' ' || text[next_line-1] == '\t' ) ? next_line-1 : next_line; - } + segment_set_t::iterator segment_iter; + S32 segment_offset; + getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset); + + LLRect selection_rect; + selection_rect.mLeft = 0; + selection_rect.mRight = 0; + selection_rect.mBottom = line_iter->mBottom; + selection_rect.mTop = line_iter->mTop; + + for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0) + { + LLTextSegmentPtr segmentp = *segment_iter; - const llwchar* line = text.c_str() + line_start; + S32 segment_line_start = segmentp->getStart() + segment_offset; + S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd); - if( line_start <= selection_left && selection_left <= line_end ) - { - left_line_num = cur_line; - selection_left_visible = TRUE; - selection_left_x = mTextRect.mLeft + mGLFont->getWidth(line, 0, selection_left - line_start, mAllowEmbeddedItems); - selection_left_y = text_y; - } - if( line_start <= selection_right && selection_right <= line_end ) - { - right_line_num = cur_line; - selection_right_visible = TRUE; - selection_right_x = mTextRect.mLeft + mGLFont->getWidth(line, 0, selection_right - line_start, mAllowEmbeddedItems); - if (selection_right == line_end) - { - // add empty space for "newline" - //selection_right_x += mGLFont->getWidth("n"); - } - selection_right_y = text_y; - } - - // if selection spans end of current line... - if (selection_left <= line_end && line_end < selection_right && selection_left != selection_right) - { - // extend selection slightly beyond end of line - // to indicate selection of newline character (use "n" character to determine width) - const LLWString nstr(utf8str_to_wstring(std::string("n"))); - line_endings.push(mTextRect.mLeft + mGLFont->getWidth(line, 0, line_end - line_start, mAllowEmbeddedItems) + mGLFont->getWidth(nstr.c_str())); - } - - // move down one line - text_y -= line_height; + // if selection after beginning of segment + if(selection_left >= segment_line_start) + { + S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start; + selection_rect.mLeft += segmentp->getWidth(segment_offset, num_chars); + } - right_visible_pos = line_end; - line_start = next_line; - cur_line++; + // if selection spans end of current segment... + if (selection_right > segment_line_end) + { + // extend selection slightly beyond end of line + // to indicate selection of newline character (use "n" character to determine width) + selection_rect.mRight += segmentp->getWidth(segment_offset, segment_line_end - segment_line_start); + } + // else if selection ends on current segment... + else + { + S32 num_chars = selection_right - segment_line_start; + selection_rect.mRight += segmentp->getWidth(segment_offset, num_chars); - if (selection_right_visible) - { - break; + break; + } + } + selection_rects.push_back(selection_rect); } } // Draw the selection box (we're using a box instead of reversing the colors on the selected text). - BOOL selection_visible = (left_visible_pos <= selection_right) && (selection_left <= right_visible_pos); - if( selection_visible ) + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + const LLColor4& color = mReadOnly ? mReadOnlyBgColor.get() : mWriteableBgColor.get(); + F32 alpha = hasFocus() ? 0.7f : 0.3f; + gGL.color4f( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], alpha ); + + for (std::vector<LLRect>::iterator rect_it = selection_rects.begin(); + rect_it != selection_rects.end(); + ++rect_it) { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - const LLColor4& color = mReadOnly ? mReadOnlyBgColor.get() : mWriteableBgColor.get(); - F32 alpha = hasFocus() ? 1.f : 0.5f; - gGL.color4f( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], alpha ); - S32 margin_offset = mShowLineNumbers ? UI_TEXTEDITOR_LINE_NUMBER_MARGIN : 0; - - if( selection_left_y == selection_right_y ) - { - // Draw from selection start to selection end - gl_rect_2d( selection_left_x + margin_offset, selection_left_y + line_height + 1, - selection_right_x + margin_offset, selection_right_y); - } - else - { - // Draw from selection start to the end of the first line - if( mTextRect.mRight == selection_left_x ) - { - selection_left_x -= CURSOR_THICKNESS; - } - - S32 line_end = line_endings.front(); - line_endings.pop(); - gl_rect_2d( selection_left_x + margin_offset, selection_left_y + line_height + 1, - line_end + margin_offset, selection_left_y ); - - S32 line_num = left_line_num + 1; - while(line_endings.size()) - { - S32 vert_offset = -(line_num - left_line_num) * line_height; - // Draw the block between the two lines - gl_rect_2d( mTextRect.mLeft + margin_offset, selection_left_y + vert_offset + line_height + 1, - line_endings.front() + margin_offset, selection_left_y + vert_offset); - line_endings.pop(); - line_num++; - } - - // Draw from the start of the last line to selection end - if( mTextRect.mLeft == selection_right_x ) - { - selection_right_x += CURSOR_THICKNESS; - } - gl_rect_2d( mTextRect.mLeft + margin_offset, selection_right_y + line_height + 1, - selection_right_x + margin_offset, selection_right_y ); - } - } - } -} + LLRect selection_rect = *rect_it; + selection_rect.translate(mTextRect.mLeft - content_display_rect.mLeft, mTextRect.mBottom - content_display_rect.mBottom); + gl_rect_2d(selection_rect); + } + } +} void LLTextEditor::drawCursor() { - if( gFocusMgr.getKeyboardFocus() == this - && gShowTextEditCursor && !mReadOnly) + if( hasFocus() + && gFocusMgr.getAppHasFocus() + && !mReadOnly) { - LLWString text = getWText(); - const S32 text_len = getLength(); + LLWString wtext = getWText(); + const llwchar* text = wtext.c_str(); - // Skip through the lines we aren't drawing. - S32 cur_pos = mScrollbar->getDocPos(); + LLRect cursor_rect = getLocalRectFromDocIndex(mCursorPos); + cursor_rect.translate(-1, 0); + segment_set_t::iterator seg_it = getSegIterContaining(mCursorPos); - S32 num_lines = getLineCount(); - if (cur_pos >= num_lines) + // take style from last segment + LLTextSegmentPtr segmentp; + + if (seg_it != mSegments.end()) { + segmentp = *seg_it; + } + else + { + //segmentp = mSegments.back(); return; } - S32 line_start = getLineStart(cur_pos); - - F32 line_height = mGLFont->getLineHeight(); - F32 text_y = (F32)(mTextRect.mTop) - line_height; - - F32 cursor_left = 0.f; - F32 next_char_left = 0.f; - F32 cursor_bottom = 0.f; - BOOL cursor_visible = FALSE; - S32 line_end = 0; - // Determine if the cursor is visible and if so what its coordinates are. - while( (mTextRect.mBottom <= llround(text_y)) && (cur_pos < num_lines)) + // Draw the cursor + // (Flash the cursor every half second starting a fixed time after the last keystroke) + F32 elapsed = mKeystrokeTimer.getElapsedTimeF32(); + if( (elapsed < CURSOR_FLASH_DELAY ) || (S32(elapsed * 2) & 1) ) { - line_end = text_len + 1; - S32 next_line = -1; - if ((cur_pos + 1) < num_lines) + if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection()) { - next_line = getLineStart(cur_pos + 1); - line_end = next_line - 1; + S32 width = llmax(CURSOR_THICKNESS, segmentp->getWidth(mCursorPos - segmentp->getStart(), 1)); + cursor_rect.mRight = cursor_rect.mLeft + width; } - - const llwchar* line = text.c_str() + line_start; - - // Find the cursor and selection bounds - if( line_start <= mCursorPos && mCursorPos <= line_end ) + else { - cursor_visible = TRUE; - next_char_left = (F32)mTextRect.mLeft + mGLFont->getWidthF32(line, 0, mCursorPos - line_start, mAllowEmbeddedItems ); - cursor_left = next_char_left - 1.f; - cursor_bottom = text_y; - break; + cursor_rect.mRight = cursor_rect.mLeft + CURSOR_THICKNESS; } + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - // move down one line - text_y -= line_height; - line_start = next_line; - cur_pos++; - } - - if(mShowLineNumbers) - { - cursor_left += UI_TEXTEDITOR_LINE_NUMBER_MARGIN; - } + gGL.color4fv( mCursorColor.get().mV ); + + gl_rect_2d(cursor_rect); - // Draw the cursor - if( cursor_visible ) - { - // (Flash the cursor every half second starting a fixed time after the last keystroke) - F32 elapsed = mKeystrokeTimer.getElapsedTimeF32(); - if( (elapsed < CURSOR_FLASH_DELAY ) || (S32(elapsed * 2) & 1) ) + if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection() && text[mCursorPos] != '\n') { - F32 cursor_top = cursor_bottom + line_height + 1.f; - F32 cursor_right = cursor_left + (F32)CURSOR_THICKNESS; - if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection()) + LLColor4 text_color; + const LLFontGL* fontp; + if (segmentp) { - cursor_left += CURSOR_THICKNESS; - const LLWString space(utf8str_to_wstring(std::string(" "))); - F32 spacew = mGLFont->getWidthF32(space.c_str()); - if (mCursorPos == line_end) - { - cursor_right = cursor_left + spacew; - } - else - { - F32 width = mGLFont->getWidthF32(text.c_str(), mCursorPos, 1, mAllowEmbeddedItems); - cursor_right = cursor_left + llmax(spacew, width); - } + text_color = segmentp->getColor(); + fontp = segmentp->getStyle()->getFont(); } - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - gGL.color4fv( mCursorColor.get().mV ); - - gl_rect_2d(llfloor(cursor_left), llfloor(cursor_top), - llfloor(cursor_right), llfloor(cursor_bottom)); - - if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection() && text[mCursorPos] != '\n') + else if (mReadOnly) { - const LLTextSegment* segmentp = getSegmentAtOffset(mCursorPos); - LLColor4 text_color; - if (segmentp) - { - text_color = segmentp->getColor(); - } - else if (mReadOnly) - { - text_color = mReadOnlyFgColor.get(); - } - else - { - text_color = mFgColor.get(); - } - mGLFont->render(text, mCursorPos, next_char_left, cursor_bottom + line_height, - LLColor4(1.f - text_color.mV[VRED], 1.f - text_color.mV[VGREEN], 1.f - text_color.mV[VBLUE], 1.f), - LLFontGL::LEFT, LLFontGL::TOP, - LLFontGL::NORMAL, - LLFontGL::NO_SHADOW, - 1); + text_color = mReadOnlyFgColor.get(); + fontp = mDefaultFont; } + else + { + text_color = mFgColor.get(); + fontp = mDefaultFont; + } + fontp->render(text, mCursorPos, cursor_rect.mLeft, cursor_rect.mBottom, + LLColor4(1.f - text_color.mV[VRED], 1.f - text_color.mV[VGREEN], 1.f - text_color.mV[VBLUE], 1.f), + LLFontGL::LEFT, LLFontGL::BOTTOM, + LLFontGL::NORMAL, + LLFontGL::NO_SHADOW, + 1); + } - // Make sure the IME is in the right place - LLRect screen_pos = calcScreenRect(); - LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_left), screen_pos.mBottom + llfloor(cursor_top) ); + // Make sure the IME is in the right place + LLRect screen_pos = calcScreenRect(); + LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_rect.mLeft), screen_pos.mBottom + llfloor(cursor_rect.mTop) ); - ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]); - ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]); - getWindow()->setLanguageTextInput( ime_pos ); - } + ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]); + ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]); + getWindow()->setLanguageTextInput( ime_pos ); } } } @@ -2879,13 +2996,13 @@ void LLTextEditor::drawPreeditMarker() const S32 text_len = getLength(); const S32 num_lines = getLineCount(); - S32 cur_line = mScrollbar->getDocPos(); + S32 cur_line = getFirstVisibleLine(); if (cur_line >= num_lines) { return; } - const S32 line_height = llround( mGLFont->getLineHeight() ); + const S32 line_height = llround( mDefaultFont->getLineHeight() ); S32 line_start = getLineStart(cur_line); S32 line_y = mTextRect.mTop - line_height; @@ -2924,16 +3041,16 @@ void LLTextEditor::drawPreeditMarker() S32 preedit_left = mTextRect.mLeft; if (left > line_start) { - preedit_left += mGLFont->getWidth(text, line_start, left - line_start, mAllowEmbeddedItems); + preedit_left += mDefaultFont->getWidth(text, line_start, left - line_start); } S32 preedit_right = mTextRect.mLeft; if (right < line_end) { - preedit_right += mGLFont->getWidth(text, line_start, right - line_start, mAllowEmbeddedItems); + preedit_right += mDefaultFont->getWidth(text, line_start, right - line_start); } else { - preedit_right += mGLFont->getWidth(text, line_start, line_end - line_start, mAllowEmbeddedItems); + preedit_right += mDefaultFont->getWidth(text, line_start, line_end - line_start); } if (mPreeditStandouts[i]) @@ -2981,25 +3098,34 @@ void LLTextEditor::drawText() } LLGLSUIDefault gls_ui; - - S32 cur_line = mScrollbar->getDocPos(); + LLRect scrolled_view_rect = mScroller->getVisibleContentRect(); + LLRect content_rect = mScroller->getContentWindowRect(); + S32 first_line = getFirstVisibleLine(); S32 num_lines = getLineCount(); - if (cur_line >= num_lines) + if (first_line >= num_lines) { return; } - S32 line_start = getLineStart(cur_line); - LLTextSegment t(line_start); - segment_list_t::iterator seg_iter; - seg_iter = std::upper_bound(mSegments.begin(), mSegments.end(), &t, LLTextSegment::compare()); - if (seg_iter == mSegments.end() || (*seg_iter)->getStart() > line_start) --seg_iter; - LLTextSegment* cur_segment = *seg_iter; - - S32 line_height = llround( mGLFont->getLineHeight() ); - F32 text_y = (F32)(mTextRect.mTop - line_height); - while((mTextRect.mBottom <= text_y) && (cur_line < num_lines)) + S32 line_start = getLineStart(first_line); + // find first text segment that spans top of visible portion of text buffer + segment_set_t::iterator seg_iter = getSegIterContaining(line_start); + if (seg_iter == mSegments.end()) { + return; + } + + LLTextSegmentPtr cur_segment = *seg_iter; + + for (S32 cur_line = first_line; cur_line < num_lines; cur_line++) + { + line_info& line = mLineInfoList[cur_line]; + + if ((line.mTop - scrolled_view_rect.mBottom) < mTextRect.mBottom) + { + break; + } + S32 next_start = -1; S32 line_end = text_len; @@ -3012,9 +3138,13 @@ void LLTextEditor::drawText() { --line_end; } - - F32 text_x = (F32)mTextRect.mLeft; + LLRect text_rect(mTextRect.mLeft - scrolled_view_rect.mLeft, + line.mTop - scrolled_view_rect.mBottom + mTextRect.mBottom, + mTextRect.getWidth() - scrolled_view_rect.mLeft, + line.mBottom - scrolled_view_rect.mBottom + mTextRect.mBottom); + + // draw a single line of text S32 seg_start = line_start; while( seg_start < line_end ) { @@ -3024,184 +3154,120 @@ void LLTextEditor::drawText() if (seg_iter == mSegments.end()) { llwarns << "Ran off the segmentation end!" << llendl; + return; } cur_segment = *seg_iter; } - // Draw a segment within the line - S32 clipped_end = llmin( line_end, cur_segment->getEnd() ); - S32 clipped_len = clipped_end - seg_start; - if( clipped_len > 0 ) - { - LLStyleSP style = cur_segment->getStyle(); - if ( style->isImage() && (cur_segment->getStart() >= seg_start) && (cur_segment->getStart() <= clipped_end)) - { - S32 style_image_height = style->mImageHeight; - S32 style_image_width = style->mImageWidth; - LLUIImagePtr image = style->getImage(); - image->draw(llround(text_x), llround(text_y)+line_height-style_image_height, - style_image_width, style_image_height); - } + S32 clipped_end = llmin( line_end, cur_segment->getEnd() ) - cur_segment->getStart(); + text_rect.mLeft = (S32)(cur_segment->draw(seg_start - cur_segment->getStart(), clipped_end, selection_left, selection_right, text_rect)); - if (cur_segment == mHoverSegment && style->getIsEmbeddedItem()) - { - style->mUnderline = TRUE; - } - - S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); - - if ( (mParseHTML) && (left_pos > seg_start) && (left_pos < clipped_end) && mIsSelecting && (mSelectionStart == mSelectionEnd) ) - { - mHTML = style->getLinkHREF(); - } - - drawClippedSegment( text, seg_start, clipped_end, text_x, text_y, selection_left, selection_right, style, &text_x ); - - // Note: text_x is incremented by drawClippedSegment() - seg_start += clipped_len; - } + seg_start = clipped_end + cur_segment->getStart(); } - // move down one line - text_y -= (F32)line_height; - line_start = next_start; - cur_line++; } } - -// Draws a single text segment, reversing the color for selection if needed. -void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyleSP& style, F32* right_x ) +void LLTextEditor::drawLineNumbers() { - if (!style->isVisible()) - { - return; - } - - const LLFontGL* font = mGLFont; - - LLColor4 color = style->getColor(); + LLGLSUIDefault gls_ui; - if ( style->getFontString()[0] ) + LLRect scrolled_view_rect = mScroller->getVisibleContentRect(); + LLRect content_rect = mScroller->getContentWindowRect(); + LLLocalClipRect clip(content_rect); + S32 first_line = getFirstVisibleLine(); + S32 num_lines = getLineCount(); + if (first_line >= num_lines) { - font = style->getFont(); + return; } - - U8 font_flags = LLFontGL::NORMAL; - if (style->mBold) - { - font_flags |= LLFontGL::BOLD; - } - if (style->mItalic) - { - font_flags |= LLFontGL::ITALIC; - } - if (style->mUnderline) - { - font_flags |= LLFontGL::UNDERLINE; - } + S32 cursor_line = getCurrentLine(); - if (style->getIsEmbeddedItem()) + if (mShowLineNumbers) { - static LLUIColor text_embedded_item_readonly_color = LLUIColorTable::instance().getColor("TextEmbeddedItemReadOnlyColor"); - static LLUIColor text_embedded_item_color = LLUIColorTable::instance().getColor("TextEmbeddedItemColor"); - if (mReadOnly) - { - color = text_embedded_item_readonly_color; - } - else - { - color = text_embedded_item_color; - } - } + S32 last_line_num = -1; - F32 y_top = y + (F32)llround(font->getLineHeight()); + for (S32 cur_line = first_line; cur_line < num_lines; cur_line++) + { + line_info& line = mLineInfoList[cur_line]; - if( selection_left > seg_start ) - { - // Draw normally - S32 start = seg_start; - S32 end = llmin( selection_left, seg_end ); - S32 length = end - start; - font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, 0, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); - } - x = *right_x; - - if( (selection_left < seg_end) && (selection_right > seg_start) ) - { - // Draw reversed - S32 start = llmax( selection_left, seg_start ); - S32 end = llmin( selection_right, seg_end ); - S32 length = end - start; + if ((line.mTop - scrolled_view_rect.mBottom) < mTextRect.mBottom) + { + break; + } - font->render(text, start, x, y_top, - LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ), - LLFontGL::LEFT, LLFontGL::TOP, 0, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); - } - x = *right_x; - if( selection_right < seg_end ) - { - // Draw normally - S32 start = llmax( selection_right, seg_start ); - S32 end = seg_end; - S32 length = end - start; - font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, 0, LLFontGL::NO_SHADOW, length, S32_MAX, right_x, mAllowEmbeddedItems); + S32 line_bottom = line.mBottom - scrolled_view_rect.mBottom + mTextRect.mBottom; + // draw the line numbers + if(line.mLineNum != last_line_num && line.mTop <= scrolled_view_rect.mTop) + { + const LLFontGL *num_font = LLFontGL::getFontMonospace(); + const LLWString ltext = utf8str_to_wstring(llformat("%d", line.mLineNum )); + BOOL is_cur_line = cursor_line == line.mLineNum; + const U8 style = is_cur_line ? LLFontGL::BOLD : LLFontGL::NORMAL; + const LLColor4 fg_color = is_cur_line ? mCursorColor : mReadOnlyFgColor; + num_font->render( + ltext, // string to draw + 0, // begin offset + UI_TEXTEDITOR_LINE_NUMBER_MARGIN - 2, // x + line_bottom, // y + fg_color, + LLFontGL::RIGHT, // horizontal alignment + LLFontGL::BOTTOM, // vertical alignment + style, + LLFontGL::NO_SHADOW, + S32_MAX, // max chars + UI_TEXTEDITOR_LINE_NUMBER_MARGIN - 2); // max pixels + last_line_num = line.mLineNum; + } + } } - } - +} void LLTextEditor::draw() { - // do on-demand reflow - if (mReflowNeeded) - { - updateLineStartList(); - mReflowNeeded = FALSE; - } + // reflow if needed, on demand + reflow(); // then update scroll position, as cursor may have moved - if (mScrollNeeded) - { - updateScrollFromCursor(); - mScrollNeeded = FALSE; - } + updateScrollFromCursor(); - { - static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); - LLLocalClipRect clip(LLRect(0, getRect().getHeight(), getRect().getWidth() - (mScrollbar->getVisible() ? scrollbar_size : 0), 0)); + LLColor4 bg_color = mReadOnly + ? mReadOnlyBgColor.get() + : hasFocus() + ? mFocusBgColor.get() + : mWriteableBgColor.get(); + + mDocumentPanel->setBackgroundColor(bg_color); - bindEmbeddedChars( mGLFont ); + drawChildren(); + drawBackground(); //overlays scrolling panel bg + drawLineNumbers(); - drawBackground(); + { + LLLocalClipRect clip(mTextRect); drawSelectionBackground(); drawPreeditMarker(); drawText(); drawCursor(); - - unbindEmbeddedChars( mGLFont ); - - //RN: the decision was made to always show the orange border for keyboard focus but do not put an insertion caret - // when in readonly mode - mBorder->setKeyboardFocusHighlight( gFocusMgr.getKeyboardFocus() == this);// && !mReadOnly); } - - LLView::draw(); // Draw children (scrollbar and border) - // remember if we are supposed to be at the bottom of the buffer - mScrolledToBottom = isScrolledToBottom(); + //RN: the decision was made to always show the orange border for keyboard focus but do not put an insertion caret + // when in readonly mode + mBorder->setKeyboardFocusHighlight( hasFocus() );// && !mReadOnly); } -void LLTextEditor::onTabInto() +S32 LLTextEditor::getFirstVisibleLine() const { - // selecting all on tabInto causes users to hit tab twice and replace their text with a tab character - // theoretically, one could selectAll if mTabsToNextField is true, but we couldn't think of a use case - // where you'd want to select all anyway - // preserve insertion point when returning to the editor - //selectAll(); + LLRect visible_region = mScroller->getVisibleContentRect(); + + // binary search for line that starts before top of visible buffer + line_list_t::const_iterator iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), visible_region.mTop, compare_bottom()); + + return iter - mLineInfoList.begin(); } // virtual @@ -3270,103 +3336,62 @@ S32 LLTextEditor::getPos( S32 line, S32 offset ) void LLTextEditor::changePage( S32 delta ) { + const S32 PIXEL_OVERLAP_ON_PAGE_CHANGE = 10; + if (delta == 0) return; + + //RN: use pixel heights S32 line, offset; getLineAndOffset( mCursorPos, &line, &offset ); - // get desired x position to remember previous position - S32 desired_x_pixel = mDesiredXPixel; + LLRect cursor_rect = getLocalRectFromDocIndex(mCursorPos); - // allow one line overlap - S32 page_size = mScrollbar->getPageSize() - 1; if( delta == -1 ) { - line = llmax( line - page_size, 0); - setCursorPos(getPos( line, offset )); - mScrollbar->setDocPos( mScrollbar->getDocPos() - page_size ); + mScroller->pageUp(PIXEL_OVERLAP_ON_PAGE_CHANGE); } else if( delta == 1 ) { - setCursorPos(getPos( line + page_size, offset )); - mScrollbar->setDocPos( mScrollbar->getDocPos() + page_size ); + mScroller->pageDown(PIXEL_OVERLAP_ON_PAGE_CHANGE); } - // put desired position into remember-buffer after setCursorPos() - mDesiredXPixel = desired_x_pixel; - - if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax())) + if (getLocalRectFromDocIndex(mCursorPos) == cursor_rect) + { + // cursor didn't change apparent position, so move to top or bottom of document, respectively + if (delta < 0) + { + startOfDoc(); + } + else + { + endOfDoc(); + } + } + else { - mOnScrollEndCallback(mOnScrollEndData); + setCursorAtLocalPos(cursor_rect.getCenterX(), cursor_rect.getCenterY(), true, false); } } void LLTextEditor::changeLine( S32 delta ) { - bindEmbeddedChars(mGLFont); - S32 line, offset; getLineAndOffset( mCursorPos, &line, &offset ); - S32 line_start = getLineStart(line); - - // set desired x position to remembered previous position - S32 desired_x_pixel = mDesiredXPixel; - // if remembered position was reset (thus -1), calculate new one here - if( desired_x_pixel == -1 ) - { - LLWString text(getWText()); - desired_x_pixel = mGLFont->getWidth(text.c_str(), line_start, offset, mAllowEmbeddedItems ); - } - - S32 new_line = 0; + S32 new_line = line; if( (delta < 0) && (line > 0 ) ) { new_line = line - 1; } - else - if( (delta > 0) && (line < (getLineCount() - 1)) ) + else if( (delta > 0) && (line < (getLineCount() - 1)) ) { new_line = line + 1; } - else - { - unbindEmbeddedChars(mGLFont); - return; - } - - S32 num_lines = getLineCount(); - S32 new_line_start = getLineStart(new_line); - S32 new_line_end = getLength(); - if (new_line + 1 < num_lines) - { - new_line_end = getLineStart(new_line + 1) - 1; - } - S32 new_line_len = new_line_end - new_line_start; + LLRect visible_region = mScroller->getVisibleContentRect(); - S32 new_offset; - LLWString text(getWText()); - new_offset = mGLFont->charFromPixelOffset(text.c_str(), new_line_start, - (F32)desired_x_pixel, - (F32)mTextRect.getWidth(), - new_line_len, - mAllowEmbeddedItems); - - setCursorPos (getPos( new_line, new_offset )); - - // put desired position into remember-buffer after setCursorPos() - mDesiredXPixel = desired_x_pixel; - unbindEmbeddedChars(mGLFont); -} - -BOOL LLTextEditor::isScrolledToTop() -{ - return mScrollbar->isAtBeginning(); -} - -BOOL LLTextEditor::isScrolledToBottom() -{ - return mScrollbar->isAtEnd(); + S32 new_cursor_pos = getDocIndexFromLocalCoord(mDesiredXPixel, mLineInfoList[new_line].mBottom + mTextRect.mBottom - visible_region.mBottom, TRUE); + setCursorPos(new_cursor_pos, true); } @@ -3383,32 +3408,11 @@ void LLTextEditor::setCursorAndScrollToEnd() { deselect(); endOfDoc(); - needsScroll(); } void LLTextEditor::getLineAndColumnForPosition( S32 position, S32* line, S32* col, BOOL include_wordwrap ) { - if( include_wordwrap ) - { - getLineAndOffset( mCursorPos, line, col ); - } - else - { - LLWString text = getWText(); - S32 line_count = 0; - S32 line_start = 0; - S32 i; - for( i = 0; text[i] && (i < position); i++ ) - { - if( '\n' == text[i] ) - { - line_start = i + 1; - line_count++; - } - } - *line = line_count; - *col = i - line_start; - } + getLineAndOffset( mCursorPos, line, col, include_wordwrap ); } void LLTextEditor::getCurrentLineAndColumn( S32* line, S32* col, BOOL include_wordwrap ) @@ -3444,64 +3448,39 @@ void LLTextEditor::endOfLine() } } -void LLTextEditor::endOfDoc() +void LLTextEditor::startOfDoc() { - mScrollbar->setDocPos(mScrollbar->getDocPosMax()); - mScrolledToBottom = true; + setCursorPos(0); +} - S32 len = getLength(); - if( len ) - { - setCursorPos(len); - } - if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax())) - { - mOnScrollEndCallback(mOnScrollEndData); - } +void LLTextEditor::endOfDoc() +{ + setCursorPos(getLength()); } // Sets the scrollbar from the cursor position void LLTextEditor::updateScrollFromCursor() { - mScrollbar->setDocSize( getLineCount() ); - if (mReadOnly) { // no cursor in read only mode return; } - S32 line, offset; - getLineAndOffset( mCursorPos, &line, &offset ); - - S32 page_size = mScrollbar->getPageSize(); - - if( line < mScrollbar->getDocPos() ) - { - // scroll so that the cursor is at the top of the page - mScrollbar->setDocPos( line ); - } - else if( line >= mScrollbar->getDocPos() + page_size - 1 ) + if (!mScrollNeeded) { - S32 new_pos = 0; - if( line < mScrollbar->getDocSize() - 1 ) - { - // scroll so that the cursor is one line above the bottom of the page, - new_pos = line - page_size + 1; - } - else - { - // if there is less than a page of text remaining, scroll so that the cursor is at the bottom - new_pos = mScrollbar->getDocPosMax(); - } - mScrollbar->setDocPos( new_pos ); + return; } + mScrollNeeded = FALSE; - // Check if we've scrolled to bottom for callback if asked for callback - if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax())) - { - mOnScrollEndCallback(mOnScrollEndData); - } + S32 line, offset; + getLineAndOffset( mCursorPos, &line, &offset ); + + // scroll so that the cursor is at the top of the page + LLRect scroller_doc_window = mScroller->getVisibleContentRect(); + LLRect cursor_rect_doc = getLocalRectFromDocIndex(mCursorPos); + cursor_rect_doc.translate(scroller_doc_window.mLeft, scroller_doc_window.mBottom); + mScroller->scrollToShowRect(cursor_rect_doc, LLRect(0, scroller_doc_window.getHeight() - 5, scroller_doc_window.getWidth(), 5)); } void LLTextEditor::reshape(S32 width, S32 height, BOOL called_from_parent) @@ -3513,13 +3492,6 @@ void LLTextEditor::reshape(S32 width, S32 height, BOOL called_from_parent) updateTextRect(); needsReflow(); - - // propagate shape information to scrollbar - mScrollbar->setDocSize( getLineCount() ); - - S32 line_height = llround( mGLFont->getLineHeight() ); - S32 page_lines = mTextRect.getHeight() / line_height; - mScrollbar->setPageSize( page_lines ); } void LLTextEditor::autoIndent() @@ -3564,7 +3536,7 @@ void LLTextEditor::insertText(const std::string &new_text) deleteSelection(TRUE); } - setCursorPos(mCursorPos + insert( mCursorPos, utf8str_to_wstring(new_text), FALSE )); + setCursorPos(mCursorPos + insert( mCursorPos, utf8str_to_wstring(new_text), FALSE, LLTextSegmentPtr() )); needsReflow(); @@ -3585,17 +3557,23 @@ void LLTextEditor::appendColoredText(const std::string &new_text, highlight->parseFullLineHighlights(new_text, &lcolor); } - LLStyleSP style(new LLStyle); - style->setVisible(true); - style->setColor(lcolor); - style->setFontName(font_name); - appendStyledText(new_text, allow_undo, prepend_newline, style); + LLStyle::Params style_params; + style_params.color = lcolor; + if (font_name.empty()) + { + style_params.font = mDefaultFont; + } + else + { + style_params.font.name = font_name; + } + appendStyledText(new_text, allow_undo, prepend_newline, style_params); } void LLTextEditor::appendStyledText(const std::string &new_text, bool allow_undo, bool prepend_newline, - LLStyleSP stylep) + const LLStyle::Params& style_params) { S32 part = (S32)LLTextParser::WHOLE; if(mParseHTML) @@ -3605,14 +3583,10 @@ void LLTextEditor::appendStyledText(const std::string &new_text, std::string text = new_text; while ( findHTML(text, &start, &end) ) { - LLStyleSP html(new LLStyle); - html->setVisible(true); - html->setColor(mLinkColor); - if (stylep) - { - html->setFontName(stylep->getFontString()); - } - html->mUnderline = TRUE; + LLStyle::Params link_params = style_params; + link_params.color = mLinkColor; + link_params.font.style = "UNDERLINE"; + link_params.link_href = text.substr(start,end-start); if (start > 0) { @@ -3626,11 +3600,10 @@ void LLTextEditor::appendStyledText(const std::string &new_text, part = (S32)LLTextParser::MIDDLE; } std::string subtext=text.substr(0,start); - appendHighlightedText(subtext,allow_undo, prepend_newline, part, stylep); + appendHighlightedText(subtext,allow_undo, prepend_newline, part, style_params); } - html->setLinkHREF(text.substr(start,end-start)); - appendText(text.substr(start, end-start),allow_undo, prepend_newline, html); + appendText(text.substr(start, end-start),allow_undo, prepend_newline, link_params); if (end < (S32)text.length()) { text = text.substr(end,text.length() - end); @@ -3643,11 +3616,11 @@ void LLTextEditor::appendStyledText(const std::string &new_text, } } if (part != (S32)LLTextParser::WHOLE) part=(S32)LLTextParser::END; - if (end < (S32)text.length()) appendHighlightedText(text,allow_undo, prepend_newline, part, stylep); + if (end < (S32)text.length()) appendHighlightedText(text,allow_undo, prepend_newline, part, style_params); } else { - appendHighlightedText(new_text, allow_undo, prepend_newline, part, stylep); + appendHighlightedText(new_text, allow_undo, prepend_newline, part, style_params); } } @@ -3655,38 +3628,40 @@ void LLTextEditor::appendHighlightedText(const std::string &new_text, bool allow_undo, bool prepend_newline, S32 highlight_part, - LLStyleSP stylep) + const LLStyle::Params& style_params) { if (mParseHighlights) { LLTextParser* highlight = LLTextParser::getInstance(); - if (highlight && stylep) + if (highlight && !style_params.isDefault()) { - LLSD pieces = highlight->parsePartialLineHighlights(new_text, stylep->getColor(), highlight_part); + LLStyle::Params highlight_params = style_params; + + LLSD pieces = highlight->parsePartialLineHighlights(new_text, highlight_params.color(), highlight_part); bool lprepend=prepend_newline; for (S32 i=0;i<pieces.size();i++) { LLSD color_llsd = pieces[i]["color"]; LLColor4 lcolor; lcolor.setValue(color_llsd); - LLStyleSP lstylep(new LLStyle(*stylep)); - lstylep->setColor(lcolor); + highlight_params.color = lcolor; if (i != 0 && (pieces.size() > 1) ) lprepend=FALSE; - appendText((std::string)pieces[i]["text"], allow_undo, lprepend, lstylep); + appendText((std::string)pieces[i]["text"], allow_undo, lprepend, highlight_params); } return; } } - appendText(new_text, allow_undo, prepend_newline, stylep); + appendText(new_text, allow_undo, prepend_newline, style_params); } // Appends new text to end of document void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool prepend_newline, - const LLStyleSP stylep) + const LLStyle::Params& stylep) { + if (new_text.empty()) return; + // Save old state - BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()); S32 selection_start = mSelectionStart; S32 selection_end = mSelectionEnd; BOOL was_selecting = mIsSelecting; @@ -3698,49 +3673,93 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool setCursorPos(old_length); + LLWString wide_text; + // Add carriage return if not first line if (getLength() != 0 && prepend_newline) { - std::string final_text = "\n"; - final_text += new_text; - append(utf8str_to_wstring(final_text), TRUE); + wide_text = utf8str_to_wstring(std::string("\n") + new_text); } else { - append(utf8str_to_wstring(new_text), TRUE ); + wide_text = utf8str_to_wstring(new_text); } - if (stylep) + LLTextSegmentPtr segmentp; + if (!stylep.isDefault()) { S32 segment_start = old_length; - S32 segment_end = getLength(); - LLTextSegment* segment = new LLTextSegment(stylep, segment_start, segment_end ); - mSegments.push_back(segment); + S32 segment_end = old_length + wide_text.size(); + segmentp = new LLNormalTextSegment(new LLStyle(stylep), segment_start, segment_end, *this ); } + + append(wide_text, TRUE, segmentp); needsReflow(); // Set the cursor and scroll position - // Maintain the scroll position unless the scroll was at the end of the doc (in which - // case, move it to the new end of the doc) or unless the user was doing actively selecting - if( was_scrolled_to_bottom && !was_selecting ) - { - if( selection_start != selection_end ) - { - // maintain an existing non-active selection - mSelectionStart = selection_start; - mSelectionEnd = selection_end; - } - endOfDoc(); - } - else if( selection_start != selection_end ) + if( selection_start != selection_end ) { mSelectionStart = selection_start; mSelectionEnd = selection_end; + mIsSelecting = was_selecting; + setCursorPos(cursor_pos); + } + else if( cursor_was_at_end ) + { + setCursorPos(getLength()); + } + else + { + setCursorPos(cursor_pos); + } + + if( !allow_undo ) + { + blockUndo(); + } +} + + +void LLTextEditor::appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool prepend_newline) +{ + // Save old state + S32 selection_start = mSelectionStart; + S32 selection_end = mSelectionEnd; + BOOL was_selecting = mIsSelecting; + S32 cursor_pos = mCursorPos; + S32 old_length = getLength(); + BOOL cursor_was_at_end = (mCursorPos == old_length); + + deselect(); + + setCursorPos(old_length); + + LLWString widget_wide_text; + // Add carriage return if not first line + if (getLength() != 0 + && prepend_newline) + { + widget_wide_text = utf8str_to_wstring(std::string("\n") + widget_text); + } + else + { + widget_wide_text = utf8str_to_wstring(widget_text); + } + LLTextSegmentPtr segment = new LLInlineViewSegment(widget, old_length, old_length + widget_text.size()); + append(widget_wide_text, FALSE, segment); + + needsReflow(); + + // Set the cursor and scroll position + if( selection_start != selection_end ) + { + mSelectionStart = selection_start; + mSelectionEnd = selection_end; mIsSelecting = was_selecting; setCursorPos(cursor_pos); @@ -3767,26 +3786,79 @@ void LLTextEditor::removeTextFromEnd(S32 num_chars) remove(getLength() - num_chars, num_chars, FALSE); S32 len = getLength(); - mCursorPos = llclamp(mCursorPos, 0, len); + setCursorPos (llclamp(mCursorPos, 0, len)); mSelectionStart = llclamp(mSelectionStart, 0, len); mSelectionEnd = llclamp(mSelectionEnd, 0, len); - pruneSegments(); - - // pruneSegments will invalidate mLineStartList. - updateLineStartList(); + reflow(); needsScroll(); } /////////////////////////////////////////////////////////////////// // Returns change in number of characters in mWText -S32 LLTextEditor::insertStringNoUndo(const S32 pos, const LLWString &wstr) +S32 LLTextEditor::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextEditor::segment_vec_t* segments ) { - LLWString text(getWText()); + LLWString text(getWText()); S32 old_len = text.length(); // length() returns character length S32 insert_len = wstr.length(); + pos = getEditableIndex(pos, true); + + segment_set_t::iterator seg_iter = getSegIterContaining(pos); + + LLTextSegmentPtr default_segment; + + LLTextSegmentPtr segmentp; + if (seg_iter != mSegments.end()) + { + segmentp = *seg_iter; + } + else + { + //segmentp = mSegments.back(); + return pos; + } + + if (segmentp->canEdit()) + { + segmentp->setEnd(segmentp->getEnd() + insert_len); + if (seg_iter != mSegments.end()) + { + ++seg_iter; + } + } + else + { + // create default editable segment to hold new text + default_segment = new LLNormalTextSegment( getDefaultStyle(), pos, pos + insert_len, *this); + } + + // shift remaining segments to right + for(;seg_iter != mSegments.end(); ++seg_iter) + { + LLTextSegmentPtr segmentp = *seg_iter; + segmentp->setStart(segmentp->getStart() + insert_len); + segmentp->setEnd(segmentp->getEnd() + insert_len); + } + + // insert new segments + if (segments) + { + if (default_segment.notNull()) + { + // potentially overwritten by segments passed in + insertSegment(default_segment); + } + for (segment_vec_t::iterator seg_iter = segments->begin(); + seg_iter != segments->end(); + ++seg_iter) + { + LLTextSegment* segmentp = *seg_iter; + insertSegment(segmentp); + } + } + text.insert(pos, wstr); getViewModel()->setDisplay(text); @@ -3797,14 +3869,67 @@ S32 LLTextEditor::insertStringNoUndo(const S32 pos, const LLWString &wstr) insert_len = getLength() - old_len; } + onValueChange(pos, pos + insert_len); + return insert_len; } S32 LLTextEditor::removeStringNoUndo(S32 pos, S32 length) { LLWString text(getWText()); + segment_set_t::iterator seg_iter = getSegIterContaining(pos); + while(seg_iter != mSegments.end()) + { + LLTextSegmentPtr segmentp = *seg_iter; + S32 end = pos + length; + if (segmentp->getStart() < pos) + { + // deleting from middle of segment + if (segmentp->getEnd() > end) + { + segmentp->setEnd(segmentp->getEnd() - length); + } + // truncating segment + else + { + segmentp->setEnd(pos); + } + } + else if (segmentp->getStart() < end) + { + // deleting entire segment + if (segmentp->getEnd() <= end) + { + // remove segment + segmentp->unlinkFromDocument(this); + segment_set_t::iterator seg_to_erase(seg_iter++); + mSegments.erase(seg_to_erase); + continue; + } + // deleting head of segment + else + { + segmentp->setStart(pos); + segmentp->setEnd(segmentp->getEnd() - length); + } + } + else + { + // shifting segments backward to fill deleted portion + segmentp->setStart(segmentp->getStart() - length); + segmentp->setEnd(segmentp->getEnd() - length); + } + ++seg_iter; + } + text.erase(pos, length); getViewModel()->setDisplay(text); + + // recreate default segment in case we erased everything + createDefaultSegment(); + + onValueChange(pos, pos); + return -length; // This will be wrong if someone calls removeStringNoUndo with an excessive length } @@ -3817,6 +3942,9 @@ S32 LLTextEditor::overwriteCharNoUndo(S32 pos, llwchar wc) LLWString text(getWText()); text[pos] = wc; getViewModel()->setDisplay(text); + + onValueChange(pos, pos + 1); + return 1; } @@ -3887,21 +4015,25 @@ void LLTextEditor::updateTextRect() { static LLUICachedControl<S32> texteditor_border ("UITextEditorBorder", 0); static LLUICachedControl<S32> texteditor_h_pad ("UITextEditorHPad", 0); - static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); - static LLUICachedControl<S32> texteditor_vpad_top ("UITextEditorVPadTop", 0); - - mTextRect.setOriginAndSize( - texteditor_border + texteditor_h_pad, - texteditor_border, - getRect().getWidth() - scrollbar_size - 2 * (texteditor_border + texteditor_h_pad), - getRect().getHeight() - 2 * texteditor_border - texteditor_vpad_top ); + + LLRect old_text_rect = mTextRect; + mTextRect = mScroller->getContentWindowRect(); + mTextRect.stretch(texteditor_border * -1); + mTextRect.mLeft += texteditor_h_pad; + mTextRect.mLeft += mShowLineNumbers ? UI_TEXTEDITOR_LINE_NUMBER_MARGIN : 0; + if (mTextRect != old_text_rect) + { + needsReflow(); + } } +LLFastTimer::DeclareTimer FTM_TEXT_EDITOR_LOAD_KEYWORD("Text Editor Load Keywords"); void LLTextEditor::loadKeywords(const std::string& filename, const std::vector<std::string>& funcs, const std::vector<std::string>& tooltips, const LLColor3& color) { + LLFastTimer ft(FTM_TEXT_EDITOR_LOAD_KEYWORD); if(mKeywords.loadFromFile(filename)) { S32 count = llmin(funcs.size(), tooltips.size()); @@ -3910,133 +4042,115 @@ void LLTextEditor::loadKeywords(const std::string& filename, std::string name = utf8str_trim(funcs[i]); mKeywords.addToken(LLKeywordToken::WORD, name, color, tooltips[i] ); } + segment_vec_t segment_list; + mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this); - mKeywords.findSegments( &mSegments, getWText(), mDefaultColor.get() ); - - llassert( mSegments.front()->getStart() == 0 ); - llassert( mSegments.back()->getEnd() == getLength() ); + mSegments.clear(); + segment_set_t::iterator insert_it = mSegments.begin(); + for (segment_vec_t::iterator list_it = segment_list.begin(); list_it != segment_list.end(); ++list_it) + { + insert_it = mSegments.insert(insert_it, *list_it); + } } } -void LLTextEditor::updateSegments() +void LLTextEditor::createDefaultSegment() { - if (mKeywords.isLoaded()) - { - // HACK: No non-ascii keywords for now - mKeywords.findSegments(&mSegments, getWText(), mDefaultColor.get()); - } - else if (mAllowEmbeddedItems) - { - findEmbeddedItemSegments(); - } - - // Make sure we have at least one segment - if (mSegments.size() == 1 && mSegments[0]->getIsDefault()) - { - delete mSegments[0]; - mSegments.clear(); // create default segment - } + // ensures that there is always at least one segment if (mSegments.empty()) { - LLColor4 text_color = ( mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get() ); - LLTextSegment* default_segment = new LLTextSegment( text_color, 0, getLength() ); - default_segment->setIsDefault(TRUE); - mSegments.push_back(default_segment); + LLTextSegmentPtr default_segment = new LLNormalTextSegment( getDefaultStyle(), 0, getLength() + 1, *this); + mSegments.insert(default_segment); + default_segment->linkToDocument(this); } } -// Only effective if text was removed from the end of the editor -// *NOTE: Using this will invalidate references to mSegments from mLineStartList. -void LLTextEditor::pruneSegments() +LLStyleSP LLTextEditor::getDefaultStyle() { - S32 len = getLength(); - // Find and update the first valid segment - segment_list_t::iterator iter = mSegments.end(); - while(iter != mSegments.begin()) - { - --iter; - LLTextSegment* seg = *iter; - if (seg->getStart() < len) - { - // valid segment - if (seg->getEnd() > len) - { - seg->setEnd(len); - } - break; // done - } - } - if (iter != mSegments.end()) - { - // erase invalid segments - ++iter; - std::for_each(iter, mSegments.end(), DeletePointer()); - mSegments.erase(iter, mSegments.end()); - } - else - { - llwarns << "Tried to erase end of empty LLTextEditor" << llendl; - } + LLColor4 text_color = ( mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get() ); + return LLStyleSP(new LLStyle(LLStyle::Params().color(text_color).font(mDefaultFont))); } -void LLTextEditor::findEmbeddedItemSegments() +LLFastTimer::DeclareTimer FTM_UPDATE_TEXT_SEGMENTS("Update Text Segments"); +void LLTextEditor::updateSegments() { - mHoverSegment = NULL; - std::for_each(mSegments.begin(), mSegments.end(), DeletePointer()); - mSegments.clear(); - - BOOL found_embedded_items = FALSE; - LLWString text = getWText(); - S32 idx = 0; - while( text[idx] ) + LLFastTimer ft(FTM_UPDATE_TEXT_SEGMENTS); + if (mKeywords.isLoaded()) { - if( text[idx] >= FIRST_EMBEDDED_CHAR && text[idx] <= LAST_EMBEDDED_CHAR ) - { - found_embedded_items = TRUE; - break; + // HACK: No non-ascii keywords for now + segment_vec_t segment_list; + mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this); + + mSegments.clear(); + segment_set_t::iterator insert_it = mSegments.begin(); + for (segment_vec_t::iterator list_it = segment_list.begin(); list_it != segment_list.end(); ++list_it) + { + insert_it = mSegments.insert(insert_it, *list_it); } - ++idx; } - if( !found_embedded_items ) + createDefaultSegment(); + +} + +void LLTextEditor::insertSegment(LLTextSegmentPtr segment_to_insert) +{ + if (segment_to_insert.isNull()) { return; } - S32 text_len = text.length(); - - BOOL in_text = FALSE; - - LLColor4 text_color = ( mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get() ); + segment_set_t::iterator cur_seg_iter = getSegIterContaining(segment_to_insert->getStart()); - if( idx > 0 ) + if (cur_seg_iter == mSegments.end()) { - mSegments.push_back( new LLTextSegment( text_color, 0, text_len ) ); // text - in_text = TRUE; + mSegments.insert(segment_to_insert); + segment_to_insert->linkToDocument(this); } - - LLStyleSP embedded_style(new LLStyle); - embedded_style->setIsEmbeddedItem( TRUE ); - - // Start with i just after the first embedded item - while ( text[idx] ) + else { - if( text[idx] >= FIRST_EMBEDDED_CHAR && text[idx] <= LAST_EMBEDDED_CHAR ) + LLTextSegmentPtr cur_segmentp = *cur_seg_iter; + if (cur_segmentp->getStart() < segment_to_insert->getStart()) { - if( in_text ) - { - mSegments.back()->setEnd( idx ); - } - mSegments.push_back( new LLTextSegment( embedded_style, idx, idx + 1 ) ); // item - in_text = FALSE; + S32 old_segment_end = cur_segmentp->getEnd(); + // split old at start point for new segment + cur_segmentp->setEnd(segment_to_insert->getStart()); + // advance to next segment + ++cur_seg_iter; + // insert remainder of old segment + LLTextSegmentPtr remainder_segment = new LLNormalTextSegment( cur_segmentp->getStyle(), segment_to_insert->getStart(), old_segment_end, *this); + cur_seg_iter = mSegments.insert(cur_seg_iter, remainder_segment); + remainder_segment->linkToDocument(this); + // insert new segment before remainder of old segment + cur_seg_iter = mSegments.insert(cur_seg_iter, segment_to_insert); + + segment_to_insert->linkToDocument(this); + // move to "remanider" segment and start truncation there + ++cur_seg_iter; } else - if( !in_text ) { - mSegments.push_back( new LLTextSegment( text_color, idx, text_len ) ); // text - in_text = TRUE; + cur_seg_iter = mSegments.insert(cur_seg_iter, segment_to_insert); + ++cur_seg_iter; + segment_to_insert->linkToDocument(this); + } + + // now delete/truncate remaining segments as necessary + while(cur_seg_iter != mSegments.end()) + { + cur_segmentp = *cur_seg_iter; + if (cur_segmentp->getEnd() <= segment_to_insert->getEnd()) + { + cur_segmentp->unlinkFromDocument(this); + segment_set_t::iterator seg_to_erase(cur_seg_iter++); + mSegments.erase(seg_to_erase); + } + else + { + cur_segmentp->setStart(segment_to_insert->getEnd()); + break; + } } - ++idx; } } @@ -4050,9 +4164,9 @@ BOOL LLTextEditor::handleMouseUpOverSegment(S32 x, S32 y, MASK mask) if (mParseHTML && mHTML.length() > 0) { //Special handling for slurls - if ( (mSecondlifeURLcallback!=NULL) && !(*mSecondlifeURLcallback)(mHTML) ) + if ( (sSecondlifeURLcallback!=NULL) && !(*sSecondlifeURLcallback)(mHTML) ) { - if (mURLcallback!=NULL) (*mURLcallback)(mHTML); + if (sURLcallback!=NULL) (*sURLcallback)(mHTML); } mHTML.clear(); } @@ -4063,44 +4177,37 @@ BOOL LLTextEditor::handleMouseUpOverSegment(S32 x, S32 y, MASK mask) // Finds the text segment (if any) at the give local screen position -const LLTextSegment* LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y ) const +LLTextSegmentPtr LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y ) { // Find the cursor position at the requested local screen position - S32 offset = getCursorPosFromLocalCoord( x, y, FALSE ); - S32 idx = getSegmentIdxAtOffset(offset); - return idx >= 0 ? mSegments[idx] : NULL; -} - -const LLTextSegment* LLTextEditor::getSegmentAtOffset(S32 offset) const -{ - S32 idx = getSegmentIdxAtOffset(offset); - return idx >= 0 ? mSegments[idx] : NULL; -} - -S32 LLTextEditor::getSegmentIdxAtOffset(S32 offset) const -{ - if (mSegments.empty() || offset < 0 || offset >= getLength()) + S32 offset = getDocIndexFromLocalCoord( x, y, FALSE ); + segment_set_t::iterator seg_iter = getSegIterContaining(offset); + if (seg_iter != mSegments.end()) { - return -1; + return *seg_iter; } else { - S32 segidx, segoff; - getSegmentAndOffset(offset, &segidx, &segoff); - return segidx; + return LLTextSegmentPtr(); } } -void LLTextEditor::onMouseCaptureLost() +LLTextEditor::segment_set_t::iterator LLTextEditor::getSegIterContaining(S32 index) { - endSelection(); + segment_set_t::iterator it = mSegments.upper_bound(new LLIndexSegment(index)); + return it; +} + +LLTextEditor::segment_set_t::const_iterator LLTextEditor::getSegIterContaining(S32 index) const +{ + LLTextEditor::segment_set_t::const_iterator it = mSegments.upper_bound(new LLIndexSegment(index)); + return it; } -void LLTextEditor::setOnScrollEndCallback(void (*callback)(void*), void* userdata) + +void LLTextEditor::onMouseCaptureLost() { - mOnScrollEndCallback = callback; - mOnScrollEndData = userdata; - mScrollbar->setOnScrollEndCallback(callback, userdata); + endSelection(); } /////////////////////////////////////////////////////////////////// @@ -4186,7 +4293,7 @@ BOOL LLTextEditor::importBuffer(const char* buffer, S32 length ) delete[] text; - setCursorPos(0); + startOfDoc(); deselect(); needsReflow(); @@ -4207,74 +4314,6 @@ BOOL LLTextEditor::exportBuffer(std::string &buffer ) return TRUE; } -////////////////////////////////////////////////////////////////////////// -// LLTextSegment - -LLTextSegment::LLTextSegment(S32 start) : - mStart(start), - mEnd(0), - mToken(NULL), - mIsDefault(FALSE) -{ -} -LLTextSegment::LLTextSegment( const LLStyleSP& style, S32 start, S32 end ) : - mStyle( style ), - mStart( start), - mEnd( end ), - mToken(NULL), - mIsDefault(FALSE) -{ -} -LLTextSegment::LLTextSegment( const LLColor4& color, S32 start, S32 end, BOOL is_visible) : - mStyle(new LLStyle(is_visible,color,LLStringUtil::null)), - mStart( start), - mEnd( end ), - mToken(NULL), - mIsDefault(FALSE) -{ -} -LLTextSegment::LLTextSegment( const LLColor4& color, S32 start, S32 end ) : - mStyle(new LLStyle(TRUE, color,LLStringUtil::null )), - mStart( start), - mEnd( end ), - mToken(NULL), - mIsDefault(FALSE) -{ -} -LLTextSegment::LLTextSegment( const LLColor3& color, S32 start, S32 end ) : - mStyle(new LLStyle(TRUE, color,LLStringUtil::null )), - mStart( start), - mEnd( end ), - mToken(NULL), - mIsDefault(FALSE) -{ -} - -BOOL LLTextSegment::getToolTip(std::string& msg) const -{ - if (mToken && !mToken->getToolTip().empty()) - { - const LLWString& wmsg = mToken->getToolTip(); - msg = wstring_to_utf8str(wmsg); - return TRUE; - } - return FALSE; -} - - - -void LLTextSegment::dump() const -{ - llinfos << "Segment [" << -// mColor.mV[VX] << ", " << -// mColor.mV[VY] << ", " << -// mColor.mV[VZ] << "]\t[" << - mStart << ", " << - getEnd() << "]" << - llendl; - -} - /////////////////////////////////////////////////////////////////// // Refactoring note: We may eventually want to replace this with boost::regex or // boost::tokenizer capabilities since we've already fixed at least two JIRAs @@ -4473,7 +4512,7 @@ void LLTextEditor::resetPreedit() deselect(); } - mCursorPos = mPreeditPositions.front(); + setCursorPos(mPreeditPositions.front()); removeStringNoUndo(mCursorPos, mPreeditPositions.back() - mCursorPos); insertStringNoUndo(mCursorPos, mPreeditOverwrittenWString); @@ -4557,7 +4596,7 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect return FALSE; } - const S32 first_visible_line = mScrollbar->getDocPos(); + const S32 first_visible_line = getFirstVisibleLine(); if (query < getLineStart(first_visible_line)) { return FALSE; @@ -4583,11 +4622,11 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect const LLWString textString(getWText()); const llwchar * const text = textString.c_str(); - const S32 line_height = llround(mGLFont->getLineHeight()); + const S32 line_height = llround(mDefaultFont->getLineHeight()); if (coord) { - const S32 query_x = mTextRect.mLeft + mGLFont->getWidth(text, current_line_start, query - current_line_start, mAllowEmbeddedItems); + const S32 query_x = mTextRect.mLeft + mDefaultFont->getWidth(text, current_line_start, query - current_line_start); const S32 query_y = mTextRect.mTop - (current_line - first_visible_line) * line_height - line_height / 2; S32 query_screen_x, query_screen_y; localPointToScreen(query_x, query_y, &query_screen_x, &query_screen_y); @@ -4599,17 +4638,17 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect S32 preedit_left = mTextRect.mLeft; if (preedit_left_position > current_line_start) { - preedit_left += mGLFont->getWidth(text, current_line_start, preedit_left_position - current_line_start, mAllowEmbeddedItems); + preedit_left += mDefaultFont->getWidth(text, current_line_start, preedit_left_position - current_line_start); } S32 preedit_right = mTextRect.mLeft; if (preedit_right_position < current_line_end) { - preedit_right += mGLFont->getWidth(text, current_line_start, preedit_right_position - current_line_start, mAllowEmbeddedItems); + preedit_right += mDefaultFont->getWidth(text, current_line_start, preedit_right_position - current_line_start); } else { - preedit_right += mGLFont->getWidth(text, current_line_start, current_line_end - current_line_start, mAllowEmbeddedItems); + preedit_right += mDefaultFont->getWidth(text, current_line_start, current_line_end - current_line_start); } const S32 preedit_top = mTextRect.mTop - (current_line - first_visible_line) * line_height; @@ -4686,10 +4725,267 @@ void LLTextEditor::markAsPreedit(S32 position, S32 length) S32 LLTextEditor::getPreeditFontSize() const { - return llround(mGLFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]); + return llround(mDefaultFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]); } LLWString LLTextEditor::getWText() const { return getViewModel()->getDisplay(); } + +void LLTextEditor::onValueChange(S32 start, S32 end) +{ +} + +// +// LLTextSegment +// + +LLTextSegment::~LLTextSegment() +{} + +S32 LLTextSegment::getWidth(S32 first_char, S32 num_chars) const { return 0; } +S32 LLTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const { return 0; } +S32 LLTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const { return 0; } +void LLTextSegment::updateLayout(const LLTextEditor& editor) {} +F32 LLTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) { return draw_rect.mLeft; } +S32 LLTextSegment::getMaxHeight() const { return 0; } +bool LLTextSegment::canEdit() const { return false; } +void LLTextSegment::unlinkFromDocument(LLTextEditor*) {} +void LLTextSegment::linkToDocument(LLTextEditor*) {} +void LLTextSegment::setHasMouseHover(bool hover) {} +const LLColor4& LLTextSegment::getColor() const { return LLColor4::white; } +void LLTextSegment::setColor(const LLColor4 &color) {} +const LLStyleSP LLTextSegment::getStyle() const {static LLStyleSP sp(new LLStyle()); return sp; } +void LLTextSegment::setStyle(const LLStyleSP &style) {} +void LLTextSegment::setToken( LLKeywordToken* token ) {} +LLKeywordToken* LLTextSegment::getToken() const { return NULL; } +BOOL LLTextSegment::getToolTip( std::string& msg ) const { return FALSE; } +void LLTextSegment::dump() const {} + + +// +// LLNormalTextSegment +// + +LLNormalTextSegment::LLNormalTextSegment( const LLStyleSP& style, S32 start, S32 end, LLTextEditor& editor ) +: LLTextSegment(start, end), + mStyle( style ), + mToken(NULL), + mHasMouseHover(false), + mEditor(editor) +{ + mMaxHeight = llceil(mStyle->getFont()->getLineHeight()); +} + +LLNormalTextSegment::LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextEditor& editor, BOOL is_visible) +: LLTextSegment(start, end), + mToken(NULL), + mHasMouseHover(false), + mEditor(editor) +{ + mStyle = new LLStyle(LLStyle::Params().visible(is_visible).color(color)); + + mMaxHeight = llceil(mStyle->getFont()->getLineHeight()); +} + +F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) +{ + if( end - start > 0 ) + { + if ( mStyle->isImage() && (start >= 0) && (end <= mEnd - mStart)) + { + S32 style_image_height = mStyle->mImageHeight; + S32 style_image_width = mStyle->mImageWidth; + LLUIImagePtr image = mStyle->getImage(); + image->draw(draw_rect.mLeft, draw_rect.mTop-style_image_height, + style_image_width, style_image_height); + } + + return drawClippedSegment( getStart() + start, getStart() + end, selection_start, selection_end, draw_rect.mLeft, draw_rect.mBottom); + } + return draw_rect.mLeft; +} + +// Draws a single text segment, reversing the color for selection if needed. +F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, F32 x, F32 y) +{ + const LLWString &text = mEditor.getWText(); + + F32 right_x = x; + if (!mStyle->isVisible()) + { + return right_x; + } + + const LLFontGL* font = mStyle->getFont(); + + LLColor4 color = mStyle->getColor(); + + font = mStyle->getFont(); + + if( selection_start > seg_start ) + { + // Draw normally + S32 start = seg_start; + S32 end = llmin( selection_start, seg_end ); + S32 length = end - start; + font->render(text, start, x, y, color, LLFontGL::LEFT, LLFontGL::BOTTOM, 0, LLFontGL::NO_SHADOW, length, S32_MAX, &right_x, mEditor.allowsEmbeddedItems()); + } + x = right_x; + + if( (selection_start < seg_end) && (selection_end > seg_start) ) + { + // Draw reversed + S32 start = llmax( selection_start, seg_start ); + S32 end = llmin( selection_end, seg_end ); + S32 length = end - start; + + font->render(text, start, x, y, + LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ), + LLFontGL::LEFT, LLFontGL::BOTTOM, 0, LLFontGL::NO_SHADOW, length, S32_MAX, &right_x, mEditor.allowsEmbeddedItems()); + } + x = right_x; + if( selection_end < seg_end ) + { + // Draw normally + S32 start = llmax( selection_end, seg_start ); + S32 end = seg_end; + S32 length = end - start; + font->render(text, start, x, y, color, LLFontGL::LEFT, LLFontGL::BOTTOM, 0, LLFontGL::NO_SHADOW, length, S32_MAX, &right_x, mEditor.allowsEmbeddedItems()); + } + return right_x; +} + +S32 LLNormalTextSegment::getMaxHeight() const +{ + return mMaxHeight; +} + +BOOL LLNormalTextSegment::getToolTip(std::string& msg) const +{ + if (mToken && !mToken->getToolTip().empty()) + { + const LLWString& wmsg = mToken->getToolTip(); + msg = wstring_to_utf8str(wmsg); + return TRUE; + } + return FALSE; +} + + +S32 LLNormalTextSegment::getWidth(S32 first_char, S32 num_chars) const +{ + LLWString text = mEditor.getWText(); + return mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars); +} + +S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const +{ + LLWString text = mEditor.getWText(); + return mStyle->getFont()->charFromPixelOffset(text.c_str(), mStart + start_offset, + (F32)segment_local_x_coord, + F32_MAX, + num_chars, + round); +} + +S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const +{ + LLWString text = mEditor.getWText(); + S32 num_chars = mStyle->getFont()->maxDrawableChars(text.c_str() + segment_offset + mStart, + (F32)num_pixels, + max_chars, + mEditor.getWordWrap()); + + if (num_chars == 0 + && line_offset == 0 + && max_chars > 0) + { + // If at the beginning of a line, and a single character won't fit, draw it anyway + num_chars = 1; + } + if (mStart + segment_offset + num_chars == mEditor.getLength()) + { + // include terminating NULL + num_chars++; + } + return num_chars; +} + +void LLNormalTextSegment::dump() const +{ + llinfos << "Segment [" << +// mColor.mV[VX] << ", " << +// mColor.mV[VY] << ", " << +// mColor.mV[VZ] << "]\t[" << + mStart << ", " << + getEnd() << "]" << + llendl; +} + +// +// LLInlineViewSegment +// + +LLInlineViewSegment::LLInlineViewSegment(LLView* view, S32 start, S32 end) +: LLTextSegment(start, end), + mView(view) +{ +} + +LLInlineViewSegment::~LLInlineViewSegment() +{ + mView->die(); +} + +S32 LLInlineViewSegment::getWidth(S32 first_char, S32 num_chars) const +{ + if (first_char == 0 && num_chars == 0) + { + return 0; + } + else + { + return mView->getRect().getWidth(); + } +} + +S32 LLInlineViewSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const +{ + if (line_offset != 0 && num_pixels < mView->getRect().getWidth()) + { + return 0; + } + else + { + return mEnd - mStart; + } +} + +void LLInlineViewSegment::updateLayout(const LLTextEditor& editor) +{ + LLRect start_rect = editor.getLocalRectFromDocIndex(mStart); + LLRect doc_rect = editor.getDocumentPanel()->getRect(); + mView->setOrigin(doc_rect.mLeft + start_rect.mLeft, doc_rect.mBottom + start_rect.mBottom); +} + +F32 LLInlineViewSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) +{ + return (F32)(draw_rect.mLeft + mView->getRect().getWidth()); +} + +S32 LLInlineViewSegment::getMaxHeight() const +{ + return mView->getRect().getHeight(); +} + +void LLInlineViewSegment::unlinkFromDocument(LLTextEditor* editor) +{ + editor->removeDocumentChild(mView); +} + +void LLInlineViewSegment::linkToDocument(LLTextEditor* editor) +{ + editor->addDocumentChild(mView); +} diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 0babd7ba581415656530e5f85d4efff6978e93fa..67c67d0f676de2813968ace41439d19929c72771 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -53,6 +53,101 @@ class LLScrollbar; class LLKeywordToken; class LLTextCmd; class LLUICtrlFactory; +class LLScrollContainer; + +class LLTextSegment : public LLRefCount +{ +public: + LLTextSegment(S32 start, S32 end) : mStart(start), mEnd(end){}; + virtual ~LLTextSegment(); + + virtual S32 getWidth(S32 first_char, S32 num_chars) const; + virtual S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const; + virtual S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const; + virtual void updateLayout(const class LLTextEditor& editor); + virtual F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect); + virtual S32 getMaxHeight() const; + virtual bool canEdit() const; + virtual void unlinkFromDocument(class LLTextEditor* editor); + virtual void linkToDocument(class LLTextEditor* editor); + + virtual void setHasMouseHover(bool hover); + virtual const LLColor4& getColor() const; + virtual void setColor(const LLColor4 &color); + virtual const LLStyleSP getStyle() const; + virtual void setStyle(const LLStyleSP &style); + virtual void setToken( LLKeywordToken* token ); + virtual LLKeywordToken* getToken() const; + virtual BOOL getToolTip( std::string& msg ) const; + virtual void dump() const; + + S32 getStart() const { return mStart; } + void setStart(S32 start) { mStart = start; } + S32 getEnd() const { return mEnd; } + void setEnd( S32 end ) { mEnd = end; } + +protected: + S32 mStart; + S32 mEnd; +}; + +class LLNormalTextSegment : public LLTextSegment +{ +public: + LLNormalTextSegment( const LLStyleSP& style, S32 start, S32 end, LLTextEditor& editor ); + LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextEditor& editor, BOOL is_visible = TRUE); + + /*virtual*/ S32 getWidth(S32 first_char, S32 num_chars) const; + /*virtual*/ S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const; + /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const; + /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect); + /*virtual*/ S32 getMaxHeight() const; + /*virtual*/ bool canEdit() const { return true; } + /*virtual*/ void setHasMouseHover(bool hover) { mHasMouseHover = hover; } + /*virtual*/ const LLColor4& getColor() const { return mStyle->getColor(); } + /*virtual*/ void setColor(const LLColor4 &color) { mStyle->setColor(color); } + /*virtual*/ const LLStyleSP getStyle() const { return mStyle; } + /*virtual*/ void setStyle(const LLStyleSP &style) { mStyle = style; } + /*virtual*/ void setToken( LLKeywordToken* token ) { mToken = token; } + /*virtual*/ LLKeywordToken* getToken() const { return mToken; } + /*virtual*/ BOOL getToolTip( std::string& msg ) const; + /*virtual*/ void dump() const; + +protected: + F32 drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, F32 x, F32 y); + + class LLTextEditor& mEditor; + LLStyleSP mStyle; + S32 mMaxHeight; + LLKeywordToken* mToken; + bool mHasMouseHover; +}; + +typedef LLPointer<LLTextSegment> LLTextSegmentPtr; + +class LLInlineViewSegment : public LLTextSegment +{ +public: + LLInlineViewSegment(LLView* widget, S32 start, S32 end); + ~LLInlineViewSegment(); + /*virtual*/ S32 getWidth(S32 first_char, S32 num_chars) const; + /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const; + /*virtual*/ void updateLayout(const class LLTextEditor& editor); + /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect); + /*virtuaL*/ S32 getMaxHeight() const; + /*virtual*/ bool canEdit() const { return false; } + /*virtual*/ void unlinkFromDocument(class LLTextEditor* editor); + /*virtual*/ void linkToDocument(class LLTextEditor* editor); + +private: + LLView* mView; +}; + +class LLIndexSegment : public LLTextSegment +{ +public: + LLIndexSegment(S32 pos) : LLTextSegment(pos, pos) {} +}; class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor { @@ -64,12 +159,13 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor Optional<bool> read_only, embedded_items, - hide_scrollbar, word_wrap, ignore_tab, hide_border, track_bottom, - takes_non_scroll_clicks; + handle_edit_keys_directly, + show_line_numbers, + commit_on_focus_lost; //colors Optional<LLUIColor> cursor_color, @@ -78,13 +174,15 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor text_readonly_color, bg_readonly_color, bg_writeable_color, - bg_focus_color; + bg_focus_color, + link_color; Optional<LLViewBorder::Params> border; Ignored type, length, - is_unicode; + is_unicode, + hide_scrollbar; Params(); }; @@ -101,6 +199,17 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor static const llwchar LAST_EMBEDDED_CHAR = 0x10ffff; static const S32 MAX_EMBEDDED_ITEMS = LAST_EMBEDDED_CHAR - FIRST_EMBEDDED_CHAR + 1; + + struct compare_segment_end + { + bool operator()(const LLTextSegmentPtr& a, const LLTextSegmentPtr& b) const + { + return a->getEnd() < b->getEnd(); + } + }; + + typedef std::multiset<LLTextSegmentPtr, compare_segment_end> segment_set_t; + virtual ~LLTextEditor(); void setParseHTML(BOOL parsing) {mParseHTML=parsing;} @@ -110,7 +219,6 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); - virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask ); virtual BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask); @@ -128,14 +236,15 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor virtual void draw(); virtual void onFocusReceived(); virtual void onFocusLost(); + virtual void onCommit(); virtual void setEnabled(BOOL enabled); // uictrl overrides - virtual void onTabInto(); virtual void clear(); virtual void setFocus( BOOL b ); virtual BOOL acceptsTextInput() const; - virtual BOOL isDirty() const { return( mLastCmd != NULL || (mPristineCmd && (mPristineCmd != mLastCmd)) ); } + virtual BOOL isDirty() const { return isPristine(); } + virtual void setValue(const LLSD& value); // LLEditMenuHandler interface virtual void undo(); @@ -162,9 +271,12 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor virtual void deselect(); virtual BOOL canDeselect() const; + virtual void onValueChange(S32 start, S32 end); + void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE); BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE); void replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive); + BOOL hasSelection() const { return (mSelectionStart !=mSelectionEnd); } // Undo/redo stack void blockUndo(); @@ -173,12 +285,20 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor virtual void makePristine(); BOOL isPristine() const; BOOL allowsEmbeddedItems() const { return mAllowEmbeddedItems; } + BOOL getWordWrap() { return mWordWrap; } + S32 getLength() const { return getWText().length(); } + void setReadOnly(bool read_only) { mReadOnly = read_only; } + bool getReadOnly() { return mReadOnly; } + + // + // Text manipulation + // // inserts text at cursor void insertText(const std::string &text); // appends text at end void appendText(const std::string &wtext, bool allow_undo, bool prepend_newline, - const LLStyleSP stylep = NULL); + const LLStyle::Params& style = LLStyle::Params()); void appendColoredText(const std::string &wtext, bool allow_undo, bool prepend_newline, @@ -187,19 +307,24 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor // if styled text starts a line, you need to prepend a newline. void appendStyledText(const std::string &new_text, bool allow_undo, bool prepend_newline, - LLStyleSP stylep = NULL); + const LLStyle::Params& style); void appendHighlightedText(const std::string &new_text, bool allow_undo, bool prepend_newline, S32 highlight_part, - LLStyleSP stylep); - + const LLStyle::Params& style); + void appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool prepend_newline); + // Non-undoable + void setText(const LLStringExplicit &utf8str); + void setWText(const LLWString &wtext); + + // Removes text from the end of document // Does not change highlight or cursor position. void removeTextFromEnd(S32 num_chars); BOOL tryToRevertToPristineState(); - void setCursor(S32 row, S32 column); - void setCursorPos(S32 offset); + bool setCursor(S32 row, S32 column); + bool setCursorPos(S32 offset, bool keep_cursor_offset = false); void setCursorAndScrollToEnd(); void getLineAndColumnForPosition( S32 position, S32* line, S32* col, BOOL include_wordwrap ); @@ -214,90 +339,57 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor LLKeywords::keyword_iterator_t keywordsBegin() { return mKeywords.begin(); } LLKeywords::keyword_iterator_t keywordsEnd() { return mKeywords.end(); } - // Color support - void setCursorColor(const LLColor4& c) { mCursorColor = c; } - void setFgColor( const LLColor4& c ) { mFgColor = c; } - void setTextDefaultColor( const LLColor4& c ) { mDefaultColor = c; } - void setReadOnlyFgColor( const LLColor4& c ) { mReadOnlyFgColor = c; } - void setWriteableBgColor( const LLColor4& c ) { mWriteableBgColor = c; } - void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; } - void setTrackColor( const LLColor4& color ); - void setThumbColor( const LLColor4& color ); - // Hacky methods to make it into a word-wrapping, potentially scrolling, // read-only text box. - void setBorderVisible(BOOL b); - BOOL isBorderVisible() const; - void setTakesNonScrollClicks(BOOL b) { mTakesNonScrollClicks = b; } - void setHideScrollbarForShortDocs(BOOL b); - - void setWordWrap( BOOL b ); - void setTabsToNextField(BOOL b) { mTabsToNextField = b; } - BOOL tabsToNextField() const { return mTabsToNextField; } void setCommitOnFocusLost(BOOL b) { mCommitOnFocusLost = b; } // Hack to handle Notecards virtual BOOL importBuffer(const char* buffer, S32 length ); virtual BOOL exportBuffer(std::string& buffer ); - // If takes focus, will take keyboard focus on click. - void setTakesFocus(BOOL b) { mTakesFocus = b; } + const class DocumentPanel* getDocumentPanel() const { return mDocumentPanel; } - void setSourceID(const LLUUID& id) { mSourceID = id; } const LLUUID& getSourceID() const { return mSourceID; } - void setHandleEditKeysDirectly( BOOL b ) { mHandleEditKeysDirectly = b; } - // Callbacks - static void setLinkColor(LLColor4 color) { mLinkColor = color; } static void setURLCallbacks(void (*callback1) (const std::string& url), bool (*callback2) (const std::string& url), bool (*callback3) (const std::string& url) ) - { mURLcallback = callback1; mSecondlifeURLcallback = callback2; mSecondlifeURLcallbackRightClick = callback3;} - - void setOnScrollEndCallback(void (*callback)(void*), void* userdata); - - // new methods - void setValue(const LLSD& value); + { sURLcallback = callback1; sSecondlifeURLcallback = callback2; sSecondlifeURLcallbackRightClick = callback3;} std::string getText() const; - // Non-undoable - void setText(const LLStringExplicit &utf8str); - void setWText(const LLWString &wtext); - - // Returns byte length limit - S32 getMaxLength() const { return mMaxTextByteLength; } - - // Change cursor - void startOfLine(); - void endOfLine(); - void endOfDoc(); - - BOOL isScrolledToTop(); - BOOL isScrolledToBottom(); - // Getters LLWString getWText() const; llwchar getWChar(S32 pos) const { return getWText()[pos]; } LLWString getWSubString(S32 pos, S32 len) const { return getWText().substr(pos, len); } - const LLTextSegment* getCurrentSegment() const { return getSegmentAtOffset(mCursorPos); } - const LLTextSegment* getPreviousSegment() const; - void getSelectedSegments(std::vector<const LLTextSegment*>& segments) const; + typedef std::vector<LLTextSegmentPtr> segment_vec_t; + + const LLTextSegmentPtr getPreviousSegment() const; + void getSelectedSegments(segment_vec_t& segments) const; + + void getSegmentsInRange(segment_vec_t& segments, S32 start, S32 end, bool include_partial) const; + LLRect getLocalRectFromDocIndex(S32 index) const; - static bool isPartOfWord(llwchar c) { return (c == '_') || LLStringOps::isAlnum((char)c); } + void addDocumentChild(LLView* view); + void removeDocumentChild(LLView* view); protected: - // - // Methods - // + // Change cursor + void startOfLine(); + void endOfLine(); + void startOfDoc(); + void endOfDoc(); - S32 getLength() const { return getWText().length(); } - void getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ) const; + void getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const; + void getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp ) ; void drawPreeditMarker(); - void updateLineStartList(S32 startpos = 0); + void needsReflow() { mReflowNeeded = TRUE; } + void needsScroll() { mScrollNeeded = TRUE; } + void updateCursorXPos(); + void updateScrollFromCursor(); void updateTextRect(); const LLRect& getTextRect() const { return mTextRect; } @@ -306,16 +398,16 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor BOOL truncate(); // Returns true if truncation occurs void removeCharOrTab(); - void setCursorAtLocalPos(S32 x, S32 y, BOOL round); - S32 getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const; + void setCursorAtLocalPos(S32 x, S32 y, bool round, bool keep_cursor_offset = false); + S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const; void indentSelectedLines( S32 spaces ); S32 indentLine( S32 pos, S32 spaces ); void unindentLineBeforeCloseBrace(); - S32 getSegmentIdxAtOffset(S32 offset) const; - const LLTextSegment* getSegmentAtLocalPos(S32 x, S32 y) const; - const LLTextSegment* getSegmentAtOffset(S32 offset) const; + LLTextSegmentPtr getSegmentAtLocalPos(S32 x, S32 y); + segment_set_t::iterator getSegIterContaining(S32 index); + segment_set_t::const_iterator getSegIterContaining(S32 index) const; void reportBadKeystroke() { make_ui_sound("UISndBadKeystroke"); } @@ -325,7 +417,6 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor BOOL handleControlKey(const KEY key, const MASK mask); BOOL handleEditKey(const KEY key, const MASK mask); - BOOL hasSelection() const { return (mSelectionStart !=mSelectionEnd); } BOOL selectionContainsLineBreaks(); void startSelection(); void endSelection(); @@ -334,9 +425,10 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor S32 prevWordPos(S32 cursorPos) const; S32 nextWordPos(S32 cursorPos) const; - S32 getLineCount() const { return mLineStartList.size(); } + S32 getLineCount() const { return mLineInfoList.size(); } S32 getLineStart( S32 line ) const; - void getLineAndOffset(S32 pos, S32* linep, S32* offsetp) const; + S32 getLineHeight( S32 line ) const; + void getLineAndOffset(S32 pos, S32* linep, S32* offsetp, bool include_wordwrap = true) const; S32 getPos(S32 line, S32 offset); void changePage(S32 delta); @@ -344,13 +436,13 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor void autoIndent(); - void findEmbeddedItemSegments(); + void findEmbeddedItemSegments(S32 start, S32 end); + void insertSegment(LLTextSegmentPtr segment_to_insert); + virtual BOOL handleMouseUpOverSegment(S32 x, S32 y, MASK mask); virtual llwchar pasteEmbeddedItem(llwchar ext_char) { return ext_char; } - virtual void bindEmbeddedChars(const LLFontGL* font) const {} - virtual void unbindEmbeddedChars(const LLFontGL* font) const {} S32 findHTMLToken(const std::string &line, S32 pos, BOOL reverse) const; BOOL findHTML(const std::string &line, S32 *begin, S32 *end) const; @@ -361,7 +453,15 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor class LLTextCmd { public: - LLTextCmd( S32 pos, BOOL group_with_next ) : mPos(pos), mGroupWithNext(group_with_next) {} + LLTextCmd( S32 pos, BOOL group_with_next, LLTextSegmentPtr segment = LLTextSegmentPtr() ) + : mPos(pos), + mGroupWithNext(group_with_next) + { + if (segment.notNull()) + { + mSegments.push_back(segment); + } + } virtual ~LLTextCmd() {} virtual BOOL execute(LLTextEditor* editor, S32* delta) = 0; virtual S32 undo(LLTextEditor* editor) = 0; @@ -372,16 +472,17 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor virtual BOOL hasExtCharValue( llwchar value ) const { return FALSE; } // Defined here so they can access protected LLTextEditor editing methods - S32 insert(LLTextEditor* editor, S32 pos, const LLWString &wstr) { return editor->insertStringNoUndo( pos, wstr ); } + S32 insert(LLTextEditor* editor, S32 pos, const LLWString &wstr) { return editor->insertStringNoUndo( pos, wstr, &mSegments ); } S32 remove(LLTextEditor* editor, S32 pos, S32 length) { return editor->removeStringNoUndo( pos, length ); } S32 overwrite(LLTextEditor* editor, S32 pos, llwchar wc) { return editor->overwriteCharNoUndo(pos, wc); } S32 getPosition() const { return mPos; } BOOL groupWithNext() const { return mGroupWithNext; } - private: - const S32 mPos; - BOOL mGroupWithNext; + protected: + const S32 mPos; + BOOL mGroupWithNext; + segment_vec_t mSegments; }; // Here's the method that takes and applies text commands. S32 execute(LLTextCmd* cmd); @@ -392,12 +493,12 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor S32 overwriteChar(S32 pos, llwchar wc); void removeChar(); S32 removeChar(S32 pos); - S32 insert(const S32 pos, const LLWString &wstr, const BOOL group_with_next_op); - S32 remove(const S32 pos, const S32 length, const BOOL group_with_next_op); - S32 append(const LLWString &wstr, const BOOL group_with_next_op); + S32 insert(S32 pos, const LLWString &wstr, bool group_with_next_op, LLTextSegmentPtr segment); + S32 remove(S32 pos, S32 length, bool group_with_next_op); + S32 append(const LLWString &wstr, bool group_with_next_op, LLTextSegmentPtr segment); // Direct operations - S32 insertStringNoUndo(S32 pos, const LLWString &wstr); // returns num of chars actually inserted + S32 insertStringNoUndo(S32 pos, const LLWString &wstr, segment_vec_t* segments = NULL); // returns num of chars actually inserted S32 removeStringNoUndo(S32 pos, S32 length); S32 overwriteCharNoUndo(S32 pos, llwchar wc); @@ -441,22 +542,38 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor BOOL mParseHighlights; std::string mHTML; - typedef std::vector<LLTextSegment *> segment_list_t; - segment_list_t mSegments; - const LLTextSegment* mHoverSegment; + segment_set_t mSegments; + LLTextSegmentPtr mHoverSegment; // Scrollbar data - class LLScrollbar* mScrollbar; - BOOL mHideScrollbarForShortDocs; - BOOL mTakesNonScrollClicks; - void (*mOnScrollEndCallback)(void*); + class DocumentPanel* mDocumentPanel; + LLScrollContainer* mScroller; + void *mOnScrollEndData; LLWString mPreeditWString; LLWString mPreeditOverwrittenWString; std::vector<S32> mPreeditPositions; std::vector<BOOL> mPreeditStandouts; - + + S32 mScrollIndex; // index into document that controls default scroll position + +protected: + LLUIColor mCursorColor; + LLUIColor mFgColor; + LLUIColor mDefaultColor; + LLUIColor mReadOnlyFgColor; + LLUIColor mWriteableBgColor; + LLUIColor mReadOnlyBgColor; + LLUIColor mFocusBgColor; + LLUIColor mLinkColor; + + BOOL mReadOnly; + BOOL mWordWrap; + BOOL mShowLineNumbers; + + void updateSegments(); + private: // @@ -465,32 +582,28 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor void pasteHelper(bool is_primary); virtual LLTextViewModel* getViewModel() const; - - void updateSegments(); - void pruneSegments(); + void reflow(S32 startpos = 0); + + void clearSegments(); + void createDefaultSegment(); + LLStyleSP getDefaultStyle(); + S32 getEditableIndex(S32 index, bool increasing_direction); void drawBackground(); void drawSelectionBackground(); void drawCursor(); void drawText(); - void drawClippedSegment(const LLWString &wtext, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyleSP& color, F32* right_x); - - void needsReflow() - { - mReflowNeeded = TRUE; - // cursor might have moved, need to scroll - mScrollNeeded = TRUE; - } - void needsScroll() { mScrollNeeded = TRUE; } + void drawLineNumbers(); + + S32 getFirstVisibleLine() const; // // Data // LLKeywords mKeywords; - static LLUIColor mLinkColor; - static void (*mURLcallback) (const std::string& url); - static bool (*mSecondlifeURLcallback) (const std::string& url); - static bool (*mSecondlifeURLcallbackRightClick) (const std::string& url); + static void (*sURLcallback) (const std::string& url); + static bool (*sSecondlifeURLcallback) (const std::string& url); + static bool (*sSecondlifeURLcallbackRightClick) (const std::string& url); // Concrete LLTextCmd sub-classes used by the LLTextEditor base class class LLTextCmdInsert; @@ -500,7 +613,7 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes - const LLFontGL* mGLFont; + const LLFontGL* mDefaultFont; class LLViewBorder* mBorder; @@ -515,49 +628,35 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor S32 mDesiredXPixel; // X pixel position where the user wants the cursor to be LLRect mTextRect; // The rect in which text is drawn. Excludes borders. // List of offsets and segment index of the start of each line. Always has at least one node (0). - struct pred; struct line_info { - line_info(S32 segment, S32 offset) : mSegment(segment), mOffset(offset) {} - S32 mSegment; - S32 mOffset; - }; - struct line_info_compare - { - bool operator()(const line_info& a, const line_info& b) const - { - if (a.mSegment < b.mSegment) - return true; - else if (a.mSegment > b.mSegment) - return false; - else - return a.mOffset < b.mOffset; - } + line_info(S32 index_start, S32 index_end, S32 top, S32 bottom, S32 line_num) + : mDocIndexStart(index_start), + mDocIndexEnd(index_end), + mTop(top), + mBottom(bottom), + mLineNum(line_num) + {} + S32 mDocIndexStart; + S32 mDocIndexEnd; + S32 mTop; + S32 mBottom; + S32 mLineNum; // actual line count (ignoring soft newlines due to word wrap) }; + struct compare_bottom; + struct compare_top; + struct line_end_compare; typedef std::vector<line_info> line_list_t; - line_list_t mLineStartList; + line_list_t mLineInfoList; BOOL mReflowNeeded; BOOL mScrollNeeded; LLFrameTimer mKeystrokeTimer; - LLUIColor mCursorColor; - LLUIColor mFgColor; - LLUIColor mDefaultColor; - LLUIColor mReadOnlyFgColor; - LLUIColor mWriteableBgColor; - LLUIColor mReadOnlyBgColor; - LLUIColor mFocusBgColor; - - BOOL mReadOnly; - BOOL mWordWrap; - BOOL mShowLineNumbers; - BOOL mTabsToNextField; // if true, tab moves focus to next field, else inserts spaces BOOL mCommitOnFocusLost; BOOL mTakesFocus; BOOL mTrackBottom; // if true, keeps scroll position at bottom during resize - BOOL mScrolledToBottom; BOOL mAllowEmbeddedItems; @@ -571,47 +670,4 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor }; // end class LLTextEditor - -class LLTextSegment -{ -public: - // for creating a compare value - LLTextSegment(S32 start); - LLTextSegment( const LLStyleSP& style, S32 start, S32 end ); - LLTextSegment( const LLColor4& color, S32 start, S32 end, BOOL is_visible); - LLTextSegment( const LLColor4& color, S32 start, S32 end ); - LLTextSegment( const LLColor3& color, S32 start, S32 end ); - - S32 getStart() const { return mStart; } - S32 getEnd() const { return mEnd; } - void setEnd( S32 end ) { mEnd = end; } - const LLColor4& getColor() const { return mStyle->getColor(); } - void setColor(const LLColor4 &color) { mStyle->setColor(color); } - const LLStyleSP& getStyle() const { return mStyle; } - void setStyle(const LLStyleSP &style) { mStyle = style; } - void setIsDefault(BOOL b) { mIsDefault = b; } - BOOL getIsDefault() const { return mIsDefault; } - void setToken( LLKeywordToken* token ) { mToken = token; } - LLKeywordToken* getToken() const { return mToken; } - BOOL getToolTip( std::string& msg ) const; - - void dump() const; - - struct compare - { - bool operator()(const LLTextSegment* a, const LLTextSegment* b) const - { - return a->mStart < b->mStart; - } - }; - -private: - LLStyleSP mStyle; - S32 mStart; - S32 mEnd; - LLKeywordToken* mToken; - BOOL mIsDefault; -}; - - #endif // LL_TEXTEDITOR_ diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index fab8f613567c0b922b6ca3cc071b8aadcd9edbce..7e4df892c4b4e1ed662ba362785ba47d371991bc 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -71,9 +71,6 @@ // const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f); -// Used to hide the flashing text cursor when window doesn't have focus. -BOOL gShowTextEditCursor = TRUE; - // Language for UI construction std::map<std::string, std::string> gTranslation; std::list<std::string> gUntranslated; @@ -1898,6 +1895,12 @@ void LLScreenClipRect::pushClipRect(const LLRect& rect) { LLRect top = sClipRectStack.top(); combined_clip_rect.intersectWith(top); + + if(combined_clip_rect.isEmpty()) + { + // avoid artifacts where zero area rects show up as lines + combined_clip_rect = LLRect::null; + } } sClipRectStack.push(combined_clip_rect); } diff --git a/indra/llui/llui.h b/indra/llui/llui.h index b1943a7b028cc9f831029f7a9582e5fbda2f7788..1f9b0b2dbc0df6d8d55c89506c816ce947489028 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -151,9 +151,6 @@ inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled ); } -// Used to hide the flashing text cursor when window doesn't have focus. -extern BOOL gShowTextEditCursor; - class LLImageProviderInterface; typedef void (*LLUIAudioCallback)(const LLUUID& uuid); diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 8aa7540446f11ab91da77c78f31b8a07006f1856..4a9fec31912412d23a450bebb52fd4f2e1261d7a 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -278,24 +278,46 @@ void LLUICtrl::onMouseLeave(S32 x, S32 y, MASK mask) { mMouseLeaveSignal(this, getValue()); } + //virtual -BOOL LLUICtrl::handleMouseDown(S32 x, S32 y, MASK mask){ +BOOL LLUICtrl::handleMouseDown(S32 x, S32 y, MASK mask) +{ BOOL handled = LLView::handleMouseDown(x,y,mask); mMouseDownSignal(this,x,y,mask); return handled; } + //virtual -BOOL LLUICtrl::handleMouseUp(S32 x, S32 y, MASK mask){ +BOOL LLUICtrl::handleMouseUp(S32 x, S32 y, MASK mask) +{ BOOL handled = LLView::handleMouseUp(x,y,mask); mMouseUpSignal(this,x,y,mask); return handled; } + +//virtual +BOOL LLUICtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + BOOL handled = LLView::handleRightMouseDown(x,y,mask); + mRightMouseDownSignal(this,x,y,mask); + return handled; +} + //virtual -BOOL LLUICtrl::handleRightMouseUp(S32 x, S32 y, MASK mask){ +BOOL LLUICtrl::handleRightMouseUp(S32 x, S32 y, MASK mask) +{ BOOL handled = LLView::handleRightMouseUp(x,y,mask); - mRightClickSignal(this,x,y,mask); + mRightMouseUpSignal(this,x,y,mask); return handled; } + +// can't tab to children of a non-tab-stop widget +BOOL LLUICtrl::canFocusChildren() const +{ + return hasTabStop(); +} + + void LLUICtrl::onCommit() { mCommitSignal(this, getValue()); diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 6ba3b01fcb4f215a7fc746eb7b6024800ca0ad0a..a4f539af14c3afa234251038081e1d2b2ffa500f 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -186,8 +186,10 @@ class LLUICtrl /*virtual*/ BOOL getTentative() const; /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL canFocusChildren() const; /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); // From LLFocusableElement @@ -258,7 +260,8 @@ class LLUICtrl boost::signals2::connection setMouseDownCallback( const mouse_signal_t::slot_type& cb ) { return mMouseDownSignal.connect(cb); } boost::signals2::connection setMouseUpCallback( const mouse_signal_t::slot_type& cb ) { return mMouseUpSignal.connect(cb); } - boost::signals2::connection setRightClickedCallback( const mouse_signal_t::slot_type& cb ) { return mRightClickSignal.connect(cb); } + boost::signals2::connection setRightMouseDownCallback( const mouse_signal_t::slot_type& cb ) { return mRightMouseDownSignal.connect(cb); } + boost::signals2::connection setRightMouseUpCallback( const mouse_signal_t::slot_type& cb ) { return mRightMouseUpSignal.connect(cb); } // *TODO: Deprecate; for backwards compatability only: boost::signals2::connection setCommitCallback( boost::function<void (LLUICtrl*,void*)> cb, void* data); @@ -292,7 +295,8 @@ class LLUICtrl mouse_signal_t mMouseDownSignal; mouse_signal_t mMouseUpSignal; - mouse_signal_t mRightClickSignal; + mouse_signal_t mRightMouseDownSignal; + mouse_signal_t mRightMouseUpSignal; LLViewModelPtr mViewModel; diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 2bbede8c133e756f93256cda227dff50049dbf04..1161101f90dc3506fa7363d8a2f7c544c7a9a6b7 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -45,31 +45,7 @@ #include "llquaternion.h" // this library includes -#include "llbutton.h" -#include "llcheckboxctrl.h" -//#include "llcolorswatch.h" -#include "llcombobox.h" -#include "llcontrol.h" -#include "lldir.h" -#include "llevent.h" #include "llfloater.h" -#include "lliconctrl.h" -#include "lllineeditor.h" -#include "llmenugl.h" -#include "llradiogroup.h" -#include "llscrollcontainer.h" -#include "llscrollingpanellist.h" -#include "llscrolllistctrl.h" -#include "llslider.h" -#include "llsliderctrl.h" -#include "llmultislider.h" -#include "llmultisliderctrl.h" -#include "llspinctrl.h" -#include "lltabcontainer.h" -#include "lltextbox.h" -#include "lltexteditor.h" -#include "llui.h" -#include "llviewborder.h" LLFastTimer::DeclareTimer FTM_WIDGET_CONSTRUCTION("Widget Construction"); LLFastTimer::DeclareTimer FTM_INIT_FROM_PARAMS("Widget InitFromParams"); @@ -149,7 +125,7 @@ void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, const wid } -LLFastTimer::DeclareTimer FTM_XML_PARSE("XML Reading/Parsing"); +static LLFastTimer::DeclareTimer FTM_XML_PARSE("XML Reading/Parsing"); //----------------------------------------------------------------------------- // getLayeredXMLNode() //----------------------------------------------------------------------------- @@ -177,14 +153,14 @@ bool LLUICtrlFactory::getLocalizedXMLNode(const std::string &xui_filename, LLXML } } -static LLFastTimer::DeclareTimer BUILD_FLOATERS("Build Floaters"); +static LLFastTimer::DeclareTimer FTM_BUILD_FLOATERS("Build Floaters"); //----------------------------------------------------------------------------- // buildFloater() //----------------------------------------------------------------------------- void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filename, LLXMLNodePtr output_node) { - LLFastTimer timer(BUILD_FLOATERS); + LLFastTimer timer(FTM_BUILD_FLOATERS); LLXMLNodePtr root; //if exporting, only load the language being exported, @@ -248,14 +224,14 @@ S32 LLUICtrlFactory::saveToXML(LLView* viewp, const std::string& filename) return 0; } -static LLFastTimer::DeclareTimer BUILD_PANELS("Build Panels"); +static LLFastTimer::DeclareTimer FTM_BUILD_PANELS("Build Panels"); //----------------------------------------------------------------------------- // buildPanel() //----------------------------------------------------------------------------- BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const std::string& filename, LLXMLNodePtr output_node) { - LLFastTimer timer(BUILD_PANELS); + LLFastTimer timer(FTM_BUILD_PANELS); BOOL didPost = FALSE; LLXMLNodePtr root; @@ -317,7 +293,7 @@ BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const std::string& filename, L //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -LLFastTimer::DeclareTimer FTM_CREATE_FROM_XML("Create child widget"); +static LLFastTimer::DeclareTimer FTM_CREATE_FROM_XML("Create child widget"); LLView *LLUICtrlFactory::createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t& registry, LLXMLNodePtr output_node) { diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 0ba028e1c8f6f429e06a589a8768c1f3f50f7263..e2dc85d03fbc6c537a142de9bba74a101fd3b7ac 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1300,6 +1300,11 @@ LLView* LLView::childrenHandleMiddleMouseUp(S32 x, S32 y, MASK mask) } void LLView::draw() +{ + drawChildren(); +} + +void LLView::drawChildren() { if (sDebugRects) { @@ -1329,7 +1334,7 @@ void LLView::draw() { // Only draw views that are within the root view localRectToScreen(viewp->getRect(),&screenRect); - if ( rootRect.rectInRect(&screenRect) ) + if ( rootRect.overlaps(screenRect) ) { glMatrixMode(GL_MODELVIEW); LLUI::pushMatrix(); @@ -1540,7 +1545,7 @@ void LLView::updateBoundingRect() LLRect child_bounding_rect = childp->getBoundingRect(); - if (local_bounding_rect.isNull()) + if (local_bounding_rect.isEmpty()) { // start out with bounding rect equal to first visible child's bounding rect local_bounding_rect = child_bounding_rect; @@ -1548,7 +1553,7 @@ void LLView::updateBoundingRect() else { // accumulate non-null children rectangles - if (!child_bounding_rect.isNull()) + if (!child_bounding_rect.isEmpty()) { local_bounding_rect.unionWith(child_bounding_rect); } @@ -1639,7 +1644,7 @@ BOOL LLView::hasAncestor(const LLView* parentp) const BOOL LLView::childHasKeyboardFocus( const std::string& childname ) const { - LLView *child = getChildView(childname, TRUE, FALSE); + LLView *child = findChildView(childname, TRUE); if (child) { return gFocusMgr.childHasKeyboardFocus(child); @@ -1654,13 +1659,27 @@ BOOL LLView::childHasKeyboardFocus( const std::string& childname ) const BOOL LLView::hasChild(const std::string& childname, BOOL recurse) const { - return getChildView(childname, recurse, FALSE) != NULL; + return findChildView(childname, recurse) != NULL; } //----------------------------------------------------------------------------- // getChildView() //----------------------------------------------------------------------------- -LLView* LLView::getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const +LLView* LLView::getChildView(const std::string& name, BOOL recurse) const +{ + LLView* child = findChildView(name, recurse); + if (!child) + { + child = getDefaultWidget<LLView>(name); + if (!child) + { + child = LLUICtrlFactory::createDefaultWidget<LLView>(name); + } + } + return child; +} + +LLView* LLView::findChildView(const std::string& name, BOOL recurse) const { //richard: should we allow empty names? //if(name.empty()) @@ -1681,23 +1700,13 @@ LLView* LLView::getChildView(const std::string& name, BOOL recurse, BOOL create_ for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* childp = *child_it; - LLView* viewp = childp->getChildView(name, recurse, FALSE); + LLView* viewp = childp->findChildView(name, recurse); if ( viewp ) { return viewp; } } } - - if (create_if_missing) - { - LLView* view = getDefaultWidget<LLView>(name); - if (!view) - { - view = LLUICtrlFactory::createDefaultWidget<LLView>(name); - } - return view; - } return NULL; } diff --git a/indra/llui/llview.h b/indra/llui/llview.h index ee492761396d3b5969bfe642b05b0fc36a2df813..6247bf036cc87038e1063972ad6ad05f71fc5615 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -213,6 +213,9 @@ class LLView : public LLMouseHandler, public LLMortician LLView(const LLView::Params&); friend class LLUICtrlFactory; +private: + // widgets in general are not copyable + LLView(const LLView& other) {}; public: #if LL_DEBUG static BOOL sIsDrawing; @@ -421,6 +424,7 @@ class LLView : public LLMouseHandler, public LLMortician virtual std::string getShowNamesToolTip(); virtual void draw(); + void drawChildren(); void parseFollowsFlags(const LLView::Params& params); @@ -484,19 +488,20 @@ class LLView : public LLMouseHandler, public LLMortician template <class T> T* findChild(const std::string& name, BOOL recurse = TRUE) const { - LLView* child = getChildView(name, recurse, FALSE); + LLView* child = findChildView(name, recurse); T* result = dynamic_cast<T*>(child); return result; } - template <class T> T* getChild(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const; + template <class T> T* getChild(const std::string& name, BOOL recurse = TRUE) const; template <class T> T& getChildRef(const std::string& name, BOOL recurse = TRUE) const { - return *getChild<T>(name, recurse, TRUE); + return *getChild<T>(name, recurse); } - virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const; + virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE) const; + virtual LLView* findChildView(const std::string& name, BOOL recurse = TRUE) const; template <class T> T* getDefaultWidget(const std::string& name) const { @@ -636,9 +641,9 @@ class LLCompareByTabOrder LLView::child_tab_order_t mTabOrder; }; -template <class T> T* LLView::getChild(const std::string& name, BOOL recurse, BOOL create_if_missing) const +template <class T> T* LLView::getChild(const std::string& name, BOOL recurse) const { - LLView* child = getChildView(name, recurse, FALSE); + LLView* child = findChildView(name, recurse); T* result = dynamic_cast<T*>(child); if (!result) { @@ -647,28 +652,25 @@ template <class T> T* LLView::getChild(const std::string& name, BOOL recurse, BO { llwarns << "Found child named " << name << " but of wrong type " << typeid(child).name() << ", expecting " << typeid(T*).name() << llendl; } - if (create_if_missing) + result = getDefaultWidget<T>(name); + if (!result) { - result = getDefaultWidget<T>(name); - if (!result) + result = LLUICtrlFactory::getDefaultWidget<T>(name); + + if (result) { - result = LLUICtrlFactory::getDefaultWidget<T>(name); - - if (result) - { - // *NOTE: You cannot call mFoo = getChild<LLFoo>("bar") - // in a floater or panel constructor. The widgets will not - // be ready. Instead, put it in postBuild(). - llwarns << "Making dummy " << typeid(T).name() << " named \"" << name << "\" in " << getName() << llendl; - } - else - { - llwarns << "Failed to create dummy " << typeid(T).name() << llendl; - return NULL; - } - - getDefaultWidgetMap()[name] = result; + // *NOTE: You cannot call mFoo = getChild<LLFoo>("bar") + // in a floater or panel constructor. The widgets will not + // be ready. Instead, put it in postBuild(). + llwarns << "Making dummy " << typeid(T).name() << " named \"" << name << "\" in " << getName() << llendl; } + else + { + llwarns << "Failed to create dummy " << typeid(T).name() << llendl; + return NULL; + } + + getDefaultWidgetMap()[name] = result; } } return result; diff --git a/indra/llui/llviewborder.cpp b/indra/llui/llviewborder.cpp index 860aa3302e8c8901479565a82f8a293def09cd14..f41c98f7b3d57d3260bdba3bf43ce3bb4a1375d7 100644 --- a/indra/llui/llviewborder.cpp +++ b/indra/llui/llviewborder.cpp @@ -134,9 +134,7 @@ void LLViewBorder::draw() } } - // draw the children - LLView::draw(); - + drawChildren(); } void LLViewBorder::drawOnePixelLines() diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp index 6b1563bab1e753075634edec1a1497fd3b55bad4..5fdf41188d46faf90bff83d9b85f5e486e81ec4c 100644 --- a/indra/llvfs/llvfile.cpp +++ b/indra/llvfs/llvfile.cpp @@ -44,6 +44,8 @@ const S32 LLVFile::WRITE = 0x00000002; const S32 LLVFile::READ_WRITE = 0x00000003; // LLVFile::READ & LLVFile::WRITE const S32 LLVFile::APPEND = 0x00000006; // 0x00000004 & LLVFile::WRITE +static LLFastTimer::DeclareTimer FTM_VFILE_WAIT("VFile Wait"); + //---------------------------------------------------------------------------- LLVFSThread* LLVFile::sVFSThread = NULL; BOOL LLVFile::sAllocdVFSThread = FALSE; @@ -318,7 +320,7 @@ BOOL LLVFile::setMaxSize(S32 size) if (!mVFS->checkAvailable(size)) { - LLFastTimer t(LLFastTimer::FTM_VFILE_WAIT); + LLFastTimer t(FTM_VFILE_WAIT); S32 count = 0; while (sVFSThread->getPending() > 1000) { @@ -426,7 +428,7 @@ bool LLVFile::isLocked(EVFSLock lock) void LLVFile::waitForLock(EVFSLock lock) { - LLFastTimer t(LLFastTimer::FTM_VFILE_WAIT); + LLFastTimer t(FTM_VFILE_WAIT); // spin until the lock clears while (isLocked(lock)) { diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index ce1bc821685fc63a36722adf161d67bfbbab1bc3..9936b24292cb4ba6d03ab434e5653b718a11b1a7 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1645,6 +1645,9 @@ void LLWindowWin32::gatherInput() mMousePositionModified = FALSE; } +static LLFastTimer::DeclareTimer FTM_KEYHANDLER("Handle Keyboard"); +static LLFastTimer::DeclareTimer FTM_MOUSEHANDLER("Handle Mouse"); + LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_param, LPARAM l_param) { LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(h_wnd, GWL_USERDATA); @@ -1878,7 +1881,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ case WM_KEYUP: { window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYUP"); - LLFastTimer t2(LLFastTimer::FTM_KEYHANDLER); + LLFastTimer t2(FTM_KEYHANDLER); if (gDebugWindowProc) { @@ -1987,7 +1990,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ case WM_LBUTTONDOWN: { window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDOWN"); - LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER); + LLFastTimer t2(FTM_MOUSEHANDLER); if (LLWinImm::isAvailable() && window_imp->mPreeditor) { window_imp->interruptLanguageTextInput(); @@ -2051,7 +2054,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ case WM_LBUTTONUP: { window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONUP"); - LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER); + LLFastTimer t2(FTM_MOUSEHANDLER); //if (gDebugClicks) //{ // LL_INFOS("Window") << "WndProc left button up" << LL_ENDL; @@ -2085,7 +2088,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ case WM_RBUTTONDOWN: { window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_RBUTTONDOWN"); - LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER); + LLFastTimer t2(FTM_MOUSEHANDLER); if (LLWinImm::isAvailable() && window_imp->mPreeditor) { window_imp->interruptLanguageTextInput(); @@ -2119,7 +2122,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ case WM_RBUTTONUP: { window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_RBUTTONUP"); - LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER); + LLFastTimer t2(FTM_MOUSEHANDLER); // Because we move the cursor position in the app, we need to query // to find out where the cursor at the time the event is handled. // If we don't do this, many clicks could get buffered up, and if the @@ -2149,7 +2152,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // case WM_MBUTTONDBLCLK: { window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONDOWN"); - LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER); + LLFastTimer t2(FTM_MOUSEHANDLER); if (LLWinImm::isAvailable() && window_imp->mPreeditor) { window_imp->interruptLanguageTextInput(); @@ -2183,7 +2186,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ case WM_MBUTTONUP: { window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONUP"); - LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER); + LLFastTimer t2(FTM_MOUSEHANDLER); // Because we move the cursor position in tllviewerhe app, we need to query // to find out where the cursor at the time the event is handled. // If we don't do this, many clicks could get buffered up, and if the diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 08649408669197be90b6e13f1e08c292d34d0757..7d946015683860a645e3c68ca908980a200b9dad 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -96,7 +96,7 @@ typedef enum e_control_type TYPE_COUNT } eControlType; -class LLControlVariable : public LLRefCount, boost::noncopyable +class LLControlVariable : public LLRefCount { friend class LLControlGroup; diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index cb56049ae2fd7f3aefb7e2efad98f48f6a6c785c..a1d0831939fdd246d8ce722b12602c8e67a77186 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -430,6 +430,7 @@ namespace LLInitParam const Param* getLastChangedParam() const { return mLastChangedParam ? getParamFromHandle(mLastChangedParam) : NULL; } S32 getLastChangeVersion() const { return mChangeVersion; } + bool isDefault() const { return mChangeVersion == 0; } bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack); bool serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const; diff --git a/indra/llxuixml/lltrans.cpp b/indra/llxuixml/lltrans.cpp index db7421575ce6c7420d8ef12035315aba14394932..2efc475f573911bbe25c27381146abb8d5c4d92e 100644 --- a/indra/llxuixml/lltrans.cpp +++ b/indra/llxuixml/lltrans.cpp @@ -169,3 +169,28 @@ std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil:: } } +//static +bool LLTrans::findString(std::string &result, const std::string &xml_desc, const LLStringUtil::format_map_t& msg_args) +{ + LLFastTimer timer(FTM_GET_TRANS); + + template_map_t::iterator iter = sStringTemplates.find(xml_desc); + if (iter != sStringTemplates.end()) + { + std::string text = iter->second.mText; + LLStringUtil::format_map_t args = sDefaultArgs; + args.insert(msg_args.begin(), msg_args.end()); + LLStringUtil::format(text, args); + result = text; + return true; + } + else + { + LLSD args; + args["STRING_NAME"] = xml_desc; + LL_WARNS_ONCE("configuration") << "Missing String in strings.xml: [" << xml_desc << "]" << LL_ENDL; + //LLNotifications::instance().add("MissingString", args); + + return false; + } +} diff --git a/indra/llxuixml/lltrans.h b/indra/llxuixml/lltrans.h index 6423c882459ee3f3f262be26024856351ae3a18f..340d70e4347d726b9898b6a8fdf4355fe6da0391 100644 --- a/indra/llxuixml/lltrans.h +++ b/indra/llxuixml/lltrans.h @@ -78,6 +78,7 @@ class LLTrans * @returns Translated string */ static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args); + static bool findString(std::string &result, const std::string &xml_desc, const LLStringUtil::format_map_t& args); /** * @brief Returns a translated string @@ -89,7 +90,14 @@ class LLTrans LLStringUtil::format_map_t empty; return getString(xml_desc, empty); } - + + static bool findString(std::string &result, const std::string &xml_desc) + { + LLStringUtil::format_map_t empty; + return findString(result, xml_desc, empty); + } + + // get the default args static const LLStringUtil::format_map_t& getDefaultArgs() { diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index e1f61906e20eca02c8eeead82ee78efd0f057473..e28e52fd16e9551668017ca72457be33c3aa8ba2 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -399,11 +399,11 @@ LLXUIParser::LLXUIParser() boost::bind(&LLXUIParser::writeSDValue, this, _1, _2)); } -static LLFastTimer::DeclareTimer PARSE_XUI("XUI Parsing"); +static LLFastTimer::DeclareTimer FTM_PARSE_XUI("XUI Parsing"); void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, bool silent) { - LLFastTimer timer(PARSE_XUI); + LLFastTimer timer(FTM_PARSE_XUI); mNameStack.clear(); mCurReadDepth = 0; setParseSilently(silent); diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp index 05fee9a4194235f71d1b4ab1b92258a323f868f0..d7f445d3d89739d57898d0db9e26a4c28379bd33 100644 --- a/indra/lscript/lscript_execute/lscript_execute.cpp +++ b/indra/lscript/lscript_execute/lscript_execute.cpp @@ -4280,7 +4280,6 @@ BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) } { - // LLFastTimer time_in_libraries1(LLFastTimer::FTM_TEMP7); gScriptLibrary.mFunctions[arg]->mExecFunc(returnvalue, arguments, id); } add_register_fp(buffer, LREG_ESR, -gScriptLibrary.mFunctions[arg]->mEnergyUse); @@ -4351,7 +4350,6 @@ BOOL run_calllib_two_byte(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &i } { - // LLFastTimer time_in_libraries2(LLFastTimer::FTM_TEMP8); gScriptLibrary.mFunctions[arg]->mExecFunc(returnvalue, arguments, id); } add_register_fp(buffer, LREG_ESR, -gScriptLibrary.mFunctions[arg]->mEnergyUse); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 5045f187840f54106a2c01f0fe4a30f3fd04f6c1..fe9eae04a1493455ee65dd6b039f9c4baced97a0 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -290,9 +290,9 @@ static std::set<std::string> default_trans_args; void init_default_trans_args() { default_trans_args.insert("SECOND_LIFE"); // World - default_trans_args.insert("SECOND_LIFE_VIEWER"); + default_trans_args.insert("APP_NAME"); default_trans_args.insert("SECOND_LIFE_GRID"); - default_trans_args.insert("SECOND_LIFE_SUPPORT"); + default_trans_args.insert("SUPPORT_SITE"); } //---------------------------------------------------------------------------- @@ -863,6 +863,11 @@ bool LLAppViewer::init() return true; } +static LLFastTimer::DeclareTimer FTM_MESSAGES("System Messages"); +static LLFastTimer::DeclareTimer FTM_SLEEP("Sleep"); +static LLFastTimer::DeclareTimer FTM_IDLE("Idle"); +static LLFastTimer::DeclareTimer FTM_PUMP("Pump"); + bool LLAppViewer::mainLoop() { LLMemType mt1(LLMemType::MTYPE_MAIN); @@ -905,7 +910,7 @@ bool LLAppViewer::mainLoop() if (gViewerWindow) { - LLFastTimer t2(LLFastTimer::FTM_MESSAGES); + LLFastTimer t2(FTM_MESSAGES); gViewerWindow->mWindow->processMiscNativeEvents(); } @@ -913,7 +918,7 @@ bool LLAppViewer::mainLoop() if (gViewerWindow) { - LLFastTimer t2(LLFastTimer::FTM_MESSAGES); + LLFastTimer t2(FTM_MESSAGES); if (!restoreErrorTrap()) { llwarns << " Someone took over my signal/exception handler (post messagehandling)!" << llendl; @@ -963,14 +968,14 @@ bool LLAppViewer::mainLoop() { pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! - LLFastTimer t3(LLFastTimer::FTM_IDLE); + LLFastTimer t3(FTM_IDLE); idle(); if (gAres != NULL && gAres->isInitialized()) { LLMemType mt_ip(LLMemType::MTYPE_IDLE_PUMP); pingMainloopTimeout("Main:ServicePump"); - LLFastTimer t4(LLFastTimer::FTM_PUMP); + LLFastTimer t4(FTM_PUMP); gAres->process(); // this pump is necessary to make the login screen show up gServicePump->pump(); @@ -1007,7 +1012,7 @@ bool LLAppViewer::mainLoop() // Sleep and run background threads { LLMemType mt_sleep(LLMemType::MTYPE_SLEEP); - LLFastTimer t2(LLFastTimer::FTM_SLEEP); + LLFastTimer t2(FTM_SLEEP); bool run_multiple_threads = gSavedSettings.getBOOL("RunMultipleThreads"); // yield some time to the os based on command line option @@ -2025,7 +2030,7 @@ bool LLAppViewer::initConfiguration() #if LL_DARWIN // Initialize apple menubar and various callbacks - init_apple_menu(LLTrans::getString("SECOND_LIFE_VIEWER").c_str()); + init_apple_menu(LLTrans::getString("APP_NAME").c_str()); #if __ppc__ // If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further. @@ -2064,7 +2069,7 @@ bool LLAppViewer::initConfiguration() // // Set the name of the window // - gWindowTitle = LLTrans::getString("SECOND_LIFE_VIEWER"); + gWindowTitle = LLTrans::getString("APP_NAME"); #if LL_DEBUG gWindowTitle += std::string(" [DEBUG] ") + gArgs; #else @@ -2181,7 +2186,7 @@ void LLAppViewer::checkForCrash(void) { std::ostringstream msg; msg << LLTrans::getString("MBFrozenCrashed"); - std::string alert = LLTrans::getString("SECOND_LIFE_VIEWER") + " " + LLTrans::getString("MBAlert"); + std::string alert = LLTrans::getString("APP_NAME") + " " + LLTrans::getString("MBAlert"); choice = OSMessageBox(msg.str(), alert, OSMB_YESNO); @@ -2391,7 +2396,7 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)true; // Dump some debugging info - LL_INFOS("SystemInfo") << LLTrans::getString("SECOND_LIFE_VIEWER") + LL_INFOS("SystemInfo") << LLTrans::getString("APP_NAME") << " version " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << LL_ENDL; @@ -3069,7 +3074,7 @@ void LLAppViewer::purgeCache() std::string LLAppViewer::getSecondLifeTitle() const { - return LLTrans::getString("SECOND_LIFE_VIEWER"); + return LLTrans::getString("APP_NAME"); } std::string LLAppViewer::getWindowTitle() const @@ -3234,6 +3239,15 @@ class LLFrameStatsTimer : public LLFrameTimer } }; +static LLFastTimer::DeclareTimer FTM_AUDIO_UPDATE("Update Audio"); +static LLFastTimer::DeclareTimer FTM_CLEANUP("Cleanup"); +static LLFastTimer::DeclareTimer FTM_IDLE_CB("Idle Callbacks"); +static LLFastTimer::DeclareTimer FTM_LOD_UPDATE("Update LOD"); +static LLFastTimer::DeclareTimer FTM_OBJECTLIST_UPDATE("Update Objectlist"); +static LLFastTimer::DeclareTimer FTM_REGION_UPDATE("Update Region"); +static LLFastTimer::DeclareTimer FTM_WORLD_UPDATE("Update World"); +static LLFastTimer::DeclareTimer FTM_NETWORK("Network"); + /////////////////////////////////////////////////////// // idle() // @@ -3300,7 +3314,7 @@ void LLAppViewer::idle() if (!gDisconnected) { - LLFastTimer t(LLFastTimer::FTM_NETWORK); + LLFastTimer t(FTM_NETWORK); // Update spaceserver timeinfo LLWorld::getInstance()->setSpaceTimeUSec(LLWorld::getInstance()->getSpaceTimeUSec() + (U32)(dt_raw * SEC_TO_MICROSEC)); @@ -3381,7 +3395,7 @@ void LLAppViewer::idle() if (!gDisconnected) { - LLFastTimer t(LLFastTimer::FTM_NETWORK); + LLFastTimer t(FTM_NETWORK); //////////////////////////////////////////////// // @@ -3410,7 +3424,7 @@ void LLAppViewer::idle() // { -// LLFastTimer t(LLFastTimer::FTM_IDLE_CB); +// LLFastTimer t(FTM_IDLE_CB); // Do event notifications if necessary. Yes, we may want to move this elsewhere. gEventNotifier.update(); @@ -3445,7 +3459,7 @@ void LLAppViewer::idle() } { - LLFastTimer t(LLFastTimer::FTM_OBJECTLIST_UPDATE); // Actually "object update" + LLFastTimer t(FTM_OBJECTLIST_UPDATE); // Actually "object update" if (!(logoutRequestSent() && hasSavedFinalSnapshot())) { @@ -3460,7 +3474,7 @@ void LLAppViewer::idle() // { - LLFastTimer t(LLFastTimer::FTM_CLEANUP); + LLFastTimer t(FTM_CLEANUP); gObjectList.cleanDeadObjects(); LLDrawable::cleanupDeadDrawables(); } @@ -3492,7 +3506,7 @@ void LLAppViewer::idle() // { - LLFastTimer t(LLFastTimer::FTM_NETWORK); + LLFastTimer t(FTM_NETWORK); gVLManager.unpackData(); } @@ -3504,7 +3518,7 @@ void LLAppViewer::idle() LLWorld::getInstance()->updateVisibilities(); { const F32 max_region_update_time = .001f; // 1ms - LLFastTimer t(LLFastTimer::FTM_REGION_UPDATE); + LLFastTimer t(FTM_REGION_UPDATE); LLWorld::getInstance()->updateRegions(max_region_update_time); } @@ -3551,7 +3565,7 @@ void LLAppViewer::idle() if (!gNoRender) { - LLFastTimer t(LLFastTimer::FTM_WORLD_UPDATE); + LLFastTimer t(FTM_WORLD_UPDATE); gPipeline.updateMove(); LLWorld::getInstance()->updateParticles(); @@ -3574,12 +3588,12 @@ void LLAppViewer::idle() // objects and camera should be in sync, do LOD calculations now { - LLFastTimer t(LLFastTimer::FTM_LOD_UPDATE); + LLFastTimer t(FTM_LOD_UPDATE); gObjectList.updateApparentAngles(gAgent); } { - LLFastTimer t(LLFastTimer::FTM_AUDIO_UPDATE); + LLFastTimer t(FTM_AUDIO_UPDATE); if (gAudiop) { @@ -3719,6 +3733,8 @@ void LLAppViewer::sendLogoutRequest() static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; #endif +static LLFastTimer::DeclareTimer FTM_IDLE_NETWORK("Network"); + void LLAppViewer::idleNetwork() { LLMemType mt_in(LLMemType::MTYPE_IDLE_NETWORK); @@ -3731,7 +3747,7 @@ void LLAppViewer::idleNetwork() if (!gSavedSettings.getBOOL("SpeedTest")) { - LLFastTimer t(LLFastTimer::FTM_IDLE_NETWORK); // decode + LLFastTimer t(FTM_IDLE_NETWORK); // decode // deal with any queued name requests and replies. gCacheName->processPending(); diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index a85f8710c74a8eb756c4b15d7aae28970989e5f1..f557adf6a6a6308e7594bd12d4798d1d097b0c43 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -200,7 +200,7 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str // 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 - sortItems(); + updateSort(); // re-select items selectMultiple(selected_ids); diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 2687feb68b5ba5b4fda096bd2a7392d2ba16036e..2403e891f68db6b178f9c7ca2c92d5f58039bbf7 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -164,7 +164,7 @@ void LLBottomTray::setVisible(BOOL visible) { LLPanel::setVisible(visible); - // *NOTE: we must check mToolbarStack against NULL because sewtVisible is called from the + // *NOTE: we must check mToolbarStack against NULL because setVisible is called from the // LLPanel::initFromParams BEFORE postBuild is called and child controls are not exist yet if (NULL != mToolbarStack) { diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 7a118deb8a52caea21557b506222e1f53dde444c..bea11ecfeb8c6f42ce89e4c000f116d7d66dd197 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -103,10 +103,6 @@ LLChatBar::LLChatBar() mObserver(NULL) { setIsChrome(TRUE); - -#if !LL_RELEASE_FOR_DOWNLOAD - childDisplayNotFound(); -#endif } @@ -125,7 +121,7 @@ BOOL LLChatBar::postBuild() // * NOTE: mantipov: getChild with default parameters returns dummy widget. // Seems this class will be completle removed // attempt to bind to an existing combo box named gesture - setGestureCombo(getChild<LLComboBox>( "Gesture", TRUE, FALSE)); + setGestureCombo(findChild<LLComboBox>( "Gesture")); mInputEditor = getChild<LLLineEditor>("Chat Editor"); mInputEditor->setKeystrokeCallback(&onInputEditorKeystroke, this); diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 45b322e106f51dddcfc3b66c71654f3c5ee4db11..05c574b154689474dd3911ca33b5838dc77c7492 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -93,13 +93,11 @@ void LLChatItemCtrl::reshape (S32 width, S32 height, BOOL called_from_parent ) caption->reshape( width - 4, caption_rect.getHeight(), 1); caption->setRect(caption_rect); - LLRect msg_text_rect = msg_text->getRect(); msg_text_rect.setLeftTopAndSize( msg_left_offset, height - caption_rect.getHeight() , width - msg_left_offset - msg_right_offset, height - caption_rect.getHeight()); msg_text->reshape( width - msg_left_offset - msg_right_offset, height - caption_rect.getHeight(), 1); msg_text->setRect(msg_text_rect); } - } BOOL LLChatItemCtrl::postBuild() diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp index 933d9b8771b5711ab70034b1803242a0f66af79e..9399e1f68d7ea6d68a848035d7e4d60043848bb0 100644 --- a/indra/newview/llchatmsgbox.cpp +++ b/indra/newview/llchatmsgbox.cpp @@ -371,7 +371,7 @@ void LLChatMsgBox::drawText( S32 x, S32 y, const LLColor4& color ) mHAlign, mVAlign, mFontStyle, mShadowType, - line_length, getRect().getWidth(), NULL, TRUE, mUseEllipses ); + line_length, getRect().getWidth(), NULL, mUseEllipses ); cur_pos += line_length + 1; y -= llfloor(mFontGL->getLineHeight()) + mLineSpacing; diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index d8bd32382fad429f017f5fb10704b2b8d9e93244..7cc78aff928466300a39889de1640ac30aeb1413 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -60,6 +60,9 @@ const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f; const F32 OBJECT_DAMPING_TIME_CONSTANT = 0.06f; const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f; +static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound"); + + //////////////////////// // // Inline implementations. @@ -188,7 +191,7 @@ BOOL LLDrawable::isLight() const void LLDrawable::cleanupReferences() { - LLFastTimer t(LLFastTimer::FTM_PIPELINE); + LLFastTimer t(FTM_PIPELINE); std::for_each(mFaces.begin(), mFaces.end(), DeletePointer()); mFaces.clear(); @@ -1033,7 +1036,7 @@ void LLSpatialBridge::updateSpatialExtents() LLSpatialGroup* root = (LLSpatialGroup*) mOctree->getListener(0); { - LLFastTimer ftm(LLFastTimer::FTM_CULL_REBOUND); + LLFastTimer ftm(FTM_CULL_REBOUND); root->rebound(); } diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 940e1fc9687964b4f3f0ba20f08a76abc865e85f..c765980c30ce9e5b8f66ac61a56a7fa6e18d76c7 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -63,7 +63,6 @@ class LLViewerTexture; // Can have multiple silhouettes for each object const U32 SILHOUETTE_HIGHLIGHT = 0; - // All data for new renderer goes into this class. class LLDrawable : public LLRefCount { diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 267f83f2956f513af91216f014ee13a9bd194b65..de97e2406dcebba80bfb546526e8e8ee66e4b9dd 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -90,7 +90,7 @@ void LLDrawPoolAlpha::endDeferredPass(S32 pass) { gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.4f); { - LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS); + LLFastTimer t(FTM_RENDER_GRASS); gDeferredTreeProgram.bind(); LLGLEnable test(GL_ALPHA_TEST); //render alpha masked objects @@ -112,7 +112,7 @@ S32 LLDrawPoolAlpha::getNumPostDeferredPasses() void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA); + LLFastTimer t(FTM_RENDER_ALPHA); simple_shader = &gDeferredAlphaProgram; fullbright_shader = &gDeferredFullbrightProgram; @@ -139,7 +139,7 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass) void LLDrawPoolAlpha::beginRenderPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA); + LLFastTimer t(FTM_RENDER_ALPHA); if (LLPipeline::sUnderWaterRender) { @@ -163,7 +163,7 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass) void LLDrawPoolAlpha::endRenderPass( S32 pass ) { - LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA); + LLFastTimer t(FTM_RENDER_ALPHA); LLRenderPass::endRenderPass(pass); if(gPipeline.canUseWindLightShaders()) @@ -174,7 +174,7 @@ void LLDrawPoolAlpha::endRenderPass( S32 pass ) void LLDrawPoolAlpha::render(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA); + LLFastTimer t(FTM_RENDER_ALPHA); LLGLSPipelineAlpha gls_pipeline_alpha; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index b15cd0b0dc926ece4d64116b66330b68704090fa..a2d8c965ec6861e054639ec30d13538cdb106eff 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -89,12 +89,13 @@ S32 AVATAR_OFFSET_TEX0 = 32; S32 AVATAR_OFFSET_TEX1 = 40; S32 AVATAR_VERTEX_BYTES = 48; - BOOL gAvatarEmbossBumpMap = FALSE; static BOOL sRenderingSkinned = FALSE; S32 normal_channel = -1; S32 specular_channel = -1; +static LLFastTimer::DeclareTimer FTM_SHADOW_AVATAR("Avatar Shadow"); + LLDrawPoolAvatar::LLDrawPoolAvatar() : LLFacePool(POOL_AVATAR) { @@ -154,7 +155,7 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses() void LLDrawPoolAvatar::beginDeferredPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS); + LLFastTimer t(FTM_RENDER_CHARACTERS); if (LLPipeline::sImpostorRender) { @@ -178,7 +179,7 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass) void LLDrawPoolAvatar::endDeferredPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS); + LLFastTimer t(FTM_RENDER_CHARACTERS); if (LLPipeline::sImpostorRender) { @@ -248,7 +249,7 @@ S32 LLDrawPoolAvatar::getNumShadowPasses() void LLDrawPoolAvatar::beginShadowPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_SHADOW_AVATAR); + LLFastTimer t(FTM_SHADOW_AVATAR); sVertexProgram = &gDeferredAvatarShadowProgram; if (sShaderLevel > 0) @@ -270,7 +271,7 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass) void LLDrawPoolAvatar::endShadowPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_SHADOW_AVATAR); + LLFastTimer t(FTM_SHADOW_AVATAR); if (sShaderLevel > 0) { @@ -284,7 +285,7 @@ void LLDrawPoolAvatar::endShadowPass(S32 pass) void LLDrawPoolAvatar::renderShadow(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_SHADOW_AVATAR); + LLFastTimer t(FTM_SHADOW_AVATAR); if (mDrawFace.empty()) { @@ -320,7 +321,7 @@ S32 LLDrawPoolAvatar::getNumPasses() void LLDrawPoolAvatar::render(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS); + LLFastTimer t(FTM_RENDER_CHARACTERS); if (LLPipeline::sImpostorRender) { renderAvatars(NULL, 2); @@ -332,7 +333,7 @@ void LLDrawPoolAvatar::render(S32 pass) void LLDrawPoolAvatar::beginRenderPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS); + LLFastTimer t(FTM_RENDER_CHARACTERS); //reset vertex buffer mappings LLVertexBuffer::unbind(); @@ -358,7 +359,7 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass) void LLDrawPoolAvatar::endRenderPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS); + LLFastTimer t(FTM_RENDER_CHARACTERS); if (LLPipeline::sImpostorRender) { diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 971949e885037c5e8d836ad3728b33b5fa2751a6..2cb4d5d6d5b2cb1b59efdd43ddca0a5a7d43df23 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -74,6 +74,7 @@ const U32 VERTEX_MASK_BUMP = LLVertexBuffer::MAP_VERTEX |LLVertexBuffer::MAP_TEX U32 LLDrawPoolBump::sVertexMask = VERTEX_MASK_SHINY; + static LLGLSLShader* shader = NULL; static S32 cube_channel = -1; static S32 diffuse_channel = -1; @@ -220,7 +221,7 @@ S32 LLDrawPoolBump::getNumPasses() void LLDrawPoolBump::beginRenderPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP); + LLFastTimer t(FTM_RENDER_BUMP); switch( pass ) { case 0: @@ -247,7 +248,7 @@ void LLDrawPoolBump::beginRenderPass(S32 pass) void LLDrawPoolBump::render(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP); + LLFastTimer t(FTM_RENDER_BUMP); if (!gPipeline.hasRenderType(LLDrawPool::POOL_SIMPLE)) { @@ -280,7 +281,7 @@ void LLDrawPoolBump::render(S32 pass) void LLDrawPoolBump::endRenderPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP); + LLFastTimer t(FTM_RENDER_BUMP); switch( pass ) { case 0: @@ -308,7 +309,7 @@ void LLDrawPoolBump::endRenderPass(S32 pass) //static void LLDrawPoolBump::beginShiny(bool invisible) { - LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); + LLFastTimer t(FTM_RENDER_SHINY); if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)|| invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) { @@ -383,7 +384,7 @@ void LLDrawPoolBump::beginShiny(bool invisible) void LLDrawPoolBump::renderShiny(bool invisible) { - LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); + LLFastTimer t(FTM_RENDER_SHINY); if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)|| invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) { @@ -410,7 +411,7 @@ void LLDrawPoolBump::renderShiny(bool invisible) void LLDrawPoolBump::endShiny(bool invisible) { - LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); + LLFastTimer t(FTM_RENDER_SHINY); if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)|| invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) { @@ -450,7 +451,7 @@ void LLDrawPoolBump::endShiny(bool invisible) void LLDrawPoolBump::beginFullbrightShiny() { - LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); + LLFastTimer t(FTM_RENDER_SHINY); if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY)) { return; @@ -499,7 +500,7 @@ void LLDrawPoolBump::beginFullbrightShiny() void LLDrawPoolBump::renderFullbrightShiny() { - LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); + LLFastTimer t(FTM_RENDER_SHINY); if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY)) { return; @@ -514,7 +515,7 @@ void LLDrawPoolBump::renderFullbrightShiny() void LLDrawPoolBump::endFullbrightShiny() { - LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); + LLFastTimer t(FTM_RENDER_SHINY); if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY)) { return; @@ -624,7 +625,7 @@ void LLDrawPoolBump::beginBump() } sVertexMask = VERTEX_MASK_BUMP; - LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP); + LLFastTimer t(FTM_RENDER_BUMP); // Optional second pass: emboss bump map stop_glerror(); @@ -668,7 +669,7 @@ void LLDrawPoolBump::renderBump() return; } - LLFastTimer ftm(LLFastTimer::FTM_RENDER_BUMP); + LLFastTimer ftm(FTM_RENDER_BUMP); LLGLDisable fog(GL_FOG); LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL); LLGLEnable blend(GL_BLEND); @@ -705,7 +706,7 @@ void LLDrawPoolBump::beginDeferredPass(S32 pass) { return; } - LLFastTimer ftm(LLFastTimer::FTM_RENDER_BUMP); + LLFastTimer ftm(FTM_RENDER_BUMP); mShiny = TRUE; gDeferredBumpProgram.bind(); diffuse_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); @@ -720,7 +721,7 @@ void LLDrawPoolBump::endDeferredPass(S32 pass) { return; } - LLFastTimer ftm(LLFastTimer::FTM_RENDER_BUMP); + LLFastTimer ftm(FTM_RENDER_BUMP); mShiny = FALSE; gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::BUMP_MAP); @@ -734,7 +735,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass) { return; } - LLFastTimer ftm(LLFastTimer::FTM_RENDER_BUMP); + LLFastTimer ftm(FTM_RENDER_BUMP); U32 type = LLRenderPass::PASS_BUMP; LLCullResult::drawinfo_list_t::iterator begin = gPipeline.beginRenderMap(type); @@ -1250,7 +1251,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) void LLDrawPoolInvisible::render(S32 pass) { //render invisiprims - LLFastTimer t(LLFastTimer::FTM_RENDER_INVISIBLE); + LLFastTimer t(FTM_RENDER_INVISIBLE); U32 invisi_mask = LLVertexBuffer::MAP_VERTEX; glStencilMask(0); @@ -1279,7 +1280,7 @@ void LLDrawPoolInvisible::endDeferredPass( S32 pass ) void LLDrawPoolInvisible::renderDeferred( S32 pass ) { //render invisiprims; this doesn't work becaue it also blocks all the post-deferred stuff - LLFastTimer t(LLFastTimer::FTM_RENDER_INVISIBLE); + LLFastTimer t(FTM_RENDER_INVISIBLE); U32 invisi_mask = LLVertexBuffer::MAP_VERTEX; glStencilMask(0); diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 1fdf87f6d26c521974968e8b9f341e32c2922f83..d084bda2eacfa3631c1176b5d3d945ae8fa56df6 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -50,7 +50,7 @@ static LLGLSLShader* fullbright_shader = NULL; void LLDrawPoolGlow::render(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_GLOW); + LLFastTimer t(FTM_RENDER_GLOW); LLGLEnable blend(GL_BLEND); LLGLDisable test(GL_ALPHA_TEST); gGL.setSceneBlendType(LLRender::BT_ADD); @@ -98,7 +98,7 @@ void LLDrawPoolSimple::prerender() void LLDrawPoolSimple::beginRenderPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE); + LLFastTimer t(FTM_RENDER_SIMPLE); if (LLPipeline::sUnderWaterRender) { @@ -125,7 +125,7 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass) void LLDrawPoolSimple::endRenderPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE); + LLFastTimer t(FTM_RENDER_SIMPLE); LLRenderPass::endRenderPass(pass); if (mVertexShaderLevel > 0){ @@ -140,7 +140,7 @@ void LLDrawPoolSimple::render(S32 pass) LLGLDisable alpha_test(GL_ALPHA_TEST); { //render simple - LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE); + LLFastTimer t(FTM_RENDER_SIMPLE); gPipeline.enableLightsDynamic(); renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask()); @@ -157,13 +157,13 @@ void LLDrawPoolSimple::render(S32 pass) void LLDrawPoolSimple::beginDeferredPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE); + LLFastTimer t(FTM_RENDER_SIMPLE); gDeferredDiffuseProgram.bind(); } void LLDrawPoolSimple::endDeferredPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE); + LLFastTimer t(FTM_RENDER_SIMPLE); LLRenderPass::endRenderPass(pass); gDeferredDiffuseProgram.unbind(); @@ -175,7 +175,7 @@ void LLDrawPoolSimple::renderDeferred(S32 pass) LLGLDisable alpha_test(GL_ALPHA_TEST); { //render simple - LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE); + LLFastTimer t(FTM_RENDER_SIMPLE); renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask()); } } @@ -195,7 +195,7 @@ void LLDrawPoolGrass::prerender() void LLDrawPoolGrass::beginRenderPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS); + LLFastTimer t(FTM_RENDER_GRASS); if (LLPipeline::sUnderWaterRender) { @@ -222,7 +222,7 @@ void LLDrawPoolGrass::beginRenderPass(S32 pass) void LLDrawPoolGrass::endRenderPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS); + LLFastTimer t(FTM_RENDER_GRASS); LLRenderPass::endRenderPass(pass); if (mVertexShaderLevel > 0) @@ -237,7 +237,7 @@ void LLDrawPoolGrass::render(S32 pass) gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); { - LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS); + LLFastTimer t(FTM_RENDER_GRASS); LLGLEnable test(GL_ALPHA_TEST); gGL.setSceneBlendType(LLRender::BT_ALPHA); //render grass @@ -262,7 +262,7 @@ void LLDrawPoolGrass::renderDeferred(S32 pass) gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); { - LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS); + LLFastTimer t(FTM_RENDER_GRASS); gDeferredTreeProgram.bind(); LLGLEnable test(GL_ALPHA_TEST); //render grass @@ -286,7 +286,7 @@ void LLDrawPoolFullbright::prerender() void LLDrawPoolFullbright::beginRenderPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_FULLBRIGHT); + LLFastTimer t(FTM_RENDER_FULLBRIGHT); if (LLPipeline::sUnderWaterRender) { @@ -300,7 +300,7 @@ void LLDrawPoolFullbright::beginRenderPass(S32 pass) void LLDrawPoolFullbright::endRenderPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_FULLBRIGHT); + LLFastTimer t(FTM_RENDER_FULLBRIGHT); LLRenderPass::endRenderPass(pass); if (mVertexShaderLevel > 0) @@ -311,7 +311,7 @@ void LLDrawPoolFullbright::endRenderPass(S32 pass) void LLDrawPoolFullbright::render(S32 pass) { //render fullbright - LLFastTimer t(LLFastTimer::FTM_RENDER_FULLBRIGHT); + LLFastTimer t(FTM_RENDER_FULLBRIGHT); if (mVertexShaderLevel > 0) { fullbright_shader->bind(); diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index a01c9026c8c9a9d24a878694a0a5506a978defe4..345dd6bb8445fbc99df56d0960cc970d739f6ea3 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -61,6 +61,8 @@ int DebugDetailMap = 0; S32 LLDrawPoolTerrain::sDetailMode = 1; F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE; static LLGLSLShader* sShader = NULL; +static LLFastTimer::DeclareTimer FTM_SHADOW_TERRAIN("Terrain Shadow"); + LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) : LLFacePool(POOL_TERRAIN), @@ -131,7 +133,7 @@ void LLDrawPoolTerrain::prerender() void LLDrawPoolTerrain::beginRenderPass( S32 pass ) { - LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN); + LLFastTimer t(FTM_RENDER_TERRAIN); LLFacePool::beginRenderPass(pass); sShader = LLPipeline::sUnderWaterRender ? @@ -146,7 +148,7 @@ void LLDrawPoolTerrain::beginRenderPass( S32 pass ) void LLDrawPoolTerrain::endRenderPass( S32 pass ) { - LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN); + LLFastTimer t(FTM_RENDER_TERRAIN); LLFacePool::endRenderPass(pass); if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0) { @@ -162,7 +164,7 @@ S32 LLDrawPoolTerrain::getDetailMode() void LLDrawPoolTerrain::render(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN); + LLFastTimer t(FTM_RENDER_TERRAIN); if (mDrawFace.empty()) { @@ -235,7 +237,7 @@ void LLDrawPoolTerrain::render(S32 pass) void LLDrawPoolTerrain::beginDeferredPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN); + LLFastTimer t(FTM_RENDER_TERRAIN); LLFacePool::beginRenderPass(pass); sShader = &gDeferredTerrainProgram; @@ -245,14 +247,14 @@ void LLDrawPoolTerrain::beginDeferredPass(S32 pass) void LLDrawPoolTerrain::endDeferredPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN); + LLFastTimer t(FTM_RENDER_TERRAIN); LLFacePool::endRenderPass(pass); sShader->unbind(); } void LLDrawPoolTerrain::renderDeferred(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN); + LLFastTimer t(FTM_RENDER_TERRAIN); if (mDrawFace.empty()) { return; @@ -262,7 +264,7 @@ void LLDrawPoolTerrain::renderDeferred(S32 pass) void LLDrawPoolTerrain::beginShadowPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_SHADOW_TERRAIN); + LLFastTimer t(FTM_SHADOW_TERRAIN); LLFacePool::beginRenderPass(pass); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gDeferredShadowProgram.bind(); @@ -270,14 +272,14 @@ void LLDrawPoolTerrain::beginShadowPass(S32 pass) void LLDrawPoolTerrain::endShadowPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_SHADOW_TERRAIN); + LLFastTimer t(FTM_SHADOW_TERRAIN); LLFacePool::endRenderPass(pass); gDeferredShadowProgram.unbind(); } void LLDrawPoolTerrain::renderShadow(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_SHADOW_TERRAIN); + LLFastTimer t(FTM_SHADOW_TERRAIN); if (mDrawFace.empty()) { return; diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index f572e2cb44893cbf2d5255c110ea108b8817b6d3..5cb1fcb635bc145c5e14f10d934690b53bbf1cb4 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -46,6 +46,7 @@ S32 LLDrawPoolTree::sDiffTex = 0; static LLGLSLShader* shader = NULL; +static LLFastTimer::DeclareTimer FTM_SHADOW_TREE("Tree Shadow"); LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) : LLFacePool(POOL_TREE), @@ -67,7 +68,7 @@ void LLDrawPoolTree::prerender() void LLDrawPoolTree::beginRenderPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); + LLFastTimer t(FTM_RENDER_TREES); gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); if (LLPipeline::sUnderWaterRender) @@ -91,7 +92,7 @@ void LLDrawPoolTree::beginRenderPass(S32 pass) void LLDrawPoolTree::render(S32 pass) { - LLFastTimer t(LLPipeline::sShadowRender ? LLFastTimer::FTM_SHADOW_TREE : LLFastTimer::FTM_RENDER_TREES); + LLFastTimer t(LLPipeline::sShadowRender ? FTM_SHADOW_TREE : FTM_RENDER_TREES); if (mDrawFace.empty()) { @@ -122,7 +123,7 @@ void LLDrawPoolTree::render(S32 pass) void LLDrawPoolTree::endRenderPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); + LLFastTimer t(FTM_RENDER_TREES); gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); if (gPipeline.canUseWindLightShadersOnObjects()) @@ -136,7 +137,7 @@ void LLDrawPoolTree::endRenderPass(S32 pass) //============================================ void LLDrawPoolTree::beginDeferredPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); + LLFastTimer t(FTM_RENDER_TREES); gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); shader = &gDeferredTreeProgram; @@ -150,7 +151,7 @@ void LLDrawPoolTree::renderDeferred(S32 pass) void LLDrawPoolTree::endDeferredPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); + LLFastTimer t(FTM_RENDER_TREES); gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); shader->unbind(); @@ -161,7 +162,7 @@ void LLDrawPoolTree::endDeferredPass(S32 pass) //============================================ void LLDrawPoolTree::beginShadowPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_SHADOW_TREE); + LLFastTimer t(FTM_SHADOW_TREE); gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); gDeferredShadowProgram.bind(); } @@ -173,7 +174,7 @@ void LLDrawPoolTree::renderShadow(S32 pass) void LLDrawPoolTree::endShadowPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_SHADOW_TREE); + LLFastTimer t(FTM_SHADOW_TREE); gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); gDeferredShadowProgram.unbind(); } diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 16623ca2b62236cb7a4118fc1e8cbee5a87c3076..fd4dc123d5fd70771ccca4ffa519873cd59d8583 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -138,7 +138,7 @@ void LLDrawPoolWater::endPostDeferredPass(S32 pass) void LLDrawPoolWater::render(S32 pass) { - LLFastTimer ftm(LLFastTimer::FTM_RENDER_WATER); + LLFastTimer ftm(FTM_RENDER_WATER); if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1) { return; diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 917b6fafbce8ebb662dc156d07182f010814b4b2..9b52ddb73c6321c5bc2fc6eaefa5e34e0e6c634b 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -260,7 +260,7 @@ void LLDrawPoolWLSky::render(S32 pass) { return; } - LLFastTimer ftm(LLFastTimer::FTM_RENDER_WL_SKY); + LLFastTimer ftm(FTM_RENDER_WL_SKY); const F32 camHeightLocal = LLWLParamManager::instance()->getDomeOffset() * LLWLParamManager::instance()->getDomeRadius(); diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 0aef3123d6fe124f45e9163268aab1d7ef4d0c5f..8ceb41c27a609bbdea4949f08ff1a39495d14c2f 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -195,7 +195,8 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) if(LLFastTimer::sPauseHistory && mBarRect.pointInRect(x, y)) { - mHoverBarIndex = llmin(LLFastTimer::getCurFrameIndex() - 1, MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight())); + mHoverBarIndex = llmin(LLFastTimer::getCurFrameIndex() - 1, + MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight())); if (mHoverBarIndex == 0) { return TRUE; @@ -217,9 +218,9 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) mHoverID = (*it); mHoverTimer = (*it); mToolTipRect.set(mBarStart[mHoverBarIndex][i], - mBarRect.mBottom + llround(((F32)mHoverBarIndex + 1.f) * ((F32)mBarRect.getHeight() / ((F32)MAX_VISIBLE_HISTORY + 2.f))), + mBarRect.mBottom + llround(((F32)(MAX_VISIBLE_HISTORY - mHoverBarIndex + 1)) * ((F32)mBarRect.getHeight() / ((F32)MAX_VISIBLE_HISTORY + 2.f))), mBarEnd[mHoverBarIndex][i], - mBarRect.mBottom + llround((F32)mHoverBarIndex * ((F32)mBarRect.getHeight() / ((F32)MAX_VISIBLE_HISTORY + 2.f)))); + mBarRect.mBottom + llround((F32)(MAX_VISIBLE_HISTORY - mHoverBarIndex) * ((F32)mBarRect.getHeight() / ((F32)MAX_VISIBLE_HISTORY + 2.f)))); } if ((*it)->getCollapsed()) @@ -248,6 +249,7 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* stic // tooltips for timer bars if (mHoverTimer) { + localRectToScreen(mToolTipRect, sticky_rect_screen); msg = mHoverTimer->getToolTip(LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex); return TRUE; } @@ -960,9 +962,14 @@ void LLFastTimerView::draw() LLView::draw(); } -F64 LLFastTimerView::getTime(LLFastTimer::NamedTimer::FrameState& id) +F64 LLFastTimerView::getTime(const std::string& name) { - return (F64)id.mTimer->getCountAverage() / (F64)LLFastTimer::countsPerSecond(); + const LLFastTimer::NamedTimer* timerp = LLFastTimer::getTimerByName(name); + if (timerp) + { + return (F64)timerp->getCountAverage() / (F64)LLFastTimer::countsPerSecond(); + } + return 0.0; } //static diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index 78ca7b50d6ef612c60355d9b7b5c2298dcf7af97..f301888984f4c60d8e4eff230f80dc204ddd1603 100644 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -62,7 +62,7 @@ class LLFastTimerView : public LLFloater virtual void draw(); LLFastTimer::NamedTimer* getLegendID(S32 y); - F64 getTime(LLFastTimer::NamedTimer::FrameState& id); + F64 getTime(const std::string& name); private: typedef std::vector<std::vector<S32> > bar_positions_t; diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 7fc127f8031e25d549af9832d532b68216c10e57..9c1a7ecb0408dda8911dd60e58b44cdf3a895b6d 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -36,6 +36,7 @@ #include "llbutton.h" #include "llfloaterreg.h" +#include "llfocusmgr.h" #include "llinventory.h" #include "lluictrlfactory.h" #include "llmenugl.h" @@ -292,7 +293,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) if (mFirstDropDownItem != count) { // Chevron button should stay right aligned - LLView *chevron_button = getChildView(std::string(">>"), FALSE, FALSE); + LLView *chevron_button = findChildView(std::string(">>"), FALSE); if (chevron_button) { LLRect rect; @@ -335,7 +336,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width) else { // Hide chevron button if all items are visible on bar - LLView *chevron_button = getChildView(std::string(">>"), FALSE, FALSE); + LLView *chevron_button = findChildView(std::string(">>"), FALSE); if (chevron_button) { chevron_button->setVisible(FALSE); @@ -366,7 +367,7 @@ void LLFavoritesBarCtrl::createButtons(const LLInventoryModel::item_array_t &ite fav_btn->setLabel(item->getName()); fav_btn->setToolTip(item->getName()); fav_btn->setCommitCallback(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID())); - fav_btn->setRightClickedCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID(), _1, _2, _3,_4 )); + fav_btn->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID(), _1, _2, _3,_4 )); sendChildToBack(fav_btn); curr_x += buttonWidth + buttonHGap; @@ -486,7 +487,7 @@ void LLFavoritesBarCtrl::showDropDownMenu() item_params.on_click.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID())); LLMenuItemCallGL *menu_item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params); - menu_item->setRightClickedCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this,item->getUUID(),_1,_2,_3,_4)); + menu_item->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this,item->getUUID(),_1,_2,_3,_4)); // Check whether item name wider than menu if ((S32) menu_item->getNominalWidth() > bar_width) { @@ -545,6 +546,10 @@ void LLFavoritesBarCtrl::onButtonRightClick( LLUUID item_id,LLView* fav_button,S return; } + // Release mouse capture so hover events go to the popup menu + // because this is happening during a mouse down. + gFocusMgr.setMouseCapture(NULL); + menu->updateParent(LLMenuGL::sMenuContainer); LLMenuGL::showPopup(fav_button, menu, x, y); } diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index bafb69a8354f061dbbcc412048a55bdbc7f63520..216bca8262ceb96bff83b02da00dcefa146f0771 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -261,6 +261,7 @@ void LLVolumeImplFlexible::onSetVolume(const LLVolumeParams &volume_params, cons // updated every time step. In the future, perhaps there could be an // optimization similar to what Havok does for objects that are stationary. //--------------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies"); BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { if (mVO->mDrawable.isNull()) @@ -279,7 +280,7 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6 parent->mDrawable->mQuietCount = 0; } - LLFastTimer ftm(LLFastTimer::FTM_FLEXIBLE_UPDATE); + LLFastTimer ftm(FTM_FLEXIBLE_UPDATE); S32 new_res = mAttributes->getSimulateLOD(); diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 7332ca4b5c77f3806f3af0b98b2d17c883ce2655..3c27d37ee92cc45edbac69b734a53319c46805f8 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -61,6 +61,8 @@ #include "llmediamanager.h" #include "llwindow.h" +#include "llbutton.h" + #if LL_WINDOWS #include "lldxhardware.h" #endif @@ -102,20 +104,18 @@ BOOL LLFloaterAbout::postBuild() support_widget->setParseHTML(TRUE); // Text styles for release notes hyperlinks - LLStyleSP viewer_link_style(new LLStyle); - viewer_link_style->setVisible(true); - viewer_link_style->setFontName(LLStringUtil::null); - viewer_link_style->setLinkHREF(get_viewer_release_notes_url()); - viewer_link_style->setColor(LLUIColorTable::instance().getColor("HTMLLinkColor")); + LLStyle::Params link_style_params; + link_style_params.color.control = "HTMLLinkColor"; + link_style_params.link_href = get_viewer_release_notes_url(); // Version string - std::string version = LLTrans::getString("SECOND_LIFE_VIEWER") + std::string version = LLTrans::getString("APP_NAME") + llformat(" %d.%d.%d (%d) %s %s (%s)\n", LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VIEWER_BUILD, __DATE__, __TIME__, gSavedSettings.getString("VersionChannelName").c_str()); support_widget->appendColoredText(version, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor")); - support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, viewer_link_style); + support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, link_style_params); std::string support; support.append("\n\n"); @@ -132,11 +132,9 @@ BOOL LLFloaterAbout::postBuild() LLViewerRegion* region = gAgent.getRegion(); if (region) { - LLStyleSP server_link_style(new LLStyle); - server_link_style->setVisible(true); - server_link_style->setFontName(LLStringUtil::null); - server_link_style->setLinkHREF(region->getCapability("ServerReleaseNotes")); - server_link_style->setColor(LLUIColorTable::instance().getColor("HTMLLinkColor")); + LLStyle::Params server_link_style_params; + server_link_style_params.color.control = "HTMLLinkColor"; + server_link_style_params.link_href = region->getCapability("ServerReleaseNotes"); const LLVector3d &pos = gAgent.getPositionGlobal(); LLUIString pos_text = getString("you_are_at"); @@ -159,7 +157,7 @@ BOOL LLFloaterAbout::postBuild() support.append("\n"); support_widget->appendColoredText(support, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor")); - support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, server_link_style); + support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, server_link_style_params); support = "\n\n"; } @@ -251,13 +249,9 @@ BOOL LLFloaterAbout::postBuild() // Fix views support_widget->setCursorPos(0); support_widget->setEnabled(FALSE); - support_widget->setTakesFocus(TRUE); - support_widget->setHandleEditKeysDirectly(TRUE); credits_widget->setCursorPos(0); credits_widget->setEnabled(FALSE); - credits_widget->setTakesFocus(TRUE); - credits_widget->setHandleEditKeysDirectly(TRUE); return TRUE; } diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index 3d1b7965a115ed4bfd0d91565bf46c9c5ebc9945..7075719299c7b2258a7a704605d122e1e7e386f5 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -566,32 +566,25 @@ void LLFloaterBuyLandUI::onChangeAgreeCovenant(LLUICtrl* ctrl, void* user_data) void LLFloaterBuyLandUI::updateFloaterCovenantText(const std::string &string, const LLUUID& asset_id) { LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("covenant_editor"); - if (editor) - { - editor->setHandleEditKeysDirectly(FALSE); - editor->setText(string); + editor->setText(string); - LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant"); - LLTextBox* box = getChild<LLTextBox>("covenant_text"); - if(check && box) - { - if (asset_id.isNull()) - { - check->set(true); - check->setEnabled(false); - refreshUI(); + LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant"); + LLTextBox* box = getChild<LLTextBox>("covenant_text"); + if (asset_id.isNull()) + { + check->set(true); + check->setEnabled(false); + refreshUI(); - // remove the line stating that you must agree - box->setVisible(FALSE); - } - else - { - check->setEnabled(true); + // remove the line stating that you must agree + box->setVisible(FALSE); + } + else + { + check->setEnabled(true); - // remove the line stating that you must agree - box->setVisible(TRUE); - } - } + // remove the line stating that you must agree + box->setVisible(TRUE); } } diff --git a/indra/newview/llfloaterbuyland.h b/indra/newview/llfloaterbuyland.h index 7df07f752dd24eb59dc98a0b456ef89f700f4a1a..00d44035aeba301750a295ebfaa9cb2e3f5bc594 100644 --- a/indra/newview/llfloaterbuyland.h +++ b/indra/newview/llfloaterbuyland.h @@ -35,7 +35,6 @@ class LLFloater; class LLViewerRegion; -class LLViewerTextEditor; class LLParcelSelection; class LLFloaterBuyLand diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp index 742cc5c5de073bc5a234b8274248b11e20fd77c3..8c09ee7d4842bac2d48a9a41898c838e5654d035 100644 --- a/indra/newview/llfloaterchat.cpp +++ b/indra/newview/llfloaterchat.cpp @@ -172,8 +172,7 @@ void add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& { std::string start_line = line.substr(0, chat.mFromName.length() + 1); line = line.substr(chat.mFromName.length() + 1); - const LLStyleSP &sourceStyle = LLStyleMap::instance().lookup(chat.mFromID,chat.mURL); - edit->appendStyledText(start_line, false, prepend_newline, sourceStyle); + edit->appendStyledText(start_line, false, prepend_newline, LLStyleMap::instance().lookup(chat.mFromID,chat.mURL)); prepend_newline = false; } edit->appendColoredText(line, false, prepend_newline, color); diff --git a/indra/newview/llfloaterchat.h b/indra/newview/llfloaterchat.h index e8af48d0958f96c4a15241e3626ec78b23ce1cd1..6ba3165d6a04ff697d118296954ebc18fa44e360 100644 --- a/indra/newview/llfloaterchat.h +++ b/indra/newview/llfloaterchat.h @@ -42,14 +42,8 @@ #include "lllogchat.h" class LLChat; -class LLViewerTextEditor; -class LLMessageSystem; -class LLUUID; -class LLCheckBoxCtrl; class LLPanelActiveSpeakers; class LLLogChat; -class LLVector3d; -class LLWindow; enum ELogOptions { diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp index 1e8e7bad74f4cef0c83f4bc46ec53402528c63df..eb73bd6d8f44c50057f9f3af87b3a216cf87dfa2 100644 --- a/indra/newview/llfloaterfriends.cpp +++ b/indra/newview/llfloaterfriends.cpp @@ -404,7 +404,7 @@ void LLPanelFriends::refreshNames(U32 changed_mask) // 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 - mFriendsList->sortItems(); + mFriendsList->updateSort(); // re-select items mFriendsList->selectMultiple(selected_ids); diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp index 3c66a2add14409453d0b8efcb3ee0999ad582899..45a42f994d44df333be55caa37b5d8b56afe6caf 100644 --- a/indra/newview/llfloaterinventory.cpp +++ b/indra/newview/llfloaterinventory.cpp @@ -1000,7 +1000,7 @@ BOOL LLFloaterInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, { // Check to see if we are auto scrolling from the last frame LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel(); - BOOL needsToScroll = panel->getScrollableContainer()->needsToScroll(x, y, LLScrollContainer::VERTICAL); + BOOL needsToScroll = panel->getScrollableContainer()->autoScroll(x, y); if(mFilterTabs) { if(needsToScroll) @@ -1320,9 +1320,11 @@ LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState() return mFolders->getFilter()->getShowFolderState(); } +static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh"); + void LLInventoryPanel::modelChanged(U32 mask) { - LLFastTimer t2(LLFastTimer::FTM_REFRESH); + LLFastTimer t2(FTM_REFRESH); bool handled = false; if(mask & LLInventoryObserver::LABEL) diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index c5e07c6596ba32b0af1becaf78400b94ee7f4df1..1746d6d4353c3df06869a3ddbf942d018d2a5d6c 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -2847,11 +2847,7 @@ void LLPanelLandCovenant::updateCovenantText(const std::string &string) if (self) { LLViewerTextEditor* editor = self->getChild<LLViewerTextEditor>("covenant_editor"); - if (editor) - { - editor->setHandleEditKeysDirectly(TRUE); - editor->setText(string); - } + editor->setText(string); } } diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 7fc5ed0c9eecdf877d0983ecea07fbe1068f68aa..29d1c4dd84a97d9435734af0200d9fb607b28b9a 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -59,7 +59,6 @@ class LLTextBox; class LLTextEditor; class LLTextureCtrl; class LLUIImage; -class LLViewerTextEditor; class LLParcelSelection; class LLPanelLandGeneral; diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp index 0a3d97245b3b9dcff7777fbeb121d58751dcc6b3..f2dff55044aa831f8cf15524c22f7aeadc3f40d4 100644 --- a/indra/newview/llfloaternotificationsconsole.cpp +++ b/indra/newview/llfloaternotificationsconsole.cpp @@ -39,7 +39,6 @@ #include "llscrolllistitem.h" #include "llpanel.h" #include "llcombobox.h" -#include "llviewertexteditor.h" const S32 NOTIFICATION_PANEL_HEADER_HEIGHT = 20; const S32 HEADER_PADDING = 38; @@ -250,7 +249,7 @@ LLFloaterNotification::LLFloaterNotification(LLNotification* note) BOOL LLFloaterNotification::postBuild() { setTitle(mNote->getName()); - getChild<LLViewerTextEditor>("payload")->setText(mNote->getMessage()); + getChild<LLUICtrl>("payload")->setValue(mNote->getMessage()); LLComboBox* responses_combo = getChild<LLComboBox>("response"); LLCtrlListInterface* response_list = responses_combo->getListInterface(); diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp index aa68a1b2292a0811a7686b132169db381d0f2995..ac687ed3e9306efdc774777f73e89fc129c92b4d 100644 --- a/indra/newview/llfloaterpostcard.cpp +++ b/indra/newview/llfloaterpostcard.cpp @@ -43,8 +43,8 @@ #include "llagent.h" #include "llui.h" #include "lllineeditor.h" -#include "llviewertexteditor.h" #include "llbutton.h" +#include "lltexteditor.h" #include "llfloaterreg.h" #include "llviewercontrol.h" #include "llviewernetwork.h" @@ -104,14 +104,8 @@ BOOL LLFloaterPostcard::postBuild() gAgent.buildFullname(name_string); childSetValue("name_form", LLSD(name_string)); - LLTextEditor* MsgField = getChild<LLTextEditor>("msg_form"); - if (MsgField) - { - MsgField->setWordWrap(TRUE); - - // For the first time a user focusess to .the msg box, all text will be selected. - MsgField->setFocusChangedCallback(onMsgFormFocusRecieved, this); - } + // For the first time a user focusess to .the msg box, all text will be selected. + getChild<LLUICtrl>("msg_form")->setFocusChangedCallback(onMsgFormFocusRecieved, this); childSetFocus("to_form", TRUE); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 1a7f72d49c75153ed1f2a9a46ff117e59371a3ec..79f8f412fdf8a39a8257d68a273d31559ed22329 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -62,13 +62,11 @@ #include "llpanellogin.h" #include "llradiogroup.h" #include "llsky.h" -#include "llstylemap.h" #include "llscrolllistctrl.h" #include "llscrolllistitem.h" #include "llsliderctrl.h" #include "lltabcontainer.h" #include "lltrans.h" -#include "lltexteditor.h" #include "llviewercontrol.h" #include "llviewercamera.h" #include "llviewerwindow.h" @@ -169,7 +167,6 @@ void LLVoiceSetKeyDialog::onCancel(void* user_data) // a static member and update all our static callbacks void free_web_media(LLMediaBase *media_source); -void handleHTMLLinkColorChanged(const LLSD& newvalue); void handleNameTagOptionChanged(const LLSD& newvalue); LLMediaBase *get_web_media(); bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response); @@ -239,12 +236,6 @@ bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response return false; } -void handleHTMLLinkColorChanged(const LLSD& newvalue) -{ - LLTextEditor::setLinkColor(LLColor4(newvalue)); - LLStyleMap::instance().update(); - -} void handleNameTagOptionChanged(const LLSD& newvalue) { S32 name_tag_option = S32(newvalue); @@ -458,14 +449,12 @@ void LLFloaterPreference::apply() } free_web_media(media_source); - LLTextEditor* busy = getChild<LLTextEditor>("busy_response"); - LLWString busy_response; - if (busy) busy_response = busy->getWText(); - LLWStringUtil::replaceTabsWithSpaces(busy_response, 4); +// LLWString busy_response = utf8str_to_wstring(getChild<LLUICtrl>("busy_response")->getValue().asString()); +// LLWStringUtil::replaceTabsWithSpaces(busy_response, 4); if(mGotPersonalInfo) { - gSavedPerAccountSettings.setString("BusyModeResponse2", std::string(wstring_to_utf8str(busy_response))); +// gSavedSettings.setString("BusyModeResponse2", std::string(wstring_to_utf8str(busy_response))); bool new_im_via_email = childGetValue("send_im_to_email").asBoolean(); bool new_hide_online = childGetValue("online_visibility").asBoolean(); @@ -1172,13 +1161,13 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im childSetValue("send_im_to_email", im_via_email); childEnable("log_instant_messages"); // childEnable("log_chat"); - childEnable("busy_response"); +// childEnable("busy_response"); // childEnable("log_instant_messages_timestamp"); // childEnable("log_chat_timestamp"); childEnable("log_chat_IM"); childEnable("log_date_timestamp"); - childSetText("busy_response", gSavedPerAccountSettings.getString("BusyModeResponse2")); +// childSetText("busy_response", gSavedSettings.getString("BusyModeResponse2")); enableHistory(); std::string display_email(email); @@ -1349,8 +1338,7 @@ static LLRegisterPanelClassWrapper<LLPanelPreference> t_places("panel_preference LLPanelPreference::LLPanelPreference() : LLPanel() { - // - mCommitCallbackRegistrar.add("setControlFalse", boost::bind(&LLPanelPreference::setControlFalse,this, _2)); + mCommitCallbackRegistrar.add("Pref.setControlFalse", boost::bind(&LLPanelPreference::setControlFalse,this, _2)); } static void applyUIColor(const std::string& color_name, LLUICtrl* ctrl, const LLSD& param) @@ -1422,23 +1410,17 @@ BOOL LLPanelPreference::postBuild() ////// if(hasChild("online_visibility") && hasChild("send_im_to_email")) { - requires("online_visibility"); - requires("send_im_to_email"); - if (!checkRequirements()) - { - return FALSE; - } childSetText("email_address",getString("log_in_to_change") ); - childSetText("busy_response", getString("log_in_to_change")); +// childSetText("busy_response", getString("log_in_to_change")); } - if(hasChild("fullscreen combo")) + if(hasChild("aspect_ratio")) { //============================================================================ // Resolution - +/* S32 num_resolutions = 0; LLWindow::LLWindowResolution* supported_resolutions = gViewerWindow->getWindow()->getSupportedResolutions(num_resolutions); @@ -1481,7 +1463,7 @@ BOOL LLPanelPreference::postBuild() ctrl_full_screen->setCurrentByIndex(0); } } - + */ LLFloaterPreference::initWindowSizeControls(this); if (gSavedSettings.getBOOL("FullScreenAutoDetectAspectRatio")) diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp index 8ac00832c93d93c5dc02bed709b586b3934a25e2..ab281e9f9f6d9386edb9e4f9417742c475a88824 100644 --- a/indra/newview/llfloaterproperties.cpp +++ b/indra/newview/llfloaterproperties.cpp @@ -46,6 +46,7 @@ #include "llavataractions.h" #include "llinventorymodel.h" #include "lllineeditor.h" +#include "llspinctrl.h" #include "llradiogroup.h" #include "llresmgr.h" #include "roles_constants.h" @@ -151,7 +152,7 @@ BOOL LLFloaterProperties::postBuild() getChild<LLUICtrl>("CheckPurchase")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleInfo, this)); getChild<LLUICtrl>("RadioSaleType")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleType, this)); // "Price" label for edit - getChild<LLUICtrl>("EditPrice")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleInfo, this)); + getChild<LLUICtrl>("Edit Cost")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleInfo, this)); // The UI has been built, now fill in all the values refresh(); @@ -195,7 +196,7 @@ void LLFloaterProperties::refresh() "CheckNextOwnerTransfer", "CheckPurchase", "RadioSaleType", - "EditPrice" + "Edit Cost" }; for(size_t t=0; t<LL_ARRAY_SIZE(enableNames); ++t) { @@ -499,7 +500,7 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) childSetEnabled("RadioSaleType",is_complete && is_for_sale); childSetEnabled("TextPrice",is_complete && is_for_sale); - childSetEnabled("EditPrice",is_complete && is_for_sale); + childSetEnabled("Edit Cost",is_complete && is_for_sale); } else { @@ -513,11 +514,13 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) childSetEnabled("RadioSaleType",FALSE); childSetEnabled("TextPrice",FALSE); - childSetEnabled("EditPrice",FALSE); + childSetEnabled("Edit Cost",FALSE); } // Set values. childSetValue("CheckPurchase", is_for_sale); + childSetEnabled("combobox sale copy", is_for_sale); + childSetEnabled("Edit Cost", is_for_sale); childSetValue("CheckNextOwnerModify",LLSD(BOOL(next_owner_mask & PERM_MODIFY))); childSetValue("CheckNextOwnerCopy",LLSD(BOOL(next_owner_mask & PERM_COPY))); childSetValue("CheckNextOwnerTransfer",LLSD(BOOL(next_owner_mask & PERM_TRANSFER))); @@ -528,12 +531,12 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) radioSaleType->setSelectedIndex((S32)sale_info.getSaleType() - 1); S32 numerical_price; numerical_price = sale_info.getSalePrice(); - childSetText("EditPrice",llformat("%d",numerical_price)); + childSetText("Edit Cost",llformat("%d",numerical_price)); } else { radioSaleType->setSelectedIndex(-1); - childSetText("EditPrice",llformat("%d",0)); + childSetText("Edit Cost",llformat("%d",0)); } } @@ -790,12 +793,13 @@ void LLFloaterProperties::updateSaleInfo() sale_type = LLSaleInfo::FS_ORIGINAL; } - LLLineEditor* EditPrice = getChild<LLLineEditor>("EditPrice"); + // LLLineEditor* EditPrice = getChild<LLLineEditor>("EditPrice"); + LLSpinCtrl *EditPrice = getChild<LLSpinCtrl>("Edit Cost"); S32 price = -1; if(EditPrice) { - price = atoi(EditPrice->getText().c_str()); + price = EditPrice->getValue().asInteger();; } // Invalid data - turn off the sale if (price < 0) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 94d25aa0c8245bcf853ccd93f04f1359c43013a4..a50bcaa09872d1b098e302715abb0680ea52e183 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -2746,7 +2746,6 @@ BOOL LLPanelEstateCovenant::postBuild() mEstateOwnerText = getChild<LLTextBox>("estate_owner_text"); mLastModifiedText = getChild<LLTextBox>("covenant_timestamp_text"); mEditor = getChild<LLViewerTextEditor>("covenant_editor"); - if (mEditor) mEditor->setHandleEditKeysDirectly(TRUE); LLButton* reset_button = getChild<LLButton>("reset_covenant"); reset_button->setEnabled(gAgent.canManageEstate()); reset_button->setClickedCallback(LLPanelEstateCovenant::resetCovenantID, NULL); diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 00cbc2f0c8298a2bf84e72b74b4893f1d90557d1..e2176350c928766c887b3c386afacd3cf262cb44 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -48,6 +48,7 @@ #include "llversionviewer.h" #include "message.h" #include "v3math.h" +#include "lltexteditor.h" // viewer project includes #include "llagent.h" @@ -61,7 +62,6 @@ #include "llimview.h" #include "lltextbox.h" #include "lldispatcher.h" -#include "llviewertexteditor.h" #include "llviewerobject.h" #include "llviewerregion.h" #include "llcombobox.h" diff --git a/indra/newview/llfloaterscriptdebug.cpp b/indra/newview/llfloaterscriptdebug.cpp index c8690de68c14e7d7621145f9c53fe8f14fcf6dd5..328fb6450e644d7a961b562b22181d0796d83dfd 100644 --- a/indra/newview/llfloaterscriptdebug.cpp +++ b/indra/newview/llfloaterscriptdebug.cpp @@ -80,9 +80,6 @@ BOOL LLFloaterScriptDebug::postBuild() if (mTabContainer) { - // *FIX: apparantly fails for tab containers? -// mTabContainer->requires<LLFloater>("all_scripts"); -// mTabContainer->checkRequirements(); return TRUE; } diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp index 53b40f8b7a883256b5fc0872ba2777897041367a..616e9bac358a4e8a4decb72a4410dea1cb587679 100644 --- a/indra/newview/llfloatersettingsdebug.cpp +++ b/indra/newview/llfloatersettingsdebug.cpp @@ -39,6 +39,7 @@ #include "llspinctrl.h" #include "llcolorswatch.h" #include "llviewercontrol.h" +#include "lltexteditor.h" LLFloaterSettingsDebug::LLFloaterSettingsDebug(const LLSD& key) diff --git a/indra/newview/llfloatersettingsdebug.h b/indra/newview/llfloatersettingsdebug.h index e7dda3a5f425528363c882751c5450da5a5ce68a..65803fbf70fe024ba1cf534d30194faa98bfbd26 100644 --- a/indra/newview/llfloatersettingsdebug.h +++ b/indra/newview/llfloatersettingsdebug.h @@ -35,7 +35,6 @@ #include "llcontrol.h" #include "llfloater.h" -#include "lltexteditor.h" class LLFloaterSettingsDebug : public LLFloater @@ -60,7 +59,7 @@ class LLFloaterSettingsDebug virtual ~LLFloaterSettingsDebug(); protected: - LLTextEditor* mComment; + class LLTextEditor* mComment; }; #endif //LLFLOATERDEBUGSETTINGS_H diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 371dfa50cdd87a400d8b068439053645eb017155..814395395c80e71cf5699235e5e51e08984ebdf4 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -41,7 +41,6 @@ #include "llcallbacklist.h" #include "llcriticaldamp.h" #include "llui.h" -#include "llviewertexteditor.h" #include "llfocusmgr.h" #include "llbutton.h" #include "llcombobox.h" diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp index 1e84902594af6948a87980d4b520ad1ec8fd32fa..f61d5cb0778ed8cfabf920c97f66c15b02ef0acf 100644 --- a/indra/newview/llfloatertos.cpp +++ b/indra/newview/llfloatertos.cpp @@ -39,7 +39,6 @@ #include "llappviewer.h" #include "llstartup.h" #include "llviewerstats.h" -#include "llviewertexteditor.h" #include "llviewerwindow.h" // linden library includes @@ -118,12 +117,10 @@ BOOL LLFloaterTOS::postBuild() if (hasChild("tos_text")) { // this displays the critical message - LLTextEditor *editor = getChild<LLTextEditor>("tos_text"); - editor->setHandleEditKeysDirectly( TRUE ); - editor->setEnabled( FALSE ); - editor->setWordWrap(TRUE); - editor->setFocus(TRUE); - editor->setValue(LLSD(mMessage)); + LLUICtrl *tos_text = getChild<LLUICtrl>("tos_text"); + tos_text->setEnabled( FALSE ); + tos_text->setFocus(TRUE); + tos_text->setValue(LLSD(mMessage)); return TRUE; } @@ -133,7 +130,7 @@ BOOL LLFloaterTOS::postBuild() tos_agreement->setEnabled( false ); // hide the SL text widget if we're displaying TOS with using a browser widget. - LLTextEditor *editor = getChild<LLTextEditor>("tos_text"); + LLUICtrl *editor = getChild<LLUICtrl>("tos_text"); editor->setVisible( FALSE ); LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("tos_html"); diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index e5b46577421f398e335a0f0b1c561078575885c7..2eb4e7580ee40af020937d9dc9327c19d95edb55 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -747,8 +747,8 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) panel->setUseBoundingRect(TRUE); // enable the use of its outer bounding rect (normally disabled because it's O(n) on the number of sub-elements) panel->updateBoundingRect(); // update bounding rect LLRect bounding_rect = panel->getBoundingRect(); // get the bounding rect - LLRect panel_rect = panel->getRect(); // get the panel's rect - LLRect new_rect = panel_rect.unionWith(bounding_rect); // union them to make sure we get the biggest one possible + LLRect new_rect = panel->getRect(); // get the panel's rect + new_rect.unionWith(bounding_rect); // union them to make sure we get the biggest one possible (*floaterp)->reshape(new_rect.getWidth(), new_rect.getHeight() + floater_header_size); // reshape floater to match the union rect's dimensions panel->reshape(new_rect.getWidth(), new_rect.getHeight()); // reshape panel to match the union rect's dimensions as well (both are needed) (*floaterp)->addChild(panel); // add panel as child @@ -1274,7 +1274,7 @@ void LLFloaterUIPreview::highlightChangedElements() BOOL failed = FALSE; for(token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) { - element = element->getChild<LLView>(*token_iter,FALSE,FALSE); // try to find element: don't recur, and don't create if missing + element = element->findChild<LLView>(*token_iter,FALSE); // try to find element: don't recur, and don't create if missing // if we still didn't find it... if(NULL == element) diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 4a5a775a0560d010483f4147d5a6a9f50b3e8907..d1f0f94fa092c6f00c474190017bceddc734ccc7 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -176,7 +176,7 @@ LLFolderView::LLFolderView(const Params& p) mSourceID(p.task_id), mRenameItem( NULL ), mNeedsScroll( FALSE ), - mLastScrollItem( NULL ), + mPinningSelectedItem(FALSE), mNeedsAutoSelect( FALSE ), mAutoSelectOverride(FALSE), mNeedsAutoRename(FALSE), @@ -191,7 +191,6 @@ LLFolderView::LLFolderView(const Params& p) mDragAndDropThisFrame(FALSE), mCallbackRegistrar(NULL), mParentPanel(p.parent_panel) - { LLRect rect = p.rect; LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom); @@ -290,11 +289,13 @@ void LLFolderView::checkTreeResortForModelChanged() } } +static LLFastTimer::DeclareTimer FTM_SORT("Sort Inventory"); + void LLFolderView::setSortOrder(U32 order) { if (order != mSortOrder) { - LLFastTimer t(LLFastTimer::FTM_SORT); + LLFastTimer t(FTM_SORT); mSortOrder = order; for (folders_t::iterator iter = mFolders.begin(); @@ -359,10 +360,12 @@ void LLFolderView::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse mIsOpen = TRUE; } +static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange"); + // This view grows and shinks to enclose all of its children items and folders. S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_generation ) { - LLFastTimer t2(LLFastTimer::FTM_ARRANGE); + LLFastTimer t2(FTM_ARRANGE); filter_generation = mFilter->getMinRequiredGeneration(); mMinWidth = 0; @@ -431,17 +434,13 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen } } - S32 dummy_s32; - BOOL dummy_bool; - S32 min_width; - mScrollContainer->calcVisibleSize( &min_width, &dummy_s32, &dummy_bool, &dummy_bool); - reshape( llmax(min_width, total_width), running_height ); + LLRect scroll_rect = mScrollContainer->getContentWindowRect(); + reshape( llmax(scroll_rect.getWidth(), total_width), running_height ); - S32 new_min_width; - mScrollContainer->calcVisibleSize( &new_min_width, &dummy_s32, &dummy_bool, &dummy_bool); - if (new_min_width != min_width) + LLRect new_scroll_rect = mScrollContainer->getContentWindowRect(); + if (new_scroll_rect.getWidth() != scroll_rect.getWidth()) { - reshape( llmax(min_width, total_width), running_height ); + reshape( llmax(scroll_rect.getWidth(), total_width), running_height ); } // move item renamer text field to item's new position @@ -456,9 +455,11 @@ const std::string LLFolderView::getFilterSubString(BOOL trim) return mFilter->getFilterSubString(trim); } +static LLFastTimer::DeclareTimer FTM_FILTER("Filter Inventory"); + void LLFolderView::filter( LLInventoryFilter& filter ) { - LLFastTimer t2(LLFastTimer::FTM_FILTER); + LLFastTimer t2(FTM_FILTER); filter.setFilterCount(llclamp(gSavedSettings.getS32("FilterItemsPerFrame"), 1, 5000)); if (getCompletedFilterGeneration() < filter.getCurrentGeneration()) @@ -467,18 +468,20 @@ void LLFolderView::filter( LLInventoryFilter& filter ) mMinWidth = 0; LLFolderViewFolder::filter(filter); } + else + { + mFiltered = TRUE; + } } void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent) { - S32 min_width = 0; - S32 dummy_height; - BOOL dummy_bool; + LLRect scroll_rect; if (mScrollContainer) { - mScrollContainer->calcVisibleSize( &min_width, &dummy_height, &dummy_bool, &dummy_bool); + scroll_rect = mScrollContainer->getContentWindowRect(); } - width = llmax(mMinWidth, min_width); + width = llmax(mMinWidth, scroll_rect.getWidth()); LLView::reshape(width, height, called_from_parent); mReshapeSignal(mSelectedItems, FALSE); @@ -1127,7 +1130,9 @@ void LLFolderView::autoOpenItem( LLFolderViewFolder* item ) mAutoOpenItems.push(item); item->setOpen(TRUE); - scrollToShowItem(item); + LLRect content_rect = mScrollContainer->getContentWindowRect(); + LLRect constraint_rect(0,content_rect.getHeight(), content_rect.getWidth(), 0); + scrollToShowItem(item, constraint_rect); } void LLFolderView::closeAutoOpenedFolders() @@ -1791,49 +1796,41 @@ void LLFolderView::scrollToShowSelection() // If the parent is scroll containter, scroll it to make the selection // is maximally visible. -void LLFolderView::scrollToShowItem(LLFolderViewItem* item) +void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect) { + if (!mScrollContainer) return; + // don't scroll to items when mouse is being used to scroll/drag and drop if (gFocusMgr.childHasMouseCapture(mScrollContainer)) { mNeedsScroll = FALSE; return; } - if(item && mScrollContainer) + + // if item exists and is in visible portion of parent folder... + if(item) { - LLRect local_rect = item->getRect(); + LLRect local_rect = item->getLocalRect(); LLRect item_scrolled_rect; // item position relative to display area of scroller + LLRect visible_doc_rect = mScrollContainer->getVisibleContentRect(); S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight(); S32 label_height = llround(sFont->getLineHeight()); // when navigating with keyboard, only move top of folders on screen, otherwise show whole folder - S32 max_height_to_show = gFocusMgr.childHasKeyboardFocus(this) ? (llmax( icon_height, label_height ) + ICON_PAD) : local_rect.getHeight(); - item->localPointToOtherView(item->getIndentation(), llmax(0, local_rect.getHeight() - max_height_to_show), &item_scrolled_rect.mLeft, &item_scrolled_rect.mBottom, mScrollContainer); - item->localPointToOtherView(local_rect.getWidth(), local_rect.getHeight(), &item_scrolled_rect.mRight, &item_scrolled_rect.mTop, mScrollContainer); - - item_scrolled_rect.mRight = llmin(item_scrolled_rect.mLeft + MIN_ITEM_WIDTH_VISIBLE, item_scrolled_rect.mRight); - LLCoordGL scroll_offset(-mScrollContainer->getBorderWidth() - item_scrolled_rect.mLeft, - mScrollContainer->getRect().getHeight() - item_scrolled_rect.mTop - 1); - - S32 max_scroll_offset = getVisibleRect().getHeight() - item_scrolled_rect.getHeight(); - if (item != mLastScrollItem || // if we're scrolling to focus on a new item - // or the item has just appeared on screen and it wasn't onscreen before - (scroll_offset.mY > 0 && scroll_offset.mY < max_scroll_offset && - (mLastScrollOffset.mY < 0 || mLastScrollOffset.mY > max_scroll_offset))) - { - // we now have a position on screen that we want to keep stable - // offset of selection relative to top of visible area - mLastScrollOffset = scroll_offset; - mLastScrollItem = item; - } + S32 max_height_to_show = mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + ICON_PAD) : local_rect.getHeight(); + + // get portion of item that we want to see... + LLRect item_local_rect = LLRect(item->getIndentation(), + local_rect.getHeight(), + llmin(MIN_ITEM_WIDTH_VISIBLE, local_rect.getWidth()), + llmax(0, local_rect.getHeight() - max_height_to_show)); + + LLRect item_doc_rect; + + item->localRectToOtherView(item_local_rect, &item_doc_rect, this); - mScrollContainer->scrollToShowRect( item_scrolled_rect, mLastScrollOffset ); + mScrollContainer->scrollToShowRect( item_doc_rect, constraint_rect ); - // after scrolling, store new offset - // in case we don't have room to maintain the original position - LLCoordGL new_item_left_top; - item->localPointToOtherView(item->getIndentation(), item->getRect().getHeight(), &new_item_left_top.mX, &new_item_left_top.mY, mScrollContainer); - mLastScrollOffset.set(-mScrollContainer->getBorderWidth() - new_item_left_top.mX, mScrollContainer->getRect().getHeight() - new_item_left_top.mY - 1); } } @@ -1973,10 +1970,13 @@ bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata) return true; } +static LLFastTimer::DeclareTimer FTM_AUTO_SELECT("Open and Select"); +static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory"); + // Main idle routine void LLFolderView::doIdle() { - LLFastTimer t2(LLFastTimer::FTM_INVENTORY); + LLFastTimer t2(FTM_INVENTORY); BOOL debug_filters = gSavedSettings.getBOOL("DebugInventoryFilters"); if (debug_filters != getDebugFilters()) @@ -1990,7 +1990,7 @@ void LLFolderView::doIdle() mFilter->isNotDefault(); mNeedsAutoSelect = filter_modified_and_active && !(gFocusMgr.childHasKeyboardFocus(this) || gFocusMgr.getMouseCapture()); - + // filter to determine visiblity before arranging filterFromRoot(); @@ -2001,7 +2001,7 @@ void LLFolderView::doIdle() // potentially changed if (mNeedsAutoSelect) { - LLFastTimer t3(LLFastTimer::FTM_AUTO_SELECT); + LLFastTimer t3(FTM_AUTO_SELECT); // select new item only if a filtered item not currently selected LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back(); if ((!selected_itemp || !selected_itemp->getFiltered()) && !mAutoSelectOverride) @@ -2013,6 +2013,59 @@ void LLFolderView::doIdle() scrollToShowSelection(); } + // during filtering process, try to pin selected item's location on screen + // this will happen when searching your inventory and when new items arrive + if (filter_modified_and_active) + { + // calculate rectangle to pin item to at start of animated rearrange + if (!mPinningSelectedItem && !mSelectedItems.empty()) + { + // lets pin it! + mPinningSelectedItem = TRUE; + + LLRect visible_content_rect = mScrollContainer->getVisibleContentRect(); + LLFolderViewItem* selected_item = mSelectedItems.back(); + + LLRect item_rect; + selected_item->localRectToOtherView(selected_item->getLocalRect(), &item_rect, this); + // if item is visible in scrolled region + if (visible_content_rect.overlaps(item_rect)) + { + // then attempt to keep it in same place on screen + mScrollConstraintRect = item_rect; + mScrollConstraintRect.translate(-visible_content_rect.mLeft, -visible_content_rect.mBottom); + } + else + { + // otherwise we just want it onscreen somewhere + LLRect content_rect = mScrollContainer->getContentWindowRect(); + mScrollConstraintRect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight()); + } + } + } + else + { + // stop pinning selected item after folders stop rearranging + if (!needsArrange()) + { + mPinningSelectedItem = FALSE; + } + } + + LLRect constraint_rect; + if (mPinningSelectedItem) + { + // use last known constraint rect for pinned item + constraint_rect = mScrollConstraintRect; + } + else + { + // during normal use (page up/page down, etc), just try to fit item on screen + LLRect content_rect = mScrollContainer->getContentWindowRect(); + constraint_rect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight()); + } + + BOOL is_visible = isInVisibleChain(); if ( is_visible ) @@ -2026,10 +2079,10 @@ void LLFolderView::doIdle() if (mSelectedItems.size() && mNeedsScroll) { - scrollToShowItem(mSelectedItems.back()); + scrollToShowItem(mSelectedItems.back(), constraint_rect); // continue scrolling until animated layout change is done - if (getCompletedFilterGeneration() >= mFilter->getMinRequiredGeneration() && - (!needsArrange() || !is_visible)) + if (!filter_modified_and_active + && (!needsArrange() || !is_visible)) { mNeedsScroll = FALSE; } @@ -2077,15 +2130,13 @@ void LLFolderView::updateRenamerPosition() screenPointToLocal( x, y, &x, &y ); mRenamer->setOrigin( x, y ); - S32 scroller_height = 0; - S32 scroller_width = gViewerWindow->getWindowWidth(); - BOOL dummy_bool; + LLRect scroller_rect(0, 0, gViewerWindow->getWindowWidth(), 0); if (mScrollContainer) { - mScrollContainer->calcVisibleSize( &scroller_width, &scroller_height, &dummy_bool, &dummy_bool); + scroller_rect = mScrollContainer->getContentWindowRect(); } - S32 width = llmax(llmin(mRenameItem->getRect().getWidth() - x, scroller_width - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH); + S32 width = llmax(llmin(mRenameItem->getRect().getWidth() - x, scroller_rect.getWidth() - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH); S32 height = llfloor(sFont->getLineHeight() + RENAME_HEIGHT_PAD); mRenamer->reshape( width, height, TRUE ); } diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 8d9d52cd172bbcb2c58485c4c38fe532fb301bd1..a05dec3193e52839884f9902da2efb89825be1f9 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -240,7 +240,7 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler virtual void deleteAllChildren(); void scrollToShowSelection(); - void scrollToShowItem(LLFolderViewItem* item); + void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect); void setScrollContainer( LLScrollContainer* parent ) { mScrollContainer = parent; } LLRect getVisibleRect(); @@ -299,8 +299,8 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler LLLineEditor* mRenamer; BOOL mNeedsScroll; - LLFolderViewItem* mLastScrollItem; - LLCoordGL mLastScrollOffset; + BOOL mPinningSelectedItem; + LLRect mScrollConstraintRect; BOOL mNeedsAutoSelect; BOOL mAutoSelectOverride; BOOL mNeedsAutoRename; diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index de6a1a097d81da0b6f0c9b66f7a3e997764212a8..8961508bccd960c00bd424a6c462b21398f78780 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -233,7 +233,7 @@ void LLFolderViewItem::refreshFromListener() // temporary attempt to display the inventory folder in the user locale. if (LLAssetType::lookupIsProtectedCategoryType(preferred_type)) { - mLabel = LLTrans::getString("InvFolder " + mLabel); + LLTrans::findString(mLabel, "InvFolder " + mLabel); }; setIcon(mListener->getIcon()); diff --git a/indra/newview/llhudmanager.cpp b/indra/newview/llhudmanager.cpp index 8588de0fa0746536838de85e836bb83cae11573b..bdb8dadfb475404ffccebf1db438f07f0723f493 100644 --- a/indra/newview/llhudmanager.cpp +++ b/indra/newview/llhudmanager.cpp @@ -62,10 +62,11 @@ LLHUDManager::~LLHUDManager() { } +static LLFastTimer::DeclareTimer FTM_HUD_EFFECTS("Hud Effects"); void LLHUDManager::updateEffects() { - LLFastTimer ftm(LLFastTimer::FTM_HUD_EFFECTS); + LLFastTimer ftm(FTM_HUD_EFFECTS); S32 i; for (i = 0; i < mHUDEffects.count(); i++) { diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp index bdff49294838ad6aa29042788d7e3a71d7b7af8b..dc55aba0dbf6db94b34dd3a39bdb47c4d89ea794 100644 --- a/indra/newview/llhudobject.cpp +++ b/indra/newview/llhudobject.cpp @@ -254,10 +254,12 @@ LLHUDEffect *LLHUDObject::addHUDEffect(const U8 type) return hud_objectp; } +static LLFastTimer::DeclareTimer FTM_HUD_UPDATE("Update Hud"); + // static void LLHUDObject::updateAll() { - LLFastTimer ftm(LLFastTimer::FTM_HUD_UPDATE); + LLFastTimer ftm(FTM_HUD_UPDATE); LLHUDText::updateAll(); LLHUDIcon::updateAll(); sortObjects(); diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index c71262c311fc86d89ccdc85282d5205467b4b67f..8086400493c1b8eef40632857947d6d628cb018b 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -957,7 +957,7 @@ void LLHUDText::updateAll() { continue; } - if (src_textp->mSoftScreenRect.rectInRect(&dst_textp->mSoftScreenRect)) + if (src_textp->mSoftScreenRect.overlaps(dst_textp->mSoftScreenRect)) { LLRectf intersect_rect = src_textp->mSoftScreenRect; intersect_rect.intersectWith(dst_textp->mSoftScreenRect); diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 0b4e0f9317cc2243cf92dd4a8197de454726b1db..72e2bb02d5c458a1dc06515db87d0d2e6975e9bd 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -1097,66 +1097,58 @@ BOOL LLFloaterIMPanel::postBuild() mVisibleSignal.connect(boost::bind(&LLFloaterIMPanel::onVisibilityChange, this, _2)); - requires<LLLineEditor>("chat_editor"); - requires<LLTextEditor>("im_history"); - - if (checkRequirements()) - { - mInputEditor = getChild<LLLineEditor>("chat_editor"); - mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this ); - mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this ); - mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this ); - mInputEditor->setCommitCallback( onCommitChat, this ); - mInputEditor->setCommitOnFocusLost( FALSE ); - mInputEditor->setRevertOnEsc( FALSE ); - mInputEditor->setReplaceNewlinesWithSpaces( FALSE ); - - childSetAction("profile_callee_btn", onClickProfile, this); - childSetAction("group_info_btn", onClickGroupInfo, this); + mInputEditor = getChild<LLLineEditor>("chat_editor"); + mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this ); + mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this ); + mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this ); + mInputEditor->setCommitCallback( onCommitChat, this ); + mInputEditor->setCommitOnFocusLost( FALSE ); + mInputEditor->setRevertOnEsc( FALSE ); + mInputEditor->setReplaceNewlinesWithSpaces( FALSE ); - childSetAction("start_call_btn", onClickStartCall, this); - childSetAction("end_call_btn", onClickEndCall, this); - childSetAction("send_btn", onClickSend, this); - childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this); + childSetAction("profile_callee_btn", onClickProfile, this); + childSetAction("group_info_btn", onClickGroupInfo, this); - childSetAction("moderator_kick_speaker", onKickSpeaker, this); - //LLButton* close_btn = getChild<LLButton>("close_btn"); - //close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this); + childSetAction("start_call_btn", onClickStartCall, this); + childSetAction("end_call_btn", onClickEndCall, this); + childSetAction("send_btn", onClickSend, this); + childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this); - mHistoryEditor = getChild<LLViewerTextEditor>("im_history"); - mHistoryEditor->setParseHTML(TRUE); - mHistoryEditor->setParseHighlights(TRUE); + childSetAction("moderator_kick_speaker", onKickSpeaker, this); + //LLButton* close_btn = getChild<LLButton>("close_btn"); + //close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this); - if ( IM_SESSION_GROUP_START == mDialog ) - { - childSetEnabled("profile_btn", FALSE); - } - - if(!mProfileButtonEnabled) - { - childSetEnabled("profile_callee_btn", FALSE); - } + mHistoryEditor = getChild<LLViewerTextEditor>("im_history"); + mHistoryEditor->setParseHTML(TRUE); + mHistoryEditor->setParseHighlights(TRUE); - sTitleString = getString("title_string"); - sTypingStartString = getString("typing_start_string"); - sSessionStartString = getString("session_start_string"); + if ( IM_SESSION_GROUP_START == mDialog ) + { + childSetEnabled("profile_btn", FALSE); + } + + if(!mProfileButtonEnabled) + { + childSetEnabled("profile_callee_btn", FALSE); + } - if (mSpeakerPanel) - { - mSpeakerPanel->refreshSpeakers(); - } + sTitleString = getString("title_string"); + sTypingStartString = getString("typing_start_string"); + sSessionStartString = getString("session_start_string"); - if (mDialog == IM_NOTHING_SPECIAL) - { - childSetAction("mute_btn", onClickMuteVoice, this); - childSetCommitCallback("speaker_volume", onVolumeChange, this); - } + if (mSpeakerPanel) + { + mSpeakerPanel->refreshSpeakers(); + } - setDefaultBtn("send_btn"); - return TRUE; + if (mDialog == IM_NOTHING_SPECIAL) + { + childSetAction("mute_btn", onClickMuteVoice, this); + childSetCommitCallback("speaker_volume", onVolumeChange, this); } - return FALSE; + setDefaultBtn("send_btn"); + return TRUE; } void* LLFloaterIMPanel::createSpeakersPanel(void* data) @@ -1385,8 +1377,7 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 else { // Convert the name to a hotlink and add to message. - const LLStyleSP &source_style = LLStyleMap::instance().lookupAgent(source); - mHistoryEditor->appendStyledText(name + separator_string, false, prepend_newline, source_style); + mHistoryEditor->appendStyledText(name + separator_string, false, prepend_newline, LLStyleMap::instance().lookupAgent(source)); } prepend_newline = false; } diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 6ad483a2f19dcd7fc5ba8d6ed3ed135fdff10703..e3902bffa0775eaac58133cad9ecdeb1b1e72e59 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -69,7 +69,6 @@ #include "llviewerwindow.h" #include "llnotify.h" #include "llviewerregion.h" -#include "llviewertexteditor.h" #include "lltrans.h" #include "llfirstuse.h" @@ -847,8 +846,13 @@ BOOL LLIncomingCallDialog::postBuild() EInstantMessage type = (EInstantMessage)mPayload["type"].asInteger(); std::string call_type = getString("VoiceInviteP2P"); - std::string caller_name = mPayload["caller_name"].asString() + " "; - setTitle(caller_name + call_type); + std::string caller_name = mPayload["caller_name"].asString(); + if (caller_name == "anonymous") + { + caller_name = getString("anonymous"); + } + + setTitle(caller_name + " " + call_type); // If it is not a P2P invite, then it's an AdHoc invite if ( type != IM_SESSION_P2P_INVITE ) @@ -856,8 +860,8 @@ BOOL LLIncomingCallDialog::postBuild() call_type = getString("VoiceInviteAdHoc"); } - LLViewerTextEditor* text = getChild<LLViewerTextEditor>("caller name"); - text->setEmbeddedText(caller_name + call_type); + LLUICtrl* caller_name_widget = getChild<LLUICtrl>("caller name"); + caller_name_widget->setValue(caller_name + " " + call_type); LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon"); icon->setValue(caller_id); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 54802ee7620c8975e29b7bc8667626cc7c8e3d57..efa97de69270fd547732eaeed91ab11e43859c31 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3684,8 +3684,8 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) // commented out for DEV-32347 //items.push_back(std::string("Restore to Last Position")); - LLMenuGL* attach_menu = menu.getChildMenuByName("Attach To", TRUE); - LLMenuGL* attach_hud_menu = menu.getChildMenuByName("Attach To HUD", TRUE); + LLMenuGL* attach_menu = menu.findChildMenuByName("Attach To", TRUE); + LLMenuGL* attach_hud_menu = menu.findChildMenuByName("Attach To HUD", TRUE); LLVOAvatar *avatarp = gAgent.getAvatarObject(); if (attach_menu && (attach_menu->getChildCount() == 0) diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index cdfb15fd71c610b7da9b45bf3fa552173c98a01b..63a40e40a03ff17f3b4beef695246e5e8999dcf1 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -227,7 +227,7 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) llwarns << "Error loading navigation bar context menu" << llendl; } - getTextEntry()->setRightClickedCallback(boost::bind(&LLLocationInputCtrl::onTextEditorRightClicked,this,_2,_3,_4)); + getTextEntry()->setRightMouseUpCallback(boost::bind(&LLLocationInputCtrl::onTextEditorRightClicked,this,_2,_3,_4)); updateWidgetlayout(); // - Make the "Add landmark" button updated when either current parcel gets changed diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 9a66507eae3f0838855528bef7c18f8ff78a8517..713c44d366656414dcad7b1a979d601edab8b41a 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -103,7 +103,7 @@ const std::string LLTeleportHistoryMenuItem::ICON_IMG_FORWARD("teleport_history_ LLTeleportHistoryMenuItem::Params::Params(EType type, std::string title) { item_type(type); - font.name("SansSerif"); + font.name("SANSSERIF"); if (type == TYPE_CURRENT) font.style("BOLD"); @@ -123,7 +123,6 @@ LLTeleportHistoryMenuItem::LLTeleportHistoryMenuItem(const Params& p) icon_params.rect(LLRect(0, ICON_HEIGHT, ICON_WIDTH, 0)); icon_params.mouse_opaque(false); icon_params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP); - icon_params.tab_stop(false); icon_params.visible(false); mArrowIcon = LLUICtrlFactory::create<LLIconCtrl> (icon_params); diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 32d7bc94ff64ec0f8434ab8131dfbec322918136..da9f50a2bc9e70b5f91d5dd674542bd22b82968d 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -208,8 +208,7 @@ void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, cons { std::string start_line = line.substr(0, chat.mFromName.length() + 1); line = line.substr(chat.mFromName.length() + 1); - const LLStyleSP &sourceStyle = LLStyleMap::instance().lookup(chat.mFromID,chat.mURL); - edit->appendStyledText(start_line, false, prepend_newline, sourceStyle); + edit->appendStyledText(start_line, false, prepend_newline, LLStyleMap::instance().lookup(chat.mFromID,chat.mURL)); prepend_newline = false; } edit->appendColoredText(line, false, prepend_newline, color); @@ -343,6 +342,7 @@ BOOL LLNearbyChat::handleMouseDown (S32 x, S32 y, MASK mask) S32 local_y = caption_local_y - nearby_speakers_btn->getRect().mBottom; if(nearby_speakers_btn->pointInView(local_x, local_y)) { + onNearbySpeakers(); bringToFront( x, y ); return true; diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 50e31e85e48184ba556b50897adc543b849bca6e..0696d41732763016f6f184f9419b8013517d5ae8 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -65,7 +65,7 @@ LLGestureComboBox::LLGestureComboBox(const LLGestureComboBox::Params& p) , mGestureLabelTimer() , mLabel(p.label) { - setCommitCallback(boost::bind(&LLGestureComboBox::onCommitGesture, this, _1)); + setCommitCallback(boost::bind(&LLGestureComboBox::onCommitGesture, this)); // now register us as observer since we have a place to put the results LLGestureManager::instance().addObserver(this); @@ -82,41 +82,33 @@ LLGestureComboBox::~LLGestureComboBox() void LLGestureComboBox::refreshGestures() { //store current selection so we can maintain it - std::string cur_gesture = getValue().asString(); + LLSD cur_gesture = getValue(); selectFirstItem(); // clear clearRows(); + mGestures.clear(); - // collect list of unique gestures - std::map <std::string, BOOL> unique; LLGestureManager::item_map_t::iterator it; + LLSD::Integer idx(0); for (it = LLGestureManager::instance().mActive.begin(); it != LLGestureManager::instance().mActive.end(); ++it) { LLMultiGesture* gesture = (*it).second; if (gesture) { - if (!gesture->mTrigger.empty()) - { - unique[gesture->mTrigger] = TRUE; - } + addSimpleElement(gesture->mName, ADD_BOTTOM, LLSD(idx)); + mGestures.push_back(gesture); + idx++; } } - // add unique gestures - std::map <std::string, BOOL>::iterator it2; - for (it2 = unique.begin(); it2 != unique.end(); ++it2) - { - addSimpleElement((*it2).first); - } - sortByName(); // Insert label after sorting, at top, with separator below it addSeparator(ADD_TOP); addSimpleElement(mLabel, ADD_TOP); - if (!cur_gesture.empty()) + if (cur_gesture.isDefined()) { - selectByValue(LLSD(cur_gesture)); + selectByValue(cur_gesture); } else { @@ -124,7 +116,7 @@ void LLGestureComboBox::refreshGestures() } } -void LLGestureComboBox::onCommitGesture(LLUICtrl* ctrl) +void LLGestureComboBox::onCommitGesture() { LLCtrlListInterface* gestures = getListInterface(); if (gestures) @@ -134,19 +126,16 @@ void LLGestureComboBox::onCommitGesture(LLUICtrl* ctrl) { return; } - const std::string& trigger = gestures->getSelectedValue().asString(); - // pretend the user chatted the trigger string, to invoke - // substitution and logging. - std::string text(trigger); - std::string revised_text; - LLGestureManager::instance().triggerAndReviseString(text, &revised_text); - - revised_text = utf8str_trim(revised_text); - if (!revised_text.empty()) + index = gestures->getSelectedValue().asInteger(); + LLMultiGesture* gesture = mGestures.at(index); + if(gesture) { - // Don't play nodding animation - LLNearbyChatBar::sendChatFromViewer(revised_text, CHAT_TYPE_NORMAL, FALSE); + LLGestureManager::instance().playGesture(gesture); + if(!gesture->mReplaceText.empty()) + { + LLNearbyChatBar::sendChatFromViewer(gesture->mReplaceText, CHAT_TYPE_NORMAL, FALSE); + } } } @@ -267,9 +256,6 @@ void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata) LLNearbyChatBar* self = (LLNearbyChatBar *)userdata; - if (!self->mChatBox) - return; - LLWString raw_text = self->mChatBox->getWText(); // Can't trim the end, because that will cause autocompletion @@ -429,7 +415,7 @@ void LLNearbyChatBar::sendChat( EChatType type ) void LLNearbyChatBar::onChatBoxCommit() { - if (mChatBox && mChatBox->getText().length() > 0) + if (mChatBox->getText().length() > 0) { sendChat(CHAT_TYPE_NORMAL); } @@ -501,7 +487,7 @@ void LLNearbyChatBar::startChat(const char* line) LLNearbyChatBar* cb = bt->getNearbyChatBar(); - if (!cb || !cb->mChatBox) + if (!cb ) return; bt->setVisible(TRUE); @@ -527,7 +513,7 @@ void LLNearbyChatBar::stopChat() LLNearbyChatBar* cb = bt->getNearbyChatBar(); - if (!cb || !cb->mChatBox) + if (!cb) return; cb->mChatBox->setFocus(FALSE); diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index 4b0c42c3c09364b1015796a8883e3017ccbf6a4a..19177e37b3d9d0c1033260a63d5140b7e6c1f74a 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -53,7 +53,7 @@ class LLGestureComboBox ~LLGestureComboBox(); void refreshGestures(); - void onCommitGesture(LLUICtrl* ctrl); + void onCommitGesture(); virtual void draw(); // LLGestureManagerObserver trigger @@ -61,6 +61,7 @@ class LLGestureComboBox protected: LLFrameTimer mGestureLabelTimer; + std::vector<LLMultiGesture*> mGestures; std::string mLabel; }; diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index a56688d8621df25de601a38c103ead59d429ba75..8124d4b36a454a0c63ffa33bc3201af359c0b661 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -68,6 +68,8 @@ LLNearbyChatHandler::~LLNearbyChatHandler() } void LLNearbyChatHandler::processChat(const LLChat& chat_msg) { + if(chat_msg.mMuted == TRUE) + return; if(chat_msg.mSourceType == CHAT_SOURCE_AGENT && chat_msg.mFromID.notNull()) LLRecentPeople::instance().add(chat_msg.mFromID); diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 42522942f339ee30312860c03490d6d3b35e8809..f58f993a2e7e8c2b08d117e97a8f546b2670763f 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -57,8 +57,8 @@ #include "lllineeditor.h" #include "lltextbox.h" #include "llcombobox.h" -#include "llviewertexteditor.h" #include "lltexturectrl.h" +#include "lltexteditor.h" #include "lluiconstants.h" #include "llurldispatcher.h" // for classified HTML detail click teleports #include "lluictrlfactory.h" @@ -246,8 +246,7 @@ BOOL LLPanelClassified::postBuild() mDescEditor->setCommitOnFocusLost(TRUE); mDescEditor->setFocusReceivedCallback(focusReceived, this); mDescEditor->setCommitCallback(onCommitAny, this); - mDescEditor->setTabsToNextField(TRUE); - + mLocationEditor = getChild<LLLineEditor>("location_editor"); mSetBtn = getChild<LLButton>( "set_location_btn"); diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index d95240e30ce8e18348e0acd782d125a8098ff4ec..8caa7d85eb3055274d3697d1690b089f37bd1e10 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -50,6 +50,7 @@ #include "llscrolllistcell.h" #include "lltextbox.h" #include "lltabcontainer.h" +#include "lltexteditor.h" #include "lltrans.h" #include "lltransactiontypes.h" #include "lltrans.h" diff --git a/indra/newview/llpanelgrouplandmoney.h b/indra/newview/llpanelgrouplandmoney.h index 73c52cdf2e9303d8f10972c92a8f6e8c976f4713..0f275ea9a8770d356878bc88ac62a2fc55de899d 100644 --- a/indra/newview/llpanelgrouplandmoney.h +++ b/indra/newview/llpanelgrouplandmoney.h @@ -37,10 +37,6 @@ #include "llmap.h" #include "lluuid.h" -#include "llbutton.h" -#include "lltexteditor.h" -#include "llpanel.h" - class LLPanelGroupLandMoney : public LLPanelGroupTab { public: diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index f06342ebfc75d333ae0f7381a41afb1948e7f6b7..56042f6bff0316b5e40654fbae4d84332a272858 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -508,7 +508,7 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg) mNoticesList->addElement(row, ADD_BOTTOM); } - mNoticesList->sortItems(); + mNoticesList->updateSort(); } void LLPanelGroupNotices::onSelectNotice(LLUICtrl* ctrl, void* data) diff --git a/indra/newview/llpanelplace.cpp b/indra/newview/llpanelplace.cpp index 2cb7fd8c14e6d020769872376cd214087641fd95..c6840721a31ba65d3748009196f798e8c70ce783 100644 --- a/indra/newview/llpanelplace.cpp +++ b/indra/newview/llpanelplace.cpp @@ -48,7 +48,7 @@ #include "lllineeditor.h" #include "lluiconstants.h" #include "lltextbox.h" -#include "llviewertexteditor.h" +#include "lltexteditor.h" #include "lltexturectrl.h" #include "lltrans.h" #include "llworldmap.h" diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 39f7d41a8d2b26158e67647c003e90839dd98eec..cf91972e8b60a03b8e04d98ce14c271d25083f15 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -149,14 +149,12 @@ BOOL LLPanelPlaces::postBuild() } mPlaceInfo = getChild<LLPanelPlaceInfo>("panel_place_info"); - if (!mPlaceInfo) - return FALSE; LLButton* back_btn = mPlaceInfo->getChild<LLButton>("back_btn"); - if (back_btn) - { - back_btn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); - } + back_btn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); + + // *TODO: Assign the action to an appropriate event. + mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::toggleMediaPanel, this)); return TRUE; } diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index ce9fcd9da250da87b6f6f41fa60e3aab312c7426..cadab71ba840c4d034b5331a1867c75a275e8baf 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -101,14 +101,6 @@ BOOL LLPreviewNotecard::postBuild() childSetText("desc", item->getDescription()); childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe); - LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor"); - - if (editor) - { - editor->setWordWrap(TRUE); - editor->setHandleEditKeysDirectly(TRUE); - } - return LLPreview::postBuild(); } diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index ad978cc5b3a74e9a7deeaf2bea91e176bd33eda7..49b9bbadfb5e005390ddaabefd55eeda5762e86a 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -340,10 +340,6 @@ BOOL LLScriptEdCore::postBuild() childSetCommitCallback("Insert...", &LLScriptEdCore::onBtnInsertFunction, this); mEditor = getChild<LLViewerTextEditor>("Script Editor"); - mEditor->setFollowsAll(); - mEditor->setHandleEditKeysDirectly(TRUE); - mEditor->setEnabled(TRUE); - mEditor->setWordWrap(TRUE); childSetCommitCallback("lsl errors", &LLScriptEdCore::onErrorList, this); childSetAction("Save_btn", boost::bind(&LLScriptEdCore::doSave,this,FALSE)); @@ -459,12 +455,12 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate) return; } - const LLTextSegment* segment = NULL; - std::vector<const LLTextSegment*> selected_segments; + LLTextSegmentPtr segment = NULL; + std::vector<LLTextSegmentPtr> selected_segments; mEditor->getSelectedSegments(selected_segments); // try segments in selection range first - std::vector<const LLTextSegment*>::iterator segment_iter; + std::vector<LLTextSegmentPtr>::iterator segment_iter; for (segment_iter = selected_segments.begin(); segment_iter != selected_segments.end(); ++segment_iter) { if((*segment_iter)->getToken() && (*segment_iter)->getToken()->getType() == LLKeywordToken::WORD) @@ -477,7 +473,7 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate) // then try previous segment in case we just typed it if (!segment) { - const LLTextSegment* test_segment = mEditor->getPreviousSegment(); + const LLTextSegmentPtr test_segment = mEditor->getPreviousSegment(); if(test_segment->getToken() && test_segment->getToken()->getType() == LLKeywordToken::WORD) { segment = test_segment; diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 9990c22dac216b8e6dd0c7aded337dcb0c4f1ec0..2e005834b53e2a95ed97759f4424144295394449 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -158,7 +158,7 @@ void LLSideTrayTab::arrange(S32 width, S32 height ) S32 offset = 0; - LLView* title_panel = getChildView(TAB_PANEL_CAPTION_NAME, true, false); + LLView* title_panel = findChildView(TAB_PANEL_CAPTION_NAME, true); if(title_panel) { @@ -181,7 +181,7 @@ void LLSideTrayTab::reshape (S32 width, S32 height, BOOL called_from_parent ) return; S32 offset = 0; - LLView* title_panel = getChildView(TAB_PANEL_CAPTION_NAME, true, false); + LLView* title_panel = findChildView(TAB_PANEL_CAPTION_NAME, true); if(title_panel) { @@ -612,7 +612,7 @@ LLPanel* LLSideTray::showPanel (const std::string& panel_name, const LLSD& para child_vector_const_iter_t child_it; for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it) { - LLView* view = (*child_it)->getChildView(panel_name,true,false); + LLView* view = (*child_it)->findChildView(panel_name,true); if(view) { onTabButtonClick((*child_it)->getName()); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index c4364ed6cab0d79883d6bc62942a1433b0ccd9bd..c2fce08ae452f432c2a170ae611f8054b8f8ea82 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -49,6 +49,9 @@ #include "lloctree.h" #include "llvoavatar.h" +static LLFastTimer::DeclareTimer FTM_FRUSTUM_CULL("Frustum Culling"); +static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound"); + const F32 SG_OCCLUSION_FUDGE = 0.25f; #define SG_DISCARD_TOLERANCE 0.01f @@ -570,6 +573,8 @@ void LLSpatialGroup::rebuildMesh() } } +static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt"); + void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) { if (!gPipeline.hasRenderType(mDrawableType)) @@ -588,7 +593,7 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) return; } - LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO); + LLFastTimer ftm(FTM_REBUILD_VBO); group->clearDrawMap(); @@ -1256,6 +1261,7 @@ BOOL LLSpatialGroup::rebound() return TRUE; } +static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion"); void LLSpatialGroup::checkOcclusion() { if (LLPipeline::sUseOcclusion > 1) @@ -1267,7 +1273,7 @@ void LLSpatialGroup::checkOcclusion() } else if (isState(QUERY_PENDING)) { //otherwise, if a query is pending, read it back - LLFastTimer t(LLFastTimer::FTM_OCCLUSION_READBACK); + LLFastTimer t(FTM_OCCLUSION_READBACK); GLuint res = 1; if (!isState(DISCARD_QUERY) && mOcclusionQuery) { @@ -1312,7 +1318,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) else { { - LLFastTimer t(LLFastTimer::FTM_RENDER_OCCLUSION); + LLFastTimer t(FTM_RENDER_OCCLUSION); if (!mOcclusionQuery) { @@ -1873,7 +1879,7 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result { BOOL temp = sFreezeState; sFreezeState = FALSE; - LLFastTimer ftm(LLFastTimer::FTM_CULL_REBOUND); + LLFastTimer ftm(FTM_CULL_REBOUND); LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); group->rebound(); sFreezeState = temp; @@ -1891,19 +1897,19 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result } else if (LLPipeline::sShadowRender) { - LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL); + LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCullShadow culler(&camera); culler.traverse(mOctree); } else if (mInfiniteFarClip || !LLPipeline::sUseFarClip) { - LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL); + LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCullNoFarClip culler(&camera); culler.traverse(mOctree); } else { - LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL); + LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCull culler(&camera); culler.traverse(mOctree); } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 04a3b52e98bd3ce5874d42d35e4baf8de0ae4fe3..222672deff3452e87f5ca941b93e5cc1ddd63daf 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1001,9 +1001,6 @@ bool idle_startup() } - //For HTML parsing in text boxes. - LLTextEditor::setLinkColor( LLUIColorTable::instance().getColor("HTMLLinkColor") ); - // Load URL History File LLURLHistory::loadFile("url_history.xml"); diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 569e7b33971b08090a97c19858a376b667303f56..8a5de61280d8334b5ade507ebe0968e6dbc32c0b 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -265,7 +265,7 @@ BOOL LLStatusBar::postBuild() mHideNavbarContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); gMenuHolder->addChild(mHideNavbarContextMenu); - gMenuBarView->setRightClickedCallback(boost::bind(&LLStatusBar::onMainMenuRightClicked, this, _1, _2, _3, _4)); + gMenuBarView->setRightMouseDownCallback(boost::bind(&LLStatusBar::onMainMenuRightClicked, this, _1, _2, _3, _4)); return TRUE; } diff --git a/indra/newview/llstylemap.cpp b/indra/newview/llstylemap.cpp index a422db1cc120547e832a8af16f63a3ae79ec2f76..fc125dcf9caab0abed0ed2e38ed95312ebaf9b36 100644 --- a/indra/newview/llstylemap.cpp +++ b/indra/newview/llstylemap.cpp @@ -38,83 +38,53 @@ #include "llviewercontrol.h" #include "llagent.h" -LLStyleMap::LLStyleMap() -{ -} - -LLStyleMap::~LLStyleMap() -{ -} - -LLStyleMap &LLStyleMap::instance() -{ - static LLStyleMap style_map; - return style_map; -} - -// This is similar to the [] accessor except that if the entry doesn't already exist, -// then this will create the entry. -const LLStyleSP &LLStyleMap::lookupAgent(const LLUUID &source) +const LLStyle::Params &LLStyleMap::lookupAgent(const LLUUID &source) { // Find this style in the map or add it if not. This map holds links to residents' profiles. - if (find(source) == end()) + if (mMap.find(source) == mMap.end()) { - LLStyleSP style(new LLStyle); - style->setVisible(true); - style->setFontName(LLStringUtil::null); + LLStyle::Params style_params; if (source != LLUUID::null && source != gAgent.getID() ) { - style->setColor(LLUIColorTable::instance().getColor("HTMLLinkColor")); - std::string link = llformat("secondlife:///app/agent/%s/about",source.asString().c_str()); - style->setLinkHREF(link); + style_params.color.control = "HTMLLinkColor"; + style_params.link_href = llformat("secondlife:///app/agent/%s/about",source.asString().c_str()); } else { // Make the resident's own name white and don't make the name clickable. - style->setColor(LLColor4::white); + style_params.color = LLColor4::white; } - (*this)[source] = style; + + mMap[source] = LLStyle::Params(); } - return (*this)[source]; + return mMap[source]; } // This is similar to lookupAgent for any generic URL encoded style. -const LLStyleSP &LLStyleMap::lookup(const LLUUID& id, const std::string& link) +const LLStyle::Params &LLStyleMap::lookup(const LLUUID& id, const std::string& link) { // Find this style in the map or add it if not. - iterator iter = find(id); - if (iter == end()) + style_map_t::iterator iter = mMap.find(id); + if (iter == mMap.end()) { - LLStyleSP style(new LLStyle); - style->setVisible(true); - style->setFontName(LLStringUtil::null); + LLStyle::Params style_params; + if (id != LLUUID::null && !link.empty()) { - style->setColor(LLUIColorTable::instance().getColor("HTMLLinkColor")); - style->setLinkHREF(link); + style_params.color.control = "HTMLLinkColor"; + style_params.link_href = link; } else - style->setColor(LLColor4::white); - (*this)[id] = style; + { + style_params.color = LLColor4::white; + } + mMap[id] = style_params; } else { - LLStyleSP style = (*iter).second; - if ( style->getLinkHREF() != link ) - { - style->setLinkHREF(link); - } + iter->second.link_href = link; } - return (*this)[id]; + return mMap[id]; } -void LLStyleMap::update() -{ - for (style_map_t::iterator iter = begin(); iter != end(); ++iter) - { - LLStyleSP &style = iter->second; - // Update the link color in case it has been changed. - style->setColor(LLUIColorTable::instance().getColor("HTMLLinkColor")); - } -} diff --git a/indra/newview/llstylemap.h b/indra/newview/llstylemap.h index 254509ea1d1af00a452cbf3a9581434f1ae2504b..d29ff1ae2852ca0e365de954a383e2019b07c881 100644 --- a/indra/newview/llstylemap.h +++ b/indra/newview/llstylemap.h @@ -36,24 +36,22 @@ #include "llstyle.h" #include "lluuid.h" +#include "llsingleton.h" // Lightweight class for holding and managing mappings between UUIDs and links. // Used (for example) to create clickable name links off of IM chat. -typedef std::map<LLUUID, LLStyleSP> style_map_t; +typedef std::map<LLUUID, LLStyle::Params> style_map_t; -class LLStyleMap : public style_map_t +class LLStyleMap : public LLSingleton<LLStyleMap> { public: - LLStyleMap(); - ~LLStyleMap(); // Just like the [] accessor but it will add the entry in if it doesn't exist. - const LLStyleSP &lookupAgent(const LLUUID &source); - const LLStyleSP &lookup(const LLUUID &source, const std::string& link); - static LLStyleMap &instance(); + const LLStyle::Params &lookupAgent(const LLUUID &source); + const LLStyle::Params &lookup(const LLUUID &source, const std::string& link); - // Forces refresh of the entries, call when something changes (e.g. link color). - void update(); +private: + style_map_t mMap; }; #endif // LL_LLSTYLE_MAP_H diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp index 8a61f6cfdaf5a7acbf03d6fef769a81bc43950ad..6f26b4077cd0eb07474ccaa7dbae299782dd486a 100644 --- a/indra/newview/lltoastgroupnotifypanel.cpp +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -40,12 +40,12 @@ #include "lliconctrl.h" #include "llnotify.h" #include "lltextbox.h" -#include "llviewertexteditor.h" +#include "lltexteditor.h" #include "lluiconstants.h" #include "llui.h" #include "llviewercontrol.h" #include "lltrans.h" -#include "llinitparam.h" +#include "llstyle.h" #include "llglheaders.h" #include "llagent.h" @@ -75,23 +75,25 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification const std::string& from_name = payload["sender_name"].asString(); std::stringstream from; from << from_name << "/" << groupData.mName; - LLTextBox* pTitleText = this->getChild<LLTextBox>("title"); + LLTextBox* pTitleText = getChild<LLTextBox>("title"); pTitleText->setValue(from.str()); //message body const std::string& subject = payload["subject"].asString(); const std::string& message = payload["message"].asString(); - LLTextEditor* pMessageText = getChild< LLTextEditor>("message"); + LLTextEditor* pMessageText = getChild<LLTextEditor>("message"); pMessageText->setValue(""); pMessageText->setEnabled(FALSE); - pMessageText->setTakesFocus(FALSE); - static const LLStyleSP headerstyle(new LLStyle(true, textColor, - "SansSerifBig")); - static const LLStyleSP datestyle(new LLStyle(true, textColor, "serif")); + LLStyle::Params date_style; + date_style.color = textColor; + date_style.font.name = "SANSSERIF"; - pMessageText->appendStyledText(subject + "\n",false,false,headerstyle); + LLStyle::Params header_style_params; + header_style_params.color = textColor; + header_style_params.font = LLFontGL::getFontSansSerifBig(); + pMessageText->appendStyledText(subject + "\n",false,false,header_style_params); std::string timeStr = "["+LLTrans::getString("UTCTimeWeek")+"],[" +LLTrans::getString("UTCTimeDay")+"] [" @@ -106,7 +108,10 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification LLSD substitution; substitution["datetime"] = (S32) notice_date.secondsSinceEpoch(); LLStringUtil::format(timeStr, substitution); - pMessageText->appendStyledText(timeStr, false, false, datestyle); + LLStyle::Params date_style_params; + date_style_params.color = textColor; + date_style_params.font = LLFontGL::getFontMonospace(); + pMessageText->appendStyledText(timeStr, false, false, date_style); pMessageText->appendColoredText(std::string("\n\n") + message, false, false, textColor); diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index a7b57802c1d28439da8552af011e6c90572a1831..844c54da6a0f5f06c09d43df2649d02607eaf028 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -107,7 +107,6 @@ LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification) : LLToas common_params.rect(LLRect(x, y, x+32, TOP-32)); common_params.mouse_opaque(false); common_params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP); - common_params.tab_stop(false); if (mIsTip) { @@ -180,8 +179,6 @@ LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification) : LLToas params.mouse_opaque(false); params.bg_readonly_color(LLColor4::transparent); params.text_readonly_color(LLUIColorTable::instance().getColor("NotifyTextColor")); - params.takes_non_scroll_clicks(false); - params.hide_scrollbar(true); params.enabled(false); params.hide_border(true); text = LLUICtrlFactory::create<LLTextEditor> (params); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index f08c28752907d4095bed0f34901eb572470cd1e4..8e65c7e65e930a6f9e8e287dd7e641c698e87843 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -207,11 +207,17 @@ void display_stats() } } +static LLFastTimer::DeclareTimer FTM_PICK("Picking"); +static LLFastTimer::DeclareTimer FTM_RENDER("Render", true); +static LLFastTimer::DeclareTimer FTM_UPDATE_SKY("Update Sky"); +static LLFastTimer::DeclareTimer FTM_UPDATE_TEXTURES("Update Textures"); +static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE("Update Images"); + // Paint the display! void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLMemType mt_render(LLMemType::MTYPE_RENDER); - LLFastTimer t(LLFastTimer::FTM_RENDER); + LLFastTimer t(FTM_RENDER); if (LLPipeline::sRenderFrameTest) { @@ -258,7 +264,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gViewerWindow->checkSettings(); { - LLFastTimer ftm(LLFastTimer::FTM_PICK); + LLFastTimer ftm(FTM_PICK); LLAppViewer::instance()->pingMainloopTimeout("Display:Pick"); gViewerWindow->performPick(); } @@ -504,7 +510,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES)) { LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures"); - LLFastTimer t(LLFastTimer::FTM_UPDATE_TEXTURES); + LLFastTimer t(FTM_UPDATE_TEXTURES); if (LLViewerDynamicTexture::updateAllInstances()) { gGL.setColorMask(true, true); @@ -616,7 +622,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLMemType mt_ds(LLMemType::MTYPE_DISPLAY_SWAP); { - LLFastTimer ftm(LLFastTimer::FTM_CLIENT_COPY); + LLFastTimer ftm(FTM_CLIENT_COPY); LLVertexBuffer::clientCopy(0.016); } @@ -687,7 +693,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLMemType mt_iu(LLMemType::MTYPE_DISPLAY_IMAGE_UPDATE); - LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE); + LLFastTimer t(FTM_IMAGE_UPDATE); LLViewerTexture::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(), LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean()); @@ -730,7 +736,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLMemType mt_ds(LLMemType::MTYPE_DISPLAY_SKY); LLAppViewer::instance()->pingMainloopTimeout("Display:Sky"); - LLFastTimer t(LLFastTimer::FTM_UPDATE_SKY); + LLFastTimer t(FTM_UPDATE_SKY); gSky.updateSky(); } @@ -860,7 +866,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI"); if (!for_snapshot) { - LLFastTimer t(LLFastTimer::FTM_RENDER_UI); + LLFastTimer t(FTM_RENDER_UI); render_ui(); } @@ -1040,6 +1046,7 @@ BOOL setup_hud_matrices(const LLRect& screen_region) } } +static LLFastTimer::DeclareTimer FTM_SWAP("Swap"); void render_ui(F32 zoom_factor, int subfield) { @@ -1075,7 +1082,7 @@ void render_ui(F32 zoom_factor, int subfield) gGL.color4f(1,1,1,1); if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - LLFastTimer t(LLFastTimer::FTM_RENDER_UI); + LLFastTimer t(FTM_RENDER_UI); if (!gDisconnected) { @@ -1102,7 +1109,7 @@ void render_ui(F32 zoom_factor, int subfield) if (gDisplaySwapBuffers) { - LLFastTimer t(LLFastTimer::FTM_SWAP); + LLFastTimer t(FTM_SWAP); gViewerWindow->mWindow->swapBuffers(); } gDisplaySwapBuffers = TRUE; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 499632def3335911e492aace372e1ebc2c9718c7..207b9592b820f8e8d398e3af94199562f36c54d7 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -458,13 +458,13 @@ void set_underclothes_menu_options() { if (gMenuHolder && gAgent.isTeen()) { - gMenuHolder->getChild<LLView>("Self Underpants", TRUE)->setVisible(FALSE); - gMenuHolder->getChild<LLView>("Self Undershirt", TRUE)->setVisible(FALSE); + gMenuHolder->getChild<LLView>("Self Underpants")->setVisible(FALSE); + gMenuHolder->getChild<LLView>("Self Undershirt")->setVisible(FALSE); } if (gMenuBarView && gAgent.isTeen()) { - gMenuBarView->getChild<LLView>("Menu Underpants", TRUE)->setVisible(FALSE); - gMenuBarView->getChild<LLView>("Menu Undershirt", TRUE)->setVisible(FALSE); + gMenuBarView->getChild<LLView>("Menu Underpants")->setVisible(FALSE); + gMenuBarView->getChild<LLView>("Menu Undershirt")->setVisible(FALSE); } } @@ -567,8 +567,8 @@ void init_menus() gAFKMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Away", TRUE); gBusyMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Busy", TRUE); - gAttachSubMenu = gMenuBarView->getChildMenuByName("Attach Object", TRUE); - gDetachSubMenu = gMenuBarView->getChildMenuByName("Detach Object", TRUE); + gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE); + gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE); gMenuBarView->createJumpKeys(); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 33568bf3cb55080bd497f07cb67a597908cf2235..d83f3d9207140d69bf83bb9864090392ed921c23 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3302,11 +3302,12 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_ gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED); } +static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects"); void process_kill_object(LLMessageSystem *mesgsys, void **user_data) { - LLFastTimer t(LLFastTimer::FTM_PROCESS_OBJECTS); + LLFastTimer t(FTM_PROCESS_OBJECTS); LLUUID id; U32 local_id; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index ec11e0aee264d8b7cc0a8e6cf075f18491b1d390..99723f86a7013e5703568bfc19221e4d730096c0 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -115,11 +115,13 @@ S32 LLViewerObject::sAxisArrowLength(50); BOOL LLViewerObject::sPulseEnabled(FALSE); BOOL LLViewerObject::sUseSharedDrawables(FALSE); // TRUE +static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object"); + // static LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) { LLViewerObject *res = NULL; - LLFastTimer t1(LLFastTimer::FTM_CREATE_OBJECT); + LLFastTimer t1(FTM_CREATE_OBJECT); switch (pcode) { diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 8939faeb919d618675f9eadf4d5bc637f4d33653..a8232e9a9df8a5d011719f75e56923038481164f 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -258,13 +258,15 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, } } +static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects"); + void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, const EObjectUpdateType update_type, bool cached, bool compressed) { LLMemType mt(LLMemType::MTYPE_OBJECT_PROCESS_UPDATE); - LLFastTimer t(LLFastTimer::FTM_PROCESS_OBJECTS); + LLFastTimer t(FTM_PROCESS_OBJECTS); LLVector3d camera_global = gAgent.getCameraPositionGlobal(); LLViewerObject *objectp; @@ -1304,12 +1306,13 @@ LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLVi } +static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object"); LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id, const LLHost &sender) { LLMemType mt(LLMemType::MTYPE_OBJECT); - LLFastTimer t(LLFastTimer::FTM_CREATE_OBJECT); + LLFastTimer t(FTM_CREATE_OBJECT); LLUUID fullid; if (uuid == LLUUID::null) diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index ec39819bc821d3cebc932c1d3e93a7a112959d0c..cfb83404620703f0d3c945863d42f851f5896d3b 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -631,6 +631,8 @@ void LLViewerPartSim::shift(const LLVector3 &offset) } } +static LLFastTimer::DeclareTimer FTM_SIMULATE_PARTICLES("Simulate Particles"); + void LLViewerPartSim::updateSimulation() { LLMemType mt(LLMemType::MTYPE_PARTICLES); @@ -644,7 +646,7 @@ void LLViewerPartSim::updateSimulation() return; } - LLFastTimer ftm(LLFastTimer::FTM_SIMULATE_PARTICLES); + LLFastTimer ftm(FTM_SIMULATE_PARTICLES); // Start at a random particle system so the same // particle system doesn't always get first pick at the diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 709fcdcf01a04c96f41fa3321047d7700ed82328..444d8e3164b9b106b80c2bf15f55c4140196e4f8 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -594,14 +594,14 @@ void update_statistics(U32 frame_count) LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_AVATAR, (F64)gSavedSettings.getBOOL("VertexShaderLevelAvatar")); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_ENVIRONMENT, (F64)gSavedSettings.getBOOL("VertexShaderLevelEnvironment")); #endif - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::NamedTimer::getRootNamedTimer().getFrameState())); - F64 idle_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IDLE); - F64 network_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_NETWORK); + LLViewerStats::getInstance()->setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame")); + F64 idle_secs = gDebugView->mFastTimerView->getTime("Idle"); + F64 network_secs = gDebugView->mFastTimerView->getTime("Network"); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_NETWORK_SECS, network_secs); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IMAGE_UPDATE)); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_STATESORT )); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_RENDER_GEOMETRY)); + LLViewerStats::getInstance()->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images")); + LLViewerStats::getInstance()->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State")); + LLViewerStats::getInstance()->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry")); LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost()); if (cdp) diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 9e0713b494818cc43d473e4f859b5fd150029207..7565c8669674358bf01eea89571145019187519f 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -62,6 +62,7 @@ #include "llnotecard.h" #include "llmemorystream.h" #include "llmenugl.h" +#include "llscrollcontainer.h" #include "llavataractions.h" #include "llappviewer.h" // for gPacificDaylightTime @@ -108,6 +109,105 @@ class LLEmbeddedNotecardOpener : public LLInventoryCallback } }; +// +// class LLEmbeddedItemSegment +// + +const S32 EMBEDDED_ITEM_LABEL_PADDING = 2; + +class LLEmbeddedItemSegment : public LLTextSegment +{ +public: + LLEmbeddedItemSegment(S32 pos, LLUIImagePtr image, LLPointer<LLInventoryItem> inv_item, LLTextEditor& editor) + : LLTextSegment(pos, pos + 1), + mImage(image), + mLabel(utf8str_to_wstring(inv_item->getName())), + mItem(inv_item), + mEditor(editor), + mHasMouseHover(false) + { + + mStyle = new LLStyle(LLStyle::Params().font(LLFontGL::getFontSansSerif())); + mToolTip = inv_item->getName() + '\n' + inv_item->getDescription(); + } + + /*virtual*/ S32 getWidth(S32 first_char, S32 num_chars) const + { + if (num_chars == 0) + { + return 0; + } + else + { + return EMBEDDED_ITEM_LABEL_PADDING + mImage->getWidth() + mStyle->getFont()->getWidth(mLabel.c_str()); + } + + } + //virtual S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const; + //virtual void updateLayout(const class LLTextEditor& editor); + + /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const + { + return 1; + } + /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) + { + LLRect image_rect = draw_rect; + image_rect.mRight = image_rect.mLeft + mImage->getWidth(); + image_rect.mTop = image_rect.mBottom + mImage->getHeight(); + mImage->draw(image_rect); + + LLColor4 color; + if (mEditor.getReadOnly()) + { + color = LLUIColorTable::instance().getColor("TextEmbeddedItemReadOnlyColor"); + } + else + { + color = LLUIColorTable::instance().getColor("TextEmbeddedItemColor"); + } + + F32 right_x; + mStyle->getFont()->render(mLabel, 0, image_rect.mRight + EMBEDDED_ITEM_LABEL_PADDING, draw_rect.mBottom, color, LLFontGL::LEFT, LLFontGL::BOTTOM, mHasMouseHover ? LLFontGL::UNDERLINE : 0, LLFontGL::NO_SHADOW, mLabel.length(), S32_MAX, &right_x); + return right_x; + } + + /*virtual*/ S32 getMaxHeight() const + { + return llmax(mImage->getHeight(), llceil(mStyle->getFont()->getLineHeight())); + } + /*virtual*/ bool canEdit() const { return false; } + //virtual void unlinkFromDocument(class LLTextEditor* editor); + //virtual void linkToDocument(class LLTextEditor* editor); + + virtual void setHasMouseHover(bool hover) + { + mHasMouseHover = hover; + } + //virtual const LLColor4& getColor() const; + //virtual void setColor(const LLColor4 &color); + //virtual void setStyle(const LLStyleSP &style); + virtual BOOL getToolTip( std::string& msg ) const + { + msg = mToolTip; + return TRUE; + } + + /*virtual*/ const LLStyleSP getStyle() const { return mStyle; } + +private: + LLUIImagePtr mImage; + LLWString mLabel; + LLStyleSP mStyle; + std::string mToolTip; + LLPointer<LLInventoryItem> mItem; + LLTextEditor& mEditor; + bool mHasMouseHover; + +}; + + + //////////////////////////////////////////////////////////// // LLEmbeddedItems // @@ -130,13 +230,11 @@ class LLEmbeddedItems // return true if there are no embedded items. bool empty(); - void bindEmbeddedChars(const LLFontGL* font) const; - void unbindEmbeddedChars(const LLFontGL* font) const; - BOOL insertEmbeddedItem(LLInventoryItem* item, llwchar* value, bool is_new); BOOL removeEmbeddedItem( llwchar ext_char ); BOOL hasEmbeddedItem(llwchar ext_char); // returns TRUE if /this/ editor has an entry for this item + LLUIImagePtr getItemImage(llwchar ext_char) const; void getEmbeddedItemList( std::vector<LLPointer<LLInventoryItem> >& items ); void addItems(const std::vector<LLPointer<LLInventoryItem> >& items); @@ -351,27 +449,13 @@ BOOL LLEmbeddedItems::hasEmbeddedItem(llwchar ext_char) return FALSE; } -void LLEmbeddedItems::bindEmbeddedChars( const LLFontGL* font ) const -{ - if( sEntries.empty() ) - { - return; - } - for (std::set<llwchar>::const_iterator iter1 = mEmbeddedUsedChars.begin(); iter1 != mEmbeddedUsedChars.end(); ++iter1) +LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const +{ + LLInventoryItem* item = getEmbeddedItem(ext_char); + if (item) { - llwchar wch = *iter1; - item_map_t::iterator iter2 = sEntries.find(wch); - if (iter2 == sEntries.end()) - { - continue; - } - LLInventoryItem* item = iter2->second.mItem; - if (!item) - { - continue; - } - const char* img_name; + const char* img_name = ""; switch( item->getType() ) { case LLAssetType::AT_TEXTURE: @@ -428,27 +512,14 @@ void LLEmbeddedItems::bindEmbeddedChars( const LLFontGL* font ) const case LLAssetType::AT_GESTURE: img_name = "inv_item_gesture.tga"; break; //TODO need img_name case LLAssetType::AT_FAVORITE: img_name = "inv_item_landmark.tga"; break; - default: llassert(0); continue; + default: llassert(0); } - LLUIImagePtr image = LLUI::getUIImage(img_name); - - font->addEmbeddedChar( wch, image->getImage(), item->getName() ); + return LLUI::getUIImage(img_name); } + return LLUIImagePtr(); } -void LLEmbeddedItems::unbindEmbeddedChars( const LLFontGL* font ) const -{ - if( sEntries.empty() ) - { - return; - } - - for (std::set<llwchar>::const_iterator iter1 = mEmbeddedUsedChars.begin(); iter1 != mEmbeddedUsedChars.end(); ++iter1) - { - font->removeEmbeddedChar(*iter1); - } -} void LLEmbeddedItems::addItems(const std::vector<LLPointer<LLInventoryItem> >& items) { @@ -613,30 +684,16 @@ BOOL LLViewerTextEditor::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* s } const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); - if( cur_segment ) + if( cur_segment && cur_segment->getToolTip( msg ) ) { - BOOL has_tool_tip = FALSE; - if( cur_segment->getStyle()->getIsEmbeddedItem() ) - { - LLWString wtip; - has_tool_tip = getEmbeddedItemToolTipAtPos(cur_segment->getStart(), wtip); - msg = wstring_to_utf8str(wtip); - } - else - { - has_tool_tip = cur_segment->getToolTip( msg ); - } - if( has_tool_tip ) - { - // Just use a slop area around the cursor - // Convert rect local to screen coordinates - S32 SLOP = 8; - localPointToScreen( - x - SLOP, y - SLOP, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP; - sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP; - } + // Just use a slop area around the cursor + // Convert rect local to screen coordinates + S32 SLOP = 8; + localPointToScreen( + x - SLOP, y - SLOP, + &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); + sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP; + sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP; } return TRUE; } @@ -648,21 +705,8 @@ BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) // Let scrollbar have first dibs handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL; - // enable I Agree checkbox if the user scrolled through entire text - BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()); - if (mOnScrollEndCallback && was_scrolled_to_bottom) + if( !handled) { - mOnScrollEndCallback(mOnScrollEndData); - } - - if( !handled && mTakesNonScrollClicks) - { - if (!(mask & MASK_SHIFT)) - { - deselect(); - } - - BOOL start_select = TRUE; if( allowsEmbeddedItems() ) { setCursorAtLocalPos( x, y, FALSE ); @@ -685,192 +729,55 @@ BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) localPointToScreen(x, y, &screen_x, &screen_y ); LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y ); - start_select = FALSE; - } - else - { - mDragItem = NULL; - } - } - - if( start_select ) - { - // If we're not scrolling (handled by child), then we're selecting - if (mask & MASK_SHIFT) - { - S32 old_cursor_pos = mCursorPos; - setCursorAtLocalPos( x, y, TRUE ); - - if (hasSelection()) - { - /* Mac-like behavior - extend selection towards the cursor - if (mCursorPos < mSelectionStart - && mCursorPos < mSelectionEnd) - { - // ...left of selection - mSelectionStart = llmax(mSelectionStart, mSelectionEnd); - mSelectionEnd = mCursorPos; - } - else if (mCursorPos > mSelectionStart - && mCursorPos > mSelectionEnd) - { - // ...right of selection - mSelectionStart = llmin(mSelectionStart, mSelectionEnd); - mSelectionEnd = mCursorPos; - } - else - { - mSelectionEnd = mCursorPos; - } - */ - // Windows behavior - mSelectionEnd = mCursorPos; - } - else + if (hasTabStop()) { - mSelectionStart = old_cursor_pos; - mSelectionEnd = mCursorPos; + setFocus( TRUE ); } - // assume we're starting a drag select - mIsSelecting = TRUE; + handled = TRUE; } else { - setCursorAtLocalPos( x, y, TRUE ); - startSelection(); + mDragItem = NULL; } - gFocusMgr.setMouseCapture( this ); } - handled = TRUE; - } - - if (hasTabStop()) - { - setFocus(TRUE); - handled = TRUE; + if (!handled) + { + handled = LLTextEditor::handleMouseDown(x, y, mask); + } } - // Delay cursor flashing - resetKeystrokeTimer(); - return handled; } BOOL LLViewerTextEditor::handleHover(S32 x, S32 y, MASK mask) { - static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); - BOOL handled = FALSE; + BOOL handled = LLTextEditor::handleHover(x, y, mask); - if (!mDragItem) + if(hasMouseCapture() && mDragItem) { - // leave hover segment active during drag and drop - mHoverSegment = NULL; - } - if(hasMouseCapture() ) - { - if( mIsSelecting ) - { - if (x != mLastSelectionX || y != mLastSelectionY) - { - mLastSelectionX = x; - mLastSelectionY = y; - } + S32 screen_x; + S32 screen_y; + localPointToScreen(x, y, &screen_x, &screen_y ); - if( y > getTextRect().mTop ) - { - mScrollbar->setDocPos( mScrollbar->getDocPos() - 1 ); - } - else - if( y < getTextRect().mBottom ) - { - mScrollbar->setDocPos( mScrollbar->getDocPos() + 1 ); - } + mScroller->autoScroll(x, y); - setCursorAtLocalPos( x, y, TRUE ); - mSelectionEnd = mCursorPos; - - updateScrollFromCursor(); - getWindow()->setCursor(UI_CURSOR_IBEAM); - } - else if( mDragItem ) + if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) ) { - S32 screen_x; - S32 screen_y; - localPointToScreen(x, y, &screen_x, &screen_y ); - if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) ) - { - LLToolDragAndDrop::getInstance()->beginDrag( - LLAssetType::lookupDragAndDropType( mDragItem->getType() ), - mDragItem->getUUID(), - LLToolDragAndDrop::SOURCE_NOTECARD, - mPreviewID, mObjectID); + LLToolDragAndDrop::getInstance()->beginDrag( + LLAssetType::lookupDragAndDropType( mDragItem->getType() ), + mDragItem->getUUID(), + LLToolDragAndDrop::SOURCE_NOTECARD, + mPreviewID, mObjectID); - return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask ); - } - getWindow()->setCursor(UI_CURSOR_HAND); + return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask ); } - - lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl; + getWindow()->setCursor(UI_CURSOR_HAND); handled = TRUE; } - if( !handled ) - { - // Pass to children - handled = LLView::childrenHandleHover(x, y, mask) != NULL; - } - - if( handled ) - { - // Delay cursor flashing - resetKeystrokeTimer(); - } - - // Opaque - if( !handled && mTakesNonScrollClicks) - { - // Check to see if we're over an HTML-style link - if( !mSegments.empty() ) - { - const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); - if( cur_segment ) - { - if(cur_segment->getStyle()->isLink()) - { - lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over link, inactive)" << llendl; - getWindow()->setCursor(UI_CURSOR_HAND); - handled = TRUE; - } - else - if(cur_segment->getStyle()->getIsEmbeddedItem()) - { - lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over embedded item, inactive)" << llendl; - getWindow()->setCursor(UI_CURSOR_HAND); - //getWindow()->setCursor(UI_CURSOR_ARROW); - handled = TRUE; - } - mHoverSegment = cur_segment; - } - } - - if( !handled ) - { - lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl; - if (!mScrollbar->getVisible() || x < getRect().getWidth() - scrollbar_size) - { - getWindow()->setCursor(UI_CURSOR_IBEAM); - } - else - { - getWindow()->setCursor(UI_CURSOR_ARROW); - } - handled = TRUE; - } - } - return handled; } @@ -903,13 +810,6 @@ BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) handled = LLTextEditor::handleMouseUp(x,y,mask); - // Used to enable I Agree checkbox if the user scrolled through entire text - BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()); - if (mOnScrollEndCallback && was_scrolled_to_bottom) - { - mOnScrollEndCallback(mOnScrollEndData); - } - return handled; } @@ -949,24 +849,6 @@ BOOL LLViewerTextEditor::handleRightMouseDown(S32 x, S32 y, MASK mask) return handled; } -BOOL LLViewerTextEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask) -{ - BOOL handled = FALSE; - handled = childrenHandleMiddleMouseDown(x, y, mask) != NULL; - if (!handled) - { - handled = LLTextEditor::handleMiddleMouseDown(x, y, mask); - } - return handled; -} - -BOOL LLViewerTextEditor::handleMiddleMouseUp(S32 x, S32 y, MASK mask) -{ - BOOL handled = childrenHandleMiddleMouseUp(x, y, mask) != NULL; - - return handled; -} - BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; @@ -974,14 +856,15 @@ BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) // let scrollbar have first dibs handled = LLView::childrenHandleDoubleClick(x, y, mask) != NULL; - if( !handled && mTakesNonScrollClicks) + if( !handled) { if( allowsEmbeddedItems() ) { - const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); - if( cur_segment && cur_segment->getStyle()->getIsEmbeddedItem() ) + S32 doc_index = getDocIndexFromLocalCoord(x, y, FALSE); + llwchar doc_char = getWText()[doc_index]; + if (mEmbeddedItemList->hasEmbeddedItem(doc_char)) { - if( openEmbeddedItemAtPos( cur_segment->getStart() ) ) + if( openEmbeddedItemAtPos( doc_index )) { deselect(); setFocus( FALSE ); @@ -989,47 +872,7 @@ BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) } } } - - setCursorAtLocalPos( x, y, FALSE ); - deselect(); - - const LLWString &text = getWText(); - - if( isPartOfWord( text[mCursorPos] ) ) - { - // Select word the cursor is over - while ((mCursorPos > 0) && isPartOfWord(text[mCursorPos-1])) - { - mCursorPos--; - } - startSelection(); - - while ((mCursorPos < (S32)text.length()) && isPartOfWord( text[mCursorPos] ) ) - { - mCursorPos++; - } - - mSelectionEnd = mCursorPos; - } - else if ((mCursorPos < (S32)text.length()) && !iswspace( text[mCursorPos]) ) - { - // Select the character the cursor is over - startSelection(); - mCursorPos++; - mSelectionEnd = mCursorPos; - } - - // We don't want handleMouseUp() to "finish" the selection (and thereby - // set mSelectionEnd to where the mouse is), so we finish the selection here. - mIsSelecting = FALSE; - - // delay cursor flashing - resetKeystrokeTimer(); - - // take selection to 'primary' clipboard - updatePrimary(); - - handled = TRUE; + handled = LLTextEditor::handleDoubleClick(x, y, mask); } return handled; } @@ -1051,80 +894,78 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, return FALSE; } - if (mTakesNonScrollClicks) + if (getEnabled() && acceptsTextInput()) { - if (getEnabled() && acceptsTextInput()) + switch( cargo_type ) { - switch( cargo_type ) + case DAD_CALLINGCARD: + case DAD_TEXTURE: + case DAD_SOUND: + case DAD_LANDMARK: + case DAD_SCRIPT: + case DAD_CLOTHING: + case DAD_OBJECT: + case DAD_NOTECARD: + case DAD_BODYPART: + case DAD_ANIMATION: + case DAD_GESTURE: { - case DAD_CALLINGCARD: - case DAD_TEXTURE: - case DAD_SOUND: - case DAD_LANDMARK: - case DAD_SCRIPT: - case DAD_CLOTHING: - case DAD_OBJECT: - case DAD_NOTECARD: - case DAD_BODYPART: - case DAD_ANIMATION: - case DAD_GESTURE: + LLInventoryItem *item = (LLInventoryItem *)cargo_data; + if( item && allowsEmbeddedItems() ) { - LLInventoryItem *item = (LLInventoryItem *)cargo_data; - if( item && allowsEmbeddedItems() ) + U32 mask_next = item->getPermissions().getMaskNextOwner(); + if((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) { - U32 mask_next = item->getPermissions().getMaskNextOwner(); - if((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) - { - if( drop ) - { - deselect(); - S32 old_cursor = mCursorPos; - setCursorAtLocalPos( x, y, TRUE ); - S32 insert_pos = mCursorPos; - setCursorPos(old_cursor); - BOOL inserted = insertEmbeddedItem( insert_pos, item ); - if( inserted && (old_cursor > mCursorPos) ) - { - setCursorPos(mCursorPos + 1); - } - - updateLineStartList(); - } - *accept = ACCEPT_YES_COPY_MULTI; - } - else + if( drop ) { - *accept = ACCEPT_NO; - if (tooltip_msg.empty()) + deselect(); + S32 old_cursor = mCursorPos; + setCursorAtLocalPos( x, y, TRUE ); + S32 insert_pos = mCursorPos; + setCursorPos(old_cursor); + BOOL inserted = insertEmbeddedItem( insert_pos, item ); + if( inserted && (old_cursor > mCursorPos) ) { - // *TODO: Translate - tooltip_msg.assign("Only items with unrestricted\n" - "'next owner' permissions \n" - "can be attached to notecards."); + setCursorPos(mCursorPos + 1); } + + needsReflow(); + } + *accept = ACCEPT_YES_COPY_MULTI; } else { *accept = ACCEPT_NO; + if (tooltip_msg.empty()) + { + // *TODO: Translate + tooltip_msg.assign("Only items with unrestricted\n" + "'next owner' permissions \n" + "can be attached to notecards."); + } } - break; } - - default: + else + { *accept = ACCEPT_NO; - break; + } + break; } - } - else - { - // Not enabled + + default: *accept = ACCEPT_NO; + break; } - - handled = TRUE; - lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLViewerTextEditor " << getName() << llendl; } + else + { + // Not enabled + *accept = ACCEPT_NO; + } + + handled = TRUE; + lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLViewerTextEditor " << getName() << llendl; return handled; } @@ -1244,33 +1085,33 @@ llwchar LLViewerTextEditor::pasteEmbeddedItem(llwchar ext_char) return LL_UNKNOWN_CHAR; // item not found or list full } -void LLViewerTextEditor::bindEmbeddedChars(const LLFontGL* font) const +void LLViewerTextEditor::onValueChange(S32 start, S32 end) { - mEmbeddedItemList->bindEmbeddedChars( font ); + updateSegments(); + findEmbeddedItemSegments(start, end); } -void LLViewerTextEditor::unbindEmbeddedChars(const LLFontGL* font) const +void LLViewerTextEditor::findEmbeddedItemSegments(S32 start, S32 end) { - mEmbeddedItemList->unbindEmbeddedChars( font ); -} + LLWString text = getWText(); -BOOL LLViewerTextEditor::getEmbeddedItemToolTipAtPos(S32 pos, LLWString &msg) const -{ - if (pos < getLength()) + LLColor4 text_color = ( mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get() ); + + // Start with i just after the first embedded item + for(S32 idx = start; idx < end; idx++ ) { - LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItem(getWChar(pos)); - if( item ) + llwchar embedded_char = text[idx]; + if( embedded_char >= FIRST_EMBEDDED_CHAR + && embedded_char <= LAST_EMBEDDED_CHAR + && mEmbeddedItemList->hasEmbeddedItem(embedded_char) ) { - msg = utf8str_to_wstring(item->getName()); - msg += '\n'; - msg += utf8str_to_wstring(item->getDescription()); - return TRUE; + LLInventoryItem* itemp = mEmbeddedItemList->getEmbeddedItem(embedded_char); + LLUIImagePtr image = mEmbeddedItemList->getItemImage(embedded_char); + insertSegment(new LLEmbeddedItemSegment(idx, image, itemp, *this)); } } - return FALSE; } - BOOL LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos) { if( pos < getLength()) diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h index 1a69c6869df51c18899ffbe419df5508261bcdcf..9567bfbc48e1fb0d755c5d2409a7a3c5079d123d 100644 --- a/indra/newview/llviewertexteditor.h +++ b/indra/newview/llviewertexteditor.h @@ -65,8 +65,6 @@ class LLViewerTextEditor : public LLTextEditor // mousehandler overrides virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); - virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); - virtual BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask ); @@ -80,6 +78,8 @@ class LLViewerTextEditor : public LLTextEditor virtual BOOL importBuffer(const char* buffer, S32 length); virtual bool importStream(std::istream& str); virtual BOOL exportBuffer(std::string& buffer); + virtual void onValueChange(S32 start, S32 end); + void setNotecardInfo(const LLUUID& notecard_item_id, const LLUUID& object_id, const LLUUID& preview_id) { mNotecardInventoryID = notecard_item_id; @@ -106,11 +106,9 @@ class LLViewerTextEditor : public LLTextEditor private: // Embedded object operations + void findEmbeddedItemSegments(S32 start, S32 end); virtual llwchar pasteEmbeddedItem(llwchar ext_char); - virtual void bindEmbeddedChars(const LLFontGL* font) const; - virtual void unbindEmbeddedChars(const LLFontGL* font) const; - BOOL getEmbeddedItemToolTipAtPos(S32 pos, LLWString &wmsg) const; BOOL openEmbeddedItemAtPos( S32 pos ); BOOL openEmbeddedItem(LLInventoryItem* item, llwchar wc); @@ -128,6 +126,7 @@ class LLViewerTextEditor : public LLTextEditor static bool onNotecardDialog(const LLSD& notification, const LLSD& response ); LLPointer<LLInventoryItem> mDragItem; + LLTextSegment* mDragSegment; llwchar mDragItemChar; BOOL mDragItemSaved; class LLEmbeddedItems* mEmbeddedItemList; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 7b01fe4280c7f106c86b495d026ab80cad91177e..83442dc2bb9b43e3adfe021ecef71128266647ad 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -75,6 +75,7 @@ const S32 IMAGES_MAX_PACKET_UPDATES = 1; // Only send N packets of IMAGES_PER_RE const F32 RESEND_IMAGE_REQUEST_TIME = 15.f; // seconds LLViewerTextureList gTextureList; +static LLFastTimer::DeclareTimer FTM_PROCESS_IMAGES("Process Images"); /////////////////////////////////////////////////////////////////////////////// @@ -542,6 +543,7 @@ void LLViewerTextureList::dirtyImage(LLViewerFetchedTexture *image) } //////////////////////////////////////////////////////////////////////////// +static LLFastTimer::DeclareTimer FTM_IMAGE_MARK_DIRTY("Dirty Images"); void LLViewerTextureList::updateImages(F32 max_time) { @@ -559,7 +561,7 @@ void LLViewerTextureList::updateImages(F32 max_time) max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f); if (!mDirtyTextureList.empty()) { - LLFastTimer t(LLFastTimer::FTM_IMAGE_MARK_DIRTY); + LLFastTimer t(FTM_IMAGE_MARK_DIRTY); gPipeline.dirtyPoolObjectTextures(mDirtyTextureList); mDirtyTextureList.clear(); } @@ -697,6 +699,7 @@ void LLViewerTextureList::updateImagesDecodePriorities() return type_from_host; } */ +static LLFastTimer::DeclareTimer FTM_IMAGE_CREATE("Create Images"); F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) { @@ -706,7 +709,7 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) // Create GL textures for all textures that need them (images which have been // decoded, but haven't been pushed into GL). // - LLFastTimer t(LLFastTimer::FTM_IMAGE_CREATE); + LLFastTimer t(FTM_IMAGE_CREATE); LLTimer create_timer; image_list_t::iterator enditer = mCreateTextureList.begin(); @@ -1115,7 +1118,7 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32 mem) // static void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_data) { - LLFastTimer t(LLFastTimer::FTM_PROCESS_IMAGES); + LLFastTimer t(FTM_PROCESS_IMAGES); // Receive image header, copy into image object and decompresses // if this is a one-packet image. @@ -1179,7 +1182,7 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_data) { LLMemType mt1(LLMemType::MTYPE_APPFMTIMAGE); - LLFastTimer t(LLFastTimer::FTM_PROCESS_IMAGES); + LLFastTimer t(FTM_PROCESS_IMAGES); // Receives image packet, copy into image object, // checks if all packets received, decompresses if so. @@ -1244,7 +1247,7 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d // static void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **user_data) { - LLFastTimer t(LLFastTimer::FTM_PROCESS_IMAGES); + LLFastTimer t(FTM_PROCESS_IMAGES); LLUUID image_id; msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, image_id); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2b1dbf8e84a2a6d7107d6d34a4e1dd6f61b7ffde..74ed5b12fe1fa0e0c43b012942a0dbf86b1a2b2e 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -935,8 +935,6 @@ void LLViewerWindow::handleFocus(LLWindow *window) gAgent.onAppFocusGained(); LLToolMgr::getInstance()->onAppFocusGained(); - gShowTextEditCursor = TRUE; - // See if we're coming in with modifier keys held down if (gKeyboard) { @@ -966,11 +964,6 @@ void LLViewerWindow::handleFocusLost(LLWindow *window) showCursor(); getWindow()->setMouseClipping(FALSE); - // JC - Leave keyboard focus, so if you're popping in and out editing - // a script, you don't have to click in the editor again and again. - // gFocusMgr.setKeyboardFocus( NULL ); - gShowTextEditCursor = FALSE; - // If losing focus while keys are down, reset them. if (gKeyboard) { @@ -2020,6 +2013,11 @@ void LLViewerWindow::draw() // No translation needed, this view is glued to 0,0 mRootView->draw(); + if (mToolTip->getVisible() && LLView::sDebugRects) + { + gl_rect_2d(mToolTipStickyRect, LLColor4::white, false); + } + // Draw optional on-top-of-everyone view LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); if (top_ctrl && top_ctrl->getVisible()) @@ -3320,7 +3318,7 @@ void LLViewerWindow::schedulePick(LLPickInfo& pick_info) return; } - llassert_always(pick_info.mScreenRegion.notNull()); + llassert_always(pick_info.mScreenRegion.notEmpty()); mPicks.push_back(pick_info); // delay further event processing until we receive results of pick diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 2b5c3361c432bc36f8910fa23bf8ddbeea149017..e98e4f2e6a938713dadd60cfdaf102327eaaadbd 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2085,13 +2085,16 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid) } } +static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Update Avatar"); +static LLFastTimer::DeclareTimer FTM_JOINT_UPDATE("Update Joints"); + //------------------------------------------------------------------------ // idleUpdate() //------------------------------------------------------------------------ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { LLMemType mt(LLMemType::MTYPE_AVATAR); - LLFastTimer t(LLFastTimer::FTM_AVATAR_UPDATE); + LLFastTimer t(FTM_AVATAR_UPDATE); if (isDead()) { @@ -2110,7 +2113,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) // force asynchronous drawable update if(mDrawable.notNull() && !gNoRender) { - LLFastTimer t(LLFastTimer::FTM_JOINT_UPDATE); + LLFastTimer t(FTM_JOINT_UPDATE); if (mIsSitting && getParent()) { @@ -2272,6 +2275,8 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) }//if ( voiceEnabled ) } +static LLFastTimer::DeclareTimer FTM_ATTACHMENT_UPDATE("Update Attachments"); + void LLVOAvatar::idleUpdateMisc(bool detailed_update) { if (LLVOAvatar::sJointDebug) @@ -2293,7 +2298,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) // update attachments positions if (detailed_update || !sUseImpostors) { - LLFastTimer t(LLFastTimer::FTM_ATTACHMENT_UPDATE); + LLFastTimer t(FTM_ATTACHMENT_UPDATE); for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ) { @@ -4613,9 +4618,11 @@ void LLVOAvatar::requestStopMotion( LLMotion* motion ) //----------------------------------------------------------------------------- // loadAvatar() //----------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_LOAD_AVATAR("Load Avatar"); + BOOL LLVOAvatar::loadAvatar() { -// LLFastTimer t(LLFastTimer::FTM_LOAD_AVATAR); +// LLFastTimer t(FTM_LOAD_AVATAR); // avatar_skeleton.xml if( !buildSkeleton(sAvatarSkeletonInfo) ) @@ -5168,9 +5175,10 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline) //----------------------------------------------------------------------------- // updateGeometry() //----------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_UPDATE_AVATAR("Update Avatar"); BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable) { - LLFastTimer ftm(LLFastTimer::FTM_UPDATE_AVATAR); + LLFastTimer ftm(FTM_UPDATE_AVATAR); if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))) { return TRUE; diff --git a/indra/newview/llvoclouds.cpp b/indra/newview/llvoclouds.cpp index fbc4e2e609f948fde71bb772a9294c2dbadb3e9f..130e1fd749a19bf26b3a249c763aa170827b0aef 100644 --- a/indra/newview/llvoclouds.cpp +++ b/indra/newview/llvoclouds.cpp @@ -115,9 +115,11 @@ LLDrawable* LLVOClouds::createDrawable(LLPipeline *pipeline) return mDrawable; } +static LLFastTimer::DeclareTimer FTM_UPDATE_CLOUDS("Update Clouds"); + BOOL LLVOClouds::updateGeometry(LLDrawable *drawable) { - LLFastTimer ftm(LLFastTimer::FTM_UPDATE_CLOUDS); + LLFastTimer ftm(FTM_UPDATE_CLOUDS); if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS))) { return TRUE; diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index cf6eb8e9fd342307239c9919eb9ce00f4b5fca54..a2793acceac60a99f730c28a3ba0cb0201e6ff1a 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -382,9 +382,11 @@ LLDrawable* LLVOGrass::createDrawable(LLPipeline *pipeline) return mDrawable; } +static LLFastTimer::DeclareTimer FTM_UPDATE_GRASS("Update Grass"); + BOOL LLVOGrass::updateGeometry(LLDrawable *drawable) { - LLFastTimer ftm(LLFastTimer::FTM_UPDATE_GRASS); + LLFastTimer ftm(FTM_UPDATE_GRASS); dirtySpatialGroup(); plantBlades(); return TRUE; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 29036f4947bf0e7717846a3f7e2644aa304fb736..38c9ce28c4695a0df3bd6076f8fd7ac9154fed3c 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -139,9 +139,10 @@ LLVector3 LLVOPartGroup::getCameraPosition() const return gAgent.getCameraPositionAgent(); } +static LLFastTimer::DeclareTimer FTM_UPDATE_PARTICLES("Update Particles"); BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) { - LLFastTimer ftm(LLFastTimer::FTM_UPDATE_PARTICLES); + LLFastTimer ftm(FTM_UPDATE_PARTICLES); dirtySpatialGroup(); @@ -416,12 +417,15 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co } } +static LLFastTimer::DeclareTimer FTM_REBUILD_GRASS_VB("Grass VB"); +static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VB("Particle VB"); + void LLParticlePartition::getGeometry(LLSpatialGroup* group) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); LLFastTimer ftm(mDrawableType == LLPipeline::RENDER_TYPE_GRASS ? - LLFastTimer::FTM_REBUILD_GRASS_VB : - LLFastTimer::FTM_REBUILD_PARTICLE_VB); + FTM_REBUILD_GRASS_VB : + FTM_REBUILD_PARTICLE_VB); std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater()); diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 993cf522e98a18c260e9fa2925cf8f7dfee3799f..ae5992099d967e0e4bd7f6c4903cf427cef5cbfa 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -1231,6 +1231,8 @@ void LLVOSky::createDummyVertexBuffer() } } +static LLFastTimer::DeclareTimer FTM_RENDER_FAKE_VBO_UPDATE("Fake VBO Update"); + void LLVOSky::updateDummyVertexBuffer() { if(!LLVertexBuffer::sEnableVBOs) @@ -1242,7 +1244,7 @@ void LLVOSky::updateDummyVertexBuffer() return ; } - LLFastTimer t(LLFastTimer::FTM_RENDER_FAKE_VBO_UPDATE) ; + LLFastTimer t(FTM_RENDER_FAKE_VBO_UPDATE) ; if(!mFace[FACE_DUMMY] || mFace[FACE_DUMMY]->mVertexBuffer.isNull()) createDummyVertexBuffer() ; @@ -1255,10 +1257,11 @@ void LLVOSky::updateDummyVertexBuffer() //---------------------------------- //end of fake vertex buffer updating //---------------------------------- +static LLFastTimer::DeclareTimer FTM_GEO_SKY("Sky Geometry"); BOOL LLVOSky::updateGeometry(LLDrawable *drawable) { - LLFastTimer ftm(LLFastTimer::FTM_GEO_SKY); + LLFastTimer ftm(FTM_GEO_SKY); if (mFace[FACE_REFLECTION] == NULL) { LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 4980b50de4555ce10a500b63afbea3d7b18ed5ad..157d719fcca10840eadc4ef46e6805dc26025fdd 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -176,10 +176,11 @@ LLDrawable *LLVOSurfacePatch::createDrawable(LLPipeline *pipeline) return mDrawable; } +static LLFastTimer::DeclareTimer FTM_UPDATE_TERRAIN("Update Terrain"); BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable) { - LLFastTimer ftm(LLFastTimer::FTM_UPDATE_TERRAIN); + LLFastTimer ftm(FTM_UPDATE_TERRAIN); dirtySpatialGroup(); @@ -1028,9 +1029,10 @@ LLVertexBuffer* LLTerrainPartition::createVertexBuffer(U32 type_mask, U32 usage) return new LLVertexBufferTerrain(); } +static LLFastTimer::DeclareTimer FTM_REBUILD_TERRAIN_VB("Terrain VB"); void LLTerrainPartition::getGeometry(LLSpatialGroup* group) { - LLFastTimer ftm(LLFastTimer::FTM_REBUILD_TERRAIN_VB); + LLFastTimer ftm(FTM_REBUILD_TERRAIN_VB); LLVertexBuffer* buffer = group->mVertexBuffer; diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index d1cac4c77e53f35f8321ac36e7423dec064c1c3e..86d9f31d071aabfa45001b4c3167f5d714a0d3fb 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -504,9 +504,11 @@ LLDrawable* LLVOTree::createDrawable(LLPipeline *pipeline) const S32 LEAF_INDICES = 24; const S32 LEAF_VERTICES = 16; +static LLFastTimer::DeclareTimer FTM_UPDATE_TREE("Update Tree"); + BOOL LLVOTree::updateGeometry(LLDrawable *drawable) { - LLFastTimer ftm(LLFastTimer::FTM_UPDATE_TREE); + LLFastTimer ftm(FTM_UPDATE_TREE); if (mReferenceBuffer.isNull() || mDrawable->getFace(0)->mVertexBuffer.isNull()) { diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index bef38bb669ab0014f12a95052cd6294d71d82e38..f7a16571d117297abb33673e4ab0ff051bc1e299 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -79,6 +79,9 @@ F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectiv F32 LLVOVolume::sDistanceFactor = 1.0f; S32 LLVOVolume::sNumLODChanges = 0; +static LLFastTimer::DeclareTimer FTM_GEN_TRIANGLES("Generate Triangles"); +static LLFastTimer::DeclareTimer FTM_GEN_VOLUME("Generate Volumes"); + LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) : LLViewerObject(id, pcode, regionp), mVolumeImpl(NULL) @@ -1130,15 +1133,18 @@ void LLVOVolume::updateRelativeXform() } } +static LLFastTimer::DeclareTimer FTM_GEN_FLEX("Generate Flexies"); +static LLFastTimer::DeclareTimer FTM_UPDATE_PRIMITIVES("Update Primitives"); + BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) { - LLFastTimer t(LLFastTimer::FTM_UPDATE_PRIMITIVES); + LLFastTimer t(FTM_UPDATE_PRIMITIVES); if (mVolumeImpl != NULL) { BOOL res; { - LLFastTimer t(LLFastTimer::FTM_GEN_FLEX); + LLFastTimer t(FTM_GEN_FLEX); res = mVolumeImpl->doUpdateGeometry(drawable); } updateFaceFlags(); @@ -1162,14 +1168,14 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) if (mVolumeChanged) { - LLFastTimer ftm(LLFastTimer::FTM_GEN_VOLUME); + LLFastTimer ftm(FTM_GEN_VOLUME); LLVolumeParams volume_params = getVolume()->getParams(); setVolume(volume_params, 0); drawable->setState(LLDrawable::REBUILD_VOLUME); } { - LLFastTimer t(LLFastTimer::FTM_GEN_TRIANGLES); + LLFastTimer t(FTM_GEN_TRIANGLES); regenFaces(); genBBoxes(FALSE); } @@ -1186,7 +1192,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) old_volumep = NULL ; { - LLFastTimer ftm(LLFastTimer::FTM_GEN_VOLUME); + LLFastTimer ftm(FTM_GEN_VOLUME); LLVolumeParams volume_params = getVolume()->getParams(); setVolume(volume_params, 0); } @@ -1204,7 +1210,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles() { - LLFastTimer t(LLFastTimer::FTM_GEN_TRIANGLES); + LLFastTimer t(FTM_GEN_TRIANGLES); if (new_num_faces != old_num_faces) { regenFaces(); @@ -1218,7 +1224,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) { compiled = TRUE; // All it did was move or we changed the texture coordinate offset - LLFastTimer t(LLFastTimer::FTM_GEN_TRIANGLES); + LLFastTimer t(FTM_GEN_TRIANGLES); genBBoxes(FALSE); } @@ -2235,6 +2241,9 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group) } +static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume"); +static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt"); + void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { if (LLPipeline::sSkipUpdate) @@ -2253,8 +2262,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate) { - LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO); - LLFastTimer ftm2(LLFastTimer::FTM_REBUILD_VOLUME_VB); + LLFastTimer ftm(FTM_REBUILD_VBO); + LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB); rebuildMesh(group); } @@ -2262,9 +2271,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } group->mBuilt = 1.f; - LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO); + LLFastTimer ftm(FTM_REBUILD_VBO); - LLFastTimer ftm2(LLFastTimer::FTM_REBUILD_VOLUME_VB); + LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB); group->clearDrawMap(); diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 427119285b3bfc466d5472ca5f60cbba5ba0e87c..332c9dd952709fa7c6f5343ad62f48e44523d12c 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -139,9 +139,11 @@ LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline) return mDrawable; } +static LLFastTimer::DeclareTimer FTM_UPDATE_WATER("Update Water"); + BOOL LLVOWater::updateGeometry(LLDrawable *drawable) { - LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WATER); + LLFastTimer ftm(FTM_UPDATE_WATER); LLFace *face; if (drawable->getNumFaces() < 1) diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index abd25e6598aefc84819c1ccdc66461713da27480..8621e5e1d9218b46d9a4cb21f010807f85682e78 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -307,9 +307,11 @@ void LLVOWLSky::restoreGL() gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); } +static LLFastTimer::DeclareTimer FTM_GEO_SKY("Sky Geometry"); + BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) { - LLFastTimer ftm(LLFastTimer::FTM_GEO_SKY); + LLFastTimer ftm(FTM_GEO_SKY); LLStrider<LLVector3> vertices; LLStrider<LLVector2> texCoords; LLStrider<U16> indices; diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 92c223e43dc3b3b4de75279672e9ff9df7036fbd..3661be500bfa21e501d241a42d589ee79772934d 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -263,9 +263,11 @@ void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader) } } +static LLFastTimer::DeclareTimer FTM_UPDATE_WLPARAM("Update Windlight Params"); + void LLWaterParamManager::update(LLViewerCamera * cam) { - LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM); + LLFastTimer ftm(FTM_UPDATE_WLPARAM); // update the shaders and the menu propagateParameters(); diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index c237c0bdede925da2a7d88fae5a272fd67a654a0..ae476c88c91c583116a3b60840d9d5965fcd3e43 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -64,6 +64,7 @@ #include "curl/curl.h" LLWLParamManager * LLWLParamManager::sInstance = NULL; +static LLFastTimer::DeclareTimer FTM_UPDATE_WLPARAM("Update Windlight Params"); LLWLParamManager::LLWLParamManager() : @@ -292,7 +293,7 @@ void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader) void LLWLParamManager::propagateParameters(void) { - LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM); + LLFastTimer ftm(FTM_UPDATE_WLPARAM); LLVector4 sunDir; LLVector4 moonDir; @@ -363,7 +364,7 @@ void LLWLParamManager::propagateParameters(void) void LLWLParamManager::update(LLViewerCamera * cam) { - LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM); + LLFastTimer ftm(FTM_UPDATE_WLPARAM); // update clouds, sun, and general mCurParams.updateCloudScrolling(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f4227918684ef9586f7f8acd2c9603ecf550d127..bf00957212507b37ddc2f65a0729e31c4d79c335 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -138,6 +138,33 @@ BOOL gDebugPipeline = FALSE; LLPipeline gPipeline; const LLMatrix4* gGLLastMatrix = NULL; +LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY("Geometry"); +LLFastTimer::DeclareTimer FTM_RENDER_GRASS("Grass"); +LLFastTimer::DeclareTimer FTM_RENDER_INVISIBLE("Invisible"); +LLFastTimer::DeclareTimer FTM_RENDER_OCCLUSION("Occlusion"); +LLFastTimer::DeclareTimer FTM_RENDER_SHINY("Shiny"); +LLFastTimer::DeclareTimer FTM_RENDER_SIMPLE("Simple"); +LLFastTimer::DeclareTimer FTM_RENDER_TERRAIN("Terrain"); +LLFastTimer::DeclareTimer FTM_RENDER_TREES("Trees"); +LLFastTimer::DeclareTimer FTM_RENDER_UI("UI"); +LLFastTimer::DeclareTimer FTM_RENDER_WATER("Water"); +LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY("Windlight Sky"); +LLFastTimer::DeclareTimer FTM_RENDER_ALPHA("Alpha Objects"); +LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS("Avatars"); +LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump"); +LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright"); +LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow"); +LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update"); +LLFastTimer::DeclareTimer FTM_POOLRENDER("RenderPool"); +LLFastTimer::DeclareTimer FTM_POOLS("Pools"); +LLFastTimer::DeclareTimer FTM_RENDER_BLOOM_FBO("First FBO"); +LLFastTimer::DeclareTimer FTM_STATESORT("Sort Draw State"); +LLFastTimer::DeclareTimer FTM_PIPELINE("Pipeline"); +LLFastTimer::DeclareTimer FTM_CLIENT_COPY("Client Copy"); + +static LLFastTimer::DeclareTimer FTM_STATESORT_DRAWABLE("Sort Drawables"); +static LLFastTimer::DeclareTimer FTM_STATESORT_POSTSORT("Post Sort"); + //---------------------------------------- std::string gPoolNames[] = { @@ -973,7 +1000,7 @@ void LLPipeline::allocDrawable(LLViewerObject *vobj) void LLPipeline::unlinkDrawable(LLDrawable *drawable) { - LLFastTimer t(LLFastTimer::FTM_PIPELINE); + LLFastTimer t(FTM_PIPELINE); assertInitialized(); @@ -1035,7 +1062,7 @@ U32 LLPipeline::addObject(LLViewerObject *vobj) void LLPipeline::createObjects(F32 max_dtime) { - LLFastTimer ftm(LLFastTimer::FTM_GEO_UPDATE); + LLFastTimer ftm(FTM_GEO_UPDATE); LLMemType mt(LLMemType::MTYPE_PIPELINE_CREATE_OBJECTS); LLTimer update_timer; @@ -1201,9 +1228,12 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) } } +static LLFastTimer::DeclareTimer FTM_OCTREE_BALANCE("Balance Octree"); +static LLFastTimer::DeclareTimer FTM_UPDATE_MOVE("Update Move"); + void LLPipeline::updateMove() { - LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE); + LLFastTimer t(FTM_UPDATE_MOVE); LLMemType mt_um(LLMemType::MTYPE_PIPELINE_UPDATE_MOVE); if (gSavedSettings.getBOOL("FreezeTime")) @@ -1249,7 +1279,7 @@ void LLPipeline::updateMove() //balance octrees { - LLFastTimer ot(LLFastTimer::FTM_OCTREE_BALANCE); + LLFastTimer ot(FTM_OCTREE_BALANCE); for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -1354,10 +1384,11 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& return res; } +static LLFastTimer::DeclareTimer FTM_CULL("Object Culling"); void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip) { - LLFastTimer t(LLFastTimer::FTM_CULL); + LLFastTimer t(FTM_CULL); LLMemType mt_uc(LLMemType::MTYPE_PIPELINE_UPDATE_CULL); grabReferences(result); @@ -1572,7 +1603,7 @@ void LLPipeline::updateGeom(F32 max_dtime) LLMemType mt(LLMemType::MTYPE_PIPELINE_UPDATE_GEOM); LLPointer<LLDrawable> drawablep; - LLFastTimer t(LLFastTimer::FTM_GEO_UPDATE); + LLFastTimer t(FTM_GEO_UPDATE); assertInitialized(); @@ -1840,6 +1871,8 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f } } +static LLFastTimer::DeclareTimer FTM_RESET_DRAWORDER("Reset Draw Order"); + void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) { const U32 face_mask = (1 << LLPipeline::RENDER_TYPE_AVATAR) | @@ -1852,11 +1885,11 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) if (mRenderTypeMask & face_mask) { //clear faces from face pools - LLFastTimer t(LLFastTimer::FTM_RESET_DRAWORDER); + LLFastTimer t(FTM_RESET_DRAWORDER); gPipeline.resetDrawOrders(); } - LLFastTimer ftm(LLFastTimer::FTM_STATESORT); + LLFastTimer ftm(FTM_STATESORT); LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT); //LLVertexBuffer::unbind(); @@ -1912,7 +1945,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } { - LLFastTimer ftm(LLFastTimer::FTM_STATESORT_DRAWABLE); + LLFastTimer ftm(FTM_STATESORT_DRAWABLE); for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) { @@ -1925,7 +1958,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } { - LLFastTimer ftm(LLFastTimer::FTM_CLIENT_COPY); + LLFastTimer ftm(FTM_CLIENT_COPY); LLVertexBuffer::clientCopy(); } @@ -2188,7 +2221,7 @@ void renderSoundHighlights(LLDrawable* drawablep) void LLPipeline::postSort(LLCamera& camera) { LLMemType mt(LLMemType::MTYPE_PIPELINE_POST_SORT); - LLFastTimer ftm(LLFastTimer::FTM_STATESORT_POSTSORT); + LLFastTimer ftm(FTM_STATESORT_POSTSORT); assertInitialized(); @@ -2382,7 +2415,7 @@ void LLPipeline::postSort(LLCamera& camera) void render_hud_elements() { LLMemType mt_rhe(LLMemType::MTYPE_PIPELINE_RENDER_HUD_ELS); - LLFastTimer t(LLFastTimer::FTM_RENDER_UI); + LLFastTimer t(FTM_RENDER_UI); gPipeline.disableLights(); LLGLDisable fog(GL_FOG); @@ -2495,7 +2528,7 @@ void LLPipeline::renderHighlights() void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) { LLMemType mt(LLMemType::MTYPE_PIPELINE_RENDER_GEOM); - LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY); + LLFastTimer t(FTM_RENDER_GEOMETRY); assertInitialized(); @@ -2594,7 +2627,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) } else { - LLFastTimer t(LLFastTimer::FTM_POOLS); + LLFastTimer t(FTM_POOLS); // HACK: don't calculate local lights if we're rendering the HUD! // Removing this check will cause bad flickering when there are @@ -2626,7 +2659,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) pool_set_t::iterator iter2 = iter1; if (hasRenderType(poolp->getType()) && poolp->getNumPasses() > 0) { - LLFastTimer t(LLFastTimer::FTM_POOLRENDER); + LLFastTimer t(FTM_POOLRENDER); gGLLastMatrix = NULL; glLoadMatrixd(gGLModelView); @@ -2760,9 +2793,9 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); LLMemType mt_rgd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED); - LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY); + LLFastTimer t(FTM_RENDER_GEOMETRY); - LLFastTimer t2(LLFastTimer::FTM_POOLS); + LLFastTimer t2(FTM_POOLS); LLGLEnable cull(GL_CULL_FACE); @@ -2804,7 +2837,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) pool_set_t::iterator iter2 = iter1; if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) { - LLFastTimer t(LLFastTimer::FTM_POOLRENDER); + LLFastTimer t(FTM_POOLRENDER); gGLLastMatrix = NULL; glLoadMatrixd(gGLModelView); @@ -2862,7 +2895,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) void LLPipeline::renderGeomPostDeferred(LLCamera& camera) { LLMemType mt_rgpd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_POST_DEF); - LLFastTimer t(LLFastTimer::FTM_POOLS); + LLFastTimer t(FTM_POOLS); U32 cur_type = 0; LLGLEnable cull(GL_CULL_FACE); @@ -2895,7 +2928,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) pool_set_t::iterator iter2 = iter1; if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0) { - LLFastTimer t(LLFastTimer::FTM_POOLRENDER); + LLFastTimer t(FTM_POOLRENDER); gGLLastMatrix = NULL; glLoadMatrixd(gGLModelView); @@ -4979,6 +5012,7 @@ void LLPipeline::bindScreenToTexture() } +static LLFastTimer::DeclareTimer FTM_RENDER_BLOOM("Bloom"); void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) { LLMemType mt_ru(LLMemType::MTYPE_PIPELINE_RENDER_BLOOM); @@ -5012,7 +5046,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.setColorMask(true, true); - LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM); + LLFastTimer ftm(FTM_RENDER_BLOOM); gGL.color4f(1,1,1,1); LLGLDepthTest depth(GL_FALSE); LLGLDisable blend(GL_BLEND); @@ -5087,7 +5121,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) { { - LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO); + LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); mGlow[2].bindTarget(); mGlow[2].clear(); } @@ -5159,7 +5193,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); { - LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO); + LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); mGlow[i%2].bindTarget(); mGlow[i%2].clear(); } @@ -5201,7 +5235,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) if (LLRenderTarget::sUseFBO) { - LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO); + LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } @@ -6095,6 +6129,10 @@ glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max) return ret; } +static LLFastTimer::DeclareTimer FTM_SHADOW_RENDER("Render Shadows"); +static LLFastTimer::DeclareTimer FTM_SHADOW_ALPHA("Alpha Shadow"); +static LLFastTimer::DeclareTimer FTM_SHADOW_SIMPLE("Simple Shadow"); + void LLPipeline::generateSunShadow(LLCamera& camera) { @@ -6343,7 +6381,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadowCamera[j+4] = shadow_cam; } - LLFastTimer t(LLFastTimer::FTM_SHADOW_RENDER); + LLFastTimer t(FTM_SHADOW_RENDER); stop_glerror(); @@ -6381,7 +6419,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) gDeferredShadowProgram.bind(); { - LLFastTimer ftm(LLFastTimer::FTM_SHADOW_SIMPLE); + LLFastTimer ftm(FTM_SHADOW_SIMPLE); LLGLDisable test(GL_ALPHA_TEST); gGL.getTexUnit(0)->disable(); for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) @@ -6392,7 +6430,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) } { - LLFastTimer ftm(LLFastTimer::FTM_SHADOW_ALPHA); + LLFastTimer ftm(FTM_SHADOW_ALPHA); LLGLEnable test(GL_ALPHA_TEST); gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f); renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index fc02e7dd8826f72b4f3456cce4e1dced42b0b622..8f6867aa01240b950f010bb0ce9849e43ee30e9a 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -78,6 +78,27 @@ glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar); glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up); +extern LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY; +extern LLFastTimer::DeclareTimer FTM_RENDER_GRASS; +extern LLFastTimer::DeclareTimer FTM_RENDER_INVISIBLE; +extern LLFastTimer::DeclareTimer FTM_RENDER_OCCLUSION; +extern LLFastTimer::DeclareTimer FTM_RENDER_SHINY; +extern LLFastTimer::DeclareTimer FTM_RENDER_SIMPLE; +extern LLFastTimer::DeclareTimer FTM_RENDER_TERRAIN; +extern LLFastTimer::DeclareTimer FTM_RENDER_TREES; +extern LLFastTimer::DeclareTimer FTM_RENDER_UI; +extern LLFastTimer::DeclareTimer FTM_RENDER_WATER; +extern LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY; +extern LLFastTimer::DeclareTimer FTM_RENDER_ALPHA; +extern LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS; +extern LLFastTimer::DeclareTimer FTM_RENDER_BUMP; +extern LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT; +extern LLFastTimer::DeclareTimer FTM_RENDER_GLOW; +extern LLFastTimer::DeclareTimer FTM_STATESORT; +extern LLFastTimer::DeclareTimer FTM_PIPELINE; +extern LLFastTimer::DeclareTimer FTM_CLIENT_COPY; + + class LLPipeline { public: diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png index a4060e5e376bec6a202203df50ed98d96782b506..e27dbe2cadc5f32d71829fa49a2d9fe3addda558 100644 Binary files a/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png and b/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png differ diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png index 9c2815ebba05f6f4960f6370cf0dbf7e7cd26240..82d044d81745ad3f82cb4a65cf016ae77d0f6a68 100644 Binary files a/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png and b/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png differ diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png index 377b707529ff04da778b4aa7fae2002c349bb5c3..7909d54f2b575d91ecb5e3005a54fdd0618d585e 100644 Binary files a/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png and b/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png differ diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png index a69a729bd4f11b1ede6ba08d8c109dd251d0025e..6670667022ad09a9b0f188733d5c633a358610e0 100644 Binary files a/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png and b/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png index fb59f2e61e4f3aec4726495a7dfaab3007408744..5dd0852a7255ce0ce036d6e73ed7b0ad0427975d 100644 Binary files a/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png and b/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Close_Press.png b/indra/newview/skins/default/textures/windows/Icon_Close_Press.png index 7177c803b0f60b292774405bafd5f2f02a8ba95d..ea547fca6f0001ae127ecd0ddbe2e5a6534efa5e 100644 Binary files a/indra/newview/skins/default/textures/windows/Icon_Close_Press.png and b/indra/newview/skins/default/textures/windows/Icon_Close_Press.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png index cadd6bc8ce1f67bbe74257d27d8afb1013662c78..4207ba68e558e2e9446df8ab84000d5f0f1f479f 100644 Binary files a/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png and b/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png b/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png index 08f8cfc3d43a9d3541a1cb23494d4c82c4a5d5f4..2d0947578301c83e248671cf1d339fb34b50f966 100644 Binary files a/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png and b/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png index d790cf57ef28942d2cc5cdbb2fd29068405e4402..9a71d16a3fb927e5f7be3ee64d49830743975b69 100644 Binary files a/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png and b/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png differ diff --git a/indra/newview/skins/default/textures/windows/Icon_Undock_Press.png b/indra/newview/skins/default/textures/windows/Icon_Undock_Press.png index fdae4b75f6226527f33498c49b66758a045a0af7..3ab8c3666af63e3079401cb4166408039429675a 100644 Binary files a/indra/newview/skins/default/textures/windows/Icon_Undock_Press.png and b/indra/newview/skins/default/textures/windows/Icon_Undock_Press.png differ diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml index eedc5884496d4470135a0930ff63ce1af9221ce0..633fff079b8e221558cc5f9aee1190cea7086b64 100644 --- a/indra/newview/skins/default/xui/da/notifications.xml +++ b/indra/newview/skins/default/xui/da/notifications.xml @@ -1,15 +1,14 @@ -<?xml version="1.0" ?><notifications> - - <global name="skipnexttime"> - +<?xml version="1.0" encoding="utf-8"?> +<notifications> + <global name="skipnexttime"> Vis ikke dette igen - </global> - - <global name="alwayschoose"> - + </global> + <global name="alwayschoose"> Vælg altid dette - </global> - + </global> + <global name="implicitclosebutton"> + Luk + </global> <template name="okbutton"> <form> <button @@ -74,421 +73,438 @@ text="$canceltext"/> </form> </template> + <notification functor="GenericAcknowledge" label="Ukendt advarsels-besked" name="MissingAlert"> + Din version af Second Life kan ikke vise den advarselsbesked den modtog. - <notification - functor="GenericAcknowledge" - - name="MissingAlert" - > -'[_NAME]' mangler fra notifications.xml. - <usetemplate - name="okbutton" - yestext="OK"/> - </notification> - - <notification - - name="FloaterNotFound" - > -Floater error: Kunne ikke finde følgende kontrol: +Fejl detaljer: Advarslen '[_NAME]' blev ikke fundet i notifications.xml. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="FloaterNotFound"> + Floater error: Kunne ikke finde følgende kontrol: [CONTROLS] + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TutorialNotFound"> + Der er i øjeblikket ingen tilgængelig guide. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="GenericAlert"> + [MESSAGE] + </notification> + <notification name="GenericAlertYesCancel"> + [MESSAGE] + <usetemplate name="okcancelbuttons" notext="Annullér" yestext="Ja"/> + </notification> + <notification name="BadInstallation"> + Der opstod en fejl ved opdatering af Second Life. Hent venligst den nyeste version fra secondlife.com. <usetemplate name="okbutton" yestext="OK"/> - </notification> - - <notification - - name="TutorialNotFound" - > -Der er i øjeblikket ingen tilgængelig guide. - <usetemplate + </notification> + <notification name="LoginFailedNoNetwork"> + Netværksfejl: Kunne ikke oprette forbindelse. +'[DIAGNOSTIC]' +Check venligst din netværksforbindelse. + <usetemplate name="okbutton" yestext="OK"/> - </notification> - - <notification - - name="GenericAlert" - > -[MESSAGE] - </notification> - - <notification - - name="GenericAlertYesCancel" - > -[MESSAGE] - <usetemplate - name="okcancelbuttons" - notext="Annullér" - yestext="Ja"/> - </notification> - - <notification - - name="WearableSave" - > -Gem ændringer til nuværende tøj/krops del? - <usetemplate - canceltext="Annullér" - name="yesnocancelbuttons" - notext="Gem ikke" - yestext="Gem"/> - </notification> - - <notification - - name="CompileQueueSaveText" - > -Der var problemer med upload af teksten til et script af følgende Ã¥rsager: [REASON]. Prøv igen senere. - </notification> - - <notification - - name="CompileQueueSaveBytecode" - > -Der var problemer med at uploade den kompileret script af følgende Ã¥rsager: [REASON]. Prøv igen senere. - </notification> - - <notification - - name="WriteAnimationFail" - > -Der var et problem med skrivning af animations data. Prøv igen senere. - </notification> - - <notification - - name="UploadAuctionSnapshotFail" - > -Der var problemer med at uploade billedet til auktionen af følgende Ã¥rsager: [REASON] - </notification> - - <notification - - name="UnableToViewContentsMoreThanOne" - > -Ude af stand til at se indholdet af mere end ét element ad gangen. + </notification> + <notification name="MessageTemplateNotFound"> + Besked template [PATH] kunne ikke findes. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + <notification name="WearableSave"> + Gem ændringer til nuværende tøj/krops del? + <usetemplate canceltext="Annullér" name="yesnocancelbuttons" notext="Gem ikke" yestext="Gem"/> + </notification> + <notification name="CompileQueueSaveText"> + Der var problemer med upload af teksten til et script af følgende Ã¥rsager: [REASON]. Prøv igen senere. + </notification> + <notification name="CompileQueueSaveBytecode"> + Der var problemer med at uploade den kompileret script af følgende Ã¥rsager: [REASON]. Prøv igen senere. + </notification> + <notification name="WriteAnimationFail"> + Der var et problem med skrivning af animations data. Prøv igen senere. + </notification> + <notification name="UploadAuctionSnapshotFail"> + Der var problemer med at uploade billedet til auktionen af følgende Ã¥rsager: [REASON] + </notification> + <notification name="UnableToViewContentsMoreThanOne"> + Ude af stand til at se indholdet af mere end ét element ad gangen. Vælg kun en genstand, og prøv igen. - </notification> - - <notification - - name="SaveClothingBodyChanges" - > -Gem alle ændringer til tøj/krops dele? - <usetemplate - canceltext="Annullér" - name="yesnocancelbuttons" - notext="Gem Ikke" - yestext="Gem Alt"/> - </notification> - - <notification - - name="GrantModifyRights" - > -At give redigerings rettigheder til en anden beboer, giver dem mulighed for at ændre, slette eller tage alle genstande, du mÃ¥tte have i verden. Vær meget forsigtig nÃ¥r uddeler denne tilladelse. + </notification> + <notification name="SaveClothingBodyChanges"> + Gem alle ændringer til tøj/krops dele? + <usetemplate canceltext="Annullér" name="yesnocancelbuttons" notext="Gem Ikke" yestext="Gem Alt"/> + </notification> + <notification name="GrantModifyRights"> + At give redigerings rettigheder til en anden beboer, giver dem mulighed for at ændre, slette eller tage alle genstande, du mÃ¥tte have i verden. Vær meget forsigtig nÃ¥r uddeler denne tilladelse. Ønsker du at ændre rettigheder for [FIRST_NAME] [LAST_NAME]? - <usetemplate - name="okcancelbuttons" - notext="Nej" - yestext="Ja"/> - </notification> - - <notification - - name="GrantModifyRightsMultiple" - > -At give redigerings rettigheder til en anden beboer, giver dem mulighed for at ændre, slette eller tage alle genstande, du mÃ¥tte have i verden. Vær meget forsigtig nÃ¥r uddeler denne tilladelse. + <usetemplate name="okcancelbuttons" notext="Nej" yestext="Ja"/> + </notification> + <notification name="GrantModifyRightsMultiple"> + At give redigerings rettigheder til en anden beboer, giver dem mulighed for at ændre, slette eller tage alle genstande, du mÃ¥tte have i verden. Vær meget forsigtig nÃ¥r uddeler denne tilladelse. Ønsker du at ændre rettigheder for de valgte beboere? - <usetemplate - name="okcancelbuttons" - notext="Nej" - yestext="Ja"/> - </notification> - - <notification - - name="RevokeModifyRights" - > -Vil du tilbagekalde rettighederne for [FIRST_NAME] [LAST_NAME]? - <usetemplate - name="okcancelbuttons" - notext="Nej" - yestext="Ja"/> - </notification> - - <notification - - name="RevokeModifyRightsMultiple" - > -Vil du tilbagekalde rettighederne for de valgte beboere? - <usetemplate - name="okcancelbuttons" - notext="Nej" - yestext="Ja"/> - </notification> - - <notification - - name="UnableToCreateGroup" - > -Kunne ikke oprette gruppe. + <usetemplate name="okcancelbuttons" notext="Nej" yestext="Ja"/> + </notification> + <notification name="RevokeModifyRights"> + Vil du tilbagekalde rettighederne for [FIRST_NAME] [LAST_NAME]? + <usetemplate name="okcancelbuttons" notext="Nej" yestext="Ja"/> + </notification> + <notification name="RevokeModifyRightsMultiple"> + Vil du tilbagekalde rettighederne for de valgte beboere? + <usetemplate name="okcancelbuttons" notext="Nej" yestext="Ja"/> + </notification> + <notification name="UnableToCreateGroup"> + Kunne ikke oprette gruppe. [MESSAGE] - <usetemplate - name="okbutton" - yestext="OK"/> - </notification> - - <notification - - name="PanelGroupApply" - > -[NEEDS_APPLY_MESSAGE] + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="PanelGroupApply"> + [NEEDS_APPLY_MESSAGE] [WANT_APPLY_MESSAGE] - <usetemplate - canceltext="Annullér" - name="yesnocancelbuttons" - notext="Ignorer Ændringer" - yestext="Godkend Ændringer"/> - </notification> - - <notification - - name="MustSpecifyGroupNoticeSubject" - > -Du skal angive et emne for at sende en gruppe besked. - <usetemplate - name="okbutton" - yestext="OK"/> - </notification> - - <notification - - name="AddGroupOwnerWarning" - > -Du er ved at tilføje medlemmer til rollen som [ROLE_NAME]. + <usetemplate canceltext="Annullér" name="yesnocancelbuttons" notext="Ignorer Ændringer" yestext="Godkend Ændringer"/> + </notification> + <notification name="MustSpecifyGroupNoticeSubject"> + Du skal angive et emne for at sende en gruppe besked. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="AddGroupOwnerWarning"> + Du er ved at tilføje medlemmer til rollen som [ROLE_NAME]. Medlemmer ikke kan fjernes fra denne rolle. Medlemmerne skal fratræde sin rolle selv. Er du sikker pÃ¥ du vil fortsætte? - <usetemplate - ignoretext="NÃ¥r du tilføjer medlemmer til ejer rollen" - name="okcancelignore" - notext="Nej" - yestext="Ja"/> - </notification> - - <notification - - name="AssignDangerousActionWarning" - > -Du er ved at tilføje muligheden for '[ACTION_NAME]' til + <usetemplate ignoretext="NÃ¥r du tilføjer medlemmer til ejer rollen" name="okcancelignore" notext="Nej" yestext="Ja"/> + </notification> + <notification name="AssignDangerousActionWarning"> + Du er ved at tilføje muligheden for '[ACTION_NAME]' til rollen '[ROLE_NAME]'. *ADVARSEL* Ethvert medlem i en rolle med denne evne kan tildele sig selv -- og et andet medlem - roller med flere beføjelser, end de har i øjeblikket, potentielt kan de ophøje sig selv til nær-Ejer magt. Være sikker pÃ¥, at du ved, hvad du laver, før tildeling af denne evne. Add this Ability to '[ROLE_NAME]'? + <usetemplate name="okcancelbuttons" notext="Nej" yestext="Ja"/> + </notification> + <notification name="ClickSoundHelpLand"> + Media og musik kan kun ses og høres indenfor parcellen. Lyd og stemme valg muligheder kan begrænses til parcellen eller de kan høres af beboere udenfor parcellen, afhængigt af deres indholdsrating. GÃ¥ til 'Knowledge Base' for at lære hvordan disse valg opsættes. + <url name="url"> + https://support.secondlife.com/ics/support/default.asp?deptID=4417&task=knowledge&questionID=5046 + </url> <usetemplate name="okcancelbuttons" - notext="Nej" - yestext="Ja"/> - </notification> - - <notification - - name="ClickPublishHelpAvatar" - > -Hvis du vælger "Vis i Søgning" Vises: + yestext="GÃ¥ til 'Knowledge Base'" + notext="Luk" /> + </notification> + <notification name="ClickSearchHelpAll"> + Søgeresultater er organiseret baseret pÃ¥ den fane du stÃ¥r pÃ¥, din indholdsrating, den valgte kategori og andre faktorer. for yderligere detaljer se i 'Knowledge Base'. + <url name="url"> + https://support.secondlife.com/ics/support/default.asp?deptID=4417&task=knowledge&questionID=4722 + </url> + <usetemplate + name="okcancelbuttons" + yestext="GÃ¥ til 'Knowledge Base'" + notext="Luk" /> + </notification> + <notification name="ClickPublishHelpAvatar"> + Hvis du vælger "Vis i Søgning" Vises: - Din profil i søgeresultater - Et link til din profile i de offentlige gruppe sider - </notification> - - <notification - - name="ClickWebProfileHelpAvatar" - > -Hvis en beboer har en hjemmeside adresse kan du: + </notification> + <notification name="ClickUploadHelpPermissions"> + Dinne standard rettigheder virker muligvis ikke i ældre regioner. + </notification> + <notification name="ClickWebProfileHelpAvatar"> + Hvis en beboer har en hjemmeside adresse kan du: * Klikke 'Load' for at side deres side her. * Klikke Load > 'I ekstern browser' for at se siden i din standard browser. * Klikke Load > 'Hjemme URL' for at returnere til denne beboers side hvis du har navigeret væk. NÃ¥r du ser din egen profil, kan du skrive hvilken som helst adresse og klikke ok for at fÃ¥ den vist i din egen profil. Andre beboere kan besøge den adresse du har sat, nÃ¥r de besøger din profil. - </notification> - - <notification - - name="JoinGroupCannotAfford" - > -Tilmelding til denne gruppe koster L$[COST]. + </notification> + <notification name="JoinGroupCannotAfford"> + Tilmelding til denne gruppe koster L$[COST]. Du har ikke nok L$ til denne tilmelding. - </notification> - - <notification - - name="PromptMissingSubjMsg" - > -E-mail dette billede med standard emne eller besked? - <usetemplate - name="okcancelbuttons" - notext="Annullér" - yestext="OK"/> - </notification> - - <notification - - name="ErrorUploadingPostcard" - > -Der var et problem med at sende billedet pÃ¥ grund af følgende: [REASON] - </notification> - - <notification - - name="MustHaveAccountToLogIn" - > -Ups! Noget var tomt. + </notification> + <notification name="PromptMissingSubjMsg"> + E-mail dette billede med standard emne eller besked? + <usetemplate name="okcancelbuttons" notext="Annullér" yestext="OK"/> + </notification> + <notification name="ErrorUploadingPostcard"> + Der var et problem med at sende billedet pÃ¥ grund af følgende: [REASON] + </notification> + <notification name="MustHaveAccountToLogIn"> + Ups! Noget var tomt. Du skal skrive bÃ¥de fornavn og efternavn pÃ¥ din figur. Du har brug for en konto for at logge ind i [SECOND_LIFE]. Vil du oprette en nu? - <usetemplate - name="okcancelbuttons" - notext="Prøv igen" - yestext="Lav ny konto"/> - </notification> - - <notification - - name="ResetShowNextTimeDialogs" - > -Vil du gerne genaktivere alle disse popups, som du tidligere har bedt om ikke at fÃ¥ vist? - <usetemplate - name="okcancelbuttons" - notext="Annullér" - yestext="OK"/> - </notification> - - <notification - - name="SkipShowNextTimeDialogs" - > -Vil du deaktivere alle popups som kan undværes? - <usetemplate - name="okcancelbuttons" - notext="Annullér" - yestext="OK"/> - </notification> - - <notification - - name="ChangeSkin" - > -Det nye udseende vil vises efter du har genstartet [SECOND_LIFE]. - </notification> - - <notification - - name="UnsupportedHardware" - > - <form name="form"> - <ignore name="ignore" - text="Ved opdagelse af ikke supporteret hardware"/> - </form> - </notification> - - <notification - - name="UnknownGPU" - > - <form name="form"> - <ignore name="ignore" - text="Ved opdagelse af et ukendt grafikkort"/> - </form> - </notification> - - <notification - - name="CannotGiveCategory" - > -Du har ikke tilladelse til at videreføre den valgte mappe. - </notification> - - <notification - - name="CannotBuyLandNoRegion" - > -Ikke i stand til at købe land: + <usetemplate name="okcancelbuttons" notext="Prøv igen" yestext="Lav ny konto"/> + </notification> + <notification name="ResetShowNextTimeDialogs"> + Vil du gerne genaktivere alle disse popups, som du tidligere har bedt om ikke at fÃ¥ vist? + <usetemplate name="okcancelbuttons" notext="Annullér" yestext="OK"/> + </notification> + <notification name="SkipShowNextTimeDialogs"> + Vil du deaktivere alle popups som kan undværes? + <usetemplate name="okcancelbuttons" notext="Annullér" yestext="OK"/> + </notification> + <notification name="ChangeSkin"> + Det nye udseende vil vises efter du har genstartet [SECOND_LIFE]. + </notification> + <notification name="UnsupportedHardware"/> + <notification name="UnknownGPU"> + <form name="form"> + <ignore name="ignore" text="Ved opdagelse af et ukendt grafikkort"/> + </form> + </notification> + + <notification name="invalid_tport"> +Der er problemer med at hÃ¥ndtere din teleport. Det kan være nødvendigt at logge ud og ind for at kunne skifte teleportere. +Hvis du bliver ved med at have problemet kan du checke teknisk support pÃ¥: +www.secondlife.com/support + </notification> + <notification name="invalid_region_handoff"> +Problem registreret i forbindelse med skift til ny region. Det kan være nødvendigt at logge ud og ind for at kunne skifte regioner. +Hvis du bliver ved med at have problemet kan du checke teknisk support pÃ¥: +www.secondlife.com/support + </notification> + <notification name="blocked_tport"> +Beklager, teleport er blokeret lige nu. Prøv igen senere. +Hvis du stadig ikke kan teleporte, prøv venligst at logge ud og ligge ind for at løse dette problem. + </notification> + <notification name="nolandmark_tport"> +Beklager, systemet kunne ikke finde landmærke destinationen. + </notification> + <notification name="timeout_tport"> +Beklager, systemet kunne ikke fuldføre teleport forbindelse. +Prøv igen om lidt. + </notification> + <notification name="noaccess_tport"> +Beklager, du har ikke adgang til denne teleport destination. + </notification> + <notification name="missing_attach_tport"> +Dine vedhæng er ikke ankommet endnu. Prøv at vente lidt endnu eller log ud og ind igen før du prøver at teleporte igen. + </notification> + <notification name="too_many_uploads_tport"> +Tekniske problemer hindrer at din teleport kan gennemføres. +Prøv venligst igen om lidt eller vælg et mindre travlt omrÃ¥de. + </notification> + <notification name="expired_tport"> +Beklager, men systemet kunne ikke fuldføre din teleport i rimelig tid. Prøv venligst igen om lidt. + </notification> + <notification name="expired_region_handoff"> +Beklager, men systemet kunne ikke fuldføre skift til anden region i rimelig tid. Prøv venligst igen om lidt. + </notification> + <notification name="no_host"> +Ikke muligt at fine teleport destination. Destinationen kan være midlertidig utilgængelig eller findes ikke mere. +Prøv evt. igen om lidt. + </notification> + <notification name="no_inventory_host"> +Beholdningssystemet er ikke tilgængelig lige nu. + </notification> + + <notification name="CannotGiveCategory"> + Du har ikke tilladelse til at videreføre den valgte mappe. + </notification> + <notification name="CannotEncodeFile"> + Kunne ikke 'forstÃ¥' filen: [FILE] + </notification> + <notification name="CannotBuyLandNoRegion"> + Ikke i stand til at købe land: Kan ikke finde region som dette land er i. - </notification> - - <notification - - name="YouHaveBeenLoggedOut" - > -Du er blevet logget ud af [SECOND_LIFE]: + </notification> + <notification name="ShowOwnersHelp"> + Vis ejere: +Farver pÃ¥ parceller viser ejer-type. + +Grøn = Dit land +Turkis = Din gruppes land +Rød = Ejet af andre +Gul = Til salg +Lilla = PÃ¥ auktion +GrÃ¥ = Offentligt ejet + </notification> + <notification name="YouHaveBeenLoggedOut"> + Du er blevet logget ud af [SECOND_LIFE]: [MESSAGE] Du kan stadig se eksiterende PB'er og chat ved at klikke'Se PB & Chat'. Ellers, klik 'Afslut' for at afslutte [SECOND_LIFE] nu. - <usetemplate - name="okcancelbuttons" - notext="Quit" - yestext="Se IM & Chat"/> - </notification> - - <notification - - label="Add Friend" - name="AddFriend" - > -Venner kan give tilladelse til at følge hinanden + <usetemplate name="okcancelbuttons" notext="Afslut" yestext="Se PB & Chat"/> + </notification> + <notification label="Tilføj ven" name="AddFriend"> + Venner kan give tilladelse til at følge hinanden pÃ¥ Verdenskortet eller modtage status opdateringer. Tilbyd venskab til [NAME]? - <usetemplate - name="okcancelbuttons" - notext="Annullér" - yestext="OK"/> - </notification> - - <notification - - label="Add Friend" - name="AddFriendWithMessage" - > -Venner kan give tilladelse til at følge hinanden + <usetemplate name="okcancelbuttons" notext="Annullér" yestext="OK"/> + </notification> + <notification label="Tilføj ven" name="AddFriendWithMessage"> + Venner kan give tilladelse til at følge hinanden pÃ¥ Verdenskortet eller modtage status opdateringer. Tilbyd venskab til [NAME]? - <form name="form"> - <input name="message" type="text"> -Vil du være min ven? - </input> + <form name="form"> + <input name="message" type="text"> + Vil du være min ven? + </input> + <button name="Offer" text="OK"/> + <button name="Cancel" text="Annullér"/> + </form> + </notification> + <notification name="NotEnoughCurrency"> + [NAME] L$ [PRICE] Du har ikke nok L$ til dette. + </notification> + <notification name="BuyOneObjectOnly"> + Ikke muligt at købe mere end et objekt ad gangen. Vælg kun ét objekt og prøv igen. + </notification> + <notification name="CannotStartAuctionAlreadyForSale"> + Du kan ikke starte en auktion pÃ¥ en parcel som allerede er sat til salg. Fjern 'til salg' muligheden hvis du ønsker at starte en auktion. + </notification> + <notification name="OfferTeleport"> + <form name="form"> + <input name="message" type="text"> + Mød mig i [REGION] + </input> + <button name="OK" text="OK"/> + <button name="Cancel" text="Annullér"/> + </form> + </notification> + <notification name="RegionEntryAccessBlocked"> + Du har ikke adgang til denne region pÃ¥ grund af din valgte indholdsrating. Dette kan skyldes manglende validering af din alder. + +Undersøg venligst om du har installeret den nyeste Second Life klient, og gÃ¥ til 'Knowledge Base' for yderligere detaljer om adgang til omrÃ¥der med denne indholdsrating. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + <notification name="RegionEntryAccessBlocked_KB"> + Du har ikke adgang til denne region pÃ¥ grund af din valgte indholdsrating. + +GÃ¥ til 'Knowledge Base' for mere information om indholdsratings. + <url name="url"> + https://support.secondlife.com/ics/support/default.asp?deptID=4417&task=knowledge&questionID=6010 + </url> + <usetemplate + name="okcancelignore" + yestext="GÃ¥ til 'Knowledge Base'" + notext="Luk" + ignoretext="NÃ¥r regionen er blokeret pÃ¥ grund af indholdsrating"/> + </notification> + <notification name="RegionEntryAccessBlocked_Notify"> + Du har ikke adgang til denne region pÃ¥ grund af din valgte indholdsrating. + </notification> + <notification name="RegionEntryAccessBlocked_Change"> + Du har ikke adgang til denne region pÃ¥ grund af din nuværende indholdsrating opsætning. + +Du kan vælge 'Indstillinger' for at hæve din indholdsrating nu og dermed fÃ¥ adgang. Du vil sÃ¥ fÃ¥ mulighed for at søge og fÃ¥ adgang til omrÃ¥der med indhold af typen [REGIONMATURITY]. Hvis du senere ønsker at skifte tilbage, kan du skifte tilbage i 'Indstillinger'. + <form name="form"> <button - - - name="Offer" - text="OK"/> + name="OK" + text="Ændre præferencer"/> <button - name="Cancel" - text="Annullér"/> + text="Luk"/> + <ignore name="ignore" text="NÃ¥r regionen er blokeret pÃ¥ grund af indholdsrating"/> </form> - </notification> + </notification> + <notification name="LandClaimAccessBlocked"> + Du kan ikke kræve dette land pÃ¥ grund af din nuværende indholdsrating indstillinge . Dette kan skyldes manglende validering af din alder. - <notification - - name="NotEnoughCurrency" - > -[NAME] L$ [PRICE] Du har ikke nok L$ til dette. - </notification> +Undersøg om du har den nyeste Second Life klient og gÃ¥ venligst til 'Knowledge Base' for yderligere detaljer om adgang til omrÃ¥der med denne indholdsrating. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + <notification name="LandClaimAccessBlocked_KB"> + Du kan ikke kræve dette land pÃ¥ grund af din nuværende indholdsrating indstilling.. + +GÃ¥ venligst til 'Knowledge Base' for yderligere information om indholdsrating. + <url name="url"> + https://support.secondlife.com/ics/support/default.asp?deptID=4417&task=knowledge&questionID=6010 + </url> + <usetemplate + name="okcancelignore" + yestext="GÃ¥ til 'Knowledge Base'" + notext="Luk" + ignoretext="NÃ¥r land ikke kan kræves pÃ¥ grund af indholdsrating"/> + </notification> + <notification name="LandClaimAccessBlocked_Notify"> + Du kan ikke kræve dette land pÃ¥ grund af din indholdsrating. + </notification> + <notification name="LandClaimAccessBlocked_Change"> + Du kan ikke kræve dette land pÃ¥ grund af din nuværende indholdsrating indstilling.. + +Du kan vælge 'Indstillinger' for at hæve din indholdsrating nu og dermed fÃ¥ adgang. Du vil sÃ¥ fÃ¥ mulighed for at søge og fÃ¥ adgang til omrÃ¥der med indhold af typen [REGIONMATURITY]. Hvis du senere ønsker at skifte tilbage, kan du skifte tilbage i 'Indstillinger'. + <usetemplate + name="okcancelignore" + yestext="Ændre præferencer" + notext="Luk" + ignoretext="NÃ¥r land ikke kan kræves pÃ¥ grund af indholdsrating"/> + </notification> + <notification name="LandBuyAccessBlocked"> + Du kan ikke købe dette land pÃ¥ grund af din nuværende indholdsrating indstillinge . Dette kan skyldes manglende validering af din alder. + +Undersøg om du har den nyeste Second Life klient og gÃ¥ venligst til 'Knowledge Base' for yderligere detaljer om adgang til omrÃ¥der med denne indholdsrating. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + <notification name="LandBuyAccessBlocked_KB"> + Du kan ikke købe dette land pÃ¥ grund af din nuværende indholdsrating. + +GÃ¥ til 'Knowledge Base' for yderligere detaljer om indholdsrating. + <url name="url"> + https://support.secondlife.com/ics/support/default.asp?deptID=4417&task=knowledge&questionID=6010 + </url> + <usetemplate + name="okcancelignore" + yestext="GÃ¥ til 'Knowledge Base'" + notext="Luk" + ignoretext="NÃ¥r land ikke kan købes pÃ¥ grund af indholdsrating"/> + </notification> + <notification name="LandBuyAccessBlocked_Notify"> + Du kan ikke købe dette land pÃ¥ grund af din nuværende indholdsrating indstilling. + </notification> + <notification name="LandBuyAccessBlocked_Change"> + Du kan ikke købe dette land pÃ¥ grund af din valgte inholdsrating. + +Du kan vælge 'Indstillinger' for at hæve din indholdsrating nu og dermed fÃ¥ adgang. Du vil sÃ¥ fÃ¥ mulighed for at søge og fÃ¥ adgang til omrÃ¥der med indhold af typen [REGIONMATURITY]. Hvis du senere ønsker at skifte tilbage, kan du skifte tilbage i 'Indstillinger'. + <usetemplate + name="okcancelignore" + yestext="Ændre præferencer" + notext="Luk" + ignoretext="NÃ¥r land ikke kan købes pÃ¥ grund af indholdsrating"/> + </notification> + <notification name="UnableToLoadNotecardAsset"> + Kunne ikke hente notecard indhold. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="SetClassifiedMature"> + Indeholder denne annonce 'Mature' indhold? + <usetemplate + canceltext="Annullér" + name="yesnocancelbuttons" + notext="Nej" + yestext="Ja"/> + </notification> + <notification name="SetGroupMature"> + Indeholder denne gruppe 'Mature' indhold? + <usetemplate + canceltext="Annullér" + name="yesnocancelbuttons" + notext="Nej" + yestext="Ja"/> + </notification> + <notification label="Indholdsrating" name="HelpRegionMaturity"> + Sætter indholdsrating for regionen, som den vises øverst pÃ¥ menu-bjælken i beboernes klient, og i tooltips pÃ¥ verdenskortet nÃ¥r cursoren placeres over denne region. Denne indstilling har ogsÃ¥ betydning for adgangen til regionen og for søgeresultater. Andre beboere mÃ¥ kun fÃ¥ adgang til regionen eller se regionen i søgeresultater hvis de har valgt samme eller højere indholdsrating i deres opsætning. - <notification - - name="HelpReportAbuseEmailLL" - > -Brug dette værktøj for at rapportere brud pÃ¥ de almindelige bestemmelser og fællesskabs Standarder. Se: +Det kan tage noget tid inden en ændring af indholdsrating er synligt pÃ¥ kortet. + </notification> + <notification name="HelpReportAbuseEmailLL"> + Brug dette værktøj for at rapportere brud pÃ¥ de almindelige bestemmelser og fællesskabs Standarder. Se: http://secondlife.com/corporate/tos.php http://secondlife.com/corporate/cs.php @@ -496,13 +512,9 @@ http://secondlife.com/corporate/cs.php Alle rapporterede brud pÃ¥ almindelige bestemmelser og fællesskabs Standarder bliver undersøgt og løst. Du kan følge løsningen pÃ¥ din anmeldselse pÃ¥: http://secondlife.com/support/incidentreport.php - </notification> - - <notification - - name="HelpReportAbuseContainsCopyright" - > -Dear Resident, + </notification> + <notification name="HelpReportAbuseContainsCopyright"> + Dear Resident, Du ser ud til at være ved at rapportere noget vedr. krænkelse af intellektuelle ejendomsrettigheder. Sørg for, at du rapporterer dette korrekt: @@ -515,1268 +527,659 @@ Hvis du stadig ønsker at fortsætte med misbrugs processen, luk da venligst det Mange tak, Linden Lab - </notification> - - <notification - - name="ConfirmClearCookies" - > -Er du sikker pÃ¥ du vil slette alle cookies? - </notification> - - <notification - - name="ChatterBoxSessionStartError" - > -Ikke i stand til at start chat med [RECIPIENT]. + </notification> + <notification name="ConfirmClearCookies"> + Er du sikker pÃ¥ du vil slette alle cookies? + </notification> + <notification name="NewSkyPreset"> + <form name="form"> + <input name="message" type="text"> + Ny forudindstilling + </input> + <button name="OK" text="OK"/> + <button name="Cancel" text="Annullér"/> + </form> + </notification> + <notification name="NewWaterPreset"> + <form name="form"> + <input name="message" type="text"> + Ny forudindstilling + </input> + <button name="OK" text="OK"/> + <button name="Cancel" text="Annullér"/> + </form> + </notification> + <notification name="ChatterBoxSessionStartError"> + Ikke i stand til at start chat med [RECIPIENT]. [REASON] - <usetemplate - name="okbutton" - yestext="OK"/> - </notification> - - <notification - - name="Cannot_Purchase_an_Attachment" - > -Ting kan ikke købes imens de er en del af tilbehør. - </notification> - - <notification - - name="NewWaterPreset" - > - <form name="form"> - <input name="message" type="text"> -Ny forudindstilling - </input> - <button - - - name="OK" - text="OK"/> - <button - - name="Cancel" - text="Annullér"/> - </form> - </notification> - - <notification - - name="NewSkyPreset" - > - <form name="form"> - <input name="message" type="text"> -Ny forudindstilling - </input> - <button - - - name="OK" - text="OK"/> - <button - - name="Cancel" - text="Annullér"/> - </form> - </notification> - - <notification - - name="OfferTeleport" - > - <form name="form"> - <input name="message" type="text"> -Mød mig i [REGION] - </input> - <button - - - name="OK" - text="OK"/> - <button - - name="Cancel" - text="Annullér"/> - </form> - </notification> - - <notification - - name="SystemMessageTip" - > + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="Cannot_Purchase_an_Attachment"> + Ting kan ikke købes imens de er en del af tilbehør. + </notification> + <notification name="SystemMessageTip"> + [MESSAGE] + </notification> + <notification name="Cancelled"> + Annulléret + </notification> + <notification name="CancelledSit"> + Annulléret sid + </notification> + <notification name="CancelledAttach"> + Annulléreret vedhæft + </notification> + <notification name="ReplacedMissingWearable"> + Erstattet manglende tøj/kropsdele med standard. + </notification> + <notification name="FriendOnline"> + [FIRST] [LAST] er Online + </notification> + <notification name="FriendOffline"> + [FIRST] [LAST] er Offline + </notification> + <notification name="AddSelfFriend"> + Du kan ikke tilføje dig selv som ven. + </notification> + <notification name="UploadingAuctionSnapshot"> + Uploader billeder fra verdenen og www... +(Tager omkring 5 minutter.) + </notification> + <notification name="UploadPayment"> + Du betalte L$[AMOUNT] for at uploade. + </notification> + <notification name="UploadWebSnapshotDone"> + Billeder fra www er uploadet. + </notification> + <notification name="UploadSnapshotDone"> + Billeder fra verdenen er uploadet + </notification> + <notification name="TerrainDownloaded"> + Terrain.raw downloadet + </notification> + <notification name="GestureMissing"> + Gestus [NAME] mangler i databasen. + </notification> + <notification name="UnableToLoadGesture"> + Ikke muligt at indlæse gestus [NAME]. +Prøv venligst igen. + </notification> + <notification name="LandmarkMissing"> + Landmærke mangler i databasen. + </notification> + <notification name="UnableToLoadLandmark"> + Ikke muligt at indlæse landmærke. Prøv venligst igen. + </notification> + <notification name="CapsKeyOn"> + Du har slÃ¥et store bogstaver til. +Da det vil have betydning nÃ¥r du indtaster kodeordet, vil du højest sandsynlig slÃ¥ dem fra. + </notification> + <notification name="NotecardMissing"> + Note mangler i databasen. + </notification> + <notification name="NotecardNoPermissions"> + Utilstrækkelige tilladelser til at se note. + </notification> + <notification name="RezItemNoPermissions"> + Utilstrækkelige tilladelser til at danne genstanden. + </notification> + <notification name="UnableToLoadNotecard"> + Ikke muligt at indlæse note. +Prøv venligst igen. + </notification> + <notification name="ScriptMissing"> + Script mangler i databasen. + </notification> + <notification name="ScriptNoPermissions"> + Utilstrækkelige tilladelser til at se script. + </notification> + <notification name="UnableToLoadScript"> + Ikke muligt at indlæse script. Prøv venligst igen. + </notification> + <notification name="IncompleteInventory"> + Det komplette indhold, du tilbyder, er ikke endnu tilgængelig lokalt. Prøv venligst at tilbyde tingene igen om lidt. + </notification> + <notification name="CannotModifyProtectedCategories"> + Du kan ikke ændre beskyttede kategorier. + </notification> + <notification name="CannotRemoveProtectedCategories"> + Du kan ikke fjerne beskyttede kategorier. + </notification> + <notification name="OfferedCard"> + Du har tilbudt et visitkort til [FIRST] [LAST] + </notification> + <notification name="UnableToBuyWhileDownloading"> + Ikke muligt at købe, imens genstandens data hentes. +Prøv venligst igen. + </notification> + <notification name="UnableToLinkWhileDownloading"> + Ikke muligt at lænke imens genstandens data hentes. +Prøv venligst igen. + </notification> + <notification name="CannotBuyObjectsFromDifferentOwners"> + Kan ikke købe genstande fra forskellige ejere pÃ¥ samme tid. +Prøv venligst at vælge en enkelt genstand. + </notification> + <notification name="ObjectNotForSale"> + Genstanden ser ikke ud til at være til salg. + </notification> + <notification name="EnteringGodMode"> + Starter gud-tilstand, niveau [LEVEL] + </notification> + <notification name="LeavingGodMode"> + Stopper gud-tilstand, niveau [LEVEL] + </notification> + <notification name="CopyFailed"> + Kopiering lykkedes ikke fordi du ikke har nok tilladelser til at kopiere + </notification> + <notification name="InventoryAccepted"> + [NAME] accepterede det du tilbød fra din beholdning. + </notification> + <notification name="InventoryDeclined"> + [NAME] afviste det du tilbød fra din beholdning. + </notification> + <notification name="ObjectMessage"> + [NAME]: [MESSAGE] + </notification> + <notification name="CallingCardAccepted"> + Dit visitkort blev accepteret. + </notification> + <notification name="CallingCardDeclined"> + Dit visitkort blev afvist. + </notification> + <notification name="TeleportToLandmark"> + Nu hvor du er nÃ¥et frem til hovedlandet, kan du teleportere til steder som '[NAME]' ved at klikke pÃ¥ Beholdning-knappen i nederste højre side af skærmen hvorefter du vælger Landmærke-mappen. +Dobbeltklik pÃ¥ landmærket og klik pÃ¥ Teleportér, for at rejse derhen. + </notification> + <notification name="TeleportToPerson"> + Nu hvor du har nÃ¥et frem til hovedlandet, kan du kontakte indbyggere som '[NAME]' ved at klikke pÃ¥ Beholdning-knappen i nederste højre side af skærmen, hvorefter du vælger Visitkort-mappen. +Dobbeltklik pÃ¥ kortet, klik pÃ¥ IM og skriv beskeden. + </notification> + <notification name="CantSelectLandFromMultipleRegions"> + Kan ikke vælge land pÃ¥ tværs af grænser. +Prøv at vælge mindre stykker land. + </notification> + <notification name="SearchWordBanned"> + Visse ord er fjernet fra din søge-sætning pÃ¥ grund af at disse strider mod de generelle 'Community Standards'. + </notification> + <notification name="NoContentToSearch"> + Vælg venligst mindst en indholdstype for at søge (PG, Mature, or Adult). + </notification> + <notification name="GroupVote"> + [NAME] har forslÃ¥et at stemme for: [MESSAGE] - </notification> - - <notification - - name="Cancelled" - > -Annulléret - </notification> + <form name="form"> + <button name="VoteNow" text="Stem nu"/> + <button name="Later" text="Senere"/> + </form> + </notification> + <notification name="SystemMessage"> + [MESSAGE] + </notification> + <notification name="EventNotification"> + Besked om begivenhed: - <notification - - name="CancelledSit" - > -Annulléret sid - </notification> +[NAME] +[DATE] + <form name="form"> + <button name="Teleport" text="Teleportér"/> + <button name="Description" text="Beskrivelse"/> + <button name="Cancel" text="Annullér"/> + </form> + </notification> + <notification name="TransferObjectsHighlighted"> + Alle genstande pÃ¥ denne grund, som vil blive overført til køberen af denne grund, er nu oplyst. - <notification - - name="CancelledAttach" - > -Annulléreret vedhæft - </notification> +* Træer og græs, der vil blive overført, er ikke fremhævet. + <form name="form"> + <button name="Done" text="Færdig"/> + </form> + </notification> + <notification name="DeactivatedGesturesTrigger"> + Deaktiverede bevægelser med samme udløser: [NAMES] + </notification> + <notification name="NoQuickTime"> + Apple's QuickTime ser ikke ud til at være installeret pÃ¥ computeren. +Hvis du vil se live transmitteret medie pÃ¥ grunde, der understøtter det, skal du gÃ¥ ind pÃ¥ QuickTime-siden (http://www.apple.dk/quicktime) og installere QuickTime afspilleren. + </notification> + <notification name="OwnedObjectsReturned"> + De genstande du ejer pÃ¥ det valgte stykke land er blevet returneret til din beholdning. + </notification> + <notification name="OtherObjectsReturned"> + Genstandene pÃ¥ det valgte stykke land der er ejet af [FIRST] [LAST] er blevet returneret til hans eller hendes beholdning. + </notification> + <notification name="OtherObjectsReturned2"> + Genstandene pÃ¥ det valgte stykke land der er ejet af beboeren '[NAME]' er blevet returneret til deres ejere. + </notification> + <notification name="GroupObjectsReturned"> + Genstandene pÃ¥ det valgte stykke land, delt med gruppen [GROUPNAME], er blevet returneret til deres ejeres beholdninger. +Genstande, som er dedikerede og som kan overføres, er blevet returneret til deres forrige ejere. +Genstande, der ikke kan overføres og som er dedikeret til gruppen, er blevet slettet. + </notification> + <notification name="UnOwnedObjectsReturned"> + Genstandene pÃ¥ det valgte stykke land, der IKKE er ejet af dig, er blevet returneret til deres ejere. + </notification> + <notification name="NotSafe"> + Dette land har sat skade til ('ikke sikker'). +Du kan komme til skade her. Hvis du dør, vil du blive teleporteret til din hjem-lokalitet. + </notification> + <notification name="NoFly"> + Dette land har slÃ¥et flyvning fra ('ingen flyvning'). +Du kan ikke flyve her. + </notification> + <notification name="PushRestricted"> + Dette land giver ikke mulighed for at 'skubbe' andre, med mindre du ejer landet. + </notification> + <notification name="NoVoice"> + Dette land har ikke mulighed for at bruge stemme. + </notification> + <notification name="NoBuild"> + Dette land giver ikke mulighed for at bygge ('byggeri forbudt'). +Du kan ikke skabe genstande her. + </notification> + <notification name="ScriptsStopped"> + En administrator har midlertidig stoppet scripts i denne region. + </notification> + <notification name="ScriptsNotRunning"> + Denne region kører ikke nogen scripts. + </notification> + <notification name="NoOutsideScripts"> + Dette land har eksterne scripts slÃ¥et fra +('ingen eksterne scripts'). +Ingen scripts vil køre pÃ¥ nær dem, som tilhører ejeren af landet. + </notification> + <notification name="ClaimPublicLand"> + Du kan kun gøre krav pÃ¥ offentlig land i den region, du befinder dig i. + </notification> + <notification name="RegionTPAccessBlocked"> + Du har ikke adgang til denne region pÃ¥ grund af din valgte indholdsrating. Dette kan skyldes manglende validering af din alder eller at du ikke benytter den nyeste Second Life klient. + +GÃ¥ venligst til 'Knowledge Base' for yderligere detaljer om adgang til omrÃ¥der med denne indholdsrating. + </notification> + <notification name="URBannedFromRegion"> + Du er blokeret i denne region. + </notification> + <notification name="NoTeenGridAccess"> + Du kan ikke tilslutte dig denne 'Teen' region. + </notification> + <notification name="NoHelpIslandTP"> + Du kan ikke teleportere tilbage til Help Island. +GÃ¥ til 'Help Island Puclic' for at prøve tutorial igen. + </notification> + <notification name="ImproperPaymentStatus"> + Du har ikke de rette betalingsoplysninger til at komme ind i denne region. + </notification> + <notification name="MustGetAgeRegion"> + Du skal være aldersgodkendt for at komme ind i denne region. + </notification> + <notification name="MustGetAgeParcel"> + Du skal være aldersgodkendt for at komme ind pÃ¥ denne parcel. + </notification> + <notification name="NoDestRegion"> + Destinations region ikke fundet. + </notification> + <notification name="NotAllowedInDest"> + Du har ikke adgang til denne destination. + </notification> + <notification name="RegionParcelBan"> + Kan ikke skifte til ny region via en blokeret parcel. Prøv en anden vej ind. + </notification> + <notification name="TelehubRedirect"> + Du er blevet omdirigeret til en telehub. + </notification> + <notification name="CouldntTPCloser"> + Kunne ikke teleportere nærmere til destination. + </notification> + <notification name="TPCancelled"> + Teleport afbrudt. + </notification> + <notification name="FullRegionTryAgain"> + Den region du prøver at komme ind i er fuld for øjeblikket. +Prøv igen om lidt. + </notification> + <notification name="GeneralFailure"> + Generel fejl. + </notification> + <notification name="RoutedWrongRegion"> + Du blev sendt til en forkert region. Prøv igen. + </notification> + <notification name="NoValidAgentID"> + Ikke en gyldig agent ID. + </notification> + <notification name="NoValidSession"> + Ikke noget gyldig sessions-ID + </notification> + <notification name="NoValidCircuit"> + Ingen gyldig kode for kredsløb. + </notification> + <notification name="NoValidTimestamp"> + Ikke et gyldigt klokkeslæt. + </notification> + <notification name="NoPendingConnection"> + Kunne ikke skabe fast forbindelse. + </notification> + <notification name="InternalUsherError"> + Der opstod en intern fejl ved teleportering til din teleport destination.. Der kan være generelle problemer med Second Life lige nu. + </notification> + <notification name="NoGoodTPDestination"> + Kunne ikke finde et egnet teleport sted i denne region. + </notification> + <notification name="InternalErrorRegionResolver"> + Der opstod en intern fejl ved beregning af globale koordinater for din teleport forespørgsel. Der kan være generelle problemer med Second Life lige nu. + </notification> + <notification name="NoValidLanding"> + Kunne ikke finde et gyldigt landingspunkt. + </notification> + <notification name="NoValidParcel"> + No valid parcel could be found. + </notification> + <notification name="ObjectGiveItem"> + En genstand med navnet [OBJECTFROMNAME], ejet af [FIRST] [LAST], har givet dig en/et [OBJECTTYPE] med navnet [OBJECTNAME]. + <form name="form"> + <button name="Keep" text="Behold"/> + <button name="Discard" text="Smid væk"/> + <button name="Mute" text="Blokér"/> + </form> + </notification> + <notification name="ObjectGiveItemUnknownUser"> + En genstand med navnet [OBJECTFROMNAME], ejet af (en ukendt bruger), har givet dig en/et [OBJECTTYPE] med navnet [OBJECTNAME]. + <form name="form"> + <button name="Keep" text="Behold"/> + <button name="Discard" text="Smid væk"/> + <button name="Mute" text="Blokér"/> + </form> + </notification> + <notification name="UserGiveItem"> + [NAME] har givet dig en/et [OBJECTTYPE] med navnet '[OBJECTNAME]'. + <form name="form"> + <button name="Keep" text="Behold"/> + <button name="Discard" text="Smid væk"/> + <button name="Mute" text="Blokér"/> + </form> + </notification> + <notification name="GodMessage"> + [NAME] +[MESSAGE] + </notification> + <notification name="JoinGroup"> + [MESSAGE] + <form name="form"> + <button name="Join" text="Indmeld"/> + <button name="Decline" text="Afvis"/> + <button name="Info" text="Information"/> + </form> + </notification> + <notification name="TeleportOffered"> + [NAME] har tilbudt at teleportere dig til hans eller hendes lokalitet: - <notification - - name="ReplacedMissingWearable" - > -Erstattet manglende tøj/kropsdele med standard. - </notification> +[MESSAGE] + <form name="form"> + <button name="Teleport" text="Teleportér"/> + <button name="Cancel" text="Annullér"/> + </form> + </notification> + <notification name="GotoURL"> + [MESSAGE] +[URL] + <form name="form"> + <button name="Later" text="Senere"/> + <button name="GoNow..." text="GÃ¥ nu..."/> + </form> + </notification> + <notification name="OfferFriendship"> + [NAME] tilbyder venskab. - <notification - - name="FriendOnline" - > -[FIRST] [LAST] er Online - </notification> +Som standard vil du kunne se andres onlinestatus. + <form name="form"> + <button name="Accept" text="Acceptér"/> + <button name="Decline" text="Afvis"/> + </form> + </notification> + <notification name="FriendshipAccepted"> + [NAME] accepterede dit tilbud om venskab. + </notification> + <notification name="FriendshipDeclined"> + [NAME] afviste dit tilbud om venskab. + </notification> + <notification name="OfferCallingCard"> + [FIRST] [LAST] tilbyder vedkommendes visitkort. +Dette vil tilføje et bogmærke i din beholdning, sÃ¥ du hurtigt kan sende en personlig besked (IM) til denne beboer. + <form name="form"> + <button name="Accept" text="Acceptér"/> + <button name="Decline" text="Afvis"/> + </form> + </notification> + <notification name="RegionRestartMinutes"> + Regionen genstarter om [MINUTES] minutter. +Hvis du bliver i denne region, vil du blive logget af. + </notification> + <notification name="RegionRestartSeconds"> + Regionen genstarter om [SECONDS] sekunder. +Hvis du bliver i denne region, vil du blive logget af. + </notification> + <notification name="LoadWebPage"> + Indlæs internetside [URL]? - <notification - - name="FriendOffline" - > -[FIRST] [LAST] er Offline - </notification> +[MESSAGE] - <notification - - name="AddSelfFriend" - > -Du kan ikke tilføje dig selv som ven. - </notification> +Fra genstand: [OBJECTNAME], ejer: [NAME]? + <form name="form"> + <button name="Gotopage" text="GÃ¥ til side"/> + <button name="Cancel" text="Afbryd"/> + </form> + </notification> + <notification name="FailedToFindWearableUnnamed"> + Det lykkedes ikke at finde [TYPE] i databasen. + </notification> + <notification name="FailedToFindWearable"> + Det lykkedes ikke at finde [TYPE] med navnet [DESC] i databasen. + </notification> + <notification name="InvalidWearable"> + Den genstand du prøver at tage pÃ¥ benytter funktioner som din klient ikke kan forstÃ¥. Opdatér din version af Second Life for at tage genstanden pÃ¥. + </notification> + <notification name="ScriptQuestion"> + '[OBJECTNAME]', en genstand, ejet af '[NAME]', vil gerne: + [QUESTIONS] +Er det iorden? + <form name="form"> + <button name="Yes" text="Ja"/> + <button name="No" text="Nej"/> + <button name="Mute" text="Blokér"/> + </form> + </notification> + <notification name="ScriptQuestionCaution"> + '[OBJECTNAME]', en genstand, ejet af '[NAME]', vil gerne: - <notification - - name="UploadingAuctionSnapshot" - > -Uploader billeder fra verdenen og www... -(Tager omkring 5 minutter.) - </notification> - - <notification - - name="UploadPayment" - > -Du betalte L$[AMOUNT] for at uploade. - </notification> - - <notification - - name="UploadWebSnapshotDone" - > -Billeder fra www er uploadet. - </notification> - - <notification - - name="UploadSnapshotDone" - > -Billeder fra verdenen er uploadet - </notification> - - <notification - - name="TerrainDownloaded" - > -Terrain.raw downloadet - </notification> - - <notification - - name="GestureMissing" - > -Gestus [NAME] mangler i databasen. - </notification> - - <notification - - name="UnableToLoadGesture" - > -Ikke muligt at indlæse gestus [NAME]. -Prøv venligst igen. - </notification> - - <notification - - name="LandmarkMissing" - > -Landmærke mangler i databasen. - </notification> - - <notification - - name="UnableToLoadLandmark" - > -Ikke muligt at indlæse landmærke. Prøv venligst igen. - </notification> - - <notification - - name="CapsKeyOn" - > -Du har slÃ¥et store bogstaver til. -Da det vil have betydning nÃ¥r du indtaster kodeordet, vil du højest sandsynlig slÃ¥ dem fra. - </notification> - - <notification - - name="NotecardMissing" - > -Note mangler i databasen. - </notification> - - <notification - - name="NotecardNoPermissions" - > -Utilstrækkelige tilladelser til at se note. - </notification> - - <notification - - name="RezItemNoPermissions" - > -Utilstrækkelige tilladelser til at danne genstanden. - </notification> - - <notification - - name="UnableToLoadNotecard" - > -Ikke muligt at indlæse note. -Prøv venligst igen. - </notification> - - <notification - - name="ScriptMissing" - > -Script mangler i databasen. - </notification> - - <notification - - name="ScriptNoPermissions" - > -Utilstrækkelige tilladelser til at se script. - </notification> - - <notification - - name="UnableToLoadScript" - > -Ikke muligt at indlæse script. Prøv venligst igen. - </notification> - - <notification - - name="IncompleteInventory" - > -Det komplette indhold, du tilbyder, er ikke endnu tilgængelig lokalt. Prøv venligst at tilbyde tingene igen om lidt. - </notification> - - <notification - - name="CannotModifyProtectedCategories" - > -Du kan ikke ændre beskyttede kategorier. - </notification> - - <notification - - name="CannotRemoveProtectedCategories" - > -Du kan ikke fjerne beskyttede kategorier. - </notification> - - <notification - - name="OfferedCard" - > -Du har tilbudt et visitkort til [FIRST] [LAST] - </notification> - - <notification - - name="OfferedFriendship" - > -Du har tilbudt venskab til [FIRST] [LAST] - </notification> - - <notification - - name="UnableToBuyWhileDownloading" - > -Ikke muligt at købe, imens genstandens data hentes. -Prøv venligst igen. - </notification> - - <notification - - name="UnableToLinkWhileDownloading" - > -Ikke muligt at lænke imens genstandens data hentes. -Prøv venligst igen. - </notification> - - <notification - - name="CannotBuyObjectsFromDifferentOwners" - > -Kan ikke købe genstande fra forskellige ejere pÃ¥ samme tid. -Prøv venligst at vælge en enkelt genstand. - </notification> - - <notification - - name="ObjectNotForSale" - > -Genstanden ser ikke ud til at være til salg. - </notification> - - <notification - - name="EnteringGodMode" - > -Starter gud-tilstand, niveau [LEVEL] - </notification> - - <notification - - name="LeavingGodMode" - > -Stopper gud-tilstand, niveau [LEVEL] - </notification> - - <notification - - name="CopyFailed" - > -Kopiering lykkedes ikke fordi du ikke har nok tilladelser til at kopiere - </notification> - - <notification - - name="InventoryAccepted" - > -[NAME] accepterede det du tilbød fra din beholdning. - </notification> - - <notification - - name="InventoryDeclined" - > -[NAME] afviste det du tilbød fra din beholdning. - </notification> - - <notification - - name="ObjectMessage" - > -[NAME]: [MESSAGE] - </notification> - - <notification - - name="CallingCardAccepted" - > -Dit visitkort blev accepteret. - </notification> - - <notification - - name="CallingCardDeclined" - > -Dit visitkort blev afvist. - </notification> - - <notification - - name="TeleportToLandmark" - > -Nu hvor du er nÃ¥et frem til hovedlandet, kan du teleportere til steder som '[NAME]' ved at klikke pÃ¥ Beholdning-knappen i nederste højre side af skærmen hvorefter du vælger Landmærke-mappen. -Dobbeltklik pÃ¥ landmærket og klik pÃ¥ Teleportér, for at rejse derhen. - </notification> - - <notification - - name="TeleportToPerson" - > -Nu hvor du har nÃ¥et frem til hovedlandet, kan du kontakte indbyggere som '[NAME]' ved at klikke pÃ¥ Beholdning-knappen i nederste højre side af skærmen, hvorefter du vælger Visitkort-mappen. -Dobbeltklik pÃ¥ kortet, klik pÃ¥ IM og skriv beskeden. - </notification> - - <notification - - name="CantSelectLandFromMultipleRegions" - > -Kan ikke vælge land pÃ¥ tværs af grænser. -Prøv at vælge mindre stykker land. - </notification> - - <notification - - name="GroupVote" - > -[NAME] har forslÃ¥et at stemme for: -[MESSAGE] - <form name="form"> - <button - - name="VoteNow" - text="Stem nu"/> - <button - - name="Later" - text="Senere"/> - </form> - </notification> - - <notification - - name="SystemMessage" - > -[MESSAGE] - </notification> - - <notification - - name="EventNotification" - > -Besked om begivenhed: - -[NAME] -[DATE] - <form name="form"> - <button - - name="Teleport" - text="Teleportér"/> - <button - - name="Description" - text="Beskrivelse"/> - <button - - name="Cancel" - text="Annullér"/> - </form> - </notification> - - <notification - - name="TransferObjectsHighlighted" - > -Alle genstande pÃ¥ denne grund, som vil blive overført til køberen af denne grund, er nu oplyst. - -* Træer og græs, der vil blive overført, er ikke fremhævet. - <form name="form"> - <button - - name="Done" - text="Færdig"/> - </form> - </notification> - - <notification - - name="DeactivatedGesturesTrigger" - > -Deaktiverede bevægelser med samme udløser: [NAMES] - </notification> - - <notification - - name="NoQuickTime" - > -Apple's QuickTime ser ikke ud til at være installeret pÃ¥ computeren. -Hvis du vil se live transmitteret medie pÃ¥ grunde, der understøtter det, skal du gÃ¥ ind pÃ¥ QuickTime-siden (http://www.apple.dk/quicktime) og installere QuickTime afspilleren. - </notification> - - <notification - - name="OwnedObjectsReturned" - > -De genstande du ejer pÃ¥ det valgte stykke land er blevet returneret til din beholdning. - </notification> - - <notification - - name="OtherObjectsReturned" - > -Genstandene pÃ¥ det valgte stykke land der er ejet af [FIRST] [LAST] er blevet returneret til hans eller hendes beholdning. - </notification> - - <notification - - name="OtherObjectsReturned2" - > -Genstandene pÃ¥ det valgte stykke land der er ejet af beboeren '[NAME]' er blevet returneret til deres ejere. - </notification> - - <notification - - name="GroupObjectsReturned" - > -Genstandene pÃ¥ det valgte stykke land, delt med gruppen [GROUPNAME], er blevet returneret til deres ejeres beholdninger. -Genstande, som er dedikerede og som kan overføres, er blevet returneret til deres forrige ejere. -Genstande, der ikke kan overføres og som er dedikeret til gruppen, er blevet slettet. - </notification> - - <notification - - name="UnOwnedObjectsReturned" - > -Genstandene pÃ¥ det valgte stykke land, der IKKE er ejet af dig, er blevet returneret til deres ejere. - </notification> - - <notification - - name="NotSafe" - > -Dette land har sat skade til ('ikke sikker'). -Du kan komme til skade her. Hvis du dør, vil du blive teleporteret til din hjem-lokalitet. - </notification> - - <notification - - name="NoFly" - > -Dette land har slÃ¥et flyvning fra ('ingen flyvning'). -Du kan ikke flyve her. - </notification> - - <notification - - name="PushRestricted" - > -Dette land giver ikke mulighed for at 'skubbe' andre, med mindre du ejer landet. - </notification> - - <notification - - name="NoVoice" - > -Dette land har ikke mulighed for at bruge stemme. - </notification> - - <notification - - name="NoBuild" - > -Dette land giver ikke mulighed for at bygge ('byggeri forbudt'). -Du kan ikke skabe genstande her. - </notification> - - <notification - - name="ScriptsStopped" - > -En administrator har midlertidig stoppet scripts i denne region. - </notification> - - <notification - - name="ScriptsNotRunning" - > -Denne region kører ikke nogen scripts. - </notification> - - <notification - - name="NoOutsideScripts" - > -Dette land har eksterne scripts slÃ¥et fra -('ingen eksterne scripts'). -Ingen scripts vil køre pÃ¥ nær dem, som tilhører ejeren af landet. - </notification> - - <notification - - name="ClaimPublicLand" - > -Du kan kun gøre krav pÃ¥ offentlig land i den region, du befinder dig i. - </notification> - - <notification - - name="ObjectGiveItem" - > -En genstand med navnet [OBJECTFROMNAME], ejet af [FIRST] [LAST], har givet dig en/et [OBJECTTYPE] med navnet [OBJECTNAME]. - <form name="form"> - <button - - name="Keep" - text="Behold"/> - <button - - name="Discard" - text="Smid væk"/> - <button - - name="Mute" - text="Blokér"/> - </form> - </notification> - - <notification - - name="ObjectGiveItemUnknownUser" - > -En genstand med navnet [OBJECTFROMNAME], ejet af (en ukendt bruger), har givet dig en/et [OBJECTTYPE] med navnet [OBJECTNAME]. - <form name="form"> - <button - - name="Keep" - text="Behold"/> - <button - - name="Discard" - text="Smid væk"/> - <button - - name="Mute" - text="Blokér"/> - </form> - </notification> - - <notification - - name="UserGiveItem" - > -[NAME] har givet dig en/et [OBJECTTYPE] med navnet '[OBJECTNAME]'. - <form name="form"> - <button - - name="Keep" - text="Behold"/> - <button - - name="Discard" - text="Smid væk"/> - <button - - name="Mute" - text="Blokér"/> - </form> - </notification> - - <notification - - name="GodMessage" - > -[NAME] -[MESSAGE] - </notification> - - <notification - - name="JoinGroup" - > -[MESSAGE] - <form name="form"> - <button - - name="Join" - text="Indmeld"/> - <button - - name="Decline" - text="Afvis"/> - <button - - name="Info" - text="Information"/> - </form> - </notification> - - <notification - - name="TeleportOffered" - > -[NAME] har tilbudt at teleportere dig til hans eller hendes lokalitet: - -[MESSAGE] - <form name="form"> - <button - - name="Teleport" - text="Teleportér"/> - <button - - name="Cancel" - text="Annullér"/> - </form> - </notification> - - <notification - - name="GotoURL" - > -[MESSAGE] -[URL] - <form name="form"> - <button - - name="Later" - text="Senere"/> - <button - - name="GoNow..." - text="GÃ¥ nu..."/> - </form> - </notification> - - <notification - - name="OfferFriendship" - > -[NAME] tilbyder venskab. - -Som standard vil du kunne se andres onlinestatus. - <form name="form"> - <button - - name="Accept" - text="Acceptér"/> - <button - - name="Decline" - text="Afvis"/> - </form> - </notification> - - <notification - - name="FriendshipAccepted" - > -[NAME] accepterede dit tilbud om venskab. - </notification> - - <notification - - name="FriendshipDeclined" - > -[NAME] afviste dit tilbud om venskab. - </notification> - - <notification - - name="OfferCallingCard" - > -[FIRST] [LAST] tilbyder vedkommendes visitkort. -Dette vil tilføje et bogmærke i din beholdning, sÃ¥ du hurtigt kan sende en personlig besked (IM) til denne beboer. - <form name="form"> - <button - - name="Accept" - text="Acceptér"/> - <button - - name="Decline" - text="Afvis"/> - </form> - </notification> - - <notification - - name="RegionRestartMinutes" - - - > -Regionen genstarter om [MINUTES] minutter. -Hvis du bliver i denne region, vil du blive logget af. - </notification> - - <notification - - name="RegionRestartSeconds" - - - > -Regionen genstarter om [SECONDS] sekunder. -Hvis du bliver i denne region, vil du blive logget af. - </notification> - - <notification - - name="LoadWebPage" - > -Indlæs internetside [URL]? - -[MESSAGE] - -Fra genstand: [OBJECTNAME], ejer: [NAME]? - <form name="form"> - <button - - name="Gotopage" - text="GÃ¥ til side"/> - <button - - name="Cancel" - text="Afbryd"/> - </form> - </notification> - - <notification - - name="FailedToFindWearableUnnamed" - > -Det lykkedes ikke at finde [TYPE] i databasen. - </notification> - - <notification - - name="FailedToFindWearable" - > -Det lykkedes ikke at finde [TYPE] med navnet [DESC] i databasen. - </notification> - - <notification - - name="ScriptQuestion" - > -'[OBJECTNAME]', en genstand, ejet af '[NAME]', vil gerne: - [QUESTIONS] -Er det iorden? - <form name="form"> - <button - - name="Yes" - text="Ja"/> - <button - - name="No" - text="Nej"/> - <button - - name="Mute" - text="Blokér"/> - </form> - </notification> - - <notification - - name="ScriptQuestionCaution" - > -'[OBJECTNAME]', en genstand, ejet af '[NAME]', vil gerne: - -[QUESTIONS] -Hvis du ikke har tillid til denne genstand og dens skaber, bør du afvise denne forespørgsel. For yderligere information klik pÃ¥ Detaljer-knappen. +[QUESTIONS] +Hvis du ikke har tillid til denne genstand og dens skaber, bør du afvise denne forespørgsel. For yderligere information klik pÃ¥ Detaljer-knappen. Imødekom denne forespørgsel? - <form name="form"> - <button - - name="Grant" - text="Imødekom"/> - <button - - name="Deny" - text="Afvis"/> - <button - - name="Details" - text="Detaljer..."/> - </form> - </notification> - - <notification - - name="ScriptDialog" - > -[FIRST] [LAST]'s '[TITLE]' + <form name="form"> + <button name="Grant" text="Imødekom"/> + <button name="Deny" text="Afvis"/> + <button name="Details" text="Detaljer..."/> + </form> + </notification> + <notification name="ScriptDialog"> + [FIRST] [LAST]'s '[TITLE]' [MESSAGE] - <form name="form"> - <button - - name="Ignore" - text="Ignorér"/> - </form> - </notification> - - <notification - - name="ScriptDialogGroup" - > -[GROUPNAME]'s '[TITLE]' + <form name="form"> + <button name="Ignore" text="Ignorér"/> + </form> + </notification> + <notification name="ScriptDialogGroup"> + [GROUPNAME]'s '[TITLE]' [MESSAGE] - <form name="form"> - <button - - name="Ignore" - text="Ignorér"/> - </form> - </notification> - - <notification - - name="FirstBalanceIncrease" - > -Du har lige modtaget L$[AMOUNT]. + <form name="form"> + <button name="Ignore" text="Ignorér"/> + </form> + </notification> + <notification name="FirstBalanceIncrease"> + Du har lige modtaget L$[AMOUNT]. Genstande og andre brugere kan give dig L$. Din saldo er vist i øverste højre hjørne af skærmen. - </notification> - - <notification - - name="FirstBalanceDecrease" - > -Du har lige modtaget L$[AMOUNT]. + </notification> + <notification name="FirstBalanceDecrease"> + Du har lige modtaget L$[AMOUNT]. Din saldo er vist i øverste højre hjørne af skærmen. - </notification> - - <notification - - name="FirstSit" - > -Du sidder. + </notification> + <notification name="FirstSit"> + Du sidder. Brug piletasterne (eller AWSD) for at ændre hvilken vej du ser. Klik pÃ¥ 'StÃ¥ op'-knappen for at rejse dig op. - </notification> - - <notification - - name="FirstMap" - > -Klik og træk for at flytte kortvisningen. + </notification> + <notification name="FirstMap"> + Klik og træk for at flytte kortvisningen. Dobbelt-klik for at teleportere. Brug kontrollerne til højre for at finde ting og se forskellige baggrunde. - </notification> - - <notification - - name="FirstBuild" - > -Du kan bygge nye genstande i nogle omrÃ¥der af [SECOND_LIFE]. + </notification> + <notification name="FirstBuild"> + Du kan bygge nye genstande i nogle omrÃ¥der af [SECOND_LIFE]. Brug værktøjet øverst til venstre for at bygge, og prøv at holde Ctrl eller Alt nede for hurtigt at skifte imellem værktøjerne. Tryk Esc for at stoppe med at bygge. - </notification> - - <notification - - name="FirstLeftClickNoHit" - > -Venstre-klik interagerer med specielle genstande. + </notification> + <notification name="FirstLeftClickNoHit"> + Venstre-klik interagerer med specielle genstande. Hvis musemarkøren ændrer sig til en hÃ¥nd, kan du interagere med genstanden. Højre-klik viser altid en menu med ting du kan gøre. - </notification> - - <notification - - name="FirstTeleport" - > -Du har lige teleporteret. + </notification> + <notification name="FirstTeleport"> + Du har lige teleporteret. Du er ved info-standen nærmest ved din destination. Din destination er markeret med en stor rød lyskegle. - </notification> - - <notification - - name="FirstOverrideKeys" - > -Dine bevælgelsestaster bliver nu hÃ¥ndteret af et objekt. + </notification> + <notification name="FirstOverrideKeys"> + Dine bevælgelsestaster bliver nu hÃ¥ndteret af et objekt. Brug piletasterne eller AWSD for at se, hvad de gør. Nogle genstande (som skydevÃ¥ben) kræver at du gÃ¥r ind i musevisning for at bruge dem. Tryk pÃ¥ 'M' for at gÃ¥re det. - </notification> - - <notification - - name="FirstAppearance" - > -Du tilretter dit udseende. + </notification> + <notification name="FirstAppearance"> + Du tilretter dit udseende. For at rotere og zoome brug piletasterne. NÃ¥r du er færdig, tryk pÃ¥ 'Gem alt' for at gemme dit udseende og lukke. Du kan rette dit udseende sÃ¥ tit du vil. - </notification> - - <notification - - name="FirstInventory" - > -Dette er din beholdning, der indeholder objekter, noter, tøj og andre ting du ejer. + </notification> + <notification name="FirstInventory"> + Dette er din beholdning, der indeholder objekter, noter, tøj og andre ting du ejer. * For at bære et objekt eller en mappe med tøj, træk den over pÃ¥ dig selv. * For at fÃ¥ et objekt frem i verdenen, træk den ud pÃ¥ jorden. * For at læse en note, dobbeltklik pÃ¥ den. - </notification> - - <notification - - name="FirstSandbox" - > -Dette er sandkasseomrÃ¥det. + </notification> + <notification name="FirstSandbox"> + Dette er sandkasseomrÃ¥det. Genstande, der er skabt her, vil blive slettet efter du har forladt omrÃ¥det. Sandkasser renses jævnligt. Se venligst informationen øverst pÃ¥ skærmen, lige ved siden af omrÃ¥denavnet. SandkasseomrÃ¥der er ikke almindelige. De er mærket med skilte. - </notification> - - <notification - - name="FirstFlexible" - > -Denne genstand er fleksibel. + </notification> + <notification name="FirstFlexible"> + Denne genstand er fleksibel. Fleksible genstande er ikke fysiske og man kan gÃ¥ igennem dem, indtil fleksibel-punktet ikke er afkrydset. - </notification> - - <notification - - name="FirstDebugMenus" - > -Du har sat avanceret menu til. + </notification> + <notification name="FirstDebugMenus"> + Du har sat avanceret menu til. Denne menu indeholder funktioner brugbare for udviklere, der udbedrer fejl i Second Life. -For at vise denne menu, skal man i Windows trykke Ctrl-Alt-D. PÃ¥ Mac tryk Cmd-Opt-Shift-D. - </notification> - - <notification - - name="FirstSculptedPrim" - > -Du retter en sculpted prim. +For at vise denne menu, skal man i Windows trykke Ctrl-Alt-D. PÃ¥ Mac tryk ⌘-Opt-Shift-D. + </notification> + <notification name="FirstSculptedPrim"> + Du retter en sculpted prim. Sculpted prims kræver et specielt tekstur for at specificere deres form. Du kan finde eksempler pÃ¥ sculptede teksturer i din beholdning. - </notification> - - <notification - - name="FirstMedia" - > -Du er begyndt at afspille medie. Medie kan sættes til automatisk af blive afspillet under Indstillinger, Lyd / Video. Vær opmærksom pÃ¥, at der kan være en sikkerhedsrisiko for medie-steder, du ikke stoler pÃ¥. - </notification> - - <notification - - name="MaxListSelectMessage" - > -Du mÃ¥ kun vælge op til [MAX_SELECT] genstande pÃ¥ denne liste. - </notification> - - <notification - - name="VoiceInviteP2P" - > -[NAME] inviterer dig til en stemme-chat. + </notification> + <notification name="FirstMedia"> + Du er begyndt at afspille medie. Medie kan sættes til automatisk af blive afspillet under Indstillinger, Lyd / Video. Vær opmærksom pÃ¥, at der kan være en sikkerhedsrisiko for medie-steder, du ikke stoler pÃ¥. + </notification> + <notification name="MaxListSelectMessage"> + Du mÃ¥ kun vælge op til [MAX_SELECT] genstande pÃ¥ denne liste. + </notification> + <notification name="VoiceInviteP2P"> + [NAME] inviterer dig til en stemme-chat. Klik for at acceptere at koble dig pÃ¥ samtalen eller Afvis for at afvise invitationen. Klik pÃ¥ SlÃ¥ fra for at blokere denne opkalder. - <form name="form"> - <button - - name="Accept" - text="Acceptér"/> - <button - - name="Decline" - text="Afvis"/> - <button - - name="Mute" - text="Blokér"/> - </form> - </notification> - - <notification - - name="AutoUnmuteByIM" - > -[FIRST] [LAST] har fÃ¥et en personlig besked (IM) og er automatisk ikke blokeret mere. - </notification> - - <notification - - name="AutoUnmuteByMoney" - > -[FIRST] [LAST] har fÃ¥et penge og er automatisk ikke blokeret mere. - </notification> - - <notification - - name="AutoUnmuteByInventory" - > -[FIRST] [LAST] har fÃ¥et tilbudt genstande og er automatisk ikke blokeret mere. - </notification> - - <notification - - name="VoiceInviteGroup" - > -[NAME] har tilsluttet sig stemme-chat med gruppen [GROUP]. + <form name="form"> + <button name="Accept" text="Acceptér"/> + <button name="Decline" text="Afvis"/> + <button name="Mute" text="Blokér"/> + </form> + </notification> + <notification name="AutoUnmuteByIM"> + [FIRST] [LAST] har fÃ¥et en personlig besked (IM) og er automatisk ikke blokeret mere. + </notification> + <notification name="AutoUnmuteByMoney"> + [FIRST] [LAST] har fÃ¥et penge og er automatisk ikke blokeret mere. + </notification> + <notification name="AutoUnmuteByInventory"> + [FIRST] [LAST] har fÃ¥et tilbudt genstande og er automatisk ikke blokeret mere. + </notification> + <notification name="VoiceInviteGroup"> + [NAME] har tilsluttet sig stemme-chat med gruppen [GROUP]. Klik Acceptér for at slutte dig til samtalen eller Afvis for at afvise invitationen. Klik SlÃ¥ fra for at blokere denne opkalder. - <form name="form"> - <button - - name="Accept" - text="Acceptér"/> - <button - - name="Decline" - text="Afvis"/> - <button - - name="Mute" - text="Blokér"/> - </form> - </notification> - - <notification - - name="VoiceInviteAdHoc" - > -[NAME] har tilsluttet sig stemme-chat med en konference-chat. + <form name="form"> + <button name="Accept" text="Acceptér"/> + <button name="Decline" text="Afvis"/> + <button name="Mute" text="Blokér"/> + </form> + </notification> + <notification name="VoiceInviteAdHoc"> + [NAME] har tilsluttet sig stemme-chat med en konference-chat. Klik Acceptér for at slutte dig til samtalen eller Afvis for at afvise invitationen. Klik SlÃ¥ fra for at blokere denne opkalder. - <form name="form"> - <button - - name="Accept" - text="Acceptér"/> - <button - - name="Decline" - text="Afvis"/> - <button - - name="Mute" - text="Blokér"/> - </form> - </notification> - - <notification - - name="InviteAdHoc" - > -[NAME] inviterer dig til en konference-chat. + <form name="form"> + <button name="Accept" text="Acceptér"/> + <button name="Decline" text="Afvis"/> + <button name="Mute" text="Blokér"/> + </form> + </notification> + <notification name="InviteAdHoc"> + [NAME] inviterer dig til en konference-chat. Klik Acceptér for at slutte dig til samtalen eller Afvis for at afvise invitationen. Klik SlÃ¥ fra for at blokere denne opkalder. - <form name="form"> - <button - - name="Accept" - text="Acceptér"/> - <button - - name="Decline" - text="Afvis"/> - <button - - name="Mute" - text="Blokeret"/> - </form> - </notification> - - <notification - - name="VoiceChannelFull" - > -Den stemme-chat, du prøver at tilslutte dig, [VOICE_CHANNEL_NAME], har nÃ¥et maksiumum kapacitet. Prøv venligst igen senere. - </notification> - - <notification - - name="ProximalVoiceChannelFull" - > -Vi beklager. Dette omrÃ¥de har nÃ¥et sin maksimale kapacitet for stemme-chat. Prøv venligst at benytte stemme i et andet omrÃ¥de. - </notification> - - <notification - - name="VoiceChannelDisconnected" - > -Du er blevet koblet af [VOICE_CHANNEL_NAME]. Du vil nu blive koblet op pÃ¥ en lokal stemme-chat. - </notification> - - <notification - - name="VoiceChannelDisconnectedP2P" - > -[VOICE_CHANNEL_NAME] har afsluttet opkaldet. Du vil nu blive koblet op pÃ¥ en lokal stemme-chat. - </notification> - - <notification - - name="P2PCallDeclined" - > -[VOICE_CHANNEL_NAME] har afvist dit opkald. Du vil nu blive koblet op pÃ¥ en lokal stemme-chat. - </notification> - - <notification - - name="P2PCallNoAnswer" - > -[VOICE_CHANNEL_NAME] har ikke mulighed for at besvare dit opkald. Du vil nu blive koblet op pÃ¥ en lokal chat. - </notification> - - <notification - - name="VoiceChannelJoinFailed" - > -Det lykkedes ikke at koble op til [VOICE_CHANNEL_NAME]. Prøv venligst igen senere. - </notification> - - <notification - - name="VoiceLoginRetry" - > -Vi laver en stemmekanal til dig. Det kan tage op til et minut. - </notification> - - <notification - - name="Cannot enter parcel: not a group member" - > -Du kan ikke komme ind pÃ¥ omrÃ¥det. Du er ikke medlem af den nødvendige gruppe. - </notification> - - <notification - - name="Cannot enter parcel: banned" - > -Du kan ikke komme ind pÃ¥ omrÃ¥det. Du er blevet udelukket. - </notification> - - <notification - - name="Cannot enter parcel: not on access list" - > -Du kan ikke komme ind pÃ¥ omrÃ¥det. Du er ikke pÃ¥ adgangslisten. - </notification> - - <notification - - name="VoiceNotAllowed" - > -Du har ikke tilladelse til at tilslutte dig stemme-chat pÃ¥ [VOICE_CHANNEL_NAME]. - </notification> - - <notification - - name="VoiceCallGenericError" - > -En fejl er opstÃ¥et under forsøget pÃ¥ at koble sig pÃ¥ stemme chatten [VOICE_CHANNEL_NAME]. PrÃ¥v venligst senere. - </notification> - - <notification - - name="ServerVersionChanged" - > -Det omrÃ¥de, du er kommet ind pÃ¥, kører en anden simulatorversion. Klik pÃ¥ denne besked for detaljer. - </notification> - - <notification - - name="UnableToOpenCommandURL" - > -Www-adressen, du har klikket pÃ¥, kan ikke Ã¥bnes fra denne internetbrowser. - </notification> + <form name="form"> + <button name="Accept" text="Acceptér"/> + <button name="Decline" text="Afvis"/> + <button name="Mute" text="Blokeret"/> + </form> + </notification> + <notification name="VoiceChannelFull"> + Den stemme-chat, du prøver at tilslutte dig, [VOICE_CHANNEL_NAME], har nÃ¥et maksiumum kapacitet. Prøv venligst igen senere. + </notification> + <notification name="ProximalVoiceChannelFull"> + Vi beklager. Dette omrÃ¥de har nÃ¥et sin maksimale kapacitet for stemme-chat. Prøv venligst at benytte stemme i et andet omrÃ¥de. + </notification> + <notification name="VoiceChannelDisconnected"> + Du er blevet koblet af [VOICE_CHANNEL_NAME]. Du vil nu blive koblet op pÃ¥ en lokal stemme-chat. + </notification> + <notification name="VoiceChannelDisconnectedP2P"> + [VOICE_CHANNEL_NAME] har afsluttet opkaldet. Du vil nu blive koblet op pÃ¥ en lokal stemme-chat. + </notification> + <notification name="P2PCallDeclined"> + [VOICE_CHANNEL_NAME] har afvist dit opkald. Du vil nu blive koblet op pÃ¥ en lokal stemme-chat. + </notification> + <notification name="P2PCallNoAnswer"> + [VOICE_CHANNEL_NAME] har ikke mulighed for at besvare dit opkald. Du vil nu blive koblet op pÃ¥ en lokal chat. + </notification> + <notification name="VoiceChannelJoinFailed"> + Det lykkedes ikke at koble op til [VOICE_CHANNEL_NAME]. Prøv venligst igen senere. + </notification> + <notification name="VoiceLoginRetry"> + Vi laver en stemmekanal til dig. Det kan tage op til et minut. + </notification> + <notification name="Cannot enter parcel: not a group member"> + Du kan ikke komme ind pÃ¥ omrÃ¥det. Du er ikke medlem af den nødvendige gruppe. + </notification> + <notification name="Cannot enter parcel: banned"> + Du kan ikke komme ind pÃ¥ omrÃ¥det. Du er blevet udelukket. + </notification> + <notification name="Cannot enter parcel: not on access list"> + Du kan ikke komme ind pÃ¥ omrÃ¥det. Du er ikke pÃ¥ adgangslisten. + </notification> + <notification name="VoiceNotAllowed"> + Du har ikke tilladelse til at tilslutte dig stemme-chat pÃ¥ [VOICE_CHANNEL_NAME]. + </notification> + <notification name="VoiceCallGenericError"> + En fejl er opstÃ¥et under forsøget pÃ¥ at koble sig pÃ¥ stemme chatten [VOICE_CHANNEL_NAME]. PrÃ¥v venligst senere. + </notification> + <notification name="ServerVersionChanged"> + Det omrÃ¥de, du er kommet ind pÃ¥, kører en anden simulatorversion. Klik pÃ¥ denne besked for detaljer. + </notification> + <notification name="UnableToOpenCommandURL"> + Www-adressen, du har klikket pÃ¥, kan ikke Ã¥bnes fra denne internetbrowser. + </notification> </notifications> - diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index 6c103f7e3745b56be4bfc49ff1a27a4d28eff94b..06a432bd3b0dad5dce244ae7e769403b3a88e597 100644 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -6,6 +6,9 @@ <global name="alwayschoose"> Diese Option immer auswählen </global> + <global name="implicitclosebutton"> + Schließen + </global> <template name="okbutton"> <form> <button diff --git a/indra/newview/skins/default/xui/en/floater_aaa.xml b/indra/newview/skins/default/xui/en/floater_aaa.xml index d2a01937639c0fdf7c6dcf0dcab9ee607a02455a..bf8988ca4577696a11c0d5dfffa0ca3546acf43c 100644 --- a/indra/newview/skins/default/xui/en/floater_aaa.xml +++ b/indra/newview/skins/default/xui/en/floater_aaa.xml @@ -4,7 +4,8 @@ layout="topleft" name="floater_aaa" save_rect="true" - title="About [SECOND_LIFE_VIEWER]" + can_resize="true" + title="About [APP_NAME]" width="470"> <text_editor follows="left|top|right|bottom" @@ -16,9 +17,6 @@ top="25" width="458" word_wrap="true"> - This is line 1a - - - This is line 4 +This is line 4 </text_editor> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index ece0cf737fbefe242de23b4e8aac4e6d05dae438..6eb55fa57fae17d3ad9aa11aa2abab9376876b35 100644 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -4,7 +4,7 @@ layout="topleft" name="floater_about" save_rect="true" - title="About [SECOND_LIFE_VIEWER]" + title="About [APP_NAME]" width="470"> <floater.string name="you_are_at"> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index cb3388ccbc24356caae84f20350a32ca092fc648..9165e8db986da6453d5cd03f3ae000cd13fb0ee3 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -627,6 +627,7 @@ Go to World menu > About Land or select another parcel to show its details. length="1" enabled="false" follows="left|top|right|bottom" + handle_edit_keys_directly="true" height="115" layout="topleft" left_delta="0" @@ -1993,7 +1994,7 @@ Options: layout="topleft" left_delta="0" name="limit_age_verified" - tool_tip="Ban residents who have not verified their age. See support.secondlife.com for more information." + tool_tip="Ban residents who have not verified their age. See the [SUPPORT_SITE] for more information." top_pad="4" width="278" /> <check_box diff --git a/indra/newview/skins/default/xui/en/floater_buy_land.xml b/indra/newview/skins/default/xui/en/floater_buy_land.xml index 777236504d9c31af7ff716f59e42e18ccec94a94..5e0e4231286fcbbf400db3cc3cb4af1baa5caeca 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_land.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_land.xml @@ -341,6 +341,7 @@ supports [AMOUNT2] objects length="1" enabled="false" follows="top|right" + handle_edit_keys_directly="false" height="237" layout="topleft" left="444" diff --git a/indra/newview/skins/default/xui/en/floater_incoming_call.xml b/indra/newview/skins/default/xui/en/floater_incoming_call.xml index 5c4649276a15291b73ee6610963d32b5458a80ed..2e7f5e6c42388cb8c1627efa01eba8b802016612 100644 --- a/indra/newview/skins/default/xui/en/floater_incoming_call.xml +++ b/indra/newview/skins/default/xui/en/floater_incoming_call.xml @@ -8,6 +8,10 @@ name="incoming call" title="Unknown Person is calling" width="240"> + <floater.string + name="anonymous"> + anonymous + </floater.string> <floater.string name="VoiceInviteP2P"> is calling. diff --git a/indra/newview/skins/default/xui/en/floater_land_holdings.xml b/indra/newview/skins/default/xui/en/floater_land_holdings.xml index 0a97a96ee3dd06746e25b20132e34f9cb930a9f3..60677ca0dfb6b2231164632ee753c09933dfbed5 100644 --- a/indra/newview/skins/default/xui/en/floater_land_holdings.xml +++ b/indra/newview/skins/default/xui/en/floater_land_holdings.xml @@ -52,8 +52,8 @@ <button height="20" font="SansSerifSmall" - label="Show on Map" - label_selected="Show on Map" + label="Map" + label_selected="Map" layout="topleft" left_pad="4" name="Show on Map" diff --git a/indra/newview/skins/default/xui/en/floater_postcard.xml b/indra/newview/skins/default/xui/en/floater_postcard.xml index 91c2a418916eabaa3f53a952fad10e7cc1611e5a..8657663057e2a6b2ca1dd2ba043b3c9ddc9ee46e 100644 --- a/indra/newview/skins/default/xui/en/floater_postcard.xml +++ b/indra/newview/skins/default/xui/en/floater_postcard.xml @@ -12,7 +12,7 @@ width="450"> <floater.string name="default_subject"> - Postcard from Second Life. + Postcard from [SECOND_LIFE]. </floater.string> <floater.string name="default_message"> @@ -121,6 +121,7 @@ left_delta="0" max_length="700" name="msg_form" + word_wrap="true" top_pad="10" width="420"> Type your message here. diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml index 2906b73af82205c997451eaff4de36c4fc8564aa..bacec627e1b84f9ca68e0c12cc108346e7c9336e 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences.xml @@ -53,6 +53,7 @@ layout="topleft" name="general" /> <panel + class="panel_preference" filename="panel_preferences_graphics1.xml" label="Graphics" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml index a463b2274d7c6185e648161bb1f75c925d163e50..2fd561f9915133f17578c2cd4507edcc0ae2f449 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater auto_tile="true" - height="400" + height="600" layout="topleft" name="gesture_preview" width="280"> @@ -48,7 +48,7 @@ name="desc_label" top="25" width="100"> - Description: + Name (not working yet): </text> <line_editor follows="left|top" @@ -66,21 +66,21 @@ height="10" layout="topleft" left="10" - name="trigger_label" - top="54" + name="desc_label" + top_pad="10" width="100"> - Trigger: + Description: </text> <line_editor follows="left|top" - height="20" + height="40" layout="topleft" left_delta="84" - max_length="31" - name="trigger_editor" + name="desc" top_delta="-4" - width="100" /> - <text + width="180" /> + <!--ACCORDION GOES HERE --> + <text type="string" length="1" follows="top|left" @@ -88,22 +88,20 @@ height="10" layout="topleft" left="10" - name="replace_text" - tool_tip="Replace the trigger word(s) with these words. For example, trigger 'hello' replace with 'howdy' will turn the chat 'I wanted to say hello' into 'I wanted to say howdy' as well as playing the gesture!" - top="79" - width="200"> - Replace with: + name="trigger_label" + top_pad="10" + width="100"> + Chat: </text> <line_editor follows="left|top" height="20" layout="topleft" - left_delta="84" + left_pad="5" max_length="31" - name="replace_editor" - tool_tip="Replace the trigger word(s) with these words. For example, trigger 'hello' replace with 'howdy' will turn the chat 'I wanted to say hello' into 'I wanted to say howdy' as well as playing the gesture" + name="trigger_editor" top_delta="-4" - width="130" /> + width="135" /> <text type="string" length="1" @@ -113,15 +111,15 @@ layout="topleft" left="10" name="key_label" - top="104" + top_pad="10" width="100"> - Shortcut Key: + Keyboard: </text> <combo_box height="20" label="None" layout="topleft" - left_delta="84" + left_pad="5" name="modifier_combo" top_delta="-4" width="50" /> @@ -129,7 +127,7 @@ height="20" label="None" layout="topleft" - left_pad="10" + left_pad="5" name="key_combo" top_delta="0" width="45" /> @@ -141,32 +139,52 @@ height="10" layout="topleft" left="10" - name="library_label" - top="135" + name="replace_text" + tool_tip="Replace the trigger word(s) with these words. For example, trigger 'hello' replace with 'howdy' will turn the chat 'I wanted to say hello' into 'I wanted to say howdy' as well as playing the gesture!" + top_pad="10" width="100"> - Library: + Replace: </text> - <text - type="string" - length="1" + <line_editor + follows="left|top" + height="20" + layout="topleft" + left_pad="5" + max_length="31" + name="replace_editor" + tool_tip="Replace the trigger word(s) with these words. For example, trigger 'hello' replace with 'howdy' will turn the chat 'I wanted to say hello' into 'I wanted to say howdy' as well as playing the gesture" + top_delta="-4" + width="135" /> + + <!--ACCORDION GOES HERE --> + <scroll_list + follows="top|left" + height="110" + layout="topleft" + left="10" + name="step_list" + top_pad="10" + width="260" /> + <button follows="top|left" + height="20" font="SansSerifSmall" - height="10" + label="Add" layout="topleft" - left_pad="75" - name="steps_label" - top_delta="0" - width="100"> - Steps: - </text> + left_pad="-100" + name="add_btn" + top_pad="5" + width="100" /> + + <scroll_list follows="top|left" height="110" layout="topleft" left="10" name="library_list" - top="150" - width="80"> + top_pad="10" + width="260"> <scroll_list.rows value="Animation" /> <scroll_list.rows @@ -176,54 +194,39 @@ <scroll_list.rows value="Wait" /> </scroll_list> + + + <button follows="top|left" height="20" - font="SansSerifSmall" - label="Add >>" - layout="topleft" - left_pad="14" - name="add_btn" - top_delta="0" - width="70" /> - <button - follows="top|left" - height="20" - font="SansSerifSmall" - label="Up" + label="Preview" layout="topleft" - left_delta="0" - name="up_btn" - top_pad="10" - width="70" /> + left="20" + name="preview_btn" + top_pad="50" + width="80" /> <button follows="top|left" height="20" - font="SansSerifSmall" - label="Down" + label="Save" layout="topleft" - left_delta="0" - name="down_btn" - top_pad="10" - width="70" /> + left_pad="5" + name="save_btn" + top_delta="0" + width="80" /> <button follows="top|left" height="20" - font="SansSerifSmall" - label="Remove" - layout="topleft" - left_delta="0" - name="delete_btn" - top_pad="10" - width="70" /> - <scroll_list - follows="top|left" - height="110" + label="Cancel (not working)" layout="topleft" - left="185" - name="step_list" - top="150" - width="85" /> + left_pad="5" + name="save_btn" + top_delta="0" + width="80" /> + + + <text type="string" length="1" @@ -233,7 +236,7 @@ layout="topleft" left="10" name="help_label" - top="270" + top_pad="10" width="200"> All steps happen simultaneously, unless you add wait steps. @@ -244,7 +247,7 @@ unless you add wait steps. layout="topleft" left="10" name="options_text" - top="300" + top_pad="10" width="205" /> <combo_box follows="top|left" @@ -252,7 +255,7 @@ unless you add wait steps. layout="topleft" left_delta="10" name="animation_list" - top="320" + top_pad="10" width="100" /> <combo_box follows="top|left" @@ -278,7 +281,7 @@ unless you add wait steps. layout="topleft" left_pad="8" name="animation_trigger_type" - top_delta="0" + top="445" width="80"> <radio_item height="16" @@ -304,7 +307,7 @@ unless you add wait steps. layout="topleft" left="16" name="wait_anim_check" - top="315" + top="430" width="100" /> <check_box follows="top|left" @@ -324,6 +327,73 @@ unless you add wait steps. name="wait_time_editor" top_delta="0" width="50" /> + + + + <!--accordion + layout="topleft" + left="2" + width="280" + top_pad="10" + height="600" + follows="all" + name="preview_gesture_shortcuts"> + <accordion_tab + min_height="515" + title="Shortcuts" + name="preview_gesture_shortcuts"> + <panel + class="preview_gesture_shortcuts" + filename="floater_preview_gesture_shortcuts" + name="preview_gesture_shortcuts" /> + </accordion_tab> + <accordion_tab + min_height="380" + title="Group Roles" + name="group_roles_tab" + can_resize="false"> + <panel + class="panel_group_roles" + filename="panel_group_roles.xml" + name="group_roles_tab_panel"/> + </accordion_tab> + <accordion_tab + min_height="530" + title="Group Notices" + name="group_notices_tab" + can_resize="false"> + <panel + class="panel_group_notices" + filename="panel_group_notices.xml" + name="group_notices_tab_panel"/> + </accordion_tab> + <accordion_tab + min_height="270" + title="Group Land Money" + name="group_land_tab" + can_resize="false"> + <panel + class="panel_group_land_money" + filename="panel_group_land_money.xml" + name="group_land_tab_panel"/> + </accordion_tab> + </accordion--> + + + + <!--text + type="string" + length="1" + follows="top|left" + font="SansSerifSmall" + height="10" + layout="topleft" + left="10" + name="library_label" + top_pad="10" + width="100"> + Library: + </text> <check_box follows="top|left" height="20" @@ -333,23 +403,5 @@ unless you add wait steps. name="active_check" tool_tip="Active gestures can be triggered by chatting their trigger phrases or pressing their hot keys. Gestures usually become inactive when there is a key binding conflict." top="365" - width="100" /> - <button - follows="top|left" - height="20" - label="Preview" - layout="topleft" - left_delta="75" - name="preview_btn" - top_delta="2" - width="80" /> - <button - follows="top|left" - height="20" - label="Save" - layout="topleft" - left_pad="10" - name="save_btn" - top_delta="0" - width="80" /> + width="100" /--> </floater> \ No newline at end of file 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 f8f1abd1790477f06093b389c3b0a338cf159932..4595c9eedab981dee34a9e1552463487d0241fb8 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml @@ -74,6 +74,7 @@ left="4" max_length="65536" name="Notecard Editor" + handle_edit_keys_directly="true" tab_group="1" top="46" width="392" diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml index 6585667c8b63b2428481ed86d9bd15bf02e59b33..54facbb659153afa7a19f4d172496feecad9cdba 100644 --- a/indra/newview/skins/default/xui/en/floater_tos.xml +++ b/indra/newview/skins/default/xui/en/floater_tos.xml @@ -49,7 +49,7 @@ name="tos_heading" top_delta="-399" width="552"> - Please read the following Terms of Service carefully. To continue logging in to Second Life, + Please read the following Terms of Service carefully. To continue logging in to [SECOND_LIFE], you must accept the agreement. </text> <text_editor @@ -64,6 +64,7 @@ you must accept the agreement. name="tos_text" top_pad="43" width="568" + handle_edit_keys_directly="true" word_wrap="true"> TOS_TEXT </text_editor> diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml index 6a022e8966b632205d248d182e028b5af6b39c5f..e46588dd711c3a18a43786465e1c027a377c9431 100644 --- a/indra/newview/skins/default/xui/en/floater_world_map.xml +++ b/indra/newview/skins/default/xui/en/floater_world_map.xml @@ -359,8 +359,6 @@ label="Landmarks" name="item1" value="None" /> - <combo_box.commit_callback - function="WMap.Landmark" /> </combo_box> <icon color="0.5 0 0 1" diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index 4e3c0d0c40d03fc58df5ed1f6aff0a59644b04c2..642087baff05ab97dded94ae6d3eb71c03a53245 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -43,7 +43,7 @@ layout="topleft" name="Help"> <menu_item_call - label="Second Life Help" + label="[SECOND_LIFE] Help" layout="topleft" name="Second Life Help" shortcut="F1"> @@ -52,7 +52,7 @@ parameter="help f1" /> </menu_item_call> <menu_item_call - label="About Second Life" + label="About [APP_NAME]" layout="topleft" name="About Second Life"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_picks.xml b/indra/newview/skins/default/xui/en/menu_picks.xml index 146d7d06fe31ea41a7d6c18e804e70d3ef2ef91a..7e07a97016febf41d334c8e424ef3c040e0daad9 100644 --- a/indra/newview/skins/default/xui/en/menu_picks.xml +++ b/indra/newview/skins/default/xui/en/menu_picks.xml @@ -25,7 +25,7 @@ function="Pick.Teleport" /> </menu_item_call> <menu_item_call - label="Show on Map" + label="Map" layout="topleft" name="pick_map"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_slurl.xml b/indra/newview/skins/default/xui/en/menu_slurl.xml index d5d9d3c43da5a1b51527f02ae618d2018e715ef4..ee37d4994662dae9a1b0ebc2f8765f0c5eefc32e 100644 --- a/indra/newview/skins/default/xui/en/menu_slurl.xml +++ b/indra/newview/skins/default/xui/en/menu_slurl.xml @@ -27,7 +27,7 @@ parameter="about" /> </menu_item_call> <menu_item_call - label="Show on Map" + label="Map" layout="topleft" name="show_on_map"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 3d2558ce5a58e31703dad301c006341e10456815..5e894e177371cec337e91de4d43eab542e64e442 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -138,7 +138,7 @@ <menu_item_separator layout="topleft" /> <menu_item_call - label="Quit Second Life" + label="Quit [APP_NAME]" layout="topleft" name="Quit" shortcut="control|Q"> @@ -449,7 +449,7 @@ name="Help" tear_off="true"> <menu_item_call - label="Second Life Help" + label="[SECOND_LIFE] Help" layout="topleft" name="Second Life Help" shortcut="F1"> @@ -496,7 +496,7 @@ <menu_item_separator layout="topleft" /> <menu_item_call - label="About Second Life" + label="About [APP_NAME]" layout="topleft" name="About Second Life"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 3083a7f689d22519177e8984d20f1491ee333a0f..8b0741524d50d26c4f0bfdbb7ef6948c135f502b 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -102,7 +102,7 @@ name="MissingAlert" label="Unknown Alert Message" type="alertmodal"> -Your version of Second Life does not know how to display the alert it just received. Please verify that you have the latest Viewer installed. +Your version of [APP_NAME] does not know how to display the alert it just received. Please verify that you have the latest Viewer installed. Error details: The alert called '[_NAME]' was not found in notifications.xml. <usetemplate @@ -154,7 +154,7 @@ No tutorial is currently available. icon="alertmodal.tga" name="BadInstallation" type="alertmodal"> - An error occurred while updating Second Life. Please download the latest version of the Viewer. http://get.secondlife.com + An error occurred while updating [APP_NAME]. Please download the latest version of the Viewer. http://get.secondlife.com <usetemplate name="okbutton" yestext="Ok"/> @@ -164,7 +164,7 @@ No tutorial is currently available. icon="alertmodal.tga" name="LoginFailedNoNetwork" type="alertmodal"> -Could not connect to the Second Life Grid. +Could not connect to the [SECOND_LIFE_GRID]. '[DIAGNOSTIC]' Make sure your Internet connection is working properly. <usetemplate @@ -331,7 +331,7 @@ Members cannot be removed from that role. The members must resign from the role themselves. Are you sure you want to continue? <usetemplate - ignoretext="When adding group members to the owner role" + ignoretext="Confirm before I add a new group Owner" name="okcancelignore" notext="No" yestext="Yes"/> @@ -429,7 +429,7 @@ Selecting "Show in Search" will show: type="alertmodal"> You can propose to another Resident or dissolve an existing partnership through the [SECOND_LIFE] website. -Go to the Second Life web site for more information on partnering? +Go to the [SECOND_LIFE] web site for more information on partnering? <usetemplate name="okcancelbuttons" notext="Cancel" @@ -519,7 +519,7 @@ Your selling price will be L$[SALE_PRICE] and will be authorized for sale to [NA icon="alertmodal.tga" name="ConfirmLandSaleToAnyoneChange" type="alertmodal"> -ATTENTION: Clicking 'sell to anyone' makes your land available to the entire Second Life community, even those not in this region. +ATTENTION: Clicking 'sell to anyone' makes your land available to the entire [SECOND_LIFE] community, even those not in this region. The selected [LAND_SIZE] m² land is being set for sale. Your selling price will be L$[SALE_PRICE] and will be authorized for sale to [NAME]. @@ -765,7 +765,7 @@ Fill out your ad, then click 'Publish...' to add it to the directory. You'll be asked for a price to pay when clicking Publish. Paying more makes your ad appear higher in the list, and also appear higher when people search for keywords. <usetemplate - ignoretext="When adding a new Classified" + ignoretext="How to create a new Classified ad" name="okcancelignore" notext="Cancel" yestext="OK"/> @@ -861,14 +861,14 @@ Would you like to disable all popups which can be skipped? icon="alertmodal.tga" name="CacheWillClear" type="alertmodal"> -Cache will be cleared after you restart [SECOND_LIFE]. +Cache will be cleared after you restart [APP_NAME]. </notification> <notification icon="alertmodal.tga" name="CacheWillBeMoved" type="alertmodal"> -Cache will be moved after you restart [SECOND_LIFE]. +Cache will be moved after you restart [APP_NAME]. Note: This will clear the cache. </notification> @@ -876,14 +876,14 @@ Note: This will clear the cache. icon="alertmodal.tga" name="ChangeConnectionPort" type="alertmodal"> -Port settings take effect after you restart [SECOND_LIFE]. +Port settings take effect after you restart [APP_NAME]. </notification> <notification icon="alertmodal.tga" name="ChangeSkin" type="alertmodal"> -The new skin will appear after you restart [SECOND_LIFE]. +The new skin will appear after you restart [APP_NAME]. </notification> <notification @@ -1020,7 +1020,7 @@ Unable to write file [[FILE]] icon="alertmodal.tga" name="UnsupportedHardware" type="alertmodal"> -Warning: Your system does not meet Second Life's minimum system requirements. If you continue using Second Life, you may experience poor performance. Unfortunately, we cannot provide technical support for unsupported system configurations. +Warning: Your system does not meet [APP_NAME]'s minimum system requirements. If you continue using [APP_NAME], you may experience poor performance. Unfortunately, the [SUPPORT_SITE] cannot provide technical support for unsupported system configurations. MINSPECS Do you wish to visit [_URL] for more information? @@ -1029,7 +1029,7 @@ Do you wish to visit [_URL] for more information? http://www.secondlife.com/corporate/sysreqs.php </url> <usetemplate - ignoretext="When detecting unsupported hardware" + ignoretext="My computer hardware is not supported" name="okcancelignore" notext="No" yestext="Yes"/> @@ -1039,12 +1039,12 @@ Do you wish to visit [_URL] for more information? icon="alertmodal.tga" name="UnknownGPU" type="alertmodal"> -Your system contains a graphics card that is unknown to us at this time. -This is often the case with new hardware we haven't had a chance to test. Second Life will most likely run properly, but you may need to adjust your graphics settings to something more appropriate. +Your system contains a graphics card that is unknown to [APP_NAME] at this time. +This is often the case with new hardware that hasn't been tested yet with [APP_NAME]. [APP_NAME] will most likely run properly, but you may need to adjust your graphics settings to something more appropriate. (Edit menu > Preferences > Graphics). <form name="form"> <ignore name="ignore" - text="When detecting an unknown graphics card"/> + text="My graphics card could not be identified"/> </form> </notification> @@ -1052,9 +1052,8 @@ This is often the case with new hardware we haven't had a chance to test. icon="alertmodal.tga" name="DisplaySettingsNoShaders" type="alertmodal"> -[SECOND_LIFE] crashed while initializing graphics drivers. -Graphics Quality will be set to low to avoid some common driver errors. -This will disable some graphics features. +[APP_NAME] crashed while initializing graphics drivers. +Graphics Quality will be set to Low to avoid some common driver errors. This will disable some graphics features. We recommend updating your graphics card drivers. Graphics Quality can be raised in Preferences > Graphics. </notification> @@ -1388,7 +1387,7 @@ Unable to create output file: [FILE] icon="alertmodal.tga" name="DoNotSupportBulkAnimationUpload" type="alertmodal"> -We do not currently support bulk upload of animation files. +[APP_NAME] does not currently support bulk upload of animation files. </notification> <notification @@ -1507,15 +1506,15 @@ Could not teleport. icon="alertmodal.tga" name="invalid_tport" type="alertmodal"> -Problem encountered processing your teleport request. You may need to log back in before you can teleport. If you continue to get this message, please check the Tech Support FAQ at: -www.secondlife.com/support +Problem encountered processing your teleport request. You may need to log back in before you can teleport. +If you continue to get this message, please check the [SUPPORT_SITE]. </notification> <notification icon="alertmodal.tga" name="invalid_region_handoff" type="alertmodal"> -Problem encountered processing your region crossing. You may need to log back in before you can cross regions. If you continue to get this message, please check the Tech Support FAQ at: -www.secondlife.com/support +Problem encountered processing your region crossing. You may need to log back in before you can cross regions. +If you continue to get this message, please check the [SUPPORT_SITE]. </notification> <notification icon="alertmodal.tga" @@ -1656,7 +1655,7 @@ Cannot find the region this land is in. icon="alertmodal.tga" name="CannotCloseFloaterBuyLand" type="alertmodal"> -You cannot close the Buy Land window until Second Life estimates the price of this transaction. +You cannot close the Buy Land window until [APP_NAME] estimates the price of this transaction. </notification> <notification @@ -1974,7 +1973,7 @@ and provide details about your network setup. type="alertmodal"> You have been logged out of [SECOND_LIFE]: [MESSAGE] -You can still look at existing IM and chat by clicking 'View IM & Chat'. Otherwise, click 'Quit' to exit [SECOND_LIFE] immediately. +You can still look at existing IM and chat by clicking 'View IM & Chat'. Otherwise, click 'Quit' to exit [APP_NAME] immediately. <usetemplate name="okcancelbuttons" notext="Quit" @@ -2332,10 +2331,10 @@ You may want to set a new home location. name="ClothingLoading" type="alertmodal"> Your clothing is still downloading. -You can use [SECOND_LIFE] normally and other users will see you correctly. +You can use [SECOND_LIFE] normally and other people will see you correctly. <form name="form"> <ignore name="ignore" - text="When clothing is taking a long time to download"/> + text="Clothing is taking a long time to download"/> </form> </notification> @@ -2344,7 +2343,7 @@ You can use [SECOND_LIFE] normally and other users will see you correctly. name="FirstRun" type="alertmodal"> -[SECOND_LIFE] installation is complete. +[APP_NAME] installation is complete. If this is your first time using [SECOND_LIFE], you will need to create an account before you can log in. Return to www.secondlife.com to create a new account? @@ -2358,9 +2357,9 @@ Return to www.secondlife.com to create a new account? icon="alertmodal.tga" name="LoginPacketNeverReceived" type="alertmodal"> -We're having trouble connecting. There may be a problem with your internet connection or the Second Life servers. +We're having trouble connecting. There may be a problem with your Internet connection or the [SECOND_LIFE_GRID]. -You can either check your internet connection and try again in a few minutes, click Help to connect to our support site, or click Teleport to attempt to teleport home. +You can either check your Internet connection and try again in a few minutes, click Help to view the [SUPPORT_SITE], or click Teleport to attempt to teleport home. <url option="1" name="url"> http://secondlife.com/support/ @@ -2591,9 +2590,9 @@ Finished download of raw terrain file to: icon="alertmodal.tga" name="DownloadWindowsMandatory" type="alertmodal"> -A new version of [SECOND_LIFE] is available. +A new version of [APP_NAME] is available. [MESSAGE] -You must download this update to use [SECOND_LIFE]. +You must download this update to use [APP_NAME]. <usetemplate name="okcancelbuttons" notext="Quit" @@ -2604,7 +2603,7 @@ You must download this update to use [SECOND_LIFE]. icon="alertmodal.tga" name="DownloadWindows" type="alertmodal"> -An updated version of [SECOND_LIFE] is available. +An updated version of [APP_NAME] is available. [MESSAGE] This update is not required, but we suggest you install it to improve performance and stability. <usetemplate @@ -2617,7 +2616,7 @@ This update is not required, but we suggest you install it to improve performanc icon="alertmodal.tga" name="DownloadWindowsReleaseForDownload" type="alertmodal"> -An updated version of [SECOND_LIFE] is available. +An updated version of [APP_NAME] is available. [MESSAGE] This update is not required, but we suggest you install it to improve performance and stability. <usetemplate @@ -2669,9 +2668,9 @@ This update is not required, but we suggest you install it to improve performanc icon="alertmodal.tga" name="DownloadMacMandatory" type="alertmodal"> -A new version of [SECOND_LIFE] is available. +A new version of [APP_NAME] is available. [MESSAGE] -You must download this update to use [SECOND_LIFE]. +You must download this update to use [APP_NAME]. Download to your Applications folder? <usetemplate @@ -2684,7 +2683,7 @@ Download to your Applications folder? icon="alertmodal.tga" name="DownloadMac" type="alertmodal"> -An updated version of [SECOND_LIFE] is available. +An updated version of [APP_NAME] is available. [MESSAGE] This update is not required, but we suggest you install it to improve performance and stability. @@ -2699,7 +2698,7 @@ Download to your Applications folder? icon="alertmodal.tga" name="DownloadMacReleaseForDownload" type="alertmodal"> -An updated version of [SECOND_LIFE] is available. +An updated version of [APP_NAME] is available. [MESSAGE] This update is not required, but we suggest you install it to improve performance and stability. @@ -2717,7 +2716,7 @@ Download to your Applications folder? Deeding this object will cause the group to: * Receive L$ paid into the object <usetemplate - ignoretext="When deeding objects to groups" + ignoretext="Confirm before I deed an object to a group" name="okcancelignore" notext="Cancel" yestext="Deed"/> @@ -2727,9 +2726,9 @@ Deeding this object will cause the group to: icon="alertmodal.tga" name="WebLaunchExternalTarget" type="alertmodal"> -Open your system Web browser to view this content? +Do you want to open your Web browser to view this content? <usetemplate - ignoretext="When opening your system browser to view a Web page" + ignoretext="Launch my browser to view a web page" name="okcancelignore" notext="Cancel" yestext="OK"/> @@ -2739,9 +2738,9 @@ Open your system Web browser to view this content? icon="alertmodal.tga" name="WebLaunchJoinNow" type="alertmodal"> -Go to www.secondlife.com to manage your account? +Go to secondlife.com to manage your account? <usetemplate - ignoretext="When launching web browser to manage your account" + ignoretext="Launch my browser to manage my account" name="okcancelignore" notext="Cancel" yestext="OK"/> @@ -2753,7 +2752,7 @@ Go to www.secondlife.com to manage your account? type="alertmodal"> Visit the [SECOND_LIFE] Wiki and learn how to report bugs correctly. <usetemplate - ignoretext="When launching web browser to view the Bug Reporting 101 Wiki" + ignoretext="Launch my browser to learn how to report a Bug" name="okcancelignore" notext="Cancel" yestext="OK"/> @@ -2765,7 +2764,7 @@ Visit the [SECOND_LIFE] Wiki and learn how to report bugs correctly. type="alertmodal"> Visit the [SECOND_LIFE] Wiki for details of how to report a security issue. <usetemplate - ignoretext="When launching web browser to view Security Issues Wiki" + ignoretext="Launch my browser to learn how to report a Security Issue" name="okcancelignore" notext="Cancel" yestext="OK"/> @@ -2777,7 +2776,7 @@ Visit the [SECOND_LIFE] Wiki for details of how to report a security issue. type="alertmodal"> Visit the [SECOND_LIFE] QA Wiki. <usetemplate - ignoretext="When launching web browser to view the QA Wiki" + ignoretext="Launch my browser to view the QA Wiki" name="okcancelignore" notext="Cancel" yestext="OK"/> @@ -2789,7 +2788,7 @@ Visit the [SECOND_LIFE] QA Wiki. type="alertmodal"> Visit the [SECOND_LIFE] Public Issue Tracker, where you can report bugs and other issues. <usetemplate - ignoretext="When launching web browser to view the Public Issue Tracker" + ignoretext="Launch my browser to use the Public Issue Tracker" name="okcancelignore" notext="Cancel" yestext="Go to page"/> @@ -2801,7 +2800,7 @@ Visit the [SECOND_LIFE] Public Issue Tracker, where you can report bugs and othe type="alertmodal"> Visit the [SECOND_LIFE] Wiki for info on how to use the Public Issue Tracker. <usetemplate - ignoretext="When launching web browser to view Public Issue Tracker Wiki" + ignoretext="Launch my browser to view instructions for the Public Issue Tracker" name="okcancelignore" notext="Cancel" yestext="Go to page"/> @@ -2813,7 +2812,7 @@ Visit the [SECOND_LIFE] Wiki for info on how to use the Public Issue Tracker. type="alertmodal"> Go to the Official Linden Blog, for the latest news and information. <usetemplate - ignoretext="When launching web browser to view the blog" + ignoretext="Launch my browser to view the blog" name="okcancelignore" notext="Cancel" yestext="OK"/> @@ -2823,9 +2822,9 @@ Go to the Official Linden Blog, for the latest news and information. icon="alertmodal.tga" name="WebLaunchLSLGuide" type="alertmodal"> -Go to the Scripting Guide for scripting help? +Do you want to open the Scripting Guide for help with scripting? <usetemplate - ignoretext="When launching web browser to view the Scripting Guide" + ignoretext="Launch my browser to view the Scripting Guide" name="okcancelignore" notext="Cancel" yestext="OK"/> @@ -2835,9 +2834,9 @@ Go to the Scripting Guide for scripting help? icon="alertmodal.tga" name="WebLaunchLSLWiki" type="alertmodal"> -Go to the LSL Portal for scripting help? +Do you want to visit the LSL Portal for help with scripting? <usetemplate - ignoretext="When launching web browser to view the LSL Portal" + ignoretext="Launch my browser to view the LSL Portal" name="okcancelignore" notext="Cancel" yestext="Go to page"/> @@ -2851,7 +2850,7 @@ Are you sure you want to return the selected objects to their owners? Transferab *WARNING* No-transfer deeded objects will be deleted! <usetemplate - ignoretext="When returning objects to their owners" + ignoretext="Confirm before I return objects to their owners" name="okcancelignore" notext="Cancel" yestext="OK"/> @@ -2943,10 +2942,10 @@ Cannot offer friendship at this time. Please try again in a moment. icon="alert.tga" name="BusyModeSet" type="alert"> -Busy mode set. +Busy mode is set. Chat and instant messages will be hidden. Instant messages will get your Busy mode response. All teleportation offers will be declined. All inventory offers will go to your Trash. <usetemplate - ignoretext="When setting busy mode" + ignoretext="I change my status to Busy mode" name="okignore" yestext="OK"/> </notification> @@ -3096,7 +3095,7 @@ Join me in [REGION] type="alertmodal"> Are you sure you want to teleport? <usetemplate - ignoretext="When teleporting from a landmark in inventory" + ignoretext="Confirm that I want to teleport to a landmark" name="okcancelignore" notext="Cancel" yestext="Teleport"/> @@ -3108,7 +3107,7 @@ Are you sure you want to teleport? type="alertmodal"> Teleport to [PICK]? <usetemplate - ignoretext="When teleporting from double-clicking a pick" + ignoretext="Confirm that I want to teleport to a location in Picks" name="okcancelignore" notext="Cancel" yestext="Teleport"/> @@ -3318,7 +3317,7 @@ Go to the Knowledge Base for more information about maturity Ratings? name="okcancelignore" yestext="Go to Knowledge Base" notext="Close" - ignoretext="When Region entry is blocked due to maturity Rating"/> + ignoretext="I can't enter this Region, due to restrictions of the maturity Rating"/> </notification> <notification @@ -3345,7 +3344,7 @@ You can click 'Change Preference' to raise your maturity Rating prefer index="1" name="Cancel" text="Close"/> - <ignore name="ignore" text="When Region entry is blocked due to maturity Rating preference"/> + <ignore name="ignore" text="My chosen Rating preference prevents me from entering a Region"/> </form> </notification> @@ -3375,7 +3374,7 @@ Go to the Knowledge Base for more information about maturity Ratings? name="okcancelignore" yestext="Go to Knowledge Base" notext="Close" - ignoretext="When claiming land is blocked due to maturity Rating"/> + ignoretext="I can't claim this Land, due to restrictions of the maturity Rating"/> </notification> <notification @@ -3396,7 +3395,7 @@ You can click 'Change Preference' to raise your maturity Rating prefer name="okcancelignore" yestext="Change Preference" notext="Close" - ignoretext="When claiming land is blocked due to maturity Rating preference"/> + ignoretext="My chosen Rating preference prevents me from claiming Land"/> </notification> <notification @@ -3425,7 +3424,7 @@ Go to the Knowledge Base for more information about maturity Ratings? name="okcancelignore" yestext="Go to Knowledge Base" notext="Close" - ignoretext="When a Land purchase is blocked due to maturity Rating"/> + ignoretext="I can't buy this Land, due to restrictions of the maturity Rating"/> </notification> <notification @@ -3446,7 +3445,7 @@ You can click 'Change Preference' to raise your maturity Rating prefer name="okcancelignore" yestext="Change Preference" notext="Close" - ignoretext="When a Land purchase is blocked due to maturity Rating preference"/> + ignoretext="My chosen Rating preference prevents me from buying Land"/> </notification> <notification @@ -3969,7 +3968,7 @@ Default: off label="Voice Version Mismatch" name="VoiceVersionMismatch" type="alertmodal"> -This version of Second Life is not compatible with the Voice Chat feature in this region. In order for Voice Chat to function correctly you will need to update Second Life. +This version of [APP_NAME] is not compatible with the Voice Chat feature in this region. In order for Voice Chat to function correctly you will need to update [APP_NAME]. </notification> <notification @@ -4158,7 +4157,7 @@ These items will be moved to your inventory, not copied. Move the inventory item(s)? <usetemplate - ignoretext="When moving no-copy inventory from objects" + ignoretext="Warn me before I move 'no-copy' items from an object" name="okcancelignore" notext="Cancel" yestext="OK"/> @@ -4173,7 +4172,7 @@ Because this object is scripted, moving these items to your inventory may cause Move the inventory item(s)? <usetemplate - ignoretext="When moving no-copy inventory from scripted objects" + ignoretext="Warn me before I move 'no-copy' items which might break a scripted object" name="okcancelignore" notext="Cancel" yestext="OK"/> @@ -4183,10 +4182,10 @@ Move the inventory item(s)? icon="alert.tga" name="ClickActionNotPayable" type="alert"> -Warning: The Pay Object click action has been set, but it will only work if a script is added with a money() event. +Warning: The 'Pay object' click action has been set, but it will only work if a script is added with a money() event. <form name="form"> <ignore name="ignore" - text="When Setting 'Pay' on objects without money() events"/> + text="I set the action 'Pay object' when building an object without a money() script"/> </form> </notification> @@ -4201,9 +4200,9 @@ There are no items in this object that you are allowed to copy. icon="alertmodal.tga" name="WebLaunchAccountHistory" type="alertmodal"> -Go to the Second Life web site to see your account history? +Go to secondlife.com to see your account history? <usetemplate - ignoretext="When loading account history web page" + ignoretext="Launch my browser to see my account history" name="okcancelignore" notext="Cancel" yestext="Go to page"/> @@ -4213,9 +4212,9 @@ Go to the Second Life web site to see your account history? icon="alertmodal.tga" name="ClickOpenF1Help" type="alertmodal"> -View Second Life help? +Do you want to visit [SECOND_LIFE] help? <usetemplate - ignoretext="When visiting the Second Life Support Website." + ignoretext="Launch my browser to view Help/Support" name="okcancelignore" notext="Cancel" yestext="Go"/> @@ -4227,7 +4226,7 @@ View Second Life help? type="alertmodal"> Are you sure you want to quit? <usetemplate - ignoretext="When Quitting Second Life." + ignoretext="Confirm before I quit" name="okcancelignore" notext="Don't Quit" yestext="Quit"/> @@ -4259,7 +4258,7 @@ As a service to residents and visitors, the owner of the region you are in has e The region owner will resolve reports based on the local rules of this region as outlined in the estate Covenant. (View covenants by going to the World menu and selecting About Land.) -The resolution of this report applies only to this Region; Residents access to other areas of Second Life will not be affected by the outcome of this report. Only Linden Lab can restrict access to the entirety of Second Life. +The resolution of this report applies only to this Region. Residents' access to other areas of [SECOND_LIFE] will not be affected by the outcome of this report. Only Linden Lab can restrict access to the entirety of [SECOND_LIFE]. </notification> <notification @@ -4352,9 +4351,9 @@ Dear Resident, You appear to be reporting intellectual property infringement. Please make sure you are reporting it correctly: -(1) The Abuse Process. You may submit an abuse report if you believe a Resident is exploiting the Second Life permissions system, for example, by using CopyBot or similar copying tools, to infringe intellectual property rights. The Abuse Team investigates and issues appropriate disciplinary action for behavior that violates the Second Life Community Standards or Terms of Service. However, the Abuse Team does not handle and will not respond to requests to remove content from the Second Life world. +(1) The Abuse Process. You may submit an abuse report if you believe a Resident is exploiting the [SECOND_LIFE] permissions system, for example, by using CopyBot or similar copying tools, to infringe intellectual property rights. The Abuse Team investigates and issues appropriate disciplinary action for behavior that violates the [SECOND_LIFE] Community Standards or Terms of Service. However, the Abuse Team does not handle and will not respond to requests to remove content from the [SECOND_LIFE] world. -(2) The DMCA or Content Removal Process. To request removal of content from Second Life, you MUST submit a valid notification of infringement as provided in our DMCA Policy at http://secondlife.com/corporate/dmca.php. +(2) The DMCA or Content Removal Process. To request removal of content from [SECOND_LIFE], you MUST submit a valid notification of infringement as provided in our DMCA Policy at http://secondlife.com/corporate/dmca.php. If you still wish to continue with the abuse process, please close this window and finish submitting your report. You may need to select the specific category 'CopyBot or Permissions Exploit'. @@ -4381,7 +4380,7 @@ Do you want to replace it with the selected object? <form name="form"> <ignore name="ignore" save_option="true" - text="When replacing existing attachments"/> + text="Replace an existing attachment with the selected item"/> <button default="true" ignore="Replace Automatically" @@ -4407,7 +4406,7 @@ Would you like to leave Busy Mode before completing this transaction? <form name="form"> <ignore name="ignore" save_option="true" - text="When paying a person or object in busy mode"/> + text="I am about to pay a person or object while I am in Busy mode"/> <button default="true" ignore="Always leave Busy Mode" @@ -4428,7 +4427,7 @@ Would you like to leave Busy Mode before completing this transaction? type="alertmodal"> Are you sure you want to permanently delete the contents of your Trash? <usetemplate - ignoretext="When emptying your inventory trash folder" + ignoretext="Confirm before I empty the inventory Trash folder" name="okcancelignore" notext="Cancel" yestext="OK"/> @@ -4438,7 +4437,7 @@ Are you sure you want to permanently delete the contents of your Trash? icon="alertmodal.tga" name="ConfirmClearBrowserCache" type="alertmodal"> -Are you sure you want to clear your browser cache? +Delete your travel, web, and search history? <usetemplate name="okcancelbuttons" notext="Cancel" @@ -4473,7 +4472,7 @@ Are you sure you want to clear your list of saved URLs? type="alertmodal"> Are you sure you want to permanently delete the contents of your Lost And Found? <usetemplate - ignoretext="When emptying your inventory Lost And Found folder" + ignoretext="Confirm before I empty the inventory Lost And Found folder" name="okcancelignore" notext="No" yestext="Yes"/> @@ -4486,10 +4485,10 @@ Are you sure you want to permanently delete the contents of your Lost And Found? The following SLurl has been copied to your clipboard: [SLURL] -Put it in a web page to give others easy access to this location or try it out yourself by pasting it into the address bar of your web browser. +Link to this from a web page to give others easy access to this location, or try it out yourself by pasting it into the address bar of any web browser. <form name="form"> <ignore name="ignore" - text="When copying a SLurl to your clipboard"/> + text="SLurl is copied to my clipboard"/> </form> </notification> @@ -4604,7 +4603,7 @@ Click "Advanced Water" to bring up an editor with more advanced settin icon="alertmodal.tga" name="HelpDayCycle" type="alertmodal"> -The Day Cycle Editor gives you control over the sky during Second Life's day/night cycle. This is the cycle that is used by the Basic Environment Editor's Time of Day slider. +The Day Cycle Editor gives you control over the sky during [SECOND_LIFE]'s day/night cycle. This is the cycle that is used by the Basic Environment Editor's Time of Day slider. The Day Cycle Editor works by setting keyframes. These are nodes (represented by the gray blips on the time graph) that have Sky Presets associated with them. As the Time of Day progresses, the WindLight sky "animates" as it interpolates between these keyframes. @@ -4771,7 +4770,7 @@ Controls the speed of the clouds as they move in the Y direction. icon="alertmodal.tga" name="HelpClassicClouds" type="alertmodal"> -Check this box to enable rendering of Second Life's older classic clouds in addition to WindLight's clouds. +Check this box to enable rendering of [SECOND_LIFE]'s older classic clouds in addition to WindLight's clouds. </notification> <notification @@ -4983,9 +4982,9 @@ Granting this request gives a script ongoing permission to take Linden dollars ( icon="alertmodal.tga" name="AutoWearNewClothing" type="alertmodal"> -Automatically wear the clothing you create? +Would you like to automatically wear the clothing you are about to create? <usetemplate - ignoretext="Automatically wear new clothing" + ignoretext="Wear the clothing I create while editing My Appearance" name="okcancelignore" notext="No" yestext="Yes"/> @@ -4995,7 +4994,7 @@ Automatically wear the clothing you create? icon="alertmodal.tga" name="NotAgeVerified" type="alertmodal"> -You must be age-verified to visit this area. Visit the Second Life website and verify your age? +You must be age-verified to visit this area. Do you want to go to the [SECOND_LIFE] website and verify your age? [_URL] <url option="0" name="url"> @@ -5003,7 +5002,7 @@ You must be age-verified to visit this area. Visit the Second Life website and https://secondlife.com/account/verification.php </url> <usetemplate - ignoretext="Warn about lack of age verification" + ignoretext="I have not verified my age" name="okcancelignore" notext="No" yestext="Yes"/> @@ -5013,7 +5012,7 @@ You must be age-verified to visit this area. Visit the Second Life website and icon="alertmodal.tga" name="Cannot enter parcel: no payment info on file" type="alertmodal"> -You must have payment information on file to visit this area. Visit the Second Life website and set this up? +You must have payment information on file to visit this area. Do you want to go to the [SECOND_LIFE] website and set this up? [_URL] <url option="0" name="url"> @@ -5021,7 +5020,7 @@ You must have payment information on file to visit this area. Visit the Second https://secondlife.com/account/ </url> <usetemplate - ignoretext="Warn about lack of payment info" + ignoretext="I lack payment information on file" name="okcancelignore" notext="No" yestext="Yes"/> @@ -5773,7 +5772,7 @@ How odd. The string [STRING_NAME] is missing from strings.xml icon="notify.tga" name="ObjectGiveItemUnknownUser" type="notify"> - An object named [OBJECTFROMNAME] owned by (an unknown user) has given you a [OBJECTTYPE] named [OBJECTNAME]. + An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you a [OBJECTTYPE] named [OBJECTNAME]. <form name="form"> <button index="0" @@ -6008,7 +6007,7 @@ How odd. The string [STRING_NAME] is missing from strings.xml icon="notify.tga" name="InvalidWearable" type="notify"> - The item you are trying to wear uses a feature that your viewer can't read. Please upgrade your version of Second Life to wear this item. + The item you are trying to wear uses a feature that your Viewer can't read. Please upgrade your version of [APP_NAME] to wear this item. </notification> <notification @@ -6146,7 +6145,7 @@ How odd. The string [STRING_NAME] is missing from strings.xml icon="notify.tga" name="FirstTeleport" type="notify"> - You can only teleport to certain areas in this region. The arrow points to your specific destination. Click to dismiss it. + You can only teleport to certain areas in this region. The arrow points to your specific destination. Click the arrow to dismiss it. </notification> <notification @@ -6185,7 +6184,7 @@ When you are done, press 'Save All'. type="notify"> This is a sandbox area, and is meant to help Residents learn how to build. - Things you build here will be deleted after you leave, so don't forget to right-click and choose 'take' to move your creation to your Inventory. + Things you build here will be deleted after you leave, so don't forget to right-click and choose 'Take' to move your creation to your Inventory. </notification> <notification @@ -6214,12 +6213,12 @@ When you are done, press 'Save All'. You are editing a Sculpted prim. Sculpties require a special texture to define their shape. </notification> - <notification + <!--notification icon="notify.tga" name="FirstMedia" type="notify"> You have begun playing media. Media can set to play automatically in the preferences window under Audio / Video. Note that this can be a security risk for media sites you do not trust. - </notification> + </notification--> <notification icon="notifytip.tga" @@ -6305,7 +6304,7 @@ Click Accept to join the call or Decline to decline the invitation. Click Block name="VoiceInviteAdHoc" type="notify"> [NAME] has joined a voice chat call with a conference chat. -Click Accept to join the call or Decline to decline the invitation. Click Block to block this user. +Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller. <unique> <context key="NAME"/> </unique> @@ -6330,7 +6329,7 @@ Click Accept to join the call or Decline to decline the invitation. Click Block name="InviteAdHoc" type="notify"> [NAME] is inviting you to a conference chat. -Click Accept to join the chat or Decline to decline the invitation. Click Block to block this user. +Click Accept to join the chat or Decline to decline the invitation. Click Block to block this caller. <unique> <context key="NAME"/> </unique> @@ -6516,9 +6515,9 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block </global> <global name="UnsupportedGLRequirements"> -You do not appear to have the proper hardware requirements for Second Life. Second Life requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system. +You do not appear to have the proper hardware requirements for [APP_NAME]. [APP_NAME] requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system. -If you continue to have problems, please visit: http://www.secondlife.com/support +If you continue to have problems, please visit the [SUPPORT_SITE]. </global> <global name="UnsupportedCPUAmount"> diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index 4f241664fbb185b1713ebf9934f77829d36b3f50..b6d0678cfb997824cb84fdc2182503ab9e75c92a 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -65,6 +65,7 @@ width="70" top_delta="-10" min_width="70" + name="movement_panel" user_resize="false"> <button follows="right" @@ -100,6 +101,7 @@ layout="topleft" min_height="28" min_width="150" + name="cam_panel" top_delta="-10" width="150"> <split_button @@ -113,6 +115,7 @@ image_unselected="camera_presets/camera_presets_arrow.png" image_disabled_selected="camera_presets/camera_presets_arrow.png" image_disabled="camera_presets/camera_presets_arrow.png" + name="camera_presets" tool_tip="Camera Presets" /> <split_button.item diff --git a/indra/newview/skins/default/xui/en/panel_classified.xml b/indra/newview/skins/default/xui/en/panel_classified.xml index 3acd8fae4b066e6445b7f101ff3f931c267de930..fde795260e7d12934166d982305f2c4bf406c178 100644 --- a/indra/newview/skins/default/xui/en/panel_classified.xml +++ b/indra/newview/skins/default/xui/en/panel_classified.xml @@ -84,7 +84,7 @@ <button follows="left|top" height="20" - label="Show on Map" + label="Map" layout="topleft" left_pad="5" name="classified_map_btn" diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml index b0f8052a9c9ba29709ee45019077c9bbbe3d294f..b336c86e9542435b097be41e37a316c65daebc2a 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml @@ -73,7 +73,7 @@ text_color="white" top="0" width="125"> - Second Life photo: + [SECOND_LIFE] photo: </text> <texture_picker allow_no_texture="true" @@ -149,7 +149,7 @@ text_color="white" top_pad="10" width="250"> - Second Life description: + [SECOND_LIFE] description: </text> <text_editor type="string" diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml index 9fa2765e97782a4feba1e06fead8ea62d9a58735..a38d7eee362edf67ec2f7aa784b5ff27d106ce2b 100644 --- a/indra/newview/skins/default/xui/en/panel_group_general.xml +++ b/indra/newview/skins/default/xui/en/panel_group_general.xml @@ -40,41 +40,6 @@ Hover your mouse over the options for more help. name="help_button" top="8" width="20" /> --> - <line_editor - follows="left|top" - font="SansSerifSmall" - prevalidate_callback="ascii" - halign="left" - height="16" - label="Type your new group name here" - layout="topleft" - left="10" - max_length="35" - name="group_name_editor" - top="10" - visible="false" - width="235" /> - <name_box - follows="left|top" - height="16" - initial_value="(retrieving)" - layout="topleft" - left="10" - name="founder_name" - top="10" - width="100" /> - <text - type="string" - follows="left|top" - height="16" - layout="topleft" - left_pad="10" - name="prepend_founded_by" - top_delta="0" - width="140"> - , Founder - </text> - <text_editor type="string" follows="left|top" 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 e90a57a3752769d728a38dbebb673bd725407158..be68187eaf2c59f7bd841bcc50c1aca20ef7ed86 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 @@ -40,6 +40,37 @@ follows="top|left|right" mouse_opaque="true" name="group_name">(Loading...)</text> + <texture_picker + follows="left|top" + height="113" + label="" + layout="topleft" + left_delta="-10" + name="insignia" + tool_tip="Click to choose a picture" + top_pad="5" + width="100" /> + <text + type="string" + follows="left|top" + height="16" + length="1" + layout="topleft" + left_pad="10" + name="prepend_founded_by" + top_delta="0" + width="140"> + Founded by: + </text> + <name_box + follows="left|top" + height="16" + initial_value="(retrieving)" + layout="topleft" + left_delta="0" + name="founder_name" + top_pad="10" + width="140" /> <button top="632" height="20" @@ -69,20 +100,20 @@ left="5" visible="false" width="65" /> - <accordion layout="topleft" left="2" width="296" top="28" height="600" follows="all" name="group_accordion"> + <accordion layout="topleft" left="2" width="296" top="135" height="600" follows="all" name="panel_me_profile"> <accordion_tab min_height="515" title="Group General" name="group_general_tab"> <panel class="panel_group_general" filename="panel_group_general.xml" name="group_general_tab_panel"/> </accordion_tab> - <accordion_tab min_height="380" title="Group Roles" name="group_roles_tab" can_resize="false"> + <accordion_tab min_height="380" title="Group Roles" name="group_roles_tab" expanded="False" can_resize="false"> <panel class="panel_group_roles" filename="panel_group_roles.xml" name="group_roles_tab_panel"/> </accordion_tab> - <accordion_tab min_height="530" title="Group Notices" name="group_notices_tab" can_resize="false"> + <accordion_tab min_height="530" title="Group Notices" name="group_notices_tab" expanded="False" can_resize="false"> <panel class="panel_group_notices" filename="panel_group_notices.xml" name="group_notices_tab_panel"/> </accordion_tab> - <accordion_tab min_height="270" title="Group Land Money" name="group_land_tab" can_resize="false"> + <accordion_tab min_height="270" title="Group Land Money" name="group_land_tab" expanded="False" can_resize="false"> <panel class="panel_group_land_money" filename="panel_group_land_money.xml" name="group_land_tab_panel"/> </accordion_tab> </accordion> -</panel> +</panel> \ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml index d24d11039acc74c5e30ba31954ab1a907bd8007b..4d373fbf3a514a099240abec2d812c56af6e7731 100644 --- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml @@ -87,8 +87,8 @@ <button follows="top" height="20" - label="Show on Map" - label_selected="Show on Map" + label="Map" + label_selected="Map" layout="topleft" left="150" name="map_button" 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 33592d289f0de5619f6f408dbbf7b8c4228e2821..b4d2bbb19487c96cdcec03a2eede0adad5ab1871 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml @@ -143,7 +143,7 @@ follows="bottom|left" font="SansSerifSmallBold" height="25" - label="Show on Map" + label="Map" layout="topleft" left_pad="2" name="show_on_map_btn" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml index 0e87c621b9d05b1a773dcda6c48404c5716dc0e9..060d84b2e4870e1930ec72bf9037a5a6f7ac4030 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml @@ -10,8 +10,14 @@ name="advanced" top="1" width="517"> - - + <panel.string + name="resolution_format"> + [RES_X] x [RES_Y] + </panel.string> + <panel.string + name="aspect_ratio_text"> + [NUM]:[DEN] + </panel.string> <check_box control_name="UseChatBubbles" height="16" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index 0c01aec95d5fb246772ca29c4bc70cea93883b10..ecfb0048a3793d603b71c7b65cdd722e8b41670e 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -9,14 +9,6 @@ name="Display panel" top="1" width="517"> - <panel.string - name="resolution_format"> - [RES_X] x [RES_Y] - </panel.string> - <panel.string - name="aspect_ratio_text"> - [NUM]:[DEN] - </panel.string> <text type="string" length="1" @@ -39,63 +31,63 @@ top_pad="4" width="175"> </check_box> - <combo_box + <combo_box visiblity_control="WindowFullScreen" - allow_text_entry="false" - enabled="true" - layout="topleft" - height="18" - left_delta="220" - max_chars="20" - mouse_opaque="true" - name="windowsize combo" - top_delta="-1" - width="150"> - <combo_box.item - type="string" - length="1" - enabled="true" - name="640x480" - value="640 x 480"> - 640x480 - </combo_box.item> - <combo_box.item - type="string" - length="1" - enabled="true" - name="800x600" - value="800 x 600"> - 800x600 - </combo_box.item> - <combo_box.item - type="string" - length="1" - enabled="true" - name="720x480" - value="720 x 480"> - 720x480 (NTSC) - </combo_box.item> - <combo_box.item - type="string" - length="1" - enabled="true" - name="768x576" - value="768 x 576"> - 768x576 (PAL) - </combo_box.item> - <combo_box.item - type="string" - length="1" - enabled="true" - name="1024x768" - value="1024 x 768"> - 1024x768 - </combo_box.item> - <combo_box.commit_callback - function="setControlFalse" - parameter="FullScreenAutoDetectAspectRatio" /> + allow_text_entry="false" + enabled="true" + layout="topleft" + height="18" + left_delta="220" + max_chars="20" + mouse_opaque="true" + name="windowsize combo" + top_delta="-1" + width="150"> + <combo_box.item + type="string" + length="1" + enabled="true" + name="640x480" + value="640 x 480"> + 640x480 + </combo_box.item> + <combo_box.item + type="string" + length="1" + enabled="true" + name="800x600" + value="800 x 600"> + 800x600 + </combo_box.item> + <combo_box.item + type="string" + length="1" + enabled="true" + name="720x480" + value="720 x 480"> + 720x480 (NTSC) + </combo_box.item> + <combo_box.item + type="string" + length="1" + enabled="true" + name="768x576" + value="768 x 576"> + 768x576 (PAL) + </combo_box.item> + <combo_box.item + type="string" + length="1" + enabled="true" + name="1024x768" + value="1024 x 768"> + 1024x768 + </combo_box.item> + <combo_box.commit_callback + function="Pref.setControlFalse" + parameter="FullScreenAutoDetectAspectRatio" /> </combo_box> - <text + <text type="string" length="1" follows="left|top" @@ -134,7 +126,6 @@ name="ui_scale_slider" top_delta="0" width="58" /> - <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml index 65db3cc7a15c175a4b89c0f751f950576101d3eb..5d0af26af52f7430af0e89b938d1ce1fae16d4ed 100644 --- a/indra/newview/skins/default/xui/en/panel_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_profile.xml @@ -64,7 +64,6 @@ reserve_scroll_corner="true" opaque="true" width="255"> - <panel name="scroll_content_panel" follows="left|top|right" @@ -73,7 +72,7 @@ left="0" width="240" height="520"> - + <panel follows="left|top" height="125" @@ -102,7 +101,7 @@ name="title_sl_descr_text" text_color="white" top_delta="0" - value="Second Life:" + value="[SECOND_LIFE]:" width="140" /> <text follows="left|top|right" @@ -208,6 +207,60 @@ value="Resident. No payment info on file." width="160" word_wrap="true" /> + <spinner + control_name="AFKTimeout" + decimal_digits="0" + follows="left|top" + height="16" + increment="1" + initial_value="300" + label="Away Timeout:" + label_width="141" + layout="topleft" + left="10" + max_val="600" + min_val="30" + name="afk_timeout_spinner" + top_pad="10" + width="202" /> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left="220" + name="seconds_textbox" + top_delta="0" + width="128"> + seconds + </text> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left="12" + mouse_opaque="false" + name="text_box3" + top_pad="10" + width="128"> + Busy Mode Response: + </text> + <text_editor + control_name="BusyModeResponse2" + commit_on_focus_lost = "true" + follows="left|top" + height="70" + layout="topleft" + left_pad="8" + name="busy_response" + top_delta="0" + width="330" + word_wrap="true"> + log_in_to_change + </text_editor> <text follows="left|top" font="SansSerifBold" @@ -260,7 +313,7 @@ left="10" name="online_me_status_text" text_color="white" - top_pad="20" + top_pad="20" width="100"> Status: </text> @@ -308,10 +361,10 @@ 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" diff --git a/indra/newview/skins/default/xui/en/panel_region_covenant.xml b/indra/newview/skins/default/xui/en/panel_region_covenant.xml index 8265ab32274707b0a2a4aa15a47ab68aa01ba52e..8445b933bf44678c4cc8c12773f291572e5c0bff 100644 --- a/indra/newview/skins/default/xui/en/panel_region_covenant.xml +++ b/indra/newview/skins/default/xui/en/panel_region_covenant.xml @@ -140,6 +140,7 @@ max_length="65535" name="covenant_editor" top_delta="30" + handle_edit_keys_directly="true" width="193" word_wrap="true"> There is no Covenant provided for this Estate. diff --git a/indra/newview/skins/default/xui/en/panel_region_estate.xml b/indra/newview/skins/default/xui/en/panel_region_estate.xml index 1dafd50cdbc8f668b5546c9babe6a606d4a04765..ee5218411925be5b5f3054e397ca570d4f39a45c 100644 --- a/indra/newview/skins/default/xui/en/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/en/panel_region_estate.xml @@ -2,517 +2,529 @@ <panel border="true" follows="top|left" - height="950" + height="512" + name="EstateWrapper" label="Estate" layout="topleft" - left="0" - name="Estate" - top="320" width="280"> - <panel.string - name="email_unsupported"> - Feature unsupported - </panel.string> - <text - type="string" - length="1" - follows="left|top" - height="32" + <scroll_container + follows="top|left|right|bottom" + height="508" + layout="topleft" + width="280"> + <panel + follows="top|left" + height="950" + label="Estate" layout="topleft" - left="10" - name="estate_help_text" - top="14" - width="300"> + name="Estate" + width="258"> + <panel.string + name="email_unsupported"> + Feature unsupported + </panel.string> + <text + type="string" + length="1" + follows="left|top" + height="32" + layout="topleft" + left="10" + name="estate_help_text" + top="14" + width="300"> Changes to settings on this tab will affect all -regions in the estate. - </text> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="20" - layout="topleft" - left_delta="0" - name="estate_text" - top_pad="2" - width="80"> + regions in the estate. + </text> + <text + type="string" + length="1" + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left_delta="0" + name="estate_text" + top_pad="2" + width="80"> Estate: - </text> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="20" - layout="topleft" - left_delta="0" - name="estate_name" - top_delta="16" - width="150"> + </text> + <text + type="string" + length="1" + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left_delta="0" + name="estate_name" + top_delta="16" + width="150"> (unknown) - </text> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="20" - layout="topleft" - left_delta="0" - name="owner_text" - top_pad="2" - width="80"> + </text> + <text + type="string" + length="1" + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left_delta="0" + name="owner_text" + top_pad="2" + width="80"> Owner: - </text> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="20" - layout="topleft" - left_delta="0" - name="estate_owner" - top_delta="16" - width="150"> + </text> + <text + type="string" + length="1" + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left_delta="0" + name="estate_owner" + top_delta="16" + width="150"> (unknown) - </text> - <view_border - bevel_style="in" - follows="top|left" - height="290" - layout="topleft" - left_delta="-4" - top_pad="5" - width="250" /> - <check_box - height="20" - label="Use Global Time" - layout="topleft" - left="12" - name="use_global_time_check" - top="132" - width="200" /> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_pad="20" - name="use_global_time_help" - top_delta="2" - width="18" /> - <check_box - height="20" - label="Fixed Sun" - layout="topleft" - left="12" - name="fixed_sun_check" - top="152" - width="100" /> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_pad="120" - name="fixed_sun_help" - top_delta="2" - width="18" /> - <icon - height="20" - image_name="icon_day_cycle.tga" - layout="topleft" - left="47" - name="daycycle" - top="177" - width="165" /> - <slider - follows="left|top" - height="20" - increment="0.001" - label="Phase" - layout="topleft" - left="12" - max_val="30" - min_val="6" - name="sun_hour_slider" - show_text="false" - top="202" - width="200" /> - <check_box - height="20" - label="Allow Public Access" - layout="topleft" - left_delta="0" - name="externally_visible_check" - top_pad="6" - width="200" /> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_pad="20" - name="externally_visible_help" - top_delta="2" - width="18" /> - <text - type="string" - length="1" - follows="top|left" - height="16" - layout="topleft" - left="32" - name="Only Allow" - top="250" - width="278"> + </text> + <view_border + bevel_style="in" + follows="top|left" + height="290" + layout="topleft" + left_delta="-4" + top_pad="5" + width="250" /> + <check_box + height="20" + label="Use Global Time" + layout="topleft" + left="12" + name="use_global_time_check" + top="132" + width="200" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="20" + name="use_global_time_help" + top_delta="2" + width="18" /> + <check_box + height="20" + label="Fixed Sun" + layout="topleft" + left="12" + name="fixed_sun_check" + top="152" + width="100" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="120" + name="fixed_sun_help" + top_delta="2" + width="18" /> + <icon + height="20" + image_name="icon_day_cycle.tga" + layout="topleft" + left="47" + name="daycycle" + top="177" + width="165" /> + <slider + follows="left|top" + height="20" + increment="0.001" + label="Phase" + layout="topleft" + left="12" + max_val="30" + min_val="6" + name="sun_hour_slider" + show_text="false" + top="202" + width="200" /> + <check_box + height="20" + label="Allow Public Access" + layout="topleft" + left_delta="0" + name="externally_visible_check" + top_pad="6" + width="200" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="20" + name="externally_visible_help" + top_delta="2" + width="18" /> + <text + type="string" + length="1" + follows="top|left" + height="16" + layout="topleft" + left="32" + name="Only Allow" + top="250" + width="278"> Restrict Access To: - </text> - <check_box - follows="top|left" - height="16" - label="Residents with payment info on file" - layout="topleft" - left_delta="0" - name="limit_payment" - tool_tip="Ban unidentified residents." - top_pad="2" - width="278" /> - <check_box - follows="top|left" - height="16" - label="Age-verified adults" - layout="topleft" - left_delta="0" - name="limit_age_verified" - tool_tip="Ban residents who have not verified their age. See support.secondlife.com for more information." - top_pad="2" - width="278" /> - <check_box - height="20" - label="Allow Voice Chat" - layout="topleft" - left="12" - name="voice_chat_check" - top="304" - width="200" /> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_pad="20" - name="voice_chat_help" - top_delta="2" - width="18" /> - <check_box - height="20" - label="Allow Direct Teleport" - layout="topleft" - left="12" - name="allow_direct_teleport" - top_pad="4" - width="80" /> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_pad="140" - name="allow_direct_teleport_help" - top_delta="2" - width="18" /> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left="10" - name="abuse_email_text" - top_pad="5" - width="180"> + </text> + <check_box + follows="top|left" + height="16" + label="Residents with payment info on file" + layout="topleft" + left_delta="0" + name="limit_payment" + tool_tip="Ban unidentified residents." + top_pad="2" + width="278" /> + <check_box + follows="top|left" + height="16" + label="Age-verified adults" + layout="topleft" + left_delta="0" + name="limit_age_verified" + tool_tip="Ban residents who have not verified their age. See the [SUPPORT_SITE] for more information." + top_pad="2" + width="278" /> + <check_box + height="20" + label="Allow Voice Chat" + layout="topleft" + left="12" + name="voice_chat_check" + top="304" + width="200" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="20" + name="voice_chat_help" + top_delta="2" + width="18" /> + <check_box + height="20" + label="Allow Direct Teleport" + layout="topleft" + left="12" + name="allow_direct_teleport" + top_pad="4" + width="80" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="140" + name="allow_direct_teleport_help" + top_delta="2" + width="18" /> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="10" + name="abuse_email_text" + top_pad="5" + width="180"> Abuse email address: - </text> - <line_editor - follows="top|left" - height="19" - layout="topleft" - left="15" - name="abuse_email_address" - top_pad="5" - width="205" /> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_pad="12" - name="abuse_email_address_help" - top_dekta="0" - width="18" /> - <button - enabled="false" - follows="left|top" - height="20" - label="Apply" - layout="topleft" - name="apply_btn" - right="250" - top_pad="4" - width="90" /> - <button - follows="left|top" - height="20" - label="Send Message To Estate..." - layout="topleft" - left="8" - name="message_estate_btn" - top_pad="5" - width="250" /> - <button - follows="left|top" - height="20" - label="Kick User from Estate..." - layout="topleft" - left="8" - name="kick_user_from_estate_btn" - top_pad="5" - width="250" /> - <text - type="string" - length="1" - top="490" - follows="left|top" - height="20" - layout="topleft" - name="estate_manager_label" - left="8" - width="200"> + </text> + <line_editor + follows="top|left" + height="19" + layout="topleft" + left="15" + name="abuse_email_address" + top_pad="5" + width="205" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="12" + name="abuse_email_address_help" + top_delta="0" + width="18" /> + <button + enabled="false" + follows="left|top" + height="20" + label="Apply" + layout="topleft" + name="apply_btn" + right="250" + top_pad="4" + width="90" /> + <button + follows="left|top" + height="20" + label="Send Message To Estate..." + layout="topleft" + left="8" + name="message_estate_btn" + top_pad="5" + width="250" /> + <button + follows="left|top" + height="20" + label="Kick User from Estate..." + layout="topleft" + left="8" + name="kick_user_from_estate_btn" + top_pad="5" + width="250" /> + <text + type="string" + length="1" + top="490" + follows="left|top" + height="20" + layout="topleft" + name="estate_manager_label" + left="8" + width="200"> Estate Managers: - </text> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_delta="232" - name="estate_manager_help" - top_delta="-1" - width="18" /> - <view_border - bevel_style="none" - follows="top|left" - height="60" - layout="topleft" - left="8" - top_pad="5" - width="250" /> - <name_list - follows="left|top" - height="60" - layout="topleft" - left_delta="0" - multi_select="true" - name="estate_manager_name_list" - top_delta="0" - width="250" /> - <button - follows="left|top" - height="20" - label="Add..." - layout="topleft" - left="8" - name="add_estate_manager_btn" - top_pad="5" - width="90" /> - <button - follows="left|top" - height="20" - label="Remove..." - layout="topleft" - name="remove_estate_manager_btn" - left_pad="70" - top_delta="0" - width="90" /> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left="8" - name="allow_resident_label" - top_pad="5" - width="200"> + </text> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_delta="232" + name="estate_manager_help" + top_delta="-1" + width="18" /> + <view_border + bevel_style="none" + follows="top|left" + height="60" + layout="topleft" + left="8" + top_pad="5" + width="250" /> + <name_list + follows="left|top" + height="60" + layout="topleft" + left_delta="0" + multi_select="true" + name="estate_manager_name_list" + top_delta="0" + width="250" /> + <button + follows="left|top" + height="20" + label="Add..." + layout="topleft" + left="8" + name="add_estate_manager_btn" + top_pad="5" + width="90" /> + <button + follows="left|top" + height="20" + label="Remove..." + layout="topleft" + name="remove_estate_manager_btn" + left_pad="70" + top_delta="0" + width="90" /> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="8" + name="allow_resident_label" + top_pad="5" + width="200"> Allowed Residents: - </text> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_delta="232" - name="allow_resident_help" - top_delta="-1" - width="18" /> - <view_border - bevel_style="none" - follows="top|left" - height="60" - layout="topleft" - left="8" - top_pad="5" - width="250" /> - <name_list - follows="left|top" - height="60" - layout="topleft" - left_delta="0" - multi_select="true" - name="allowed_avatar_name_list" - top_delta="0" - width="250" /> - <button - follows="left|top" - height="20" - label="Add..." - layout="topleft" - left="8" - name="add_allowed_avatar_btn" - top_pad="5" - width="90" /> - <button - follows="left|top" - height="20" - label="Remove..." - layout="topleft" - name="remove_allowed_avatar_btn" - left_pad="70" - top_delta="0" - width="90" /> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left="8" - name="allow_group_label" - top_pad="5" - width="200"> + </text> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_delta="232" + name="allow_resident_help" + top_delta="-1" + width="18" /> + <view_border + bevel_style="none" + follows="top|left" + height="60" + layout="topleft" + left="8" + top_pad="5" + width="250" /> + <name_list + follows="left|top" + height="60" + layout="topleft" + left_delta="0" + multi_select="true" + name="allowed_avatar_name_list" + top_delta="0" + width="250" /> + <button + follows="left|top" + height="20" + label="Add..." + layout="topleft" + left="8" + name="add_allowed_avatar_btn" + top_pad="5" + width="90" /> + <button + follows="left|top" + height="20" + label="Remove..." + layout="topleft" + name="remove_allowed_avatar_btn" + left_pad="70" + top_delta="0" + width="90" /> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="8" + name="allow_group_label" + top_pad="5" + width="200"> Allowed Groups: - </text> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_delta="232" - name="allow_group_help" - top_delta="-1" - width="18" /> - <view_border - bevel_style="none" - follows="top|left" - height="60" - layout="topleft" - left="8" - top_pad="5" - width="250" /> - <name_list - follows="left|top" - height="60" - layout="topleft" - left_delta="0" - multi_select="true" - name="allowed_group_name_list" - top_delta="0" - width="250" /> - <button - follows="left|top" - height="20" - label="Add..." - layout="topleft" - left="8" - name="add_allowed_group_btn" - top_pad="5" - width="90" /> - <button - follows="left|top" - height="20" - label="Remove..." - layout="topleft" - name="remove_allowed_group_btn" - left_pad="70" - top_delta="0" - width="90" /> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left="8" - name="ban_resident_label" - top_pad="5" - width="200"> + </text> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_delta="232" + name="allow_group_help" + top_delta="-1" + width="18" /> + <view_border + bevel_style="none" + follows="top|left" + height="60" + layout="topleft" + left="8" + top_pad="5" + width="250" /> + <name_list + follows="left|top" + height="60" + layout="topleft" + left_delta="0" + multi_select="true" + name="allowed_group_name_list" + top_delta="0" + width="250" /> + <button + follows="left|top" + height="20" + label="Add..." + layout="topleft" + left="8" + name="add_allowed_group_btn" + top_pad="5" + width="90" /> + <button + follows="left|top" + height="20" + label="Remove..." + layout="topleft" + name="remove_allowed_group_btn" + left_pad="70" + top_delta="0" + width="90" /> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="8" + name="ban_resident_label" + top_pad="5" + width="200"> Banned Residents: - </text> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_delta="232" - name="ban_resident_help" - top_delta="-1" - width="18" /> - <view_border - bevel_style="none" - follows="top|left" - height="60" - layout="topleft" - left="8" - top_pad="5" - width="250" /> - <name_list - follows="left|top" - height="60" - layout="topleft" - left_delta="0" - multi_select="true" - name="banned_avatar_name_list" - top_delta="0" - width="250" /> - <button - follows="left|top" - height="20" - label="Add..." - layout="topleft" - left="8" - name="add_banned_avatar_btn" - top_pad="5" - width="90" /> - <button - follows="left|top" - height="20" - label="Remove..." - layout="topleft" - name="remove_banned_avatar_btn" - left_pad="70" - top_delta="0" - width="90" /> + </text> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_delta="232" + name="ban_resident_help" + top_delta="-1" + width="18" /> + <view_border + bevel_style="none" + follows="top|left" + height="60" + layout="topleft" + left="8" + top_pad="5" + width="250" /> + <name_list + follows="left|top" + height="60" + layout="topleft" + left_delta="0" + multi_select="true" + name="banned_avatar_name_list" + top_delta="0" + width="250" /> + <button + follows="left|top" + height="20" + label="Add..." + layout="topleft" + left="8" + name="add_banned_avatar_btn" + top_pad="5" + width="90" /> + <button + follows="left|top" + height="20" + label="Remove..." + layout="topleft" + name="remove_banned_avatar_btn" + left_pad="70" + top_delta="0" + width="90" /> + </panel> + </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_region_texture.xml b/indra/newview/skins/default/xui/en/panel_region_texture.xml index bf63bb0cb60a1259b1484a8c1ec46e2c724d3b98..8e8fc9ef7f447a38ac27ddc1225663670ccb7b7e 100644 --- a/indra/newview/skins/default/xui/en/panel_region_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_region_texture.xml @@ -2,333 +2,344 @@ <panel border="true" follows="top|left" - height="575" + height="512" label="Ground Textures" layout="topleft" - left="0" - name="Textures" - top="320" width="280"> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="20" + <scroll_container + follows="top|left|right|bottom" + height="508" + layout="topleft" + width="280"> + <panel + follows="top|left" + height="575" + label="Ground Textures" layout="topleft" - left="10" - name="region_text_lbl" - top="10" - width="100"> + name="Textures" + width="258"> + <text + type="string" + length="1" + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left="10" + name="region_text_lbl" + top="10" + width="100"> Region: - </text> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="20" - layout="topleft" - left_delta="50" - name="region_text" - top_delta="0" - width="200"> + </text> + <text + type="string" + length="1" + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left_delta="50" + name="region_text" + top_delta="0" + width="200"> unknown - </text> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left="10" - name="detail_texture_text" - top="36" - width="300"> + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="10" + name="detail_texture_text" + top="36" + width="300"> Terrain Textures -(requires 512x512, 24 bit .tga files) - </text> - <texture_picker - follows="left|top" - height="100" - layout="topleft" - left_delta="0" - name="texture_detail_0" - top_delta="30" - width="100" /> - <texture_picker - follows="left|top" - height="100" - layout="topleft" - left_pad="10" - name="texture_detail_1" - top_delta="0" - width="100" /> - <texture_picker - follows="left|top" - height="100" - layout="topleft" - left="10" - name="texture_detail_2" - top_delta="105" - width="100" /> - <texture_picker - follows="left|top" - height="100" - layout="topleft" - left_pad="10" - name="texture_detail_3" - top_delta="0" - width="100" /> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left="10" - name="height_text_lbl" - top="157" - width="65"> + (requires 512x512, 24 bit .tga files) + </text> + <texture_picker + follows="left|top" + height="100" + layout="topleft" + left_delta="0" + name="texture_detail_0" + top_delta="30" + width="100" /> + <texture_picker + follows="left|top" + height="100" + layout="topleft" + left_pad="10" + name="texture_detail_1" + top_delta="0" + width="100" /> + <texture_picker + follows="left|top" + height="100" + layout="topleft" + left="10" + name="texture_detail_2" + top_delta="105" + width="100" /> + <texture_picker + follows="left|top" + height="100" + layout="topleft" + left_pad="10" + name="texture_detail_3" + top_delta="0" + width="100" /> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="10" + name="height_text_lbl" + top="157" + width="65"> 1 (Low) - </text> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left_pad="45" - name="height_text_lbl2" - top_delta="0" - width="100"> + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left_pad="45" + name="height_text_lbl2" + top_delta="0" + width="100"> 2 - </text> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left="10" - name="height_text_lbl3" - top_delta="105" - width="100"> + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="10" + name="height_text_lbl3" + top_delta="105" + width="100"> 3 - </text> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left_pad="10" - name="height_text_lbl4" - top_delta="0" - width="100"> + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left_pad="10" + name="height_text_lbl4" + top_delta="0" + width="100"> 4 (High) - </text> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left="10" - name="height_text_lbl5" - top_delta="25" - width="300"> + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="10" + name="height_text_lbl5" + top_delta="25" + width="300"> Texture Elevation Ranges - </text> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left="51" - name="height_text_lbl6" - top_delta="20" - width="100"> + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="51" + name="height_text_lbl6" + top_delta="20" + width="100"> Southwest - </text> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left_pad="10" - name="height_text_lbl7" - top_delta="0" - width="100"> + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left_pad="10" + name="height_text_lbl7" + top_delta="0" + width="100"> Northwest - </text> - <spinner - follows="left|top" - height="20" - increment="0.5" - label="Low" - label_width="37" - layout="topleft" - left="10" - max_val="500" - min_val="-500" - name="height_start_spin_0" - top_delta="20" - width="100" /> - <spinner - follows="left|top" - height="20" - increment="0.5" - label="Low" - label_width="37" - layout="topleft" - left_pad="10" - max_val="500" - min_val="-500" - name="height_start_spin_1" - top_delta="0" - width="100" /> - <spinner - follows="left|top" - height="20" - increment="0.5" - label="High" - label_width="37" - layout="topleft" - left="10" - max_val="500" - min_val="-500" - name="height_range_spin_0" - top_delta="20" - width="100" /> - <spinner - follows="left|top" - height="20" - increment="0.5" - label="High" - label_width="37" - layout="topleft" - left_pad="10" - max_val="500" - min_val="-500" - name="height_range_spin_1" - top_delta="0" - width="100" /> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left="51" - name="height_text_lbl8" - top_delta="30" - width="100"> + </text> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="Low" + label_width="37" + layout="topleft" + left="10" + max_val="500" + min_val="-500" + name="height_start_spin_0" + top_delta="20" + width="100" /> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="Low" + label_width="37" + layout="topleft" + left_pad="10" + max_val="500" + min_val="-500" + name="height_start_spin_1" + top_delta="0" + width="100" /> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="High" + label_width="37" + layout="topleft" + left="10" + max_val="500" + min_val="-500" + name="height_range_spin_0" + top_delta="20" + width="100" /> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="High" + label_width="37" + layout="topleft" + left_pad="10" + max_val="500" + min_val="-500" + name="height_range_spin_1" + top_delta="0" + width="100" /> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="51" + name="height_text_lbl8" + top_delta="30" + width="100"> Southeast - </text> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left_pad="10" - name="height_text_lbl9" - top_delta="0" - width="100"> + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left_pad="10" + name="height_text_lbl9" + top_delta="0" + width="100"> Northeast - </text> - <spinner - follows="left|top" - height="20" - increment="0.5" - label="Low" - label_width="37" - layout="topleft" - left="10" - max_val="500" - min_val="-500" - name="height_start_spin_2" - top_delta="20" - width="100" /> - <spinner - follows="left|top" - height="20" - increment="0.5" - label="Low" - label_width="37" - layout="topleft" - left_pad="10" - max_val="500" - min_val="-500" - name="height_start_spin_3" - top_delta="0" - width="100" /> - <spinner - follows="left|top" - height="20" - increment="0.5" - label="High" - label_width="37" - layout="topleft" - left="10" - max_val="500" - min_val="-500" - name="height_range_spin_2" - top_delta="20" - width="100" /> - <spinner - follows="left|top" - height="20" - increment="0.5" - label="High" - label_width="37" - layout="topleft" - left_pad="10" - max_val="500" - min_val="-500" - name="height_range_spin_3" - top_delta="0" - width="100" /> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left="10" - name="height_text_lbl10" - top_delta="30" - width="270"> + </text> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="Low" + label_width="37" + layout="topleft" + left="10" + max_val="500" + min_val="-500" + name="height_start_spin_2" + top_delta="20" + width="100" /> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="Low" + label_width="37" + layout="topleft" + left_pad="10" + max_val="500" + min_val="-500" + name="height_start_spin_3" + top_delta="0" + width="100" /> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="High" + label_width="37" + layout="topleft" + left="10" + max_val="500" + min_val="-500" + name="height_range_spin_2" + top_delta="20" + width="100" /> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="High" + label_width="37" + layout="topleft" + left_pad="10" + max_val="500" + min_val="-500" + name="height_range_spin_3" + top_delta="0" + width="100" /> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="10" + name="height_text_lbl10" + top_delta="30" + width="270"> These values represent the blend range -for the textures above. - </text> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left_delta="0" - name="height_text_lbl11" - top_delta="32" - width="270"> - Measured in meters, the LOW value -is the MAXIMUM height of Texture #1, -and the HIGH value is the MINIMUM -height of Texture #4. - </text> - - <button - enabled="false" - follows="left|bottom" - height="20" - label="Apply" - layout="topleft" - left="120" - name="apply_btn" - top_delta="60" - width="100" /> + for the textures above. + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left_delta="0" + name="height_text_lbl11" + top_delta="32" + width="270"> + Measured in meters, the LOW value + is the MAXIMUM height of Texture #1, + and the HIGH value is the MINIMUM + height of Texture #4. + </text> + + <button + enabled="false" + follows="left|bottom" + height="20" + label="Apply" + layout="topleft" + left="120" + name="apply_btn" + top_delta="60" + width="100" /> + </panel> + </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml index 9fd075f79bc79d105a0d190671376b0d55ac46cd..5738879c5a53281d47cf4cb98ca06bff87a0d182 100644 --- a/indra/newview/skins/default/xui/en/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml @@ -44,6 +44,8 @@ max_length="65536" name="Script Editor" width="492" + show_line_numbers="true" + handle_edit_keys_directly="true" word_wrap="true"> Loading... </text_editor> diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml index 82b7e02aeb654b2a8cd4bc28c18d66a21d8c9d14..3ad5cbe018cbe208402765cbdf4f3aba0914b925 100644 --- a/indra/newview/skins/default/xui/en/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml @@ -224,7 +224,7 @@ left_delta="1" name="search_editor" tab_group="1" - tool_tip="Search Second Life" + tool_tip="Search [SECOND_LIFE]" top_delta="4" width="78" /> <button @@ -240,7 +240,7 @@ name="search_btn" picture_style="true" scale_image="false" - tool_tip="Search Second Life" + tool_tip="Search [SECOND_LIFE]" top_delta="-4" width="16" /> <text diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 3d4ac940448fa6ded728b8bb4ed2f52c05eace42..655cf2b40f790fa7413d68e9b1e73053b3f0d211 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -7,9 +7,9 @@ <!-- Default Args - these arguments will be replaced in all strings --> <string name="SECOND_LIFE">Second Life</string> - <string name="SECOND_LIFE_VIEWER">Second Life</string> - <string name="SECOND_LIFE_GRID">Second Life</string> - <string name="SECOND_LIFE_SUPPORT">Second Life Support Portal</string> + <string name="APP_NAME">Second Life</string> + <string name="SECOND_LIFE_GRID">Second Life Grid</string> + <string name="SUPPORT_SITE">Second Life Support Portal</string> <!-- starting up --> <string name="StartupDetectingHardware">Detecting hardware...</string> @@ -19,7 +19,7 @@ <string name="CacheNobody">(nobody)</string> <string name="CacheNone">(none)</string> <!-- Login --> - <string name="LoginInProgress">Logging in. [SECOND_LIFE_VIEWER] may appear frozen. Please wait.</string> + <string name="LoginInProgress">Logging in. [APP_NAME] may appear frozen. Please wait.</string> <string name="LoginInProgressNoFrozen">Logging in...</string> <string name="LoginAuthenticating">Authenticating</string> <string name="LoginMaintenance">Performing account maintenance...</string> @@ -683,29 +683,29 @@ Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh Please see: http://wiki.secondlife.com/wiki/Client_parameters Error: </string> - <string name="MBCmdLineUsg">[SECOND_LIFE] Command line usage:</string> + <string name="MBCmdLineUsg">[APP_NAME] Command line usage:</string> <string name="MBUnableToAccessFile"> - [SECOND_LIFE] is unable to access a file that it needs. + [APP_NAME] is unable to access a file that it needs. This can be because you somehow have multiple copies running, or your system incorrectly thinks a file is open. If this message persists, restart your computer and try again. -If it continues to persist, you may need to completely uninstall [SECOND_LIFE] and reinstall it. +If it continues to persist, you may need to completely uninstall [APP_NAME] and reinstall it. </string> <string name="MBFatalError">Fatal Error</string> - <string name="MBRequiresAltiVec"> [SECOND_LIFE] requires a processor with AltiVec (G4 or later).</string> + <string name="MBRequiresAltiVec"> [APP_NAME] requires a processor with AltiVec (G4 or later).</string> <string name="MBAlreadyRunning"> - [SECOND_LIFE] is already running. + [APP_NAME] is already running. Check your task bar for a minimized copy of the program. If this message persists, restart your computer. </string> <string name="MBFrozenCrashed"> - [SECOND_LIFE] appears to have frozen or crashed on the previous run. + [APP_NAME] appears to have frozen or crashed on the previous run. Would you like to send a crash report? </string> <string name="MBAlert">Alert</string> <string name="MBNoDirectX"> - [SECOND_LIFE] is unable to detect DirectX 9.0b or greater. -[SECOND_LIFE] uses DirectX to detect hardware and/or outdated drivers that can cause stability problems, poor performance and crashes. While you can run [SECOND_LIFE] without it, we highly recommend running with DirectX 9.0b. + [APP_NAME] is unable to detect DirectX 9.0b or greater. +[APP_NAME] uses DirectX to detect hardware and/or outdated drivers that can cause stability problems, poor performance and crashes. While you can run [APP_NAME] without it, we highly recommend running with DirectX 9.0b. Do you wish to continue? </string> @@ -726,23 +726,23 @@ Running in window. <string name="MBPixelFmtErr">Can't find suitable pixel format</string> <string name="MBPixelFmtDescErr">Can't get pixel format description</string> <string name="MBTrueColorWindow"> - [SECOND_LIFE] requires True Color (32-bit) to run in a window. + [APP_NAME] requires True Color (32-bit) to run in a window. Please go to Control Panels > Display > Settings and set the screen to 32-bit color. -Alternately, if you choose to run fullscreen, [SECOND_LIFE] will automatically adjust the screen each time it runs. +Alternately, if you choose to run fullscreen, [APP_NAME] will automatically adjust the screen each time it runs. </string> <string name="MBAlpha"> - [SECOND_LIFE] is unable to run because it can't get an 8 bit alpha channel. Usually this is due to video card driver issues. + [APP_NAME] is unable to run because it can't get an 8 bit alpha channel. Usually this is due to video card driver issues. Please make sure you have the latest video card drivers installed. Also be sure your monitor is set to True Color (32-bit) in Control Panels > Display > Settings. -If you continue to receive this message, contact customer support. +If you continue to receive this message, contact the [SUPPORT_SITE]. </string> <string name="MBPixelFmtSetErr">Can't set pixel format</string> <string name="MBGLContextErr">Can't create GL rendering context</string> <string name="MBGLContextActErr">Can't activate GL rendering context</string> <string name="MBVideoDrvErr"> - [SECOND_LIFE] is unable to run because your video card drivers did not install properly, are out of date, or are for unsupported hardware. Please make sure you have the latest video card drivers and even if you do have the latest, try reinstalling them. + [APP_NAME] is unable to run because your video card drivers did not install properly, are out of date, or are for unsupported hardware. Please make sure you have the latest video card drivers and even if you do have the latest, try reinstalling them. -If you continue to receive this message, contact customer support. +If you continue to receive this message, contact the [SUPPORT_SITE]. </string> <!-- Avatar Shape Information --> diff --git a/indra/newview/skins/default/xui/en/teleport_strings.xml b/indra/newview/skins/default/xui/en/teleport_strings.xml index 616dc1a1d49fbafc2d5a1f41efb739394f930667..e8f6b1319a363ffe2fc35431cf24c11f69eaf6c1 100644 --- a/indra/newview/skins/default/xui/en/teleport_strings.xml +++ b/indra/newview/skins/default/xui/en/teleport_strings.xml @@ -2,21 +2,16 @@ <teleport_messages> <message_set name="errors"> <message name="invalid_tport"> - Problem encountered processing your teleport request. You may -need to log back in before you can teleport. If you continue -to get this message, please check the Tech Support FAQ at: -www.secondlife.com/support + Problem encountered processing your teleport request. You may need to log back in before you can teleport. +If you continue to get this message, please check the [SUPPORT_SITE]. </message> <message name="invalid_region_handoff"> - Problem encountered processing your region crossing. You may -need to log back in before you can cross regions. If you continue -to get this message, please check the Tech Support FAQ at: -www.secondlife.com/support. + Problem encountered processing your region crossing. You may need to log back in before you can cross regions. +If you continue to get this message, please check the [SUPPORT_SITE]. </message> <message name="blocked_tport"> Sorry, teleport is currently blocked. Try again in a moment. -If you still cannot teleport, please log out and log back in to -resolve the problem. +If you still cannot teleport, please log out and log back in to resolve the problem. </message> <message name="nolandmark_tport"> Sorry, but system was unable to locate landmark destination. @@ -29,27 +24,19 @@ Try again in a moment. Sorry, you do not have access to that teleport destination. </message> <message name="missing_attach_tport"> - Your attachments have not arrived yet. Try waiting for a few -more seconds or log out and back in again before attempting -to teleport. + Your attachments have not arrived yet. Try waiting for a few more seconds or log out and back in again before attempting to teleport. </message> <message name="too_many_uploads_tport"> - The asset queue in this region is currently clogged so your teleport -request will not be able to succeed in a timely manner. Please try again -in a few minutes or go to a less busy area. + The asset queue in this region is currently clogged so your teleport request will not be able to succeed in a timely manner. Please try again in a few minutes or go to a less busy area. </message> <message name="expired_tport"> - Sorry, but the system was unable to complete your teleport request -in a timely fashion. Please try again in a few minutes. + Sorry, but the system was unable to complete your teleport request in a timely fashion. Please try again in a few minutes. </message> <message name="expired_region_handoff"> - Sorry, but the system was unable to complete your region crossing -in a timely fashion. Please try again in a few minutes. + Sorry, but the system was unable to complete your region crossing in a timely fashion. Please try again in a few minutes. </message> <message name="no_host"> - Unable to find teleport destination. The destination may be -temporarily unavailable or no longer exists. Please try again -in a few minutes. + Unable to find teleport destination. The destination may be temporarily unavailable or no longer exists. Please try again in a few minutes. </message> <message name="no_inventory_host"> The inventory system is currently unavailable. diff --git a/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml index 17e9a7beb27de3bb0d31005d2a12bdb2e30deb6d..26af76d8a35df12f02f8bef384b72d2fb7c87598 100644 --- a/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml +++ b/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <gesture_combo_box font="SansSerifSmall" + label="Gestures" list_position="below" max_chars="20" follows="right|top"> @@ -26,5 +27,4 @@ <gesture_combo_box.combo_editor name="Combo Text Entry" select_on_focus="true" font="SansSerifSmall" /> - <gesture_combo_box.item label="Gestures" /> </gesture_combo_box> diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml index 89a88330c7b85ffa5c368b21533829832b864ab5..b2494512478edacc7b74869896233cd0555b6eaa 100644 --- a/indra/newview/skins/default/xui/en/widgets/location_input.xml +++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml @@ -29,6 +29,9 @@ image_disabled="Info_Off" /> <add_landmark_button name="Add Landmark" label="" + hover_glow_amount="0.15" + image_hover_selected="Favorite_Star_Over" + image_hover_unselected="Favorite_Star_Over" width="16" height="16" tool_tip="Add to My Landmarks" diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_bar.xml b/indra/newview/skins/default/xui/en/widgets/scroll_bar.xml index 4ad11c41dabc17262058801b19e2cf18ce764909..48bc021e6dcac6200d7c3f7fcb03dd031e4f2c50 100644 --- a/indra/newview/skins/default/xui/en/widgets/scroll_bar.xml +++ b/indra/newview/skins/default/xui/en/widgets/scroll_bar.xml @@ -9,17 +9,17 @@ <up_button image_unselected="ScrollArrow_Up" image_selected="ScrollArrow_Up" scale_image="true" thickness="15" - hover_glow_amount="0.15"/> + hover_glow_amount="0.35"/> <down_button image_unselected="ScrollArrow_Down" image_selected="ScrollArrow_Down" scale_image="true" thickness="15" - hover_glow_amount="0.15"/> + hover_glow_amount="0.35"/> <left_button image_unselected="ScrollArrow_Left" image_selected="ScrollArrow_Left" scale_image="true" thickness="15" - hover_glow_amount="0.15"/> + hover_glow_amount="0.35"/> <right_button image_unselected="ScrollArrow_Right" image_selected="ScrollArrow_Right" scale_image="true" thickness="15" - hover_glow_amount="0.15"/> + hover_glow_amount="0.35"/> </scroll_bar> diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_container.xml b/indra/newview/skins/default/xui/en/widgets/scroll_container.xml index cb9ef0479754fb1fddeb82dd551da28913866ab0..86356ff563eb82444972881f9368bd53ab21cbea 100644 --- a/indra/newview/skins/default/xui/en/widgets/scroll_container.xml +++ b/indra/newview/skins/default/xui/en/widgets/scroll_container.xml @@ -1,3 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <scroll_container color="black" - opaque="false"/> + opaque="false" + min_auto_scroll_rate="120" + max_auto_scroll_rate="500"/> diff --git a/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml index 960c4e81e5e224ae25b66f3d222b417a70f64c1b..4f2261c95349a28101b6a18cea564d5a8c406c0b 100644 --- a/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml +++ b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml @@ -9,14 +9,14 @@ word_wrap="false" ignore_tab="true" track_bottom="false" - takes_non_scroll_clicks="true" cursor_color="TextCursorColor" default_color="TextDefaultColor" text_color="TextFgColor" text_readonly_color="TextFgReadOnlyColor" bg_readonly_color="TextBgReadOnlyColor" bg_writeable_color="TextBgWriteableColor" - bg_focus_color="TextBgFocusColor"> + bg_focus_color="TextBgFocusColor" + link_color="HTMLLinkColor"> <simple_text_editor.border bevel_style="in" follows="all" /> diff --git a/indra/newview/skins/default/xui/es/floater_joystick.xml b/indra/newview/skins/default/xui/es/floater_joystick.xml index 527485e57da2c32744ad7c24687999432e5616e4..da7753a7d760e1a201bc4fa6db33074e3d4ebb32 100644 --- a/indra/newview/skins/default/xui/es/floater_joystick.xml +++ b/indra/newview/skins/default/xui/es/floater_joystick.xml @@ -3,13 +3,14 @@ <check_box name="enable_joystick"> Activar el joystick: </check_box> - <spinner label="Mapping: X" name="JoystickAxis1"/> - <spinner label="Mapping: Y" name="JoystickAxis2"/> - <spinner label="Mapping: Z" name="JoystickAxis0"/> - <spinner label="Mapping: arriba/abajo" name="JoystickAxis4"/> - <spinner label="Mapping: izq./der." name="JoystickAxis5"/> - <spinner label="Mapping: giro" name="JoystickAxis3"/> - <spinner label="Mapping: zoom" name="JoystickAxis6"/> + <text left="140" name="joystick_type" width="360"/> + <spinner label="Mapping: eje X" name="JoystickAxis1" label_width="118" width="161"/> + <spinner label="Mapping: eje Y" name="JoystickAxis2" label_width="105" width="148"/> + <spinner label="Mapping: eje Z" name="JoystickAxis0" label_width="95" width="138"/> + <spinner label="Mapping: arriba/abajo" name="JoystickAxis4" label_width="118" width="161"/> + <spinner label="Mapping: izq./der." name="JoystickAxis5" label_width="105" width="148"/> + <spinner label="Mapping: giro" name="JoystickAxis3" label_width="95" width="138"/> + <spinner label="Mapping: zoom" name="JoystickAxis6" label_width="118" width="161"/> <check_box label="Zoom directo" name="ZoomDirect"/> <check_box label="Cursor 3D" name="Cursor3D"/> <check_box label="Nivel automático" name="AutoLeveling"/> @@ -19,7 +20,7 @@ <check_box name="JoystickAvatarEnabled"> Avatar </check_box> - <check_box name="JoystickBuildEnabled"> + <check_box name="JoystickBuildEnabled" left="192"> Construir </check_box> <check_box name="JoystickFlycamEnabled"> @@ -34,7 +35,7 @@ <text name="ZScale"> Escala: Z </text> - <text name="PitchScale"> + <text name="PitchScale" left="3" width="115"> Escala: arriba/abajo </text> <text name="YawScale"> @@ -52,11 +53,11 @@ <text name="ZDeadZone"> Zona muerta Z </text> - <text name="PitchDeadZone"> - Zona muerta arriba/abajo + <text name="PitchDeadZone" left="3" width="115"> + Zona muerta arri./aba. </text> - <text name="YawDeadZone"> - Zona muerta izq./der + <text name="YawDeadZone" left="3" width="115"> + Zona muerta izq./der. </text> <text name="RollDeadZone"> Zona muerta giro @@ -70,9 +71,9 @@ <text name="ZoomDeadZone"> Zona muerta zoom </text> - <button label="Predeterminados del SpaceNavigator" name="SpaceNavigatorDefaults"/> - <button label="OK" label_selected="OK" name="ok_btn"/> - <button label="Cancelar" label_selected="Cancelar" name="cancel_btn"/> + <button label="Predeterminados del SpaceNavigator" name="SpaceNavigatorDefaults" font="SansSerifSmall" left="330" width="210"/> + <button label="OK" label_selected="OK" name="ok_btn" left="330"/> + <button label="Cancelar" label_selected="Cancelar" name="cancel_btn" left_delta="120"/> <string name="JoystickMonitor"> Monitor del joystick </string> diff --git a/indra/newview/skins/default/xui/es/menu_inventory.xml b/indra/newview/skins/default/xui/es/menu_inventory.xml index 557123d4f8f410037c187b6df6836e4ab7b8c61e..28d47fce52527da8488b23cffdbce06cf96945f6 100644 --- a/indra/newview/skins/default/xui/es/menu_inventory.xml +++ b/indra/newview/skins/default/xui/es/menu_inventory.xml @@ -12,7 +12,7 @@ <menu_item_call label="Script nuevo" name="New Script"/> <menu_item_call label="Nota nueva" name="New Note"/> <menu_item_call label="Gesto nuevo" name="New Gesture"/> - <menu name="New Clothes"> + <menu name="New Clothes" label="Nueva ropa"> <menu_item_call label="Camisa nueva" name="New Shirt"/> <menu_item_call label="Pantalones nuevos" name="New Pants"/> <menu_item_call label="Zapatos nuevos" name="New Shoes"/> @@ -23,7 +23,7 @@ <menu_item_call label="Camiseta nueva" name="New Undershirt"/> <menu_item_call label="Ropa interior nueva" name="New Underpants"/> </menu> - <menu name="New Body Parts"> + <menu name="New Body Parts" label="Nuevas partes del cuerpo"> <menu_item_call label="Forma nueva" name="New Shape"/> <menu_item_call label="Piel nueva" name="New Skin"/> <menu_item_call label="Pelo nuevo" name="New Hair"/> diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml index d7e480c653fe406450d84a44777239b99a54e914..f045c6fe9e8a77b5dc373031e93f4953691212dd 100644 --- a/indra/newview/skins/default/xui/es/notifications.xml +++ b/indra/newview/skins/default/xui/es/notifications.xml @@ -6,6 +6,9 @@ <global name="alwayschoose"> Elegir siempre esta opción </global> + <global name="implicitclosebutton"> + Cerrar + </global> <template name="okbutton"> <form> <button @@ -189,7 +192,7 @@ No podrá removérseles de ese rol, sino que deberán renunciar a él por sà mi <usetemplate name="okcancelbuttons" notext="No" yestext="SÃ"/> </notification> <notification name="ClickPublishHelpLand"> - Seleccionar "Publicar en la web" + Seleccionar 'Publicar en la web' Marcando este Ãtem, se mostrará: - esta parcela en los resultados de la búsqueda - los objetos públicos de esta parcela @@ -219,7 +222,7 @@ Marcando este Ãtem, se mostrará: No puede hacer que esta parcela aparezca en la búsqueda, porque está situada en una región que lo prohÃbe. </notification> <notification name="ClickPublishHelpAvatar"> - Al seleccionar "Mostrar en Buscar" se mostrará: + Al seleccionar 'Mostrar en la búsqueda' se mostrará: - mi perfil en los resultados de la búsqueda - un enlace a mi perfil en las páginas públicas de grupo </notification> @@ -928,7 +931,7 @@ Deberá reconfigurar el nombre y las opciones de la nueva parcela. El color de las parcelas indica el tipo de propietario. Verde = Su terreno -Agua = Terreno de su's grupo's +Agua = Terreno de sus grupos Rojo = Propiedad de otros Amarillo = En venta Morado = Para subasta @@ -1196,13 +1199,13 @@ Por favor, selección sólo uno y reinténtelo. No se han podido configurar las texturas de la región: La textura del terreno [TEXTURE_NUM] tiene una profundidad de bites inválida: [TEXTURE_BIT_DEPTH]. -Cambie la textura [TEXTURE_NUM] por una imagen de 24-bit y 512x512 o menor, y pulse de nuevo "Aplicar" . +Cambie la textura [TEXTURE_NUM] por una imagen de 24-bit y 512x512 o menor, y pulse de nuevo 'Aplicar' . </notification> <notification name="InvalidTerrainSize"> No se han podido configurar las texturas de la región: La textura del terreno [TEXTURE_NUM] es demasiado grande: [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y]. -Cambie la textura [TEXTURE_NUM] por una imagen de 24-bit y 512x512 o menor, y pulse de nuevo "Aplicar" . +Cambie la textura [TEXTURE_NUM] por una imagen de 24-bit y 512x512 o menor, y pulse de nuevo 'Aplicar' . </notification> <notification name="RawUploadStarted"> Ha empezado la subida. Dependiendo de la velocidad de su conexión, llevará unos dos minutos. @@ -1537,7 +1540,7 @@ Por favor, compruebe que tiene instalado el último visor, y vaya a la Base de C Usted no está autorizado en esa región por su nivel de calificación.. Puede pulsar 'Cambiar preferencia' para aumentar su nivel de calificación y poder entrar. Desde ese momento, podrá buscar y acceder a contenido [REGIONMATURITY]. Si más adelante quiere deshacer esta configuración, vaya a Editar > Preferencias... > General. - <form> + <form name="form"> <button name="OK" text="Cambiar preferencia"/> @@ -1545,7 +1548,7 @@ Puede pulsar 'Cambiar preferencia' para aumentar su nivel de calificac default="true" name="Cancel" text="Cerrar"/> - <ignore text="Cuando la entrada a la región está bloqueada por la preferencia del nivel de calificación"/> + <ignore name="ignore" text="Cuando la entrada a la región está bloqueada por la preferencia del nivel de calificación"/> </form> </notification> <notification name="LandClaimAccessBlocked"> @@ -1735,7 +1738,7 @@ Cuando está activada, los residentes sólo pueden ser empujados por sà mismos Por defecto: Off </notification> <notification label="Unir/Dividir parcelas" name="HelpParcelChanges"> - Esta casilla determina si las parcelas que no son del propietario del estado pueden puede unirse o subdividirse. + Esta casilla determina si las parcelas que no son del propietario del estado pueden unirse o subdividirse. Si no se marca esta opción: * Sólo los propietarios o los administradores del estado pueden unir o dividir parcelas. * Sólo podrán unir o dividir las parcelas pertenecientes al propietario o a un grupo en el que tengan los poderes adecuados. @@ -1860,7 +1863,7 @@ Por defecto: on Esta casilla fija la posición del Sol en la posición del deslizable Fase, y detiene su movimiento. </notification> <notification label="Acceso público" name="HelpEstateExternallyVisible"> - Esta casilla habilita a cualquier residente que esté en otro estado pueda entrar en éste sin tener que estar en una lista de acceso. + Esta casilla habilita que cualquier residente que esté en otro estado pueda entrar en éste sin tener que estar en una lista de acceso. Por defecto: on </notification> @@ -2162,7 +2165,7 @@ Núm. máx. de partÃculas: define el número máximo de partÃculas que podrá Calidad del procesamiento: define la resolución con que se renderiza el brillo. -Detalle de la malla: define la cantidad de dettales o número de triángulos usados para renderizar algunos objetos. Cuanto más alto sea el valor, más detalle, pero más tiempo para renderizar. +Detalle de la malla: define la cantidad de detalles o número de triángulos usados para renderizar algunos objetos. Cuanto más alto sea el valor, más detalle, pero más tiempo para renderizar. Detalles de la iluminación: determina que tipo de luces quiere usted que se rendericen. @@ -2195,30 +2198,30 @@ Nivel de detalle del terreno: marca con cuánto detalle quiere ver la textura de <notification name="EnvSettingsHelpButton"> Estas configuraciones ajustan la forma en que usted ve el medio ambiente localmente, en su ordenador. Su tarjeta gráfica debe admitir shaders de la atmósfera ('atmospheric shaders') para poder acceder a esta configuración. -Ajuste el deslizable "Duración de un dÃa" para cambiar localmente, en su visor, las etapas del dÃa. +Ajuste el deslizable 'Duración de un dÃa' para cambiar localmente, en su visor, las etapas del dÃa. -Ajuste el deslizable "Nubosidad" para controlar cuántas nubes cubren el cielo. +Ajuste el deslizable 'Nubosidad' para controlar cuántas nubes cubren el cielo. -Pulse un color en el selector de "Color del agua" para cambiar el color de la misma. +Pulse un color en el selector de 'Color del agua' para cambiar el color de la misma. -Ajuste el deslizable "Claridad del agua" para controlar el nivel de claridad del agua bajo la superficie. +Ajuste el deslizable 'Claridad del agua' para controlar el nivel de claridad del agua bajo la superficie. -Pulse "Usar el horario del estado" para devolver los valores del dÃa al tiempo actual de la región y seguir a partir de él. +Pulse 'Usar el horario del estado' para devolver los valores del dÃa al tiempo actual de la región y seguir a partir de él. -Pulse "Cielo avanzado" para abrir un editor con configuraciones avanzadas para el cielo. +Pulse 'Cielo avanzado' para abrir un editor con configuraciones avanzadas para el cielo. -Pulse "Agua avanzada" para abrir un editor con configuraciones avanzadas para el agua. +Pulse 'Agua avanzada' para abrir un editor con configuraciones avanzadas para el agua. </notification> <notification name="HelpDayCycle"> El Editor del ciclo del dÃa le permite controlar el cielo de Second Life durante el ciclo dÃa/noche. Este es el ciclo que usa el deslizable Duración de un dÃa del Editor del entorno. -El Editor del ciclo del dÃa trabaja configurando fotogramas clave ('keyframes'): nodos (representados por los puntos grises en la lÃnea del tiempo) cada uno de los cuales tiene asociado un Cielo definido. Según progresa la Duración de un dÃa, el WindLight realiza la "animación" del cielo interpolándose entre esos fotogramas clave. +El Editor del ciclo del dÃa trabaja configurando fotogramas clave ('keyframes'): nodos (representados por los puntos grises en la lÃnea del tiempo) cada uno de los cuales tiene asociado un Cielo definido. Según progresa la Duración de un dÃa, el WindLight realiza la 'animación' del cielo interpolándose entre esos fotogramas clave. La flecha amarilla sobre la lÃnea del tiempo representa lo que usted ve actualmente, basándose en la Duración de un dÃa. Púlsela y muévela para ver cómo cambia la animación del dÃa. Puede añadir o borrar fotogramas clave pulsando los botones Añadir un punto o Quitar un punto, situados a la derecha de la lÃnea del tiempo. -Puede establecer la posición en el tiempo de cualquier fotograma clave moviéndolo a lo largo de la lÃnea del tiempo, o configurando manualmente su valor por su valor manualmente en el recuadro Configuración del fotograma clave. También en ese recuadro podrá asociar el fotograma clave a un modelo predefinido de WindLight. +Puede establecer la posición en el tiempo de cualquier fotograma clave moviéndolo a lo largo de la lÃnea del tiempo, o configurando manualmente su valor en el recuadro Configuración del fotograma clave. También en ese recuadro podrá asociar el fotograma clave a un modelo predefinido de WindLight. -La Duración del ciclo establece la duración total de un "dÃa". Marcar un valor bajo (por ejemplo, 2 min.) hará que las 24 horas de su lÃnea del tiempo se animen ¡en sólo dos minutos reales! Una vez que esté satisfecho con su ciclo de la lÃnea del tiempo y los fotogramas clave, utilice los botones Probar y Parar para obtener una vista previa de los resultados. Recuerde que también puede mover la flecha amarilla de encima de la lÃnea del tiempo para ver el ciclo de la animación. El botón Usar el horario del estado sincronizará su ciclo de duración de un dÃa con el ciclo del estado. +La Duración del ciclo establece la duración total de un 'dÃa'. Marcar un valor bajo (por ejemplo, 2 min.) hará que las 24 horas de su lÃnea del tiempo se animen ¡en sólo dos minutos reales! Una vez que esté satisfecho con su ciclo de la lÃnea del tiempo y los fotogramas clave, utilice los botones Probar y Parar para obtener una vista previa de los resultados. Recuerde que también puede mover la flecha amarilla de encima de la lÃnea del tiempo para ver el ciclo de la animación. El botón Usar el horario del estado sincronizará su ciclo de duración de un dÃa con el ciclo del estado. Cuando todo esté a su gusto, puede guardar esos datos y cargarlos luego usando los botones Guardar este tipo de dÃa y Cargar un tipo de dÃa. Note que, por el momento, sólo podemos permitir un ciclo de un dÃa. </notification> @@ -2235,13 +2238,13 @@ Cuando todo esté a su gusto, puede guardar esos datos y cargarlos luego usando La Densidad de la bruma controla lo sombrÃo de la atmósfera, su neblina. Es eficaz para simular escenas con mucho humo o contaminantes, y también para simular niebla y llovizna. </notification> <notification name="HelpDensityMult"> - La Densidad puede usarse para definir globalmente la 'pesadez' de la atmósfera. Los ajustes bajos dan sensación de un "aire limpio", y los altos de pesadez, de esmog. + La Densidad puede usarse para definir globalmente la 'pesadez' de la atmósfera. Los ajustes bajos dan sensación de un 'aire limpio', y los altos de pesadez, de esmog. </notification> <notification name="HelpDistanceMult"> Ajusta a qué distancia se percibe el WindLight. El valor cero desactiva la influencia del WindLight en el terreno y los objetos. Los valores superiores a 1 simulan mayores distancias a las que afectan los efectos atmosféricos </notification> <notification name="HelpMaxAltitude"> - La Altitud máx. ajusta hasta que altura el WindLight realiza sus cálculos para computar la iluminación atmosférica. En las últimas horas del dÃa, es útil para ajustar la "profundidad" a la que aparece el Sol. + La Altitud máx. ajusta hasta que altura el WindLight realiza sus cálculos para computar la iluminación atmosférica. En las últimas horas del dÃa, es útil para ajustar la 'profundidad' a la que aparece el Sol. </notification> <notification name="HelpSunlightColor"> Ajusta en la escena la intensidad y el color de las luces directas. @@ -2382,7 +2385,7 @@ Pero, vaya, diviértase si quiere. </notification> <notification name="AutoWearNewClothing"> ¿Quiere vestirse automáticamente el Ãtem de ropa nueva que ha creado? - <usetemplate ignoretext="Vestirme automáticamente la ropa nueva" name="okcancelignore" notext="No" yestext="SÃ"/> + <usetemplate ignoretext="Al vestirme automáticamente la ropa nueva" name="okcancelignore" notext="No" yestext="SÃ"/> </notification> <notification name="NotAgeVerified"> Para acceder a esta parcela, se debe haber verificado su edad. @@ -2390,7 +2393,7 @@ Pero, vaya, diviértase si quiere. [_URL] <url name="url" option="0"> - https://secondlife.com/account/verification.php + https://secondlife.com/account/verification.php?lang=es </url> <usetemplate ignoretext="Advertir de la falta de la verificación de edad" name="okcancelignore" notext="No" yestext="SÃ"/> </notification> @@ -2663,7 +2666,7 @@ Vaya a la 'Help Island Public' ('Isla Pública de Ayuda') pa <notification name="ImproperPaymentStatus"> No tiene el estado de pago adecuado para entrar a esta región. </notification> - <notification name="MustGetAgeRgion"> + <notification name="MustGetAgeRegion"> Debe haber verificado su edad para entrar a esta región. </notification> <notification name="MustGetAgeParcel"> @@ -2944,7 +2947,7 @@ Los objetos flexibles no pueden ser materiales, y serán inmateriales hasta que <notification name="FirstDebugMenus"> Ha activado el menú Avanzado. Contiene herramientas útiles para los desarrolladores que trabajan mejorando Second Life. -Para pasar este menú a una ventana, pulse Ctrl-Alt-D. En un Mac, pulse Cmd-Opt-Shift-D. +Para pasar este menú a una ventana, pulse Ctrl-Alt-D. En un Mac, pulse ⌘-Opt-D. </notification> <notification name="FirstSculptedPrim"> Está editando un prim 'sculpted'. diff --git a/indra/newview/skins/default/xui/es/role_actions.xml b/indra/newview/skins/default/xui/es/role_actions.xml index 1e10ccf992f681f7c82eb558e0b7b06e8768b4e5..da9a820eb8b06e59c2cde09035df313d9557e6d8 100644 --- a/indra/newview/skins/default/xui/es/role_actions.xml +++ b/indra/newview/skins/default/xui/es/role_actions.xml @@ -1,186 +1,199 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <role_actions> <action_set - description="Estas habilidades incluyen poderes de adicionar o remover miembros del grupo y permitir que nuevos miembros se junten sin una invitación." + description="Estas capacidades incluyen poderes para añadir o quitar miembros del grupo, y para pemitir que se sumen nuevos miembros sin necesidad de invitación." name="Membership"> - <action description="Invitar personas para este grupo" - longdescription="Invite personas para este grupo usando el botón 'Invitar nueva persona...' en Miembros & pestaña Funciones > subpestaña Miembros." + <action description="Invitar personas al grupo" + longdescription="Invitar a personas al grupo usando el botón 'Invitar a un nuevo miembro' en Miembros y Roles > subpestaña Miembros." name="member invite" value="1" /> - <action description="Expulsar a miembros de este grupo" - longdescription="Expulse a miembros de este grupo usando el botón 'Expulsar del grupo' en Miembros & pestaña Funciones > subpestaña Miembros. Un propietario puede expulsar a cualquiera, excepto a otro propietario. Si usted no es un propietario, un miembro puede a expulsarlo del grupo si, y solamente si, él apenas tiene la función de todos y no otras funciones. Para remover miembros de funciones, necesita tener la habilidad 'Remover miembros de funciones'." + <action description="Expulsar a miembros del grupo" + longdescription="Expulsar a miembros del grupo usando el botón 'Expulsar del grupo' en Miembros y Roles > subpestaña Miembros. Un propietario puede expulsar a cualquiera, excepto a otro propietario. Si usted no es un propietario, un miembro del grupo puede expulsarle sólo si tiene concedida tal capacidad especÃfica. Para quitar capacidades a los miembros, usted debe tener la de 'Quitar capacidades a miembros'." name="member eject" value="2" /> <action - description="Activar/desactivar 'Abrir registro' y cambiar 'Tasa de suscripción'" - longdescription="Active/desactive 'Abrir registro' para permitir que nuevos miembros se unan sin una invitación, y cambie 'Tasa de registro' en la sección Preferencia de grupo de la pestaña General." + description="Activar/desactivar 'Inscripción libre' y cambiar 'Cuota de inscripción'" + longdescription="Activar/desactivar 'Inscripción libre' para permitir o no que se unan sin invitación nuevos miembros, y cambiar la 'Cuota de inscripción' en la sección Preferencias del grupo de la pestaña General." name="member options" value="3" /> </action_set> <action_set - description="Estas habilidades incluyen poderes de adicionar, remover y cambiar funciones del grupo; adicionar y remover miembros en funciones y designar habilidades a funciones." + description="Estas habilidades incluyen el poder añadir, quitar y cambiar roles, asignarlos a miembros, y darles capacidades." name="Roles"> - <action description="Crear nuevas funciones" - longdescription="Cree nuevas funciones en Miembros & pestaña Funciones > subpestaña Funciones." + <action description="Crear nuevos roles" + longdescription="Crear nuevos roles en Miembros y Roles > pestaña Roles > botón Crear un rol nuevo." name="role create" value="4" /> - <action description="Borrar funciones" - longdescription="Borra funciones en Miembros & pestaña Funciones > subpestaña Funciones." + <action description="Borrar roles" + longdescription="Borrar roles en Miembros y Roles > pestaña Roles > botón Eliminar el rol." name="role delete" value="5" /> - <action description="Cambiar nombres de funciones, tÃtulos y descripciones" - longdescription="Cambie el nombre de funciones, tÃtulos y descripciones en la parte inferior de Miembros & pestaña Funciones > subpestaña Funciones después de seleccionar una función." + <action description="Cambiar nombres de roles, tÃtulos y descripciones" + longdescription="Cambiar el nombre del rol que elija, su etiqueta y descripción en la parte media de la pestaña Miembros y Roles." name="role properties" value="6" /> - <action description="Designar miembros para la función's del asignador" - longdescription="Designe miembros para funciones en la sección de funciones designadas de Miembros & pestaña Funciones > subpestaña Miembros. Un miembro con este poder puede solamente adicionar miembros para la función que el asignador ya posee." + <action description="Designar miembros para el rol del asignador" + longdescription="Designar miembros para un rol en la sección Roles asignados de la pestaña Miembros y Roles > subpestaña Miembros. Un miembro con este poder sólo puede asignar a otros el rol que él posee." name="role assign member limited" value="7" /> - <action description="Designar miembros para cualquier función" - longdescription="Designe miembros para cualquier función en la sección de funciones designadas de Miembros & pestaña Funciones > subpestaña Miembros. *AVISO* Cualesquiera miembros en una función con esta habilidad pueden designar a sà propios--y cualesquiera otros miembros no propietarios--para funciones que tienen más poderes que las actuales, promocionándolos a poderes próximos al del propietario. Asegúrese de saber lo que está haciendo antes de designar esta habilidad." + <action description="Designar miembros para cualquier rol" + longdescription="Designar miembros para cualquier rol en la sección Roles asignados de la pestaña Miembros y Roles > subpestaña Miembros. *AVISO* Todos los miembros con esta capacidad podrán asignarse a sà mismos -y a otros miembros- roles con mayores poderes de los que actualmente tienen. Potencialmente, podrÃan elevarse hasta poderes cercanos a los del propietario. Asegúrese de lo que está haciendo antes de otorgar esta capacidad." name="role assign member" value="8" /> - <action description="Remover miembros de las funciones" - longdescription="Remueva miembros de funciones en la sección de funciones designadas de Miembros & pestaña Funciones > subpestaña Miembros. Propietarios no pueden' ser removidos." + <action description="Quitar capacidades a los miembros" + longdescription="Quitar capacidades a los miembros en la sección Capacidades asignadas de Miembros y Roles > subpestaña Roles. No se pueden quitar a los Propietarios." name="role remove member" value="9" /> - <action description="Determinar y remover habilidades en función" - longdescription="Designe y remueva habilidades en funciones en la sección habilidades permitidas de Miembros & pestaña Funciones > subpestaña Funciones. *AVISO* Cualesquiera miembros en una función con esta habilidad pueden designar a sà propios--y cualesquiera otros miembros no propietarios--todas las habilidades, promocionándolos a poderes próximos al del propietario. Asegúrese de saber lo que está haciendo antes de designar esta habilidad." + <action description="Añadir o quitar capacidades a los roles" + longdescription="Añadir o quitar capacidades a los roles en la sección Capacidades asignadas de Miembros y Roles > subpestaña Roles. *AVISO* Todos los miembros con esta capacidad podrán asignarse a sà mismos -y a otros miembros- roles con mayores poderes de los que actualmente tienen. Potencialmente, podrÃan elevarse hasta poderes cercanos a los del propietario. Asegúrese de lo que está haciendo antes de otorgar esta capacidad." name="role change actions" value="10" /> </action_set> <action_set - description="Estas habilidades incluyen poderes para modificar esta identidad de grupo, como cambiar la visibilidad pública, presentación y insignia." + description="Estas capacidades incluyen poderes para modificar la identidad del grupo, como su visibilidad pública, su carta o su emblema." name="Group Identity"> <action - description="Cambiar presentación, insignia, 'Publicar en la web', y cuales miembros están públicamente visibles en Informaciones del Grupo." - longdescription="Cambie la presentación, insignia, 'Publicar en la web' y cuales miembros están públicamente visibles en Informaciones del grupo. Es hecho en la pestaña General." + description="Cambiar la carta, emblema, 'Mostrar en la búsqueda', y qué miembros serán visibles en la información del grupo" + longdescription="Cambiar la carta, emblema, 'Mostrar en la búsqueda', y qué miembros serán visibles en la información del grupo de la pestaña General." name="group change identity" value="11" /> </action_set> <action_set - description="Estas habilidades incluyen poderes para transferir, modificar y vender terrenos del grupo. Vaya para la ventana Sobre el terreno, haga clic con el botón derecho en el terreno y seleccione 'Sobre el terreno...' o haga clic en la información de la parcela en la barra del menú." + description="Estas capacidades incluyen poderes para transferir, modificar y vender terrenos del grupo. Vea el menú Mundo > Acerca del terreno, o pulse con el botón derecho en el terreno y seleccione 'Acerca del terreno...', o pulse en la información de la parcela en la barra superior del menú." name="Parcel Management"> <action description="Transferir y comprar terreno para el grupo" - longdescription="Transfiere y compre terreno para el grupo. Es hecho en Sobre el terreno > pestaña General." + longdescription="Transferir y comprar terreno para el grupo. Se hace en Acerca del terreno > pestaña General." name="land deed" value="12" /> - <action description="Abandonar al terreno para Gobernador Linden" - longdescription="Abandone al terreno para Gobernador Linden. *AVISO* Cualquier miembro en una función con esta habilidad puede abandonar al terreno perteneciente al grupo en Sobre el terreno > pestaña General, revirtiendo a la posesión Linden sin una venta! Asegúrese de saber lo que está haciendo antes de designar esta habilidad." + <action description="Abandonar al terreno a favor de Governor Linden" + longdescription="Abandonar al terreno a favor de Governor Linden. *AVISO* Todos los miembros con esta capacidad pueden abandonar terreno perteneciente al grupo en Acerca del terreno > pestaña General, devolviendo la posesión a Linden ¡gratuitamente! Asegúrese de lo que está haciendo antes de otorgar esta capacidad." name="land release" value="13" /> - <action description="Definir terreno para información de venta" - longdescription="Defina informaciones de venta para terreno. *AVISO* Cualquier miembro en una función con esta habilidad puede vender terrenos pertenecientes al grupo en Sobre el terreno > pestaña General ¡cómo quiera! Asegúrese de saber lo que está haciendo antes de designar esta habilidad." + <action description="Vender terreno" + longdescription="Vender terreno. *AVISO* Todos los miembros con esta capacidad pueden vender terreno perteneciente al grupo -¡en la forma en que quieran!- en Acerca del terreno > pestaña General. Asegúrese de lo que está haciendo antes de otorgar esta capacidad." name="land set sale info" value="14" /> - <action description="Subdividir y unir parcelas" - longdescription="Subdivide and join parcels. This is done by right-clicking the ground, 'Edit Terrain', and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click 'Subdivide...'. To join, select two or more contiguous parcels and click 'Join...'. " + <action description="Dividir y unir parcelas" + longdescription="Dividir y unir parcelas. Se hace pulsando con el botón derecho en el terreno, 'Modificar el terreno', y dibujando en el terreno con el ratón lo que se quiere seleccionar. Para dividir, elija la parte que quiere separar y pulse 'Subdividir...'. Para unir, seleccione dos o más parcelas contiguas y pulse 'Unir...'. " name="land divide join" value="15" /> </action_set> <action_set - description="Estas habilidades incluyen poderes para cambiar el nombre de las parcelas y configuraciones de publicación, visibilidad de la búsqueda de directorio y punto de aterrizaje & opciones de ruta de TP." + description="Estas capacidades incluyen poder cambiar el nombre de la parcela y su configuración, asà como si se muestra en Buscar y las opciones del punto de llegada y el de teleporte." name="Parcel Identity"> <action - description="Activar/desactivar 'Exhibir en locales de encuentro' y definir categorÃa" - longdescription="Activar/desactivar 'Exhibir en locales de encuentro' y configurar una categorÃa de parcela en Sobre el terreno > pestaña Opciones." + description="Activar/desactivar 'Mostrar en Buscar' y el definir la categorÃa" + longdescription="Activar/desactivar el 'Mostrar en Buscar' y en que categorÃa se mostrará en Acerca del terreno > pestaña Opciones." name="land find places" value="17" /> <action - description="Cambiar nombre de la parcela, descripción, y configuraciones 'Publicar en la web'" - longdescription="Cambie el nombre de la parcela, descripción y configuraciones de 'Publicar en la web'. Es hecho en Sobre el terreno > pestaña Opciones." + description="Cambiar el nombre de la parcela, la descripción, y la configuración de 'Mostrar en Buscar'" + longdescription="Cambiar el nombre y descripción de la parcela, y la configuración de 'Mostrar en Buscar'. Se hace en Acerca del terreno > pestaña Opciones." name="land change identity" value="18" /> - <action description="Definir punto de aterrizaje y ruta de teletransporte" - longdescription="En una parcela perteneciente al grupo, miembros en una función con esta habilidad pueden definir un punto de aterrizaje para especificar donde los teletransportes llegan y también definir la ruta del teletransporte para un mayor control. Es hecho en Sobre el terreno > pestaña Opciones." + <action description="Definir los puntos de llegada y teleporte" + longdescription="En una parcela perteneciente al grupo, los miembros con un rol que tenga esta capacidad pueden precisar el punto de llegada o el de teleporte. Se hace en Acerca del terreno > pestaña Opciones." name="land set landing point" value="19" /> </action_set> <action_set - description="Estas habilidades incluyen poderes que afectan opciones de parcela, como 'Crear objetos', 'Editar terreno' y música & configuraciones de multimedia." + description="Estas capacidades incluyen poderes que afectan a las opciones de la parcela, como 'Crear objetos', 'Editar el terreno' y las configuraciones de la música y los media." name="Parcel Settings"> - <action description="Cambiar música & configuraciones de multimedia" - longdescription="Cambie streaming de música y configuraciones de vÃdeo en Sobre el terreno > pestaña Multimedia." + <action description="Cambiar música y configuraciones de los media" + longdescription="Cambiar la música en streaming y las configuraciones de vÃdeo en Acerca del terreno > pestaña Media." name="land change media" value="20" /> - <action description="Activar/desactivar 'Editar terreno'" - longdescription="Active/desactive 'Editar terreno'. *AVISO* Sobre el terreno > pestaña Opciones > Editar terreno permite a cualquiera alterar las formas de su terreno', sustituir y mover plantas Linden. Asegúrese de saber lo que está haciendo antes de designar esta habilidad. La edición de terreno es activada/desactivada en Sobre el terreno > pestaña Opciones." + <action description="Activar/desactivar 'Editar el terreno'" + longdescription="Activar/desactivar 'Editar el terreno'. *AVISO* Acerca del terreno > pestaña Opciones > Editar el terreno, permite a cualquiera alterar la forma de su terreno y sustituir y mover plantas Linden. Asegúrese de lo que está haciendo antes de otorgar esta capacidad. La edición del terreno se activada/desactiva en Acerca del terreno > pestaña Opciones." name="land edit" value="21" /> <action - description="Activar/desactivar variados Sobre el Terreno > Opciones de configuraciones" - longdescription="Active/desactive 'Seguro (sin daño)', 'Volar', y permita a otros residentes: 'Crear objetos', 'Editar terreno', 'Crear puntos de referencia', y 'Ejecutar scripts' en un terreno perteneciente al grupo en Sobre el terreno > pestaña Opciones." + description="Activar/desactivar varios Ãtems de Acerca del terreno > Opciones" + longdescription="Activar/desactivar en un terreno del grupo los Ãtems de Acerca del terreno > pestaña Opciones: 'Seguro (sin daño)', 'Volar', y permitir a otros residentes: 'Crear objetos', 'Editar el terreno', 'Crear hitos', y 'Ejecutar scripts'." name="land options" value="22" /> </action_set> <action_set - description="Estas habilidades incluyen poderes que permiten a miembros rebasar restricciones en parcelas pertenecientes al grupo." + description="Estas capacidades incluyen poderes que permiten a los miembros rebasar las restricciones de parcelas pertenecientes al grupo." name="Parcel Powers"> - <action description="Siempre permitir 'Editar terreno'" - longdescription="Miembros en una función con esta habilidad pueden editar terreno en una parcela perteneciente al grupo, mismo si está desactivada en Sobre el terreno > pestaña Opciones." + <action description="Permitir siempre 'Editar el terreno'" + longdescription="Quien tenga un rol con esta capacidad puede editar el terreno de una parcela perteneciente al grupo aunque eso esté desactivado en Acerca del terreno > pestaña Opciones." name="land allow edit land" value="23" /> - <action description="Siempre permitir 'Volar'" - longdescription="Miembros en una función con esta habilidad pueden volar sobre una parcela perteneciente al grupo, mismo si está desactivada en Sobre el terreno > pestaña Opciones." + <action description="Permitir siempre 'Volar'" + longdescription="Quien tenga un rol con esta capacidad puede volar sobre una parcela perteneciente al grupo aunque eso esté desactivado en Acerca del terreno > pestaña Opciones." name="land allow fly" value="24" /> - <action description="Siempre permitir 'Crear objetos'" - longdescription="Miembros en una función con esta habilidad pueden crear objetos en una parcela perteneciente al grupo, mismo si está desactivada en Sobre el terreno > pestaña Opciones." + <action description="Permitir siempre 'Crear objetos'" + longdescription="Quien tenga un rol con esta capacidad puede crear objetos en una parcela perteneciente al grupo aunque eso esté desactivado en Acerca del terreno > pestaña Opciones." name="land allow create" value="25" /> - <action description="Siempre permitir 'Crear punto de referencia'" - longdescription="Miembros en una función con esta habilidad pueden poner un punto de referencia en una parcela perteneciente al grupo, mismo si está desactivada en Sobre el terreno > pestaña Opciones." + <action description="Permitir siempre 'Crear hitos'" + longdescription="Quien tenga un rol con esta capacidad puede crear un hito en una parcela perteneciente al grupo aunque eso esté desactivado en Acerca del terreno > pestaña Opciones." name="land allow landmark" value="26" /> - <action description="Permitir 'Colocar casa aquÃ' en el terreno del grupo" - longdescription="Miembros en una función con esta habilidad pueden usar el menú Mundo > Definir hogar aquà en una parcela del grupo (definir terreno o transferir para este grupo)." + <action description="Permitir 'Fijar mi Base aquÃ' en el terreno del grupo" + longdescription="Quien tenga un rol con esta capacidad puede usar el menú Mundo > Fijar mi Base aquà en una parcela transferida al grupo." name="land allow set home" value="28" /> </action_set> <action_set - description="Estas habilidades incluyen poderes de permitir o restringir acceso a parcelas pertenecientes al grupo, incluyendo congelar y expulsar a residentes." + description="Estas capacidades incluyen poderes para permitir o restringir el acceso a parcelas pertenecientes al grupo, incluyendo el congelar y expulsar a residentes." name="Parcel Access"> - <action description="Administrar listas de acceso a la parcela" - longdescription="Administre la lista de acceso a la parcela en Sobre el terreno > pestaña Acceso." + <action description="Administrar las listas de acceso a la parcela" + longdescription="Administre las listas de acceso a la parcela en Acerca del terreno > pestaña Acceso." name="land manage allowed" value="29" /> - <action description="Administrar lista de desterrados de la parcela" - longdescription="Administre la lista de desterrados de la parcela en Sobre el terreno > pestaña Desterrado." + <action description="Administrar la lista de residentes con el acceso prohibido" + longdescription="Administrar la lista de residentes con el acceso prohibido a la parcela en Acerca del terreno > pestaña Acceso." name="land manage banned" value="30" /> - <action description="Cambiar configuraciones de parcela 'Vender pases...'" - longdescription="Cambie configuraciones de 'Vender pases...' en Sobre el terreno > pestaña Acceso." + <action description="Cambiar en las configuraciones de parcela el 'Vender pases a...'" + longdescription="Cambiar la configuración de 'Vender pases a...' en Acerca del terreno > pestaña Acceso." name="land manage passes" value="31" /> <action description="Expulsar y congelar residentes en las parcelas" - longdescription="Miembros en una función con esta habilidad pueden lidiar con un residente indeseado en una parcela perteneciente al grupo haciendo clic con el botón derecho sobre él, Más > y seleccionando 'Expulsar...' o 'Congelar...'." + longdescription="Quien tenga un rol con esta capacidad puede actuar frente a un residente indeseado en una parcela del grupo pulsando con el botón derecho sobre él, Más > y seleccionando 'Expulsar...' o 'Congelar...'." name="land admin" value="32" /> </action_set> <action_set - description="Estas habilidades incluyen poderes de permitir a miembros devolver objetos y poner y mover plantas Linden. Útil para que miembros organicen el paisaje, pero debe ser usado con cuidado, debido a no ser posible deshacer la mudanza de los objetos." + description="Estas capacidades incluyen poderes que permitan a los miembros devolver objetos y poner y mover plantas Linden. Es útil para que miembros organicen el paisaje, pero debe ser usado con cuidado, ya que no se pueden deshacer esos cambios en los objetos." name="Parcel Content"> <action description="Devolver objetos que pertenecen al grupo" - longdescription="Devuelva objetos en parcelas pertenecientes al grupo que pertenecen al grupo en Sobre el terreno > pestaña Objetos." + longdescription="Devolver objetos pertenecientes al grupo en parcelas de su propiedad en Acerca del terreno > pestaña Objetos." name="land return group owned" value="48" /> <action description="Devolver objetos definidos para el grupo" - longdescription="Devuelva objetos en parcelas pertenecientes al grupo en Sobre el terreno > pestaña Objetos." + longdescription="Devuelva objetos en parcelas pertenecientes al grupo en Acerca del terreno > pestaña Objetos." name="land return group set" value="33" /> <action description="Devolver objetos que no pertenecen al grupo" - longdescription="Devuelva objetos en las parcelas pertenecientes a un grupo que está sin grupo en el Sobre el terreno > pestaña Objetos." + longdescription="Devuolver objetos que estén en una parcela del grupo y pertenezcan a alguien que no sea del grupo en Acerca del terreno > pestaña Objetos." name="land return non group" value="34" /> - <action description="Enjardinar usando plantas Linden" - longdescription="La habilidad de enjardinar permite poner y mover árboles Linden, plantas y céspedes. Estos Ãtems pueden ser encontrados en la's Biblioteca de su inventario > carpeta Objetos o pueden ser criados a través del botón Construir." + <action description="Modificar el paisaje usando plantas Linden" + longdescription="La capacidad de modificar el paisaje permite poner y mover árboles Linden, plantas y arbustos. Estos Ãtems están en la 's Biblioteca de su Inventario > carpeta Objetos, o pueden crearse con el botón Construir." name="land gardening" value="35" /> </action_set> <action_set - description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Edit Tools > General Tab. Right-click an object and Edit to see its settings. " + description="Estas capacidades incluyen poderes para tranferir, modificar y vender objetos pertenecientes al grupo. Estos cambios se hacen en la pestaña General de la herramienta de edición. Para verlo, pulse en un objeto con el botón derecho y elija Editar. " name="Object Management"> - <action description="Transferir objetos para el grupo" - longdescription="Transfiere objetos para el grupo en Editar herramientas > pestaña General." + <action description="Transferir objetos al grupo" + longdescription="Transferir objetos al grupo en Editar > pestaña General." name="object deed" value="36" /> - <action description="Manipular (mover, copiar, modificar) objetos del grupo" - longdescription="Manipule (mover,copiar, modificar) objetos pertenecientes al grupo en Editar Herramientas > pestaña General." + <action description="Manipular (mover, copiar, y modificar) objetos del grupo" + longdescription="Manipular (mover, copiar, y modificar) objetos pertenecientes al grupo en Editar > pestaña General." name="object manipulate" value="38" /> - <action description="Definir objetos pertenecientes al grupo para venta" - longdescription="Defina objetos pertenecientes al grupo para venta en Editar Herramientas > pestaña General." + <action description="Vender objetos pertenecientes al grupo" + longdescription="Poner a la venta objetos pertenecientes al grupo para venta en Editar > pestaña General." name="object set sale" value="39" /> </action_set> <action_set - description="Estas habilidades incluyen poderes que requieren que miembros paguen deudas y reciban dividendos del grupo, y restringen acceso al historial de cuenta del grupo." + description="Estas habilidades incluyen poderes para que los miembros paguen deudas del grupo o reciban sus dividendos, y para limitar el acceso al historial de la cuenta del grupo." name="Accounting"> - <action description="Pagar débitos y reciber dividendos del grupo" - longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees. " + <action description="Pagar deudas y recibir dividendos del grupo" + longdescription="Quien tenga un rol con esta capacidad, automáticamente pagará deudas del grupo y recibirá sus dividendos. Esto significa que recibirá una parte de las ventas de terreno de grupo, y que contribuirá a cosas como, por ejemplo, las cuotas por posesión de terreno. " name="accounting accountable" value="40" /> </action_set> <action_set - description="Estas habilidades incluyen poderes de permitir enviar, recibir y ver avisos de grupo." + description="Estas habilidades incluyen poderes para enviar, recibir y ver avisos de grupo." name="Notices"> <action description="Enviar aviso" - longdescription="Miembros en una función con esta habilidad pueden enviar avisos en Informaciones de grupo > pestaña Avisos." + longdescription="Quien tenga un rol con esta capacidad puede enviar avisos en Información del grupo > pestaña Avisos." name="notices send" value="42" /> - <action description="Reciber nuevos avisos y ver los anteriores" - longdescription="Miembros en una función con esta habilidad pueden recibir los nuevos avisos y ver los anteriores en Informaciones de grupo > pestaña Avisos." + <action description="Recibir avisos nuevos y ver los anteriores" + longdescription="Quien tenga un rol con esta capacidad puede recibir los avisos nuevos, y ver los anteriores en Información del grupo > pestaña Avisos." name="notices receive" value="43" /> </action_set> <action_set - description="Estas habilidades incluyen poderes de permitir a miembros definir y votar en propuestas y ver historial de votación." + description="Estas habilidades incluyen poderes para permitir a los miembros crear propuestas, votarlas, y ver el historial de votaciones." name="Proposals"> - <action description="Crear propuesta" - longdescription="Miembros en una función con esta habilidad pueden crear propuestas para que sean votadas en Informaciones de grupo > pestaña Propuestas." + <action description="Hacer una propuesta" + longdescription="Quien tenga un rol con esta capacidad puede crear propuestas para que sean votadas en Información del grupo > pestaña Propuestas." name="proposal start" value="44" /> <action description="Votar en propuestas" - longdescription="Miembros en una función con esta habilidad pueden votar en propuestas en Informaciones de grupo > pestaña Propuestas." + longdescription="Quien tenga un rol con esta capacidad puede votar las propuestas en Información del grupo > pestaña Propuestas." name="proposal vote" value="45" /> </action_set> + <action_set + description="Estas capacidades incluyen poderes para permitir o no el aceso a las sesiones de chat del grupo y al chat de voz del mismo." + name="Chat"> + <action description="Abrir chat de grupo" + longdescription="Quien tenga un rol con esta capacidad puede abrir sesiones de chat del grupo, tanto de texto como de voz." + name="join group chat" value="16" /> + <action description="Abrir chat de voz del grupo" + longdescription="Quien tenga un rol con esta capacidad puede abrir sesiones de chat de voz del grupo. NOTA: para acceder al chat de voz debe tenerse la capacidad 'Abrir chat de grupo'." + name="join voice chat" value="27" /> + <action description="Moderar el chat de grupo" + longdescription="Quien tenga esta capacidad puede controlar el acceso y la participación en los chats de texto y de voz del grupo." + name="moderate group chat" value="37" /> + </action_set> </role_actions> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index 4793f6c6614634e96e386ac9d25c99fb43c0b9a8..96bf0ea865f5edd9fa4cdeeb4bfc34ddec3ace0f 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -55,6 +55,9 @@ <string name="LoginDownloadingClothing"> Descargando la ropa... </string> + <string name="Quit"> + Salir + </string> <string name="AgentLostConnection"> Esta región puede estar teniendo problemas. Por favor, compruebe su conexión a internet. </string> diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index 30092a426f77954058d65cc1b65f40897a2cf79d..7d2cdd84548ef84acfa9a0697b361507bfa329f4 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -6,6 +6,9 @@ <global name="alwayschoose"> Toujours choisir cette option </global> + <global name="implicitclosebutton"> + Fermer + </global> <template name="okbutton"> <form> <button @@ -2877,7 +2880,7 @@ Les objets flexibles ne peuvent pas avoir de propriétés physiques et doivent r <notification name="FirstDebugMenus"> Vous avez activé le menu Avancé. Ce menu contient des fonctionnalités utiles pour les développeurs qui travaillent sur Second Life. -Pour activer/désactiver ce menu sous Windows, appuyez sur Ctrl-Alt-D. Sur un Mac, appuyez sur Cmd-Opt-Maj-D +Pour activer/désactiver ce menu sous Windows, appuyez sur Ctrl-Alt-D. Sur un Mac, appuyez sur ⌘-Opt-Maj-D </notification> <notification name="FirstSculptedPrim"> Vous êtes en train d'éditer un sculptie. diff --git a/indra/newview/skins/default/xui/it/floater_tools.xml b/indra/newview/skins/default/xui/it/floater_tools.xml index a89ae9d8037f46616901a93eb51751bcf460e918..3c79cd8829934433798ee76d2ad7698e24bbf849 100644 --- a/indra/newview/skins/default/xui/it/floater_tools.xml +++ b/indra/newview/skins/default/xui/it/floater_tools.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="toolbox floater" title=""> +<floater name="toolbox floater" title="" short_title="Costruisci" width="288"> <button label="" label_selected="" name="button focus" tool_tip="Focus"/> <button label="" label_selected="" name="button move" tool_tip="Muoviti"/> <button label="" label_selected="" name="button edit" tool_tip="Modifica"/> <button label="" label_selected="" name="button create" tool_tip="Crea"/> <button label="" label_selected="" name="button land" tool_tip="Terra"/> <check_box label="Zoom" name="radio zoom"/> - <check_box label="Guarda ruotando(Ctrl)" name="radio orbit"/> + <check_box label="Guarda ruotando (Ctrl)" name="radio orbit"/> <check_box label="Guarda panoramicamente (Ctrl-Shift)" name="radio pan"/> <check_box label="Muovi" name="radio move"/> <check_box label="Alza (Ctrl)" name="radio lift"/> @@ -17,9 +17,9 @@ <check_box label="Seleziona Texture" name="radio select face"/> <check_box label="Modifica parti unite" name="checkbox edit linked parts"/> <text name="text ruler mode"> - Modalità  regolo di precisione: + Modalità : </text> - <combo_box name="combobox grid mode"> + <combo_box name="combobox grid mode" left_delta="48"> <combo_item name="World"> Globale </combo_item> @@ -30,11 +30,11 @@ Riferito a </combo_item> </combo_box> - <check_box label="Ridimensiona simmetricamente" name="checkbox uniform"/> - <check_box label="Ridimensiona le Texture" name="checkbox stretch textures"/> + <check_box label="Ridimens. simmetricamente" name="checkbox uniform"/> + <check_box label="Ridimensiona le texture" name="checkbox stretch textures"/> <check_box label="Usa righello" name="checkbox snap to grid"/> <button label="Opzioni..." label_selected="Opzioni..." name="Options..."/> - <text name="text status"> + <text name="text status" width="280"> Trascina per muovere, trascina+maiuscolo per copiare </text> <button label="" label_selected="" name="ToolCube" tool_tip="Cubo"/> @@ -63,23 +63,24 @@ <check_box label="Uniforma" name="radio smooth"/> <check_box label="Ondula" name="radio noise"/> <check_box label="Ripristina" name="radio revert"/> - <button label="Applica" label_selected="Applica" name="button apply to selection" tool_tip="Modifica il terreno selezionato"/> + <button label="Applica" label_selected="Applica" name="button apply to selection" tool_tip="Modifica il terreno selezionato" left="146"/> <text name="Bulldozer:"> Bulldozer: </text> <text name="Dozer Size:"> Grandezza </text> + <volume_slider left="184" name="slider brush size" width="74" /> <text name="Strength:"> Potenza </text> - <text name="obj_count"> + <text name="obj_count" left="134"> Oggetti selezionati: [COUNT] </text> - <text name="prim_count"> - primitive: [COUNT] + <text name="prim_count" left="134"> + primitivi: [COUNT] </text> - <tab_container name="Object Info Tabs"> + <tab_container name="Object Info Tabs" tab_max_width="150" tab_min_width="30" width="288"> <panel label="Generale" name="General"> <text name="Name:"> Nome: @@ -121,7 +122,7 @@ <string name="text deed"> Cedi al gruppo </string> - <button label="Cedi al gruppo..." label_selected="Cedi al gruppo..." name="button deed" tool_tip="Gli oggetti condivisi con il gruppo possono essere ceduti da un funzionario del gruppo."/> + <button left_delta="152" width="98" label="Cedi al gruppo..." label_selected="Cedi al gruppo..." name="button deed" tool_tip="Gli oggetti condivisi con il gruppo possono essere ceduti da un funzionario del gruppo."/> <check_box label="Permetti a chiunque di spostare" name="checkbox allow everyone move"/> <check_box label="Permetti a chiunque di copiare" name="checkbox allow everyone copy"/> <check_box label="Mostra nella ricerca" name="search_check" tool_tip="Permetti che l'oggetto sia visibile nella ricerca"/> @@ -144,12 +145,12 @@ Il prossimo proprietario può: </text> <check_box label="Modificare" name="checkbox next owner can modify"/> - <check_box label="Copiare" name="checkbox next owner can copy"/> - <check_box label="Rivendere/Regalare" name="checkbox next owner can transfer"/> - <text name="label click action"> - Se cliccato con il tasto sinistro del mouse + <check_box label="Copiare" name="checkbox next owner can copy" left_delta="80"/> + <check_box label="Rivendere/Regalare" name="checkbox next owner can transfer" left_delta="67"/> + <text name="label click action" width="220"> + Se cliccato con il tasto sinistro del mouse: </text> - <combo_box name="clickaction"> + <combo_box name="clickaction" width="192"> <combo_item name="Touch/grab(default)"> Tocca/Afferra (default) </combo_item> @@ -176,7 +177,7 @@ B: </text> <text name="O:"> - O; + O: </text> <text name="G:"> G: @@ -206,7 +207,7 @@ Devi selezionare l'intero oggetto per impostare i permessi. </string> <string name="Cost Default"> - Prezzo: L$ + Prezzo: L$ </string> <string name="Cost Total"> Prezzo totale: L$ @@ -351,7 +352,7 @@ </text> <spinner label="X" name="Shear X"/> <spinner label="Y" name="Shear Y"/> - <text name="advanced_cut"> + <text name="advanced_cut" width="149"> Ritaglia il profilo Inizio e Fine </text> <text name="advanced_dimple"> @@ -398,29 +399,29 @@ </combo_box> </panel> <panel label="Caratteristiche" name="Features"> - <text name="select_single"> + <text name="select_single" width="280"> Seleziona solo un prim per modificarne le caratteristiche. </text> <text name="edit_object"> Modifica le caratteristiche dell'oggetto: </text> <check_box label="Flessibilità " name="Flexible1D Checkbox Ctrl" tool_tip="Permette all'oggetto di flettersi rispetto all'asse Z. (solo lato client)"/> - <spinner label="Morbidezza" name="FlexNumSections"/> - <spinner label="Gravità " name="FlexGravity"/> - <spinner label="Elasticità " name="FlexFriction"/> - <spinner label="Sventolio" name="FlexWind"/> - <spinner label="Tensione" name="FlexTension"/> - <spinner label="Forza X" name="FlexForceX"/> - <spinner label="Forza Y" name="FlexForceY"/> - <spinner label="Forza Z" name="FlexForceZ"/> + <spinner label="Morbidezza" name="FlexNumSections" label_width="72" width="135"/> + <spinner label="Gravità " name="FlexGravity" label_width="72" width="135"/> + <spinner label="Elasticità " name="FlexFriction" label_width="72" width="135"/> + <spinner label="Sventolio" name="FlexWind" label_width="72" width="135"/> + <spinner label="Tensione" name="FlexTension" label_width="72" width="135"/> + <spinner label="Forza X" name="FlexForceX" label_width="72" width="135"/> + <spinner label="Forza Y" name="FlexForceY" label_width="72" width="135"/> + <spinner label="Forza Z" name="FlexForceZ" label_width="72" width="135"/> <check_box label="Luce" name="Light Checkbox Ctrl" tool_tip="Imposta l'oggetto come sorgente di luce"/> <text name="label color"> Colore </text> <color_swatch label="" name="colorswatch" tool_tip="Clicca per aprire la tavolozza dei colori"/> - <spinner label="Intensità " name="Light Intensity"/> - <spinner label="Raggio" name="Light Radius"/> - <spinner label="Attenuazione" name="Light Falloff"/> + <spinner label="Intensità " name="Light Intensity" label_width="72" width="135"/> + <spinner label="Raggio" name="Light Radius" label_width="72" width="135"/> + <spinner label="Attenuazione" name="Light Falloff" label_width="72" width="135" /> </panel> <panel label="Texture" name="Texture"> <texture_picker label="Texture" name="texture control" tool_tip="Clicca per scegliere un'immagine"/> @@ -431,11 +432,11 @@ <text name="glow label"> Bagliore </text> - <check_box label="Massima luminosità " name="checkbox fullbright"/> + <check_box label="Massima luminosità " name="checkbox fullbright" bottom_delta="-21"/> <text name="tex gen"> - Applicazione della texture + Applicazione della texture </text> - <combo_box name="combobox texgen"> + <combo_box name="combobox texgen" bottom_delta="-38"> <combo_item name="Default"> Default </combo_item> @@ -443,10 +444,10 @@ Planare </combo_item> </combo_box> - <text name="label shininess"> + <text name="label shininess" bottom="-120"> Brillantezza </text> - <combo_box name="combobox shininess"> + <combo_box name="combobox shininess" bottom_delta="-22"> <combo_item name="None"> Nessuna </combo_item> @@ -460,10 +461,10 @@ Alta </combo_item> </combo_box> - <text name="label bumpiness"> + <text name="label bumpiness" bottom="-120"> Rilievo </text> - <combo_box name="combobox bumpiness"> + <combo_box name="combobox bumpiness" width="100" bottom_delta="-22"> <combo_item name="None"> Nessuna </combo_item> @@ -538,7 +539,9 @@ <text name="rpt"> Ripetizioni per metro </text> - <button label="Applica" label_selected="Applica" name="button apply"/> + <spinner left="120" name="TexRot" width="60" /> + <spinner left="120" name="rptctrl" width="60" /> + <button label="Applica" label_selected="Applica" name="button apply" left_delta="72"/> <text name="tex offset"> Offset </text> @@ -548,11 +551,12 @@ Allinea texture dei media (deve prima caricarsi) </text> - <button label="Allinea" label_selected="Allinea" name="button align"/> + <button label="Allinea" label_selected="Allinea" name="button align" left="160"/> </panel> <panel label="Contenuto" name="Contents"> <button label="Nuovo Script" label_selected="Nuovo script..." name="button new script"/> <button label="Permessi..." name="button permissions"/> + <panel name="ContentsInventory" width="272" /> </panel> </tab_container> <panel name="land info panel"> @@ -560,24 +564,24 @@ Informazioni sul terreno </text> <text name="label_area_price"> - Prezzo: [PRICE] L$ per [AREA] mq. + Prezzo: [PRICE] L$ per [AREA] m² </text> <text name="label_area"> - Area: [AREA] mq. + Area: [AREA] m² </text> - <button label="Informazioni sul terreno..." label_selected="Informazioni sul terreno..." name="button about land"/> + <button label="Informazioni sul terreno..." label_selected="Informazioni sul terreno..." name="button about land" width="156"/> <check_box label="Mostra i proprietari" name="checkbox show owners" tool_tip="Colora i terreni in base ai loro proprietari"/> - <button label="?" label_selected="?" name="button show owners help"/> + <button label="?" label_selected="?" name="button show owners help" left_delta="120"/> <text name="label_parcel_modify"> Modifica il terreno </text> - <button label="Suddividi..." label_selected="Suddividi..." name="button subdivide land"/> - <button label="Unisci..." label_selected="Unisci..." name="button join land"/> + <button label="Suddividi..." label_selected="Suddividi..." name="button subdivide land" width="156"/> + <button label="Unisci..." label_selected="Unisci..." name="button join land" width="156"/> <text name="label_parcel_trans"> Transazioni del territorio </text> - <button label="Acquista il terreno..." label_selected="Acquista il terreno..." name="button buy land"/> - <button label="Abbandona il terreno..." label_selected="Abbandona il terreno..." name="button abandon land"/> + <button label="Acquista il terreno..." label_selected="Acquista il terreno..." name="button buy land" width="156"/> + <button label="Abbandona il terreno..." label_selected="Abbandona il terreno..." name="button abandon land" width="156"/> </panel> <string name="status_rotate"> Sposta le fasce colorate per ruotare l'oggetto diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml index a9edf6766e41d1b4371a99502b9d39d33c979cef..9e54bc24a93e16d579f0df3017f28eaa09fffa6c 100644 --- a/indra/newview/skins/default/xui/it/notifications.xml +++ b/indra/newview/skins/default/xui/it/notifications.xml @@ -6,6 +6,9 @@ <global name="alwayschoose"> Scegli sempre questa opzione </global> + <global name="implicitclosebutton"> + Chiudi + </global> <template name="okbutton"> <form> <button @@ -2957,7 +2960,7 @@ Gli oggetti flessibili non possono essere fisici e devano essere fantasma fino a <notification name="FirstDebugMenus"> Hai attivato il menu Avanzato. Questo menu contiene funzioni utili per gli sviluppatori per il debug di Second Life. -Per attivare o disattivare questo menu su Windows premere Ctrl-Alt-D. Su Mac premere Cmd-Opt-Shift-D. +Per attivare o disattivare questo menu su Windows premere Ctrl-Alt-D. Su Mac premere ⌘-Opt-D. </notification> <notification name="FirstSculptedPrim"> Si sta modificando uno sculpted prim. diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index b33d883dc4315e41081d9e479a93401ffd1d211c..478bcfda18c06ada976c29359136668d4be9692b 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -6,6 +6,9 @@ <global name="alwayschoose"> 常ã«ã“ã®ã‚ªãƒ—ションをé¸æŠž </global> + <global name="implicitclosebutton"> + é–‰ã˜ã‚‹ + </global> <template name="okbutton"> <form> <button @@ -3165,7 +3168,7 @@ Second Life をデãƒãƒƒã‚°ã™ã‚‹ãƒ‡ãƒ™ãƒãƒƒãƒ‘ーã«ã¨ã£ã¦ 有用ãªæ©Ÿèƒ½ãŒã‚ã‚Šã¾ã™ã€‚ ã“ã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚’切り替ãˆã‚‹ã«ã¯ã€ Windowsã§ã¯Ctrl-Alt-Dを押ã—ã¾ã™ã€‚ -Macã®å ´åˆã¯ã€Cmd-Opt-Shift-Dを押ã—ã¦ãã ã•ã„。 +Macã®å ´åˆã¯ã€⌘-Opt-Shift-Dを押ã—ã¦ãã ã•ã„。 </notification> <notification name="FirstSculptedPrim"> スカルプトプリムを編集ã—ã¦ã„ã¾ã™ã€‚ diff --git a/indra/newview/skins/default/xui/nl/menu_inventory.xml b/indra/newview/skins/default/xui/nl/menu_inventory.xml index f406bcf6bc7dd3839219febb2ee6dd3e8ef9dcef..6a514422b944ff1586bbb6dd2a7990e67a1f459a 100644 --- a/indra/newview/skins/default/xui/nl/menu_inventory.xml +++ b/indra/newview/skins/default/xui/nl/menu_inventory.xml @@ -12,7 +12,7 @@ <menu_item_call label="Nieuw script" name="New Script"/> <menu_item_call label="Nieuwe notitie" name="New Note"/> <menu_item_call label="Nieuw gebaar" name="New Gesture"/> - <menu name="New Clothes"> + <menu name="New Clothes" label="Nieuwe Kleding"> <menu_item_call label="Nieuw shirt" name="New Shirt"/> <menu_item_call label="Nieuwe broek" name="New Pants"/> <menu_item_call label="Nieuwe schoenen" name="New Shoes"/> @@ -23,7 +23,7 @@ <menu_item_call label="Nieuw onderhemd" name="New Undershirt"/> <menu_item_call label="Nieuwe onderbroek" name="New Underpants"/> </menu> - <menu name="New Body Parts"> + <menu name="New Body Parts" label="Nieuwe Lichaamsdelen"> <menu_item_call label="Nieuwe postuur" name="New Shape"/> <menu_item_call label="Nieuwe huid" name="New Skin"/> <menu_item_call label="Nieuw haar" name="New Hair"/> diff --git a/indra/newview/skins/default/xui/nl/notifications.xml b/indra/newview/skins/default/xui/nl/notifications.xml index d6f13f1f333a00c9579ea5f824e588e1bd78d6eb..4c64c93de3dd9bd363eb22b8304bb7f47fb2ce71 100644 --- a/indra/newview/skins/default/xui/nl/notifications.xml +++ b/indra/newview/skins/default/xui/nl/notifications.xml @@ -6,6 +6,9 @@ <global name="alwayschoose"> Kies altijd deze optie </global> + <global name="implicitclosebutton"> + Sluiten + </global> <template name="okbutton"> <form> <button @@ -2953,7 +2956,7 @@ Flexibele objecten mogen niet fysiek zijn en moeten fantoom zijn tot de 'fl <notification name="FirstDebugMenus"> U heeft het menu Geavanceerd geactiveerd. Dit menu bevat opties die handig zijn voor ontwikkelaars tijdens het debuggen van Second Life. -Om dit menu in en uit te schakelen drukt u binnen Windows Ctrl-Alt-D. Met een Mac drukt u Cmd-Opt-Shift-D. +Om dit menu in en uit te schakelen drukt u binnen Windows Ctrl-Alt-D. Met een Mac drukt u ⌘-Opt-D. </notification> <notification name="FirstSculptedPrim"> U bent een sculpted prim aan het bewerken. diff --git a/indra/newview/skins/default/xui/nl/strings.xml b/indra/newview/skins/default/xui/nl/strings.xml index 4b64586887a41fb08d80366e8cdffcd60edc9bf4..49e566080ab488ab830bca9759e5264cb25f4f98 100644 --- a/indra/newview/skins/default/xui/nl/strings.xml +++ b/indra/newview/skins/default/xui/nl/strings.xml @@ -55,6 +55,9 @@ <string name="LoginDownloadingClothing"> Kleding downloaden... </string> + <string name="Quit"> + Afsluiten + </string> <string name="AgentLostConnection"> Deze regio kan problemen ondervinden. Controleer alstublieft uw verbinding met het internet. </string> diff --git a/indra/newview/skins/default/xui/pl/floater_god_tools.xml b/indra/newview/skins/default/xui/pl/floater_god_tools.xml index c978da6d65edd55dcb46788247d55405f6fe2871..762b9f0f55c6384d8c7c8be75f7dfcb093c737c1 100755 --- a/indra/newview/skins/default/xui/pl/floater_god_tools.xml +++ b/indra/newview/skins/default/xui/pl/floater_god_tools.xml @@ -42,7 +42,7 @@ <line_editor left_delta="45" name="redirecty" width="35" /> <spinner name="billable factor"/> <text name="billable factor text"> - Czynnik PÅ‚atnośći: + Czynnik PÅ‚atnoÅ›ci: </text> <spinner name="land cost"/> <text name="land cost text"> @@ -68,8 +68,8 @@ <text name="target_avatar_name"> (brak) </text> - <button label="UsuÅ„ cel 's skryptowane obiekty na innych posiadÅ‚oÅ›ciach" label_selected="UsuÅ„ cel 's skryptowane obiekty na innych posiadÅ‚oÅ›ciach" name="Delete Target's Scripted Objects On Others Land" /> - <button label="UsuÅ„ cel 's skryptowane obiekty na jakichkolwiek posiadÅ‚oÅ›ciach" label_selected="UsuÅ„ cel 's skryptowane obiekty na jakichkolwiek posiadÅ‚oÅ›ciach" name="Delete Target's Scripted Objects On *Any* Land" /> + <button label="UsuÅ„ cel z oskryptowanych obiektów na innych posiadÅ‚oÅ›ciach" label_selected="UsuÅ„ cel 's skryptowane obiekty na innych posiadÅ‚oÅ›ciach" name="Delete Target's Scripted Objects On Others Land" /> + <button label="UsuÅ„ cel z oskryptowanych obiektów na jakichkolwiek posiadÅ‚oÅ›ciach" label_selected="UsuÅ„ cel 's skryptowane obiekty na jakichkolwiek posiadÅ‚oÅ›ciach" name="Delete Target's Scripted Objects On *Any* Land" /> <button label="UsuÅ„ wszystkie cele i obiekty" label_selected="UsuÅ„ wszystkie cele i obiekty" name="Delete *ALL* Of Target's Objects" /> <button label="Główne Kolizje" label_selected="Główne Kolizje" name="Get Top Colliders" /> <button label="Główne Skrypty" label_selected="Główne Skrypty" name="Get Top Scripts" /> diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml index 74f92ba1c0a58968314cb048632b7250f436f27d..84075b9db84b02e2cf9ade0b7d2d8bb2a7649b49 100644 --- a/indra/newview/skins/default/xui/pl/notifications.xml +++ b/indra/newview/skins/default/xui/pl/notifications.xml @@ -6,6 +6,9 @@ <global name="alwayschoose"> Pozwalaj na wybór tej opcji </global> + <global name="implicitclosebutton"> + Zamknij + </global> <template name="okbutton"> <form> <button @@ -2718,7 +2721,7 @@ Spróbuj ponowanie za kilka minut. </form> </notification> <notification name="TeleportOffered"> - [NAME] proponuje Ci teleportcjÄ™ do siebie: + [NAME] proponuje Ci teleportacjÄ™ do siebie: [MESSAGE] <form name="form"> @@ -2899,8 +2902,8 @@ Obiekty elastyczne nie mogÄ… być fizyczne i muszÄ… być typu fantom. </notification> <notification name="FirstDebugMenus"> Zaawansowane menu zostaÅ‚o wÅ‚Ä…czone. -To menu zawiera funkcje użyteczne dla programistów analizujÄ…cych Secon Life. -To menu jest wÅ‚Ä…czne przez Ctrl-Alt-D pod Windows. Mac używa Cmd-Opt-Shift-D. +To menu zawiera funkcje użyteczne dla programistów analizujÄ…cych Second Life. +To menu jest aktywowane dziÄ™ki kombinacji klawiszy Ctrl-Alt-D (Windows) lub ⌘-Opt-D (Mac). </notification> <notification name="FirstSculptedPrim"> Edytujesz sculpt. diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml index 5067f044e0f088229f1bf484f80b672a44e60d61..3ec2b45237c2ee600c6fab963c38dd08f1a6707b 100755 --- a/indra/newview/skins/default/xui/pl/strings.xml +++ b/indra/newview/skins/default/xui/pl/strings.xml @@ -55,6 +55,9 @@ <string name="LoginDownloadingClothing"> Åadowanie ubrania... </string> + <string name="Quit"> + Wyjdź + </string> <string name="AgentLostConnection"> Ten region może mieć problemy. Sprawdź podÅ‚Ä…czenie do Internetu. </string> diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml index 26c5f9debf3cc650ab2776baf0abde1690f924a9..cc90b6d08fc8d010354c557fb3a2bd5bde88519e 100644 --- a/indra/newview/skins/default/xui/pt/notifications.xml +++ b/indra/newview/skins/default/xui/pt/notifications.xml @@ -6,6 +6,9 @@ <global name="alwayschoose"> Sempre escolher esta opção </global> + <global name="implicitclosebutton"> + Fechar + </global> <template name="okbutton"> <form> <button @@ -2118,7 +2121,7 @@ Coloque-a em uma página web para dar aos outros um fácil acesso a este local o </form> </notification> <notification name="GraphicsPreferencesHelp"> - Este painel controla o tamanho da janela, resolução e a qualidade dos gráficos do computador cliente. O Preferências > Interface Gráfica permite escolher entre quatro nÃveis gráficos: Baixo, Médio, Alto e Ultra. Você também pode personalizar suas configurações de gráficos selecionando a opção Padrão e manipulando as seguintes definições: + Este painel controla o tamanho da janela, resolução e a qualidade dos gráficos do computador cliente. O Preferências > Interface Gráfica permite escolher entre quatro nÃveis gráficos: Baixo, Médio, Alto e Ultra. Você também pode personalizar suas configurações de gráficos selecionando a opção Personalizar e manipulando as seguintes definições: Sombreamento: Ativar ou desativar vários tipos de sombreadores de pixel. @@ -2910,7 +2913,7 @@ Objetos flexÃveis não podem ser fÃsicos e devem ser fantasmas até que a caix <notification name="FirstDebugMenus"> Você ativou o menu Avançado. Este menu contém funcionalidades úteis para desenvolvedores debugarem o Second Life. -Para mostrar esse menu no Windows pressione Ctrl-Alt-D. No Mac pressione Cmd-Opt-Shift-D. +Para mostrar esse menu no Windows pressione Ctrl-Alt-D. No Mac pressione ⌘-Opt-D. </notification> <notification name="FirstSculptedPrim"> Você está editando uma primitiva esculpida. diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml index ec46c8b99ccbef072111e25fc16ccad27ff1b49b..621e99c9c5713dc4c3cdfa794cea39967bbbc0b8 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml @@ -3,7 +3,7 @@ <button label="?" name="GraphicsPreferencesHelpButton"/> <check_box label="Execute Second Life em uma janela" name="windowed mode"/> <text_editor bottom="-56" height="40" name="FullScreenInfo" width="480"> - Se desmarcado, o visualizador irá exibir em tela inteira quando fizer o acesso. + Se desmarcado, o visualizador exibirá tela inteira quando fizer o acesso. </text_editor> <text name="WindowSizeLabel"> Tamanho da Janela: @@ -56,7 +56,7 @@ rápido <text name="QualityText2"> Qualidade </text> - <check_box label="Padrão" left="395" name="CustomSettings"/> + <check_box label="Personalizar" left="395" name="CustomSettings"/> <text name="ShadersText"> Sombreadores: </text>