diff options
author | Richard Nelson <richard@lindenlab.com> | 2009-08-24 20:04:52 +0000 |
---|---|---|
committer | Richard Nelson <richard@lindenlab.com> | 2009-08-24 20:04:52 +0000 |
commit | 138bf1132262c479dbbd5c95195db46b1efd065f (patch) | |
tree | be2286f245865008b4ca6d738194133542822d65 /indra | |
parent | c2619694fd2f94ad7da2d6e936494f4c16601212 (diff) |
merge -r 130399-131510 skinning-21 -> viewer-2.0.0-3
DEV-11254 DEV-11254 DEV-2003: DEV-21567 DEV-37301 EXT-104 EXT-138 EXT-217 EXT-256 EXT-259 EXT-259 EXT-328 EXT-348 EXT-386 EXT-399 EXT-403 EXT-460 EXT-492 EXT-492 EXT-531 EXT-537 EXT-684
improved text editor (handles multiple fonts simultaneously as well as inline widgets)
Diffstat (limited to 'indra')
227 files changed, 6154 insertions, 6624 deletions
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 6633c65317..20ff7bab34 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 612068b202..0d89353dee 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -69,13 +69,13 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: mLastTimer = sCurTimer; sCurTimer = this; +#endif } ~LLFastTimer() @@ -332,6 +223,7 @@ public: 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 8db3284c42..30e5d435ae 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 540a18b8a0..d3597b454c 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 ba0f798dbb..9140ebb3f3 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 ec1718a8cb..d7da40d645 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 f6bb0e0fe2..a15d6a9a14 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 @@ public: // 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 894f0a7ed0..c03a331aff 100644 --- a/indra/llmath/llrect.h +++ b/indra/llmath/llrect.h @@ -141,10 +141,20 @@ public: // 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 @@ public: 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 @@ public: { 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 3e3f0b37a7..5e9dfd81fa 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 80ea6ce96b..8c9eb7ed42 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 62534969b7..0be6bedbee 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 177e13e27c..d76b23248d 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 42ed7a381f..af8e0909af 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -97,7 +97,7 @@ public: 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 @@ public: 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 @@ private: 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 553e7b8f9d..99f364a589 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 c3d1d9e894..3669b49e51 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 c566282bef..b13b250c75 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 b3c3a2e698..ac56d15d1b 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 7e7d6ac111..51ef80f4b9 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 d420d1141e..2679143bbc 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 30796a5ab9..db1611abb5 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 38f5e993c2..53377869ca 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 @@ public: 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 @@ public: 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 702d8e4a39..f98edec1f3 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 42a1b9ad9c..6926415c6d 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 5be53e6afc..b6c3ffc61c 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 d39a02da28..2e7f61c2dd 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -105,10 +105,15 @@ protected: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 11fa290de1..c8162fe466 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 9f9e3aecac..e8ce1a8d97 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 da55ababab..667a3e10c4 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 2a70467ffc..3ee11483c3 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -115,9 +115,6 @@ public: /*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 @@ public: 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 @@ public: 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 @@ private: 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 30adbb023c..c66b9bde2b 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 d04473fa44..b5516307fd 100644 --- a/indra/llui/llradiogroup.h +++ b/indra/llui/llradiogroup.h @@ -106,9 +106,7 @@ public: 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 1560a03796..1c09cbb1bd 100644 --- a/indra/llui/llresizehandle.h +++ b/indra/llui/llresizehandle.h @@ -76,8 +76,8 @@ private: 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 566825ff3b..b46915b379 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 5522e5d0fa..30d906e04c 100644 --- a/indra/llui/llscrollbar.h +++ b/indra/llui/llscrollbar.h @@ -127,11 +127,6 @@ public: 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 0b455f8e17..13f862f3af 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 912d126f23..8385bca02f 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -66,9 +66,13 @@ public: 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 @@ public: 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 @@ public: 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 @@ private: BOOL mReserveScrollCorner; BOOL mAutoScrolling; F32 mAutoScrollRate; + F32 mMinAutoScrollRate; + F32 mMaxAutoScrollRate; }; diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index cd43e194d2..e28da91305 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 3041773fb2..637642cdcd 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 e699711bd4..253a58ab73 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -329,15 +329,16 @@ public: 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 @@ private: const BOOL mDisplayColumnHeaders; BOOL mColumnsDirty; - item_list mItemList; + mutable item_list mItemList; LLScrollListItem *mLastSelected; @@ -429,7 +430,7 @@ private: 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 432d54dfee..929a809d88 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 32ddded2c8..dcf274a651 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 @@ public: 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 29c30004ef..ee36318107 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 78592a0f9a..ebe76af966 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -104,7 +104,8 @@ public: /*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 f9bcb685b8..96e72487b8 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 48816e4b9e..7d13220c94 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 @@ private: 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 @@ public: } 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 @@ private: 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 @@ public: } 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,156 +852,316 @@ 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(); + if (!keep_cursor_offset) + updateCursorXPos(); + // did we get requested position? + return new_cursor_pos == cursor_pos; +} + +void LLTextEditor::updateCursorXPos() +{ // reset desired x cursor position - mDesiredXPixel = -1; + mDesiredXPixel = getLocalRectFromDocIndex(mCursorPos).mLeft; +} + +// constraint cursor to editable segments of document +S32 LLTextEditor::getEditableIndex(S32 index, bool increasing_direction) +{ + //// 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 @@ -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(); + LLRect content_display_rect = mScroller->getVisibleContentRect(); - S32 left_line_num = cur_line; - S32 num_lines = getLineCount(); - S32 right_line_num = num_lines - 1; + // 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 line_start = -1; - if (cur_line >= num_lines) - { - return; - } - - line_start = getLineStart(cur_line); - - 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); + + // take style from last segment + LLTextSegmentPtr segmentp; - S32 num_lines = getLineCount(); - if (cur_pos >= num_lines) + 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); - } - - 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(); - } + 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)); - 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(); - bindEmbeddedChars( mGLFont ); + mDocumentPanel->setBackgroundColor(bg_color); - drawBackground(); + drawChildren(); + drawBackground(); //overlays scrolling panel bg + drawLineNumbers(); + + { + 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) { - mOnScrollEndCallback(mOnScrollEndData); + // cursor didn't change apparent position, so move to top or bottom of document, respectively + if (delta < 0) + { + startOfDoc(); + } + else + { + endOfDoc(); + } + } + else + { + 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; - - 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); -} + LLRect visible_region = mScroller->getVisibleContentRect(); -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,50 +3673,94 @@ 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(); + segment_set_t::iterator cur_seg_iter = getSegIterContaining(segment_to_insert->getStart()); - BOOL in_text = FALSE; - - LLColor4 text_color = ( mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get() ); - - 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 0babd7ba58..67c67d0f67 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: // 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 @@ public: 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 @@ protected: 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 @@ protected: 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 @@ protected: 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 @@ protected: 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 @@ protected: 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 @@ protected: 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 @@ protected: 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 @@ protected: 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 @@ private: 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 @@ private: S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes - const LLFontGL* mGLFont; + const LLFontGL* mDefaultFont; class LLViewBorder* mBorder; @@ -515,49 +628,35 @@ private: 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 @@ private: }; // 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 fab8f61356..7e4df892c4 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 b1943a7b02..1f9b0b2dbc 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 8aa7540446..4a9fec3191 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 6ba3b01fcb..a4f539af14 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -186,8 +186,10 @@ public: /*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 @@ public: 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 @@ protected: 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 2bbede8c13..1161101f90 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 0ba028e1c8..e2dc85d03f 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1301,6 +1301,11 @@ LLView* LLView::childrenHandleMiddleMouseUp(S32 x, S32 y, MASK mask) void LLView::draw() { + drawChildren(); +} + +void LLView::drawChildren() +{ if (sDebugRects) { drawDebugRect(); @@ -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 ee49276139..6247bf036c 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -213,6 +213,9 @@ protected: 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 @@ public: virtual std::string getShowNamesToolTip(); virtual void draw(); + void drawChildren(); void parseFollowsFlags(const LLView::Params& params); @@ -484,19 +488,20 @@ public: 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 @@ private: 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 860aa3302e..f41c98f7b3 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 6b1563bab1..5fdf41188d 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 ce1bc82168..9936b24292 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 0864940866..7d94601568 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 cb56049ae2..a1d0831939 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 db7421575c..2efc475f57 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 6423c88245..340d70e434 100644 --- a/indra/llxuixml/lltrans.h +++ b/indra/llxuixml/lltrans.h @@ -78,6 +78,7 @@ public: * @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 @@ public: 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 e1f61906e2..e28e52fd16 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 05fee9a419..d7f445d3d8 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 5045f18784..fe9eae04a1 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 @@ public: } }; +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 a85f8710c7..f557adf6a6 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 2687feb68b..2403e891f6 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 7a118deb8a..bea11ecfeb 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 45b322e106..05c574b154 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 933d9b8771..9399e1f68d 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 d8bd32382f..7cc78aff92 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 940e1fc968..c765980c30 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 267f83f295..de97e2406d 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 b15cd0b0dc..a2d8c965ec 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 971949e885..2cb4d5d6d5 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 1fdf87f6d2..d084bda2ea 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 a01c9026c8..345dd6bb84 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 f572e2cb44..5cb1fcb635 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 16623ca2b6..fd4dc123d5 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 917b6fafbc..9b52ddb73c 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 0aef3123d6..8ceb41c27a 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 78ca7b50d6..f301888984 100644 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -62,7 +62,7 @@ public: 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 7fc127f803..9c1a7ecb04 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 bafb69a835..216bca8262 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 7332ca4b5c..3c27d37ee9 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 3d1b7965a1..7075719299 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 7df07f752d..00d44035ae 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 742cc5c5de..8c09ee7d48 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 e8af48d095..6ba3165d6a 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 1e8e7bad74..eb73bd6d8f 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 3c66a2add1..45a42f994d 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 c5e07c6596..1746d6d435 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 7fc5ed0c9e..29d1c4dd84 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 0a3d97245b..f2dff55044 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 aa68a1b229..ac687ed3e9 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 1a7f72d49c..79f8f412fd 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 8ac00832c9..ab281e9f9f 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 94d25aa0c8..a50bcaa098 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 00cbc2f0c8..e2176350c9 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 c8690de68c..328fb6450e 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 53b40f8b7a..616e9bac35 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 e7dda3a5f4..65803fbf70 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 @@ private: virtual ~LLFloaterSettingsDebug(); protected: - LLTextEditor* mComment; + class LLTextEditor* mComment; }; #endif //LLFLOATERDEBUGSETTINGS_H diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 371dfa50cd..814395395c 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 1e84902594..f61d5cb077 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 e5b4657742..2eb4e7580e 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 4a5a775a05..d1f0f94fa0 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 8d9d52cd17..a05dec3193 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -240,7 +240,7 @@ public: 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 @@ protected: 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 de6a1a097d..8961508bcc 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 8588de0fa0..bdb8dadfb4 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 bdff492948..dc55aba0db 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 c71262c311..8086400493 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 0b4e0f9317..72e2bb02d5 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 6ad483a2f1..e3902bffa0 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 54802ee762..efa97de692 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 cdfb15fd71..63a40e40a0 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 9a66507eae..713c44d366 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 32d7bc94ff..da9f50a2bc 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 50e31e85e4..0696d41732 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 4b0c42c3c0..19177e37b3 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -53,7 +53,7 @@ public: ~LLGestureComboBox(); void refreshGestures(); - void onCommitGesture(LLUICtrl* ctrl); + void onCommitGesture(); virtual void draw(); // LLGestureManagerObserver trigger @@ -61,6 +61,7 @@ public: protected: LLFrameTimer mGestureLabelTimer; + std::vector<LLMultiGesture*> mGestures; std::string mLabel; }; diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index a56688d862..8124d4b36a 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 42522942f3..f58f993a2e 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 d95240e30c..8caa7d85eb 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 73c52cdf2e..0f275ea9a8 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 f06342ebfc..56042f6bff 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 2cb7fd8c14..c6840721a3 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 39f7d41a8d..cf91972e8b 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 ce9fcd9da2..cadab71ba8 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 ad978cc5b3..49b9bbadfb 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 9990c22dac..2e005834b5 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 c4364ed6ca..c2fce08ae4 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 04a3b52e98..222672deff 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 569e7b3397..8a5de61280 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 a422db1cc1..fc125dcf9c 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 254509ea1d..d29ff1ae28 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 8a61f6cfda..6f26b4077c 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 a7b57802c1..844c54da6a 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 f08c287529..8e65c7e65e 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 499632def3..207b9592b8 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 33568bf3cb..d83f3d9207 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 ec11e0aee2..99723f86a7 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 8939faeb91..a8232e9a9d 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 ec39819bc8..cfb8340462 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 709fcdcf01..444d8e3164 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 9e0713b494..7565c86696 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 @@ public: } }; +// +// 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 @@ public: // 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 1a69c6869d..9567bfbc48 100644 --- a/indra/newview/llviewertexteditor.h +++ b/indra/newview/llviewertexteditor.h @@ -65,8 +65,6 @@ public: // 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 @@ public: 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 @@ public: 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 @@ private: 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 7b01fe4280..83442dc2bb 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 2b1dbf8e84..74ed5b12fe 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 2b5c3361c4..e98e4f2e6a 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 fbc4e2e609..130e1fd749 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 cf6eb8e9fd..a2793accea 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 29036f4947..38c9ce28c4 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 993cf522e9..ae5992099d 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 4980b50de4..157d719fcc 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 d1cac4c77e..86d9f31d07 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 bef38bb669..f7a16571d1 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 427119285b..332c9dd952 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 abd25e6598..8621e5e1d9 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 92c223e43d..3661be500b 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 c237c0bded..ae476c88c9 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 f422791868..bf00957212 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 fc02e7dd88..8f6867aa01 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 Binary files differindex a4060e5e37..e27dbe2cad 100644 --- a/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png +++ b/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png Binary files differindex 9c2815ebba..82d044d817 100644 --- a/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png +++ b/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png Binary files differindex 377b707529..7909d54f2b 100644 --- a/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png +++ b/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png Binary files differindex a69a729bd4..6670667022 100644 --- a/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png +++ b/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png Binary files differindex fb59f2e61e..5dd0852a72 100644 --- a/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png +++ b/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Close_Press.png b/indra/newview/skins/default/textures/windows/Icon_Close_Press.png Binary files differindex 7177c803b0..ea547fca6f 100644 --- a/indra/newview/skins/default/textures/windows/Icon_Close_Press.png +++ b/indra/newview/skins/default/textures/windows/Icon_Close_Press.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png Binary files differindex cadd6bc8ce..4207ba68e5 100644 --- a/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png +++ b/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png b/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png Binary files differindex 08f8cfc3d4..2d09475783 100644 --- a/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png +++ b/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png Binary files differindex d790cf57ef..9a71d16a3f 100644 --- a/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png +++ b/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Undock_Press.png b/indra/newview/skins/default/textures/windows/Icon_Undock_Press.png Binary files differindex fdae4b75f6..3ab8c3666a 100644 --- a/indra/newview/skins/default/textures/windows/Icon_Undock_Press.png +++ b/indra/newview/skins/default/textures/windows/Icon_Undock_Press.png diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml index eedc588449..633fff079b 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" - > -[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... + <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]. + </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. + </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. + </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. + </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. + </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. + </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. + </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. + </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. + </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: + </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] - <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: + <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. + <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. + <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. + </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'). + </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'). + </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'). + </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 + </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] + </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> + <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="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] + <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. + <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. + <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. + <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. + </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> + <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: + <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: + <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. 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 6c103f7e37..06a432bd3b 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 d2a0193763..bf8988ca45 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 ece0cf737f..6eb55fa57f 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 cb3388ccbc..9165e8db98 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 777236504d..5e0e423128 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 5c4649276a..2e7f5e6c42 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 0a97a96ee3..60677ca0df 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 91c2a41891..8657663057 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 2906b73af8..bacec627e1 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 a463b2274d..2fd561f991 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 f8f1abd179..4595c9eeda 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 6585667c8b..54facbb659 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 6a022e8966..e46588dd71 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 4e3c0d0c40..642087baff 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 146d7d06fe..7e07a97016 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 d5d9d3c43d..ee37d49946 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 3d2558ce5a..5e894e1773 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 3083a7f689..8b0741524d 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 4f241664fb..b6d0678cfb 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 3acd8fae4b..fde795260e 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 b0f8052a9c..b336c86e95 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 9fa2765e97..a38d7eee36 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 e90a57a375..be68187eaf 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 d24d11039a..4d373fbf3a 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 33592d289f..b4d2bbb194 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 0e87c621b9..060d84b2e4 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 0c01aec95d..ecfb0048a3 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 65db3cc7a1..5d0af26af5 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 8265ab3227..8445b933bf 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 1dafd50cdb..ee52184119 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 bf63bb0cb6..8e8fc9ef7f 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 9fd075f79b..5738879c5a 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 82b7e02aeb..3ad5cbe018 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 3d4ac94044..655cf2b40f 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 616dc1a1d4..e8f6b1319a 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 17e9a7beb2..26af76d8a3 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 89a88330c7..b249451247 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 4ad11c41da..48bc021e6d 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 cb9ef04797..86356ff563 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 960c4e81e5..4f2261c953 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 527485e57d..da7753a7d7 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 557123d4f8..28d47fce52 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 d7e480c653..f045c6fe9e 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 1e10ccf992..da9a820eb8 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 4793f6c661..96bf0ea865 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 30092a426f..7d2cdd8454 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 a89ae9d803..3c79cd8829 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 a9edf6766e..9e54bc24a9 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 b33d883dc4..478bcfda18 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 f406bcf6bc..6a514422b9 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 d6f13f1f33..4c64c93de3 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 4b64586887..49e566080a 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 c978da6d65..762b9f0f55 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 74f92ba1c0..84075b9db8 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 5067f044e0..3ec2b45237 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 26c5f9debf..cc90b6d08f 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 ec46c8b99c..621e99c9c5 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> |