diff options
Diffstat (limited to 'indra')
656 files changed, 7422 insertions, 15895 deletions
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 2dd296bf12..95ed5d6bc8 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -221,6 +221,7 @@ elseif(LINUX) libcrypto.so.0.9.7 libdb-4.2.so libexpat.so + libexpat.so.1 libgmock_main.so libgmock.so.0 libgmodule-2.0.so diff --git a/indra/cmake/FindGoogleBreakpad.cmake b/indra/cmake/FindGoogleBreakpad.cmake new file mode 100644 index 0000000000..1a0493be5e --- /dev/null +++ b/indra/cmake/FindGoogleBreakpad.cmake @@ -0,0 +1,40 @@ +# -*- cmake -*- + +# - Find Google BreakPad +# Find the Google BreakPad includes and library +# This module defines +# BREAKPAD_EXCEPTION_HANDLER_INCLUDE_DIR, where to find exception_handler.h, etc. +# BREAKPAD_EXCEPTION_HANDLER_LIBRARIES, the libraries needed to use Google BreakPad. +# BREAKPAD_EXCEPTION_HANDLER_FOUND, If false, do not try to use Google BreakPad. +# also defined, but not for general use are +# BREAKPAD_EXCEPTION_HANDLER_LIBRARY, where to find the Google BreakPad library. + +FIND_PATH(BREAKPAD_EXCEPTION_HANDLER_INCLUDE_DIR google_breakpad/exception_handler.h) + +SET(BREAKPAD_EXCEPTION_HANDLER_NAMES ${BREAKPAD_EXCEPTION_HANDLER_NAMES} breakpad_client) +FIND_LIBRARY(BREAKPAD_EXCEPTION_HANDLER_LIBRARY + NAMES ${BREAKPAD_EXCEPTION_HANDLER_NAMES} + ) + +IF (BREAKPAD_EXCEPTION_HANDLER_LIBRARY AND BREAKPAD_EXCEPTION_HANDLER_INCLUDE_DIR) + SET(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES ${BREAKPAD_EXCEPTION_HANDLER_LIBRARY}) + SET(BREAKPAD_EXCEPTION_HANDLER_FOUND "YES") +ELSE (BREAKPAD_EXCEPTION_HANDLER_LIBRARY AND BREAKPAD_EXCEPTION_HANDLER_INCLUDE_DIR) + SET(BREAKPAD_EXCEPTION_HANDLER_FOUND "NO") +ENDIF (BREAKPAD_EXCEPTION_HANDLER_LIBRARY AND BREAKPAD_EXCEPTION_HANDLER_INCLUDE_DIR) + + +IF (BREAKPAD_EXCEPTION_HANDLER_FOUND) + IF (NOT BREAKPAD_EXCEPTION_HANDLER_FIND_QUIETLY) + MESSAGE(STATUS "Found Google BreakPad: ${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES}") + ENDIF (NOT BREAKPAD_EXCEPTION_HANDLER_FIND_QUIETLY) +ELSE (BREAKPAD_EXCEPTION_HANDLER_FOUND) + IF (BREAKPAD_EXCEPTION_HANDLER_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find Google BreakPad library") + ENDIF (BREAKPAD_EXCEPTION_HANDLER_FIND_REQUIRED) +ENDIF (BREAKPAD_EXCEPTION_HANDLER_FOUND) + +MARK_AS_ADVANCED( + BREAKPAD_EXCEPTION_HANDLER_LIBRARY + BREAKPAD_EXCEPTION_HANDLER_INCLUDE_DIR + ) diff --git a/indra/cmake/GoogleBreakpad.cmake b/indra/cmake/GoogleBreakpad.cmake index 8270c0fabb..7498674042 100644 --- a/indra/cmake/GoogleBreakpad.cmake +++ b/indra/cmake/GoogleBreakpad.cmake @@ -2,8 +2,8 @@ include(Prebuilt) if (STANDALONE) - MESSAGE(FATAL_ERROR "*TODO standalone support for google breakad is unimplemented") - # *TODO - implement this include(FindGoogleBreakpad) + set(BREAKPAD_EXCEPTION_HANDLER_FIND_REQUIRED ON) + include(FindGoogleBreakpad) else (STANDALONE) use_prebuilt_binary(google_breakpad) if (DARWIN) diff --git a/indra/cmake/PNG.cmake b/indra/cmake/PNG.cmake index 4d0b7b2d8d..f6522d9e2f 100644 --- a/indra/cmake/PNG.cmake +++ b/indra/cmake/PNG.cmake @@ -9,5 +9,5 @@ if (STANDALONE) else (STANDALONE) use_prebuilt_binary(libpng) set(PNG_LIBRARIES png12) - set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) + set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng12) endif (STANDALONE) diff --git a/indra/cmake/PulseAudio.cmake b/indra/cmake/PulseAudio.cmake index f8087a8083..e918de0198 100644 --- a/indra/cmake/PulseAudio.cmake +++ b/indra/cmake/PulseAudio.cmake @@ -1,28 +1,28 @@ # -*- cmake -*- include(Prebuilt) -if (STANDALONE) - include(FindPkgConfig) +set(PULSEAUDIO ON CACHE BOOL "Build with PulseAudio support, if available.") - pkg_check_modules(PULSEAUDIO REQUIRED libpulse-mainloop-glib) +if (PULSEAUDIO) + if (STANDALONE) + include(FindPkgConfig) + + pkg_check_modules(PULSEAUDIO libpulse) -elseif (LINUX) - use_prebuilt_binary(pulseaudio) - set(PULSEAUDIO_FOUND ON FORCE BOOL) - set(PULSEAUDIO_INCLUDE_DIRS - ${LIBS_PREBUILT_DIR}/include + elseif (LINUX) + use_prebuilt_binary(pulseaudio) + set(PULSEAUDIO_FOUND ON FORCE BOOL) + set(PULSEAUDIO_INCLUDE_DIRS + ${LIBS_PREBUILT_DIR}/include + ) + # We don't need to explicitly link against pulseaudio itself, because + # the viewer probes for the system's copy at runtime. + set(PULSEAUDIO_LIBRARIES + # none needed! ) - # We don't need to explicitly link against pulseaudio itself, because - # the viewer probes for the system's copy at runtime. - set(PULSEAUDIO_LIBRARIES - # none needed! - ) -endif (STANDALONE) + endif (STANDALONE) +endif (PULSEAUDIO) if (PULSEAUDIO_FOUND) - set(PULSEAUDIO ON CACHE BOOL "Build with PulseAudio support, if available.") -endif (PULSEAUDIO_FOUND) - -if (PULSEAUDIO) add_definitions(-DLL_PULSEAUDIO_ENABLED=1) -endif (PULSEAUDIO) +endif (PULSEAUDIO_FOUND) diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index bfaf3f4f26..230e228c62 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -54,19 +54,20 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(LINUX ON BOOl FORCE) # If someone has specified a word size, use that to determine the - # architecture. Otherwise, let the architecture specify the word size. + # architecture. Otherwise, let the compiler specify the word size. + # Using uname will break under chroots and other cross arch compiles. RC if (WORD_SIZE EQUAL 32) set(ARCH i686) elseif (WORD_SIZE EQUAL 64) set(ARCH x86_64) else (WORD_SIZE EQUAL 32) - execute_process(COMMAND uname -m COMMAND sed s/i.86/i686/ - OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE) - if (ARCH STREQUAL x86_64) - set(WORD_SIZE 64) - else (ARCH STREQUAL x86_64) + if(CMAKE_SIZEOF_VOID_P MATCHES 4) + set(ARCH i686) set(WORD_SIZE 32) - endif (ARCH STREQUAL x86_64) + else(CMAKE_SIZEOF_VOID_P MATCHES 4) + set(ARCH x86_64) + set(WORD_SIZE 64) + endif(CMAKE_SIZEOF_VOID_P MATCHES 4) endif (WORD_SIZE EQUAL 32) set(LL_ARCH ${ARCH}_linux) diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py index 104585c195..e377aeef48 100644 --- a/indra/cmake/run_build_test.py +++ b/indra/cmake/run_build_test.py @@ -82,10 +82,24 @@ def main(command, libpath=[], vars={}): dirs = os.environ.get(var, "").split(os.pathsep) # Append the sequence in libpath print "%s += %r" % (var, libpath) - dirs.extend(libpath) + for dir in libpath: + # append system paths at the end + if dir in ('/lib', '/usr/lib'): + dirs.append(dir) + # prepend non-system paths + else: + dirs.insert(0, dir) + + # Filter out some useless pieces + clean_dirs = [] + for dir in dirs: + if dir and dir not in ('', '.'): + clean_dirs.append(dir) + # Now rebuild the path string. This way we use a minimum of separators # -- and we avoid adding a pointless separator when libpath is empty. - os.environ[var] = os.pathsep.join(dirs) + os.environ[var] = os.pathsep.join(clean_dirs) + print "%s = %r" % (var, os.environ[var]) # Now handle arbitrary environment variables. The tricky part is ensuring # that all the keys and values we try to pass are actually strings. if vars: diff --git a/indra/integration_tests/llui_libtest/llui_libtest.cpp b/indra/integration_tests/llui_libtest/llui_libtest.cpp index 713b82509e..1f15b73182 100644 --- a/indra/integration_tests/llui_libtest/llui_libtest.cpp +++ b/indra/integration_tests/llui_libtest/llui_libtest.cpp @@ -185,10 +185,9 @@ void export_test_floaters() // Build a floater and output new attributes LLXMLNodePtr output_node = new LLXMLNode(); LLFloater* floater = new LLFloater(LLSD()); - LLUICtrlFactory::getInstance()->buildFloater(floater, - filename, - // FALSE, // don't open floater - output_node); + floater->buildFromFile( filename, + // FALSE, // don't open floater + output_node); std::string out_filename = xui_dir + filename; std::string::size_type extension_pos = out_filename.rfind(".xml"); out_filename.resize(extension_pos); diff --git a/indra/integration_tests/llui_libtest/llwidgetreg.cpp b/indra/integration_tests/llui_libtest/llwidgetreg.cpp index b4921faece..0d0d9fbff6 100644 --- a/indra/integration_tests/llui_libtest/llwidgetreg.cpp +++ b/indra/integration_tests/llui_libtest/llwidgetreg.cpp @@ -78,7 +78,7 @@ void LLWidgetReg::initClass(bool register_widgets) LLDefaultChildRegistry::Register<LLMultiSlider> multi_slider_bar("multi_slider_bar"); LLDefaultChildRegistry::Register<LLMultiSliderCtrl> multi_slider("multi_slider"); LLDefaultChildRegistry::Register<LLPanel> panel("panel", &LLPanel::fromXML); - LLDefaultChildRegistry::Register<LLLayoutStack> layout_stack("layout_stack", &LLLayoutStack::fromXML); + LLDefaultChildRegistry::Register<LLLayoutStack> layout_stack("layout_stack"); LLDefaultChildRegistry::Register<LLProgressBar> progress_bar("progress_bar"); LLDefaultChildRegistry::Register<LLRadioGroup> radio_group("radio_group"); LLDefaultChildRegistry::Register<LLSearchEditor> search_editor("search_editor"); diff --git a/indra/lib/python/indra/util/named_query.py b/indra/lib/python/indra/util/named_query.py index 5c19368240..6bf956107d 100644 --- a/indra/lib/python/indra/util/named_query.py +++ b/indra/lib/python/indra/util/named_query.py @@ -36,14 +36,6 @@ import os.path import re import time -#import sys # *TODO: remove. only used in testing. -#import pprint # *TODO: remove. only used in testing. - -try: - set = set -except NameError: - from sets import Set as set - from indra.base import llsd from indra.base import config @@ -195,8 +187,6 @@ class NamedQuery(object): style. It also has to look for %:name% and :name% and ready them for use in LIKE statements""" if sql: - #print >>sys.stderr, "sql:",sql - # This first sub is to properly escape any % signs that # are meant to be literally passed through to mysql in the # query. It leaves any %'s that are used for @@ -408,7 +398,6 @@ class NamedQuery(object): # build the query from the options available and the params base_query = [] base_query.append(self._base_query) - #print >>sys.stderr, "base_query:",base_query for opt, extra_where in self._options.items(): if type(extra_where) in (dict, list, tuple): if opt in params: @@ -418,7 +407,6 @@ class NamedQuery(object): base_query.append(extra_where) if self._query_suffix: base_query.append(self._query_suffix) - #print >>sys.stderr, "base_query:",base_query full_query = '\n'.join(base_query) # Go through the query and rewrite all of the ones with the diff --git a/indra/lib/python/uuid.py b/indra/lib/python/uuid.py index 48dac84377..0bc21a35f8 100644 --- a/indra/lib/python/uuid.py +++ b/indra/lib/python/uuid.py @@ -446,8 +446,14 @@ def uuid1(node=None, clock_seq=None): def uuid3(namespace, name): """Generate a UUID from the MD5 hash of a namespace UUID and a name.""" - import md5 - hash = md5.md5(namespace.bytes + name).digest() + try: + # Python 2.6 + from hashlib import md5 + except ImportError: + # Python 2.5 and earlier + from md5 import new as md5 + + hash = md5(namespace.bytes + name).digest() return UUID(bytes=hash[:16], version=3) def uuid4(): diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index 8843acc891..1cc03bddb8 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -97,6 +97,7 @@ void LLAudioEngine::setDefaults() } mMasterGain = 1.f; + mInternalGain = 0.f; mNextWindUpdate = 0.f; mStreamingAudioImpl = NULL; @@ -247,15 +248,6 @@ void LLAudioEngine::idle(F32 max_decode_time) // Primarily does position updating, cleanup of unused audio sources. // Also does regeneration of the current priority of each audio source. - if (getMuted()) - { - setInternalGain(0.f); - } - else - { - setInternalGain(getMasterGain()); - } - S32 i; for (i = 0; i < MAX_BUFFERS; i++) { @@ -284,6 +276,12 @@ void LLAudioEngine::idle(F32 max_decode_time) continue; } + if (sourcep->isMuted()) + { + ++iter; + continue; + } + if (!sourcep->getChannel() && sourcep->getCurrentBuffer()) { // We could potentially play this sound if its priority is high enough. @@ -336,9 +334,9 @@ void LLAudioEngine::idle(F32 max_decode_time) // attached to each channel, since only those with active channels // can have anything interesting happen with their queue? (Maybe not true) LLAudioSource *sourcep = iter->second; - if (!sourcep->mQueuedDatap) + if (!sourcep->mQueuedDatap || sourcep->isMuted()) { - // Nothing queued, so we don't care. + // Muted, or nothing queued, so we don't care. continue; } @@ -418,6 +416,10 @@ void LLAudioEngine::idle(F32 max_decode_time) for (iter = mAllSources.begin(); iter != mAllSources.end(); ++iter) { LLAudioSource *sourcep = iter->second; + if (sourcep->isMuted()) + { + continue; + } if (sourcep->isSyncMaster()) { if (sourcep->getPriority() > max_sm_priority) @@ -691,15 +693,23 @@ bool LLAudioEngine::isWindEnabled() void LLAudioEngine::setMuted(bool muted) { - mMuted = muted; + if (muted != mMuted) + { + mMuted = muted; + setMasterGain(mMasterGain); + } enableWind(!mMuted); } - void LLAudioEngine::setMasterGain(const F32 gain) { mMasterGain = gain; - setInternalGain(gain); + F32 internal_gain = getMuted() ? 0.f : gain; + if (internal_gain != mInternalGain) + { + mInternalGain = internal_gain; + setInternalGain(mInternalGain); + } } F32 LLAudioEngine::getMasterGain() @@ -1243,13 +1253,14 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 mOwnerID(owner_id), mPriority(0.f), mGain(gain), - mType(type), + mSourceMuted(false), mAmbient(false), mLoop(false), mSyncMaster(false), mSyncSlave(false), mQueueSounds(false), mPlayedOnce(false), + mType(type), mChannelp(NULL), mCurrentDatap(NULL), mQueuedDatap(NULL) @@ -1301,6 +1312,10 @@ void LLAudioSource::updatePriority() { mPriority = 1.f; } + else if (isMuted()) + { + mPriority = 0.f; + } else { // Priority is based on distance @@ -1349,25 +1364,33 @@ bool LLAudioSource::setupChannel() bool LLAudioSource::play(const LLUUID &audio_uuid) { + // Special abuse of play(); don't play a sound, but kill it. if (audio_uuid.isNull()) { if (getChannel()) { getChannel()->setSource(NULL); setChannel(NULL); - addAudioData(NULL, true); + if (!isMuted()) + { + mCurrentDatap = NULL; + } } + return false; } + // Reset our age timeout if someone attempts to play the source. mAgeTimer.reset(); LLAudioData *adp = gAudiop->getAudioData(audio_uuid); - - bool has_buffer = gAudiop->updateBufferForData(adp, audio_uuid); - - addAudioData(adp); + if (isMuted()) + { + return false; + } + + bool has_buffer = gAudiop->updateBufferForData(adp, audio_uuid); if (!has_buffer) { // Don't bother trying to set up a channel or anything, we don't have an audio buffer. @@ -1392,10 +1415,11 @@ bool LLAudioSource::play(const LLUUID &audio_uuid) } -bool LLAudioSource::isDone() +bool LLAudioSource::isDone() const { const F32 MAX_AGE = 60.f; const F32 MAX_UNPLAYED_AGE = 15.f; + const F32 MAX_MUTED_AGE = 11.f; if (isLoop()) { @@ -1403,7 +1427,6 @@ bool LLAudioSource::isDone() return false; } - if (hasPendingPreloads()) { return false; @@ -1420,10 +1443,10 @@ bool LLAudioSource::isDone() // This is a single-play source if (!mChannelp) { - if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce) + if ((elapsed > (mSourceMuted ? MAX_MUTED_AGE : MAX_UNPLAYED_AGE)) || mPlayedOnce) { // We don't have a channel assigned, and it's been - // over 5 seconds since we tried to play it. Don't bother. + // over 15 seconds since we tried to play it. Don't bother. //llinfos << "No channel assigned, source is done" << llendl; return true; } @@ -1449,7 +1472,7 @@ bool LLAudioSource::isDone() if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce) { - // The sound isn't playing back after 5 seconds or we're already done playing it, kill it. + // The sound isn't playing back after 15 seconds or we're already done playing it, kill it. return true; } diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index 6a5000d7ed..30d2490635 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -118,8 +118,8 @@ public: // Use these for temporarily muting the audio system. // Does not change buffers, initialization, etc. but // stops playing new sounds. - virtual void setMuted(bool muted); - virtual bool getMuted() const { return mMuted; } + void setMuted(bool muted); + bool getMuted() const { return mMuted; } #ifdef USE_PLUGIN_MEDIA LLPluginClassMedia* initializeMedia(const std::string& media_type); #endif @@ -239,6 +239,7 @@ protected: LLAudioBuffer *mBuffers[MAX_BUFFERS]; F32 mMasterGain; + F32 mInternalGain; // Actual gain set; either mMasterGain or 0 when mMuted is true. F32 mSecondaryGain[AUDIO_TYPE_COUNT]; F32 mNextWindUpdate; @@ -303,7 +304,8 @@ public: virtual void setGain(const F32 gain) { mGain = llclamp(gain, 0.f, 1.f); } const LLUUID &getID() const { return mID; } - bool isDone(); + bool isDone() const; + bool isMuted() const { return mSourceMuted; } LLAudioData *getCurrentData(); LLAudioData *getQueuedData(); @@ -325,6 +327,7 @@ protected: LLUUID mOwnerID; // owner of the object playing the sound F32 mPriority; F32 mGain; + bool mSourceMuted; bool mAmbient; bool mLoop; bool mSyncMaster; diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 2a036df06e..858e483036 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -157,6 +157,7 @@ set(llcommon_HEADER_FILES lleventemitter.h llextendedstatus.h llfasttimer.h + llfasttimer_class.h llfile.h llfindlocale.h llfixedbuffer.h diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer_class.cpp index bc1ae37c2b..c45921cdec 100644 --- a/indra/llcommon/llfasttimer_class.cpp +++ b/indra/llcommon/llfasttimer_class.cpp @@ -469,9 +469,9 @@ void LLFastTimer::NamedTimer::accumulateTimings() int hidx = cur_frame % HISTORY_NUM; timerp->mCountHistory[hidx] = timerp->mTotalTimeCounter; - timerp->mCountAverage = (timerp->mCountAverage * cur_frame + timerp->mTotalTimeCounter) / (cur_frame+1); + timerp->mCountAverage = ((U64)timerp->mCountAverage * cur_frame + timerp->mTotalTimeCounter) / (cur_frame+1); timerp->mCallHistory[hidx] = timerp->getFrameState().mCalls; - timerp->mCallAverage = (timerp->mCallAverage * cur_frame + timerp->getFrameState().mCalls) / (cur_frame+1); + timerp->mCallAverage = ((U64)timerp->mCallAverage * cur_frame + timerp->getFrameState().mCalls) / (cur_frame+1); } } } diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 69e3ff266a..10f460e8a6 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -71,7 +71,7 @@ void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize break; default: - llwarns << "serialize request for unkown ELLSD_Serialize" << llendl; + llwarns << "serialize request for unknown ELLSD_Serialize" << llendl; } if (f.notNull()) diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 33b55d843c..ae7e624a1a 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -1112,7 +1112,7 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token, else if(LLStringOps::sMonthList.size() == 12 && code == "%B") { struct tm * gmt = gmtime (&loc_seconds); - replacement = LLStringOps::sWeekDayList[gmt->tm_mon]; + replacement = LLStringOps::sMonthList[gmt->tm_mon]; } else if( !LLStringOps::sDayFormat.empty() && code == "%d" ) { diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 88fecb57bf..7e41e787b5 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -435,7 +435,7 @@ LL_COMMON_API bool iswindividual(llwchar elem); */ // Make the incoming string a utf8 string. Replaces any unknown glyph -// with the UNKOWN_CHARACTER. Once any unknown glph is found, the rest +// with the UNKNOWN_CHARACTER. Once any unknown glyph is found, the rest // of the data may not be recovered. LL_COMMON_API std::string rawstr_to_utf8(const std::string& raw); diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 92d9e1204a..bd65ce8573 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -28,8 +28,8 @@ #define LL_LLVERSIONVIEWER_H const S32 LL_VERSION_MAJOR = 2; -const S32 LL_VERSION_MINOR = 1; -const S32 LL_VERSION_PATCH = 2; +const S32 LL_VERSION_MINOR = 2; +const S32 LL_VERSION_PATCH = 1; const S32 LL_VERSION_BUILD = 0; const char * const LL_CHANNEL = "Second Life Developer"; diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h index 5931ba67c2..9f86de124e 100644 --- a/indra/llcommon/stdenums.h +++ b/indra/llcommon/stdenums.h @@ -113,8 +113,8 @@ enum EObjectPropertiesExtraID enum EAddPosition { ADD_TOP, - ADD_SORTED, - ADD_BOTTOM + ADD_BOTTOM, + ADD_DEFAULT }; enum LLGroupChange diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp index 02043586b2..fe737e2072 100644 --- a/indra/llimage/llpngwrapper.cpp +++ b/indra/llimage/llpngwrapper.cpp @@ -210,7 +210,7 @@ void LLPngWrapper::normalizeImage() } if (mColorType == PNG_COLOR_TYPE_GRAY && mBitDepth < 8) { - png_set_gray_1_2_4_to_8(mReadPngPtr); + png_set_expand_gray_1_2_4_to_8(mReadPngPtr); } if (mColorType == PNG_COLOR_TYPE_GRAY || mColorType == PNG_COLOR_TYPE_GRAY_ALPHA) @@ -358,7 +358,7 @@ void LLPngWrapper::releaseResources() { if (mReadPngPtr || mReadInfoPtr) { - png_destroy_read_struct(&mReadPngPtr, &mReadInfoPtr, png_infopp_NULL); + png_destroy_read_struct(&mReadPngPtr, &mReadInfoPtr, NULL); mReadPngPtr = NULL; mReadInfoPtr = NULL; } diff --git a/indra/llimage/llpngwrapper.h b/indra/llimage/llpngwrapper.h index 0721adea3b..47a4207d66 100644 --- a/indra/llimage/llpngwrapper.h +++ b/indra/llimage/llpngwrapper.h @@ -26,7 +26,7 @@ #ifndef LL_LLPNGWRAPPER_H #define LL_LLPNGWRAPPER_H -#include "libpng12/png.h" +#include "png.h" #include "llimage.h" class LLPngWrapper diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 9ce9ee2101..69ed0fb09c 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -74,6 +74,7 @@ bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::s // Queue up the media init message -- it will be sent after all the currently queued messages. LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "init"); + message.setValue("target", mTarget); sendMessage(message); mPlugin->init(launcher_filename, plugin_filename, debug); @@ -143,7 +144,7 @@ void LLPluginClassMedia::reset() mProgressPercent = 0; mClickURL.clear(); mClickTarget.clear(); - mClickTargetType = TARGET_NONE; + mClickUUID.clear(); // media_time class mCurrentTime = 0.0f; @@ -669,6 +670,18 @@ F64 LLPluginClassMedia::getCPUUsage() return result; } +void LLPluginClassMedia::sendPickFileResponse(const std::string &file) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file_response"); + message.setValue("file", file); + if(mPlugin->isBlocked()) + { + // If the plugin sent a blocking pick-file request, the response should unblock it. + message.setValueBoolean("blocking_response", true); + } + sendMessage(message); +} + void LLPluginClassMedia::cut() { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_cut"); @@ -715,24 +728,9 @@ void LLPluginClassMedia::setJavascriptEnabled(const bool enabled) sendMessage(message); } -LLPluginClassMedia::ETargetType getTargetTypeFromLLQtWebkit(int target_type) +void LLPluginClassMedia::setTarget(const std::string &target) { - // convert a LinkTargetType value from llqtwebkit to an ETargetType - // so that we don't expose the llqtwebkit header in viewer code - switch (target_type) - { - case LLQtWebKit::LTT_TARGET_NONE: - return LLPluginClassMedia::TARGET_NONE; - - case LLQtWebKit::LTT_TARGET_BLANK: - return LLPluginClassMedia::TARGET_BLANK; - - case LLQtWebKit::LTT_TARGET_EXTERNAL: - return LLPluginClassMedia::TARGET_EXTERNAL; - - default: - return LLPluginClassMedia::TARGET_OTHER; - } + mTarget = target; } /* virtual */ @@ -945,6 +943,10 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) mMediaName = message.getValue("name"); mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAME_CHANGED); } + else if(message_name == "pick_file") + { + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PICK_FILE_REQUEST); + } else { LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL; @@ -987,15 +989,13 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) { mClickURL = message.getValue("uri"); mClickTarget = message.getValue("target"); - U32 target_type = message.getValueU32("target_type"); - mClickTargetType = ::getTargetTypeFromLLQtWebkit(target_type); + mClickUUID = message.getValue("uuid"); mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF); } else if(message_name == "click_nofollow") { mClickURL = message.getValue("uri"); mClickTarget.clear(); - mClickTargetType = TARGET_NONE; mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_NOFOLLOW); } else if(message_name == "cookie_set") @@ -1005,6 +1005,20 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) mOwner->handleCookieSet(this, message.getValue("cookie")); } } + else if(message_name == "close_request") + { + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLOSE_REQUEST); + } + else if(message_name == "geometry_change") + { + mClickUUID = message.getValue("uuid"); + mGeometryX = message.getValueS32("x"); + mGeometryY = message.getValueS32("y"); + mGeometryWidth = message.getValueS32("width"); + mGeometryHeight = message.getValueS32("height"); + + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_GEOMETRY_CHANGE); + } else { LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL; @@ -1159,6 +1173,25 @@ void LLPluginClassMedia::setBrowserUserAgent(const std::string& user_agent) sendMessage(message); } +void LLPluginClassMedia::proxyWindowOpened(const std::string &target, const std::string &uuid) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_window_opened"); + + message.setValue("target", target); + message.setValue("uuid", uuid); + + sendMessage(message); +} + +void LLPluginClassMedia::proxyWindowClosed(const std::string &uuid) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_window_closed"); + + message.setValue("uuid", uuid); + + sendMessage(message); +} + void LLPluginClassMedia::crashPlugin() { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "crash"); diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index ee53f3a4da..9cb67fe909 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -156,6 +156,8 @@ public: void setLowPrioritySizeLimit(int size); F64 getCPUUsage(); + + void sendPickFileResponse(const std::string &file); // Valid after a MEDIA_EVENT_CURSOR_CHANGED event std::string getCursorName() const { return mCursorName; }; @@ -176,7 +178,8 @@ public: void setLanguageCode(const std::string &language_code); void setPluginsEnabled(const bool enabled); void setJavascriptEnabled(const bool enabled); - + void setTarget(const std::string &target); + /////////////////////////////////// // media browser class functions bool pluginSupportsMediaBrowser(void); @@ -193,6 +196,8 @@ public: void browse_back(); void set_status_redirect(int code, const std::string &url); void setBrowserUserAgent(const std::string& user_agent); + void proxyWindowOpened(const std::string &target, const std::string &uuid); + void proxyWindowClosed(const std::string &uuid); // This is valid after MEDIA_EVENT_NAVIGATE_BEGIN or MEDIA_EVENT_NAVIGATE_COMPLETE std::string getNavigateURI() const { return mNavigateURI; }; @@ -218,16 +223,14 @@ public: // This is valid after MEDIA_EVENT_CLICK_LINK_HREF std::string getClickTarget() const { return mClickTarget; }; - typedef enum - { - TARGET_NONE, // empty href target string - TARGET_BLANK, // target to open link in user's preferred browser - TARGET_EXTERNAL, // target to open link in external browser - TARGET_OTHER // nonempty and unsupported target type - }ETargetType; - - // This is valid after MEDIA_EVENT_CLICK_LINK_HREF - ETargetType getClickTargetType() const { return mClickTargetType; }; + // This is valid during MEDIA_EVENT_CLICK_LINK_HREF and MEDIA_EVENT_GEOMETRY_CHANGE + std::string getClickUUID() const { return mClickUUID; }; + + // These are valid during MEDIA_EVENT_GEOMETRY_CHANGE + S32 getGeometryX() const { return mGeometryX; }; + S32 getGeometryY() const { return mGeometryY; }; + S32 getGeometryWidth() const { return mGeometryWidth; }; + S32 getGeometryHeight() const { return mGeometryHeight; }; std::string getMediaName() const { return mMediaName; }; std::string getMediaDescription() const { return mMediaDescription; }; @@ -347,6 +350,8 @@ protected: LLColor4 mBackgroundColor; + std::string mTarget; + ///////////////////////////////////////// // media_browser class std::string mNavigateURI; @@ -359,7 +364,11 @@ protected: std::string mLocation; std::string mClickURL; std::string mClickTarget; - ETargetType mClickTargetType; + std::string mClickUUID; + S32 mGeometryX; + S32 mGeometryY; + S32 mGeometryWidth; + S32 mGeometryHeight; ///////////////////////////////////////// // media_time class diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h index b48a5ca4ac..c9efff216c 100644 --- a/indra/llplugin/llpluginclassmediaowner.h +++ b/indra/llplugin/llpluginclassmediaowner.h @@ -54,6 +54,9 @@ public: MEDIA_EVENT_LOCATION_CHANGED, // browser location (URL) has changed (maybe due to internal navagation/frames/etc) MEDIA_EVENT_CLICK_LINK_HREF, // I'm not entirely sure what the semantics of these two are MEDIA_EVENT_CLICK_LINK_NOFOLLOW, + MEDIA_EVENT_CLOSE_REQUEST, // The plugin requested its window be closed (currently hooked up to javascript window.close in webkit) + MEDIA_EVENT_PICK_FILE_REQUEST, // The plugin wants the user to pick a file + MEDIA_EVENT_GEOMETRY_CHANGE, // The plugin requested its window geometry be changed (per the javascript window interface) MEDIA_EVENT_PLUGIN_FAILED_LAUNCH, // The plugin failed to launch MEDIA_EVENT_PLUGIN_FAILED // The plugin died unexpectedly diff --git a/indra/llplugin/slplugin/slplugin.cpp b/indra/llplugin/slplugin/slplugin.cpp index 7d69e1c5cd..516a58db88 100644 --- a/indra/llplugin/slplugin/slplugin.cpp +++ b/indra/llplugin/slplugin/slplugin.cpp @@ -281,7 +281,7 @@ int main(int argc, char **argv) } // Check for a change in this process's frontmost window. - if(FrontWindow() != front_window) + if(GetFrontWindowOfClass(kAllWindowClasses, true) != front_window) { ProcessSerialNumber self = { 0, kCurrentProcess }; ProcessSerialNumber parent = { 0, kNoProcess }; @@ -307,7 +307,7 @@ int main(int argc, char **argv) } } - if((FrontWindow() != NULL) && (front_window == NULL)) + if((GetFrontWindowOfClass(kAllWindowClasses, true) != NULL) && (front_window == NULL)) { // Opening the first window @@ -319,7 +319,7 @@ int main(int argc, char **argv) if(layer_group) { - SetWindowGroup(FrontWindow(), layer_group); + SetWindowGroup(GetFrontWindowOfClass(kAllWindowClasses, true), layer_group); } if(parent_is_front_process) @@ -328,9 +328,9 @@ int main(int argc, char **argv) (void) SetFrontProcess( &self ); } - ActivateWindow(FrontWindow(), true); + ActivateWindow(GetFrontWindowOfClass(kAllWindowClasses, true), true); } - else if((FrontWindow() == NULL) && (front_window != NULL)) + else if((GetFrontWindowOfClass(kAllWindowClasses, true) == NULL) && (front_window != NULL)) { // Closing the last window @@ -350,7 +350,7 @@ int main(int argc, char **argv) window_hack_state = 2; } - front_window = FrontWindow(); + front_window = GetFrontWindowOfClass(kAllWindowClasses, true); } } diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 386bb987f9..13008292f6 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -977,37 +977,43 @@ LLFontGL::VAlign LLFontGL::vAlignFromName(const std::string& name) //static LLFontGL* LLFontGL::getFontMonospace() { - return getFont(LLFontDescriptor("Monospace","Monospace",0)); + static LLFontGL* fontp = getFont(LLFontDescriptor("Monospace","Monospace",0)); + return fontp; } //static LLFontGL* LLFontGL::getFontSansSerifSmall() { - return getFont(LLFontDescriptor("SansSerif","Small",0)); + static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Small",0)); + return fontp; } //static LLFontGL* LLFontGL::getFontSansSerif() { - return getFont(LLFontDescriptor("SansSerif","Medium",0)); + static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Medium",0)); + return fontp; } //static LLFontGL* LLFontGL::getFontSansSerifBig() { - return getFont(LLFontDescriptor("SansSerif","Large",0)); + static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Large",0)); + return fontp; } //static LLFontGL* LLFontGL::getFontSansSerifHuge() { - return getFont(LLFontDescriptor("SansSerif","Huge",0)); + static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Large",0)); + return fontp; } //static LLFontGL* LLFontGL::getFontSansSerifBold() { - return getFont(LLFontDescriptor("SansSerif","Medium",BOLD)); + static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Medium",BOLD)); + return fontp; } //static diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 8e78a5fefd..e98201ea63 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -158,6 +158,7 @@ set(llui_HEADER_FILES llnotifications.h llnotificationslistener.h llnotificationsutil.h + llnotificationtemplate.h llpanel.h llprogressbar.h llradiogroup.h diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index f9ffaaa646..d636161baf 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -83,7 +83,7 @@ LLAccordionCtrl::LLAccordionCtrl() : LLPanel() mSingleExpansion = false; mFitParent = false; - LLUICtrlFactory::getInstance()->buildPanel(this, "accordion_parent.xml"); + buildFromFile( "accordion_parent.xml"); } //--------------------------------------------------------------------------------- diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index b7da5f4a1b..e28ef1f25d 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -141,6 +141,7 @@ LLAccordionCtrlTab::LLAccordionCtrlTabHeader::LLAccordionCtrlTabHeader( textboxParams.use_ellipses = true; textboxParams.bg_visible = false; textboxParams.mouse_opaque = false; + textboxParams.parse_urls = false; mHeaderTextbox = LLUICtrlFactory::create<LLTextBox>(textboxParams); addChild(mHeaderTextbox); } diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index d6ac8cbc8f..dddaa581e6 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -85,10 +85,10 @@ public: Optional<bool> selection_enabled; - Optional<S32> padding_left; - Optional<S32> padding_right; - Optional<S32> padding_top; - Optional<S32> padding_bottom; + Optional<S32> padding_left, + padding_right, + padding_top, + padding_bottom; Params(); }; @@ -170,7 +170,7 @@ public: virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); - virtual bool addChild(LLView* child, S32 tab_group); + virtual bool addChild(LLView* child, S32 tab_group = 0 ); bool isExpanded() const { return mDisplayChildren; } diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index f0f34ebd4f..65ef3e5f8f 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -114,7 +114,6 @@ LLButton::LLButton(const LLButton::Params& p) mFlashing( FALSE ), mCurGlowStrength(0.f), mNeedsHighlight(FALSE), - mMouseOver(false), mUnselectedLabel(p.label()), mSelectedLabel(p.label_selected()), mGLFont(p.font), @@ -499,11 +498,7 @@ void LLButton::onMouseEnter(S32 x, S32 y, MASK mask) LLUICtrl::onMouseEnter(x, y, mask); if (isInEnabledChain()) - { mNeedsHighlight = TRUE; - } - - mMouseOver = true; } void LLButton::onMouseLeave(S32 x, S32 y, MASK mask) @@ -511,7 +506,6 @@ void LLButton::onMouseLeave(S32 x, S32 y, MASK mask) LLUICtrl::onMouseLeave(x, y, mask); mNeedsHighlight = FALSE; - mMouseOver = true; } void LLButton::setHighlight(bool b) @@ -564,11 +558,19 @@ void LLButton::draw() pressed_by_keyboard = gKeyboard->getKeyDown(' ') || (mCommitOnReturn && gKeyboard->getKeyDown(KEY_RETURN)); } - // Unselected image assignments + bool mouse_pressed_and_over = false; + if (hasMouseCapture()) + { + S32 local_mouse_x ; + S32 local_mouse_y; + LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y); + mouse_pressed_and_over = pointInView(local_mouse_x, local_mouse_y); + } + bool enabled = isInEnabledChain(); bool pressed = pressed_by_keyboard - || (hasMouseCapture() && mMouseOver) + || mouse_pressed_and_over || mForcePressedState; bool selected = getToggleState(); @@ -1117,7 +1119,7 @@ void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname) // Get the visibility control name for the floater std::string vis_control_name = LLFloaterReg::declareVisibilityControl(sdname.asString()); // Set the button control value (toggle state) to the floater visibility control (Sets the value as well) - button->setControlVariable(LLUI::sSettingGroups["floater"]->getControl(vis_control_name)); + button->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name)); // Set the clicked callback to toggle the floater button->setClickedCallback(boost::bind(&LLFloaterReg::toggleFloaterInstance, sdname)); } @@ -1131,7 +1133,7 @@ void LLButton::setDockableFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname) // Get the visibility control name for the floater std::string vis_control_name = LLFloaterReg::declareVisibilityControl(sdname.asString()); // Set the button control value (toggle state) to the floater visibility control (Sets the value as well) - button->setControlVariable(LLUI::sSettingGroups["floater"]->getControl(vis_control_name)); + button->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name)); // Set the clicked callback to toggle the floater button->setClickedCallback(boost::bind(&LLDockableFloater::toggleInstance, sdname)); } diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index d87ceb7c42..2d5fefa78c 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -350,7 +350,6 @@ private: BOOL mCommitOnReturn; BOOL mFadeWhenDisabled; bool mForcePressedState; - bool mMouseOver; LLFrameTimer mFlashingTimer; }; diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index cbc8f12472..bbd8db2645 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -50,9 +50,7 @@ template class LLCheckBoxCtrl* LLView::getChild<class LLCheckBoxCtrl>( const std::string& name, BOOL recurse) const; LLCheckBoxCtrl::Params::Params() -: text_enabled_color("text_enabled_color"), - text_disabled_color("text_disabled_color"), - initial_value("initial_value", false), +: initial_value("initial_value", false), label_text("label_text"), check_button("check_button"), radio_style("radio_style") @@ -61,8 +59,8 @@ LLCheckBoxCtrl::Params::Params() LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p) : LLUICtrl(p), - mTextEnabledColor(p.text_enabled_color()), - mTextDisabledColor(p.text_disabled_color()), + mTextEnabledColor(p.label_text.text_color()), + mTextDisabledColor(p.label_text.text_readonly_color()), mFont(p.font()) { mViewModel->setValue(LLSD(p.initial_value)); @@ -89,7 +87,6 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p) { tbparams.font(p.font); } - tbparams.text_color( p.enabled() ? p.text_enabled_color() : p.text_disabled_color() ); mLabel = LLUICtrlFactory::create<LLTextBox> (tbparams); addChild(mLabel); diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h index 0147088280..67d8091a97 100644 --- a/indra/llui/llcheckboxctrl.h +++ b/indra/llui/llcheckboxctrl.h @@ -52,8 +52,6 @@ public: struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> { - Optional<LLUIColor> text_enabled_color; - Optional<LLUIColor> text_disabled_color; Optional<bool> initial_value; // override LLUICtrl initial_value Optional<LLTextBox::Params> label_text; diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 910bab9a97..edd2cd340b 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -139,8 +139,8 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p) // Grab the mouse-up event and make sure the button state is correct mList->setMouseUpCallback(boost::bind(&LLComboBox::onListMouseUp, this)); - for (LLInitParam::ParamIterator<ItemParams>::const_iterator it = p.items().begin(); - it != p.items().end(); + for (LLInitParam::ParamIterator<ItemParams>::const_iterator it = p.items.begin(); + it != p.items.end(); ++it) { LLScrollListItem::Params item_params = *it; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 8d24150e1e..cae59754cb 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -36,6 +36,7 @@ #include "lluictrlfactory.h" #include "llbutton.h" #include "llcheckboxctrl.h" +#include "lldir.h" #include "lldraghandle.h" #include "llfloaterreg.h" #include "llfocusmgr.h" @@ -499,7 +500,7 @@ void LLFloater::storeRectControl() { if( mRectControl.size() > 1 ) { - LLUI::sSettingGroups["floater"]->setRect( mRectControl, getRect() ); + getControlGroup()->setRect( mRectControl, getRect() ); } } @@ -507,7 +508,7 @@ void LLFloater::storeVisibilityControl() { if( !sQuitting && mVisibilityControl.size() > 1 ) { - LLUI::sSettingGroups["floater"]->setBOOL( mVisibilityControl, getVisible() ); + getControlGroup()->setBOOL( mVisibilityControl, getVisible() ); } } @@ -515,7 +516,7 @@ void LLFloater::storeDockStateControl() { if( !sQuitting && mDocStateControl.size() > 1 ) { - LLUI::sSettingGroups["floater"]->setBOOL( mDocStateControl, isDocked() ); + getControlGroup()->setBOOL( mDocStateControl, isDocked() ); } } @@ -525,7 +526,7 @@ LLRect LLFloater::getSavedRect() const if (mRectControl.size() > 1) { - rect = LLUI::sSettingGroups["floater"]->getRect(mRectControl); + rect = getControlGroup()->getRect(mRectControl); } return rect; @@ -550,6 +551,13 @@ std::string LLFloater::getControlName(const std::string& name, const LLSD& key) return ctrl_name; } +// static +LLControlGroup* LLFloater::getControlGroup() +{ + // Floater size, position, visibility, etc are saved in per-account settings. + return LLUI::sSettingGroups["account"]; +} + void LLFloater::setVisible( BOOL visible ) { LLPanel::setVisible(visible); // calls handleVisibilityChange() @@ -805,7 +813,7 @@ void LLFloater::applyRectControl() // override center if we have saved rect control if (mRectControl.size() > 1) { - const LLRect& rect = LLUI::sSettingGroups["floater"]->getRect(mRectControl); + const LLRect& rect = getControlGroup()->getRect(mRectControl); if (rect.getWidth() > 0 && rect.getHeight() > 0) { translate( rect.mLeft - getRect().mLeft, rect.mBottom - getRect().mBottom); @@ -821,7 +829,7 @@ void LLFloater::applyDockState() { if (mDocStateControl.size() > 1) { - bool dockState = LLUI::sSettingGroups["floater"]->getBOOL(mDocStateControl); + bool dockState = getControlGroup()->getBOOL(mDocStateControl); setDocked(dockState); } @@ -2383,7 +2391,9 @@ void LLFloaterView::closeAllChildren(bool app_quitting) // Attempt to close floater. This will cause the "do you want to save" // dialogs to appear. - if (floaterp->canClose() && !floaterp->isDead()) + // Skip invisible floaters if we're not quitting (STORM-192). + if (floaterp->canClose() && !floaterp->isDead() && + (app_quitting || floaterp->getVisible())) { floaterp->closeFloater(app_quitting); } @@ -2806,7 +2816,8 @@ LLFastTimer::DeclareTimer POST_BUILD("Floater Post Build"); bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node) { Params params(LLUICtrlFactory::getDefaultParams<LLFloater>()); - LLXUIParser::instance().readXUI(node, params, filename); // *TODO: Error checking + LLXUIParser parser; + parser.readXUI(node, params, filename); // *TODO: Error checking if (output_node) { @@ -2814,8 +2825,7 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str setupParamsForExport(output_params, parent); Params default_params(LLUICtrlFactory::getDefaultParams<LLFloater>()); output_node->setName(node->getName()->mString); - LLXUIParser::instance().writeXUI( - output_node, output_params, &default_params); + parser.writeXUI(output_node, output_params, &default_params); } // Default floater position to top-left corner of screen @@ -2910,3 +2920,64 @@ bool LLFloater::isVisible(const LLFloater* floater) { return floater && floater->getVisible(); } + +static LLFastTimer::DeclareTimer FTM_BUILD_FLOATERS("Build Floaters"); + +bool LLFloater::buildFromFile(const std::string& filename, LLXMLNodePtr output_node) +{ + LLFastTimer timer(FTM_BUILD_FLOATERS); + LLXMLNodePtr root; + + //if exporting, only load the language being exported, + //instead of layering localized version on top of english + if (output_node) + { + if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root)) + { + llwarns << "Couldn't parse floater from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; + return false; + } + } + else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) + { + llwarns << "Couldn't parse floater from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; + return false; + } + + // root must be called floater + if( !(root->hasName("floater") || root->hasName("multi_floater")) ) + { + llwarns << "Root node should be named floater in: " << filename << llendl; + return false; + } + + bool res = true; + + lldebugs << "Building floater " << filename << llendl; + LLUICtrlFactory::instance().pushFileName(filename); + { + if (!getFactoryMap().empty()) + { + LLPanel::sFactoryStack.push_front(&getFactoryMap()); + } + + // for local registry callbacks; define in constructor, referenced in XUI or postBuild + getCommitCallbackRegistrar().pushScope(); + getEnableCallbackRegistrar().pushScope(); + + res = initFloaterXML(root, getParent(), filename, output_node); + + setXMLFilename(filename); + + getCommitCallbackRegistrar().popScope(); + getEnableCallbackRegistrar().popScope(); + + if (!getFactoryMap().empty()) + { + LLPanel::sFactoryStack.pop_front(); + } + } + LLUICtrlFactory::instance().popFileName(); + + return res; +} diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index ed1f0715af..c02587d9d8 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -141,6 +141,7 @@ public: // Don't export top/left for rect, only height/width static void setupParamsForExport(Params& p, LLView* parent); + bool buildFromFile(const std::string &filename, LLXMLNodePtr output_node = NULL); void initFromParams(const LLFloater::Params& p); bool initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node = NULL); @@ -206,7 +207,8 @@ public: LLRect getSavedRect() const; bool hasSavedRect() const; - static std::string getControlName(const std::string& name, const LLSD& key); + static std::string getControlName(const std::string& name, const LLSD& key); + static LLControlGroup* getControlGroup(); bool isMinimizeable() const{ return mCanMinimize; } bool isCloseable() const{ return mCanClose; } diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index ccffe98c96..4677d535db 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -121,7 +121,7 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key) res = build_func(key); - bool success = LLUICtrlFactory::getInstance()->buildFloater(res, xui_file, NULL); + bool success = res->buildFromFile(xui_file, NULL); if (!success) { llwarns << "Failed to build floater type: '" << name << "'." << llendl; @@ -284,9 +284,9 @@ void LLFloaterReg::showInitialVisibleInstances() { const std::string& name = iter->first; std::string controlname = getVisibilityControlName(name); - if (LLUI::sSettingGroups["floater"]->controlExists(controlname)) + if (LLFloater::getControlGroup()->controlExists(controlname)) { - BOOL isvis = LLUI::sSettingGroups["floater"]->getBOOL(controlname); + BOOL isvis = LLFloater::getControlGroup()->getBOOL(controlname); if (isvis) { showInstance(name, LLSD()); // keyed floaters shouldn't set save_vis to true @@ -340,7 +340,7 @@ std::string LLFloaterReg::getRectControlName(const std::string& name) std::string LLFloaterReg::declareRectControl(const std::string& name) { std::string controlname = getRectControlName(name); - LLUI::sSettingGroups["floater"]->declareRect(controlname, LLRect(), + LLFloater::getControlGroup()->declareRect(controlname, LLRect(), llformat("Window Position and Size for %s", name.c_str()), TRUE); return controlname; @@ -358,7 +358,7 @@ std::string LLFloaterReg::getVisibilityControlName(const std::string& name) std::string LLFloaterReg::declareVisibilityControl(const std::string& name) { std::string controlname = getVisibilityControlName(name); - LLUI::sSettingGroups["floater"]->declareBOOL(controlname, FALSE, + LLFloater::getControlGroup()->declareBOOL(controlname, FALSE, llformat("Window Visibility for %s", name.c_str()), TRUE); return controlname; @@ -368,7 +368,7 @@ std::string LLFloaterReg::declareVisibilityControl(const std::string& name) std::string LLFloaterReg::declareDockStateControl(const std::string& name) { std::string controlname = getDockStateControlName(name); - LLUI::sSettingGroups["floater"]->declareBOOL(controlname, TRUE, + LLFloater::getControlGroup()->declareBOOL(controlname, TRUE, llformat("Window Docking state for %s", name.c_str()), TRUE); return controlname; @@ -391,11 +391,11 @@ void LLFloaterReg::registerControlVariables() for (build_map_t::iterator iter = sBuildMap.begin(); iter != sBuildMap.end(); ++iter) { const std::string& name = iter->first; - if (LLUI::sSettingGroups["floater"]->controlExists(getRectControlName(name))) + if (LLFloater::getControlGroup()->controlExists(getRectControlName(name))) { declareRectControl(name); } - if (LLUI::sSettingGroups["floater"]->controlExists(getVisibilityControlName(name))) + if (LLFloater::getControlGroup()->controlExists(getVisibilityControlName(name))) { declareVisibilityControl(name); } @@ -419,7 +419,7 @@ void LLFloaterReg::initUICtrlToFloaterVisibilityControl(LLUICtrl* ctrl, const LL // Get the visibility control name for the floater std::string vis_control_name = LLFloaterReg::declareVisibilityControl(sdname.asString()); // Set the control value to the floater visibility control (Sets the value as well) - ctrl->setControlVariable(LLUI::sSettingGroups["floater"]->getControl(vis_control_name)); + ctrl->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name)); } // callback args may use "floatername.key" format diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index 1f16d12add..43e5f6b051 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -315,6 +315,20 @@ void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLFocusableElement* f } } +bool LLFocusMgr::keyboardFocusHasAccelerators() const +{ + LLView* focus_view = dynamic_cast<LLView*>(mKeyboardFocus); + while( focus_view ) + { + if(focus_view->hasAccelerators()) + { + return true; + } + + focus_view = focus_view->getParent(); + } + return false; +} void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor ) { diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h index eef82a3b5a..22c1895075 100644 --- a/indra/llui/llfocusmgr.h +++ b/indra/llui/llfocusmgr.h @@ -118,6 +118,8 @@ public: void unlockFocus(); BOOL focusLocked() const { return mLockedView != NULL; } + bool keyboardFocusHasAccelerators() const; + private: LLUICtrl* mLockedView; diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 0ff7557ead..940c7e7e18 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -35,95 +35,66 @@ #include "llresizebar.h" #include "llcriticaldamp.h" -static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack", &LLLayoutStack::fromXML); - +static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack"); +static LLLayoutStack::LayoutStackRegistry::Register<LLLayoutPanel> register_layout_panel("layout_panel"); // -// LLLayoutStack +// LLLayoutPanel // -struct LLLayoutStack::LayoutPanel -{ - LayoutPanel(LLPanel* panelp, ELayoutOrientation orientation, S32 min_width, S32 min_height, S32 max_width, S32 max_height, BOOL auto_resize, BOOL user_resize) : mPanel(panelp), - mMinWidth(min_width), - mMinHeight(min_height), - mMaxWidth(max_width), - mMaxHeight(max_height), - mAutoResize(auto_resize), - mUserResize(user_resize), - mOrientation(orientation), +LLLayoutPanel::LLLayoutPanel(const Params& p) +: LLPanel(p), + mMinDim(p.min_dim), + mMaxDim(p.max_dim), + mAutoResize(p.auto_resize), + mUserResize(p.user_resize), mCollapsed(FALSE), mCollapseAmt(0.f), mVisibleAmt(1.f), // default to fully visible mResizeBar(NULL) { - LLResizeBar::Side side = (orientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM; - LLRect resize_bar_rect = panelp->getRect(); - - S32 min_dim; - if (orientation == HORIZONTAL) + // panels initialized as hidden should not start out partially visible + if (!getVisible()) { - min_dim = mMinHeight; + mVisibleAmt = 0.f; } - else - { - min_dim = mMinWidth; } - LLResizeBar::Params p; - p.name("resize"); - p.resizing_view(mPanel); - p.min_size(min_dim); - p.side(side); - p.snapping_enabled(false); - mResizeBar = LLUICtrlFactory::create<LLResizeBar>(p); - // panels initialized as hidden should not start out partially visible - if (!mPanel->getVisible()) + +void LLLayoutPanel::initFromParams(const Params& p) { - mVisibleAmt = 0.f; - } + LLPanel::initFromParams(p); + setFollowsNone(); } - ~LayoutPanel() + +LLLayoutPanel::~LLLayoutPanel() { // probably not necessary, but... delete mResizeBar; mResizeBar = NULL; } - F32 getCollapseFactor() +F32 LLLayoutPanel::getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation) { - if (mOrientation == HORIZONTAL) + if (orientation == LLLayoutStack::HORIZONTAL) { F32 collapse_amt = - clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinWidth / (F32)llmax(1, mPanel->getRect().getWidth())); + clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinDim / (F32)llmax(1, getRect().getWidth())); return mVisibleAmt * collapse_amt; } else { F32 collapse_amt = - clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)mMinHeight / (F32)llmax(1, mPanel->getRect().getHeight()))); + clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)mMinDim / (F32)llmax(1, getRect().getHeight()))); return mVisibleAmt * collapse_amt; } } - LLPanel* mPanel; - S32 mMinWidth; - S32 mMinHeight; - - // mMaxWidth & mMaxHeight are added to make configurable max width of the nearby chat bar. EXT-5589 - // they are not processed by LLLayoutStack but they can be if necessary - S32 mMaxWidth; - S32 mMaxHeight; - BOOL mAutoResize; - BOOL mUserResize; - BOOL mCollapsed; - LLResizeBar* mResizeBar; - ELayoutOrientation mOrientation; - F32 mVisibleAmt; - F32 mCollapseAmt; -}; +// +// LLLayoutStack +// LLLayoutStack::Params::Params() -: orientation("orientation", std::string("vertical")), +: orientation("orientation"), animate("animate", true), clip("clip", true), border_size("border_size", LLCachedControl<S32>(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0)) @@ -157,18 +128,18 @@ void LLLayoutStack::draw() for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { // clip to layout rectangle, not bounding rectangle - LLRect clip_rect = (*panel_it)->mPanel->getRect(); + LLRect clip_rect = (*panel_it)->getRect(); // scale clipping rectangle by visible amount if (mOrientation == HORIZONTAL) { - clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor()); + clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor(mOrientation)); } else { - clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor()); + clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor(mOrientation)); } - LLPanel* panelp = (*panel_it)->mPanel; + LLPanel* panelp = (*panel_it); LLLocalClipRect clip(clip_rect, mClip); // only force drawing invisible children if visible amount is non-zero @@ -179,7 +150,7 @@ void LLLayoutStack::draw() void LLLayoutStack::removeChild(LLView* view) { - LayoutPanel* embedded_panelp = findEmbeddedPanel(dynamic_cast<LLPanel*>(view)); + LLLayoutPanel* embedded_panelp = findEmbeddedPanel(dynamic_cast<LLPanel*>(view)); if (embedded_panelp) { @@ -200,149 +171,16 @@ BOOL LLLayoutStack::postBuild() return TRUE; } -static void get_attribute_s32_and_write(LLXMLNodePtr node, - const char* name, - S32 *value, - S32 default_value, - LLXMLNodePtr output_child) -{ - BOOL has_attr = node->getAttributeS32(name, *value); - if (has_attr && *value != default_value && output_child) - { - // create an attribute child node - LLXMLNodePtr child_attr = output_child->createChild(name, TRUE); - child_attr->setIntValue(*value); - } -} - -static void get_attribute_bool_and_write(LLXMLNodePtr node, - const char* name, - BOOL *value, - BOOL default_value, - LLXMLNodePtr output_child) -{ - BOOL has_attr = node->getAttributeBOOL(name, *value); - if (has_attr && *value != default_value && output_child) - { - LLXMLNodePtr child_attr = output_child->createChild(name, TRUE); - child_attr->setBoolValue(*value); - } -} -//static -LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) -{ - LLLayoutStack::Params p(LLUICtrlFactory::getDefaultParams<LLLayoutStack>()); - LLXUIParser::instance().readXUI(node, p, LLUICtrlFactory::getInstance()->getCurFileName()); - - // Export must happen before setupParams() mungles rectangles and before - // this item gets added to parent (otherwise screws up last_child_rect - // logic). JC - if (output_node) - { - Params output_params(p); - setupParamsForExport(output_params, parent); - LLLayoutStack::Params default_params(LLUICtrlFactory::getDefaultParams<LLLayoutStack>()); - output_node->setName(node->getName()->mString); - LLXUIParser::instance().writeXUI( - output_node, output_params, &default_params); - } - - p.from_xui = true; - applyXUILayout(p, parent); - LLLayoutStack* layout_stackp = LLUICtrlFactory::create<LLLayoutStack>(p); - - if (parent && layout_stackp) - { - S32 tab_group = p.tab_group.isProvided() ? p.tab_group() : parent->getLastTabGroup(); - - parent->addChild(layout_stackp, tab_group); - } - - for (LLXMLNodePtr child_node = node->getFirstChild(); child_node.notNull(); child_node = child_node->getNextSibling()) - { - const S32 DEFAULT_MIN_WIDTH = 0; - const S32 DEFAULT_MIN_HEIGHT = 0; - const S32 DEFAULT_MAX_WIDTH = S32_MAX; - const S32 DEFAULT_MAX_HEIGHT = S32_MAX; - const BOOL DEFAULT_AUTO_RESIZE = TRUE; - - S32 min_width = DEFAULT_MIN_WIDTH; - S32 min_height = DEFAULT_MIN_HEIGHT; - S32 max_width = DEFAULT_MAX_WIDTH; - S32 max_height = DEFAULT_MAX_HEIGHT; - BOOL auto_resize = DEFAULT_AUTO_RESIZE; - - LLXMLNodePtr output_child; - if (output_node) +bool LLLayoutStack::addChild(LLView* child, S32 tab_group) { - output_child = output_node->createChild("", FALSE); - } - - // Layout stack allows child nodes to acquire additional attributes, - // such as "min_width" in: <button label="Foo" min_width="100"/> - // If these attributes exist and have non-default values, write them - // to the output node. - get_attribute_s32_and_write(child_node, "min_width", &min_width, - DEFAULT_MIN_WIDTH, output_child); - get_attribute_s32_and_write(child_node, "min_height", &min_height, - DEFAULT_MIN_HEIGHT, output_child); - get_attribute_s32_and_write(child_node, "max_width", &max_width, - DEFAULT_MAX_WIDTH, output_child); - get_attribute_s32_and_write(child_node, "max_height", &max_height, - DEFAULT_MAX_HEIGHT, output_child); - get_attribute_bool_and_write(child_node, "auto_resize", &auto_resize, - DEFAULT_AUTO_RESIZE, output_child); - - if (child_node->hasName("layout_panel")) - { - BOOL user_resize = TRUE; - get_attribute_bool_and_write(child_node, "user_resize", &user_resize, - TRUE, output_child); - LLPanel* panelp = (LLPanel*)LLPanel::fromXML(child_node, layout_stackp, output_child); + LLLayoutPanel* panelp = dynamic_cast<LLLayoutPanel*>(child); if (panelp) { - panelp->setFollowsNone(); - layout_stackp->addPanel(panelp, min_width, min_height, max_width, max_height, auto_resize, user_resize); - } - } - else - { - BOOL user_resize = FALSE; - get_attribute_bool_and_write(child_node, "user_resize", &user_resize, - FALSE, output_child); - - LLPanel::Params p; - p.mouse_opaque(false); - LLPanel* panelp = LLUICtrlFactory::create<LLPanel>(p); - LLView* new_child = LLUICtrlFactory::getInstance()->createFromXML(child_node, panelp, LLStringUtil::null, LLPanel::child_registry_t::instance(), output_child); - if (new_child) - { - // put child in new embedded panel - layout_stackp->addPanel(panelp, min_width, min_height, max_width, max_height, auto_resize, user_resize); - // resize panel to contain widget and move widget to be contained in panel - panelp->setRect(new_child->getRect()); - new_child->setOrigin(0, 0); - } - else - { - panelp->die(); + mPanels.push_back(panelp); } + return LLView::addChild(child, tab_group); } - - if (output_child && !output_child->mChildren && output_child->mAttributes.empty() && output_child->getValue().empty()) - { - output_node->deleteChild(output_child); - } - } - - if (!layout_stackp->postBuild()) - { - delete layout_stackp; - return NULL; - } - return layout_stackp; -} S32 LLLayoutStack::getDefaultHeight(S32 cur_height) { @@ -370,8 +208,8 @@ S32 LLLayoutStack::getDefaultWidth(S32 cur_width) void LLLayoutStack::movePanel(LLPanel* panel_to_move, LLPanel* target_panel, bool move_to_front) { - LayoutPanel* embedded_panel_to_move = findEmbeddedPanel(panel_to_move); - LayoutPanel* embedded_target_panel = move_to_front ? *mPanels.begin() : findEmbeddedPanel(target_panel); + LLLayoutPanel* embedded_panel_to_move = findEmbeddedPanel(panel_to_move); + LLLayoutPanel* embedded_target_panel = move_to_front ? *mPanels.begin() : findEmbeddedPanel(target_panel); if (!embedded_panel_to_move || !embedded_target_panel || embedded_panel_to_move == embedded_target_panel) { @@ -384,34 +222,14 @@ void LLLayoutStack::movePanel(LLPanel* panel_to_move, LLPanel* target_panel, boo mPanels.insert(it, embedded_panel_to_move); } -void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, S32 max_width, S32 max_height, BOOL auto_resize, BOOL user_resize, EAnimate animate, S32 index) +void LLLayoutStack::addPanel(LLLayoutPanel* panel, EAnimate animate) { - // panel starts off invisible (collapsed) - if (animate == ANIMATE) - { - panel->setVisible(FALSE); - } - LayoutPanel* embedded_panel = new LayoutPanel(panel, mOrientation, min_width, min_height, max_width, max_height, auto_resize, user_resize); - - mPanels.insert(mPanels.begin() + llclamp(index, 0, (S32)mPanels.size()), embedded_panel); - - if (panel->getParent() != this) - { - addChild(panel); - } - addChild(embedded_panel->mResizeBar); - - // bring all resize bars to the front so that they are clickable even over the panels - // with a bit of overlap - for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) - { - LLResizeBar* resize_barp = (*panel_it)->mResizeBar; - sendChildToFront(resize_barp); - } + addChild(panel); - // start expanding panel animation + // panel starts off invisible (collapsed) if (animate == ANIMATE) { + panel->mVisibleAmt = 0.f; panel->setVisible(TRUE); } } @@ -423,7 +241,7 @@ void LLLayoutStack::removePanel(LLPanel* panel) void LLLayoutStack::collapsePanel(LLPanel* panel, BOOL collapsed) { - LayoutPanel* panel_container = findEmbeddedPanel(panel); + LLLayoutPanel* panel_container = findEmbeddedPanel(panel); if (!panel_container) return; panel_container->mCollapsed = collapsed; @@ -431,7 +249,7 @@ void LLLayoutStack::collapsePanel(LLPanel* panel, BOOL collapsed) void LLLayoutStack::updatePanelAutoResize(const std::string& panel_name, BOOL auto_resize) { - LayoutPanel* panel = findEmbeddedPanelByName(panel_name); + LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name); if (panel) { @@ -441,7 +259,7 @@ void LLLayoutStack::updatePanelAutoResize(const std::string& panel_name, BOOL au void LLLayoutStack::setPanelUserResize(const std::string& panel_name, BOOL user_resize) { - LayoutPanel* panel = findEmbeddedPanelByName(panel_name); + LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name); if (panel) { @@ -449,27 +267,25 @@ void LLLayoutStack::setPanelUserResize(const std::string& panel_name, BOOL user_ } } -bool LLLayoutStack::getPanelMinSize(const std::string& panel_name, S32* min_widthp, S32* min_heightp) +bool LLLayoutStack::getPanelMinSize(const std::string& panel_name, S32* min_dimp) { - LayoutPanel* panel = findEmbeddedPanelByName(panel_name); + LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name); if (panel) { - if (min_widthp) *min_widthp = panel->mMinWidth; - if (min_heightp) *min_heightp = panel->mMinHeight; + if (min_dimp) *min_dimp = panel->mMinDim; } return NULL != panel; } -bool LLLayoutStack::getPanelMaxSize(const std::string& panel_name, S32* max_widthp, S32* max_heightp) +bool LLLayoutStack::getPanelMaxSize(const std::string& panel_name, S32* max_dimp) { - LayoutPanel* panel = findEmbeddedPanelByName(panel_name); + LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name); if (panel) { - if (max_widthp) *max_widthp = panel->mMaxWidth; - if (max_heightp) *max_heightp = panel->mMaxHeight; + if (max_dimp) *max_dimp = panel->mMaxDim; } return NULL != panel; @@ -481,6 +297,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize) LLFastTimer ft(FTM_UPDATE_LAYOUT); static LLUICachedControl<S32> resize_bar_overlap ("UIResizeBarOverlap", 0); calcMinExtents(); + createResizeBars(); // calculate current extents S32 total_width = 0; @@ -492,7 +309,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize) e_panel_list_t::iterator panel_it; for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { - LLPanel* panelp = (*panel_it)->mPanel; + LLPanel* panelp = (*panel_it); if (panelp->getVisible()) { if (mAnimate) @@ -542,11 +359,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize) if (mOrientation == HORIZONTAL) { // enforce minimize size constraint by default - if (panelp->getRect().getWidth() < (*panel_it)->mMinWidth) + if (panelp->getRect().getWidth() < (*panel_it)->mMinDim) { - panelp->reshape((*panel_it)->mMinWidth, panelp->getRect().getHeight()); + panelp->reshape((*panel_it)->mMinDim, panelp->getRect().getHeight()); } - total_width += llround(panelp->getRect().getWidth() * (*panel_it)->getCollapseFactor()); + total_width += llround(panelp->getRect().getWidth() * (*panel_it)->getCollapseFactor(mOrientation)); // want n-1 panel gaps for n panels if (panel_it != mPanels.begin()) { @@ -556,11 +373,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize) else //VERTICAL { // enforce minimize size constraint by default - if (panelp->getRect().getHeight() < (*panel_it)->mMinHeight) + if (panelp->getRect().getHeight() < (*panel_it)->mMinDim) { - panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->mMinHeight); + panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->mMinDim); } - total_height += llround(panelp->getRect().getHeight() * (*panel_it)->getCollapseFactor()); + total_height += llround(panelp->getRect().getHeight() * (*panel_it)->getCollapseFactor(mOrientation)); if (panel_it != mPanels.begin()) { total_height += mPanelSpacing; @@ -574,7 +391,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize) for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { // panels that are not fully visible do not count towards shrink headroom - if ((*panel_it)->getCollapseFactor() < 1.f) + if ((*panel_it)->getCollapseFactor(mOrientation) < 1.f) { continue; } @@ -587,11 +404,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize) { if (mOrientation == HORIZONTAL) { - shrink_headroom_total += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth; + shrink_headroom_total += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim; } else //VERTICAL { - shrink_headroom_total += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight; + shrink_headroom_total += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim; } } else @@ -599,13 +416,13 @@ void LLLayoutStack::updateLayout(BOOL force_resize) num_resizable_panels++; if (mOrientation == HORIZONTAL) { - shrink_headroom_available += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth; - shrink_headroom_total += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth; + shrink_headroom_available += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim; + shrink_headroom_total += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim; } else //VERTICAL { - shrink_headroom_available += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight; - shrink_headroom_total += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight; + shrink_headroom_available += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim; + shrink_headroom_total += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim; } } } @@ -628,17 +445,25 @@ void LLLayoutStack::updateLayout(BOOL force_resize) for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { - LLPanel* panelp = (*panel_it)->mPanel; + LLPanel* panelp = (*panel_it); S32 cur_width = panelp->getRect().getWidth(); S32 cur_height = panelp->getRect().getHeight(); - S32 new_width = llmax((*panel_it)->mMinWidth, cur_width); - S32 new_height = llmax((*panel_it)->mMinHeight, cur_height); + S32 new_width = cur_width; + S32 new_height = cur_height; + if (mOrientation == HORIZONTAL) + { + new_width = llmax((*panel_it)->mMinDim, new_width); + } + else + { + new_height = llmax((*panel_it)->mMinDim, new_height); + } S32 delta_size = 0; // if panel can automatically resize (not animating, and resize flag set)... - if ((*panel_it)->getCollapseFactor() == 1.f + if ((*panel_it)->getCollapseFactor(mOrientation) == 1.f && (force_resize || (*panel_it)->mAutoResize) && !(*panel_it)->mResizeBar->hasMouseCapture()) { @@ -649,8 +474,8 @@ void LLLayoutStack::updateLayout(BOOL force_resize) { // shrink proportionally to amount over minimum // so we can do this in one pass - delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - (*panel_it)->mMinWidth) / (F32)shrink_headroom_available)) : 0; - shrink_headroom_available -= (cur_width - (*panel_it)->mMinWidth); + delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - (*panel_it)->mMinDim) / (F32)shrink_headroom_available)) : 0; + shrink_headroom_available -= (cur_width - (*panel_it)->mMinDim); } else { @@ -659,7 +484,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize) num_resizable_panels--; } pixels_to_distribute -= delta_size; - new_width = llmax((*panel_it)->mMinWidth, cur_width + delta_size); + new_width = llmax((*panel_it)->mMinDim, cur_width + delta_size); } else { @@ -672,8 +497,8 @@ void LLLayoutStack::updateLayout(BOOL force_resize) { // shrink proportionally to amount over minimum // so we can do this in one pass - delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - (*panel_it)->mMinHeight) / (F32)shrink_headroom_available)) : 0; - shrink_headroom_available -= (cur_height - (*panel_it)->mMinHeight); + delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - (*panel_it)->mMinDim) / (F32)shrink_headroom_available)) : 0; + shrink_headroom_available -= (cur_height - (*panel_it)->mMinDim); } else { @@ -681,7 +506,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize) num_resizable_panels--; } pixels_to_distribute -= delta_size; - new_height = llmax((*panel_it)->mMinHeight, cur_height + delta_size); + new_height = llmax((*panel_it)->mMinDim, cur_height + delta_size); } else { @@ -722,11 +547,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize) if (mOrientation == HORIZONTAL) { - cur_x += llround(new_width * (*panel_it)->getCollapseFactor()) + mPanelSpacing; + cur_x += llround(new_width * (*panel_it)->getCollapseFactor(mOrientation)) + mPanelSpacing; } else //VERTICAL { - cur_y -= llround(new_height * (*panel_it)->getCollapseFactor()) + mPanelSpacing; + cur_y -= llround(new_height * (*panel_it)->getCollapseFactor(mOrientation)) + mPanelSpacing; } } @@ -734,19 +559,19 @@ void LLLayoutStack::updateLayout(BOOL force_resize) LLResizeBar* last_resize_bar = NULL; for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { - LLPanel* panelp = (*panel_it)->mPanel; + LLPanel* panelp = (*panel_it); if (mOrientation == HORIZONTAL) { (*panel_it)->mResizeBar->setResizeLimits( - (*panel_it)->mMinWidth, - (*panel_it)->mMinWidth + shrink_headroom_total); + (*panel_it)->mMinDim, + (*panel_it)->mMinDim + shrink_headroom_total); } else //VERTICAL { (*panel_it)->mResizeBar->setResizeLimits( - (*panel_it)->mMinHeight, - (*panel_it)->mMinHeight + shrink_headroom_total); + (*panel_it)->mMinDim, + (*panel_it)->mMinDim + shrink_headroom_total); } // toggle resize bars based on panel visibility, resizability, etc @@ -782,14 +607,14 @@ void LLLayoutStack::updateLayout(BOOL force_resize) } // end LLLayoutStack::updateLayout -LLLayoutStack::LayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const +LLLayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const { if (!panelp) return NULL; e_panel_list_t::const_iterator panel_it; for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { - if ((*panel_it)->mPanel == panelp) + if ((*panel_it) == panelp) { return *panel_it; } @@ -797,15 +622,15 @@ LLLayoutStack::LayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) co return NULL; } -LLLayoutStack::LayoutPanel* LLLayoutStack::findEmbeddedPanelByName(const std::string& name) const +LLLayoutPanel* LLLayoutStack::findEmbeddedPanelByName(const std::string& name) const { - LayoutPanel* result = NULL; + LLLayoutPanel* result = NULL; for (e_panel_list_t::const_iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { - LayoutPanel* p = *panel_it; + LLLayoutPanel* p = *panel_it; - if (p->mPanel->getName() == name) + if (p->getName() == name) { result = p; break; @@ -826,9 +651,7 @@ void LLLayoutStack::calcMinExtents() { if (mOrientation == HORIZONTAL) { - mMinHeight = llmax( mMinHeight, - (*panel_it)->mMinHeight); - mMinWidth += (*panel_it)->mMinWidth; + mMinWidth += (*panel_it)->mMinDim; if (panel_it != mPanels.begin()) { mMinWidth += mPanelSpacing; @@ -836,9 +659,7 @@ void LLLayoutStack::calcMinExtents() } else //VERTICAL { - mMinWidth = llmax( mMinWidth, - (*panel_it)->mMinWidth); - mMinHeight += (*panel_it)->mMinHeight; + mMinHeight += (*panel_it)->mMinDim; if (panel_it != mPanels.begin()) { mMinHeight += mPanelSpacing; @@ -847,6 +668,37 @@ void LLLayoutStack::calcMinExtents() } } +void LLLayoutStack::createResizeBars() +{ + for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) + { + LLLayoutPanel* lp = (*panel_it); + if (lp->mResizeBar == NULL) + { + LLResizeBar::Side side = (mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM; + LLRect resize_bar_rect = getRect(); + + LLResizeBar::Params resize_params; + resize_params.name("resize"); + resize_params.resizing_view(lp); + resize_params.min_size(lp->mMinDim); + resize_params.side(side); + resize_params.snapping_enabled(false); + LLResizeBar* resize_bar = LLUICtrlFactory::create<LLResizeBar>(resize_params); + lp->mResizeBar = resize_bar; + LLView::addChild(resize_bar, 0); + + // bring all resize bars to the front so that they are clickable even over the panels + // with a bit of overlap + for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) + { + LLResizeBar* resize_barp = (*panel_it)->mResizeBar; + sendChildToFront(resize_barp); + } + } + } +} + // update layout stack animations, etc. once per frame // NOTE: we use this to size world view based on animating UI, *before* we draw the UI // we might still need to call updateLayout during UI draw phase, in case UI elements diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index 6fcc8e2ac3..e19ef403ef 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -28,16 +28,21 @@ #ifndef LL_LLLAYOUTSTACK_H #define LL_LLLAYOUTSTACK_H -#include "llview.h" +#include "llpanel.h" class LLPanel; +class LLLayoutPanel; + class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack> { public: + struct LayoutStackRegistry : public LLChildRegistry<LayoutStackRegistry> + {}; + struct Params : public LLInitParam::Block<Params, LLView::Params> { - Optional<std::string> orientation; + Mandatory<std::string> orientation; Optional<S32> border_size; Optional<bool> animate, clip; @@ -45,6 +50,8 @@ public: Params(); }; + typedef LayoutStackRegistry child_registry_t; + typedef enum e_layout_orientation { HORIZONTAL, @@ -56,6 +63,7 @@ public: /*virtual*/ void draw(); /*virtual*/ void removeChild(LLView*); /*virtual*/ BOOL postBuild(); + /*virtual*/ bool addChild(LLView* child, S32 tab_group = 0); static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL); @@ -68,7 +76,7 @@ public: ANIMATE } EAnimate; - void addPanel(LLPanel* panel, S32 min_width, S32 min_height, S32 max_width, S32 max_height, BOOL auto_resize, BOOL user_resize, EAnimate animate = NO_ANIMATE, S32 index = S32_MAX); + void addPanel(LLLayoutPanel* panel, EAnimate animate = NO_ANIMATE); void removePanel(LLPanel* panel); void collapsePanel(LLPanel* panel, BOOL collapsed = TRUE); S32 getNumPanels() { return mPanels.size(); } @@ -82,20 +90,18 @@ public: void setPanelUserResize(const std::string& panel_name, BOOL user_resize); /** - * Gets minimal width and/or height of the specified by name panel. + * Gets minimal dimension along layout_stack axis of the specified by name panel. * - * If it is necessary to get only the one dimension pass NULL for another one. * @returns true if specified by panel_name internal panel exists, false otherwise. */ - bool getPanelMinSize(const std::string& panel_name, S32* min_widthp, S32* min_heightp); + bool getPanelMinSize(const std::string& panel_name, S32* min_dimp); /** - * Gets maximal width and/or height of the specified by name panel. + * Gets maximal dimension along layout_stack axis of the specified by name panel. * - * If it is necessary to get only the one dimension pass NULL for another one. * @returns true if specified by panel_name internal panel exists, false otherwise. */ - bool getPanelMaxSize(const std::string& panel_name, S32* max_width, S32* max_height); + bool getPanelMaxSize(const std::string& panel_name, S32* max_dim); void updateLayout(BOOL force_resize = FALSE); @@ -110,19 +116,18 @@ protected: friend class LLUICtrlFactory; private: - struct LayoutPanel; - + void createResizeBars(); void calcMinExtents(); S32 getDefaultHeight(S32 cur_height); S32 getDefaultWidth(S32 cur_width); const ELayoutOrientation mOrientation; - typedef std::vector<LayoutPanel*> e_panel_list_t; + typedef std::vector<LLLayoutPanel*> e_panel_list_t; e_panel_list_t mPanels; - LayoutPanel* findEmbeddedPanel(LLPanel* panelp) const; - LayoutPanel* findEmbeddedPanelByName(const std::string& name) const; + LLLayoutPanel* findEmbeddedPanel(LLPanel* panelp) const; + LLLayoutPanel* findEmbeddedPanelByName(const std::string& name) const; S32 mMinWidth; // calculated by calcMinExtents S32 mMinHeight; // calculated by calcMinExtents @@ -134,4 +139,49 @@ private: bool mClip; }; // end class LLLayoutStack +class LLLayoutPanel : public LLPanel +{ +friend class LLLayoutStack; +friend class LLUICtrlFactory; +public: + struct Params : public LLInitParam::Block<Params, LLPanel::Params> + { + Optional<S32> min_dim, + max_dim; + Optional<bool> user_resize, + auto_resize; + + Params() + : min_dim("min_dim", 0), + max_dim("max_dim", 0), + user_resize("user_resize", true), + auto_resize("auto_resize", true) + { + addSynonym(min_dim, "min_width"); + addSynonym(min_dim, "min_height"); + addSynonym(max_dim, "max_width"); + addSynonym(max_dim, "max_height"); + } + }; + + ~LLLayoutPanel(); + + void initFromParams(const Params& p); +protected: + LLLayoutPanel(const Params& p) ; + + + F32 getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation); + + S32 mMinDim; + S32 mMaxDim; + BOOL mAutoResize; + BOOL mUserResize; + BOOL mCollapsed; + class LLResizeBar* mResizeBar; + F32 mVisibleAmt; + F32 mCollapseAmt; +}; + + #endif diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 0b5c820859..50edc3e8e7 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1271,7 +1271,7 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) if( mCurrentHistoryLine > mLineHistory.begin() ) { mText.assign( *(--mCurrentHistoryLine) ); - setCursor(llmin((S32)mText.length(), getCursor())); + setCursorToEnd(); } else { @@ -1288,7 +1288,7 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) if( !mLineHistory.empty() && mCurrentHistoryLine < mLineHistory.end() - 1 ) { mText.assign( *(++mCurrentHistoryLine) ); - setCursor(llmin((S32)mText.length(), getCursor())); + setCursorToEnd(); } else { diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 900a814238..6d590cf54e 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -3738,8 +3738,7 @@ void LLContextMenuBranch::buildDrawLabel( void ) appendAcceleratorString( st ); mDrawAccelLabel = st; - // No special branch suffix - mDrawBranchLabel.clear(); + mDrawBranchLabel = LLMenuGL::BRANCH_SUFFIX; } void LLContextMenuBranch::showSubMenu() diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index 1f6fa12969..d4e6091ee0 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -101,8 +101,8 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p) setMouseUpCallback(initCommitCallback(p.mouse_up_callback)); } - for (LLInitParam::ParamIterator<SliderParams>::const_iterator it = p.sliders().begin(); - it != p.sliders().end(); + for (LLInitParam::ParamIterator<SliderParams>::const_iterator it = p.sliders.begin(); + it != p.sliders.end(); ++it) { if (it->name.isProvided()) diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 99d540a9de..30cd85619e 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -27,6 +27,7 @@ #include "linden_common.h" #include "llnotifications.h" +#include "llnotificationtemplate.h" #include "llinstantmessage.h" #include "llxmlnode.h" @@ -37,6 +38,8 @@ #include "lltrans.h" #include "llnotificationslistener.h" #include "llstring.h" +#include "llsdparam.h" +#include "llsdutil.h" #include <algorithm> #include <boost/regex.hpp> @@ -44,6 +47,56 @@ const std::string NOTIFICATION_PERSIST_VERSION = "0.93"; +void NotificationPriorityValues::declareValues() +{ + declare("low", NOTIFICATION_PRIORITY_LOW); + declare("normal", NOTIFICATION_PRIORITY_NORMAL); + declare("high", NOTIFICATION_PRIORITY_HIGH); + declare("critical", NOTIFICATION_PRIORITY_CRITICAL); +} + +LLNotificationForm::FormElementBase::FormElementBase() +: name("name") +{} + +LLNotificationForm::FormIgnore::FormIgnore() +: text("text"), + control("control"), + invert_control("invert_control", true), + save_option("save_option", false) +{} + +LLNotificationForm::FormButton::FormButton() +: index("index"), + text("text"), + ignore("ignore"), + is_default("default"), + type("type") +{ + // set type here so it gets serialized + type = "button"; +} + +LLNotificationForm::FormInput::FormInput() +: type("type"), + width("width", 0) +{} + +LLNotificationForm::FormElement::FormElement() +: button("button"), + input("input") +{} + +LLNotificationForm::FormElements::FormElements() +: elements("") +{} + +LLNotificationForm::Params::Params() +: name("name"), + ignore("ignore"), + form_elements("") +{} + // Local channel for persistent notifications // Stores only persistent notifications. // Class users can use connectChanged() to process persistent notifications @@ -88,12 +141,7 @@ bool filterIgnoredNotifications(LLNotificationPtr notification) LLNotificationFormPtr form = notification->getForm(); // Check to see if the user wants to ignore this alert - if (form->getIgnoreType() != LLNotificationForm::IGNORE_NO) - { - return LLUI::sSettingGroups["ignores"]->getBOOL(notification->getName()); - } - - return true; + return !notification->getForm()->getIgnored(); } bool handleIgnoredNotification(const LLSD& payload) @@ -135,63 +183,68 @@ namespace LLNotificationFilters }; LLNotificationForm::LLNotificationForm() -: mFormData(LLSD::emptyArray()), - mIgnore(IGNORE_NO) +: mIgnore(IGNORE_NO) { } -LLNotificationForm::LLNotificationForm(const std::string& name, const LLXMLNodePtr xml_node) -: mFormData(LLSD::emptyArray()), - mIgnore(IGNORE_NO) +LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotificationForm::Params& p) +: mIgnore(IGNORE_NO), + mInvertSetting(true) // ignore settings by default mean true=show, false=ignore { - if (!xml_node->hasName("form")) + if (p.ignore.isProvided()) { - llwarns << "Bad xml node for form: " << xml_node->getName() << llendl; - } - LLXMLNodePtr child = xml_node->getFirstChild(); - while(child) - { - child = LLNotifications::instance().checkForXMLTemplate(child); + mIgnoreMsg = p.ignore.text; - LLSD item_entry; - std::string element_name = child->getName()->mString; + if (!p.ignore.save_option) + { + mIgnore = IGNORE_WITH_DEFAULT_RESPONSE; + } + else + { + // remember last option chosen by user and automatically respond with that in the future + mIgnore = IGNORE_WITH_LAST_RESPONSE; + LLUI::sSettingGroups["ignores"]->declareLLSD(std::string("Default") + name, "", std::string("Default response for notification " + name)); + } - if (element_name == "ignore" ) + BOOL show_notification = TRUE; + if (p.ignore.control.isProvided()) { - bool save_option = false; - child->getAttribute_bool("save_option", save_option); - if (!save_option) - { - mIgnore = IGNORE_WITH_DEFAULT_RESPONSE; - } - else - { - // remember last option chosen by user and automatically respond with that in the future - mIgnore = IGNORE_WITH_LAST_RESPONSE; - LLUI::sSettingGroups["ignores"]->declareLLSD(std::string("Default") + name, "", std::string("Default response for notification " + name)); - } - child->getAttributeString("text", mIgnoreMsg); - BOOL show_notification = TRUE; - LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Ignore notification with this name", TRUE); + mIgnoreSetting = LLUI::sSettingGroups["config"]->getControl(p.ignore.control); + mInvertSetting = p.ignore.invert_control; } else { - // flatten xml form entry into single LLSD map with type==name - item_entry["type"] = element_name; - const LLXMLAttribList::iterator attrib_end = child->mAttributes.end(); - for(LLXMLAttribList::iterator attrib_it = child->mAttributes.begin(); - attrib_it != attrib_end; - ++attrib_it) - { - item_entry[std::string(attrib_it->second->getName()->mString)] = attrib_it->second->getValue(); - } - item_entry["value"] = child->getTextContents(); - mFormData.append(item_entry); + LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Ignore notification with this name", TRUE); + mIgnoreSetting = LLUI::sSettingGroups["ignores"]->getControl(name); } + } + + LLParamSDParser parser; + parser.writeSD(mFormData, p.form_elements); + + mFormData = mFormData[""]; + if (!mFormData.isArray()) + { + // change existing contents to a one element array + LLSD new_llsd_array = LLSD::emptyArray(); + new_llsd_array.append(mFormData); + mFormData = new_llsd_array; + } - child = child->getNextSibling(); + for (LLSD::array_iterator it = mFormData.beginArray(), end_it = mFormData.endArray(); + it != end_it; + ++it) + { + // lift contents of form element up a level, since element type is already encoded in "type" param + if (it->isMap() && it->beginMap() != it->endMap()) + { + *it = it->beginMap()->second; + } } + + LL_DEBUGS("Notifications") << name << LL_ENDL; + LL_DEBUGS("Notifications") << ll_pretty_print_sd(mFormData) << LL_ENDL; } LLNotificationForm::LLNotificationForm(const LLSD& sd) @@ -293,16 +346,64 @@ std::string LLNotificationForm::getDefaultOption() return ""; } -LLNotificationTemplate::LLNotificationTemplate() : - mExpireSeconds(0), - mExpireOption(-1), - mURLOption(-1), - mURLOpenExternally(-1), - mPersist(false), - mUnique(false), - mPriority(NOTIFICATION_PRIORITY_NORMAL) +LLControlVariablePtr LLNotificationForm::getIgnoreSetting() +{ + return mIgnoreSetting; +} + +bool LLNotificationForm::getIgnored() +{ + bool ignored = false; + if (mIgnore != LLNotificationForm::IGNORE_NO + && mIgnoreSetting) + { + ignored = mIgnoreSetting->getValue().asBoolean(); + if (mInvertSetting) ignored = !ignored; + } + + return ignored; +} + +void LLNotificationForm::setIgnored(bool ignored) { - mForm = LLNotificationFormPtr(new LLNotificationForm()); + if (mIgnoreSetting) + { + if (mInvertSetting) ignored = !ignored; + mIgnoreSetting->setValue(ignored); + } +} + +LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Params& p) +: mName(p.name), + mType(p.type), + mMessage(p.value), + mLabel(p.label), + mIcon(p.icon), + mURL(p.url.value), + mExpireSeconds(p.duration), + mExpireOption(p.expire_option), + mURLOption(p.url.option), + mURLTarget(p.url.target), + mUnique(p.unique.isProvided()), + mPriority(p.priority), + mPersist(p.persist), + mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name()) +{ + if (p.sound.isProvided() + && LLUI::sSettingGroups["config"]->controlExists(p.sound)) + { + mSoundEffect = LLUUID(LLUI::sSettingGroups["config"]->getString(p.sound)); + } + + for(LLInitParam::ParamIterator<LLNotificationTemplate::UniquenessContext>::const_iterator it = p.unique.contexts.begin(), + end_it = p.unique.contexts.end(); + it != end_it; + ++it) + { + mUniqueContext.push_back(it->key); + } + + mForm = LLNotificationFormPtr(new LLNotificationForm(p.name, p.form_ref.form)); } LLNotification::LLNotification(const LLNotification::Params& p) : @@ -499,7 +600,7 @@ void LLNotification::respond(const LLSD& response) { mResponder->handleRespond(asLLSD(), response); } - else + else if (!mResponseFunctorName.empty()) { // look up the functor LLNotificationFunctorRegistry::ResponseFunctor functor = @@ -507,6 +608,11 @@ void LLNotification::respond(const LLSD& response) // and then call it functor(asLLSD(), response); } + else + { + // no registered responder + return; + } if (mTemporaryResponder && !isReusable()) { @@ -517,8 +623,7 @@ void LLNotification::respond(const LLSD& response) if (mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO) { - BOOL show_notification = mIgnored ? FALSE : TRUE; - LLUI::sSettingGroups["ignores"]->setBOOL(getName(), show_notification); + mForm->setIgnored(mIgnored); if (mIgnored && mForm->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE) { LLUI::sSettingGroups["ignores"]->setLLSD("Default" + getName(), response); @@ -528,6 +633,49 @@ void LLNotification::respond(const LLSD& response) update(); } +void LLNotification::respondWithDefault() +{ + respond(getResponseTemplate(WITH_DEFAULT_BUTTON)); +} + + +const std::string& LLNotification::getName() const +{ + return mTemplatep->mName; +} + +const std::string& LLNotification::getIcon() const +{ + return mTemplatep->mIcon; +} + + +bool LLNotification::isPersistent() const +{ + return mTemplatep->mPersist; +} + +std::string LLNotification::getType() const +{ + return (mTemplatep ? mTemplatep->mType : ""); +} + +S32 LLNotification::getURLOption() const +{ + return (mTemplatep ? mTemplatep->mURLOption : -1); +} + +S32 LLNotification::getURLOpenExternally() const +{ + return(mTemplatep? mTemplatep->mURLTarget == "_external": -1); +} + +bool LLNotification::hasUniquenessConstraints() const +{ + return (mTemplatep ? mTemplatep->mUnique : false); +} + + void LLNotification::setIgnored(bool ignore) { mIgnored = ignore; @@ -607,6 +755,8 @@ void LLNotification::init(const std::string& template_name, const LLSD& form_ele // apply substitution to form labels mForm->formatElements(mSubstitutions); + mIgnored = mForm->getIgnored(); + LLDate rightnow = LLDate::now(); if (mTemplatep->mExpireSeconds) { @@ -910,12 +1060,12 @@ std::string LLNotificationChannel::summarize() // LLNotifications implementation // --- LLNotifications::LLNotifications() : LLNotificationChannelBase(LLNotificationFilters::includeEverything, - LLNotificationComparators::orderByUUID()), - mIgnoreAllNotifications(false) + LLNotificationComparators::orderByUUID()), + mIgnoreAllNotifications(false) { LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2)); - - mListener.reset(new LLNotificationsListener(*this)); + + mListener.reset(new LLNotificationsListener(*this)); } @@ -1095,11 +1245,6 @@ bool LLNotifications::templateExists(const std::string& name) return (mTemplates.count(name) != 0); } -void LLNotifications::clearTemplates() -{ - mTemplates.clear(); -} - void LLNotifications::forceResponse(const LLNotification::Params& params, S32 option) { LLNotificationPtr temp_notify(new LLNotification(params)); @@ -1162,190 +1307,88 @@ void replaceSubstitutionStrings(LLXMLNodePtr node, StringMap& replacements) } } -// private to this file -// returns true if the template request was invalid and there's nothing else we -// can do with this node, false if you should keep processing (it may have -// replaced the contents of the node referred to) -LLXMLNodePtr LLNotifications::checkForXMLTemplate(LLXMLNodePtr item) +void replaceFormText(LLNotificationForm::Params& form, const std::string& pattern, const std::string& replace) { - if (item->hasName("usetemplate")) + if (form.ignore.isProvided() && form.ignore.text() == pattern) + { + form.ignore.text = replace; + } + for (LLInitParam::ParamIterator<LLNotificationForm::FormElement>::iterator it = form.form_elements.elements.begin(), + end_it = form.form_elements.elements.end(); + it != end_it; + ++it) { - std::string replacementName; - if (item->getAttributeString("name", replacementName)) + if (it->button.isChosen() && it->button.text() == pattern) { - StringMap replacements; - for (LLXMLAttribList::const_iterator it=item->mAttributes.begin(); - it != item->mAttributes.end(); ++it) - { - replacements[it->second->getName()->mString] = it->second->getValue(); - } - if (mXmlTemplates.count(replacementName)) - { - item=LLXMLNode::replaceNode(item, mXmlTemplates[replacementName]); - - // walk the nodes looking for $(substitution) here and replace - replaceSubstitutionStrings(item, replacements); - } - else - { - llwarns << "XML template lookup failure on '" << replacementName << "' " << llendl; - } + it->button.text = replace; } } - return item; } bool LLNotifications::loadTemplates() { const std::string xml_filename = "notifications.xml"; + std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), xml_filename); + LLXMLNodePtr root; - BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root); if (!success || root.isNull() || !root->hasName( "notifications" )) { - llerrs << "Problem reading UI Notifications file: " << xml_filename << llendl; + llerrs << "Problem reading UI Notifications file: " << full_filename << llendl; return false; } - - clearTemplates(); - - for (LLXMLNodePtr item = root->getFirstChild(); - item.notNull(); item = item->getNextSibling()) + + LLNotificationTemplate::Notifications params; + LLXUIParser parser; + parser.readXUI(root, params, full_filename); + + mTemplates.clear(); + + for(LLInitParam::ParamIterator<LLNotificationTemplate::GlobalString>::const_iterator it = params.strings.begin(), end_it = params.strings.end(); + it != end_it; + ++it) { - // we do this FIRST so that item can be changed if we - // encounter a usetemplate -- we just replace the - // current xml node and keep processing - item = checkForXMLTemplate(item); - - if (item->hasName("global")) - { - std::string global_name; - if (item->getAttributeString("name", global_name)) - { - mGlobalStrings[global_name] = item->getTextContents(); - } - continue; - } - - if (item->hasName("template")) - { - // store an xml template; templates must have a single node (can contain - // other nodes) - std::string name; - item->getAttributeString("name", name); - LLXMLNodePtr ptr = item->getFirstChild(); - mXmlTemplates[name] = ptr; - continue; - } - - if (!item->hasName("notification")) - { - llwarns << "Unexpected entity " << item->getName()->mString << - " found in " << xml_filename << llendl; - continue; - } - - // now we know we have a notification entry, so let's build it - LLNotificationTemplatePtr pTemplate(new LLNotificationTemplate()); + mGlobalStrings[it->name] = it->value; + } - if (!item->getAttributeString("name", pTemplate->mName)) - { - llwarns << "Unable to parse notification with no name" << llendl; - continue; - } - - //llinfos << "Parsing " << pTemplate->mName << llendl; - - pTemplate->mMessage = item->getTextContents(); - pTemplate->mDefaultFunctor = pTemplate->mName; - item->getAttributeString("type", pTemplate->mType); - item->getAttributeString("icon", pTemplate->mIcon); - item->getAttributeString("label", pTemplate->mLabel); - item->getAttributeU32("duration", pTemplate->mExpireSeconds); - item->getAttributeU32("expireOption", pTemplate->mExpireOption); + std::map<std::string, LLNotificationForm::Params> form_templates; - std::string priority; - item->getAttributeString("priority", priority); - pTemplate->mPriority = NOTIFICATION_PRIORITY_NORMAL; - if (!priority.empty()) - { - if (priority == "low") pTemplate->mPriority = NOTIFICATION_PRIORITY_LOW; - if (priority == "normal") pTemplate->mPriority = NOTIFICATION_PRIORITY_NORMAL; - if (priority == "high") pTemplate->mPriority = NOTIFICATION_PRIORITY_HIGH; - if (priority == "critical") pTemplate->mPriority = NOTIFICATION_PRIORITY_CRITICAL; - } - - item->getAttributeString("functor", pTemplate->mDefaultFunctor); + for(LLInitParam::ParamIterator<LLNotificationTemplate::Template>::const_iterator it = params.templates.begin(), end_it = params.templates.end(); + it != end_it; + ++it) + { + form_templates[it->name] = it->form; + } - BOOL persist = false; - item->getAttributeBOOL("persist", persist); - pTemplate->mPersist = persist; - - std::string sound; - item->getAttributeString("sound", sound); - if (!sound.empty()) + for(LLInitParam::ParamIterator<LLNotificationTemplate::Params>::iterator it = params.notifications.begin(), end_it = params.notifications.end(); + it != end_it; + ++it) + { + if (it->form_ref.form_template.isChosen()) { - // test for bad sound effect name / missing effect - if (LLUI::sSettingGroups["config"]->controlExists(sound)) + // replace form contents from template + it->form_ref.form = form_templates[it->form_ref.form_template.name]; + if(it->form_ref.form_template.yes_text.isProvided()) { - pTemplate->mSoundEffect = - LLUUID(LLUI::sSettingGroups["config"]->getString(sound)); + replaceFormText(it->form_ref.form, "$yestext", it->form_ref.form_template.yes_text); } - else + if(it->form_ref.form_template.no_text.isProvided()) { - llwarns << "Unknown sound effect control name " << sound - << llendl; + replaceFormText(it->form_ref.form, "$notext", it->form_ref.form_template.no_text); } - } - - for (LLXMLNodePtr child = item->getFirstChild(); - !child.isNull(); child = child->getNextSibling()) - { - child = checkForXMLTemplate(child); - - // <url> - if (child->hasName("url")) + if(it->form_ref.form_template.cancel_text.isProvided()) { - pTemplate->mURL = child->getTextContents(); - child->getAttributeU32("option", pTemplate->mURLOption); - child->getAttributeU32("openexternally", pTemplate->mURLOpenExternally); + replaceFormText(it->form_ref.form, "$canceltext", it->form_ref.form_template.cancel_text); } - - if (child->hasName("unique")) - { - pTemplate->mUnique = true; - for (LLXMLNodePtr formitem = child->getFirstChild(); - !formitem.isNull(); formitem = formitem->getNextSibling()) - { - if (formitem->hasName("context")) - { - std::string key; - formitem->getAttributeString("key", key); - pTemplate->mUniqueContext.push_back(key); - //llwarns << "adding " << key << " to unique context" << llendl; - } - else - { - llwarns << "'unique' has unrecognized subelement " - << formitem->getName()->mString << llendl; - } - } - } - - // <form> - if (child->hasName("form")) + if(it->form_ref.form_template.ignore_text.isProvided()) { - pTemplate->mForm = LLNotificationFormPtr(new LLNotificationForm(pTemplate->mName, child)); + replaceFormText(it->form_ref.form, "$ignoretext", it->form_ref.form_template.ignore_text); } } - addTemplate(pTemplate->mName, pTemplate); + addTemplate(it->name, LLNotificationTemplatePtr(new LLNotificationTemplate(*it))); } - - //std::ostringstream ostream; - //root->writeToOstream(ostream, "\n "); - //llwarns << ostream.str() << llendl; - + return true; } @@ -1396,6 +1439,8 @@ LLNotificationPtr LLNotifications::add(const LLNotification::Params& p) void LLNotifications::add(const LLNotificationPtr pNotif) { + if (pNotif == NULL) return; + // first see if we already have it -- if so, that's a problem LLNotificationSet::iterator it=mItems.find(pNotif); if (it != mItems.end()) @@ -1408,6 +1453,8 @@ void LLNotifications::add(const LLNotificationPtr pNotif) void LLNotifications::cancel(LLNotificationPtr pNotif) { + if (pNotif == NULL) return; + LLNotificationSet::iterator it=mItems.find(pNotif); if (it == mItems.end()) { @@ -1417,6 +1464,30 @@ void LLNotifications::cancel(LLNotificationPtr pNotif) updateItem(LLSD().with("sigtype", "delete").with("id", pNotif->id()), pNotif); } +void LLNotifications::cancelByName(const std::string& name) +{ + std::vector<LLNotificationPtr> notifs_to_cancel; + for (LLNotificationSet::iterator it=mItems.begin(), end_it = mItems.end(); + it != end_it; + ++it) + { + LLNotificationPtr pNotif = *it; + if (pNotif->getName() == name) + { + notifs_to_cancel.push_back(pNotif); + } + } + + for (std::vector<LLNotificationPtr>::iterator it = notifs_to_cancel.begin(), end_it = notifs_to_cancel.end(); + it != end_it; + ++it) + { + LLNotificationPtr pNotif = *it; + pNotif->cancel(); + updateItem(LLSD().with("sigtype", "delete").with("id", pNotif->id()), pNotif); + } +} + void LLNotifications::update(const LLNotificationPtr pNotif) { LLNotificationSet::iterator it=mItems.find(pNotif); diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 2cc8803f10..f075c44520 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -100,7 +100,6 @@ #include "llnotificationptr.h" #include "llcachename.h" - typedef enum e_notification_priority { NOTIFICATION_PRIORITY_UNSPECIFIED, @@ -110,6 +109,11 @@ typedef enum e_notification_priority NOTIFICATION_PRIORITY_CRITICAL } ENotificationPriority; +struct NotificationPriorityValues : public LLInitParam::TypeValuesHelper<ENotificationPriority, NotificationPriorityValues> +{ + static void declareValues(); +}; + class LLNotificationResponderInterface { public: @@ -157,6 +161,66 @@ class LLNotificationForm LOG_CLASS(LLNotificationForm); public: + struct FormElementBase : public LLInitParam::Block<FormElementBase> + { + Optional<std::string> name; + + FormElementBase(); + }; + + struct FormIgnore : public LLInitParam::Block<FormIgnore, FormElementBase> + { + Optional<std::string> text; + Optional<bool> save_option; + Optional<std::string> control; + Optional<bool> invert_control; + + FormIgnore(); + }; + + struct FormButton : public LLInitParam::Block<FormButton, FormElementBase> + { + Mandatory<S32> index; + Mandatory<std::string> text; + Optional<std::string> ignore; + Optional<bool> is_default; + + Mandatory<std::string> type; + + FormButton(); + }; + + struct FormInput : public LLInitParam::Block<FormInput, FormElementBase> + { + Mandatory<std::string> type; + Optional<S32> width; + + FormInput(); + }; + + struct FormElement : public LLInitParam::Choice<FormElement> + { + Alternative<FormButton> button; + Alternative<FormInput> input; + + FormElement(); + }; + + struct FormElements : public LLInitParam::Block<FormElements> + { + Multiple<FormElement> elements; + FormElements(); + }; + + struct Params : public LLInitParam::Block<Params> + { + Optional<std::string> name; + Optional<FormIgnore> ignore; + Optional<FormElements> form_elements; + + Params(); + }; + typedef enum e_ignore_type { IGNORE_NO, @@ -167,8 +231,7 @@ public: LLNotificationForm(); LLNotificationForm(const LLSD& sd); - LLNotificationForm(const std::string& name, - const LLPointer<class LLXMLNode> xml_node); + LLNotificationForm(const std::string& name, const Params& p); LLSD asLLSD() const; @@ -181,92 +244,25 @@ public: // appends form elements from another form serialized as LLSD void append(const LLSD& sub_form); std::string getDefaultOption(); + LLPointer<class LLControlVariable> getIgnoreSetting(); + bool getIgnored(); + void setIgnored(bool ignored); EIgnoreType getIgnoreType() { return mIgnore; } std::string getIgnoreMessage() { return mIgnoreMsg; } private: - LLSD mFormData; - EIgnoreType mIgnore; - std::string mIgnoreMsg; + LLSD mFormData; + EIgnoreType mIgnore; + std::string mIgnoreMsg; + LLPointer<class LLControlVariable> mIgnoreSetting; + bool mInvertSetting; }; typedef boost::shared_ptr<LLNotificationForm> LLNotificationFormPtr; -// This is the class of object read from the XML file (notifications.xml, -// from the appropriate local language directory). -struct LLNotificationTemplate -{ - LLNotificationTemplate(); - // the name of the notification -- the key used to identify it - // Ideally, the key should follow variable naming rules - // (no spaces or punctuation). - std::string mName; - // The type of the notification - // used to control which queue it's stored in - std::string mType; - // The text used to display the notification. Replaceable parameters - // are enclosed in square brackets like this []. - std::string mMessage; - // The label for the notification; used for - // certain classes of notification (those with a window and a window title). - // Also used when a notification pops up underneath the current one. - // Replaceable parameters can be used in the label. - std::string mLabel; - // The name of the icon image. This should include an extension. - std::string mIcon; - // This is the Highlander bit -- "There Can Be Only One" - // An outstanding notification with this bit set - // is updated by an incoming notification with the same name, - // rather than creating a new entry in the queue. - // (used for things like progress indications, or repeating warnings - // like "the grid is going down in N minutes") - bool mUnique; - // if we want to be unique only if a certain part of the payload is constant - // specify the field names for the payload. The notification will only be - // combined if all of the fields named in the context are identical in the - // new and the old notification; otherwise, the notification will be - // duplicated. This is to support suppressing duplicate offers from the same - // sender but still differentiating different offers. Example: Invitation to - // conference chat. - std::vector<std::string> mUniqueContext; - // If this notification expires automatically, this value will be - // nonzero, and indicates the number of seconds for which the notification - // will be valid (a teleport offer, for example, might be valid for - // 300 seconds). - U32 mExpireSeconds; - // if the offer expires, one of the options is chosen automatically - // based on its "value" parameter. This controls which one. - // If expireSeconds is specified, expireOption should also be specified. - U32 mExpireOption; - // if the notification contains a url, it's stored here (and replaced - // into the message where [_URL] is found) - std::string mURL; - // if there's a URL in the message, this controls which option visits - // that URL. Obsolete this and eliminate the buttons for affected - // messages when we allow clickable URLs in the UI - U32 mURLOption; - - U32 mURLOpenExternally; - //This is a flag that tells if the url needs to open externally dispite - //what the user setting is. - - // does this notification persist across sessions? if so, it will be - // serialized to disk on first receipt and read on startup - bool mPersist; - // This is the name of the default functor, if present, to be - // used for the notification's callback. It is optional, and used only if - // the notification is constructed without an identified functor. - std::string mDefaultFunctor; - // The form data associated with a given notification (buttons, text boxes, etc) - LLNotificationFormPtr mForm; - // default priority for notifications of this type - ENotificationPriority mPriority; - // UUID of the audio file to be played when this notification arrives - // this is loaded as a name, but looked up to get the UUID upon template load. - // If null, it wasn't specified. - LLUUID mSoundEffect; -}; + +struct LLNotificationTemplate; // we want to keep a map of these by name, and it's best to manage them // with smart pointers @@ -302,7 +298,7 @@ public: // optional Optional<LLSD> substitutions; Optional<LLSD> payload; - Optional<ENotificationPriority> priority; + Optional<ENotificationPriority, NotificationPriorityValues> priority; Optional<LLSD> form_elements; Optional<LLDate> time_stamp; Optional<LLNotificationContext*> context; @@ -445,6 +441,7 @@ public: LLSD asLLSD(); void respond(const LLSD& sd); + void respondWithDefault(); void* getResponder() { return mResponderObj; } @@ -462,6 +459,13 @@ public: return mRespondedTo; } + bool isActive() const + { + return !isRespondedTo() + && !isCancelled() + && !isExpired(); + } + const LLSD& getResponse() { return mResponse; } bool isIgnored() const @@ -469,15 +473,11 @@ public: return mIgnored; } - const std::string& getName() const - { - return mTemplatep->mName; - } + const std::string& getName() const; - bool isPersistent() const - { - return mTemplatep->mPersist; - } + const std::string& getIcon() const; + + bool isPersistent() const; const LLUUID& id() const { @@ -499,28 +499,12 @@ public: return mTimestamp; } - std::string getType() const - { - return (mTemplatep ? mTemplatep->mType : ""); - } - + std::string getType() const; std::string getMessage() const; std::string getLabel() const; - std::string getURL() const; -// { -// return (mTemplatep ? mTemplatep->mURL : ""); -// } - - S32 getURLOption() const - { - return (mTemplatep ? mTemplatep->mURLOption : -1); - } - - S32 getURLOpenExternally() const - { - return(mTemplatep? mTemplatep->mURLOpenExternally : -1); - } + S32 getURLOption() const; + S32 getURLOpenExternally() const; const LLNotificationFormPtr getForm(); @@ -590,7 +574,7 @@ public: std::string summarize() const; - bool hasUniquenessConstraints() const { return (mTemplatep ? mTemplatep->mUnique : false);} + bool hasUniquenessConstraints() const; virtual ~LLNotification() {} }; @@ -872,7 +856,6 @@ public: // load notification descriptions from file; // OK to call more than once because it will reload bool loadTemplates(); - LLPointer<class LLXMLNode> checkForXMLTemplate(LLPointer<class LLXMLNode> item); // Add a simple notification (from XUI) void addFromCallback(const LLSD& name); @@ -894,6 +877,7 @@ public: void add(const LLNotificationPtr pNotif); void cancel(LLNotificationPtr pNotif); + void cancelByName(const std::string& name); void update(const LLNotificationPtr pNotif); LLNotificationPtr find(LLUUID uuid); @@ -917,8 +901,6 @@ public: // test for existence bool templateExists(const std::string& name); - // useful if you're reloading the file - void clearTemplates(); // erase all templates void forceResponse(const LLNotification::Params& params, S32 option); @@ -956,9 +938,6 @@ private: std::string mFileName; - typedef std::map<std::string, LLPointer<class LLXMLNode> > XMLTemplateMap; - XMLTemplateMap mXmlTemplates; - LLNotificationMap mUniqueNotifications; typedef std::map<std::string, std::string> GlobalStringMap; diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp index 44a90398fd..3bbeb3a778 100644 --- a/indra/llui/llnotificationslistener.cpp +++ b/indra/llui/llnotificationslistener.cpp @@ -29,6 +29,7 @@ #include "linden_common.h" #include "llnotificationslistener.h" #include "llnotifications.h" +#include "llnotificationtemplate.h" #include "llsd.h" #include "llui.h" @@ -182,7 +183,11 @@ void LLNotificationsListener::ignore(const LLSD& params) const if (params["name"].isDefined()) { // ["name"] was passed: ignore just that notification - LLUI::sSettingGroups["ignores"]->setBOOL(params["name"], ignore); + LLNotificationTemplatePtr templatep = mNotifications.getTemplate(params["name"]); + if (templatep) + { + templatep->mForm->setIgnored(ignore); + } } else { diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h new file mode 100644 index 0000000000..6bc0d2aaff --- /dev/null +++ b/indra/llui/llnotificationtemplate.h @@ -0,0 +1,282 @@ +/** +* @file llnotificationtemplate.h +* @brief Description of notification contents +* @author Q (with assistance from Richard and Coco) +* +* $LicenseInfo:firstyear=2008&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#ifndef LL_LLNOTIFICATION_TEMPLATE_H +#define LL_LLNOTIFICATION_TEMPLATE_H + +//#include <string> +//#include <list> +//#include <vector> +//#include <map> +//#include <set> +//#include <iomanip> +//#include <sstream> +// +//#include <boost/utility.hpp> +//#include <boost/shared_ptr.hpp> +//#include <boost/enable_shared_from_this.hpp> +//#include <boost/type_traits.hpp> +// +//// we want to minimize external dependencies, but this one is important +//#include "llsd.h" +// +//// and we need this to manage the notification callbacks +//#include "llevents.h" +//#include "llfunctorregistry.h" +//#include "llpointer.h" +#include "llinitparam.h" +//#include "llnotificationslistener.h" +//#include "llnotificationptr.h" +//#include "llcachename.h" +#include "llnotifications.h" + + +typedef boost::shared_ptr<LLNotificationForm> LLNotificationFormPtr; + +// This is the class of object read from the XML file (notifications.xml, +// from the appropriate local language directory). +struct LLNotificationTemplate +{ + struct GlobalString : public LLInitParam::Block<GlobalString> + { + Mandatory<std::string> name, + value; + + GlobalString() + : name("name"), + value("value") + {} + }; + + struct UniquenessContext : public LLInitParam::Block<UniquenessContext> + { + Mandatory<std::string> key; + + UniquenessContext() + : key("key") + {} + + }; + + struct UniquenessConstraint : public LLInitParam::Block<UniquenessConstraint> + { + private: + // this idiom allows + // <notification unique="true"> + // as well as + // <notification> <unique> <context key=""/> </unique>... + Optional<bool> dummy_val; + public: + Multiple<UniquenessContext> contexts; + + UniquenessConstraint() + : contexts("context"), + dummy_val("") + {} + }; + + // Templates are used to define common form types, such as OK/Cancel dialogs, etc. + + struct Template : public LLInitParam::Block<Template> + { + Mandatory<std::string> name; + Mandatory<LLNotificationForm::Params> form; + + Template() + : name("name"), + form("form") + {} + }; + + // Reference a template to use its form elements + struct TemplateRef : public LLInitParam::Block<TemplateRef> + { + Mandatory<std::string> name; + Optional<std::string> yes_text, + no_text, + cancel_text, + ignore_text; + + TemplateRef() + : name("name"), + yes_text("yestext"), + no_text("notext"), + cancel_text("canceltext"), + ignore_text("ignoretext") + {} + }; + + struct URL : public LLInitParam::Block<URL> + { + Mandatory<S32> option; + Mandatory<std::string> value; + Optional<std::string> target; + Ignored name; + + URL() + : option("option", -1), + value("value"), + target("target", "_blank"), + name("name") + {} + }; + + struct FormRef : public LLInitParam::Choice<FormRef> + { + Alternative<LLNotificationForm::Params> form; + Alternative<TemplateRef> form_template; + + FormRef() + : form("form"), + form_template("usetemplate") + {} + }; + + struct Params : public LLInitParam::Block<Params> + { + Mandatory<std::string> name; + Optional<bool> persist; + Optional<std::string> functor, + icon, + label, + sound, + type, + value; + Optional<U32> duration; + Optional<S32> expire_option; + Optional<URL> url; + Optional<UniquenessConstraint> unique; + Optional<FormRef> form_ref; + Optional<ENotificationPriority, + NotificationPriorityValues> priority; + + + Params() + : name("name"), + persist("persist", false), + functor("functor"), + icon("icon"), + label("label"), + priority("priority"), + sound("sound"), + type("type"), + value("value"), + duration("duration"), + expire_option("expireOption", -1), + url("url"), + unique("unique"), + form_ref("") + {} + + }; + + struct Notifications : public LLInitParam::Block<Notifications> + { + Multiple<GlobalString> strings; + Multiple<Template> templates; + Multiple<Params> notifications; + + Notifications() + : strings("global"), + notifications("notification"), + templates("template") + {} + }; + + LLNotificationTemplate(const Params& p); + // the name of the notification -- the key used to identify it + // Ideally, the key should follow variable naming rules + // (no spaces or punctuation). + std::string mName; + // The type of the notification + // used to control which queue it's stored in + std::string mType; + // The text used to display the notification. Replaceable parameters + // are enclosed in square brackets like this []. + std::string mMessage; + // The label for the notification; used for + // certain classes of notification (those with a window and a window title). + // Also used when a notification pops up underneath the current one. + // Replaceable parameters can be used in the label. + std::string mLabel; + // The name of the icon image. This should include an extension. + std::string mIcon; + // This is the Highlander bit -- "There Can Be Only One" + // An outstanding notification with this bit set + // is updated by an incoming notification with the same name, + // rather than creating a new entry in the queue. + // (used for things like progress indications, or repeating warnings + // like "the grid is going down in N minutes") + bool mUnique; + // if we want to be unique only if a certain part of the payload is constant + // specify the field names for the payload. The notification will only be + // combined if all of the fields named in the context are identical in the + // new and the old notification; otherwise, the notification will be + // duplicated. This is to support suppressing duplicate offers from the same + // sender but still differentiating different offers. Example: Invitation to + // conference chat. + std::vector<std::string> mUniqueContext; + // If this notification expires automatically, this value will be + // nonzero, and indicates the number of seconds for which the notification + // will be valid (a teleport offer, for example, might be valid for + // 300 seconds). + U32 mExpireSeconds; + // if the offer expires, one of the options is chosen automatically + // based on its "value" parameter. This controls which one. + // If expireSeconds is specified, expireOption should also be specified. + U32 mExpireOption; + // if the notification contains a url, it's stored here (and replaced + // into the message where [_URL] is found) + std::string mURL; + // if there's a URL in the message, this controls which option visits + // that URL. Obsolete this and eliminate the buttons for affected + // messages when we allow clickable URLs in the UI + U32 mURLOption; + + std::string mURLTarget; + //This is a flag that tells if the url needs to open externally dispite + //what the user setting is. + + // does this notification persist across sessions? if so, it will be + // serialized to disk on first receipt and read on startup + bool mPersist; + // This is the name of the default functor, if present, to be + // used for the notification's callback. It is optional, and used only if + // the notification is constructed without an identified functor. + std::string mDefaultFunctor; + // The form data associated with a given notification (buttons, text boxes, etc) + LLNotificationFormPtr mForm; + // default priority for notifications of this type + ENotificationPriority mPriority; + // UUID of the audio file to be played when this notification arrives + // this is loaded as a name, but looked up to get the UUID upon template load. + // If null, it wasn't specified. + LLUUID mSoundEffect; +}; + +#endif //LL_LLNOTIFICATION_TEMPLATE_H + diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index b2e08c48c5..c8e56630f1 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -35,6 +35,7 @@ #include "llfontgl.h" #include "llrect.h" #include "llerror.h" +#include "lldir.h" #include "lltimer.h" #include "llaccordionctrltab.h" @@ -52,6 +53,8 @@ #include "lltabcontainer.h" static LLDefaultChildRegistry::Register<LLPanel> r1("panel", &LLPanel::fromXML); +LLPanel::factory_stack_t LLPanel::sFactoryStack; + // Compiler optimization, generate extern template template class LLPanel* LLView::getChild<class LLPanel>( @@ -380,8 +383,7 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLXMLNodePtr output_ LLPanel* panelp = NULL; - { - LLFastTimer timer(FTM_PANEL_CONSTRUCTION); + { LLFastTimer _(FTM_PANEL_CONSTRUCTION); if(!class_attr.empty()) { @@ -394,7 +396,7 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLXMLNodePtr output_ if (!panelp) { - panelp = LLUICtrlFactory::getInstance()->createFactoryPanel(name); + panelp = createFactoryPanel(name); llassert(panelp); if (!panelp) @@ -407,20 +409,20 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLXMLNodePtr output_ // factory panels may have registered their own factory maps if (!panelp->getFactoryMap().empty()) { - LLUICtrlFactory::instance().pushFactoryFunctions(&panelp->getFactoryMap()); + sFactoryStack.push_back(&panelp->getFactoryMap()); } // for local registry callbacks; define in constructor, referenced in XUI or postBuild panelp->mCommitCallbackRegistrar.pushScope(); panelp->mEnableCallbackRegistrar.pushScope(); - panelp->initPanelXML(node, parent, output_node); + panelp->initPanelXML(node, parent, output_node, LLUICtrlFactory::getDefaultParams<LLPanel>()); panelp->mCommitCallbackRegistrar.popScope(); panelp->mEnableCallbackRegistrar.popScope(); if (!panelp->getFactoryMap().empty()) { - LLUICtrlFactory::instance().popFactoryFunctions(); + sFactoryStack.pop_back(); } return panelp; @@ -444,8 +446,8 @@ void LLPanel::initFromParams(const LLPanel::Params& p) setVisibleCallback(initCommitCallback(p.visible_callback)); } - for (LLInitParam::ParamIterator<LocalizedString>::const_iterator it = p.strings().begin(); - it != p.strings().end(); + for (LLInitParam::ParamIterator<LocalizedString>::const_iterator it = p.strings.begin(); + it != p.strings.end(); ++it) { mUIStrings[it->name] = it->value; @@ -487,11 +489,9 @@ static LLFastTimer::DeclareTimer FTM_PANEL_SETUP("Panel Setup"); static LLFastTimer::DeclareTimer FTM_EXTERNAL_PANEL_LOAD("Load Extern Panel Reference"); static LLFastTimer::DeclareTimer FTM_PANEL_POSTBUILD("Panel PostBuild"); -BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) +BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node, const LLPanel::Params& default_params) { - const LLPanel::Params& default_params(LLUICtrlFactory::getDefaultParams<LLPanel>()); Params params(default_params); - { LLFastTimer timer(FTM_PANEL_SETUP); @@ -505,6 +505,8 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu setXMLFilename(xml_filename); } + LLXUIParser parser; + if (!xml_filename.empty()) { LLUICtrlFactory::instance().pushFileName(xml_filename); @@ -514,12 +516,11 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu { //if we are exporting, we want to export the current xml //not the referenced xml - LLXUIParser::instance().readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName()); + parser.readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName()); Params output_params(params); setupParamsForExport(output_params, parent); output_node->setName(node->getName()->mString); - LLXUIParser::instance().writeXUI( - output_node, output_params, &default_params); + parser.writeXUI(output_node, output_params, &default_params); return TRUE; } @@ -530,7 +531,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu return FALSE; } - LLXUIParser::instance().readXUI(referenced_xml, params, LLUICtrlFactory::getInstance()->getCurFileName()); + parser.readXUI(referenced_xml, params, LLUICtrlFactory::getInstance()->getCurFileName()); // add children using dimensions from referenced xml for consistent layout setShape(params.rect); @@ -540,15 +541,14 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu } // ask LLUICtrlFactory for filename, since xml_filename might be empty - LLXUIParser::instance().readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName()); + parser.readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName()); if (output_node) { Params output_params(params); setupParamsForExport(output_params, parent); output_node->setName(node->getName()->mString); - LLXUIParser::instance().writeXUI( - output_node, output_params, &default_params); + parser.writeXUI(output_node, output_params, &default_params); } params.from_xui = true; @@ -959,3 +959,89 @@ boost::signals2::connection LLPanel::setVisibleCallback( const commit_signal_t:: return mVisibleSignal->connect(cb); } + +static LLFastTimer::DeclareTimer FTM_BUILD_PANELS("Build Panels"); + +//----------------------------------------------------------------------------- +// buildPanel() +//----------------------------------------------------------------------------- +BOOL LLPanel::buildFromFile(const std::string& filename, LLXMLNodePtr output_node, const LLPanel::Params& default_params) +{ + LLFastTimer timer(FTM_BUILD_PANELS); + BOOL didPost = FALSE; + LLXMLNodePtr root; + + //if exporting, only load the language being exported, + //instead of layering localized version on top of english + if (output_node) + { + if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root)) + { + llwarns << "Couldn't parse panel from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; + return didPost; + } + } + else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) + { + llwarns << "Couldn't parse panel from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; + return didPost; + } + + // root must be called panel + if( !root->hasName("panel" ) ) + { + llwarns << "Root node should be named panel in : " << filename << llendl; + return didPost; + } + + lldebugs << "Building panel " << filename << llendl; + + LLUICtrlFactory::instance().pushFileName(filename); + { + if (!getFactoryMap().empty()) + { + sFactoryStack.push_back(&getFactoryMap()); + } + + // for local registry callbacks; define in constructor, referenced in XUI or postBuild + getCommitCallbackRegistrar().pushScope(); + getEnableCallbackRegistrar().pushScope(); + + didPost = initPanelXML(root, NULL, output_node, default_params); + + getCommitCallbackRegistrar().popScope(); + getEnableCallbackRegistrar().popScope(); + + setXMLFilename(filename); + + if (!getFactoryMap().empty()) + { + sFactoryStack.pop_back(); + } + } + LLUICtrlFactory::instance().popFileName(); + return didPost; +} + +//----------------------------------------------------------------------------- +// createFactoryPanel() +//----------------------------------------------------------------------------- +LLPanel* LLPanel::createFactoryPanel(const std::string& name) +{ + std::deque<const LLCallbackMap::map_t*>::iterator itor; + for (itor = sFactoryStack.begin(); itor != sFactoryStack.end(); ++itor) + { + const LLCallbackMap::map_t* factory_map = *itor; + + // Look up this panel's name in the map. + LLCallbackMap::map_const_iter_t iter = factory_map->find( name ); + if (iter != factory_map->end()) + { + // Use the factory to create the panel, instead of using a default LLPanel. + LLPanel *ret = (LLPanel*) iter->second.mCallback( iter->second.mData ); + return ret; + } + } + LLPanel::Params panel_p; + return LLUICtrlFactory::create<LLPanel>(panel_p); +} diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index a7224648c1..c1a1a06f39 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -104,7 +104,10 @@ protected: LLPanel(const LLPanel::Params& params = getDefaultParams()); public: -// LLPanel(const std::string& name, const LLRect& rect = LLRect(), BOOL bordered = TRUE); + BOOL buildFromFile(const std::string &filename, LLXMLNodePtr output_node = NULL, const LLPanel::Params&default_params = getDefaultParams()); + + static LLPanel* createFactoryPanel(const std::string& name); + /*virtual*/ ~LLPanel(); // LLView interface @@ -157,7 +160,7 @@ public: EnableCallbackRegistry::ScopedRegistrar& getEnableCallbackRegistrar() { return mEnableCallbackRegistrar; } void initFromParams(const Params& p); - BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL); + BOOL initPanelXML( LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node, const LLPanel::Params& default_params); bool hasString(const std::string& name); std::string getString(const std::string& name, const LLStringUtil::format_map_t& args) const; @@ -256,6 +259,8 @@ protected: commit_signal_t* mVisibleSignal; // Called when visibility changes, passes new visibility as LLSD() std::string mHelpTopic; // the name of this panel's help topic to display in the Help Viewer + typedef std::deque<const LLCallbackMap::map_t*> factory_stack_t; + static factory_stack_t sFactoryStack; private: BOOL mBgVisible; // any background at all? @@ -285,4 +290,57 @@ extern template class LLPanel* LLView::getChild<class LLPanel>( const std::string& name, BOOL recurse) const; #endif +typedef boost::function<LLPanel* (void)> LLPanelClassCreatorFunc; + +// local static instance for registering a particular panel class + +class LLRegisterPanelClass +: public LLSingleton< LLRegisterPanelClass > +{ +public: + // reigister with either the provided builder, or the generic templated builder + void addPanelClass(const std::string& tag,LLPanelClassCreatorFunc func) + { + mPanelClassesNames[tag] = func; + } + + LLPanel* createPanelClass(const std::string& tag) + { + param_name_map_t::iterator iT = mPanelClassesNames.find(tag); + if(iT == mPanelClassesNames.end()) + return 0; + return iT->second(); + } + template<typename T> + static T* defaultPanelClassBuilder() + { + T* pT = new T(); + return pT; + } + +private: + typedef std::map< std::string, LLPanelClassCreatorFunc> param_name_map_t; + + param_name_map_t mPanelClassesNames; +}; + + +// local static instance for registering a particular panel class +template<typename T> +class LLRegisterPanelClassWrapper +: public LLRegisterPanelClass +{ +public: + // reigister with either the provided builder, or the generic templated builder + LLRegisterPanelClassWrapper(const std::string& tag); +}; + + +template<typename T> +LLRegisterPanelClassWrapper<T>::LLRegisterPanelClassWrapper(const std::string& tag) +{ + LLRegisterPanelClass::instance().addPanelClass(tag,&LLRegisterPanelClass::defaultPanelClassBuilder<T>); +} + + #endif diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index 83c42a5ab8..cc348fdc63 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -100,8 +100,8 @@ LLRadioGroup::LLRadioGroup(const LLRadioGroup::Params& p) void LLRadioGroup::initFromParams(const Params& p) { - for (LLInitParam::ParamIterator<ItemParams>::const_iterator it = p.items().begin(); - it != p.items().end(); + for (LLInitParam::ParamIterator<ItemParams>::const_iterator it = p.items.begin(); + it != p.items.end(); ++it) { LLRadioGroup::ItemParams item_params(*it); diff --git a/indra/llui/llrngwriter.cpp b/indra/llui/llrngwriter.cpp index 50b7bbab90..5e6840d7df 100644 --- a/indra/llui/llrngwriter.cpp +++ b/indra/llui/llrngwriter.cpp @@ -30,10 +30,15 @@ #include "lluicolor.h" #include "lluictrlfactory.h" +static LLInitParam::Parser::parser_read_func_map_t sReadFuncs; +static LLInitParam::Parser::parser_write_func_map_t sWriteFuncs; +static LLInitParam::Parser::parser_inspect_func_map_t sInspectFuncs; + // // LLRNGWriter - writes Relax NG schema files based on a param block // LLRNGWriter::LLRNGWriter() +: Parser(sReadFuncs, sWriteFuncs, sInspectFuncs) { // register various callbacks for inspecting the contents of a param block registerInspectFunc<bool>(boost::bind(&LLRNGWriter::writeAttribute, this, "boolean", _1, _2, _3, _4)); diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 84e438cfb7..7df7c13dc0 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -259,15 +259,15 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) } - for (LLInitParam::ParamIterator<LLScrollListColumn::Params>::const_iterator row_it = p.contents.columns().begin(); - row_it != p.contents.columns().end(); + for (LLInitParam::ParamIterator<LLScrollListColumn::Params>::const_iterator row_it = p.contents.columns.begin(); + row_it != p.contents.columns.end(); ++row_it) { addColumn(*row_it); } - for (LLInitParam::ParamIterator<LLScrollListItem::Params>::const_iterator row_it = p.contents.rows().begin(); - row_it != p.contents.rows().end(); + for (LLInitParam::ParamIterator<LLScrollListItem::Params>::const_iterator row_it = p.contents.rows.begin(); + row_it != p.contents.rows.end(); ++row_it) { addRow(*row_it); @@ -537,23 +537,7 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r setNeedsSort(); break; - case ADD_SORTED: - { - // sort by column 0, in ascending order - std::vector<sort_column_t> single_sort_column; - single_sort_column.push_back(std::make_pair(0, TRUE)); - - mItemList.push_back(item); - std::stable_sort( - mItemList.begin(), - mItemList.end(), - SortScrollListItem(single_sort_column,mSortCallback)); - - // ADD_SORTED just sorts by first column... - // this might not match user sort criteria, so flag list as being in unsorted state - setNeedsSort(); - break; - } + case ADD_DEFAULT: case ADD_BOTTOM: mItemList.push_back(item); setNeedsSort(); @@ -2578,7 +2562,8 @@ BOOL LLScrollListCtrl::canDeselect() const void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) { LLScrollListColumn::Params p; - LLParamSDParser::instance().readSD(column, p); + LLParamSDParser parser; + parser.readSD(column, p); addColumn(p, pos); } @@ -2764,31 +2749,35 @@ LLScrollListColumn* LLScrollListCtrl::getColumn(const std::string& name) return NULL; } - +LLFastTimer::DeclareTimer FTM_ADD_SCROLLLIST_ELEMENT("Add Scroll List Item"); LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& element, EAddPosition pos, void* userdata) { + LLFastTimer _(FTM_ADD_SCROLLLIST_ELEMENT); LLScrollListItem::Params item_params; - LLParamSDParser::instance().readSD(element, item_params); + LLParamSDParser parser; + parser.readSD(element, item_params); item_params.userdata = userdata; return addRow(item_params, pos); } LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_p, EAddPosition pos) { + LLFastTimer _(FTM_ADD_SCROLLLIST_ELEMENT); LLScrollListItem *new_item = new LLScrollListItem(item_p); return addRow(new_item, item_p, pos); } LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLScrollListItem::Params& item_p, EAddPosition pos) { + LLFastTimer _(FTM_ADD_SCROLLLIST_ELEMENT); if (!item_p.validateBlock() || !new_item) return NULL; new_item->setNumColumns(mColumns.size()); // Add any columns we don't already have S32 col_index = 0; - for(LLInitParam::ParamIterator<LLScrollListCell::Params>::const_iterator itor = item_p.columns().begin(); - itor != item_p.columns().end(); + for(LLInitParam::ParamIterator<LLScrollListCell::Params>::const_iterator itor = item_p.columns.begin(); + itor != item_p.columns.end(); ++itor) { LLScrollListCell::Params cell_p = *itor; @@ -2839,7 +2828,7 @@ LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLS col_index++; } - if (item_p.columns().empty()) + if (item_p.columns.empty()) { if (mColumns.empty()) { diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp index 54c3060c4a..f97f80ab6c 100644 --- a/indra/llui/llsdparam.cpp +++ b/indra/llui/llsdparam.cpp @@ -29,49 +29,42 @@ // Project includes #include "llsdparam.h" +#include "llsdutil.h" + +static LLInitParam::Parser::parser_read_func_map_t sReadFuncs; +static LLInitParam::Parser::parser_write_func_map_t sWriteFuncs; +static LLInitParam::Parser::parser_inspect_func_map_t sInspectFuncs; // // LLParamSDParser // LLParamSDParser::LLParamSDParser() +: Parser(sReadFuncs, sWriteFuncs, sInspectFuncs) { using boost::bind; - registerParserFuncs<S32>(bind(&LLParamSDParser::readTypedValue<S32>, this, _1, &LLSD::asInteger), - bind(&LLParamSDParser::writeTypedValue<S32>, this, _1, _2)); - registerParserFuncs<U32>(bind(&LLParamSDParser::readTypedValue<U32>, this, _1, &LLSD::asInteger), - bind(&LLParamSDParser::writeU32Param, this, _1, _2)); - registerParserFuncs<F32>(bind(&LLParamSDParser::readTypedValue<F32>, this, _1, &LLSD::asReal), - bind(&LLParamSDParser::writeTypedValue<F32>, this, _1, _2)); - registerParserFuncs<F64>(bind(&LLParamSDParser::readTypedValue<F64>, this, _1, &LLSD::asReal), - bind(&LLParamSDParser::writeTypedValue<F64>, this, _1, _2)); - registerParserFuncs<bool>(bind(&LLParamSDParser::readTypedValue<F32>, this, _1, &LLSD::asBoolean), - bind(&LLParamSDParser::writeTypedValue<F32>, this, _1, _2)); - registerParserFuncs<std::string>(bind(&LLParamSDParser::readTypedValue<std::string>, this, _1, &LLSD::asString), - bind(&LLParamSDParser::writeTypedValue<std::string>, this, _1, _2)); - registerParserFuncs<LLUUID>(bind(&LLParamSDParser::readTypedValue<LLUUID>, this, _1, &LLSD::asUUID), - bind(&LLParamSDParser::writeTypedValue<LLUUID>, this, _1, _2)); - registerParserFuncs<LLDate>(bind(&LLParamSDParser::readTypedValue<LLDate>, this, _1, &LLSD::asDate), - bind(&LLParamSDParser::writeTypedValue<LLDate>, this, _1, _2)); - registerParserFuncs<LLURI>(bind(&LLParamSDParser::readTypedValue<LLURI>, this, _1, &LLSD::asURI), - bind(&LLParamSDParser::writeTypedValue<LLURI>, this, _1, _2)); - registerParserFuncs<LLSD>(bind(&LLParamSDParser::readSDParam, this, _1), - bind(&LLParamSDParser::writeTypedValue<LLSD>, this, _1, _2)); -} - -bool LLParamSDParser::readSDParam(void* value_ptr) -{ - if (!mCurReadSD) return false; - *((LLSD*)value_ptr) = *mCurReadSD; - return true; + if (sReadFuncs.empty()) + { + registerParserFuncs<S32>(readS32, &LLParamSDParser::writeTypedValue<S32>); + registerParserFuncs<U32>(readU32, &LLParamSDParser::writeU32Param); + registerParserFuncs<F32>(readF32, &LLParamSDParser::writeTypedValue<F32>); + registerParserFuncs<F64>(readF64, &LLParamSDParser::writeTypedValue<F64>); + registerParserFuncs<bool>(readBool, &LLParamSDParser::writeTypedValue<bool>); + registerParserFuncs<std::string>(readString, &LLParamSDParser::writeTypedValue<std::string>); + registerParserFuncs<LLUUID>(readUUID, &LLParamSDParser::writeTypedValue<LLUUID>); + registerParserFuncs<LLDate>(readDate, &LLParamSDParser::writeTypedValue<LLDate>); + registerParserFuncs<LLURI>(readURI, &LLParamSDParser::writeTypedValue<LLURI>); + registerParserFuncs<LLSD>(readSD, &LLParamSDParser::writeTypedValue<LLSD>); + } } // special case handling of U32 due to ambiguous LLSD::assign overload -bool LLParamSDParser::writeU32Param(const void* val_ptr, const parser_t::name_stack_t& name_stack) +bool LLParamSDParser::writeU32Param(LLParamSDParser::parser_t& parser, const void* val_ptr, const parser_t::name_stack_t& name_stack) { - if (!mWriteSD) return false; + LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser); + if (!sdparser.mWriteRootSD) return false; - LLSD* sd_to_write = getSDWriteNode(name_stack); + LLSD* sd_to_write = sdparser.getSDWriteNode(name_stack); if (!sd_to_write) return false; sd_to_write->assign((S32)*((const U32*)val_ptr)); @@ -89,7 +82,8 @@ void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block) { - mWriteSD = &sd; + mNameStack.clear(); + mWriteRootSD = &sd; block.serializeBlock(*this); } @@ -139,6 +133,155 @@ void LLParamSDParser::readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block LLSD* LLParamSDParser::getSDWriteNode(const parser_t::name_stack_t& name_stack) { //TODO: implement nested LLSD writing - return mWriteSD; + LLSD* sd_to_write = mWriteRootSD; + bool new_traversal = false; + for (name_stack_t::const_iterator it = name_stack.begin(), prev_it = mNameStack.begin(); + it != name_stack.end(); + ++it) + { + bool new_array_entry = false; + if (prev_it == mNameStack.end()) + { + new_traversal = true; + } + else + { + if (!new_traversal // have not diverged yet from previous trace + && prev_it->first == it->first // names match + && prev_it->second != it->second) // versions differ + { + // name stacks match, but version numbers differ in last place. + // create a different entry at this point using an LLSD array + new_array_entry = true; + } + if (prev_it->first != it->first // names differ + || prev_it->second != it->second) // versions differ + { + // at this point we have diverged from our last trace + // so any elements referenced here are new + new_traversal = true; + } + } + + LLSD* child_sd = &(*sd_to_write)[it->first]; + + if (child_sd->isArray()) + { + if (new_traversal) + { + // write to new element at end + sd_to_write = &(*child_sd)[child_sd->size()]; + } + else + { + // write to last of existing elements, or first element if empty + sd_to_write = &(*child_sd)[llmax(0, child_sd->size() - 1)]; + } + } + else + { + if (new_array_entry && !child_sd->isArray()) + { + // copy child contents into first element of an array + LLSD new_array = LLSD::emptyArray(); + new_array.append(*child_sd); + // assign array to slot that previously held the single value + *child_sd = new_array; + // return next element in that array + sd_to_write = &((*child_sd)[1]); + } + else + { + sd_to_write = child_sd; + } + } + if (prev_it != mNameStack.end()) + { + ++prev_it; + } + } + mNameStack = name_stack; + + //llinfos << ll_pretty_print_sd(*mWriteRootSD) << llendl; + return sd_to_write; +} + +bool LLParamSDParser::readS32(Parser& parser, void* val_ptr) +{ + LLParamSDParser& self = static_cast<LLParamSDParser&>(parser); + + *((S32*)val_ptr) = self.mCurReadSD->asInteger(); + return true; +} + +bool LLParamSDParser::readU32(Parser& parser, void* val_ptr) +{ + LLParamSDParser& self = static_cast<LLParamSDParser&>(parser); + + *((U32*)val_ptr) = self.mCurReadSD->asInteger(); + return true; } +bool LLParamSDParser::readF32(Parser& parser, void* val_ptr) +{ + LLParamSDParser& self = static_cast<LLParamSDParser&>(parser); + + *((F32*)val_ptr) = self.mCurReadSD->asReal(); + return true; +} + +bool LLParamSDParser::readF64(Parser& parser, void* val_ptr) +{ + LLParamSDParser& self = static_cast<LLParamSDParser&>(parser); + + *((F64*)val_ptr) = self.mCurReadSD->asReal(); + return true; +} + +bool LLParamSDParser::readBool(Parser& parser, void* val_ptr) +{ + LLParamSDParser& self = static_cast<LLParamSDParser&>(parser); + + *((bool*)val_ptr) = self.mCurReadSD->asBoolean(); + return true; +} + +bool LLParamSDParser::readString(Parser& parser, void* val_ptr) +{ + LLParamSDParser& self = static_cast<LLParamSDParser&>(parser); + + *((std::string*)val_ptr) = self.mCurReadSD->asString(); + return true; +} + +bool LLParamSDParser::readUUID(Parser& parser, void* val_ptr) +{ + LLParamSDParser& self = static_cast<LLParamSDParser&>(parser); + + *((LLUUID*)val_ptr) = self.mCurReadSD->asUUID(); + return true; +} + +bool LLParamSDParser::readDate(Parser& parser, void* val_ptr) +{ + LLParamSDParser& self = static_cast<LLParamSDParser&>(parser); + + *((LLDate*)val_ptr) = self.mCurReadSD->asDate(); + return true; +} + +bool LLParamSDParser::readURI(Parser& parser, void* val_ptr) +{ + LLParamSDParser& self = static_cast<LLParamSDParser&>(parser); + + *((LLURI*)val_ptr) = self.mCurReadSD->asURI(); + return true; +} + +bool LLParamSDParser::readSD(Parser& parser, void* val_ptr) +{ + LLParamSDParser& self = static_cast<LLParamSDParser&>(parser); + + *((LLSD*)val_ptr) = *self.mCurReadSD; + return true; +} diff --git a/indra/llui/llsdparam.h b/indra/llui/llsdparam.h index e028fc30c2..97e8b58e49 100644 --- a/indra/llui/llsdparam.h +++ b/indra/llui/llsdparam.h @@ -31,17 +31,14 @@ #include "llinitparam.h" class LLParamSDParser -: public LLInitParam::Parser, - public LLSingleton<LLParamSDParser> +: public LLInitParam::Parser { LOG_CLASS(LLParamSDParser); typedef LLInitParam::Parser parser_t; -protected: - LLParamSDParser(); - friend class LLSingleton<LLParamSDParser>; public: + LLParamSDParser(); void readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent = false); void writeSD(LLSD& sd, const LLInitParam::BaseBlock& block); @@ -51,20 +48,12 @@ private: void readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block); template<typename T> - bool readTypedValue(void* val_ptr, boost::function<T(const LLSD&)> parser_func) - { - if (!mCurReadSD) return false; - - *((T*)val_ptr) = parser_func(*mCurReadSD); - return true; - } - - template<typename T> - bool writeTypedValue(const void* val_ptr, const parser_t::name_stack_t& name_stack) + static bool writeTypedValue(Parser& parser, const void* val_ptr, const parser_t::name_stack_t& name_stack) { - if (!mWriteSD) return false; + LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser); + if (!sdparser.mWriteRootSD) return false; - LLSD* sd_to_write = getSDWriteNode(name_stack); + LLSD* sd_to_write = sdparser.getSDWriteNode(name_stack); if (!sd_to_write) return false; sd_to_write->assign(*((const T*)val_ptr)); @@ -73,12 +62,23 @@ private: LLSD* getSDWriteNode(const parser_t::name_stack_t& name_stack); - bool readSDParam(void* value_ptr); - bool writeU32Param(const void* value_ptr, const parser_t::name_stack_t& name_stack); + static bool writeU32Param(Parser& parser, const void* value_ptr, const parser_t::name_stack_t& name_stack); + + static bool readS32(Parser& parser, void* val_ptr); + static bool readU32(Parser& parser, void* val_ptr); + static bool readF32(Parser& parser, void* val_ptr); + static bool readF64(Parser& parser, void* val_ptr); + static bool readBool(Parser& parser, void* val_ptr); + static bool readString(Parser& parser, void* val_ptr); + static bool readUUID(Parser& parser, void* val_ptr); + static bool readDate(Parser& parser, void* val_ptr); + static bool readURI(Parser& parser, void* val_ptr); + static bool readSD(Parser& parser, void* val_ptr); Parser::name_stack_t mNameStack; const LLSD* mCurReadSD; - LLSD* mWriteSD; + LLSD* mWriteRootSD; + LLSD* mCurWriteSD; }; template<typename T> @@ -88,7 +88,8 @@ class LLSDParamAdapter : public T LLSDParamAdapter() {} LLSDParamAdapter(const LLSD& sd) { - LLParamSDParser::instance().readSD(sd, *this); + LLParamSDParser parser; + parser.readSD(sd, *this); } LLSDParamAdapter(const T& val) diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index e5dfecad54..1fa449a182 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -235,6 +235,7 @@ class LLTextBase public: friend class LLTextSegment; friend class LLNormalTextSegment; + friend class LLUICtrlFactory; struct LineSpacingParams : public LLInitParam::Choice<LineSpacingParams> { diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index b02d3122fe..6390039794 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -78,9 +78,9 @@ BOOL LLToolTipView::handleHover(S32 x, S32 y, MASK mask) LLToolTipMgr& tooltip_mgr = LLToolTipMgr::instance(); - if (x != last_x && y != last_y) + if (x != last_x && y != last_y && !tooltip_mgr.getMouseNearRect().pointInRect(x, y)) { - // allow new tooltips because mouse moved + // allow new tooltips because mouse moved outside of mouse near rect tooltip_mgr.unblockToolTips(); } @@ -276,8 +276,8 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p) if (p.styled_message.isProvided()) { - for (LLInitParam::ParamIterator<LLToolTip::StyledText>::const_iterator text_it = p.styled_message().begin(); - text_it != p.styled_message().end(); + for (LLInitParam::ParamIterator<LLToolTip::StyledText>::const_iterator text_it = p.styled_message.begin(); + text_it != p.styled_message.end(); ++text_it) { mTextBox->appendText(text_it->text(), false, text_it->style); @@ -580,6 +580,7 @@ void LLToolTipMgr::updateToolTipVisibility() if (mToolTip->getVisibleTime() > tooltip_timeout) { hideToolTips(); + unblockToolTips(); } } } diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index d33d8e3178..ff9af21e54 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1796,7 +1796,8 @@ void LLUI::setupPaths() LLXMLNodePtr root; BOOL success = LLXMLNode::parseFile(filename, root, NULL); Paths paths; - LLXUIParser::instance().readXUI(root, paths, filename); + LLXUIParser parser; + parser.readXUI(root, paths, filename); sXUIPaths.clear(); @@ -1805,14 +1806,14 @@ void LLUI::setupPaths() LLStringUtil::format_map_t path_args; path_args["[LANGUAGE]"] = LLUI::getLanguage(); - for (LLInitParam::ParamIterator<Directory>::const_iterator it = paths.directories().begin(), - end_it = paths.directories().end(); + for (LLInitParam::ParamIterator<Directory>::const_iterator it = paths.directories.begin(), + end_it = paths.directories.end(); it != end_it; ++it) { std::string path_val_ui; - for (LLInitParam::ParamIterator<SubDir>::const_iterator subdir_it = it->subdirs().begin(), - subdir_end_it = it->subdirs().end(); + for (LLInitParam::ParamIterator<SubDir>::const_iterator subdir_it = it->subdirs.begin(), + subdir_end_it = it->subdirs.end(); subdir_it != subdir_end_it;) { path_val_ui += subdir_it->value(); diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp index 9891e38f7b..0641f6d175 100644 --- a/indra/llui/lluicolortable.cpp +++ b/indra/llui/lluicolortable.cpp @@ -56,8 +56,8 @@ void LLUIColorTable::insertFromParams(const Params& p, string_color_map_t& table typedef std::map<std::string, std::string> string_string_map_t; string_string_map_t unresolved_refs; - for(LLInitParam::ParamIterator<ColorEntryParams>::const_iterator it = p.color_entries().begin(); - it != p.color_entries().end(); + for(LLInitParam::ParamIterator<ColorEntryParams>::const_iterator it = p.color_entries.begin(); + it != p.color_entries.end(); ++it) { ColorEntryParams color_entry = *it; @@ -237,7 +237,8 @@ void LLUIColorTable::saveUserSettings() const } LLXMLNodePtr output_node = new LLXMLNode("colors", false); - LLXUIParser::instance().writeXUI(output_node, params); + LLXUIParser parser; + parser.writeXUI(output_node, params); if(!output_node->isNull()) { @@ -303,7 +304,8 @@ bool LLUIColorTable::loadFromFilename(const std::string& filename, string_color_ } Params params; - LLXUIParser::instance().readXUI(root, params, filename); + LLXUIParser parser; + parser.readXUI(root, params, filename); if(params.validateBlock()) { diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 15a382660e..5de96f9d48 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -42,7 +42,7 @@ #include "llquaternion.h" // this library includes -#include "llfloater.h" +#include "llpanel.h" LLFastTimer::DeclareTimer FTM_WIDGET_CONSTRUCTION("Widget Construction"); LLFastTimer::DeclareTimer FTM_INIT_FROM_PARAMS("Widget InitFromParams"); @@ -93,10 +93,12 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa std::string filename = std::string("widgets") + gDirUtilp->getDirDelimiter() + widget_tag + ".xml"; LLXMLNodePtr root_node; - if (LLUICtrlFactory::getLayeredXMLNode(filename, root_node)) + std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), filename); + if (!full_filename.empty()) { - LLUICtrlFactory::instance().pushFileName(filename); - LLXUIParser::instance().readXUI(root_node, block, filename); + LLUICtrlFactory::instance().pushFileName(full_filename); + LLSimpleXUIParser parser; + parser.readXUI(full_filename, block); LLUICtrlFactory::instance().popFileName(); } } @@ -171,70 +173,6 @@ bool LLUICtrlFactory::getLocalizedXMLNode(const std::string &xui_filename, LLXML } } -static LLFastTimer::DeclareTimer FTM_BUILD_FLOATERS("Build Floaters"); - -//----------------------------------------------------------------------------- -// buildFloater() -//----------------------------------------------------------------------------- -bool LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filename, LLXMLNodePtr output_node) -{ - LLFastTimer timer(FTM_BUILD_FLOATERS); - LLXMLNodePtr root; - - //if exporting, only load the language being exported, - //instead of layering localized version on top of english - if (output_node) - { - if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root)) - { - llwarns << "Couldn't parse floater from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; - return false; - } - } - else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) - { - llwarns << "Couldn't parse floater from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; - return false; - } - - // root must be called floater - if( !(root->hasName("floater") || root->hasName("multi_floater")) ) - { - llwarns << "Root node should be named floater in: " << filename << llendl; - return false; - } - - bool res = true; - - lldebugs << "Building floater " << filename << llendl; - pushFileName(filename); - { - if (!floaterp->getFactoryMap().empty()) - { - mFactoryStack.push_front(&floaterp->getFactoryMap()); - } - - // for local registry callbacks; define in constructor, referenced in XUI or postBuild - floaterp->getCommitCallbackRegistrar().pushScope(); - floaterp->getEnableCallbackRegistrar().pushScope(); - - res = floaterp->initFloaterXML(root, floaterp->getParent(), filename, output_node); - - floaterp->setXMLFilename(filename); - - floaterp->getCommitCallbackRegistrar().popScope(); - floaterp->getEnableCallbackRegistrar().popScope(); - - if (!floaterp->getFactoryMap().empty()) - { - mFactoryStack.pop_front(); - } - } - popFileName(); - - return res; -} - //----------------------------------------------------------------------------- // saveToXML() //----------------------------------------------------------------------------- @@ -243,69 +181,6 @@ S32 LLUICtrlFactory::saveToXML(LLView* viewp, const std::string& filename) return 0; } -static LLFastTimer::DeclareTimer FTM_BUILD_PANELS("Build Panels"); - -//----------------------------------------------------------------------------- -// buildPanel() -//----------------------------------------------------------------------------- -BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const std::string& filename, LLXMLNodePtr output_node) -{ - LLFastTimer timer(FTM_BUILD_PANELS); - BOOL didPost = FALSE; - LLXMLNodePtr root; - - //if exporting, only load the language being exported, - //instead of layering localized version on top of english - if (output_node) - { - if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root)) - { - llwarns << "Couldn't parse panel from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; - return didPost; - } - } - else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) - { - llwarns << "Couldn't parse panel from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; - return didPost; - } - - // root must be called panel - if( !root->hasName("panel" ) ) - { - llwarns << "Root node should be named panel in : " << filename << llendl; - return didPost; - } - - lldebugs << "Building panel " << filename << llendl; - - pushFileName(filename); - { - if (!panelp->getFactoryMap().empty()) - { - mFactoryStack.push_front(&panelp->getFactoryMap()); - } - - // for local registry callbacks; define in constructor, referenced in XUI or postBuild - panelp->getCommitCallbackRegistrar().pushScope(); - panelp->getEnableCallbackRegistrar().pushScope(); - - didPost = panelp->initPanelXML(root, NULL, output_node); - - panelp->getCommitCallbackRegistrar().popScope(); - panelp->getEnableCallbackRegistrar().popScope(); - - panelp->setXMLFilename(filename); - - if (!panelp->getFactoryMap().empty()) - { - mFactoryStack.pop_front(); - } - } - popFileName(); - return didPost; -} - //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -337,29 +212,6 @@ LLView *LLUICtrlFactory::createFromXML(LLXMLNodePtr node, LLView* parent, const return view; } -//----------------------------------------------------------------------------- -// createFactoryPanel() -//----------------------------------------------------------------------------- -LLPanel* LLUICtrlFactory::createFactoryPanel(const std::string& name) -{ - std::deque<const LLCallbackMap::map_t*>::iterator itor; - for (itor = mFactoryStack.begin(); itor != mFactoryStack.end(); ++itor) - { - const LLCallbackMap::map_t* factory_map = *itor; - - // Look up this panel's name in the map. - LLCallbackMap::map_const_iter_t iter = factory_map->find( name ); - if (iter != factory_map->end()) - { - // Use the factory to create the panel, instead of using a default LLPanel. - LLPanel *ret = (LLPanel*) iter->second.mCallback( iter->second.mData ); - return ret; - } - } - LLPanel::Params panel_p; - return create<LLPanel>(panel_p); -} - std::string LLUICtrlFactory::getCurFileName() { return mFileNames.empty() ? "" : gDirUtilp->getWorkingDir() + gDirUtilp->getDirDelimiter() + mFileNames.back(); @@ -376,36 +228,6 @@ void LLUICtrlFactory::popFileName() mFileNames.pop_back(); } - -//----------------------------------------------------------------------------- - -//static -BOOL LLUICtrlFactory::getAttributeColor(LLXMLNodePtr node, const std::string& name, LLColor4& color) -{ - std::string colorstring; - BOOL res = node->getAttributeString(name.c_str(), colorstring); - if (res) - { - if (LLUIColorTable::instance().colorExists(colorstring)) - { - color.setVec(LLUIColorTable::instance().getColor(colorstring)); - } - else - { - res = FALSE; - } - } - if (!res) - { - res = LLColor4::parseColor(colorstring, &color); - } - if (!res) - { - res = node->getAttributeColor(name.c_str(), color); - } - return res; -} - //static void LLUICtrlFactory::setCtrlParent(LLView* view, LLView* parent, S32 tab_group) { @@ -421,28 +243,22 @@ std::string LLUICtrlFactory::findSkinnedFilename(const std::string& filename) return gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), filename); } -void LLUICtrlFactory::pushFactoryFunctions(const LLCallbackMap::map_t* map) -{ - mFactoryStack.push_back(map); -} - -void LLUICtrlFactory::popFactoryFunctions() -{ - if (!mFactoryStack.empty()) - { - mFactoryStack.pop_back(); - } -} - //static void LLUICtrlFactory::copyName(LLXMLNodePtr src, LLXMLNodePtr dest) { dest->setName(src->getName()->mString); } +template<typename T> +const LLInitParam::BaseBlock& get_empty_param_block() +{ + static typename T::Params params; + return params; +} + // adds a widget and its param block to various registries //static -void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, dummy_widget_creator_func_t creator_func, const std::string& tag) +void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& tag) { // associate parameter block type with template .xml file std::string* existing_tag = LLWidgetNameRegistry::instance().getValue(param_block_type); @@ -462,17 +278,9 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st } } LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type, tag); - // associate widget type with factory function - LLDefaultWidgetRegistry::instance().defaultRegistrar().add(widget_type, creator_func); //FIXME: comment this in when working on schema generation //LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type); - //LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type, &getEmptyParamBlock<T>); -} - -//static -dummy_widget_creator_func_t* LLUICtrlFactory::getDefaultWidgetFunc(const std::type_info* widget_type) -{ - return LLDefaultWidgetRegistry::instance().getValue(widget_type); + //LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type, &get_empty_param_block<T>); } //static diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 58ec5d8387..499b97f52d 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -27,24 +27,13 @@ #ifndef LLUICTRLFACTORY_H #define LLUICTRLFACTORY_H -#include "llcallbackmap.h" +#include "llfasttimer.h" #include "llinitparam.h" #include "llregistry.h" -#include "v4color.h" -#include "llfasttimer.h" - #include "llxuiparser.h" -#include <boost/function.hpp> -#include <iosfwd> -#include <stack> -#include <set> - -class LLPanel; -class LLFloater; class LLView; - // sort functor for typeid maps struct LLCompareTypeID { @@ -85,12 +74,6 @@ class LLWidgetNameRegistry : public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry , LLCompareTypeID> {}; -// lookup factory functions for default widget instances by widget type -typedef LLView* (*dummy_widget_creator_func_t)(const std::string&); -class LLDefaultWidgetRegistry -: public LLRegistrySingleton<const std::type_info*, dummy_widget_creator_func_t, LLDefaultWidgetRegistry, LLCompareTypeID> -{}; - // lookup function for generating empty param block by widget type // this is used for schema generation //typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)(); @@ -157,58 +140,21 @@ public: return ParamDefaults<typename T::Params, 0>::instance().get(); } - bool buildFloater(LLFloater* floaterp, const std::string &filename, LLXMLNodePtr output_node); - BOOL buildPanel(LLPanel* panelp, const std::string &filename, LLXMLNodePtr output_node = NULL); - // Does what you want for LLFloaters and LLPanels // Returns 0 on success S32 saveToXML(LLView* viewp, const std::string& filename); + // filename tracking for debugging info std::string getCurFileName(); void pushFileName(const std::string& name); void popFileName(); - static BOOL getAttributeColor(LLXMLNodePtr node, const std::string& name, LLColor4& color); - - LLPanel* createFactoryPanel(const std::string& name); - - void pushFactoryFunctions(const LLCallbackMap::map_t* map); - void popFactoryFunctions(); - - template<typename T> - static T* createWidget(const typename T::Params& params, LLView* parent = NULL) - { - T* widget = NULL; - - if (!params.validateBlock()) - { - llwarns << getInstance()->getCurFileName() << ": Invalid parameter block for " << typeid(T).name() << llendl; - //return NULL; - } - - { - LLFastTimer timer(FTM_WIDGET_CONSTRUCTION); - widget = new T(params); - } - { - LLFastTimer timer(FTM_INIT_FROM_PARAMS); - widget->initFromParams(params); - } - - if (parent) - { - S32 tab_group = params.tab_group.isProvided() ? params.tab_group() : S32_MAX; - setCtrlParent(widget, parent, tab_group); - } - return widget; - } - template<typename T> static T* create(typename T::Params& params, LLView* parent = NULL) { params.fillFrom(ParamDefaults<typename T::Params, 0>::instance().get()); - T* widget = createWidget<T>(params, parent); + T* widget = createWidgetImpl<T>(params, parent); if (widget) { widget->postBuild(); @@ -266,21 +212,54 @@ fail: template<class T> static T* getDefaultWidget(const std::string& name) { - dummy_widget_creator_func_t* dummy_func = getDefaultWidgetFunc(&typeid(T)); - return dummy_func ? dynamic_cast<T*>((*dummy_func)(name)) : NULL; + typename T::Params widget_params; + widget_params.name = name; + return create<T>(widget_params); } - template <class T> - static LLView* createDefaultWidget(const std::string& name) - { - typename T::Params params; - params.name(name); - - return create<T>(params); - } + static void createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t&, LLXMLNodePtr output_node = NULL); + + static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root); + static bool getLocalizedXMLNode(const std::string &xui_filename, LLXMLNodePtr& root); + +private: + //NOTE: both friend declarations are necessary to keep both gcc and msvc happy + template <typename T> friend class LLChildRegistry; + template <typename T> template <typename U> friend class LLChildRegistry<T>::Register; static void copyName(LLXMLNodePtr src, LLXMLNodePtr dest); + // helper function for adding widget type info to various registries + static void registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& tag); + + static void loadWidgetTemplate(const std::string& widget_tag, LLInitParam::BaseBlock& block); + + template<typename T> + static T* createWidgetImpl(const typename T::Params& params, LLView* parent = NULL) + { + T* widget = NULL; + + if (!params.validateBlock()) + { + llwarns << getInstance()->getCurFileName() << ": Invalid parameter block for " << typeid(T).name() << llendl; + //return NULL; + } + + { LLFastTimer _(FTM_WIDGET_CONSTRUCTION); + widget = new T(params); + } + { LLFastTimer _(FTM_INIT_FROM_PARAMS); + widget->initFromParams(params); + } + + if (parent) + { + S32 tab_group = params.tab_group.isProvided() ? params.tab_group() : S32_MAX; + setCtrlParent(widget, parent, tab_group); + } + return widget; + } + template<typename T> static T* defaultBuilder(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) { @@ -288,7 +267,8 @@ fail: typename T::Params params(getDefaultParams<T>()); - LLXUIParser::instance().readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName()); + LLXUIParser parser; + parser.readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName()); if (output_node) { @@ -298,14 +278,13 @@ fail: // Export only the differences between this any default params typename T::Params default_params(getDefaultParams<T>()); copyName(node, output_node); - LLXUIParser::instance().writeXUI( - output_node, output_params, &default_params); + parser.writeXUI(output_node, output_params, &default_params); } // Apply layout transformations, usually munging rect params.from_xui = true; T::applyXUILayout(params, parent); - T* widget = createWidget<T>(params, parent); + T* widget = createWidgetImpl<T>(params, parent); typedef typename T::child_registry_t registry_t; @@ -320,20 +299,6 @@ fail: return widget; } - static void createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t&, LLXMLNodePtr output_node = NULL); - - static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root); - - static bool getLocalizedXMLNode(const std::string &xui_filename, LLXMLNodePtr& root); - - static void loadWidgetTemplate(const std::string& widget_tag, LLInitParam::BaseBlock& block); - - // helper function for adding widget type info to various registries - static void registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, dummy_widget_creator_func_t creator_func, const std::string& tag); - -private: - // return default widget instance factory func for a given type - static dummy_widget_creator_func_t* getDefaultWidgetFunc(const std::type_info* widget_type); static const std::string* getWidgetTag(const std::type_info* widget_type); @@ -343,20 +308,10 @@ private: // Avoid directly using LLUI and LLDir in the template code static std::string findSkinnedFilename(const std::string& filename); - typedef std::deque<const LLCallbackMap::map_t*> factory_stack_t; - factory_stack_t mFactoryStack; - - LLPanel* mDummyPanel; + class LLPanel* mDummyPanel; std::vector<std::string> mFileNames; }; -template<typename T> -const LLInitParam::BaseBlock& getEmptyParamBlock() -{ - static typename T::Params params; - return params; -} - // this is here to make gcc happy with reference to LLUICtrlFactory template<typename DERIVED> template<typename T> @@ -364,7 +319,7 @@ LLChildRegistry<DERIVED>::Register<T>::Register(const char* tag, LLWidgetCreator : LLChildRegistry<DERIVED>::StaticRegistrar(tag, func.empty() ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder<T> : func) { // add this widget to various registries - LLUICtrlFactory::instance().registerWidget(&typeid(T), &typeid(typename T::Params), &LLUICtrlFactory::createDefaultWidget<T>, tag); + LLUICtrlFactory::instance().registerWidget(&typeid(T), &typeid(typename T::Params), tag); // since registry_t depends on T, do this in line here // TODO: uncomment this for schema generation @@ -372,58 +327,4 @@ LLChildRegistry<DERIVED>::Register<T>::Register(const char* tag, LLWidgetCreator //LLChildRegistryRegistry::instance().defaultRegistrar().add(&typeid(T), registry_t::instance()); } - -typedef boost::function<LLPanel* (void)> LLPanelClassCreatorFunc; - -// local static instance for registering a particular panel class - -class LLRegisterPanelClass -: public LLSingleton< LLRegisterPanelClass > -{ -public: - // reigister with either the provided builder, or the generic templated builder - void addPanelClass(const std::string& tag,LLPanelClassCreatorFunc func) - { - mPanelClassesNames[tag] = func; - } - - LLPanel* createPanelClass(const std::string& tag) - { - param_name_map_t::iterator iT = mPanelClassesNames.find(tag); - if(iT == mPanelClassesNames.end()) - return 0; - return iT->second(); - } - template<typename T> - static T* defaultPanelClassBuilder() - { - T* pT = new T(); - return pT; - } - -private: - typedef std::map< std::string, LLPanelClassCreatorFunc> param_name_map_t; - - param_name_map_t mPanelClassesNames; -}; - - -// local static instance for registering a particular panel class -template<typename T> -class LLRegisterPanelClassWrapper -: public LLRegisterPanelClass -{ -public: - // reigister with either the provided builder, or the generic templated builder - LLRegisterPanelClassWrapper(const std::string& tag); -}; - - -template<typename T> -LLRegisterPanelClassWrapper<T>::LLRegisterPanelClassWrapper(const std::string& tag) -{ - LLRegisterPanelClass::instance().addPanelClass(tag,&LLRegisterPanelClass::defaultPanelClassBuilder<T>); -} - - #endif //LLUICTRLFACTORY_H diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp index 3e9b956ee6..ac69d3bf85 100644 --- a/indra/llui/lluistring.cpp +++ b/indra/llui/lluistring.cpp @@ -34,7 +34,7 @@ LLFastTimer::DeclareTimer FTM_UI_STRING("UI String"); LLUIString::LLUIString(const std::string& instring, const LLStringUtil::format_map_t& args) : mOrig(instring), - mArgs(args) + mArgs(new LLStringUtil::format_map_t(args)) { dirty(); } @@ -48,7 +48,7 @@ void LLUIString::assign(const std::string& s) void LLUIString::setArgList(const LLStringUtil::format_map_t& args) { - mArgs = args; + getArgs() = args; dirty(); } @@ -68,7 +68,7 @@ void LLUIString::setArgs(const LLSD& sd) void LLUIString::setArg(const std::string& key, const std::string& replacement) { - mArgs[key] = replacement; + getArgs()[key] = replacement; dirty(); } @@ -129,14 +129,14 @@ void LLUIString::updateResult() const mResult = mOrig; // get the defailt args + local args - if (mArgs.empty()) + if (!mArgs || mArgs->empty()) { LLStringUtil::format(mResult, LLTrans::getDefaultArgs()); } else { LLStringUtil::format_map_t combined_args = LLTrans::getDefaultArgs(); - combined_args.insert(mArgs.begin(), mArgs.end()); + combined_args.insert(mArgs->begin(), mArgs->end()); LLStringUtil::format(mResult, combined_args); } } @@ -147,3 +147,12 @@ void LLUIString::updateWResult() const mWResult = utf8str_to_wstring(getUpdatedResult()); } + +LLStringUtil::format_map_t& LLUIString::getArgs() +{ + if (!mArgs) + { + mArgs = new LLStringUtil::format_map_t; + } + return *mArgs; +} diff --git a/indra/llui/lluistring.h b/indra/llui/lluistring.h index fc7ac37d99..eff2467bf0 100644 --- a/indra/llui/lluistring.h +++ b/indra/llui/lluistring.h @@ -58,9 +58,9 @@ class LLUIString public: // These methods all perform appropriate argument substitution // and modify mOrig where appropriate - LLUIString() : mNeedsResult(false), mNeedsWResult(false) {} + LLUIString() : mArgs(NULL), mNeedsResult(false), mNeedsWResult(false) {} LLUIString(const std::string& instring, const LLStringUtil::format_map_t& args); - LLUIString(const std::string& instring) { assign(instring); } + LLUIString(const std::string& instring) : mArgs(NULL) { assign(instring); } void assign(const std::string& instring); LLUIString& operator=(const std::string& s) { assign(s); return *this; } @@ -80,7 +80,7 @@ public: S32 length() const { return getUpdatedWResult().size(); } void clear(); - void clearArgs() { mArgs.clear(); } + void clearArgs() { if (mArgs) mArgs->clear(); } // These utility functions are included for text editing. // They do not affect mOrig and do not perform argument substitution @@ -99,11 +99,12 @@ private: // do actual work of updating strings (non-inlined) void updateResult() const; void updateWResult() const; + LLStringUtil::format_map_t& getArgs(); std::string mOrig; mutable std::string mResult; mutable LLWString mWResult; // for displaying - LLStringUtil::format_map_t mArgs; + LLStringUtil::format_map_t* mArgs; // controls lazy evaluation mutable bool mNeedsResult; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index fe5ef269a9..3fa86bf0ca 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -102,11 +102,7 @@ LLView::Params::Params() left_pad("left_pad"), left_delta("left_delta", S32_MAX), from_xui("from_xui", false), - user_resize("user_resize"), - auto_resize("auto_resize"), needs_translate("translate"), - min_width("min_width"), - max_width("max_width"), xmlns("xmlns"), xmlns_xsi("xmlns:xsi"), xsi_schemaLocation("xsi:schemaLocation"), @@ -218,7 +214,7 @@ void LLView::setUseBoundingRect( BOOL use_bounding_rect ) } } -BOOL LLView::getUseBoundingRect() +BOOL LLView::getUseBoundingRect() const { return mUseBoundingRect; } @@ -1370,12 +1366,12 @@ void LLView::drawDebugRect() // drawing solids requires texturing be disabled gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - if (mUseBoundingRect) + if (getUseBoundingRect()) { LLUI::translate((F32)mBoundingRect.mLeft - (F32)mRect.mLeft, (F32)mBoundingRect.mBottom - (F32)mRect.mBottom, 0.f); } - LLRect debug_rect = mUseBoundingRect ? mBoundingRect : mRect; + LLRect debug_rect = getUseBoundingRect() ? mBoundingRect : mRect; // draw red rectangle for the border LLColor4 border_color(0.25f, 0.25f, 0.25f, 1.f); @@ -1573,7 +1569,7 @@ void LLView::updateBoundingRect() LLRect cur_rect = mBoundingRect; - if (mUseBoundingRect) + if (getUseBoundingRect()) { mBoundingRect = calcBoundingRect(); } @@ -1583,7 +1579,7 @@ void LLView::updateBoundingRect() } // give parent view a chance to resize, in case we just moved, for example - if (getParent() && getParent()->mUseBoundingRect) + if (getParent() && getParent()->getUseBoundingRect()) { getParent()->updateBoundingRect(); } @@ -1607,7 +1603,7 @@ LLRect LLView::calcScreenBoundingRect() const { LLRect screen_rect; // get bounding rect, if used - LLRect bounding_rect = mUseBoundingRect ? mBoundingRect : mRect; + LLRect bounding_rect = getUseBoundingRect() ? mBoundingRect : mRect; // convert to local coordinates, as defined by mRect bounding_rect.translate(-mRect.mLeft, -mRect.mBottom); @@ -1692,7 +1688,9 @@ LLView* LLView::getChildView(const std::string& name, BOOL recurse) const child = getDefaultWidget<LLView>(name); if (!child) { - child = LLUICtrlFactory::createDefaultWidget<LLView>(name); + LLView::Params view_params; + view_params.name = name; + child = LLUICtrlFactory::create<LLView>(view_params); } } return child; @@ -1736,14 +1734,14 @@ LLView* LLView::findChildView(const std::string& name, BOOL recurse) const BOOL LLView::parentPointInView(S32 x, S32 y, EHitTestType type) const { - return (mUseBoundingRect && type == HIT_TEST_USE_BOUNDING_RECT) + return (getUseBoundingRect() && type == HIT_TEST_USE_BOUNDING_RECT) ? mBoundingRect.pointInRect( x, y ) : mRect.pointInRect( x, y ); } BOOL LLView::pointInView(S32 x, S32 y, EHitTestType type) const { - return (mUseBoundingRect && type == HIT_TEST_USE_BOUNDING_RECT) + return (getUseBoundingRect() && type == HIT_TEST_USE_BOUNDING_RECT) ? mBoundingRect.pointInRect( x + mRect.mLeft, y + mRect.mBottom ) : mRect.localPointInRect( x, y ); } diff --git a/indra/llui/llview.h b/indra/llui/llview.h index f7175112bf..33d345beff 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -128,26 +128,22 @@ public: Optional<std::string> layout; Optional<LLRect> rect; + // Historical bottom-left layout used bottom_delta and left_delta // for relative positioning. New layout "topleft" prefers specifying // based on top edge. - Optional<S32> bottom_delta, // deprecated - top_pad, // from last bottom to my top - top_delta, // from last top to my top - left_pad, // from last right to my left - left_delta; // from last left to my left - - // these are nested attributes for LLLayoutPanel + Optional<S32> bottom_delta, // from last bottom to my bottom + top_pad, // from last bottom to my top + top_delta, // from last top to my top + left_pad, // from last right to my left + left_delta; // from last left to my left + //FIXME: get parent context involved in parsing traversal - Ignored user_resize, - auto_resize, - needs_translate, - min_width, - max_width, - xmlns, - xmlns_xsi, - xsi_schemaLocation, - xsi_type; + Ignored needs_translate, // cue for translation tools + xmlns, // xml namespace + xmlns_xsi, // xml namespace + xsi_schemaLocation, // xml schema + xsi_type; // xml schema type Params(); }; @@ -238,7 +234,7 @@ public: void setSoundFlags(U8 flags) { mSoundFlags = flags; } void setName(std::string name) { mName = name; } void setUseBoundingRect( BOOL use_bounding_rect ); - BOOL getUseBoundingRect(); + BOOL getUseBoundingRect() const; ECursorType getHoverCursor() { return mHoverCursor; } @@ -277,6 +273,11 @@ public: BOOL focusNextRoot(); BOOL focusPrevRoot(); + // Normally we want the app menus to get priority on accelerated keys + // However, sometimes we want to give specific views a first chance + // iat handling them. (eg. the script editor) + virtual bool hasAccelerators() const { return false; }; + // delete all children. Override this function if you need to // perform any extra clean up such as cached pointers to selected // children, etc. diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp index 6ccac45569..a1c6669b97 100644 --- a/indra/llvfs/lldir_linux.cpp +++ b/indra/llvfs/lldir_linux.cpp @@ -93,7 +93,7 @@ LLDir_Linux::LLDir_Linux() #else mAppRODataDir = tmp_str; #endif - U32 indra_pos = mExecutableDir.find("/indra"); + std::string::size_type indra_pos = mExecutableDir.find("/indra"); if (indra_pos != std::string::npos) { // ...we're in a dev checkout diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp index 8b1a2ddd3c..52d864e26f 100644 --- a/indra/llvfs/lldir_win32.cpp +++ b/indra/llvfs/lldir_win32.cpp @@ -116,10 +116,6 @@ LLDir_Win32::LLDir_Win32() mExecutableDir = utf16str_to_utf8str(llutf16string(w_str)); #endif - mAppRODataDir = "."; - - mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; - if (mExecutableDir.find("indra") == std::string::npos) { // Running from installed directory. Make sure current @@ -129,8 +125,12 @@ LLDir_Win32::LLDir_Win32() GetCurrentDirectory(MAX_PATH, w_str); mWorkingDir = utf16str_to_utf8str(llutf16string(w_str)); } + mAppRODataDir = mWorkingDir; + llinfos << "mAppRODataDir = " << mAppRODataDir << llendl; + mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; + // Build the default cache directory mDefaultCacheDir = buildSLOSCacheDir(); diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp index 0b324a10c9..2c92539387 100644 --- a/indra/llxuixml/llinitparam.cpp +++ b/indra/llxuixml/llinitparam.cpp @@ -68,7 +68,6 @@ namespace LLInitParam void BlockDescriptor::aggregateBlockData(BlockDescriptor& src_block_data) { mNamedParams.insert(src_block_data.mNamedParams.begin(), src_block_data.mNamedParams.end()); - mSynonyms.insert(src_block_data.mSynonyms.begin(), src_block_data.mSynonyms.end()); std::copy(src_block_data.mUnnamedParams.begin(), src_block_data.mUnnamedParams.end(), std::back_inserter(mUnnamedParams)); std::copy(src_block_data.mValidationList.begin(), src_block_data.mValidationList.end(), std::back_inserter(mValidationList)); std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams)); @@ -78,8 +77,7 @@ namespace LLInitParam // BaseBlock // BaseBlock::BaseBlock() - : mChangeVersion(0), - mBlockDescriptor(NULL) + : mChangeVersion(0) {} BaseBlock::~BaseBlock() @@ -88,8 +86,6 @@ namespace LLInitParam // called by each derived class in least to most derived order void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size) { - mBlockDescriptor = &descriptor; - descriptor.mCurrentBlockPtr = this; descriptor.mMaxParamOffset = block_size; @@ -182,7 +178,7 @@ namespace LLInitParam param_handle_t param_handle = it->second->mParamHandle; const Param* param = getParamFromHandle(param_handle); ParamDescriptor::serialize_func_t serialize_func = it->second->mSerializeFunc; - if (serialize_func) + if (serialize_func && param->anyProvided()) { // Ensure this param has not already been serialized // Prevents <rect> from being serialized as its own tag. @@ -274,22 +270,6 @@ namespace LLInitParam } } - for(BlockDescriptor::param_map_t::const_iterator it = block_data.mSynonyms.begin(); - it != block_data.mSynonyms.end(); - ++it) - { - param_handle_t param_handle = it->second->mParamHandle; - const Param* param = getParamFromHandle(param_handle); - ParamDescriptor::inspect_func_t inspect_func = it->second->mInspectFunc; - if (inspect_func) - { - // use existing serial number for param - name_stack.push_back(std::make_pair(it->first, it->second->mGeneration)); - inspect_func(*param, parser, name_stack, it->second->mMinCount, it->second->mMaxCount); - name_stack.pop_back(); - } - } - return true; } @@ -311,22 +291,9 @@ namespace LLInitParam // find pointer to member parameter from offset table paramp = getParamFromHandle(found_it->second->mParamHandle); deserialize_func = found_it->second->mDeserializeFunc; - } - else - { - BlockDescriptor::param_map_t::iterator found_it = block_data.mSynonyms.find(top_name); - if (found_it != block_data.mSynonyms.end()) - { - // find pointer to member parameter from offset table - paramp = getParamFromHandle(found_it->second->mParamHandle); - deserialize_func = found_it->second->mDeserializeFunc; - } - } - Parser::name_stack_range_t new_name_stack(name_stack.first, name_stack.second); - ++new_name_stack.first; - if (deserialize_func) - { + Parser::name_stack_range_t new_name_stack(name_stack.first, name_stack.second); + ++new_name_stack.first; return deserialize_func(*paramp, p, new_name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second); } } @@ -401,7 +368,7 @@ namespace LLInitParam } else { - block_data.mSynonyms[synonym] = param_descriptor; + block_data.mNamedParams[synonym] = param_descriptor; } } } @@ -426,14 +393,6 @@ namespace LLInitParam } } - for (BlockDescriptor::param_map_t::const_iterator it = block_data.mSynonyms.begin(); it != block_data.mSynonyms.end(); ++it) - { - if (it->second->mParamHandle == handle) - { - return it->first; - } - } - return LLStringUtil::null; } diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index 869b0c2cd6..8cb5bd80fc 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -34,6 +34,7 @@ f * @file llinitparam.h #include <boost/function.hpp> #include <boost/bind.hpp> #include <boost/type_traits/is_convertible.hpp> +#include <boost/unordered_map.hpp> #include "llregistry.h" #include "llmemory.h" @@ -196,36 +197,39 @@ namespace LLInitParam typedef std::pair<name_stack_t::const_iterator, name_stack_t::const_iterator> name_stack_range_t; typedef std::vector<std::string> possible_values_t; - typedef boost::function<bool (void*)> parser_read_func_t; - typedef boost::function<bool (const void*, const name_stack_t&)> parser_write_func_t; + typedef bool (*parser_read_func_t)(Parser& parser, void* output); + typedef bool (*parser_write_func_t)(Parser& parser, const void*, const name_stack_t&); typedef boost::function<void (const name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t; typedef std::map<const std::type_info*, parser_read_func_t, CompareTypeID> parser_read_func_map_t; typedef std::map<const std::type_info*, parser_write_func_t, CompareTypeID> parser_write_func_map_t; typedef std::map<const std::type_info*, parser_inspect_func_t, CompareTypeID> parser_inspect_func_map_t; - Parser() + Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map) : mParseSilently(false), - mParseGeneration(0) + mParseGeneration(0), + mParserReadFuncs(&read_map), + mParserWriteFuncs(&write_map), + mParserInspectFuncs(&inspect_map) {} virtual ~Parser(); template <typename T> bool readValue(T& param) { - parser_read_func_map_t::iterator found_it = mParserReadFuncs.find(&typeid(T)); - if (found_it != mParserReadFuncs.end()) + parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T)); + if (found_it != mParserReadFuncs->end()) { - return found_it->second((void*)¶m); + return found_it->second(*this, (void*)¶m); } return false; } template <typename T> bool writeValue(const T& param, const name_stack_t& name_stack) { - parser_write_func_map_t::iterator found_it = mParserWriteFuncs.find(&typeid(T)); - if (found_it != mParserWriteFuncs.end()) + parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T)); + if (found_it != mParserWriteFuncs->end()) { - return found_it->second((const void*)¶m, name_stack); + return found_it->second(*this, (const void*)¶m, name_stack); } return false; } @@ -233,8 +237,8 @@ namespace LLInitParam // dispatch inspection to registered inspection functions, for each parameter in a param block template <typename T> bool inspectValue(const name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values) { - parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs.find(&typeid(T)); - if (found_it != mParserInspectFuncs.end()) + parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs->find(&typeid(T)); + if (found_it != mParserInspectFuncs->end()) { found_it->second(name_stack, min_count, max_count, possible_values); return true; @@ -246,7 +250,6 @@ namespace LLInitParam virtual void parserWarning(const std::string& message); virtual void parserError(const std::string& message); void setParseSilently(bool silent) { mParseSilently = silent; } - bool getParseSilently() { return mParseSilently; } S32 getParseGeneration() { return mParseGeneration; } S32 newParseGeneration() { return ++mParseGeneration; } @@ -254,24 +257,24 @@ namespace LLInitParam protected: template <typename T> - void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func) + void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func = NULL) { - mParserReadFuncs.insert(std::make_pair(&typeid(T), read_func)); - mParserWriteFuncs.insert(std::make_pair(&typeid(T), write_func)); + mParserReadFuncs->insert(std::make_pair(&typeid(T), read_func)); + mParserWriteFuncs->insert(std::make_pair(&typeid(T), write_func)); } template <typename T> void registerInspectFunc(parser_inspect_func_t inspect_func) { - mParserInspectFuncs.insert(std::make_pair(&typeid(T), inspect_func)); + mParserInspectFuncs->insert(std::make_pair(&typeid(T), inspect_func)); } bool mParseSilently; private: - parser_read_func_map_t mParserReadFuncs; - parser_write_func_map_t mParserWriteFuncs; - parser_inspect_func_map_t mParserInspectFuncs; + parser_read_func_map_t* mParserReadFuncs; + parser_write_func_map_t* mParserWriteFuncs; + parser_inspect_func_map_t* mParserInspectFuncs; S32 mParseGeneration; }; @@ -284,7 +287,7 @@ namespace LLInitParam void setProvided(bool is_provided) { mIsProvided = is_provided; } protected: - bool getProvided() const { return mIsProvided; } + bool anyProvided() const { return mIsProvided; } Param(class BaseBlock* enclosing_block); @@ -380,14 +383,13 @@ namespace LLInitParam void aggregateBlockData(BlockDescriptor& src_block_data); public: - typedef std::map<const std::string, ParamDescriptor*> param_map_t; // references param descriptors stored in mAllParams + typedef boost::unordered_map<const std::string, ParamDescriptor*> param_map_t; // references param descriptors stored in mAllParams typedef std::vector<ParamDescriptor*> param_list_t; typedef std::list<ParamDescriptor> all_params_list_t;// references param descriptors stored in mAllParams typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t; param_map_t mNamedParams; // parameters with associated names - param_map_t mSynonyms; // parameters with alternate names param_list_t mUnnamedParams; // parameters with_out_ associated names param_validation_list_t mValidationList; // parameters that must be validated all_params_list_t mAllParams; // all parameters, owns descriptors @@ -473,8 +475,8 @@ namespace LLInitParam bool serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const; bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t()) const; - const BlockDescriptor& mostDerivedBlockDescriptor() const { return *mBlockDescriptor; } - BlockDescriptor& mostDerivedBlockDescriptor() { return *mBlockDescriptor; } + virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } + virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); } // take all provided params from other and apply to self bool overwriteFrom(const BaseBlock& other) @@ -499,8 +501,6 @@ namespace LLInitParam // can be updated in getters mutable S32 mChangeVersion; - BlockDescriptor* mBlockDescriptor; // most derived block descriptor - static BlockDescriptor& selfBlockDescriptor() { static BlockDescriptor sBlockDescriptor; @@ -568,7 +568,7 @@ namespace LLInitParam mData.mValue = value; } - bool isProvided() const { return Param::getProvided(); } + bool isProvided() const { return Param::anyProvided(); } static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) { @@ -576,7 +576,7 @@ namespace LLInitParam // no further names in stack, attempt to parse value now if (name_stack.first == name_stack.second) { - if (parser.readValue<T>(typed_param.mData.mValue)) + if (parser.readValue(typed_param.mData.mValue)) { typed_param.mData.clearKey(); typed_param.setProvided(true); @@ -589,7 +589,7 @@ namespace LLInitParam { // try to parse a known named value std::string name; - if (parser.readValue<std::string>(name)) + if (parser.readValue(name)) { // try to parse a per type named value if (NAME_VALUE_LOOKUP::get(name, typed_param.mData.mValue)) @@ -624,7 +624,7 @@ namespace LLInitParam { if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key)) { - if (!parser.writeValue<std::string>(key, name_stack)) + if (!parser.writeValue(key, name_stack)) { return; } @@ -632,7 +632,7 @@ namespace LLInitParam } // then try to serialize value directly else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), static_cast<const self_t*>(diff_param)->get())) { - if (!parser.writeValue<T>(typed_param.mData.mValue, name_stack)) + if (!parser.writeValue(typed_param.mData.mValue, name_stack)) { return; } @@ -745,7 +745,7 @@ namespace LLInitParam { // try to parse a known named value std::string name; - if (parser.readValue<std::string>(name)) + if (parser.readValue(name)) { // try to parse a per type named value if (NAME_VALUE_LOOKUP::get(name, typed_param)) @@ -772,7 +772,7 @@ namespace LLInitParam std::string key = typed_param.mData.getKey(); if (!key.empty() && typed_param.mData.mKeyVersion == typed_param.getLastChangeVersion()) { - if (!parser.writeValue<std::string>(key, name_stack)) + if (!parser.writeValue(key, name_stack)) { return; } @@ -795,13 +795,13 @@ namespace LLInitParam bool isProvided() const { // only validate block when it hasn't already passed validation and user has supplied *some* value - if (Param::getProvided() && mData.mValidatedVersion < T::getLastChangeVersion()) + if (Param::anyProvided() && mData.mValidatedVersion < T::getLastChangeVersion()) { // a sub-block is "provided" when it has been filled in enough to be valid mData.mValidated = T::validateBlock(false); mData.mValidatedVersion = T::getLastChangeVersion(); } - return Param::getProvided() && mData.mValidated; + return Param::anyProvided() && mData.mValidated; } // assign block contents to this param-that-is-a-block @@ -852,7 +852,7 @@ namespace LLInitParam { const self_t& src_typed_param = static_cast<const self_t&>(src); self_t& dst_typed_param = static_cast<self_t&>(dst); - if (dst_typed_param.T::merge(T::selfBlockDescriptor(), src_typed_param, overwrite || !dst_typed_param.isProvided())) + if (dst_typed_param.T::merge(T::selfBlockDescriptor(), src_typed_param, overwrite)) { dst_typed_param.mData.clearKey(); return true; @@ -909,7 +909,7 @@ namespace LLInitParam } } - bool isProvided() const { return Param::getProvided(); } + bool isProvided() const { return Param::anyProvided(); } static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) { @@ -919,7 +919,7 @@ namespace LLInitParam if (name_stack.first == name_stack.second) { // attempt to read value directly - if (parser.readValue<value_t>(value)) + if (parser.readValue(value)) { typed_param.mValues.push_back(value); // save an empty name/value key as a placeholder @@ -934,7 +934,7 @@ namespace LLInitParam { // try to parse a known named value std::string name; - if (parser.readValue<std::string>(name)) + if (parser.readValue(name)) { // try to parse a per type named value if (NAME_VALUE_LOOKUP::get(name, typed_param.mValues)) @@ -958,7 +958,7 @@ namespace LLInitParam const self_t& typed_param = static_cast<const self_t&>(param); if (!typed_param.isProvided() || name_stack.empty()) return; - typename container_t::const_iterator it = typed_param.mValues.begin(); + const_iterator it = typed_param.mValues.begin(); for (typename std::vector<key_cache_t>::const_iterator key_it = typed_param.mCachedKeys.begin(); it != typed_param.mValues.end(); ++key_it, ++it) @@ -968,13 +968,13 @@ namespace LLInitParam if(!key.empty()) { - if(!parser.writeValue<std::string>(key, name_stack)) + if(!parser.writeValue(key, name_stack)) { return; } } // not parse via name values, write out value directly - else if (!parser.writeValue<VALUE_TYPE>(*it, name_stack)) + else if (!parser.writeValue(*it, name_stack)) { return; } @@ -1025,8 +1025,15 @@ namespace LLInitParam // implicit conversion operator value_assignment_t() const { return self_t::get(); } - // explicit conversion - value_assignment_t operator()() const { return get(); } + + typedef typename container_t::iterator iterator; + typedef typename container_t::const_iterator const_iterator; + iterator begin() { return mValues.begin(); } + iterator end() { return mValues.end(); } + const_iterator begin() const { return mValues.begin(); } + const_iterator end() const { return mValues.end(); } + bool empty() const { return mValues.empty(); } + size_t size() const { return mValues.size(); } U32 numValidElements() const { @@ -1092,7 +1099,7 @@ namespace LLInitParam } } - bool isProvided() const { return Param::getProvided(); } + bool isProvided() const { return Param::anyProvided(); } value_ref_t operator[](S32 index) { return mValues[index]; } value_const_ref_t operator[](S32 index) const { return mValues[index]; } @@ -1100,32 +1107,41 @@ namespace LLInitParam static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) { self_t& typed_param = static_cast<self_t&>(param); + bool new_value = false; if (generation != typed_param.mLastParamGeneration || typed_param.mValues.empty()) { + new_value = true; typed_param.mValues.push_back(value_t()); typed_param.mCachedKeys.push_back(Data()); - typed_param.enclosingBlock().setLastChangedParam(param, true); - typed_param.mLastParamGeneration = generation; } - value_t& value = typed_param.mValues.back(); + value_ref_t value = typed_param.mValues.back(); // attempt to parse block... if(value.deserializeBlock(parser, name_stack)) { + if (new_value) + { // successfully parsed new value, let's keep it + typed_param.mLastParamGeneration = generation; + } + typed_param.enclosingBlock().setLastChangedParam(param, true); typed_param.setProvided(true); return true; } - - if(!NAME_VALUE_LOOKUP::empty()) + else if(!NAME_VALUE_LOOKUP::empty()) { // try to parse a known named value std::string name; - if (parser.readValue<std::string>(name)) + if (parser.readValue(name)) { // try to parse a per type named value if (NAME_VALUE_LOOKUP::get(name, value)) { + if (new_value) + { // successfully parsed new value, let's keep it + typed_param.mLastParamGeneration = generation; + } + typed_param.mCachedKeys.back().setKey(name); typed_param.mCachedKeys.back().mKeyVersion = value.getLastChangeVersion(); typed_param.enclosingBlock().setLastChangedParam(param, true); @@ -1136,6 +1152,12 @@ namespace LLInitParam } } + if (new_value) + { // failed to parse new value, pop it off + typed_param.mValues.pop_back(); + typed_param.mCachedKeys.pop_back(); + } + return false; } @@ -1144,7 +1166,7 @@ namespace LLInitParam const self_t& typed_param = static_cast<const self_t&>(param); if (!typed_param.isProvided() || name_stack.empty()) return; - typename container_t::const_iterator it = typed_param.mValues.begin(); + const_iterator it = typed_param.mValues.begin(); for (typename std::vector<Data>::const_iterator key_it = typed_param.mCachedKeys.begin(); it != typed_param.mValues.end(); ++key_it, ++it) @@ -1154,7 +1176,7 @@ namespace LLInitParam std::string key = key_it->getKey(); if (!key.empty() && key_it->mKeyVersion == it->getLastChangeVersion()) { - if(!parser.writeValue<std::string>(key, name_stack)) + if(!parser.writeValue(key, name_stack)) { return; } @@ -1208,13 +1230,20 @@ namespace LLInitParam // implicit conversion operator value_assignment_t() const { return self_t::get(); } - // explicit conversion - value_assignment_t operator()() const { return get(); } + + typedef typename container_t::iterator iterator; + typedef typename container_t::const_iterator const_iterator; + iterator begin() { return mValues.begin(); } + iterator end() { return mValues.end(); } + const_iterator begin() const { return mValues.begin(); } + const_iterator end() const { return mValues.end(); } + bool empty() const { return mValues.empty(); } + size_t size() const { return mValues.size(); } U32 numValidElements() const { U32 count = 0; - for (typename container_t::const_iterator it = mValues.begin(); + for (const_iterator it = mValues.begin(); it != mValues.end(); ++it) { @@ -1306,6 +1335,9 @@ namespace LLInitParam BaseBlock::setLastChangedParam(last_param, user_provided); } + virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } + virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); } + protected: Choice() : mCurChoice(0) @@ -1415,6 +1447,10 @@ namespace LLInitParam { return BaseBlock::merge(selfBlockDescriptor(), other, false); } + + virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } + virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); } + protected: Block() { @@ -1494,15 +1530,13 @@ namespace LLInitParam typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP> self_t; typedef typename super_t::container_t container_t; typedef typename super_t::value_assignment_t value_assignment_t; - typedef typename container_t::iterator iterator; - typedef typename container_t::const_iterator const_iterator; + typedef typename super_t::iterator iterator; + typedef typename super_t::const_iterator const_iterator; explicit Multiple(const char* name = "", value_assignment_t val = DefaultInitializer<container_t>::get()) : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, RANGE::minCount(), RANGE::maxCount()) {} - using super_t::operator(); - Multiple& operator=(value_assignment_t val) { set(val); @@ -1612,7 +1646,7 @@ namespace LLInitParam // type to apply parse direct value T if (name_stack.first == name_stack.second) { - if(parser.readValue<T>(typed_param.mData.mValue)) + if(parser.readValue(typed_param.mData.mValue)) { typed_param.enclosingBlock().setLastChangedParam(param, true); typed_param.setProvided(true); @@ -1627,7 +1661,7 @@ namespace LLInitParam { // try to parse a known named value std::string name; - if (parser.readValue<std::string>(name)) + if (parser.readValue(name)) { // try to parse a per type named value if (TypeValues<T>::get(name, typed_param.mData.mValue)) @@ -1669,7 +1703,7 @@ namespace LLInitParam { if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key)) { - if (!parser.writeValue<std::string>(key, name_stack)) + if (!parser.writeValue(key, name_stack)) { return; } @@ -1679,7 +1713,7 @@ namespace LLInitParam else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), (static_cast<const self_t*>(diff_param))->get())) { - if (parser.writeValue<T>(typed_param.mData.mValue, name_stack)) + if (parser.writeValue(typed_param.mData.mValue, name_stack)) { return; } @@ -1712,7 +1746,7 @@ namespace LLInitParam bool isProvided() const { - if (!Param::getProvided()) return false; + if (!Param::anyProvided()) return false; // block has an updated parameter // if cached value is stale, regenerate from params @@ -1779,7 +1813,7 @@ namespace LLInitParam value_assignment_t get() const { // if some parameters were provided, issue warnings on invalid blocks - if (Param::getProvided() && (mData.mValueAge == OLDER_THAN_BLOCK)) + if (Param::anyProvided() && (mData.mValueAge == OLDER_THAN_BLOCK)) { // go ahead and issue warnings at this point if any param is invalid if(block_t::validateBlock(true)) diff --git a/indra/llxuixml/llregistry.h b/indra/llxuixml/llregistry.h index ee119b9ebc..eee9933739 100644 --- a/indra/llxuixml/llregistry.h +++ b/indra/llxuixml/llregistry.h @@ -70,6 +70,11 @@ public: mMap.erase(key); } + void replace(ref_const_key_t key, ref_const_value_t value) + { + mMap[key] = value; + } + typename registry_map_t::const_iterator beginItems() const { return mMap.begin(); diff --git a/indra/llxuixml/lltrans.cpp b/indra/llxuixml/lltrans.cpp index 01e13864b6..11127a53f5 100644 --- a/indra/llxuixml/lltrans.cpp +++ b/indra/llxuixml/lltrans.cpp @@ -66,7 +66,8 @@ bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set<std::string>& defa } StringTable string_table; - LLXUIParser::instance().readXUI(root, string_table, xml_filename); + LLXUIParser parser; + parser.readXUI(root, string_table, xml_filename); if (!string_table.validateBlock()) { @@ -77,8 +78,8 @@ bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set<std::string>& defa sStringTemplates.clear(); sDefaultArgs.clear(); - for(LLInitParam::ParamIterator<StringDef>::const_iterator it = string_table.strings().begin(); - it != string_table.strings().end(); + for(LLInitParam::ParamIterator<StringDef>::const_iterator it = string_table.strings.begin(); + it != string_table.strings.end(); ++it) { LLTransTemplate xml_template(it->name, it->value); @@ -109,7 +110,8 @@ bool LLTrans::parseLanguageStrings(LLXMLNodePtr &root) } StringTable string_table; - LLXUIParser::instance().readXUI(root, string_table, xml_filename); + LLXUIParser parser; + parser.readXUI(root, string_table, xml_filename); if (!string_table.validateBlock()) { @@ -117,8 +119,8 @@ bool LLTrans::parseLanguageStrings(LLXMLNodePtr &root) return false; } - for(LLInitParam::ParamIterator<StringDef>::const_iterator it = string_table.strings().begin(); - it != string_table.strings().end(); + for(LLInitParam::ParamIterator<StringDef>::const_iterator it = string_table.strings.begin(); + it != string_table.strings.end(); ++it) { // share the same map with parseStrings() so we can search the strings using the same getString() function.- angela diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index 8469debd3e..e1ad9a5c71 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -29,17 +29,28 @@ #include "llxuiparser.h" #include "llxmlnode.h" +#include "expat/expat.h" #include <fstream> #include <boost/tokenizer.hpp> +//#include <boost/spirit/include/qi.hpp> +#include <boost/spirit/include/classic_core.hpp> #include "lluicolor.h" +using namespace BOOST_SPIRIT_CLASSIC_NS; + const S32 MAX_STRING_ATTRIBUTE_SIZE = 40; +static LLInitParam::Parser::parser_read_func_map_t sXSDReadFuncs; +static LLInitParam::Parser::parser_write_func_map_t sXSDWriteFuncs; +static LLInitParam::Parser::parser_inspect_func_map_t sXSDInspectFuncs; + + // // LLXSDWriter // LLXSDWriter::LLXSDWriter() +: Parser(sXSDReadFuncs, sXSDWriteFuncs, sXSDInspectFuncs) { registerInspectFunc<bool>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:boolean", _1, _2, _3, _4)); registerInspectFunc<std::string>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); @@ -357,41 +368,35 @@ void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& p fclose(xsd_file); } +static LLInitParam::Parser::parser_read_func_map_t sXUIReadFuncs; +static LLInitParam::Parser::parser_write_func_map_t sXUIWriteFuncs; +static LLInitParam::Parser::parser_inspect_func_map_t sXUIInspectFuncs; + // // LLXUIParser // LLXUIParser::LLXUIParser() -: mLastWriteGeneration(-1), +: Parser(sXUIReadFuncs, sXUIWriteFuncs, sXUIInspectFuncs), + mLastWriteGeneration(-1), mCurReadDepth(0) { - registerParserFuncs<bool>(boost::bind(&LLXUIParser::readBoolValue, this, _1), - boost::bind(&LLXUIParser::writeBoolValue, this, _1, _2)); - registerParserFuncs<std::string>(boost::bind(&LLXUIParser::readStringValue, this, _1), - boost::bind(&LLXUIParser::writeStringValue, this, _1, _2)); - registerParserFuncs<U8>(boost::bind(&LLXUIParser::readU8Value, this, _1), - boost::bind(&LLXUIParser::writeU8Value, this, _1, _2)); - registerParserFuncs<S8>(boost::bind(&LLXUIParser::readS8Value, this, _1), - boost::bind(&LLXUIParser::writeS8Value, this, _1, _2)); - registerParserFuncs<U16>(boost::bind(&LLXUIParser::readU16Value, this, _1), - boost::bind(&LLXUIParser::writeU16Value, this, _1, _2)); - registerParserFuncs<S16>(boost::bind(&LLXUIParser::readS16Value, this, _1), - boost::bind(&LLXUIParser::writeS16Value, this, _1, _2)); - registerParserFuncs<U32>(boost::bind(&LLXUIParser::readU32Value, this, _1), - boost::bind(&LLXUIParser::writeU32Value, this, _1, _2)); - registerParserFuncs<S32>(boost::bind(&LLXUIParser::readS32Value, this, _1), - boost::bind(&LLXUIParser::writeS32Value, this, _1, _2)); - registerParserFuncs<F32>(boost::bind(&LLXUIParser::readF32Value, this, _1), - boost::bind(&LLXUIParser::writeF32Value, this, _1, _2)); - registerParserFuncs<F64>(boost::bind(&LLXUIParser::readF64Value, this, _1), - boost::bind(&LLXUIParser::writeF64Value, this, _1, _2)); - registerParserFuncs<LLColor4>(boost::bind(&LLXUIParser::readColor4Value, this, _1), - boost::bind(&LLXUIParser::writeColor4Value, this, _1, _2)); - registerParserFuncs<LLUIColor>(boost::bind(&LLXUIParser::readUIColorValue, this, _1), - boost::bind(&LLXUIParser::writeUIColorValue, this, _1, _2)); - registerParserFuncs<LLUUID>(boost::bind(&LLXUIParser::readUUIDValue, this, _1), - boost::bind(&LLXUIParser::writeUUIDValue, this, _1, _2)); - registerParserFuncs<LLSD>(boost::bind(&LLXUIParser::readSDValue, this, _1), - boost::bind(&LLXUIParser::writeSDValue, this, _1, _2)); + if (sXUIReadFuncs.empty()) + { + registerParserFuncs<bool>(readBoolValue, writeBoolValue); + registerParserFuncs<std::string>(readStringValue, writeStringValue); + registerParserFuncs<U8>(readU8Value, writeU8Value); + registerParserFuncs<S8>(readS8Value, writeS8Value); + registerParserFuncs<U16>(readU16Value, writeU16Value); + registerParserFuncs<S16>(readS16Value, writeS16Value); + registerParserFuncs<U32>(readU32Value, writeU32Value); + registerParserFuncs<S32>(readS32Value, writeS32Value); + registerParserFuncs<F32>(readF32Value, writeF32Value); + registerParserFuncs<F64>(readF64Value, writeF64Value); + registerParserFuncs<LLColor4>(readColor4Value, writeColor4Value); + registerParserFuncs<LLUIColor>(readUIColorValue, writeUIColorValue); + registerParserFuncs<LLUUID>(readUUIDValue, writeUUIDValue); + registerParserFuncs<LLSD>(readSDValue, writeSDValue); + } } static LLFastTimer::DeclareTimer FTM_PARSE_XUI("XUI Parsing"); @@ -400,6 +405,7 @@ void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, cons { LLFastTimer timer(FTM_PARSE_XUI); mNameStack.clear(); + mRootNodeName = node->getName()->mString; mCurFileName = filename; mCurReadDepth = 0; setParseSilently(silent); @@ -410,11 +416,11 @@ void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, cons } else { - readXUIImpl(node, std::string(node->getName()->mString), block); + readXUIImpl(node, block); } } -bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLInitParam::BaseBlock& block) +bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block) { typedef boost::tokenizer<boost::char_separator<char> > tokenizer; boost::char_separator<char> sep("."); @@ -481,7 +487,15 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLIn } // check for proper nesting - if(!scope.empty() && *name_token_it != scope) + if (mNameStack.empty()) + { + if (*name_token_it != mRootNodeName) + { + childp = childp->getNextSibling(); + continue; + } + } + else if(mNameStack.back().first != *name_token_it) { childp = childp->getNextSibling(); continue; @@ -499,7 +513,7 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLIn } // recurse and visit children XML nodes - if(readXUIImpl(childp, mNameStack.empty() ? scope : mNameStack.back().first, block)) + if(readXUIImpl(childp, block)) { // child node successfully parsed, remove from DOM @@ -615,17 +629,19 @@ LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack) } -bool LLXUIParser::readBoolValue(void* val_ptr) +bool LLXUIParser::readBoolValue(Parser& parser, void* val_ptr) { S32 value; - bool success = mCurReadNode->getBoolValue(1, &value); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + bool success = self.mCurReadNode->getBoolValue(1, &value); *((bool*)val_ptr) = (value != FALSE); return success; } -bool LLXUIParser::writeBoolValue(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeBoolValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setBoolValue(*((bool*)val_ptr)); @@ -634,15 +650,17 @@ bool LLXUIParser::writeBoolValue(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readStringValue(void* val_ptr) +bool LLXUIParser::readStringValue(Parser& parser, void* val_ptr) { - *((std::string*)val_ptr) = mCurReadNode->getSanitizedValue(); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + *((std::string*)val_ptr) = self.mCurReadNode->getSanitizedValue(); return true; } -bool LLXUIParser::writeStringValue(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeStringValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { const std::string* string_val = reinterpret_cast<const std::string*>(val_ptr); @@ -671,14 +689,16 @@ bool LLXUIParser::writeStringValue(const void* val_ptr, const name_stack_t& stac return false; } -bool LLXUIParser::readU8Value(void* val_ptr) +bool LLXUIParser::readU8Value(Parser& parser, void* val_ptr) { - return mCurReadNode->getByteValue(1, (U8*)val_ptr); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + return self.mCurReadNode->getByteValue(1, (U8*)val_ptr); } -bool LLXUIParser::writeU8Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeU8Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setUnsignedValue(*((U8*)val_ptr)); @@ -687,10 +707,11 @@ bool LLXUIParser::writeU8Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readS8Value(void* val_ptr) +bool LLXUIParser::readS8Value(Parser& parser, void* val_ptr) { + LLXUIParser& self = static_cast<LLXUIParser&>(parser); S32 value; - if(mCurReadNode->getIntValue(1, &value)) + if(self.mCurReadNode->getIntValue(1, &value)) { *((S8*)val_ptr) = value; return true; @@ -698,9 +719,10 @@ bool LLXUIParser::readS8Value(void* val_ptr) return false; } -bool LLXUIParser::writeS8Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeS8Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setIntValue(*((S8*)val_ptr)); @@ -709,10 +731,11 @@ bool LLXUIParser::writeS8Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readU16Value(void* val_ptr) +bool LLXUIParser::readU16Value(Parser& parser, void* val_ptr) { + LLXUIParser& self = static_cast<LLXUIParser&>(parser); U32 value; - if(mCurReadNode->getUnsignedValue(1, &value)) + if(self.mCurReadNode->getUnsignedValue(1, &value)) { *((U16*)val_ptr) = value; return true; @@ -720,9 +743,10 @@ bool LLXUIParser::readU16Value(void* val_ptr) return false; } -bool LLXUIParser::writeU16Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeU16Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setUnsignedValue(*((U16*)val_ptr)); @@ -731,10 +755,11 @@ bool LLXUIParser::writeU16Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readS16Value(void* val_ptr) +bool LLXUIParser::readS16Value(Parser& parser, void* val_ptr) { + LLXUIParser& self = static_cast<LLXUIParser&>(parser); S32 value; - if(mCurReadNode->getIntValue(1, &value)) + if(self.mCurReadNode->getIntValue(1, &value)) { *((S16*)val_ptr) = value; return true; @@ -742,9 +767,10 @@ bool LLXUIParser::readS16Value(void* val_ptr) return false; } -bool LLXUIParser::writeS16Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeS16Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setIntValue(*((S16*)val_ptr)); @@ -753,14 +779,16 @@ bool LLXUIParser::writeS16Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readU32Value(void* val_ptr) +bool LLXUIParser::readU32Value(Parser& parser, void* val_ptr) { - return mCurReadNode->getUnsignedValue(1, (U32*)val_ptr); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + return self.mCurReadNode->getUnsignedValue(1, (U32*)val_ptr); } -bool LLXUIParser::writeU32Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeU32Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setUnsignedValue(*((U32*)val_ptr)); @@ -769,14 +797,16 @@ bool LLXUIParser::writeU32Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readS32Value(void* val_ptr) +bool LLXUIParser::readS32Value(Parser& parser, void* val_ptr) { - return mCurReadNode->getIntValue(1, (S32*)val_ptr); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + return self.mCurReadNode->getIntValue(1, (S32*)val_ptr); } -bool LLXUIParser::writeS32Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeS32Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setIntValue(*((S32*)val_ptr)); @@ -785,14 +815,16 @@ bool LLXUIParser::writeS32Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readF32Value(void* val_ptr) +bool LLXUIParser::readF32Value(Parser& parser, void* val_ptr) { - return mCurReadNode->getFloatValue(1, (F32*)val_ptr); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + return self.mCurReadNode->getFloatValue(1, (F32*)val_ptr); } -bool LLXUIParser::writeF32Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeF32Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setFloatValue(*((F32*)val_ptr)); @@ -801,14 +833,16 @@ bool LLXUIParser::writeF32Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readF64Value(void* val_ptr) +bool LLXUIParser::readF64Value(Parser& parser, void* val_ptr) { - return mCurReadNode->getDoubleValue(1, (F64*)val_ptr); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + return self.mCurReadNode->getDoubleValue(1, (F64*)val_ptr); } -bool LLXUIParser::writeF64Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeF64Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setDoubleValue(*((F64*)val_ptr)); @@ -817,10 +851,11 @@ bool LLXUIParser::writeF64Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readColor4Value(void* val_ptr) +bool LLXUIParser::readColor4Value(Parser& parser, void* val_ptr) { + LLXUIParser& self = static_cast<LLXUIParser&>(parser); LLColor4* colorp = (LLColor4*)val_ptr; - if(mCurReadNode->getFloatValue(4, colorp->mV) >= 3) + if(self.mCurReadNode->getFloatValue(4, colorp->mV) >= 3) { return true; } @@ -828,9 +863,10 @@ bool LLXUIParser::readColor4Value(void* val_ptr) return false; } -bool LLXUIParser::writeColor4Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeColor4Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { LLColor4 color = *((LLColor4*)val_ptr); @@ -840,11 +876,12 @@ bool LLXUIParser::writeColor4Value(const void* val_ptr, const name_stack_t& stac return false; } -bool LLXUIParser::readUIColorValue(void* val_ptr) +bool LLXUIParser::readUIColorValue(Parser& parser, void* val_ptr) { + LLXUIParser& self = static_cast<LLXUIParser&>(parser); LLUIColor* param = (LLUIColor*)val_ptr; LLColor4 color; - bool success = mCurReadNode->getFloatValue(4, color.mV) >= 3; + bool success = self.mCurReadNode->getFloatValue(4, color.mV) >= 3; if (success) { param->set(color); @@ -853,9 +890,10 @@ bool LLXUIParser::readUIColorValue(void* val_ptr) return false; } -bool LLXUIParser::writeUIColorValue(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeUIColorValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { LLUIColor color = *((LLUIColor*)val_ptr); @@ -868,11 +906,12 @@ bool LLXUIParser::writeUIColorValue(const void* val_ptr, const name_stack_t& sta return false; } -bool LLXUIParser::readUUIDValue(void* val_ptr) +bool LLXUIParser::readUUIDValue(Parser& parser, void* val_ptr) { + LLXUIParser& self = static_cast<LLXUIParser&>(parser); LLUUID temp_id; // LLUUID::set is destructive, so use temporary value - if (temp_id.set(mCurReadNode->getSanitizedValue())) + if (temp_id.set(self.mCurReadNode->getSanitizedValue())) { *(LLUUID*)(val_ptr) = temp_id; return true; @@ -880,9 +919,10 @@ bool LLXUIParser::readUUIDValue(void* val_ptr) return false; } -bool LLXUIParser::writeUUIDValue(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeUUIDValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setStringValue(((LLUUID*)val_ptr)->asString()); @@ -891,15 +931,18 @@ bool LLXUIParser::writeUUIDValue(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readSDValue(void* val_ptr) +bool LLXUIParser::readSDValue(Parser& parser, void* val_ptr) { - *((LLSD*)val_ptr) = LLSD(mCurReadNode->getSanitizedValue()); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + *((LLSD*)val_ptr) = LLSD(self.mCurReadNode->getSanitizedValue()); return true; } -bool LLXUIParser::writeSDValue(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeSDValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast<LLXUIParser&>(parser); + + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { std::string string_val = ((LLSD*)val_ptr)->asString(); @@ -962,3 +1005,438 @@ void LLXUIParser::parserError(const std::string& message) Parser::parserError(message); #endif } + + +// +// LLSimpleXUIParser +// + +struct ScopedFile +{ + ScopedFile( const std::string& filename, const char* accessmode ) + { + mFile = LLFile::fopen(filename, accessmode); + } + + ~ScopedFile() + { + fclose(mFile); + mFile = NULL; + } + + S32 getRemainingBytes() + { + if (!isOpen()) return 0; + + S32 cur_pos = ftell(mFile); + fseek(mFile, 0L, SEEK_END); + S32 file_size = ftell(mFile); + fseek(mFile, cur_pos, SEEK_SET); + return file_size - cur_pos; + } + + bool isOpen() { return mFile != NULL; } + + LLFILE* mFile; +}; +static LLInitParam::Parser::parser_read_func_map_t sSimpleXUIReadFuncs; +static LLInitParam::Parser::parser_write_func_map_t sSimpleXUIWriteFuncs; +static LLInitParam::Parser::parser_inspect_func_map_t sSimpleXUIInspectFuncs; + +LLSimpleXUIParser::LLSimpleXUIParser(LLSimpleXUIParser::element_start_callback_t element_cb) +: Parser(sSimpleXUIReadFuncs, sSimpleXUIWriteFuncs, sSimpleXUIInspectFuncs), + mLastWriteGeneration(-1), + mCurReadDepth(0), + mElementCB(element_cb) +{ + if (sSimpleXUIReadFuncs.empty()) + { + registerParserFuncs<bool>(readBoolValue); + registerParserFuncs<std::string>(readStringValue); + registerParserFuncs<U8>(readU8Value); + registerParserFuncs<S8>(readS8Value); + registerParserFuncs<U16>(readU16Value); + registerParserFuncs<S16>(readS16Value); + registerParserFuncs<U32>(readU32Value); + registerParserFuncs<S32>(readS32Value); + registerParserFuncs<F32>(readF32Value); + registerParserFuncs<F64>(readF64Value); + registerParserFuncs<LLColor4>(readColor4Value); + registerParserFuncs<LLUIColor>(readUIColorValue); + registerParserFuncs<LLUUID>(readUUIDValue); + registerParserFuncs<LLSD>(readSDValue); + } +} + +LLSimpleXUIParser::~LLSimpleXUIParser() +{ +} + + +bool LLSimpleXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent) +{ + LLFastTimer timer(FTM_PARSE_XUI); + + mParser = XML_ParserCreate(NULL); + XML_SetUserData(mParser, this); + XML_SetElementHandler( mParser, startElementHandler, endElementHandler); + XML_SetCharacterDataHandler( mParser, characterDataHandler); + + mOutputStack.push_back(std::make_pair(&block, 0)); + mNameStack.clear(); + mCurFileName = filename; + mCurReadDepth = 0; + setParseSilently(silent); + + ScopedFile file(filename, "rb"); + if( !file.isOpen() ) + { + LL_WARNS("ReadXUI") << "Unable to open file " << filename << LL_ENDL; + return false; + } + + S32 bytes_read = 0; + + S32 buffer_size = file.getRemainingBytes(); + void* buffer = XML_GetBuffer(mParser, buffer_size); + if( !buffer ) + { + LL_WARNS("ReadXUI") << "Unable to allocate XML buffer while reading file " << filename << LL_ENDL; + XML_ParserFree( mParser ); + return false; + } + + bytes_read = (S32)fread(buffer, 1, buffer_size, file.mFile); + if( bytes_read <= 0 ) + { + LL_WARNS("ReadXUI") << "Error while reading file " << filename << LL_ENDL; + XML_ParserFree( mParser ); + return false; + } + + if( !XML_ParseBuffer(mParser, bytes_read, TRUE ) ) + { + LL_WARNS("ReadXUI") << "Error while parsing file " << filename << LL_ENDL; + XML_ParserFree( mParser ); + return false; + } + + XML_ParserFree( mParser ); + return true; +} + +void LLSimpleXUIParser::startElementHandler(void *userData, const char *name, const char **atts) +{ + LLSimpleXUIParser* self = reinterpret_cast<LLSimpleXUIParser*>(userData); + self->startElement(name, atts); +} + +void LLSimpleXUIParser::endElementHandler(void *userData, const char *name) +{ + LLSimpleXUIParser* self = reinterpret_cast<LLSimpleXUIParser*>(userData); + self->endElement(name); +} + +void LLSimpleXUIParser::characterDataHandler(void *userData, const char *s, int len) +{ + LLSimpleXUIParser* self = reinterpret_cast<LLSimpleXUIParser*>(userData); + self->characterData(s, len); +} + +void LLSimpleXUIParser::startElement(const char *name, const char **atts) +{ + processText(); + + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep("."); + + if (mElementCB) + { + LLInitParam::BaseBlock* blockp = mElementCB(*this, name); + if (blockp) + { + mOutputStack.push_back(std::make_pair(blockp, 0)); + } + } + + mOutputStack.back().second++; + S32 num_tokens_pushed = 0; + std::string child_name(name); + + if (mOutputStack.back().second == 1) + { // root node for this block + mScope.push_back(child_name); + } + else + { // compound attribute + if (child_name.find(".") == std::string::npos) + { + mNameStack.push_back(std::make_pair(child_name, newParseGeneration())); + num_tokens_pushed++; + mScope.push_back(child_name); + } + else + { + // parse out "dotted" name into individual tokens + tokenizer name_tokens(child_name, sep); + + tokenizer::iterator name_token_it = name_tokens.begin(); + if(name_token_it == name_tokens.end()) + { + return; + } + + // check for proper nesting + if(!mScope.empty() && *name_token_it != mScope.back()) + { + return; + } + + // now ignore first token + ++name_token_it; + + // copy remaining tokens on to our running token list + for(tokenizer::iterator token_to_push = name_token_it; token_to_push != name_tokens.end(); ++token_to_push) + { + mNameStack.push_back(std::make_pair(*token_to_push, newParseGeneration())); + num_tokens_pushed++; + } + mScope.push_back(mNameStack.back().first); + } + } + + mTokenSizeStack.push_back(num_tokens_pushed); + readAttributes(atts); +} + +bool LLSimpleXUIParser::readAttributes(const char **atts) +{ + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep("."); + + bool any_parsed = false; + for(S32 i = 0; atts[i] && atts[i+1]; i += 2 ) + { + std::string attribute_name(atts[i]); + mCurAttributeValueBegin = atts[i+1]; + + S32 num_tokens_pushed = 0; + tokenizer name_tokens(attribute_name, sep); + // copy remaining tokens on to our running token list + for(tokenizer::iterator token_to_push = name_tokens.begin(); token_to_push != name_tokens.end(); ++token_to_push) + { + mNameStack.push_back(std::make_pair(*token_to_push, newParseGeneration())); + num_tokens_pushed++; + } + + // child nodes are not necessarily valid attributes, so don't complain once we've recursed + any_parsed |= mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently); + + while(num_tokens_pushed-- > 0) + { + mNameStack.pop_back(); + } + } + return any_parsed; +} + +void LLSimpleXUIParser::processText() +{ + if (!mTextContents.empty()) + { + LLStringUtil::trim(mTextContents); + if (!mTextContents.empty()) + { + mNameStack.push_back(std::make_pair(std::string("value"), newParseGeneration())); + mCurAttributeValueBegin = mTextContents.c_str(); + mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently); + mNameStack.pop_back(); + } + mTextContents.clear(); + } +} + +void LLSimpleXUIParser::endElement(const char *name) +{ + processText(); + + if (--mOutputStack.back().second == 0) + { + if (mOutputStack.empty()) + { + LL_ERRS("ReadXUI") << "Parameter block output stack popped while empty." << LL_ENDL; + } + mOutputStack.pop_back(); + } + + S32 num_tokens_to_pop = mTokenSizeStack.back(); + mTokenSizeStack.pop_back(); + while(num_tokens_to_pop-- > 0) + { + mNameStack.pop_back(); + } + mScope.pop_back(); +} + +void LLSimpleXUIParser::characterData(const char *s, int len) +{ + mTextContents += std::string(s, len); +} + + +/*virtual*/ std::string LLSimpleXUIParser::getCurrentElementName() +{ + std::string full_name; + for (name_stack_t::iterator it = mNameStack.begin(); + it != mNameStack.end(); + ++it) + { + full_name += it->first + "."; // build up dotted names: "button.param.nestedparam." + } + + return full_name; +} + +const S32 LINE_NUMBER_HERE = 0; + +void LLSimpleXUIParser::parserWarning(const std::string& message) +{ +#ifdef LL_WINDOWS + // use Visual Studo friendly formatting of output message for easy access to originating xml + llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str()); + utf16str += '\n'; + OutputDebugString(utf16str.c_str()); +#else + Parser::parserWarning(message); +#endif +} + +void LLSimpleXUIParser::parserError(const std::string& message) +{ +#ifdef LL_WINDOWS + llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str()); + utf16str += '\n'; + OutputDebugString(utf16str.c_str()); +#else + Parser::parserError(message); +#endif +} + +bool LLSimpleXUIParser::readBoolValue(Parser& parser, void* val_ptr) +{ + LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); + if (!strcmp(self.mCurAttributeValueBegin, "true")) + { + *((bool*)val_ptr) = true; + return true; + } + else if (!strcmp(self.mCurAttributeValueBegin, "false")) + { + *((bool*)val_ptr) = false; + return true; + } + + return false; +} + +bool LLSimpleXUIParser::readStringValue(Parser& parser, void* val_ptr) +{ + LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); + *((std::string*)val_ptr) = self.mCurAttributeValueBegin; + return true; +} + +bool LLSimpleXUIParser::readU8Value(Parser& parser, void* val_ptr) +{ + LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); + return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U8*)val_ptr)]).full; +} + +bool LLSimpleXUIParser::readS8Value(Parser& parser, void* val_ptr) +{ + LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); + return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S8*)val_ptr)]).full; +} + +bool LLSimpleXUIParser::readU16Value(Parser& parser, void* val_ptr) +{ + LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); + return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U16*)val_ptr)]).full; +} + +bool LLSimpleXUIParser::readS16Value(Parser& parser, void* val_ptr) +{ + LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); + return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S16*)val_ptr)]).full; +} + +bool LLSimpleXUIParser::readU32Value(Parser& parser, void* val_ptr) +{ + LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); + return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U32*)val_ptr)]).full; +} + +bool LLSimpleXUIParser::readS32Value(Parser& parser, void* val_ptr) +{ + LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); + return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S32*)val_ptr)]).full; +} + +bool LLSimpleXUIParser::readF32Value(Parser& parser, void* val_ptr) +{ + LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); + return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F32*)val_ptr)]).full; +} + +bool LLSimpleXUIParser::readF64Value(Parser& parser, void* val_ptr) +{ + LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); + return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F64*)val_ptr)]).full; +} + +bool LLSimpleXUIParser::readColor4Value(Parser& parser, void* val_ptr) +{ + LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); + LLColor4 value; + + if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full) + { + *(LLColor4*)(val_ptr) = value; + return true; + } + return false; +} + +bool LLSimpleXUIParser::readUIColorValue(Parser& parser, void* val_ptr) +{ + LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); + LLColor4 value; + LLUIColor* colorp = (LLUIColor*)val_ptr; + + if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full) + { + colorp->set(value); + return true; + } + return false; +} + +bool LLSimpleXUIParser::readUUIDValue(Parser& parser, void* val_ptr) +{ + LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); + LLUUID temp_id; + // LLUUID::set is destructive, so use temporary value + if (temp_id.set(std::string(self.mCurAttributeValueBegin))) + { + *(LLUUID*)(val_ptr) = temp_id; + return true; + } + return false; +} + +bool LLSimpleXUIParser::readSDValue(Parser& parser, void* val_ptr) +{ + LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser); + *((LLSD*)val_ptr) = LLSD(self.mCurAttributeValueBegin); + return true; +} diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h index 30b7e8c356..5c613b0c69 100644 --- a/indra/llxuixml/llxuiparser.h +++ b/indra/llxuixml/llxuiparser.h @@ -96,14 +96,12 @@ public: -class LLXUIParser : public LLInitParam::Parser, public LLSingleton<LLXUIParser> +class LLXUIParser : public LLInitParam::Parser { LOG_CLASS(LLXUIParser); -protected: - LLXUIParser(); - friend class LLSingleton<LLXUIParser>; public: + LLXUIParser(); typedef LLInitParam::Parser::name_stack_t name_stack_t; /*virtual*/ std::string getCurrentElementName(); @@ -114,42 +112,40 @@ public: void writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const LLInitParam::BaseBlock* diff_block = NULL); private: - typedef std::list<std::pair<std::string, bool> > token_list_t; - - bool readXUIImpl(LLXMLNodePtr node, const std::string& scope, LLInitParam::BaseBlock& block); + bool readXUIImpl(LLXMLNodePtr node, LLInitParam::BaseBlock& block); bool readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block); //reader helper functions - bool readBoolValue(void* val_ptr); - bool readStringValue(void* val_ptr); - bool readU8Value(void* val_ptr); - bool readS8Value(void* val_ptr); - bool readU16Value(void* val_ptr); - bool readS16Value(void* val_ptr); - bool readU32Value(void* val_ptr); - bool readS32Value(void* val_ptr); - bool readF32Value(void* val_ptr); - bool readF64Value(void* val_ptr); - bool readColor4Value(void* val_ptr); - bool readUIColorValue(void* val_ptr); - bool readUUIDValue(void* val_ptr); - bool readSDValue(void* val_ptr); + static bool readBoolValue(Parser& parser, void* val_ptr); + static bool readStringValue(Parser& parser, void* val_ptr); + static bool readU8Value(Parser& parser, void* val_ptr); + static bool readS8Value(Parser& parser, void* val_ptr); + static bool readU16Value(Parser& parser, void* val_ptr); + static bool readS16Value(Parser& parser, void* val_ptr); + static bool readU32Value(Parser& parser, void* val_ptr); + static bool readS32Value(Parser& parser, void* val_ptr); + static bool readF32Value(Parser& parser, void* val_ptr); + static bool readF64Value(Parser& parser, void* val_ptr); + static bool readColor4Value(Parser& parser, void* val_ptr); + static bool readUIColorValue(Parser& parser, void* val_ptr); + static bool readUUIDValue(Parser& parser, void* val_ptr); + static bool readSDValue(Parser& parser, void* val_ptr); //writer helper functions - bool writeBoolValue(const void* val_ptr, const name_stack_t&); - bool writeStringValue(const void* val_ptr, const name_stack_t&); - bool writeU8Value(const void* val_ptr, const name_stack_t&); - bool writeS8Value(const void* val_ptr, const name_stack_t&); - bool writeU16Value(const void* val_ptr, const name_stack_t&); - bool writeS16Value(const void* val_ptr, const name_stack_t&); - bool writeU32Value(const void* val_ptr, const name_stack_t&); - bool writeS32Value(const void* val_ptr, const name_stack_t&); - bool writeF32Value(const void* val_ptr, const name_stack_t&); - bool writeF64Value(const void* val_ptr, const name_stack_t&); - bool writeColor4Value(const void* val_ptr, const name_stack_t&); - bool writeUIColorValue(const void* val_ptr, const name_stack_t&); - bool writeUUIDValue(const void* val_ptr, const name_stack_t&); - bool writeSDValue(const void* val_ptr, const name_stack_t&); + static bool writeBoolValue(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeStringValue(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeU8Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeS8Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeU16Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeS16Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeU32Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeS32Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeF32Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeF64Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeColor4Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeUIColorValue(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeUUIDValue(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeSDValue(Parser& parser, const void* val_ptr, const name_stack_t&); LLXMLNodePtr getNode(const name_stack_t& stack); @@ -165,6 +161,78 @@ private: LLXMLNodePtr mLastWrittenChild; S32 mCurReadDepth; std::string mCurFileName; + std::string mRootNodeName; +}; + +// LLSimpleXUIParser is a streamlined SAX-based XUI parser that does not support localization +// or parsing of a tree of independent param blocks, such as child widgets. +// Use this for reading non-localized files that only need a single param block as a result. +// +// NOTE: In order to support nested block parsing, we need callbacks for start element that +// push new blocks contexts on the mScope stack. +// NOTE: To support localization without building a DOM, we need to enforce consistent +// ordering of child elements from base file to localized diff file. Then we can use a pair +// of coroutines to perform matching of xml nodes during parsing. Not sure if the overhead +// of coroutines would offset the gain from SAX parsing + +class LLSimpleXUIParser : public LLInitParam::Parser +{ +LOG_CLASS(LLSimpleXUIParser); +public: + typedef LLInitParam::Parser::name_stack_t name_stack_t; + typedef LLInitParam::BaseBlock* (*element_start_callback_t)(LLSimpleXUIParser&, const char* block_name); + + LLSimpleXUIParser(element_start_callback_t element_cb = NULL); + virtual ~LLSimpleXUIParser(); + + /*virtual*/ std::string getCurrentElementName(); + /*virtual*/ void parserWarning(const std::string& message); + /*virtual*/ void parserError(const std::string& message); + + bool readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent=false); + + +private: + //reader helper functions + static bool readBoolValue(Parser&, void* val_ptr); + static bool readStringValue(Parser&, void* val_ptr); + static bool readU8Value(Parser&, void* val_ptr); + static bool readS8Value(Parser&, void* val_ptr); + static bool readU16Value(Parser&, void* val_ptr); + static bool readS16Value(Parser&, void* val_ptr); + static bool readU32Value(Parser&, void* val_ptr); + static bool readS32Value(Parser&, void* val_ptr); + static bool readF32Value(Parser&, void* val_ptr); + static bool readF64Value(Parser&, void* val_ptr); + static bool readColor4Value(Parser&, void* val_ptr); + static bool readUIColorValue(Parser&, void* val_ptr); + static bool readUUIDValue(Parser&, void* val_ptr); + static bool readSDValue(Parser&, void* val_ptr); + +private: + static void startElementHandler(void *userData, const char *name, const char **atts); + static void endElementHandler(void *userData, const char *name); + static void characterDataHandler(void *userData, const char *s, int len); + + void startElement(const char *name, const char **atts); + void endElement(const char *name); + void characterData(const char *s, int len); + bool readAttributes(const char **atts); + void processText(); + + Parser::name_stack_t mNameStack; + struct XML_ParserStruct* mParser; + S32 mLastWriteGeneration; + LLXMLNodePtr mLastWrittenChild; + S32 mCurReadDepth; + std::string mCurFileName; + std::string mTextContents; + const char* mCurAttributeValueBegin; + std::vector<S32> mTokenSizeStack; + std::vector<std::string> mScope; + element_start_callback_t mElementCB; + + std::vector<std::pair<LLInitParam::BaseBlock*, S32> > mOutputStack; }; diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt index 9f0ff654fc..a5127ae5f4 100644 --- a/indra/media_plugins/gstreamer010/CMakeLists.txt +++ b/indra/media_plugins/gstreamer010/CMakeLists.txt @@ -42,13 +42,6 @@ set(media_plugin_gstreamer010_HEADER_FILES llmediaimplgstreamertriviallogging.h ) -if (${CXX_VERSION_NUMBER} MATCHES "4[23456789].") - # Work around a bad interaction between broken gstreamer headers and - # g++ >= 4.2's increased strictness. - set_source_files_properties(llmediaimplgstreamervidplug.cpp PROPERTIES - COMPILE_FLAGS -Wno-write-strings) -endif (${CXX_VERSION_NUMBER} MATCHES "4[23456789].") - add_library(media_plugin_gstreamer010 SHARED ${media_plugin_gstreamer010_SOURCE_FILES} diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp index a51a8aa9e1..cdb7f4faeb 100644 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp +++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp @@ -48,7 +48,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_slvideo_debug); #define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ( - "sink", + (gchar*)"sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS (SLV_ALLCAPS) @@ -508,18 +508,18 @@ plugin_init (GstPlugin * plugin) some g++ versions buggily avoid __attribute__((constructor)) functions - so we provide an explicit plugin init function. */ +#define PACKAGE (gchar*)"packagehack" +// this macro quietly refers to PACKAGE internally +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + (gchar*)"private-slvideoplugin", + (gchar*)"SL Video sink plugin", + plugin_init, (gchar*)"1.0", (gchar*)"LGPL", + (gchar*)"Second Life", + (gchar*)"http://www.secondlife.com/"); +#undef PACKAGE void gst_slvideo_init_class (void) { -#define PACKAGE "packagehack" - // this macro quietly refers to PACKAGE internally - static GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "private-slvideoplugin", - "SL Video sink plugin", - plugin_init, "0.1", GST_LICENSE_UNKNOWN, - "Second Life", - "http://www.secondlife.com/"); -#undef PACKAGE ll_gst_plugin_register_static (&gst_plugin_desc); DEBUGMSG("CLASS INIT"); } diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/webkit/CMakeLists.txt index d576638dd7..57478ddf27 100644 --- a/indra/media_plugins/webkit/CMakeLists.txt +++ b/indra/media_plugins/webkit/CMakeLists.txt @@ -51,9 +51,11 @@ set(media_plugin_webkit_LINK_LIBRARIES # Select which VolumeCatcher implementation to use if (LINUX) - if (PULSEAUDIO) + if (PULSEAUDIO_FOUND) list(APPEND media_plugin_webkit_SOURCE_FILES linux_volume_catcher.cpp) - endif (PULSEAUDIO) + else (PULSEAUDIO_FOUND) + list(APPEND media_plugin_webkit_SOURCE_FILES dummy_volume_catcher.cpp) + endif (PULSEAUDIO_FOUND) list(APPEND media_plugin_webkit_LINK_LIBRARIES ${UI_LIBRARIES} # for glib/GTK ) @@ -67,9 +69,6 @@ elseif (DARWIN) ) elseif (WINDOWS) list(APPEND media_plugin_webkit_SOURCE_FILES windows_volume_catcher.cpp) -else (LINUX) - # All other platforms use the dummy volume catcher for now. - list(APPEND media_plugin_webkit_SOURCE_FILES dummy_volume_catcher.cpp) endif (LINUX) set_source_files_properties(${media_plugin_webkit_HEADER_FILES} diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp index 047146f8f3..bd1a44a930 100644 --- a/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -115,6 +115,7 @@ private: F32 mBackgroundR; F32 mBackgroundG; F32 mBackgroundB; + std::string mTarget; VolumeCatcher mVolumeCatcher; @@ -303,7 +304,7 @@ private: LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled ); // create single browser window - mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight ); + mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight, mTarget); // tell LLQtWebKit about the size of the browser window LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight ); @@ -313,9 +314,6 @@ private: // append details to agent string LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent ); - - // Set up window open behavior - LLQtWebKit::getInstance()->setWindowOpenBehavior(mBrowserWindowId, LLQtWebKit::WOB_SIMULATE_BLANK_HREF_CLICK); #if !LL_QTWEBKIT_USES_PIXMAPS // don't flip bitmap @@ -507,9 +505,9 @@ private: void onClickLinkHref(const EventType& event) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href"); - message.setValue("uri", event.getStringValue()); - message.setValue("target", event.getStringValue2()); - message.setValueU32("target_type", event.getLinkType()); + message.setValue("uri", event.getEventUri()); + message.setValue("target", event.getStringValue()); + message.setValue("uuid", event.getStringValue2()); sendMessage(message); } @@ -518,7 +516,7 @@ private: void onClickLinkNoFollow(const EventType& event) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); - message.setValue("uri", event.getStringValue()); + message.setValue("uri", event.getEventUri()); sendMessage(message); } @@ -534,6 +532,42 @@ private: // message.setValueBoolean("dead", (event.getIntValue() != 0)) sendMessage(message); } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onWindowCloseRequested(const EventType& event) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "close_request"); + message.setValue("uuid", event.getStringValue()); + sendMessage(message); + } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onWindowGeometryChangeRequested(const EventType& event) + { + int x, y, width, height; + event.getRectValue(x, y, width, height); + + // This sometimes gets called with a zero-size request. Don't pass these along. + if(width > 0 && height > 0) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "geometry_change"); + message.setValue("uuid", event.getStringValue()); + message.setValueS32("x", x); + message.setValueS32("y", y); + message.setValueS32("width", width); + message.setValueS32("height", height); + sendMessage(message); + } + } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + std::string onRequestFilePicker( const EventType& eventIn ) + { + return blockingPickFile(); + } LLQtWebKit::EKeyboardModifier decodeModifiers(std::string &modifiers) { @@ -679,6 +713,26 @@ private: } } + + std::string mPickedFile; + + std::string blockingPickFile(void) + { + mPickedFile.clear(); + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file"); + message.setValueBoolean("blocking_request", true); + + // The "blocking_request" key in the message means this sendMessage call will block until a response is received. + sendMessage(message); + + return mPickedFile; + } + + void onPickFileResponse(const std::string &file) + { + mPickedFile = file; + } }; @@ -817,6 +871,8 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) { if(message_name == "init") { + mTarget = message_in.getValue("target"); + // This is the media init message -- all necessary data for initialization should have been received. if(initBrowser()) { @@ -1036,10 +1092,14 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE ); checkEditState(); } + if(message_name == "pick_file_response") + { + onPickFileResponse(message_in.getValue("file")); + } else { // std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl; - }; + } } else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) { @@ -1139,6 +1199,17 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) } } } + else if(message_name == "proxy_window_opened") + { + std::string target = message_in.getValue("target"); + std::string uuid = message_in.getValue("uuid"); + LLQtWebKit::getInstance()->proxyWindowOpened(mBrowserWindowId, target, uuid); + } + else if(message_name == "proxy_window_closed") + { + std::string uuid = message_in.getValue("uuid"); + LLQtWebKit::getInstance()->proxyWindowClosed(mBrowserWindowId, uuid); + } else { // std::cerr << "MediaPluginWebKit::receiveMessage: unknown media_browser message: " << message_string << std::endl; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index fe96eb6398..1829e12478 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -94,6 +94,7 @@ set(viewer_SOURCE_FILES llbottomtray.cpp llbox.cpp llbreadcrumbview.cpp + llbrowsernotification.cpp llbuycurrencyhtml.cpp llcallbacklist.cpp llcallfloater.cpp @@ -217,7 +218,6 @@ set(viewer_SOURCE_FILES llfloatertos.cpp llfloateruipreview.cpp llfloaterurlentry.cpp - llfloatervoicedevicesettings.cpp llfloatervoiceeffect.cpp llfloaterwater.cpp llfloaterwhitelistentry.cpp @@ -235,6 +235,7 @@ set(viewer_SOURCE_FILES llgroupiconctrl.cpp llgrouplist.cpp llgroupmgr.cpp + llhints.cpp llhomelocationresponder.cpp llhudeffect.cpp llhudeffectbeam.cpp @@ -305,6 +306,7 @@ set(viewer_SOURCE_FILES llnotificationalerthandler.cpp llnotificationgrouphandler.cpp llnotificationhandlerutil.cpp + llnotificationhinthandler.cpp llnotificationmanager.cpp llnotificationofferhandler.cpp llnotificationscripthandler.cpp @@ -364,6 +366,7 @@ set(viewer_SOURCE_FILES llpaneltiptoast.cpp llpanelvoiceeffect.cpp llpaneltopinfobar.cpp + llpanelvoicedevicesettings.cpp llpanelvolume.cpp llpanelvolumepulldown.cpp llpanelwearing.cpp @@ -746,7 +749,6 @@ set(viewer_HEADER_FILES llfloatertos.h llfloateruipreview.h llfloaterurlentry.h - llfloatervoicedevicesettings.h llfloatervoiceeffect.h llfloaterwater.h llfloaterwhitelistentry.h @@ -764,6 +766,7 @@ set(viewer_HEADER_FILES llgroupiconctrl.h llgrouplist.h llgroupmgr.h + llhints.h llhomelocationresponder.h llhudeffect.h llhudeffectbeam.h @@ -886,6 +889,7 @@ set(viewer_HEADER_FILES llpanelprofileview.h llpanelteleporthistory.h llpaneltiptoast.h + llpanelvoicedevicesettings.h llpanelvoiceeffect.h llpaneltopinfobar.h llpanelvolume.h @@ -1311,6 +1315,7 @@ set(viewer_APPSETTINGS_FILES app_settings/cmd_line.xml app_settings/grass.xml app_settings/high_graphics.xml + app_settings/ignorable_dialogs.xml app_settings/keys.ini app_settings/keywords.ini app_settings/logcontrol.xml @@ -1487,6 +1492,7 @@ if (WINDOWS) ${GOOGLE_PERF_TOOLS_SOURCE} ${CMAKE_CURRENT_SOURCE_DIR}/licenses-win32.txt ${CMAKE_CURRENT_SOURCE_DIR}/featuretable.txt + ${CMAKE_CURRENT_SOURCE_DIR}/featuretable_xp.txt ${CMAKE_CURRENT_SOURCE_DIR}/dbghelp.dll ${CMAKE_CURRENT_SOURCE_DIR}/fmod.dll ${ARCH_PREBUILT_DIRS_RELEASE}/libeay32.dll diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index 5f143431de..00d69f805e 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -296,7 +296,7 @@ <key>multiple</key> <map> <key>desc</key> - <string>Allow multple viewers.</string> + <string>Allow multiple viewers.</string> <key>map-to</key> <string>AllowMultipleViewers</string> </map> diff --git a/indra/newview/app_settings/ignorable_dialogs.xml b/indra/newview/app_settings/ignorable_dialogs.xml index d0e1f62a84..0720ccee49 100644 --- a/indra/newview/app_settings/ignorable_dialogs.xml +++ b/indra/newview/app_settings/ignorable_dialogs.xml @@ -1,10 +1,10 @@ <?xml version="1.0" ?> <llsd> <map> - <key>FirstAppearance</key> + <key>FirstInventoryOffer</key> <map> <key>Comment</key> - <string>Enables FirstAppearance warning dialog</string> + <string>Shows hint when a person or object offers resident an inventory item</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -12,120 +12,54 @@ <key>Value</key> <integer>1</integer> </map> - <key>FirstAttach</key> - <map> - <key>Comment</key> - <string>Enables FirstAttach warning dialog</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>FirstBalanceDecrease</key> - <map> - <key>Comment</key> - <string>Enables FirstBalanceDecrease warning dialog</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>FirstBalanceIncrease</key> - <map> - <key>Comment</key> - <string>Enables FirstBalanceIncrease warning dialog</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>FirstBuild</key> - <map> - <key>Comment</key> - <string>Enables FirstBuild warning dialog</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>FirstDebugMenus</key> - <map> - <key>Comment</key> - <string>Enables FirstDebugMenus warning dialog</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>FirstFlexible</key> - <map> - <key>Comment</key> - <string>Enables FirstFlexible warning dialog</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>FirstGoTo</key> - <map> - <key>Comment</key> - <string>Enables FirstGoTo warning dialog</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>FirstInventory</key> - <map> - <key>Comment</key> - <string>Enables FirstInventory warning dialog</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>FirstLeftClickNoHit</key> - <map> - <key>Comment</key> - <string>Enables FirstLeftClickNoHit warning dialog</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>FirstMap</key> - <map> - <key>Comment</key> - <string>Enables FirstMap warning dialog</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>FirstMedia</key> + <key>FirstNotUseDestinationGuide</key> + <map> + <key>Comment</key> + <string>Shows hint when resident doesn't activate destination guide</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>FirstNotUseSidePanel</key> + <map> + <key>Comment</key> + <string>Shows hint when resident doesn't activate side panel</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>FirstNotMoving</key> + <map> + <key>Comment</key> + <string>Shows hint when resident doesn't move</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>FirstReceiveLindens</key> + <map> + <key>Comment</key> + <string>Shows hint when resident receives linden dollars</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>FirstOtherChatBeforeUser</key> <map> <key>Comment</key> - <string>Enables FirstMedia warning dialog</string> + <string>Shows hint when someone else chats first</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -155,43 +89,11 @@ <key>Value</key> <integer>1</integer> </map> - <key>FirstSculptedPrim</key> - <map> - <key>Comment</key> - <string>Enables FirstSculptedPrim warning dialog</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> + <key>FirstSit</key> <map> <key>Comment</key> - <string>Enables FirstSit warning dialog</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>FirstTeleport</key> - <map> - <key>Comment</key> - <string>Enables FirstTeleport warning dialog</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>FirstVoice</key> - <map> - <key>Comment</key> - <string>Enables FirstVoice warning dialog</string> + <string>Shows hint when someone sits for the first time</string> <key>Persist</key> <integer>1</integer> <key>Type</key> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 0bed37b96a..742a20a849 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2688,6 +2688,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>DoubleClickTeleport</key> + <map> + <key>Comment</key> + <string>Enable double-click to teleport where allowed</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>DragAndDropToolTipDelay</key> <map> <key>Comment</key> @@ -2831,6 +2842,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>EnableUIHints</key> + <map> + <key>Comment</key> + <string>Toggles UI hint popups</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>EnableVoiceChat</key> <map> <key>Comment</key> @@ -3815,7 +3837,7 @@ <key>Comment</key> <string>URL for the web page to display in the Home side panel</string> <key>Persist</key> - <integer>0</integer> + <integer>1</integer> <key>Type</key> <string>String</string> <key>Value</key> @@ -5208,6 +5230,17 @@ <key>Value</key> <real>3.0</real> </map> + <key>MediaEnablePopups</key> + <map> + <key>Comment</key> + <string>If true, enable targeted links and javascript in media to open new media browser windows without a prompt.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>MediaOnAPrimUI</key> <map> <key>Comment</key> @@ -6469,6 +6502,17 @@ <key>Value</key> <real>1.0</real> </map> + <key>MediaBrowserWindowLimit</key> + <map> + <key>Comment</key> + <string>Maximum number of media brower windows that can be open at once (0 for no limit)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>5</integer> + </map> <key>MediaRollOffRate</key> <map> <key>Comment</key> @@ -7888,6 +7932,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>RenderHighlightSelections</key> + <map> + <key>Comment</key> + <string>Show selection outlines on objects</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>RenderHiddenSelections</key> <map> <key>Comment</key> @@ -8877,7 +8932,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> + <integer>0</integer> </map> <key>GroupListShowIcons</key> <map> @@ -12002,5 +12057,38 @@ <key>Value</key> <integer>10</integer> </map> + <key>NotMovingHintTimeout</key> + <map> + <key>Comment</key> + <string>Number of seconds to wait for resident to move before displaying move hint.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>120.0</real> + </map> + <key>DestinationGuideHintTimeout</key> + <map> + <key>Comment</key> + <string>Number of seconds to wait before telling resident about destination guide.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>600.0</real> + </map> + <key>SidePanelHintTimeout</key> + <map> + <key>Comment</key> + <string>Number of seconds to wait before telling resident about side panel.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>300.0</real> + </map> </map> </llsd> diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index e3fc9d4949..721fe81a3c 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -550,4 +550,3 @@ list NVIDIA_GeForce_Go_7800 RenderShaderLightingMaxLevel 1 2 list NVIDIA_GeForce_Go_7900 RenderShaderLightingMaxLevel 1 2 - diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index fe7e883d83..c9bd7851ed 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -38,6 +38,7 @@ #include "llcallingcard.h" #include "llchannelmanager.h" #include "llconsole.h" +#include "llfirstuse.h" #include "llfloatercamera.h" #include "llfloaterreg.h" #include "llfloatertools.h" @@ -167,6 +168,7 @@ LLAgent::LLAgent() : mbAlwaysRun(false), mbRunning(false), + mbTeleportKeepsLookAt(false), mAgentAccess(gSavedSettings), mTeleportState( TELEPORT_NONE ), @@ -193,8 +195,6 @@ LLAgent::LLAgent() : mbFlagsDirty(FALSE), mbFlagsNeedReset(FALSE), - mbJump(FALSE), - mAutoPilot(FALSE), mAutoPilotFlyOnStop(FALSE), mAutoPilotTargetGlobal(), @@ -226,8 +226,9 @@ LLAgent::LLAgent() : mControlsTakenPassedOnCount[i] = 0; } - mListener.reset(new LLAgentListener(*this)); + + mMoveTimer.stop(); } // Requires gSavedSettings to be initialized. @@ -236,6 +237,8 @@ LLAgent::LLAgent() : //----------------------------------------------------------------------------- void LLAgent::init() { + mMoveTimer.start(); + gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", FALSE); gSavedSettings.getControl("SlowMotionAnimation")->getSignal()->connect(boost::bind(&handleSlowMotionAnimation, _2)); @@ -300,6 +303,9 @@ void LLAgent::ageChat() //----------------------------------------------------------------------------- void LLAgent::moveAt(S32 direction, bool reset) { + mMoveTimer.reset(); + LLFirstUse::notMoving(false); + // age chat timer so it fades more quickly when you are intentionally moving ageChat(); @@ -325,6 +331,9 @@ void LLAgent::moveAt(S32 direction, bool reset) //----------------------------------------------------------------------------- void LLAgent::moveAtNudge(S32 direction) { + mMoveTimer.reset(); + LLFirstUse::notMoving(false); + // age chat timer so it fades more quickly when you are intentionally moving ageChat(); @@ -347,6 +356,9 @@ void LLAgent::moveAtNudge(S32 direction) //----------------------------------------------------------------------------- void LLAgent::moveLeft(S32 direction) { + mMoveTimer.reset(); + LLFirstUse::notMoving(false); + // age chat timer so it fades more quickly when you are intentionally moving ageChat(); @@ -369,6 +381,9 @@ void LLAgent::moveLeft(S32 direction) //----------------------------------------------------------------------------- void LLAgent::moveLeftNudge(S32 direction) { + mMoveTimer.reset(); + LLFirstUse::notMoving(false); + // age chat timer so it fades more quickly when you are intentionally moving ageChat(); @@ -391,6 +406,9 @@ void LLAgent::moveLeftNudge(S32 direction) //----------------------------------------------------------------------------- void LLAgent::moveUp(S32 direction) { + mMoveTimer.reset(); + LLFirstUse::notMoving(false); + // age chat timer so it fades more quickly when you are intentionally moving ageChat(); @@ -536,6 +554,9 @@ void LLAgent::toggleFlying() { BOOL fly = !gAgent.getFlying(); + gAgent.mMoveTimer.reset(); + LLFirstUse::notMoving(false); + gAgent.setFlying( fly ); gAgentCamera.resetView(); } @@ -1533,6 +1554,11 @@ void LLAgent::propagate(const F32 dt) //----------------------------------------------------------------------------- void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32 mouse_x, const S32 mouse_y) { + if (mMoveTimer.getStarted() && mMoveTimer.getElapsedTimeF32() > gSavedSettings.getF32("NotMovingHintTimeout")) + { + LLFirstUse::notMoving(); + } + propagate(dt); // static S32 cameraUpdateCount = 0; @@ -2961,12 +2987,6 @@ void LLAgent::processScriptControlChange(LLMessageSystem *msg, void **) total_count++; } } - - // Any control taken? If so, might be first time. - //if (total_count > 0) - //{ - //LLFirstUse::useOverrideKeys(); - //} } else { @@ -3249,7 +3269,11 @@ bool LLAgent::teleportCore(bool is_local) // local logic LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TELEPORT_COUNT); - if (!is_local) + if (is_local) + { + gAgent.setTeleportState( LLAgent::TELEPORT_LOCAL ); + } + else { gTeleportDisplay = TRUE; gAgent.setTeleportState( LLAgent::TELEPORT_START ); @@ -3268,13 +3292,15 @@ bool LLAgent::teleportCore(bool is_local) void LLAgent::teleportRequest( const U64& region_handle, - const LLVector3& pos_local) + const LLVector3& pos_local, + bool look_at_from_camera) { LLViewerRegion* regionp = getRegion(); - if(regionp && teleportCore()) + bool is_local = (region_handle == to_region_handle(getPositionGlobal())); + if(regionp && teleportCore(is_local)) { - llinfos << "TeleportRequest: '" << region_handle << "':" << pos_local - << llendl; + LL_INFOS("") << "TeleportLocationRequest: '" << region_handle << "':" + << pos_local << LL_ENDL; LLMessageSystem* msg = gMessageSystem; msg->newMessage("TeleportLocationRequest"); msg->nextBlockFast(_PREHASH_AgentData); @@ -3284,6 +3310,10 @@ void LLAgent::teleportRequest( msg->addU64("RegionHandle", region_handle); msg->addVector3("Position", pos_local); LLVector3 look_at(0,1,0); + if (look_at_from_camera) + { + look_at = LLViewerCamera::getInstance()->getAtAxis(); + } msg->addVector3("LookAt", look_at); sendReliableMessage(); } @@ -3395,6 +3425,16 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global) } } +// Teleport to global position, but keep facing in the same direction +void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global) +{ + mbTeleportKeepsLookAt = true; + gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); // detach camera form avatar, so it keeps direction + U64 region_handle = to_region_handle(pos_global); + LLVector3 pos_local = (LLVector3)(pos_global - from_region_handle(region_handle)); + teleportRequest(region_handle, pos_local, getTeleportKeepsLookAt()); +} + void LLAgent::setTeleportState(ETeleportState state) { mTeleportState = state; @@ -3402,18 +3442,28 @@ void LLAgent::setTeleportState(ETeleportState state) { LLFloaterReg::hideInstance("snapshot"); } - if (mTeleportState == TELEPORT_MOVING) + + switch (mTeleportState) { + case TELEPORT_NONE: + mbTeleportKeepsLookAt = false; + break; + + case TELEPORT_MOVING: // We're outa here. Save "back" slurl. LLAgentUI::buildSLURL(mTeleportSourceSLURL); - } - else if(mTeleportState == TELEPORT_ARRIVING) - { + break; + + case TELEPORT_ARRIVING: // First two position updates after a teleport tend to be weird LLViewerStats::getInstance()->mAgentPositionSnaps.mCountOfNextUpdatesToIgnore = 2; // Let the interested parties know we've teleported. LLViewerParcelMgr::getInstance()->onTeleportFinished(false, getPositionGlobal()); + break; + + default: + break; } } diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index c643cef78f..6c598d5d71 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -264,6 +264,7 @@ public: private: LLFrameTimer mFidgetTimer; LLFrameTimer mFocusObjectFadeTimer; + LLFrameTimer mMoveTimer; F32 mNextFidgetTime; S32 mCurrentFidget; @@ -339,6 +340,7 @@ public: private: bool mbAlwaysRun; // Should the avatar run by default rather than walk? bool mbRunning; // Is the avatar trying to run right now? + bool mbTeleportKeepsLookAt; // Try to keep look-at after teleport is complete //-------------------------------------------------------------------- // Sit and stand @@ -359,14 +361,6 @@ private: BOOL mIsBusy; //-------------------------------------------------------------------- - // Jump - //-------------------------------------------------------------------- -public: - BOOL getJump() const { return mbJump; } -private: - BOOL mbJump; - - //-------------------------------------------------------------------- // Grab //-------------------------------------------------------------------- public: @@ -506,7 +500,8 @@ public: TELEPORT_REQUESTED = 2, // Waiting for source simulator to respond TELEPORT_MOVING = 3, // Viewer has received destination location from source simulator TELEPORT_START_ARRIVAL = 4, // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator - TELEPORT_ARRIVING = 5 // Make the user wait while content "pre-caches" + TELEPORT_ARRIVING = 5, // Make the user wait while content "pre-caches" + TELEPORT_LOCAL = 6 // Teleporting in-sim without showing the progress screen }; public: @@ -524,12 +519,15 @@ private: //-------------------------------------------------------------------- public: void teleportRequest(const U64& region_handle, - const LLVector3& pos_local); // Go to a named location home + const LLVector3& pos_local, // Go to a named location home + bool look_at_from_camera = false); void teleportViaLandmark(const LLUUID& landmark_id); // Teleport to a landmark void teleportHome() { teleportViaLandmark(LLUUID::null); } // Go home void teleportViaLure(const LLUUID& lure_id, BOOL godlike); // To an invited location void teleportViaLocation(const LLVector3d& pos_global); // To a global location - this will probably need to be deprecated + void teleportViaLocationLookAt(const LLVector3d& pos_global);// To a global location, preserving camera rotation void teleportCancel(); // May or may not be allowed by server + bool getTeleportKeepsLookAt() { return mbTeleportKeepsLookAt; } // Whether look-at reset after teleport protected: bool teleportCore(bool is_local = false); // Stuff for all teleports; returns true if the teleport can proceed diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index fd6b8b739d..333c92e50d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -262,6 +262,7 @@ const F64 FRAME_STALL_THRESHOLD = 1.0; LLTimer gRenderStartTime; LLFrameTimer gForegroundTime; +LLFrameTimer gLoggedInTime; LLTimer gLogoutTimer; static const F32 LOGOUT_REQUEST_TIME = 6.f; // this will be cut short by the LogoutReply msg. F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME; @@ -360,19 +361,19 @@ bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base) if(gAgent.isInGroup(match_id, TRUE)) { - LLGroupIconCtrl::Params icon_params = LLUICtrlFactory::instance().getDefaultParams<LLGroupIconCtrl>(); + LLGroupIconCtrl::Params icon_params; icon_params.group_id = match_id; icon_params.rect = LLRect(0, 16, 16, 0); icon_params.visible = true; - icon = LLUICtrlFactory::instance().createWidget<LLGroupIconCtrl>(icon_params); + icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params); } else { - LLAvatarIconCtrl::Params icon_params = LLUICtrlFactory::instance().getDefaultParams<LLAvatarIconCtrl>(); + LLAvatarIconCtrl::Params icon_params; icon_params.avatar_id = match_id; icon_params.rect = LLRect(0, 16, 16, 0); icon_params.visible = true; - icon = LLUICtrlFactory::instance().createWidget<LLAvatarIconCtrl>(icon_params); + icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params); } LLInlineViewSegment::Params params; @@ -591,6 +592,7 @@ LLAppViewer::LLAppViewer() : setupErrorHandling(); sInstance = this; + gLoggedInTime.stop(); } LLAppViewer::~LLAppViewer() @@ -928,8 +930,9 @@ bool LLAppViewer::init() //EXT-7013 - On windows for some locale (Japanese) standard //datetime formatting functions didn't support some parameters such as "weekday". + //Names for days and months localized in xml are also useful for Polish locale(STORM-107). std::string language = LLControlGroup::getInstance(sGlobalSettingsName)->getString("Language"); - if(language == "ja") + if(language == "ja" || language == "pl") { LLStringOps::setupWeekDaysNames(LLTrans::getString("dateTimeWeekdaysNames")); LLStringOps::setupWeekDaysShortNames(LLTrans::getString("dateTimeWeekdaysShortNames")); @@ -4274,6 +4277,7 @@ void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs) void LLAppViewer::handleLoginComplete() { + gLoggedInTime.start(); initMainloopTimeout("Mainloop Init"); // Store some data to DebugInfo in case of a freeze. diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index c5cac6827c..56d88f07c8 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -308,6 +308,7 @@ extern U32 gFrameStalls; extern LLTimer gRenderStartTime; extern LLFrameTimer gForegroundTime; +extern LLFrameTimer gLoggedInTime; extern F32 gLogoutMaxTime; extern LLTimer gLogoutTimer; diff --git a/indra/newview/llaudiosourcevo.cpp b/indra/newview/llaudiosourcevo.cpp index 40eb5ebcd1..b37aba6c15 100644 --- a/indra/newview/llaudiosourcevo.cpp +++ b/indra/newview/llaudiosourcevo.cpp @@ -35,11 +35,8 @@ LLAudioSourceVO::LLAudioSourceVO(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, LLViewerObject *objectp) : LLAudioSource(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX), - mObjectp(objectp), - mActualGain(gain) + mObjectp(objectp) { - setAmbient(FALSE); - updateGain(); update(); } @@ -54,18 +51,18 @@ LLAudioSourceVO::~LLAudioSourceVO() void LLAudioSourceVO::setGain(const F32 gain) { - mActualGain = llclamp(gain, 0.f, 1.f); - updateGain(); + mGain = llclamp(gain, 0.f, 1.f); } -void LLAudioSourceVO::updateGain() +void LLAudioSourceVO::updateMute() { - if (!mObjectp) + if (!mObjectp || mObjectp->isDead()) { + mSourceMuted = true; return; } - BOOL mute = FALSE; + bool mute = false; LLVector3d pos_global; if (mObjectp->isAttachment()) @@ -84,21 +81,21 @@ void LLAudioSourceVO::updateGain() { pos_global = mObjectp->getPositionGlobal(); } - + if (!LLViewerParcelMgr::getInstance()->canHearSound(pos_global)) { - mute = TRUE; + mute = true; } if (!mute) { if (LLMuteList::getInstance()->isMuted(mObjectp->getID())) { - mute = TRUE; + mute = true; } else if (LLMuteList::getInstance()->isMuted(mOwnerID, LLMute::flagObjectSounds)) { - mute = TRUE; + mute = true; } else if (mObjectp->isAttachment()) { @@ -110,24 +107,38 @@ void LLAudioSourceVO::updateGain() if (parent && LLMuteList::getInstance()->isMuted(parent->getID())) { - mute = TRUE; + mute = true; } } } - if (!mute) + if (mute != mSourceMuted) { - mGain = mActualGain; - } - else - { - mGain = 0.f; + mSourceMuted = mute; + if (mSourceMuted) + { + // Stop the sound. + this->play(LLUUID::null); + } + else + { + // Muted sounds keep there data at all times, because + // it's the place where the audio UUID is stored. + // However, it's possible that mCurrentDatap is + // NULL when this source did only preload sounds. + if (mCurrentDatap) + { + // Restart the sound. + this->play(mCurrentDatap->getID()); + } + } } } - void LLAudioSourceVO::update() { + updateMute(); + if (!mObjectp) { return; @@ -139,7 +150,11 @@ void LLAudioSourceVO::update() return; } - updateGain(); + if (mSourceMuted) + { + return; + } + if (mObjectp->isHUDAttachment()) { mPositionGlobal = gAgentCamera.getCameraPositionGlobal(); diff --git a/indra/newview/llaudiosourcevo.h b/indra/newview/llaudiosourcevo.h index a68f58a4b2..f1d8ef4528 100644 --- a/indra/newview/llaudiosourcevo.h +++ b/indra/newview/llaudiosourcevo.h @@ -42,11 +42,10 @@ public: /*virtual*/ void setGain(const F32 gain); private: - void updateGain(); + void updateMute(); private: LLPointer<LLViewerObject> mObjectp; - F32 mActualGain; // The "real" gain, when not off due to parcel effects }; #endif // LL_LLAUDIOSOURCEVO_H diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index b9ae976e58..79b0c63b38 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -49,6 +49,7 @@ #include "llfloaterpay.h" #include "llfloaterworldmap.h" #include "llgiveinventory.h" +#include "llinventorybridge.h" #include "llinventorymodel.h" // for gInventory.findCategoryUUIDForType #include "llinventorypanel.h" #include "llimview.h" // for gIMMgr @@ -443,17 +444,27 @@ namespace action_give_inventory } /** - * Checks My Inventory visibility. + * @return active inventory panel, or NULL if there's no such panel */ - static bool is_give_inventory_acceptable() + static LLInventoryPanel* get_active_inventory_panel() { LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); if (!active_panel) { active_panel = get_outfit_editor_inventory_panel(); - if (!active_panel) return false; } + return active_panel; + } + + /** + * Checks My Inventory visibility. + */ + static bool is_give_inventory_acceptable() + { + LLInventoryPanel* active_panel = get_active_inventory_panel(); + if (!active_panel) return false; + // check selection in the panel const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); if (inventory_selected_uuids.empty()) return false; // nothing selected @@ -543,12 +554,8 @@ namespace action_give_inventory return; } - LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (!active_panel) - { - active_panel = get_outfit_editor_inventory_panel(); - if (!active_panel) return; - } + LLInventoryPanel* active_panel = get_active_inventory_panel(); + if (!active_panel) return; const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); if (inventory_selected_uuids.empty()) @@ -632,12 +639,8 @@ namespace action_give_inventory llassert(avatar_names.size() == avatar_uuids.size()); - LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (!active_panel) - { - active_panel = get_outfit_editor_inventory_panel(); - if (!active_panel) return; - } + LLInventoryPanel* active_panel = get_active_inventory_panel(); + if (!active_panel) return; const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); if (inventory_selected_uuids.empty()) @@ -672,6 +675,53 @@ void LLAvatarActions::shareWithAvatars() LLNotificationsUtil::add("ShareNotification"); } + +// static +bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NULL*/) +{ + using namespace action_give_inventory; + + if (!inv_panel) + { + LLInventoryPanel* active_panel = get_active_inventory_panel(); + if (!active_panel) return false; + inv_panel = active_panel; + } + + // check selection in the panel + LLFolderView* root_folder = inv_panel->getRootFolder(); + const uuid_set_t inventory_selected_uuids = root_folder->getSelectionList(); + if (inventory_selected_uuids.empty()) return false; // nothing selected + + bool can_share = true; + uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); + const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end(); + for (; it != it_end; ++it) + { + LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); + // any category can be offered. + if (inv_cat) + { + continue; + } + + // check if inventory item can be given + LLFolderViewItem* item = root_folder->getItemByID(*it); + if (!item) return false; + LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(item->getListener()); + if (bridge && bridge->canShare()) + { + continue; + } + + // there are neither item nor category in inventory + can_share = false; + break; + } + + return can_share; +} + // static void LLAvatarActions::toggleBlock(const LLUUID& id) { diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 6313ae0759..44bd3778da 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -34,6 +34,8 @@ #include <string> #include <vector> +class LLInventoryPanel; + /** * Friend-related actions (add, remove, offer teleport, etc) */ @@ -183,6 +185,15 @@ public: */ static bool canOfferTeleport(const uuid_vec_t& ids); + /** + * Checks whether all items selected in the given inventory panel can be shared + * + * @param inv_panel Inventory panel to get selection from. If NULL, the active inventory panel is used. + * + * @return false if the selected items cannot be shared or the active inventory panel cannot be obtained + */ + static bool canShareSelectedItems(LLInventoryPanel* inv_panel = NULL); + private: static bool callbackAddFriend(const LLSD& notification, const LLSD& response); static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 5241f20c0e..09083dcb98 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -509,7 +509,7 @@ LLAvalineListItem::LLAvalineListItem(bool hide_number/* = true*/) : LLAvatarList , mIsHideNumber(hide_number) { // should not use buildPanel from the base class to ensure LLAvalineListItem::postBuild is called. - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_list_item.xml"); + buildFromFile( "panel_avatar_list_item.xml"); } BOOL LLAvalineListItem::postBuild() diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 8fc4ad6763..c54913a3e1 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -70,11 +70,12 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/) mOnlineStatus(E_UNKNOWN), mShowInfoBtn(true), mShowProfileBtn(true), - mShowPermissions(false) + mShowPermissions(false), + mHovered(false) { if (not_from_ui_factory) { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_list_item.xml"); + buildFromFile("panel_avatar_list_item.xml"); } // *NOTE: mantipov: do not use any member here. They can be uninitialized here in case instance // is created from the UICtrlFactory @@ -449,20 +450,20 @@ void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item) //info btn width + padding S32 info_btn_width = avatar_item->mProfileBtn->getRect().mLeft - avatar_item->mInfoBtn->getRect().mLeft; - // edit their objects permission icon width + padding - S32 permission_edit_theirs_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mIconPermissionEditTheirs->getRect().mLeft; - - // edit my objects permission icon width + padding - S32 permission_edit_mine_width = avatar_item->mIconPermissionEditTheirs->getRect().mLeft - avatar_item->mIconPermissionEditMine->getRect().mLeft; + // online permission icon width + padding + S32 permission_online_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mIconPermissionOnline->getRect().mLeft; // map permission icon width + padding - S32 permission_map_width = avatar_item->mIconPermissionEditMine->getRect().mLeft - avatar_item->mIconPermissionMap->getRect().mLeft; + S32 permission_map_width = avatar_item->mIconPermissionOnline->getRect().mLeft - avatar_item->mIconPermissionMap->getRect().mLeft; - // online permission icon width + padding - S32 permission_online_width = avatar_item->mIconPermissionMap->getRect().mLeft - avatar_item->mIconPermissionOnline->getRect().mLeft; + // edit my objects permission icon width + padding + S32 permission_edit_mine_width = avatar_item->mIconPermissionMap->getRect().mLeft - avatar_item->mIconPermissionEditMine->getRect().mLeft; + + // edit their objects permission icon width + padding + S32 permission_edit_theirs_width = avatar_item->mIconPermissionEditMine->getRect().mLeft - avatar_item->mIconPermissionEditTheirs->getRect().mLeft; // last interaction time textbox width + padding - S32 last_interaction_time_width = avatar_item->mIconPermissionOnline->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft; + S32 last_interaction_time_width = avatar_item->mIconPermissionEditTheirs->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft; // avatar icon width + padding S32 icon_width = avatar_item->mAvatarName->getRect().mLeft - avatar_item->mAvatarIcon->getRect().mLeft; @@ -474,10 +475,10 @@ void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item) sChildrenWidths[--index] = icon_width; sChildrenWidths[--index] = 0; // for avatar name we don't need its width, it will be calculated as "left available space" sChildrenWidths[--index] = last_interaction_time_width; - sChildrenWidths[--index] = permission_online_width; - sChildrenWidths[--index] = permission_map_width; - sChildrenWidths[--index] = permission_edit_mine_width; sChildrenWidths[--index] = permission_edit_theirs_width; + sChildrenWidths[--index] = permission_edit_mine_width; + sChildrenWidths[--index] = permission_map_width; + sChildrenWidths[--index] = permission_online_width; sChildrenWidths[--index] = info_btn_width; sChildrenWidths[--index] = profile_btn_width; sChildrenWidths[--index] = speaking_indicator_width; diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index ffb988b2ab..52187284eb 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -143,10 +143,10 @@ private: ALIC_SPEAKER_INDICATOR, ALIC_PROFILE_BUTTON, ALIC_INFO_BUTTON, - ALIC_PERMISSION_EDIT_THEIRS, - ALIC_PERMISSION_EDIT_MINE, - ALIC_PERMISSION_MAP, ALIC_PERMISSION_ONLINE, + ALIC_PERMISSION_MAP, + ALIC_PERMISSION_EDIT_MINE, + ALIC_PERMISSION_EDIT_THEIRS, ALIC_INTERACTION_TIME, ALIC_NAME, ALIC_ICON, diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index f3ade83d00..29c2b7565e 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -41,6 +41,7 @@ #include "llagentcamera.h" #include "llchiclet.h" #include "llfloatercamera.h" +#include "llhints.h" #include "llimfloater.h" // for LLIMFloater #include "llnearbychatbar.h" #include "llspeakbutton.h" @@ -67,7 +68,7 @@ BOOL LLBottomtrayButton::handleHover(S32 x, S32 y, MASK mask) S32 screenX, screenY; localPointToScreen(x, y, &screenX, &screenY); // pass hover to bottomtray - LLBottomTray::getInstance()->handleHover(screenX, screenY, mask); + LLBottomTray::getInstance()->onDraggableButtonHover(screenX, screenY); return FALSE; } //virtual @@ -76,7 +77,7 @@ BOOL LLBottomtrayButton::handleMouseUp(S32 x, S32 y, MASK mask) S32 screenX, screenY; localPointToScreen(x, y, &screenX, &screenY); // pass mouse up to bottomtray - LLBottomTray::getInstance()->onDraggableButtonMouseUp(this,screenX, screenY, mask); + LLBottomTray::getInstance()->onDraggableButtonMouseUp(this, screenX, screenY); LLButton::handleMouseUp(x, y, mask); return FALSE; } @@ -86,7 +87,7 @@ BOOL LLBottomtrayButton::handleMouseDown(S32 x, S32 y, MASK mask) S32 screenX, screenY; localPointToScreen(x, y, &screenX, &screenY); // pass mouse up to bottomtray - LLBottomTray::getInstance()->onDraggableButtonMouseDown(this,screenX, screenY, mask); + LLBottomTray::getInstance()->onDraggableButtonMouseDown(this, screenX, screenY); LLButton::handleMouseDown(x, y, mask); return FALSE; } @@ -104,10 +105,6 @@ template class LLBottomTray* LLSingleton<class LLBottomTray>::getInstance(); namespace { const std::string& PANEL_CHICLET_NAME = "chiclet_list_panel"; - const std::string& PANEL_CHATBAR_NAME = "chat_bar"; - const std::string& PANEL_MOVEMENT_NAME = "movement_panel"; - const std::string& PANEL_CAMERA_NAME = "cam_panel"; - const std::string& PANEL_GESTURE_NAME = "gesture_panel"; S32 get_panel_min_width(LLLayoutStack* stack, LLView* panel) { @@ -115,7 +112,7 @@ namespace llassert(stack); if ( stack && panel && panel->getVisible() ) { - stack->getPanelMinSize(panel->getName(), &minimal_width, NULL); + stack->getPanelMinSize(panel->getName(), &minimal_width); } return minimal_width; } @@ -126,7 +123,7 @@ namespace llassert(stack); if ( stack && panel && panel->getVisible() ) { - stack->getPanelMaxSize(panel->getName(), &max_width, NULL); + stack->getPanelMaxSize(panel->getName(), &max_width); } return max_width; } @@ -148,26 +145,30 @@ class LLBottomTrayLite public: LLBottomTrayLite() : mNearbyChatBar(NULL), + mChatBarContainer(NULL), mGesturePanel(NULL) { mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL); - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_bottomtray_lite.xml"); + buildFromFile("panel_bottomtray_lite.xml"); // Necessary for focus movement among child controls setFocusRoot(TRUE); } BOOL postBuild() { - mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar"); + mNearbyChatBar = findChild<LLNearbyChatBar>("chat_bar"); + mChatBarContainer = getChild<LLLayoutPanel>("chat_bar_layout_panel"); mGesturePanel = getChild<LLPanel>("gesture_panel"); // Hide "show_nearby_chat" button - LLLineEditor* chat_box = mNearbyChatBar->getChatBox(); - LLUICtrl* show_btn = mNearbyChatBar->getChild<LLUICtrl>("show_nearby_chat"); - S32 delta_width = show_btn->getRect().getWidth(); - show_btn->setVisible(FALSE); - chat_box->reshape(chat_box->getRect().getWidth() + delta_width, chat_box->getRect().getHeight()); - + if (mNearbyChatBar) + { + LLLineEditor* chat_box = mNearbyChatBar->getChatBox(); + LLUICtrl* show_btn = mNearbyChatBar->getChild<LLUICtrl>("show_nearby_chat"); + S32 delta_width = show_btn->getRect().getWidth(); + show_btn->setVisible(FALSE); + chat_box->reshape(chat_box->getRect().getWidth() + delta_width, chat_box->getRect().getHeight()); + } return TRUE; } @@ -180,6 +181,7 @@ public: } LLNearbyChatBar* mNearbyChatBar; + LLLayoutPanel* mChatBarContainer; LLPanel* mGesturePanel; }; @@ -188,17 +190,18 @@ LLBottomTray::LLBottomTray(const LLSD&) mSpeakPanel(NULL), mSpeakBtn(NULL), mNearbyChatBar(NULL), - mToolbarStack(NULL) -, mMovementButton(NULL) -, mResizeState(RS_NORESIZE) -, mBottomTrayContextMenu(NULL) -, mCamButton(NULL) -, mBottomTrayLite(NULL) -, mIsInLiteMode(false) -, mDragStarted(false) -, mDraggedItem(NULL) -, mLandingTab(NULL) -, mCheckForDrag(false) + mChatBarContainer(NULL), + mToolbarStack(NULL), + mMovementButton(NULL), + mResizeState(RS_NORESIZE), + mBottomTrayContextMenu(NULL), + mCamButton(NULL), + mBottomTrayLite(NULL), + mIsInLiteMode(false), + mDragStarted(false), + mDraggedItem(NULL), + mLandingTab(NULL), + mCheckForDrag(false) { // Firstly add ourself to IMSession observers, so we catch session events // before chiclets do that. @@ -206,7 +209,7 @@ LLBottomTray::LLBottomTray(const LLSD&) mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL); - LLUICtrlFactory::getInstance()->buildPanel(this,"panel_bottomtray.xml"); + buildFromFile("panel_bottomtray.xml"); LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("CameraPresets.ChangeView", boost::bind(&LLFloaterCamera::onClickCameraItem, _2)); @@ -225,6 +228,7 @@ LLBottomTray::LLBottomTray(const LLSD&) } mImageDragIndication = LLUI::getUIImage(getString("DragIndicationImageName")); + mDesiredNearbyChatWidth = mNearbyChatBar ? mNearbyChatBar->getRect().getWidth() : 0; } LLBottomTray::~LLBottomTray() @@ -237,7 +241,7 @@ LLBottomTray::~LLBottomTray() if (mNearbyChatBar) { // store custom width of chatbar panel. - S32 custom_width = mNearbyChatBar->getRect().getWidth(); + S32 custom_width = mChatBarContainer->getRect().getWidth(); gSavedSettings.setS32("ChatBarCustomWidth", custom_width); } @@ -432,7 +436,7 @@ S32 LLBottomTray::notifyParent(const LLSD& info) const std::string& name = info["view_name"]; // expected only resize of nearby chatbar - if (mNearbyChatBar->getName() != name) return LLPanel::notifyParent(info); + if (mChatBarContainer->getName() != name) return LLPanel::notifyParent(info); const S32 new_width = info["new_width"]; @@ -462,8 +466,8 @@ void LLBottomTray::updateContextMenu(S32 x, S32 y, MASK mask) { LLUICtrl* edit_box = mNearbyChatBar->getChild<LLUICtrl>("chat_box"); - S32 local_x = x - mNearbyChatBar->getRect().mLeft - edit_box->getRect().mLeft; - S32 local_y = y - mNearbyChatBar->getRect().mBottom - edit_box->getRect().mBottom; + S32 local_x = x - mChatBarContainer->getRect().mLeft - edit_box->getRect().mLeft; + S32 local_y = y - mChatBarContainer->getRect().mBottom - edit_box->getRect().mBottom; bool in_edit_box = edit_box->pointInView(local_x, local_y); @@ -516,10 +520,14 @@ BOOL LLBottomTray::postBuild() mBottomTrayContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_bottomtray.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); gMenuHolder->addChild(mBottomTrayContextMenu); + mNearbyChatBar = findChild<LLNearbyChatBar>("chat_bar"); + LLHints::registerHintTarget("chat_bar", mNearbyChatBar->LLView::getHandle()); + + mChatBarContainer = getChild<LLLayoutPanel>("chat_bar_layout_panel"); - mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar"); mToolbarStack = getChild<LLLayoutStack>("toolbar_stack"); mMovementButton = getChild<LLButton>("movement_btn"); + LLHints::registerHintTarget("move_btn", mMovementButton->getHandle()); mCamButton = getChild<LLButton>("camera_btn"); setRightMouseDownCallback(boost::bind(&LLBottomTray::showBottomTrayContextMenu,this, _2, _3,_4)); @@ -561,7 +569,7 @@ BOOL LLBottomTray::postBuild() //Drag-n-drop -void LLBottomTray::onDraggableButtonMouseDown(LLUICtrl* ctrl, S32 x, S32 y, MASK mask) +void LLBottomTray::onDraggableButtonMouseDown(LLUICtrl* ctrl, S32 x, S32 y) { if (ctrl == NULL) return; LLView* parent_view = ctrl->getParent(); @@ -607,7 +615,7 @@ LLPanel* LLBottomTray::findChildPanelByLocalCoords(S32 x, S32 y) return ctrl; } -BOOL LLBottomTray::handleHover(S32 x, S32 y, MASK mask) +void LLBottomTray::onDraggableButtonHover(S32 x, S32 y) { // if mouse down on draggable item was done, check whether we should start DnD if (mCheckForDrag) @@ -634,8 +642,6 @@ BOOL LLBottomTray::handleHover(S32 x, S32 y, MASK mask) gViewerWindow->getWindow()->setCursor(UI_CURSOR_NO); } } - - return TRUE; } bool LLBottomTray::isCursorOverDraggableArea(S32 x, S32 y) @@ -764,10 +770,10 @@ void LLBottomTray::loadButtonsOrder() } // Nearbychat is not stored in order settings file, but it must be the first of the panels, so moving it // manually here - mToolbarStack->movePanel(mNearbyChatBar, NULL, true); + mToolbarStack->movePanel(mChatBarContainer, NULL, true); } -void LLBottomTray::onDraggableButtonMouseUp(LLUICtrl* ctrl, S32 x, S32 y, MASK mask) +void LLBottomTray::onDraggableButtonMouseUp(LLUICtrl* ctrl, S32 x, S32 y) { //if mouse up happened over area where drop is possible, change order of buttons if (mLandingTab != NULL && mDraggedItem != NULL && mDragStarted) @@ -963,14 +969,15 @@ void LLBottomTray::reshape(S32 width, S32 height, BOOL called_from_parent) // we can not to do this from postBuild because reshape is called from parent view on startup // creation after it and reset width according to resize logic. static bool needs_restore_custom_state = true; - if (mNearbyChatBar && needs_restore_custom_state) + if (mChatBarContainer && needs_restore_custom_state) { // restore custom width of chatbar panel. S32 new_width = gSavedSettings.getS32("ChatBarCustomWidth"); if (new_width > 0) { + mDesiredNearbyChatWidth = new_width; processChatbarCustomization(new_width); - mNearbyChatBar->reshape(new_width, mNearbyChatBar->getRect().getHeight()); + mChatBarContainer->reshape(new_width, mChatBarContainer->getRect().getHeight()); } needs_restore_custom_state = false; } @@ -984,6 +991,9 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width) const S32 chiclet_panel_width = mChicletPanel->getParent()->getRect().getWidth(); const S32 chiclet_panel_min_width = mChicletPanel->getMinWidth(); + // There are four steps of processing width decrease. If in one of them required width was reached, + // further are not needed. + // 1. Decreasing width of chiclet panel. if (chiclet_panel_width > chiclet_panel_min_width) { // we have some space to decrease chiclet panel @@ -1009,8 +1019,15 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width) << llendl; } - const S32 chatbar_panel_width = mNearbyChatBar->getRect().getWidth(); - const S32 chatbar_panel_min_width = get_panel_min_width(mToolbarStack, mNearbyChatBar); + S32 buttons_freed_width = 0; + // 2. Decreasing width of buttons. + if (still_should_be_processed) + { + processShrinkButtons(delta_width, buttons_freed_width); + } + // 3. Decreasing width of nearby chat. + const S32 chatbar_panel_min_width = get_panel_min_width(mToolbarStack, mChatBarContainer); + const S32 chatbar_panel_width = mChatBarContainer->getRect().getWidth(); if (still_should_be_processed && chatbar_panel_width > chatbar_panel_min_width) { // we have some space to decrease chatbar panel @@ -1023,7 +1040,11 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width) still_should_be_processed = delta_width < 0; - mNearbyChatBar->reshape(mNearbyChatBar->getRect().getWidth() - delta_panel, mNearbyChatBar->getRect().getHeight()); + // chatbar should only be shrunk here, not stretched + if(delta_panel > 0) + { + mChatBarContainer->reshape(mNearbyChatBar->getRect().getWidth() - delta_panel, mChatBarContainer->getRect().getHeight()); + } log(mNearbyChatBar, "after processing panel decreasing via nearby chatbar panel"); @@ -1034,11 +1055,9 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width) } S32 extra_shrink_width = 0; - S32 buttons_freed_width = 0; + // 4. Hiding buttons if needed. if (still_should_be_processed) { - processShrinkButtons(delta_width, buttons_freed_width); - processHideButtons(delta_width, buttons_freed_width); if (delta_width < 0) @@ -1050,10 +1069,15 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width) if (buttons_freed_width > 0) { - log(mNearbyChatBar, "before applying compensative width"); - mNearbyChatBar->reshape(mNearbyChatBar->getRect().getWidth() + buttons_freed_width, mNearbyChatBar->getRect().getHeight() ); - log(mNearbyChatBar, "after applying compensative width"); - lldebugs << buttons_freed_width << llendl; + S32 nearby_needed_width = mDesiredNearbyChatWidth - mNearbyChatBar->getRect().getWidth(); + if (nearby_needed_width > 0) + { + S32 compensative_width = nearby_needed_width > buttons_freed_width ? buttons_freed_width : nearby_needed_width; + log(mNearbyChatBar, "before applying compensative width"); + mChatBarContainer->reshape(mChatBarContainer->getRect().getWidth() + compensative_width, mChatBarContainer->getRect().getHeight() ); + log(mNearbyChatBar, "after applying compensative width"); + lldebugs << buttons_freed_width << llendl; + } } } @@ -1067,18 +1091,12 @@ void LLBottomTray::processWidthIncreased(S32 delta_width) const S32 chiclet_panel_width = mChicletPanel->getParent()->getRect().getWidth(); static const S32 chiclet_panel_min_width = mChicletPanel->getMinWidth(); - const S32 chatbar_panel_width = mNearbyChatBar->getRect().getWidth(); - static const S32 chatbar_panel_min_width = get_panel_min_width(mToolbarStack, mNearbyChatBar); - static const S32 chatbar_panel_max_width = get_panel_max_width(mToolbarStack, mNearbyChatBar); - - const S32 chatbar_available_shrink_width = chatbar_panel_width - chatbar_panel_min_width; const S32 available_width_chiclet = chiclet_panel_width - chiclet_panel_min_width; // how many room we have to show hidden buttons - S32 total_available_width = delta_width + chatbar_available_shrink_width + available_width_chiclet; + S32 total_available_width = delta_width + available_width_chiclet; lldebugs << "Processing extending, available width:" - << ", chatbar - " << chatbar_available_shrink_width << ", chiclets - " << available_width_chiclet << ", total - " << total_available_width << llendl; @@ -1087,8 +1105,6 @@ void LLBottomTray::processWidthIncreased(S32 delta_width) processShowButtons(available_width); - processExtendButtons(available_width); - // if we have to show/extend some buttons but resized delta width is not enough... S32 processed_width = total_available_width - available_width; if (processed_width > delta_width) @@ -1099,21 +1115,7 @@ void LLBottomTray::processWidthIncreased(S32 delta_width) // 1. use delta width of resizing required_to_process_width -= delta_width; - // 2. use width available via decreasing of nearby chat panel - S32 chatbar_shrink_width = required_to_process_width; - if (chatbar_available_shrink_width < chatbar_shrink_width) - { - chatbar_shrink_width = chatbar_available_shrink_width; - } - - log(mNearbyChatBar, "increase width: before applying compensative width"); - mNearbyChatBar->reshape(mNearbyChatBar->getRect().getWidth() - chatbar_shrink_width, mNearbyChatBar->getRect().getHeight() ); - if (mNearbyChatBar) log(mNearbyChatBar, "after applying compensative width"); - lldebugs << chatbar_shrink_width << llendl; - - // 3. use width available via decreasing of chiclet panel - required_to_process_width -= chatbar_shrink_width; - + // 2. use width available via decreasing of chiclet panel if (required_to_process_width > 0) { mChicletPanel->getParent()->reshape(mChicletPanel->getParent()->getRect().getWidth() - required_to_process_width, mChicletPanel->getParent()->getRect().getHeight()); @@ -1128,10 +1130,10 @@ void LLBottomTray::processWidthIncreased(S32 delta_width) // how many space can nearby chatbar take? - S32 chatbar_panel_width_ = mNearbyChatBar->getRect().getWidth(); - if (delta_width > 0 && chatbar_panel_width_ < chatbar_panel_max_width) + S32 chatbar_panel_width_ = mChatBarContainer->getRect().getWidth(); + if (delta_width > 0 && chatbar_panel_width_ < mDesiredNearbyChatWidth) { - S32 delta_panel_max = chatbar_panel_max_width - chatbar_panel_width_; + S32 delta_panel_max = mDesiredNearbyChatWidth - chatbar_panel_width_; S32 delta_panel = llmin(delta_width, delta_panel_max); lldebugs << "Unprocesed delta width: " << delta_width << ", can be applied to chatbar: " << delta_panel_max @@ -1139,9 +1141,13 @@ void LLBottomTray::processWidthIncreased(S32 delta_width) << llendl; delta_width -= delta_panel_max; - mNearbyChatBar->reshape(chatbar_panel_width_ + delta_panel, mNearbyChatBar->getRect().getHeight()); + mChatBarContainer->reshape(chatbar_panel_width_ + delta_panel, mChatBarContainer->getRect().getHeight()); log(mNearbyChatBar, "applied unprocessed delta width"); } + if (delta_width > 0) + { + processExtendButtons(delta_width); + } } void LLBottomTray::processShowButtons(S32& available_width) @@ -1261,7 +1267,7 @@ void LLBottomTray::processShrinkButtons(S32& required_width, S32& buttons_freed_ S32 panel_min_width = 0; std::string panel_name = mSpeakPanel->getName(); - bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width, NULL); + bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width); if (!success) { lldebugs << "Panel was not found to get its min width: " << panel_name << llendl; @@ -1307,7 +1313,7 @@ void LLBottomTray::processShrinkButton(EResizeState processed_object_type, S32& S32 panel_width = panel->getRect().getWidth(); S32 panel_min_width = 0; std::string panel_name = panel->getName(); - bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width, NULL); + bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width); S32 possible_shrink_width = panel_width - panel_min_width; if (!success) @@ -1526,7 +1532,7 @@ void LLBottomTray::setButtonsControlsAndListeners() // set control name for Build button. It is not enough to link it with Button.SetFloaterToggle in xml std::string vis_control_name = LLFloaterReg::declareVisibilityControl("build"); // Set the button control value (toggle state) to the floater visibility control (Sets the value as well) - build_btn->setControlVariable(LLUI::sSettingGroups["floater"]->getControl(vis_control_name)); + build_btn->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name)); } bool LLBottomTray::toggleShowButton(LLBottomTray::EResizeState button_type, const LLSD& new_visibility) @@ -1599,7 +1605,7 @@ bool LLBottomTray::setVisibleAndFitWidths(EResizeState object_type, bool visible { // Calculate the possible shrunk width as difference between current and minimal widths const S32 chatbar_shrunk_width = - mNearbyChatBar->getRect().getWidth() - get_panel_min_width(mToolbarStack, mNearbyChatBar); + mChatBarContainer->getRect().getWidth() - get_panel_min_width(mToolbarStack, mChatBarContainer); S32 sum_of_min_widths = get_panel_min_width(mToolbarStack, mSpeakPanel); S32 sum_of_curr_widths = get_curr_width(mSpeakPanel); @@ -1619,7 +1625,7 @@ bool LLBottomTray::setVisibleAndFitWidths(EResizeState object_type, bool visible // Minimal width of current panel S32 minimal_width = 0; - mToolbarStack->getPanelMinSize(cur_panel->getName(), &minimal_width, NULL); + mToolbarStack->getPanelMinSize(cur_panel->getName(), &minimal_width); if ( (available_width + possible_shrunk_width) >= minimal_width) { @@ -1696,10 +1702,12 @@ void LLBottomTray::processChatbarCustomization(S32 new_width) { if (NULL == mNearbyChatBar) return; - const S32 delta_width = mNearbyChatBar->getRect().getWidth() - new_width; + const S32 delta_width = mChatBarContainer->getRect().getWidth() - new_width; if (delta_width == 0) return; + mDesiredNearbyChatWidth = new_width; + LLView * chiclet_layout_panel = mChicletPanel->getParent(); const S32 chiclet_min_width = get_panel_min_width(mToolbarStack, chiclet_layout_panel); const S32 chiclet_panel_width = chiclet_layout_panel->getRect().getWidth(); diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index 14a29895f5..8d8a42c553 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -27,20 +27,18 @@ #ifndef LL_LLBOTTOMPANEL_H #define LL_LLBOTTOMPANEL_H -#include "llmenugl.h" - #include "llpanel.h" #include "llimview.h" -#include "llcombobox.h" +#include "llbutton.h" class LLChicletPanel; -class LLLineEditor; class LLLayoutStack; -class LLNotificationChiclet; class LLSpeakButton; class LLNearbyChatBar; class LLIMChiclet; class LLBottomTrayLite; +class LLLayoutPanel; +class LLMenuGL; // Build time optimization, generate once in .cpp file #ifndef LLBOTTOMTRAY_CPP @@ -131,10 +129,12 @@ public: /** * These three methods handle drag'n'drop, they may be called directly from child buttons. + * handleHover and other virtual handle* couldn't be used here, because we should call LLPanel::handle*, + * but x and y here are often outside of bottomtray. */ - /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); - void onDraggableButtonMouseDown(LLUICtrl* button, S32 x, S32 y, MASK mask); - void onDraggableButtonMouseUp(LLUICtrl* button, S32 x, S32 y, MASK mask); + void onDraggableButtonHover(S32 x, S32 y); + void onDraggableButtonMouseDown(LLUICtrl* button, S32 x, S32 y); + void onDraggableButtonMouseUp(LLUICtrl* button, S32 x, S32 y); private: @@ -437,10 +437,15 @@ protected: void onContextMenuItemClicked(const LLSD& userdata); bool onContextMenuItemEnabled(const LLSD& userdata); + // Either default or saved after user's manual resize width of nearby chat. + // Nearby chat will not always have it, because sometimes it can be shrunk on resize, + // but when possible it will be restored back to this value. + S32 mDesiredNearbyChatWidth; LLChicletPanel* mChicletPanel; LLPanel* mSpeakPanel; LLSpeakButton* mSpeakBtn; LLNearbyChatBar* mNearbyChatBar; + LLLayoutPanel* mChatBarContainer; LLLayoutStack* mToolbarStack; LLMenuGL* mBottomTrayContextMenu; LLButton* mCamButton; diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp new file mode 100644 index 0000000000..d6a813d608 --- /dev/null +++ b/indra/newview/llbrowsernotification.cpp @@ -0,0 +1,48 @@ +/** + * @file llbrowsernotification.cpp + * @brief Notification Handler Class for browser popups + * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + + +#include "llviewerprecompiledheaders.h" // must be first include + +#include "llnotificationhandler.h" +#include "llnotifications.h" +#include "llfloaterreg.h" +#include "llmediactrl.h" + +using namespace LLNotificationsUI; + +bool LLBrowserNotification::processNotification(const LLSD& notify) +{ + LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); + if (!notification) return false; + + LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(notification->getPayload()["media_id"].asUUID()); + if (media_instance) + { + media_instance->showNotification(notification); + } + return false; +} diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index c78f73c3b8..b11bba58e4 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -141,7 +141,7 @@ BOOL LLCallFloater::postBuild() childSetAction("leave_call_btn", boost::bind(&LLCallFloater::leaveCall, this)); - mNonAvatarCaller = getChild<LLNonAvatarCaller>("non_avatar_caller"); + mNonAvatarCaller = findChild<LLNonAvatarCaller>("non_avatar_caller"); mNonAvatarCaller->setVisible(FALSE); LLView *anchor_panel = LLBottomTray::getInstance()->getChild<LLView>("speak_flyout_btn"); diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 7d82ec3a71..6e58be8174 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -126,7 +126,7 @@ BOOL LLChatBar::postBuild() mInputEditor->setPassDelete(TRUE); mInputEditor->setReplaceNewlinesWithSpaces(FALSE); - mInputEditor->setMaxTextLength(1023); + mInputEditor->setMaxTextLength(DB_CHAT_MSG_STR_LEN); mInputEditor->setEnableLineHistory(TRUE); mIsBuilt = TRUE; @@ -565,12 +565,20 @@ void LLChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate) { + // as soon as we say something, we no longer care about teaching the user + // how to chat + gWarningSettings.setBOOL("FirstOtherChatBeforeUser", FALSE); + // Look for "/20 foo" channel chats. S32 channel = 0; LLWString out_text = stripChannelNumber(wtext, &channel); std::string utf8_out_text = wstring_to_utf8str(out_text); - std::string utf8_text = wstring_to_utf8str(wtext); + if (!utf8_out_text.empty()) + { + utf8_out_text = utf8str_truncate(utf8_out_text, MAX_MSG_STR_LEN); + } + std::string utf8_text = wstring_to_utf8str(wtext); utf8_text = utf8str_trim(utf8_text); if (!utf8_text.empty()) { @@ -681,14 +689,14 @@ public: } else { - S32 channel = tokens[0].asInteger(); + S32 channel = tokens[0].asInteger(); // VWR-19499 Restrict function to chat channels greater than 0. if ((channel > 0) && (channel < 2147483647)) { retval = true; // Say mesg on channel - std::string mesg = tokens[1].asString(); - send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel); + std::string mesg = tokens[1].asString(); + send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel); } else { diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 1f67a659bd..eb10add254 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -101,7 +101,7 @@ public: static LLChatHistoryHeader* createInstance(const std::string& file_name) { LLChatHistoryHeader* pInstance = new LLChatHistoryHeader; - LLUICtrlFactory::getInstance()->buildPanel(pInstance, file_name); + pInstance->buildFromFile(file_name); return pInstance; } @@ -396,7 +396,7 @@ protected: return; } - LLTextBase* name = getChild<LLTextBase>("user_name"); + LLTextBox* name = getChild<LLTextBox>("user_name"); LLRect sticky_rect = name->getRect(); S32 icon_x = llmin(sticky_rect.mLeft + name->getTextBoundingRect().getWidth() + 7, sticky_rect.mRight - 3); sInfoCtrl->setOrigin(icon_x, sticky_rect.getCenterY() - sInfoCtrl->getRect().getHeight() / 2 ) ; @@ -496,12 +496,17 @@ void LLChatHistory::initFromParams(const LLChatHistory::Params& p) const S32 NEW_TEXT_NOTICE_HEIGHT = 20; - LLPanel::Params panel_p; + LLLayoutPanel::Params panel_p; panel_p.name = "spacer"; panel_p.background_visible = false; panel_p.has_border = false; panel_p.mouse_opaque = false; - stackp->addPanel(LLUICtrlFactory::create<LLPanel>(panel_p), 0, 30, S32_MAX, S32_MAX, true, false, LLLayoutStack::ANIMATE); + panel_p.min_dim = 30; + panel_p.max_dim = S32_MAX; + panel_p.auto_resize = true; + panel_p.user_resize = false; + + stackp->addPanel(LLUICtrlFactory::create<LLLayoutPanel>(panel_p), LLLayoutStack::ANIMATE); panel_p.name = "new_text_notice_holder"; LLRect new_text_notice_rect = getLocalRect(); @@ -510,7 +515,10 @@ void LLChatHistory::initFromParams(const LLChatHistory::Params& p) panel_p.background_opaque = true; panel_p.background_visible = true; panel_p.visible = false; - mMoreChatPanel = LLUICtrlFactory::create<LLPanel>(panel_p); + panel_p.min_dim = 0; + panel_p.auto_resize = false; + panel_p.user_resize = false; + mMoreChatPanel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p); LLTextBox::Params text_p(p.more_chat_text); text_p.rect = mMoreChatPanel->getLocalRect(); @@ -519,7 +527,7 @@ void LLChatHistory::initFromParams(const LLChatHistory::Params& p) mMoreChatText = LLUICtrlFactory::create<LLTextBox>(text_p, mMoreChatPanel); mMoreChatText->setClickedCallback(boost::bind(&LLChatHistory::onClickMoreText, this)); - stackp->addPanel(mMoreChatPanel, 0, 0, S32_MAX, S32_MAX, false, false, LLLayoutStack::ANIMATE); + stackp->addPanel(mMoreChatPanel, LLLayoutStack::ANIMATE); } @@ -760,7 +768,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL if (notification != NULL) { LLIMToastNotifyPanel* notify_box = new LLIMToastNotifyPanel( - notification, chat.mSessionID); + notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history); //we can't set follows in xml since it broke toasts behavior notify_box->setFollowsLeft(); notify_box->setFollowsRight(); diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h index 112a33f1ee..ac48d7bf29 100644 --- a/indra/newview/llchathistory.h +++ b/indra/newview/llchathistory.h @@ -138,7 +138,7 @@ class LLChatHistory : public LLUICtrl S32 mTopHeaderPad; S32 mBottomHeaderPad; - LLPanel* mMoreChatPanel; + class LLLayoutPanel* mMoreChatPanel; LLTextBox* mMoreChatText; LLTextEditor* mEditor; typedef std::set<std::string> unread_chat_source_t; diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 67b7ac5383..e78bdbe25c 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -51,7 +51,7 @@ static const S32 msg_height_pad = 5; LLNearbyChatToastPanel* LLNearbyChatToastPanel::createInstance() { LLNearbyChatToastPanel* item = new LLNearbyChatToastPanel(); - LLUICtrlFactory::getInstance()->buildPanel(item, "panel_chat_item.xml"); + item->buildFromFile("panel_chat_item.xml"); item->setFollows(FOLLOWS_NONE); return item; } diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index b1e11e1a2a..84c560639e 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -397,12 +397,20 @@ void LLCOFWearables::refresh() mCOFVersion = catp->getVersion(); + // Save current scrollbar position. + typedef std::map<LLFlatListView*, LLRect> scroll_pos_map_t; + scroll_pos_map_t saved_scroll_pos; + + saved_scroll_pos[mAttachments] = mAttachments->getVisibleContentRect(); + saved_scroll_pos[mClothing] = mClothing->getVisibleContentRect(); + saved_scroll_pos[mBodyParts] = mBodyParts->getVisibleContentRect(); + + // Save current selection. typedef std::vector<LLSD> values_vector_t; typedef std::map<LLFlatListView*, values_vector_t> selection_map_t; selection_map_t preserve_selection; - // Save current selection mAttachments->getSelectedValues(preserve_selection[mAttachments]); mClothing->getSelectedValues(preserve_selection[mClothing]); mBodyParts->getSelectedValues(preserve_selection[mBodyParts]); @@ -450,6 +458,15 @@ void LLCOFWearables::refresh() list->setCommitOnSelectionChange(true); } + + // Restore previous scrollbar position. + for (scroll_pos_map_t::const_iterator it = saved_scroll_pos.begin(); it != saved_scroll_pos.end(); ++it) + { + LLFlatListView* list = it->first; + LLRect scroll_pos = it->second; + + list->scrollToShowRect(scroll_pos); + } } diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index 268d9958d1..a42677845e 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -89,7 +89,6 @@ LLFloaterScriptQueue::LLFloaterScriptQueue(const LLSD& key) : mDone(false), mMono(false) { - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_script_queue.xml", FALSE); } // Destroys the object diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index f0c2469977..5e10f60aba 100644 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -121,7 +121,6 @@ LLExpandableTextBox::LLTextBoxEx::LLTextBoxEx(const Params& p) void LLExpandableTextBox::LLTextBoxEx::reshape(S32 width, S32 height, BOOL called_from_parent) { - hideExpandText(); LLTextEditor::reshape(width, height, called_from_parent); if (getTextPixelHeight() > getRect().getHeight()) diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index b715647143..a09c0ea0f8 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -117,7 +117,7 @@ BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask) { S32 bar_idx = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight()); bar_idx = llclamp(bar_idx, 0, MAX_VISIBLE_HISTORY); - mPrintStats = bar_idx; + mPrintStats = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - bar_idx; } return FALSE; } @@ -134,6 +134,17 @@ LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y) return NULL; } +BOOL LLFastTimerView::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + it != end_timer_tree(); + ++it) + { + (*it)->setCollapsed(false); + } + return TRUE; +} + BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask) { @@ -947,7 +958,7 @@ void LLFastTimerView::draw() { legend_stat += ", "; } - first = true; + first = false; legend_stat += idp->getName(); if (idp->getCollapsed()) @@ -974,8 +985,7 @@ void LLFastTimerView::draw() U64 ticks; if (mPrintStats > 0) { - S32 hidx = (mPrintStats - 1) - mScrollIndex; - ticks = idp->getHistoricalCount(hidx); + ticks = idp->getHistoricalCount(mPrintStats); } else { diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index 961d03abf1..3788897cec 100644 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -48,6 +48,7 @@ private: public: virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 5796e67618..3981b887ad 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -161,22 +161,13 @@ public: if (!region_name.empty()) { - LLToolTip::Params params; std::string extra_message = llformat("%s (%d, %d, %d)", region_name.c_str(), mLandmarkInfoGetter.getPosX(), mLandmarkInfoGetter.getPosY(), mLandmarkInfoGetter.getPosZ()); + LLToolTip::Params params; params.message = llformat("%s\n%s", getLabelSelected().c_str(), extra_message.c_str()); - - LLRect rect = calcScreenRect(); - LLFontGL* standart_font = LLFontGL::getFontSansSerif(); - if(standart_font) - { - S32 w = llmax((S32)(standart_font->getWidthF32(getLabelSelected())+0.5),(S32)(standart_font->getWidthF32(extra_message)+0.5)); - rect.mRight = rect.mLeft + w; - params.max_width = w; - } - - params.sticky_rect = rect; + params.max_width = 1000; + params.sticky_rect = calcScreenRect(); LLToolTipMgr::instance().show(params); } @@ -299,20 +290,6 @@ public: return TRUE; } - void setVisible(BOOL b) - { - // Overflow menu shouldn't hide when it still has focus. See EXT-4217. - if (!b && hasFocus()) - return; - LLToggleableMenu::setVisible(b); - setFocus(b); - } - - void onFocusLost() - { - setVisible(FALSE); - } - protected: LLFavoriteLandmarkToggleableMenu(const LLToggleableMenu::Params& p): LLToggleableMenu(p) @@ -661,16 +638,23 @@ void LLFavoritesBarCtrl::draw() } } -LLXMLNodePtr LLFavoritesBarCtrl::getButtonXMLNode() +const LLButton::Params& LLFavoritesBarCtrl::getButtonParams() { - LLXMLNodePtr buttonXMLNode = NULL; - bool success = LLUICtrlFactory::getLayeredXMLNode("favorites_bar_button.xml", buttonXMLNode); - if (!success) + static LLButton::Params button_params; + static bool params_initialized = false; + + if (!params_initialized) { - llwarns << "Failed to create Favorites Bar button from favorites_bar_button.xml" << llendl; - buttonXMLNode = NULL; + LLXMLNodePtr button_xml_node; + if(LLUICtrlFactory::getLayeredXMLNode("favorites_bar_button.xml", button_xml_node)) + { + LLXUIParser parser; + parser.readXUI(button_xml_node, button_params, "favorites_bar_button.xml"); + } + params_initialized = true; } - return buttonXMLNode; + + return button_params; } void LLFavoritesBarCtrl::updateButtons() @@ -682,11 +666,8 @@ void LLFavoritesBarCtrl::updateButtons() return; } - static LLXMLNodePtr buttonXMLNode = getButtonXMLNode(); - if (buttonXMLNode.isNull()) - { - return; - } + const LLButton::Params& button_params = getButtonParams(); + if(mItems.empty()) { mBarLabel->setVisible(TRUE); @@ -762,7 +743,7 @@ void LLFavoritesBarCtrl::updateButtons() int j = first_changed_item_index; for (; j < mItems.count(); j++) { - last_new_button = createButton(mItems[j], buttonXMLNode, last_right_edge); + last_new_button = createButton(mItems[j], button_params, last_right_edge); if (!last_new_button) { break; @@ -780,8 +761,7 @@ void LLFavoritesBarCtrl::updateButtons() //or there are some new favorites, or width had been changed // so if we need to display chevron button, we must update dropdown items too. mUpdateDropDownItems = true; - S32 buttonHGap = 2; // default value - buttonXMLNode->getAttributeS32("left", buttonHGap); + S32 buttonHGap = button_params.rect.left; // default value LLRect rect; // Chevron button should stay right aligned rect.setOriginAndSize(getRect().mRight - mChevronButton->getRect().getWidth() - buttonHGap, 0, @@ -796,7 +776,6 @@ void LLFavoritesBarCtrl::updateButtons() LLToggleableMenu* overflow_menu = static_cast <LLToggleableMenu*> (mPopupMenuHandle.get()); if (overflow_menu && overflow_menu->getVisible()) { - overflow_menu->setFocus(FALSE); overflow_menu->setVisible(FALSE); if (mUpdateDropDownItems) showDropDownMenu(); @@ -808,12 +787,10 @@ void LLFavoritesBarCtrl::updateButtons() } } -LLButton* LLFavoritesBarCtrl::createButton(const LLPointer<LLViewerInventoryItem> item, LLXMLNodePtr &buttonXMLNode, S32 x_offset) +LLButton* LLFavoritesBarCtrl::createButton(const LLPointer<LLViewerInventoryItem> item, const LLButton::Params& button_params, S32 x_offset) { - S32 def_button_width = 120; - buttonXMLNode->getAttributeS32("width", def_button_width); - S32 button_x_delta = 2; // default value - buttonXMLNode->getAttributeS32("left", button_x_delta); + S32 def_button_width = button_params.rect.width; + S32 button_x_delta = button_params.rect.left; // default value S32 curr_x = x_offset; /** @@ -831,13 +808,16 @@ LLButton* LLFavoritesBarCtrl::createButton(const LLPointer<LLViewerInventoryItem { return NULL; } - fav_btn = LLUICtrlFactory::defaultBuilder<LLFavoriteLandmarkButton>(buttonXMLNode, this, NULL); + LLButton::Params fav_btn_params(button_params); + fav_btn = LLUICtrlFactory::create<LLFavoriteLandmarkButton>(fav_btn_params); if (NULL == fav_btn) { llwarns << "Unable to create LLFavoriteLandmarkButton widget: " << item->getName() << llendl; return NULL; } + addChild(fav_btn); + LLRect butt_rect (fav_btn->getRect()); fav_btn->setLandmarkID(item->getUUID()); butt_rect.setOriginAndSize(curr_x + button_x_delta, fav_btn->getRect().mBottom, width, fav_btn->getRect().getHeight()); @@ -916,8 +896,6 @@ void LLFavoritesBarCtrl::showDropDownMenu() if (menu) { - // Release focus to allow changing of visibility. - menu->setFocus(FALSE); if (!menu->toggleVisibility()) return; @@ -1098,6 +1076,14 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata) { gInventory.removeItem(mSelectedItemID); } + + // Pop-up the overflow menu again (it gets hidden whenever the user clicks a context menu item). + // See EXT-4217 and STORM-207. + LLToggleableMenu* menu = (LLToggleableMenu*) mPopupMenuHandle.get(); + if (menu && !menu->getVisible()) + { + showDropDownMenu(); + } } BOOL LLFavoritesBarCtrl::isClipboardPasteable() const diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index bdb1b8288f..37645523f6 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -71,8 +71,8 @@ public: protected: void updateButtons(); - LLButton* createButton(const LLPointer<LLViewerInventoryItem> item, LLXMLNodePtr &root, S32 x_offset ); - LLXMLNodePtr getButtonXMLNode(); + LLButton* createButton(const LLPointer<LLViewerInventoryItem> item, const LLButton::Params& button_params, S32 x_offset ); + const LLButton::Params& getButtonParams(); BOOL collectFavoriteItems(LLInventoryModel::item_array_t &items); void onButtonClick(LLUUID id); diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp index 4d5b08243a..dd08706f4f 100644 --- a/indra/newview/llfirstuse.cpp +++ b/indra/newview/llfirstuse.cpp @@ -30,7 +30,7 @@ // library includes #include "indra_constants.h" -#include "llnotificationsutil.h" +#include "llnotifications.h" // viewer includes #include "llagent.h" // for gAgent.inPrelude() @@ -39,7 +39,7 @@ #include "llappviewer.h" #include "lltracker.h" -/* + // static std::set<std::string> LLFirstUse::sConfigVariables; @@ -70,211 +70,109 @@ void LLFirstUse::resetFirstUse() gWarningSettings.setBOOL(*iter, TRUE); } } -*/ -/* - -// Called whenever the viewer detects that your balance went up -void LLFirstUse::useBalanceIncrease(S32 delta) -{ - if (gWarningSettings.getBOOL("FirstBalanceIncrease")) - { - gWarningSettings.setBOOL("FirstBalanceIncrease", FALSE); - - LLSD args; - args["AMOUNT"] = llformat("%d",delta); - LLNotificationsUtil::add("FirstBalanceIncrease", args); - } -} - - -// Called whenever the viewer detects your balance went down -void LLFirstUse::useBalanceDecrease(S32 delta) -{ - if (gWarningSettings.getBOOL("FirstBalanceDecrease")) - { - gWarningSettings.setBOOL("FirstBalanceDecrease", FALSE); - - LLSD args; - args["AMOUNT"] = llformat("%d",-delta); - LLNotificationsUtil::add("FirstBalanceDecrease", args); - } -} - // static -void LLFirstUse::useSit() +void LLFirstUse::otherAvatarChatFirst(bool enable) { - // Our orientation island uses sitting to teach vehicle driving - // so just never show this message. JC - //if (gWarningSettings.getBOOL("FirstSit")) - //{ - // gWarningSettings.setBOOL("FirstSit", FALSE); - // - // LLNotificationsUtil::add("FirstSit"); - //} + firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "chat_bar").with("direction", "top_right").with("distance", 24)); } // static -void LLFirstUse::useMap() +void LLFirstUse::sit(bool enable) { - if (gWarningSettings.getBOOL("FirstMap")) - { - gWarningSettings.setBOOL("FirstMap", FALSE); - - LLNotificationsUtil::add("FirstMap"); - } + firstUseNotification("FirstSit", enable, "HintSit", LLSD(), LLSD().with("target", "stand_btn").with("direction", "top")); } // static -void LLFirstUse::useGoTo() +void LLFirstUse::newInventory(bool enable) { - // nothing for now JC + // turning this off until bug EXP-62 can be fixed (inventory hint appears for new users when their initial inventory is acquired) + // firstUseNotification("FirstInventoryOffer", enable, "HintInventory", LLSD(), LLSD().with("target", "inventory_btn").with("direction", "left")); } // static -void LLFirstUse::useBuild() +void LLFirstUse::useSandbox() { - if (gWarningSettings.getBOOL("FirstBuild")) - { - gWarningSettings.setBOOL("FirstBuild", FALSE); - - LLNotificationsUtil::add("FirstBuild"); - } + firstUseNotification("FirstSandbox", true, "FirstSandbox", LLSD().with("HOURS", SANDBOX_CLEAN_FREQ).with("TIME", SANDBOX_FIRST_CLEAN_HOUR)); } - - */ -/* -// static -void LLFirstUse::useLeftClickNoHit() -{ - if (gWarningSettings.getBOOL("FirstLeftClickNoHit")) - { - gWarningSettings.setBOOL("FirstLeftClickNoHit", FALSE); - LLNotificationsUtil::add("FirstLeftClickNoHit"); - } -} -*/ -/* // static -void LLFirstUse::useTeleport() +void LLFirstUse::notUsingDestinationGuide(bool enable) { - if (gWarningSettings.getBOOL("FirstTeleport")) - { - LLVector3d teleportDestination = LLTracker::getTrackedPositionGlobal(); - if(teleportDestination != LLVector3d::zero) - { - gWarningSettings.setBOOL("FirstTeleport", FALSE); - - LLNotificationsUtil::add("FirstTeleport"); - } - } + // not doing this yet + //firstUseNotification("FirstNotUseDestinationGuide", enable, "HintDestinationGuide", LLSD(), LLSD().with("target", "dest_guide_btn").with("direction", "left")); } -*/ -// static -void LLFirstUse::useOverrideKeys() -{ - // Our orientation island uses key overrides to teach vehicle driving - // so don't show this message until you get off OI. JC - if (!gAgent.inPrelude()) - { - if (gWarningSettings.getBOOL("FirstOverrideKeys")) - { - gWarningSettings.setBOOL("FirstOverrideKeys", FALSE); - LLNotificationsUtil::add("FirstOverrideKeys"); - } - } -} -/* // static -void LLFirstUse::useAttach() +void LLFirstUse::notUsingSidePanel(bool enable) { - // nothing for now + // not doing this yet + //firstUseNotification("FirstNotUseSidePanel", enable, "HintSidePanel", LLSD(), LLSD().with("target", "side_panel_btn").with("direction", "left")); } // static -void LLFirstUse::useAppearance() +void LLFirstUse::notMoving(bool enable) { - if (gWarningSettings.getBOOL("FirstAppearance")) - { - gWarningSettings.setBOOL("FirstAppearance", FALSE); - - LLNotificationsUtil::add("FirstAppearance"); - } + firstUseNotification("FirstNotMoving", enable, "HintMove", LLSD(), LLSD().with("target", "move_btn").with("direction", "top")); } // static -void LLFirstUse::useInventory() +void LLFirstUse::receiveLindens(bool enable) { - if (gWarningSettings.getBOOL("FirstInventory")) - { - gWarningSettings.setBOOL("FirstInventory", FALSE); - - LLNotificationsUtil::add("FirstInventory"); - } + firstUseNotification("FirstReceiveLindens", enable, "HintLindenDollar", LLSD(), LLSD().with("target", "linden_balance").with("direction", "bottom")); } -*/ -// static -void LLFirstUse::useSandbox() +//static +void LLFirstUse::firstUseNotification(const std::string& control_var, bool enable, const std::string& notification_name, LLSD args, LLSD payload) { - if (gWarningSettings.getBOOL("FirstSandbox")) - { - gWarningSettings.setBOOL("FirstSandbox", FALSE); + init(); - LLSD args; - args["HOURS"] = llformat("%d",SANDBOX_CLEAN_FREQ); - args["TIME"] = llformat("%d",SANDBOX_FIRST_CLEAN_HOUR); - LLNotificationsUtil::add("FirstSandbox", args); - } -} -/* -// static -void LLFirstUse::useFlexible() -{ - if (gWarningSettings.getBOOL("FirstFlexible")) + if (enable) { - gWarningSettings.setBOOL("FirstFlexible", FALSE); - - LLNotificationsUtil::add("FirstFlexible"); - } -} + if (gSavedSettings.getBOOL("EnableUIHints")) + { + LL_DEBUGS("LLFirstUse") << "Trigger first use notification " << notification_name << LL_ENDL; -// static -void LLFirstUse::useDebugMenus() -{ - if (gWarningSettings.getBOOL("FirstDebugMenus")) + // if notification doesn't already exist and this notification hasn't been disabled... + if (gWarningSettings.getBOOL(control_var)) + { // create new notification + LLNotifications::instance().add(LLNotification::Params().name(notification_name).substitutions(args).payload(payload.with("control_var", control_var))); + } + } + } + else { - gWarningSettings.setBOOL("FirstDebugMenus", FALSE); - - LLNotificationsUtil::add("FirstDebugMenus"); + LL_DEBUGS("LLFirstUse") << "Disabling first use notification " << notification_name << LL_ENDL; + LLNotifications::instance().cancelByName(notification_name); + // redundantly clear settings var here, in case there are no notifications to cancel + gWarningSettings.setBOOL(control_var, FALSE); } + } // static -void LLFirstUse::useSculptedPrim() +void LLFirstUse::init() { - if (gWarningSettings.getBOOL("FirstSculptedPrim")) + static bool initialized = false; + if (!initialized) { - gWarningSettings.setBOOL("FirstSculptedPrim", FALSE); - - LLNotificationsUtil::add("FirstSculptedPrim"); - + LLNotifications::instance().getChannel("Hints")->connectChanged(&processNotification); } + initialized = true; } -// static -void LLFirstUse::useMedia() +//static +bool LLFirstUse::processNotification(const LLSD& notify) { - if (gWarningSettings.getBOOL("FirstMedia")) + if (notify["sigtype"].asString() == "delete") { - gWarningSettings.setBOOL("FirstMedia", FALSE); - - // Popup removed as a short-term fix for EXT-1643. - // Ultimately, the plan is to kill all First Use dialogs - //LLNotificationsUtil::add("FirstMedia"); + LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); + if (notification) + { + // disable any future notifications + gWarningSettings.setBOOL(notification->getPayload()["control_var"], FALSE); + } } + return false; } -*/ diff --git a/indra/newview/llfirstuse.h b/indra/newview/llfirstuse.h index 771e38ed33..275f134400 100644 --- a/indra/newview/llfirstuse.h +++ b/indra/newview/llfirstuse.h @@ -70,10 +70,13 @@ object or from inventory. 14. First time you create/edit a sculpted prim. */ +class LLNotification; + + class LLFirstUse { public: -/* + // Add a config variable to be reset on resetFirstUse() static void addConfigVariable(const std::string& var); @@ -81,35 +84,21 @@ public: static void disableFirstUse(); static void resetFirstUse(); - // These methods are called each time the appropriate action is - // taken. The functions themselves handle only showing the dialog - // the first time, or subsequent times if the user wishes. - static void useBalanceIncrease(S32 delta); - static void useBalanceDecrease(S32 delta); - static void useSit(); - static void useMap(); - static void useGoTo(); - static void useBuild(); -// static void useLeftClickNoHit(); - static void useTeleport(); -*/ - static void useOverrideKeys(); -/* - static void useAttach(); - static void useAppearance(); - static void useInventory(); - */ + static void otherAvatarChatFirst(bool enable = true); + static void sit(bool enable = true); + static void notUsingDestinationGuide(bool enable = true); + static void notUsingSidePanel(bool enable = true); + static void notMoving(bool enable = true); + static void newInventory(bool enable = true); + static void receiveLindens(bool enable = true); static void useSandbox(); -/* - static void useFlexible(); - static void useDebugMenus(); - static void useSculptedPrim(); - static void useMedia(); - protected: + static void firstUseNotification(const std::string& control_var, bool enable, const std::string& notification_name, LLSD args = LLSD(), LLSD payload = LLSD()); static std::set<std::string> sConfigVariables; -*/ + + static void init(); + static bool processNotification(const LLSD& notify); }; #endif diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 5ac006302e..135137069c 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -94,7 +94,6 @@ public: LLFloaterAbout::LLFloaterAbout(const LLSD& key) : LLFloater(key) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about.xml"); } diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp index 5cab770c42..252c7b51ae 100644 --- a/indra/newview/llfloaterauction.cpp +++ b/indra/newview/llfloaterauction.cpp @@ -74,7 +74,6 @@ LLFloaterAuction::LLFloaterAuction(const LLSD& key) : LLFloater(key), mParcelID(-1) { -// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_auction.xml"); mCommitCallbackRegistrar.add("ClickSnapshot", boost::bind(&LLFloaterAuction::onClickSnapshot, this)); mCommitCallbackRegistrar.add("ClickSellToAnyone", boost::bind(&LLFloaterAuction::onClickSellToAnyone, this)); mCommitCallbackRegistrar.add("ClickStartAuction", boost::bind(&LLFloaterAuction::onClickStartAuction, this)); diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 9391c761b7..9f96a22f56 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -79,7 +79,6 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key) mNearMeListComplete(FALSE), mCloseOnSelect(FALSE) { -// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_avatar_picker.xml"); mCommitCallbackRegistrar.add("Refresh.FriendList", boost::bind(&LLFloaterAvatarPicker::populateFriend, this)); } diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp index a6613968fb..10cf26521f 100644 --- a/indra/newview/llfloateravatartextures.cpp +++ b/indra/newview/llfloateravatartextures.cpp @@ -40,7 +40,6 @@ LLFloaterAvatarTextures::LLFloaterAvatarTextures(const LLSD& id) : LLFloater(id), mID(id.asUUID()) { -// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_avatar_textures.xml"); } LLFloaterAvatarTextures::~LLFloaterAvatarTextures() diff --git a/indra/newview/llfloaterbeacons.cpp b/indra/newview/llfloaterbeacons.cpp index 0b8605d041..e24df948c4 100644 --- a/indra/newview/llfloaterbeacons.cpp +++ b/indra/newview/llfloaterbeacons.cpp @@ -36,8 +36,6 @@ LLFloaterBeacons::LLFloaterBeacons(const LLSD& seed) : LLFloater(seed) { -// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_beacons.xml"); - // Initialize pipeline states from saved settings. // OK to do at floater constructor time because beacons do not display unless the floater is open // therefore it is OK to not initialize the pipeline state before needed. diff --git a/indra/newview/llfloaterbuildoptions.cpp b/indra/newview/llfloaterbuildoptions.cpp index 7e939a537d..4b6fe4a115 100644 --- a/indra/newview/llfloaterbuildoptions.cpp +++ b/indra/newview/llfloaterbuildoptions.cpp @@ -40,7 +40,6 @@ LLFloaterBuildOptions::LLFloaterBuildOptions(const LLSD& key) : LLFloater(key) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_build_options.xml"); } LLFloaterBuildOptions::~LLFloaterBuildOptions() diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp index 02c7a6da7e..90f40628a8 100644 --- a/indra/newview/llfloaterbulkpermission.cpp +++ b/indra/newview/llfloaterbulkpermission.cpp @@ -57,7 +57,6 @@ LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed) mDone(FALSE) { mID.generate(); -// LLUICtrlFactory::getInstance()->buildFloater(this,"floater_bulk_perms.xml"); mCommitCallbackRegistrar.add("BulkPermission.Apply", boost::bind(&LLFloaterBulkPermission::onApplyBtn, this)); mCommitCallbackRegistrar.add("BulkPermission.Close", boost::bind(&LLFloaterBulkPermission::onCloseBtn, this)); mCommitCallbackRegistrar.add("BulkPermission.CheckAll", boost::bind(&LLFloaterBulkPermission::onCheckAll, this)); diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp index af98453c3c..a02b67f08e 100644 --- a/indra/newview/llfloaterbump.cpp +++ b/indra/newview/llfloaterbump.cpp @@ -45,7 +45,6 @@ LLFloaterBump::LLFloaterBump(const LLSD& key) : LLFloater(key) { if(gNoRender) return; - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_bumps.xml"); } diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index 32add57737..f46a2be0fa 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -51,7 +51,6 @@ LLFloaterBuy::LLFloaterBuy(const LLSD& key) : LLFloater(key) { -// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_object.xml"); } BOOL LLFloaterBuy::postBuild() diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index 77fb5590df..a7388d21a3 100644 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -41,6 +41,7 @@ #include "llinventorydefines.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" // for gInventory +#include "llfirstuse.h" #include "llfloaterreg.h" #include "llfloaterinventory.h" // for LLInventoryIcon::getIcon #include "llnotificationsutil.h" @@ -54,7 +55,6 @@ LLFloaterBuyContents::LLFloaterBuyContents(const LLSD& key) : LLFloater(key) { -// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_contents.xml"); } BOOL LLFloaterBuyContents::postBuild() @@ -284,6 +284,10 @@ void LLFloaterBuyContents::onClickBuy() // it doesn't match region info then sale is canceled. LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, mSaleInfo); + // NOTE: do this here instead of on receipt of object, since contents are transfered + // via a generic BulkUpdateInventory message with no way of distinguishing it from + // other inventory operations + LLFirstUse::newInventory(); closeFloater(); } diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index a5c62495fe..e48e1ab64f 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -294,7 +294,6 @@ LLFloaterBuyLandUI::LLFloaterBuyLandUI(const LLSD& key) { LLViewerParcelMgr::getInstance()->addObserver(&mParcelSelectionObserver); -// LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_buy_land.xml"); } LLFloaterBuyLandUI::~LLFloaterBuyLandUI() diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index d4067452b0..ad24c6534a 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -345,7 +345,7 @@ BOOL LLFloaterCamera::postBuild() setTitleVisible(TRUE); // restore title visibility after chrome applying mRotate = getChild<LLJoystickCameraRotate>(ORBIT); - mZoom = getChild<LLPanelCameraZoom>(ZOOM); + mZoom = findChild<LLPanelCameraZoom>(ZOOM); mTrack = getChild<LLJoystickCameraTrack>(PAN); assignButton2Mode(CAMERA_CTRL_MODE_MODES, "avatarview_btn"); diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index 89e745f651..69f1774ff8 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -107,9 +107,8 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show mCanApplyImmediately ( show_apply_immediate ), mContextConeOpacity ( 0.f ) { - // build the majority of the gui using the factory builder - LLUICtrlFactory::getInstance()->buildFloater ( this, "floater_color_picker.xml", NULL ); - + buildFromFile ( "floater_color_picker.xml"); + // create user interface for this picker createUI (); diff --git a/indra/newview/llfloaterdaycycle.cpp b/indra/newview/llfloaterdaycycle.cpp index aacb543267..22816ee802 100644 --- a/indra/newview/llfloaterdaycycle.cpp +++ b/indra/newview/llfloaterdaycycle.cpp @@ -59,7 +59,6 @@ const F32 LLFloaterDayCycle::sHoursPerDay = 24.0f; LLFloaterDayCycle::LLFloaterDayCycle(const LLSD& key) : LLFloater(key) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_day_cycle_options.xml"); } BOOL LLFloaterDayCycle::postBuild() diff --git a/indra/newview/llfloaterenvsettings.cpp b/indra/newview/llfloaterenvsettings.cpp index 337d4934e1..fcaef1f34b 100644 --- a/indra/newview/llfloaterenvsettings.cpp +++ b/indra/newview/llfloaterenvsettings.cpp @@ -50,7 +50,6 @@ LLFloaterEnvSettings::LLFloaterEnvSettings(const LLSD& key) : LLFloater(key) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_env_settings.xml"); } // virtual LLFloaterEnvSettings::~LLFloaterEnvSettings() diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp index f95112a8ab..2dbe324586 100644 --- a/indra/newview/llfloatergodtools.cpp +++ b/indra/newview/llfloatergodtools.cpp @@ -121,8 +121,6 @@ LLFloaterGodTools::LLFloaterGodTools(const LLSD& key) mFactoryMap["region"] = LLCallbackMap(createPanelRegion, this); mFactoryMap["objects"] = LLCallbackMap(createPanelObjects, this); mFactoryMap["request"] = LLCallbackMap(createPanelRequest, this); -// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_god_tools.xml"); - } BOOL LLFloaterGodTools::postBuild() diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index 3cd2154531..234a09d157 100644 --- a/indra/newview/llfloatergroups.cpp +++ b/indra/newview/llfloatergroups.cpp @@ -338,11 +338,10 @@ void LLPanelGroups::onGroupList(LLUICtrl* ctrl, void* userdata) if(self) self->enableButtons(); } -void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, U64 powers_mask) +void init_group_list(LLScrollListCtrl* group_list, const LLUUID& highlight_id, U64 powers_mask) { S32 count = gAgent.mGroups.count(); LLUUID id; - LLCtrlListInterface *group_list = ctrl->getListInterface(); if (!group_list) return; group_list->operateOnAll(LLCtrlListInterface::OP_DELETE); @@ -366,10 +365,12 @@ void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, U64 pow element["columns"][0]["font"]["name"] = "SANSSERIF"; element["columns"][0]["font"]["style"] = style; - group_list->addElement(element, ADD_SORTED); + group_list->addElement(element); } } + group_list->sortOnce(0, TRUE); + // add "none" to list at top { std::string style = "NORMAL"; diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp index 2985626bd7..77af054522 100644 --- a/indra/newview/llfloaterhardwaresettings.cpp +++ b/indra/newview/llfloaterhardwaresettings.cpp @@ -56,7 +56,6 @@ LLFloaterHardwareSettings::LLFloaterHardwareSettings(const LLSD& key) mFogRatio(0.0), mProbeHardwareOnStartup(FALSE) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_hardware_settings.xml"); } LLFloaterHardwareSettings::~LLFloaterHardwareSettings() diff --git a/indra/newview/llfloaterhud.cpp b/indra/newview/llfloaterhud.cpp index 8fc0598248..4181d1906e 100644 --- a/indra/newview/llfloaterhud.cpp +++ b/indra/newview/llfloaterhud.cpp @@ -54,8 +54,6 @@ LLFloaterHUD::LLFloaterHUD(const LLSD& key) return; } - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_hud.xml"); - // Don't grab the focus as it will impede performing in-world actions // while using the HUD setIsChrome(TRUE); diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index 8e7f7e083c..691f1b206c 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -47,7 +47,6 @@ LLFloaterInspect::LLFloaterInspect(const LLSD& key) : LLFloater(key), mDirty(FALSE) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inspect.xml"); mCommitCallbackRegistrar.add("Inspect.OwnerProfile", boost::bind(&LLFloaterInspect::onClickOwnerProfile, this)); mCommitCallbackRegistrar.add("Inspect.CreatorProfile", boost::bind(&LLFloaterInspect::onClickCreatorProfile, this)); mCommitCallbackRegistrar.add("Inspect.SelectObject", boost::bind(&LLFloaterInspect::onSelectObject, this)); diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp index 0891023a6d..df769bdd88 100644 --- a/indra/newview/llfloaterinventory.cpp +++ b/indra/newview/llfloaterinventory.cpp @@ -54,7 +54,7 @@ LLFloaterInventory::~LLFloaterInventory() BOOL LLFloaterInventory::postBuild() { - mPanelMainInventory = getChild<LLPanelMainInventory>("Inventory Panel"); + mPanelMainInventory = findChild<LLPanelMainInventory>("Inventory Panel"); return TRUE; } diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index e1994bb8bc..c37798c330 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -44,8 +44,6 @@ LLFloaterJoystick::LLFloaterJoystick(const LLSD& data) : LLFloater(data) { - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_joystick.xml"); - initFromSettings(); } diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp index a92273521f..68b1770bb2 100644 --- a/indra/newview/llfloaterlagmeter.cpp +++ b/indra/newview/llfloaterlagmeter.cpp @@ -47,7 +47,6 @@ const std::string LAG_GOOD_IMAGE_NAME = "lag_status_good.tga"; LLFloaterLagMeter::LLFloaterLagMeter(const LLSD& key) : LLFloater(key) { -// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_lagmeter.xml"); mCommitCallbackRegistrar.add("LagMeter.ClickShrink", boost::bind(&LLFloaterLagMeter::onClickShrink, this)); } diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 2f080ab334..e124263db5 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -248,8 +248,6 @@ LLFloaterLand::LLFloaterLand(const LLSD& seed) mFactoryMap["land_media_panel"] = LLCallbackMap(createPanelLandMedia, this); mFactoryMap["land_access_panel"] = LLCallbackMap(createPanelLandAccess, this); - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about_land.xml", false); - sObserver = new LLParcelSelectionObserver(); LLViewerParcelMgr::getInstance()->addObserver( sObserver ); } @@ -567,7 +565,10 @@ void LLPanelLandGeneral::refresh() if (regionp) { insert_maturity_into_textbox(mContentRating, gFloaterView->getParentFloater(this), MATURITY); - mLandType->setText(LLTrans::getString(regionp->getSimProductName())); + + std::string land_type; + bool is_land_type_localized = LLTrans::findString(land_type, regionp->getSimProductName()); + mLandType->setText(is_land_type_localized ? land_type : regionp->getSimProductName()); } // estate owner/manager cannot edit other parts of the parcel @@ -2434,7 +2435,7 @@ void LLPanelLandAccess::refresh() suffix.append(" " + parent_floater->getString("Remaining") + ")"); } if (mListAccess) - mListAccess->addNameItem(entry.mID, ADD_SORTED, TRUE, suffix); + mListAccess->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix); } } @@ -2475,7 +2476,7 @@ void LLPanelLandAccess::refresh() } suffix.append(" " + parent_floater->getString("Remaining") + ")"); } - mListBanned->addNameItem(entry.mID, ADD_SORTED, TRUE, suffix); + mListBanned->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix); } } diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp index 31f20fbd29..98e9b74278 100644 --- a/indra/newview/llfloaterlandholdings.cpp +++ b/indra/newview/llfloaterlandholdings.cpp @@ -60,7 +60,6 @@ LLFloaterLandHoldings::LLFloaterLandHoldings(const LLSD& key) mSortColumn(""), mSortAscending(TRUE) { -// LLUICtrlFactory::getInstance()->buildFloater(floater, "floater_land_holdings.xml"); } BOOL LLFloaterLandHoldings::postBuild() @@ -69,10 +68,9 @@ BOOL LLFloaterLandHoldings::postBuild() childSetAction("Show on Map", onClickMap, this); // Grant list - getChild<LLScrollListCtrl>("grant list")->setDoubleClickCallback(onGrantList, this); - - LLCtrlListInterface *list = childGetListInterface("grant list"); - if (!list) return TRUE; + LLScrollListCtrl* grant_list = getChild<LLScrollListCtrl>("grant list"); + grant_list->sortByColumnIndex(0, TRUE); + grant_list->setDoubleClickCallback(onGrantList, this); S32 count = gAgent.mGroups.count(); for(S32 i = 0; i < count; ++i) @@ -91,7 +89,7 @@ BOOL LLFloaterLandHoldings::postBuild() element["columns"][1]["value"] = areastr; element["columns"][1]["font"] = "SANSSERIF"; - list->addElement(element, ADD_SORTED); + grant_list->addElement(element); } center(); diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index c9d7eff02b..a1d291fea6 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -72,7 +72,6 @@ LLFloaterMap::LLFloaterMap(const LLSD& key) mTextBoxSouthWest(NULL), mMap(NULL) { - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_map.xml", FALSE); } LLFloaterMap::~LLFloaterMap() @@ -96,7 +95,7 @@ BOOL LLFloaterMap::postBuild() mTextBoxNorthWest = getChild<LLTextBox> ("floater_map_northwest"); LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - + registrar.add("Minimap.Zoom", boost::bind(&LLFloaterMap::handleZoom, this, _2)); registrar.add("Minimap.Tracker", boost::bind(&LLFloaterMap::handleStopTracking, this, _2)); @@ -125,7 +124,9 @@ BOOL LLFloaterMap::postBuild() BOOL LLFloaterMap::handleDoubleClick( S32 x, S32 y, MASK mask ) { - LLFloaterReg::showInstance("world_map"); + // If floater is minimized, minimap should be shown on doubleclick (STORM-299) + std::string floater_to_show = this->isMinimized() ? "mini_map" : "world_map"; + LLFloaterReg::showInstance(floater_to_show); return TRUE; } @@ -258,7 +259,7 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent) void LLFloaterMap::handleZoom(const LLSD& userdata) { std::string level = userdata.asString(); - + F32 scale = 0.0f; if (level == std::string("close")) scale = LLNetMap::MAP_SCALE_MAX; diff --git a/indra/newview/llfloatermediabrowser.cpp b/indra/newview/llfloatermediabrowser.cpp index 434d0681ab..d20092e344 100644 --- a/indra/newview/llfloatermediabrowser.cpp +++ b/indra/newview/llfloatermediabrowser.cpp @@ -45,7 +45,11 @@ #include "llviewermedia.h" #include "llviewerparcelmedia.h" #include "llcombobox.h" +#include "llwindow.h" +#include "lllayoutstack.h" +#include "llcheckboxctrl.h" +#include "llnotifications.h" // TEMP #include "llsdutil.h" @@ -53,10 +57,124 @@ LLFloaterMediaBrowser::LLFloaterMediaBrowser(const LLSD& key) : LLFloater(key) { -// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_media_browser.xml"); +} + +//static +void LLFloaterMediaBrowser::create(const std::string &url, const std::string& target, const std::string& uuid) +{ + lldebugs << "url = " << url << ", target = " << target << ", uuid = " << uuid << llendl; + + std::string tag = target; + + if(target.empty() || target == "_blank") + { + if(!uuid.empty()) + { + tag = uuid; + } + else + { + // create a unique tag for this instance + LLUUID id; + id.generate(); + tag = id.asString(); + } + } + + S32 browser_window_limit = gSavedSettings.getS32("MediaBrowserWindowLimit"); + + if(LLFloaterReg::findInstance("media_browser", tag) != NULL) + { + // There's already a media browser for this tag, so we won't be opening a new window. + } + else if(browser_window_limit != 0) + { + // showInstance will open a new window. Figure out how many media browsers are already open, + // and close the least recently opened one if this will put us over the limit. + + LLFloaterReg::const_instance_list_t &instances = LLFloaterReg::getFloaterList("media_browser"); + lldebugs << "total instance count is " << instances.size() << llendl; + + for(LLFloaterReg::const_instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); iter++) + { + lldebugs << " " << (*iter)->getKey() << llendl; + } + + if(instances.size() >= (size_t)browser_window_limit) + { + // Destroy the least recently opened instance + (*instances.begin())->closeFloater(); + } + } + LLFloaterMediaBrowser *browser = dynamic_cast<LLFloaterMediaBrowser*> (LLFloaterReg::showInstance("media_browser", tag)); + llassert(browser); + if(browser) + { + browser->mUUID = uuid; + + // tell the browser instance to load the specified URL + browser->openMedia(url, target); + LLViewerMedia::proxyWindowOpened(target, uuid); + } } +//static +void LLFloaterMediaBrowser::closeRequest(const std::string &uuid) +{ + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("media_browser"); + lldebugs << "instance list size is " << inst_list.size() << ", incoming uuid is " << uuid << llendl; + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) + { + LLFloaterMediaBrowser* i = dynamic_cast<LLFloaterMediaBrowser*>(*iter); + lldebugs << " " << i->mUUID << llendl; + if (i && i->mUUID == uuid) + { + i->closeFloater(false); + return; + } + } +} + +//static +void LLFloaterMediaBrowser::geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height) +{ + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("media_browser"); + lldebugs << "instance list size is " << inst_list.size() << ", incoming uuid is " << uuid << llendl; + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) + { + LLFloaterMediaBrowser* i = dynamic_cast<LLFloaterMediaBrowser*>(*iter); + lldebugs << " " << i->mUUID << llendl; + if (i && i->mUUID == uuid) + { + i->geometryChanged(x, y, width, height); + return; + } +} +} + +void LLFloaterMediaBrowser::geometryChanged(S32 x, S32 y, S32 width, S32 height) +{ + // Make sure the layout of the browser control is updated, so this calculation is correct. + LLLayoutStack::updateClass(); + + // TODO: need to adjust size and constrain position to make sure floaters aren't moved outside the window view, etc. + LLCoordWindow window_size; + getWindow()->getSize(&window_size); + + // Adjust width and height for the size of the chrome on the Media Browser window. + width += getRect().getWidth() - mBrowser->getRect().getWidth(); + height += getRect().getHeight() - mBrowser->getRect().getHeight(); + + LLRect geom; + geom.setOriginAndSize(x, window_size.mY - (y + height), width, height); + + lldebugs << "geometry change: " << geom << llendl; + + handleReshape(geom,false); +} + + void LLFloaterMediaBrowser::draw() { getChildView("go")->setEnabled(!mAddressCombo->getValue().asString().empty()); @@ -99,6 +217,7 @@ BOOL LLFloaterMediaBrowser::postBuild() mAddressCombo = getChild<LLComboBox>("address"); mAddressCombo->setCommitCallback(onEnterAddress, this); + mAddressCombo->sortByName(); childSetAction("back", onClickBack, this); childSetAction("forward", onClickForward, this); @@ -114,6 +233,7 @@ BOOL LLFloaterMediaBrowser::postBuild() childSetAction("assign", onClickAssign, this); buildURLHistory(); + return TRUE; } @@ -154,6 +274,7 @@ std::string LLFloaterMediaBrowser::getSupportURL() //virtual void LLFloaterMediaBrowser::onClose(bool app_quitting) { + LLViewerMedia::proxyWindowClosed(mUUID); //setVisible(FALSE); destroy(); } @@ -170,7 +291,17 @@ void LLFloaterMediaBrowser::handleMediaEvent(LLPluginClassMedia* self, EMediaEve getChildView("back")->setEnabled(self->getHistoryBackAvailable()); getChildView("forward")->setEnabled(self->getHistoryForwardAvailable()); } + else if(event == MEDIA_EVENT_CLOSE_REQUEST) + { + // The browser instance wants its window closed. + closeFloater(); + } + else if(event == MEDIA_EVENT_GEOMETRY_CHANGE) + { + geometryChanged(self->getGeometryX(), self->getGeometryY(), self->getGeometryWidth(), self->getGeometryHeight()); + } } + void LLFloaterMediaBrowser::setCurrentURL(const std::string& url) { mCurrentURL = url; @@ -179,7 +310,7 @@ void LLFloaterMediaBrowser::setCurrentURL(const std::string& url) if (mCurrentURL != "about:blank") { mAddressCombo->remove(mCurrentURL); - mAddressCombo->add(mCurrentURL, ADD_SORTED); + mAddressCombo->add(mCurrentURL); mAddressCombo->selectByValue(mCurrentURL); // Serialize url history @@ -191,12 +322,6 @@ void LLFloaterMediaBrowser::setCurrentURL(const std::string& url) getChildView("reload")->setEnabled(TRUE); } -void LLFloaterMediaBrowser::onOpen(const LLSD& media_url) -{ - LLFloater::onOpen(media_url); - openMedia(media_url.asString()); -} - //static void LLFloaterMediaBrowser::onEnterAddress(LLUICtrl* ctrl, void* user_data) { @@ -322,9 +447,12 @@ void LLFloaterMediaBrowser::onClickSeek(void* user_data) if(self->mBrowser->getMediaPlugin()) self->mBrowser->getMediaPlugin()->start(2.0f); } -void LLFloaterMediaBrowser::openMedia(const std::string& media_url) +void LLFloaterMediaBrowser::openMedia(const std::string& media_url, const std::string& target) { mBrowser->setHomePageUrl(media_url); + mBrowser->setTarget(target); mBrowser->navigateTo(media_url); setCurrentURL(media_url); } + + diff --git a/indra/newview/llfloatermediabrowser.h b/indra/newview/llfloatermediabrowser.h index ffd8be4461..152d221a01 100644 --- a/indra/newview/llfloatermediabrowser.h +++ b/indra/newview/llfloatermediabrowser.h @@ -33,23 +33,30 @@ class LLComboBox; class LLMediaCtrl; +class LLNotification; class LLFloaterMediaBrowser : public LLFloater, public LLViewerMediaObserver { public: + LOG_CLASS(LLFloaterMediaBrowser); LLFloaterMediaBrowser(const LLSD& key); + static void create(const std::string &url, const std::string& target, const std::string& uuid = LLStringUtil::null); + + static void closeRequest(const std::string &uuid); + static void geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height); + void geometryChanged(S32 x, S32 y, S32 width, S32 height); + /*virtual*/ BOOL postBuild(); /*virtual*/ void onClose(bool app_quitting); /*virtual*/ void draw(); - /*virtual*/ void onOpen(const LLSD& key); // inherited from LLViewerMediaObserver /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); - void openMedia(const std::string& media_url); + void openMedia(const std::string& media_url, const std::string& target); void buildURLHistory(); std::string getSupportURL(); void setCurrentURL(const std::string& url); @@ -71,6 +78,8 @@ private: LLMediaCtrl* mBrowser; LLComboBox* mAddressCombo; std::string mCurrentURL; + boost::shared_ptr<LLNotification> mCurNotification; + std::string mUUID; }; #endif // LL_LLFLOATERMEDIABROWSER_H diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp index 08475b1e55..42dc60f9e0 100644 --- a/indra/newview/llfloaternotificationsconsole.cpp +++ b/indra/newview/llfloaternotificationsconsole.cpp @@ -37,10 +37,10 @@ const S32 NOTIFICATION_PANEL_HEADER_HEIGHT = 20; const S32 HEADER_PADDING = 38; -class LLNotificationChannelPanel : public LLPanel +class LLNotificationChannelPanel : public LLLayoutPanel { public: - LLNotificationChannelPanel(const std::string& channel_name); + LLNotificationChannelPanel(const Params& p); BOOL postBuild(); private: @@ -52,14 +52,14 @@ private: LLNotificationChannelPtr mChannelRejectsPtr; }; -LLNotificationChannelPanel::LLNotificationChannelPanel(const std::string& channel_name) - : LLPanel() +LLNotificationChannelPanel::LLNotificationChannelPanel(const LLNotificationChannelPanel::Params& p) +: LLLayoutPanel(p) { - mChannelPtr = LLNotifications::instance().getChannel(channel_name); + mChannelPtr = LLNotifications::instance().getChannel(p.name); mChannelRejectsPtr = LLNotificationChannelPtr( - LLNotificationChannel::buildChannel(channel_name + "rejects", mChannelPtr->getParentChannelName(), + LLNotificationChannel::buildChannel(p.name() + "rejects", mChannelPtr->getParentChannelName(), !boost::bind(mChannelPtr->getFilter(), _1))); - LLUICtrlFactory::instance().buildPanel(this, "panel_notifications_channel.xml"); + buildFromFile( "panel_notifications_channel.xml"); } BOOL LLNotificationChannelPanel::postBuild() @@ -167,8 +167,6 @@ LLFloaterNotificationConsole::LLFloaterNotificationConsole(const LLSD& key) : LLFloater(key) { mCommitCallbackRegistrar.add("ClickAdd", boost::bind(&LLFloaterNotificationConsole::onClickAdd, this)); - - //LLUICtrlFactory::instance().buildFloater(this, "floater_notifications_console.xml"); } BOOL LLFloaterNotificationConsole::postBuild() @@ -203,8 +201,13 @@ BOOL LLFloaterNotificationConsole::postBuild() void LLFloaterNotificationConsole::addChannel(const std::string& name, bool open) { LLLayoutStack& stack = getChildRef<LLLayoutStack>("notification_channels"); - LLNotificationChannelPanel* panelp = new LLNotificationChannelPanel(name); - stack.addPanel(panelp, 0, NOTIFICATION_PANEL_HEADER_HEIGHT, S32_MAX, S32_MAX, TRUE, TRUE, LLLayoutStack::ANIMATE); + LLNotificationChannelPanel::Params p; + p.min_dim = NOTIFICATION_PANEL_HEADER_HEIGHT; + p.auto_resize = true; + p.user_resize = true; + p.name = name; + LLNotificationChannelPanel* panelp = new LLNotificationChannelPanel(p); + stack.addPanel(panelp, LLLayoutStack::ANIMATE); LLButton& header_button = panelp->getChildRef<LLButton>("header"); header_button.setToggleState(!open); @@ -248,7 +251,7 @@ LLFloaterNotification::LLFloaterNotification(LLNotification* note) : LLFloater(LLSD()), mNote(note) { - LLUICtrlFactory::instance().buildFloater(this, "floater_notification.xml", NULL); + buildFromFile("floater_notification.xml"); } BOOL LLFloaterNotification::postBuild() diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp index d6f6ba9e5b..8b6619def2 100644 --- a/indra/newview/llfloateropenobject.cpp +++ b/indra/newview/llfloateropenobject.cpp @@ -56,7 +56,6 @@ LLFloaterOpenObject::LLFloaterOpenObject(const LLSD& key) mPanelInventoryObject(NULL), mDirty(TRUE) { -// LLUICtrlFactory::getInstance()->buildFloater(this,"floater_openobject.xml"); mCommitCallbackRegistrar.add("OpenObject.MoveToInventory", boost::bind(&LLFloaterOpenObject::onClickMoveToInventory, this)); mCommitCallbackRegistrar.add("OpenObject.MoveAndWear", boost::bind(&LLFloaterOpenObject::onClickMoveAndWear, this)); } diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp index 74dfede23e..80b55c3cbb 100644 --- a/indra/newview/llfloaterperms.cpp +++ b/indra/newview/llfloaterperms.cpp @@ -37,7 +37,6 @@ LLFloaterPerms::LLFloaterPerms(const LLSD& seed) : LLFloater(seed) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml"); mCommitCallbackRegistrar.add("Perms.Copy", boost::bind(&LLFloaterPerms::onCommitCopy, this)); mCommitCallbackRegistrar.add("Perms.OK", boost::bind(&LLFloaterPerms::onClickOK, this)); mCommitCallbackRegistrar.add("Perms.Cancel", boost::bind(&LLFloaterPerms::onClickCancel, this)); diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp index bcdcd50288..e8e9f76912 100644 --- a/indra/newview/llfloaterpostcard.cpp +++ b/indra/newview/llfloaterpostcard.cpp @@ -76,7 +76,6 @@ LLFloaterPostcard::LLFloaterPostcard(const LLSD& key) mViewerImage(NULL), mHasFirstMsgFocus(false) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_postcard.xml"); } // Destroys the object diff --git a/indra/newview/llfloaterpostprocess.cpp b/indra/newview/llfloaterpostprocess.cpp index 7f27caf68f..2d61109e17 100644 --- a/indra/newview/llfloaterpostprocess.cpp +++ b/indra/newview/llfloaterpostprocess.cpp @@ -42,7 +42,6 @@ LLFloaterPostProcess::LLFloaterPostProcess(const LLSD& key) : LLFloater(key) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_post_process.xml"); } LLFloaterPostProcess::~LLFloaterPostProcess() diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 3804a1b858..41f85ae29d 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -49,7 +49,6 @@ #include "llfloaterreg.h" #include "llfloaterabout.h" #include "llfloaterhardwaresettings.h" -#include "llfloatervoicedevicesettings.h" #include "llimfloater.h" #include "llkeyboard.h" #include "llmodaldialog.h" @@ -57,7 +56,9 @@ #include "llnearbychat.h" #include "llnotifications.h" #include "llnotificationsutil.h" +#include "llnotificationtemplate.h" #include "llpanellogin.h" +#include "llpanelvoicedevicesettings.h" #include "llradiogroup.h" #include "llsearchcombobox.h" #include "llsky.h" @@ -131,7 +132,6 @@ LLVoiceSetKeyDialog::LLVoiceSetKeyDialog(const LLSD& key) : LLModalDialog(key), mParent(NULL) { -// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_select_key.xml", NULL); } //virtual @@ -323,8 +323,9 @@ BOOL LLFloaterPreference::postBuild() if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab"))) tabcontainer->selectFirstTab(); + getChild<LLUICtrl>("cache_location")->setEnabled(FALSE); // make it read-only but selectable (STORM-227) std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""); - getChild<LLUICtrl>("cache_location")->setValue(cache_location); + setCacheLocation(cache_location); // if floater is opened before login set default localized busy message if (LLStartUp::getStartupState() < STATE_STARTED) @@ -407,12 +408,6 @@ void LLFloaterPreference::apply() hardware_settings->apply(); } - LLFloaterVoiceDeviceSettings* voice_device_settings = LLFloaterReg::findTypedInstance<LLFloaterVoiceDeviceSettings>("pref_voicedevicesettings"); - if(voice_device_settings) - { - voice_device_settings->apply(); - } - gViewerWindow->requestResolutionUpdate(); // for UIScaleFactor LLSliderCtrl* fov_slider = getChild<LLSliderCtrl>("camera_fov"); @@ -420,7 +415,7 @@ void LLFloaterPreference::apply() fov_slider->setMaxValue(LLViewerCamera::getInstance()->getMaxView()); std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""); - getChild<LLUICtrl>("cache_location")->setValue(cache_location); + setCacheLocation(cache_location); LLViewerMedia::setCookiesEnabled(getChild<LLUICtrl>("cookies_enabled")->getValue()); @@ -487,15 +482,6 @@ void LLFloaterPreference::cancel() // reverts any changes to current skin gSavedSettings.setString("SkinCurrent", sSkin); - - LLFloaterVoiceDeviceSettings* voice_device_settings = LLFloaterReg::findTypedInstance<LLFloaterVoiceDeviceSettings>("pref_voicedevicesettings"); - if (voice_device_settings) - { - voice_device_settings ->cancel(); - } - - LLFloaterReg::hideInstance("pref_voicedevicesettings"); - } void LLFloaterPreference::onOpen(const LLSD& key) @@ -798,7 +784,7 @@ void LLFloaterPreference::buildPopupLists() LLScrollListItem* item = NULL; - bool show_popup = LLUI::sSettingGroups["ignores"]->getBOOL(templatep->mName); + bool show_popup = formp->getIgnored(); if (!show_popup) { if (ignore == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE) @@ -820,13 +806,11 @@ void LLFloaterPreference::buildPopupLists() row["columns"][1]["font"] = "SANSSERIF_SMALL"; row["columns"][1]["width"] = 360; } - item = disabled_popups.addElement(row, - ADD_SORTED); + item = disabled_popups.addElement(row); } else { - item = enabled_popups.addElement(row, - ADD_SORTED); + item = enabled_popups.addElement(row); } if (item) @@ -1152,9 +1136,7 @@ void LLFloaterPreference::onClickDisablePopup() for (itor = items.begin(); itor != items.end(); ++itor) { LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate(*(std::string*)((*itor)->getUserdata())); - //gSavedSettings.setWarning(templatep->mName, TRUE); - std::string notification_name = templatep->mName; - LLUI::sSettingGroups["ignores"]->setBOOL(notification_name, FALSE); + templatep->mForm->setIgnored(false); } buildPopupLists(); @@ -1168,7 +1150,7 @@ void LLFloaterPreference::resetAllIgnored() { if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO) { - LLUI::sSettingGroups["ignores"]->setBOOL(iter->first, TRUE); + iter->second->mForm->setIgnored(true); } } } @@ -1181,7 +1163,7 @@ void LLFloaterPreference::setAllIgnored() { if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO) { - LLUI::sSettingGroups["ignores"]->setBOOL(iter->first, FALSE); + iter->second->mForm->setIgnored(false); } } } @@ -1329,6 +1311,12 @@ void LLFloaterPreference::getUIColor(LLUICtrl* ctrl, const LLSD& param) color_swatch->setOriginal(LLUIColorTable::instance().getColor(param.asString())); } +void LLFloaterPreference::setCacheLocation(const LLStringExplicit& location) +{ + LLUICtrl* cache_location_editor = getChild<LLUICtrl>("cache_location"); + cache_location_editor->setValue(location); + cache_location_editor->setToolTip(location); +} //---------------------------------------------------------------------------- static LLRegisterPanelClassWrapper<LLPanelPreference> t_places("panel_preference"); diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index d1e15d5ab8..e99731b92e 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -103,6 +103,8 @@ protected: public: + void setCacheLocation(const LLStringExplicit& location); + void onClickSetCache(); void onClickResetCache(); void onClickSkin(LLUICtrl* ctrl,const LLSD& userdata); diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp index e4e4713dbc..dd12fa64d3 100644 --- a/indra/newview/llfloaterproperties.cpp +++ b/indra/newview/llfloaterproperties.cpp @@ -108,8 +108,6 @@ LLFloaterProperties::LLFloaterProperties(const LLUUID& item_id) mDirty(TRUE) { mPropertiesObserver = new LLPropertiesObserver(this); - - //LLUICtrlFactory::getInstance()->buildFloater(this,"floater_inventory_item_properties.xml"); } // Destroys the object diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 29ad0f3b9c..ed81fdec16 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -161,7 +161,6 @@ LLUUID LLFloaterRegionInfo::sRequestInvoice; LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed) : LLFloater(seed) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_region_info.xml", FALSE); } BOOL LLFloaterRegionInfo::postBuild() @@ -174,32 +173,32 @@ BOOL LLFloaterRegionInfo::postBuild() mInfoPanels.push_back(panel); panel->getCommitCallbackRegistrar().add("RegionInfo.ManageTelehub", boost::bind(&LLPanelRegionInfo::onClickManageTelehub, panel)); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_general.xml"); + panel->buildFromFile("panel_region_general.xml"); mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(true)); panel = new LLPanelRegionDebugInfo; mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_debug.xml"); + panel->buildFromFile("panel_region_debug.xml"); mTab->addTabPanel(panel); panel = new LLPanelRegionTextureInfo; mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_texture.xml"); + panel->buildFromFile("panel_region_texture.xml"); mTab->addTabPanel(panel); panel = new LLPanelRegionTerrainInfo; mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_terrain.xml"); + panel->buildFromFile("panel_region_terrain.xml"); mTab->addTabPanel(panel); panel = new LLPanelEstateInfo; mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_estate.xml"); + panel->buildFromFile("panel_region_estate.xml"); mTab->addTabPanel(panel); panel = new LLPanelEstateCovenant; mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_covenant.xml"); + panel->buildFromFile("panel_region_covenant.xml"); mTab->addTabPanel(panel); gMessageSystem->setHandlerFunc( diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 97f192a708..66d7e804ea 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -103,7 +103,6 @@ LLFloaterReporter::LLFloaterReporter(const LLSD& key) mCopyrightWarningSeen( FALSE ), mResourceDatap(new LLResourceData()) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_report_abuse.xml"); } // static diff --git a/indra/newview/llfloaterscriptdebug.cpp b/indra/newview/llfloaterscriptdebug.cpp index 118dea2c74..a0d1a32e12 100644 --- a/indra/newview/llfloaterscriptdebug.cpp +++ b/indra/newview/llfloaterscriptdebug.cpp @@ -52,8 +52,6 @@ LLFloaterScriptDebug::LLFloaterScriptDebug(const LLSD& key) : LLMultiFloater(key) { -// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_script_debug.xml"); - // avoid resizing of the window to match // the initial size of the tabbed-childs, whenever a tab is opened or closed mAutoResize = FALSE; @@ -141,8 +139,6 @@ LLFloaterScriptDebugOutput::LLFloaterScriptDebugOutput(const LLSD& object_id) : LLFloater(LLSD(object_id)), mObjectID(object_id.asUUID()) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_script_debug_panel.xml"); - // enabled autocous blocks controling focus via LLFloaterReg::showInstance setAutoFocus(FALSE); } diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index 571f26e09f..cd792c263c 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -115,7 +115,7 @@ BOOL LLFloaterScriptLimits::postBuild() LLPanelScriptLimitsRegionMemory* panel_memory; panel_memory = new LLPanelScriptLimitsRegionMemory; mInfoPanels.push_back(panel_memory); - LLUICtrlFactory::getInstance()->buildPanel(panel_memory, "panel_script_limits_region_memory.xml"); + panel_memory->buildFromFile( "panel_script_limits_region_memory.xml"); mTab->addTabPanel(panel_memory); } @@ -124,7 +124,7 @@ BOOL LLFloaterScriptLimits::postBuild() { LLPanelScriptLimitsAttachment* panel_attachments = new LLPanelScriptLimitsAttachment; mInfoPanels.push_back(panel_attachments); - LLUICtrlFactory::getInstance()->buildPanel(panel_attachments, "panel_script_limits_my_avatar.xml"); + panel_attachments->buildFromFile("panel_script_limits_my_avatar.xml"); mTab->addTabPanel(panel_attachments); } @@ -706,38 +706,44 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content) } } - LLSD element; + LLScrollListItem::Params item_params; + item_params.value = task_id; - element["id"] = task_id; - element["columns"][0]["column"] = "size"; - element["columns"][0]["value"] = llformat("%d", size); - element["columns"][0]["font"] = "SANSSERIF"; - element["columns"][1]["column"] = "urls"; - element["columns"][1]["value"] = llformat("%d", urls); - element["columns"][1]["font"] = "SANSSERIF"; - element["columns"][2]["column"] = "name"; - element["columns"][2]["value"] = name_buf; - element["columns"][2]["font"] = "SANSSERIF"; - element["columns"][3]["column"] = "owner"; - element["columns"][3]["value"] = owner_buf; - element["columns"][3]["font"] = "SANSSERIF"; - element["columns"][4]["column"] = "parcel"; - element["columns"][4]["value"] = parcel_name; - element["columns"][4]["font"] = "SANSSERIF"; - element["columns"][5]["column"] = "location"; - if(has_locations) - { - element["columns"][5]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z); - } - else - { - element["columns"][5]["value"] = ""; - } - element["columns"][5]["font"] = "SANSSERIF"; + LLScrollListCell::Params cell_params; + cell_params.font = LLFontGL::getFontSansSerif(); + + cell_params.column = "size"; + cell_params.value = size; + item_params.columns.add(cell_params); + + cell_params.column = "urls"; + cell_params.value = urls; + item_params.columns.add(cell_params); + + cell_params.column = "name"; + cell_params.value = name_buf; + item_params.columns.add(cell_params); - list->addElement(element, ADD_SORTED); + cell_params.column = "owner"; + cell_params.value = owner_buf; + item_params.columns.add(cell_params); + + cell_params.column = "parcel"; + cell_params.value = parcel_name; + item_params.columns.add(cell_params); + + cell_params.column = "location"; + cell_params.value = has_locations + ? llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z) + : ""; + item_params.columns.add(cell_params); + + list->addRow(item_params); + LLSD element; element["owner_id"] = owner_id; + + element["id"] = task_id; element["local_id"] = local_id; mObjectListItems.push_back(element); } diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp index 7661e50eba..3ed4aec89a 100644 --- a/indra/newview/llfloatersearch.cpp +++ b/indra/newview/llfloatersearch.cpp @@ -96,11 +96,7 @@ LLFloaterSearch::LLFloaterSearch(const LLSD& key) : BOOL LLFloaterSearch::postBuild() { mBrowser = getChild<LLMediaCtrl>("browser"); - if (mBrowser) - { - mBrowser->addObserver(this); - mBrowser->setTrusted(true); - } + mBrowser->addObserver(this); return TRUE; } diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp index 41a05055fe..71882fbb83 100644 --- a/indra/newview/llfloatersettingsdebug.cpp +++ b/indra/newview/llfloatersettingsdebug.cpp @@ -39,7 +39,6 @@ LLFloaterSettingsDebug::LLFloaterSettingsDebug(const LLSD& key) : LLFloater(key) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_settings_debug.xml"); mCommitCallbackRegistrar.add("SettingSelect", boost::bind(&LLFloaterSettingsDebug::onSettingSelect, this,_1)); mCommitCallbackRegistrar.add("CommitSettings", boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); mCommitCallbackRegistrar.add("ClickDefault", boost::bind(&LLFloaterSettingsDebug::onClickDefault, this)); diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 278fee799a..36e8ad9dfc 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -2071,7 +2071,6 @@ LLFloaterSnapshot::LLFloaterSnapshot(const LLSD& key) : LLFloater(key), impl (*(new Impl)) { - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_snapshot.xml", FALSE); } // Destroys the object diff --git a/indra/newview/llfloatertelehub.cpp b/indra/newview/llfloatertelehub.cpp index d945f1a2de..b845fd132d 100644 --- a/indra/newview/llfloatertelehub.cpp +++ b/indra/newview/llfloatertelehub.cpp @@ -51,7 +51,6 @@ LLFloaterTelehub::LLFloaterTelehub(const LLSD& key) mTelehubRot(), mNumSpawn(0) { - //LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_telehub.xml"); } BOOL LLFloaterTelehub::postBuild() diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 58a0d08c7d..370bf05bf7 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -350,7 +350,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key) mFactoryMap["Contents"] = LLCallbackMap(createPanelContents, this);//LLPanelContents mFactoryMap["land info panel"] = LLCallbackMap(createPanelLandInfo, this);//LLPanelLandInfo - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_tools.xml",FALSE); mCommitCallbackRegistrar.add("BuildTool.setTool", boost::bind(&LLFloaterTools::setTool,this, _2)); mCommitCallbackRegistrar.add("BuildTool.commitZoom", boost::bind(&commit_slider_zoom, _1)); mCommitCallbackRegistrar.add("BuildTool.commitRadioFocus", boost::bind(&commit_radio_group_focus, _1)); diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index a984dd1d51..099b657c7c 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -64,7 +64,6 @@ void LLFloaterTopObjects::show() } sInstance = new LLFloaterTopObjects(); -// LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_top_objects.xml"); sInstance->center(); } */ diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index 333e44e077..5dc8067648 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -394,7 +394,6 @@ LLFloaterUIPreview::LLFloaterUIPreview(const LLSD& key) mLastDisplayedX(0), mLastDisplayedY(0) { - // called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_ui_preview.xml"); } // Destructor @@ -832,7 +831,7 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) if (save) { LLXMLNodePtr floater_write = new LLXMLNode(); - LLUICtrlFactory::getInstance()->buildFloater(*floaterp, path, floater_write); // just build it + (*floaterp)->buildFromFile(path, floater_write); // just build it if (!floater_write->isNull()) { @@ -846,7 +845,7 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) } else { - LLUICtrlFactory::getInstance()->buildFloater(*floaterp, path, NULL); // just build it + (*floaterp)->buildFromFile(path); // just build it (*floaterp)->openFloater((*floaterp)->getKey()); (*floaterp)->setCanResize((*floaterp)->isResizable()); } @@ -885,7 +884,7 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) if (save) { LLXMLNodePtr panel_write = new LLXMLNode(); - LLUICtrlFactory::getInstance()->buildPanel(panel, path, panel_write); // build it + panel->buildFromFile(path, panel_write); // build it if (!panel_write->isNull()) { @@ -899,7 +898,7 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) } else { - LLUICtrlFactory::getInstance()->buildPanel(panel, path); // build it + panel->buildFromFile(path); // build it LLRect new_size = panel->getRect(); // get its rectangle panel->setOrigin(0,0); // reset its origin point so it's not offset by -left or other XUI attributes (*floaterp)->setTitle(path); // use the file name as its title, since panels have no guaranteed meaningful name attribute diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp index 40f6d07286..151cd2a1cd 100644 --- a/indra/newview/llfloaterurlentry.cpp +++ b/indra/newview/llfloaterurlentry.cpp @@ -82,7 +82,7 @@ LLFloaterURLEntry::LLFloaterURLEntry(LLHandle<LLPanel> parent) : LLFloater(LLSD()), mPanelLandMediaHandle(parent) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_url_entry.xml", NULL); + buildFromFile("floater_url_entry.xml"); } //----------------------------------------------------------------------------- diff --git a/indra/newview/llfloaterwater.cpp b/indra/newview/llfloaterwater.cpp index 9c3f943013..be4b144f41 100644 --- a/indra/newview/llfloaterwater.cpp +++ b/indra/newview/llfloaterwater.cpp @@ -63,7 +63,6 @@ std::set<std::string> LLFloaterWater::sDefaultPresets; LLFloaterWater::LLFloaterWater(const LLSD& key) : LLFloater(key) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_water.xml"); } LLFloaterWater::~LLFloaterWater() diff --git a/indra/newview/llfloaterwhitelistentry.cpp b/indra/newview/llfloaterwhitelistentry.cpp index 7c618e788f..2a499f681b 100644 --- a/indra/newview/llfloaterwhitelistentry.cpp +++ b/indra/newview/llfloaterwhitelistentry.cpp @@ -41,7 +41,6 @@ LLFloaterWhiteListEntry::LLFloaterWhiteListEntry( const LLSD& key ) : LLFloater(key) { -// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_whitelist_entry.xml"); } /////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llfloaterwindlight.cpp b/indra/newview/llfloaterwindlight.cpp index 7131cb5de3..ae98b2cf99 100644 --- a/indra/newview/llfloaterwindlight.cpp +++ b/indra/newview/llfloaterwindlight.cpp @@ -66,7 +66,6 @@ static const F32 WL_SUN_AMBIENT_SLIDER_SCALE = 3.0f; LLFloaterWindLight::LLFloaterWindLight(const LLSD& key) : LLFloater(key) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_windlight_options.xml"); } LLFloaterWindLight::~LLFloaterWindLight() diff --git a/indra/newview/llfloaterwindowsize.cpp b/indra/newview/llfloaterwindowsize.cpp index 105efae032..a70f2af11a 100644 --- a/indra/newview/llfloaterwindowsize.cpp +++ b/indra/newview/llfloaterwindowsize.cpp @@ -80,7 +80,6 @@ public: LLFloaterWindowSize::LLFloaterWindowSize(const LLSD& key) : LLFloater(key) { - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_window_size.xml"); } LLFloaterWindowSize::~LLFloaterWindowSize() diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 3afa31b873..7236894542 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -199,7 +199,6 @@ LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key) mFactoryMap["objects_mapview"] = LLCallbackMap(createWorldMapView, NULL); - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_world_map.xml", FALSE); mCommitCallbackRegistrar.add("WMap.Coordinates", boost::bind(&LLFloaterWorldMap::onCoordinatesCommit, this)); mCommitCallbackRegistrar.add("WMap.Location", boost::bind(&LLFloaterWorldMap::onLocationCommit, this)); mCommitCallbackRegistrar.add("WMap.AvatarCombo", boost::bind(&LLFloaterWorldMap::onAvatarComboCommit, this)); diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 5d8e3f9ab9..387e300b74 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -350,6 +350,10 @@ BOOL LLFolderView::addFolder( LLFolderViewFolder* folder) { mFolders.insert(mFolders.begin(), folder); } + if (folder->numSelected()) + { + recursiveIncrementNumDescendantsSelected(folder->numSelected()); + } folder->setShowLoadStatus(true); folder->setOrigin(0, 0); folder->reshape(getRect().getWidth(), 0); @@ -692,29 +696,24 @@ BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected) return rv; } -S32 LLFolderView::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items) +void LLFolderView::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items) { - S32 rv = 0; - // now store resulting selection if (mAllowMultiSelect) { LLFolderViewItem *cur_selection = getCurSelectedItem(); - rv = LLFolderViewFolder::extendSelection(selection, cur_selection, items); + LLFolderViewFolder::extendSelection(selection, cur_selection, items); for (S32 i = 0; i < items.count(); i++) { addToSelectionList(items[i]); - rv++; } } else { setSelection(selection, FALSE, FALSE); - rv++; } mSignalSelectCallback = SIGNAL_KEYBOARD_FOCUS; - return rv; } void LLFolderView::sanitizeSelection() @@ -1972,7 +1971,11 @@ void LLFolderView::scrollToShowSelection() { // If items are filtered while background fetch is in progress // scrollbar resets to the first filtered item. See EXT-3981. - if (!LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() && mSelectedItems.size()) + // However we allow scrolling for folder views with mAutoSelectOverride + // (used in Places SP) as an exception because the selection in them + // is not reset during items filtering. See STORM-133. + if ( (!LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() || mAutoSelectOverride) + && mSelectedItems.size() ) { mNeedsScroll = TRUE; } diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 980f9a34a6..66ab4ce5eb 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -74,7 +74,6 @@ public: virtual void doItem(LLFolderViewItem* item) = 0; }; - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLFolderView // @@ -146,18 +145,18 @@ public: // Record the selected item and pass it down the hierachy. virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus); - + // Used by menu callbacks void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus); - + // Called once a frame to update the selection if mSelectThisID has been set - void updateSelection(); - + void updateSelection(); + // This method is used to toggle the selection of an item. Walks // children, and keeps track of selected objects. virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); - virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items); + virtual void extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items); virtual std::set<LLUUID> getSelectionList() const; diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 04b690b903..3c36248c1f 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -489,27 +489,34 @@ void LLFolderViewItem::dirtyFilter() // together. BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus) { - if( selection == this ) + if (selection == this && !mIsSelected) { - mIsSelected = TRUE; - if(mListener) + selectItem(); + if (mListener) { mListener->selectItem(); } } - else + else if (mIsSelected) // Deselect everything else. { - mIsSelected = FALSE; + deselectItem(); } return mIsSelected; } BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected) { - if(selection == this && mIsSelected != selected) + if (selection == this && mIsSelected != selected) { - mIsSelected = selected; - if(mListener) + if (mIsSelected) + { + deselectItem(); + } + else + { + selectItem(); + } + if (mListener) { mListener->selectItem(); } @@ -518,6 +525,33 @@ BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selecte return FALSE; } +void LLFolderViewItem::deselectItem(void) +{ + llassert(mIsSelected); + + mIsSelected = FALSE; + + // Update ancestors' count of selected descendents. + LLFolderViewFolder* parent_folder = getParentFolder(); + if (parent_folder) + { + parent_folder->recursiveIncrementNumDescendantsSelected(-1); + } +} + +void LLFolderViewItem::selectItem(void) +{ + llassert(!mIsSelected); + + mIsSelected = TRUE; + + // Update ancestors' count of selected descendents. + LLFolderViewFolder* parent_folder = getParentFolder(); + if (parent_folder) + { + parent_folder->recursiveIncrementNumDescendantsSelected(1); + } +} BOOL LLFolderViewItem::isMovable() { @@ -1073,6 +1107,7 @@ void LLFolderViewItem::draw() LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ): LLFolderViewItem( p ), // 0 = no create time + mNumDescendantsSelected(0), mIsOpen(FALSE), mExpanderHighlighted(FALSE), mCurHeight(0.f), @@ -1458,16 +1493,34 @@ BOOL LLFolderViewFolder::hasFilteredDescendants() return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration(); } +void LLFolderViewFolder::recursiveIncrementNumDescendantsSelected(S32 increment) +{ + LLFolderViewFolder* parent_folder = this; + do + { + parent_folder->mNumDescendantsSelected += increment; + + // Make sure we don't have negative values. + llassert(parent_folder->mNumDescendantsSelected >= 0); + + parent_folder = parent_folder->getParentFolder(); + } + while(parent_folder); +} + // Passes selection information on to children and record selection // information if necessary. BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus) + BOOL take_keyboard_focus) { BOOL rv = FALSE; - if( selection == this ) + if (selection == this) { - mIsSelected = TRUE; - if(mListener) + if (!isSelected()) + { + selectItem(); + } + if (mListener) { mListener->selectItem(); } @@ -1475,7 +1528,10 @@ BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem } else { - mIsSelected = FALSE; + if (isSelected()) + { + deselectItem(); + } rv = FALSE; } BOOL child_selected = FALSE; @@ -1507,21 +1563,31 @@ BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem return rv; } -// This method is used to change the selection of an item. If -// selection is 'this', then note selection as true. Returns TRUE -// if this or a child is now selected. -BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, - BOOL selected) +// This method is used to change the selection of an item. +// Recursively traverse all children; if 'selection' is 'this' then change +// the select status if necessary. +// Returns TRUE if the selection state of this folder, or of a child, was changed. +BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, BOOL selected) { BOOL rv = FALSE; if(selection == this) { - mIsSelected = selected; - if(mListener && selected) + if (isSelected() != selected) + { + rv = TRUE; + if (selected) + { + selectItem(); + } + else + { + deselectItem(); + } + } + if (mListener && selected) { mListener->selectItem(); } - rv = TRUE; } for (folders_t::iterator iter = mFolders.begin(); @@ -1545,16 +1611,14 @@ BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, return rv; } -S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& selected_items) +void LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& selected_items) { - S32 num_selected = 0; - // pass on to child folders first for (folders_t::iterator iter = mFolders.begin(); iter != mFolders.end();) { folders_t::iterator fit = iter++; - num_selected += (*fit)->extendSelection(selection, last_selected, selected_items); + (*fit)->extendSelection(selection, last_selected, selected_items); } // handle selection of our immediate children... @@ -1647,7 +1711,6 @@ S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderVie if (item->changeSelection(item, TRUE)) { selected_items.put(item); - num_selected++; } } } @@ -1657,11 +1720,8 @@ S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderVie if (selection->changeSelection(selection, TRUE)) { selected_items.put(selection); - num_selected++; } } - - return num_selected; } void LLFolderViewFolder::destroyView() @@ -1711,6 +1771,10 @@ void LLFolderViewFolder::removeView(LLFolderViewItem* item) return; } // deselect without traversing hierarchy + if (item->isSelected()) + { + item->deselectItem(); + } getRoot()->removeFromSelectionList(item); extractItem(item); delete item; @@ -1726,16 +1790,24 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item ) // This is an evil downcast. However, it's only doing // pointer comparison to find if (which it should be ) the // item is in the container, so it's pretty safe. - LLFolderViewFolder* f = reinterpret_cast<LLFolderViewFolder*>(item); + LLFolderViewFolder* f = static_cast<LLFolderViewFolder*>(item); folders_t::iterator ft; ft = std::find(mFolders.begin(), mFolders.end(), f); - if(ft != mFolders.end()) + if (ft != mFolders.end()) { + if ((*ft)->numSelected()) + { + recursiveIncrementNumDescendantsSelected(-(*ft)->numSelected()); + } mFolders.erase(ft); } } else { + if ((*it)->isSelected()) + { + recursiveIncrementNumDescendantsSelected(-1); + } mItems.erase(it); } //item has been removed, need to update filter @@ -1899,6 +1971,10 @@ BOOL LLFolderViewFolder::isRemovable() BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item) { mItems.push_back(item); + if (item->isSelected()) + { + recursiveIncrementNumDescendantsSelected(1); + } item->setRect(LLRect(0, 0, getRect().getWidth(), 0)); item->setVisible(FALSE); addChild( item ); @@ -1912,6 +1988,10 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item) BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder) { mFolders.push_back(folder); + if (folder->numSelected()) + { + recursiveIncrementNumDescendantsSelected(folder->numSelected()); + } folder->setOrigin(0, 0); folder->reshape(getRect().getWidth(), 0); folder->setVisible(FALSE); diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index 11b644e3aa..ab9317afd9 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -108,7 +108,7 @@ public: // layout constants static const S32 LEFT_PAD = 5; - // LEFT_INDENTATION is set via folder_indentation above + // LEFT_INDENTATION is set via folder_indentation above static const S32 ICON_PAD = 2; static const S32 ICON_WIDTH = 16; static const S32 TEXT_PAD = 1; @@ -121,6 +121,9 @@ public: // Mostly for debugging printout purposes. const std::string& getSearchableLabel() { return mSearchableLabel; } +private: + BOOL mIsSelected; + protected: friend class LLUICtrlFactory; friend class LLFolderViewEventListener; @@ -134,7 +137,6 @@ protected: time_t mCreationDate; LLFolderViewFolder* mParentFolder; LLFolderViewEventListener* mListener; - BOOL mIsSelected; BOOL mIsCurSelection; BOOL mSelectPending; LLFontGL::StyleFlags mLabelStyle; @@ -212,19 +214,23 @@ public: virtual void dirtyFilter(); - // If the selection is 'this' then note that otherwise - // ignore. Returns TRUE if this object was affected. If open is - // TRUE, then folders are opened up along the way to the - // selection. - virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus); + // If 'selection' is 'this' then note that otherwise ignore. + // Returns TRUE if this item ends up being selected. + virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus); - // This method is used to toggle the selection of an item. If - // selection is 'this', then note selection, and return TRUE. + // This method is used to set the selection state of an item. + // If 'selection' is 'this' then note selection. + // Returns TRUE if the selection state of this item was changed. virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); // this method is used to group select items - virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items){ return FALSE; } + virtual void extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items) { } + + // this method is used to deselect this element + void deselectItem(); + + // this method is used to select this element + void selectItem(); // gets multiple-element selection virtual std::set<LLUUID> getSelectionList() const; @@ -238,7 +244,7 @@ public: // destroys this item recursively virtual void destroyView(); - BOOL isSelected() { return mIsSelected; } + BOOL isSelected() const { return mIsSelected; } void setUnselected() { mIsSelected = FALSE; } @@ -247,7 +253,7 @@ public: BOOL getIsCurSelection() { return mIsCurSelection; } BOOL hasVisibleChildren() { return mHasVisibleChildren; } - + void setShowLoadStatus(bool status) { mShowLoadStatus = status; } // Call through to the viewed object and return true if it can be @@ -359,6 +365,13 @@ public: UNKNOWN, TRASH, NOT_TRASH } ETrash; +private: + S32 mNumDescendantsSelected; + +public: // Accessed needed by LLFolderViewItem + void recursiveIncrementNumDescendantsSelected(S32 increment); + S32 numSelected(void) const { return mNumDescendantsSelected + (isSelected() ? 1 : 0); } + protected: typedef std::list<LLFolderViewItem*> items_t; typedef std::list<LLFolderViewFolder*> folders_t; @@ -420,18 +433,19 @@ public: virtual void dirtyFilter(); // Passes selection information on to children and record - // selection information if necessary. Returns TRUE if this object - // (or a child) was affected. - virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, - BOOL take_keyboard_focus); + // selection information if necessary. + // Returns TRUE if this object (or a child) ends up being selected. + // If 'openitem' is TRUE then folders are opened up along the way to the selection. + virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus); - // This method is used to change the selection of an item. If - // selection is 'this', then note selection as true. Returns TRUE - // if this or a child is now selected. + // This method is used to change the selection of an item. + // Recursively traverse all children; if 'selection' is 'this' then change + // the select status if necessary. + // Returns TRUE if the selection state of this folder, or of a child, was changed. virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected); // this method is used to group select items - virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items); + virtual void extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items); // Returns true is this object and all of its children can be removed. virtual BOOL isRemovable(); @@ -521,6 +535,7 @@ public: time_t getCreationDate() const; bool isTrash() const; + S32 getNumSelectedDescendants(void) const { return mNumDescendantsSelected; } }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index c42b397252..5393678a6b 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -235,7 +235,7 @@ static bool isGroupUIVisible() { static LLPanel* panel = 0; if(!panel) - panel = LLSideTray::getInstance()->findChild<LLPanel>("panel_group_info_sidetray"); + panel = LLSideTray::getInstance()->getPanel("panel_group_info_sidetray"); if(!panel) return false; return panel->isInVisibleChain(); diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index 4f9d51ce58..c3e6e1c2dc 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -283,7 +283,7 @@ mGroupNameBox(NULL), mInfoBtn(NULL), mGroupID(LLUUID::null) { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_group_list_item.xml"); + buildFromFile( "panel_group_list_item.xml"); // Remember group icon width including its padding from the name text box, // so that we can hide and show the icon again later. diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 85e45d012b..7546c070ea 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -1175,8 +1175,8 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data) } else { - if (!rd) llwarns << "Received role data for unkown role " << role_id << " in group " << group_id << llendl; - if (!md) llwarns << "Received role data for unkown member " << member_id << " in group " << group_id << llendl; + if (!rd) llwarns << "Received role data for unknown role " << role_id << " in group " << group_id << llendl; + if (!md) llwarns << "Received role data for unknown member " << member_id << " in group " << group_id << llendl; } } } diff --git a/indra/newview/llhints.cpp b/indra/newview/llhints.cpp new file mode 100644 index 0000000000..d837ed8205 --- /dev/null +++ b/indra/newview/llhints.cpp @@ -0,0 +1,381 @@ +/** + * @file llhints.cpp + * @brief Hint popups for displaying context sensitive help in a UI overlay + * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + + +#include "llviewerprecompiledheaders.h" // must be first include + +#include "llhints.h" + +#include "llbutton.h" +#include "lltextbox.h" +#include "llviewerwindow.h" +#include "llviewercontrol.h" +#include "llsdparam.h" + +class LLHintPopup : public LLPanel +{ +public: + + typedef enum e_popup_direction + { + LEFT, + TOP, + RIGHT, + BOTTOM, + TOP_RIGHT + } EPopupDirection; + + struct PopupDirections : public LLInitParam::TypeValuesHelper<LLHintPopup::EPopupDirection, PopupDirections> + { + static void declareValues() + { + declare("left", LLHintPopup::LEFT); + declare("right", LLHintPopup::RIGHT); + declare("top", LLHintPopup::TOP); + declare("bottom", LLHintPopup::BOTTOM); + declare("top_right", LLHintPopup::TOP_RIGHT); + } + }; + + struct TargetParams : public LLInitParam::Block<TargetParams> + { + Mandatory<std::string> target; + Mandatory<EPopupDirection, PopupDirections> direction; + + TargetParams() + : target("target"), + direction("direction") + {} + }; + + struct Params : public LLInitParam::Block<Params, LLPanel::Params> + { + Mandatory<LLNotificationPtr> notification; + Optional<TargetParams> target_params; + Optional<S32> distance; + Optional<LLUIImage*> left_arrow, + up_arrow, + right_arrow, + down_arrow, + lower_left_arrow; + + Optional<S32> left_arrow_offset, + up_arrow_offset, + right_arrow_offset, + down_arrow_offset; + Optional<F32> fade_in_time, + fade_out_time; + + Params() + : distance("distance"), + left_arrow("left_arrow"), + up_arrow("up_arrow"), + right_arrow("right_arrow"), + down_arrow("down_arrow"), + lower_left_arrow("lower_left_arrow"), + left_arrow_offset("left_arrow_offset"), + up_arrow_offset("up_arrow_offset"), + right_arrow_offset("right_arrow_offset"), + down_arrow_offset("down_arrow_offset"), + fade_in_time("fade_in_time"), + fade_out_time("fade_out_time") + {} + }; + + LLHintPopup(const Params&); + + /*virtual*/ BOOL postBuild(); + + void onClickClose() { hide(); LLNotifications::instance().cancel(mNotification); } + void draw(); + void hide() { if(!mHidden) {mHidden = true; mFadeTimer.reset();} } + +private: + LLNotificationPtr mNotification; + std::string mTarget; + EPopupDirection mDirection; + S32 mDistance; + LLUIImagePtr mArrowLeft, + mArrowUp, + mArrowRight, + mArrowDown, + mArrowDownAndLeft; + S32 mArrowLeftOffset, + mArrowUpOffset, + mArrowRightOffset, + mArrowDownOffset; + LLFrameTimer mFadeTimer; + F32 mFadeInTime, + mFadeOutTime; + bool mHidden; +}; + +static LLDefaultChildRegistry::Register<LLHintPopup> r("hint_popup"); + + +LLHintPopup::LLHintPopup(const LLHintPopup::Params& p) +: mNotification(p.notification), + mDirection(TOP), + mDistance(p.distance), + mArrowLeft(p.left_arrow), + mArrowUp(p.up_arrow), + mArrowRight(p.right_arrow), + mArrowDown(p.down_arrow), + mArrowDownAndLeft(p.lower_left_arrow), + mArrowLeftOffset(p.left_arrow_offset), + mArrowUpOffset(p.up_arrow_offset), + mArrowRightOffset(p.right_arrow_offset), + mArrowDownOffset(p.down_arrow_offset), + mHidden(false), + mFadeInTime(p.fade_in_time), + mFadeOutTime(p.fade_out_time), + LLPanel(p) +{ + if (p.target_params.isProvided()) + { + mDirection = p.target_params.direction; + mTarget = p.target_params.target; + } + buildFromFile( "panel_hint.xml", NULL, p); +} + +BOOL LLHintPopup::postBuild() +{ + LLTextBox& hint_text = getChildRef<LLTextBox>("hint_text"); + hint_text.setText(mNotification->getMessage()); + + getChild<LLButton>("close")->setClickedCallback(boost::bind(&LLHintPopup::onClickClose, this)); + getChild<LLTextBox>("hint_title")->setText(mNotification->getLabel()); + + LLRect text_bounds = hint_text.getTextBoundingRect(); + S32 delta_height = text_bounds.getHeight() - hint_text.getRect().getHeight(); + reshape(getRect().getWidth(), getRect().getHeight() + delta_height); + return TRUE; +} + +void LLHintPopup::draw() +{ + F32 alpha = 1.f; + if (mHidden) + { + alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, mFadeOutTime, 1.f, 0.f); + if (alpha == 0.f) + { + die(); + return; + } + } + else + { + alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, mFadeInTime, 0.f, 1.f); + } + + { LLViewDrawContext context(alpha); + + if (mTarget.empty()) + { + // just draw contents, no arrow, in default position + LLPanel::draw(); + } + else + { + LLView* targetp = LLHints::getHintTarget(mTarget).get(); + if (!targetp) + { + // target widget is no longer valid, go away + die(); + } + else if (!targetp->isInVisibleChain()) + { + // if target is invisible, don't draw, but keep alive in case widget comes back + } + else + { + LLRect target_rect; + targetp->localRectToOtherView(targetp->getLocalRect(), &target_rect, getParent()); + + LLRect my_local_rect = getLocalRect(); + LLRect my_rect; + LLRect arrow_rect; + LLUIImagePtr arrow_imagep; + + switch(mDirection) + { + case LEFT: + my_rect.setCenterAndSize( target_rect.mLeft - (my_local_rect.getWidth() / 2 + mDistance), + target_rect.getCenterY(), + my_local_rect.getWidth(), + my_local_rect.getHeight()); + if (mArrowRight) + { + arrow_rect.setCenterAndSize(my_local_rect.mRight + mArrowRight->getWidth() / 2 + mArrowRightOffset, + my_local_rect.getCenterY(), + mArrowRight->getWidth(), + mArrowRight->getHeight()); + arrow_imagep = mArrowRight; + } + break; + case TOP: + my_rect.setCenterAndSize( target_rect.getCenterX(), + target_rect.mTop + (my_local_rect.getHeight() / 2 + mDistance), + my_local_rect.getWidth(), + my_local_rect.getHeight()); + if (mArrowDown) + { + arrow_rect.setCenterAndSize(my_local_rect.getCenterX(), + my_local_rect.mBottom - mArrowDown->getHeight() / 2 + mArrowDownOffset, + mArrowDown->getWidth(), + mArrowDown->getHeight()); + arrow_imagep = mArrowDown; + } + break; + case RIGHT: + my_rect.setCenterAndSize( target_rect.mRight + (my_local_rect.getWidth() / 2 + mDistance), + target_rect.getCenterY(), + my_local_rect.getWidth(), + my_local_rect.getHeight()); + if (mArrowLeft) + { + arrow_rect.setCenterAndSize(my_local_rect.mLeft - mArrowLeft->getWidth() / 2 + mArrowLeftOffset, + my_local_rect.getCenterY(), + mArrowLeft->getWidth(), + mArrowLeft->getHeight()); + arrow_imagep = mArrowLeft; + } + break; + case BOTTOM: + my_rect.setCenterAndSize( target_rect.getCenterX(), + target_rect.mBottom - (my_local_rect.getHeight() / 2 + mDistance), + my_local_rect.getWidth(), + my_local_rect.getHeight()); + if (mArrowUp) + { + arrow_rect.setCenterAndSize(my_local_rect.getCenterX(), + my_local_rect.mTop + mArrowUp->getHeight() / 2 + mArrowUpOffset, + mArrowUp->getWidth(), + mArrowUp->getHeight()); + arrow_imagep = mArrowUp; + } + break; + case TOP_RIGHT: + my_rect.setCenterAndSize( target_rect.mRight + (my_local_rect.getWidth() / 2), + target_rect.mTop + (my_local_rect.getHeight() / 2 + mDistance), + my_local_rect.getWidth(), + my_local_rect.getHeight()); + if (mArrowDownAndLeft) + { + arrow_rect.setCenterAndSize(my_local_rect.mLeft + mArrowDownAndLeft->getWidth() / 2 + mArrowLeftOffset, + my_local_rect.mBottom - mArrowDownAndLeft->getHeight() / 2 + mArrowDownOffset, + mArrowDownAndLeft->getWidth(), + mArrowDownAndLeft->getHeight()); + arrow_imagep = mArrowDownAndLeft; + } + } + setShape(my_rect); + LLPanel::draw(); + + if (arrow_imagep) arrow_imagep->draw(arrow_rect, LLColor4(1.f, 1.f, 1.f, alpha)); + } + } + } +} + + +LLRegistry<std::string, LLHandle<LLView> > LLHints::sTargetRegistry; +std::map<LLNotificationPtr, class LLHintPopup*> LLHints::sHints; + +//static +void LLHints::show(LLNotificationPtr hint) +{ + LLHintPopup::Params p(LLUICtrlFactory::getDefaultParams<LLHintPopup>()); + + LLParamSDParser parser; + parser.readSD(hint->getPayload(), p, true); + p.notification = hint; + + if (p.validateBlock()) + { + LLHintPopup* popup = new LLHintPopup(p); + + sHints[hint] = popup; + + LLView* hint_holder = gViewerWindow->getHintHolder(); + if (hint_holder) + { + hint_holder->addChild(popup); + popup->centerWithin(hint_holder->getLocalRect()); + } + } +} + +//static +void LLHints::hide(LLNotificationPtr hint) +{ + hint_map_t::iterator found_it = sHints.find(hint); + if (found_it != sHints.end()) + { + found_it->second->hide(); + sHints.erase(found_it); + } +} + +//static +void LLHints::registerHintTarget(const std::string& name, LLHandle<LLView> target) +{ + sTargetRegistry.defaultRegistrar().replace(name, target); +} + +//static +LLHandle<LLView> LLHints::getHintTarget(const std::string& name) +{ + LLHandle<LLView>* handlep = sTargetRegistry.getValue(name); + if (handlep) + { + return *handlep; + } + else + { + return LLHandle<LLView>(); + } +} + +//static +void LLHints::initClass() +{ + sRegister.reference(); + + LLControlVariablePtr control = gSavedSettings.getControl("EnableUIHints"); + control->getSignal()->connect(boost::bind(&showHints, _2)); + gViewerWindow->getHintHolder()->setVisible(control->getValue().asBoolean()); + +} + +//staic +void LLHints::showHints(const LLSD& show) +{ + bool visible = show.asBoolean(); + gViewerWindow->getHintHolder()->setVisible(visible); +} diff --git a/indra/newview/llhints.h b/indra/newview/llhints.h new file mode 100644 index 0000000000..ebffe561b9 --- /dev/null +++ b/indra/newview/llhints.h @@ -0,0 +1,50 @@ +/** + * @file llhints.h + * @brief Hint popups for displaying context sensitive help in a UI overlay + * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLHINTS_H +#define LL_LLHINTS_H + +#include "llpanel.h" +#include "llnotifications.h" + + +class LLHints : public LLInitClass<LLHints> +{ +public: + static void show(LLNotificationPtr hint); + static void hide(LLNotificationPtr hint); + static void registerHintTarget(const std::string& name, LLHandle<LLView> target); + static LLHandle<LLView> getHintTarget(const std::string& name); + static void initClass(); +private: + static LLRegistry<std::string, LLHandle<LLView> > sTargetRegistry; + typedef std::map<LLNotificationPtr, class LLHintPopup*> hint_map_t; + static hint_map_t sHints; + static void showHints(const LLSD& show); +}; + + +#endif diff --git a/indra/newview/llhudview.cpp b/indra/newview/llhudview.cpp index 686bcfae1c..9a63e99357 100644 --- a/indra/newview/llhudview.cpp +++ b/indra/newview/llhudview.cpp @@ -50,7 +50,7 @@ const S32 HUD_ARROW_SIZE = 32; LLHUDView::LLHUDView(const LLRect& r) { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_hud.xml"); + buildFromFile( "panel_hud.xml"); setShape(r, true); } diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 658e9403d8..56d3ed1c4d 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -251,14 +251,14 @@ BOOL LLIMFloater::postBuild() } mControlPanel->setSessionId(mSessionID); - mControlPanel->setVisible(gSavedSettings.getBOOL("IMShowControlPanel")); + mControlPanel->getParent()->setVisible(gSavedSettings.getBOOL("IMShowControlPanel")); LLButton* slide_left = getChild<LLButton>("slide_left_btn"); - slide_left->setVisible(mControlPanel->getVisible()); + slide_left->setVisible(mControlPanel->getParent()->getVisible()); slide_left->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this)); LLButton* slide_right = getChild<LLButton>("slide_right_btn"); - slide_right->setVisible(!mControlPanel->getVisible()); + slide_right->setVisible(!mControlPanel->getParent()->getVisible()); slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this)); mInputEditor = getChild<LLLineEditor>("chat_editor"); @@ -357,12 +357,12 @@ void* LLIMFloater::createPanelAdHocControl(void* userdata) void LLIMFloater::onSlide() { - mControlPanel->setVisible(!mControlPanel->getVisible()); + mControlPanel->getParent()->setVisible(!mControlPanel->getParent()->getVisible()); - gSavedSettings.setBOOL("IMShowControlPanel", mControlPanel->getVisible()); + gSavedSettings.setBOOL("IMShowControlPanel", mControlPanel->getParent()->getVisible()); - getChild<LLButton>("slide_left_btn")->setVisible(mControlPanel->getVisible()); - getChild<LLButton>("slide_right_btn")->setVisible(!mControlPanel->getVisible()); + getChild<LLButton>("slide_left_btn")->setVisible(mControlPanel->getParent()->getVisible()); + getChild<LLButton>("slide_right_btn")->setVisible(!mControlPanel->getParent()->getVisible()); LLLayoutStack* stack = getChild<LLLayoutStack>("im_panels"); if (stack) stack->setAnimate(true); diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp index 5bbab1f092..33cb3a54a7 100644 --- a/indra/newview/llimfloatercontainer.cpp +++ b/indra/newview/llimfloatercontainer.cpp @@ -94,9 +94,9 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp, if(gAgent.isInGroup(session_id, TRUE)) { - LLGroupIconCtrl::Params icon_params = LLUICtrlFactory::instance().getDefaultParams<LLGroupIconCtrl>(); + LLGroupIconCtrl::Params icon_params; icon_params.group_id = session_id; - icon = LLUICtrlFactory::instance().createWidget<LLGroupIconCtrl>(icon_params); + icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params); mSessions[session_id] = floaterp; floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, session_id)); @@ -105,9 +105,9 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp, { LLUUID avatar_id = LLIMModel::getInstance()->getOtherParticipantID(session_id); - LLAvatarIconCtrl::Params icon_params = LLUICtrlFactory::instance().getDefaultParams<LLAvatarIconCtrl>(); + LLAvatarIconCtrl::Params icon_params; icon_params.avatar_id = avatar_id; - icon = LLUICtrlFactory::instance().createWidget<LLAvatarIconCtrl>(icon_params); + icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params); mSessions[session_id] = floaterp; floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, session_id)); diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp index bc76092a20..cd71da7393 100644 --- a/indra/newview/llimhandler.cpp +++ b/indra/newview/llimhandler.cpp @@ -115,7 +115,7 @@ bool LLIMHandler::processNotification(const LLSD& notify) { mChannel->killToastByNotificationID(notification->getID()); } - return true; + return false; } //-------------------------------------------------------------------------- diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 5f7d1a2ffa..b3b0c93b99 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -168,7 +168,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label, LLUICtrlFactory::getInstance()->buildFloater(this, xml_filename, NULL); setTitle(mSessionLabel); - mInputEditor->setMaxTextLength(1023); + mInputEditor->setMaxTextLength(DB_IM_MSG_STR_LEN); // enable line history support for instant message bar mInputEditor->setEnableLineHistory(TRUE); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 129c9aec14..01e1c3caa0 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -69,7 +69,6 @@ const static std::string IM_TEXT("message"); const static std::string IM_FROM("from"); const static std::string IM_FROM_ID("from_id"); -const static std::string NO_SESSION("(IM Session Doesn't Exist)"); const static std::string ADHOC_NAME_SUFFIX(" Conference"); const static std::string NEARBY_P2P_BY_OTHER("nearby_P2P_by_other"); @@ -231,25 +230,6 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& new LLSessionTimeoutTimer(mSessionID, SESSION_INITIALIZATION_TIMEOUT); } - // *WORKAROUND: for server hard-coded string in indra\newsim\llsimchatterbox.cpp - if (isAdHocSessionType() && IM_SESSION_INVITE == type) - { - // For an ad-hoc incoming chat name is received from the server and is in a form of "<Avatar's name> Conference" - // Lets update it to localize the "Conference" word. See EXT-8429. - S32 separator_index = mName.rfind(" "); - std::string name = mName.substr(0, separator_index); - ++separator_index; - std::string conference_word = mName.substr(separator_index, mName.length()); - - // additional check that session name is what we expected - if ("Conference" == conference_word) - { - LLStringUtil::format_map_t args; - args["[AGENT_NAME]"] = name; - LLTrans::findString(mName, "conference-title-incoming", args); - } - } - if (IM_NOTHING_SPECIAL == type) { mCallBackEnabled = LLVoiceClient::getInstance()->isSessionCallBackPossible(mSessionID); @@ -266,6 +246,27 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& LLLogChat::loadAllHistory(mHistoryFileName, chat_history); addMessagesFromHistory(chat_history); } + + // Localizing name of ad-hoc session. STORM-153 + // Changing name should happen here- after the history file was created, so that + // history files have consistent (English) names in different locales. + if (isAdHocSessionType() && IM_SESSION_INVITE == type) + { + // Name here has a form of "<Avatar's name> Conference" + // Lets update it to localize the "Conference" word. See EXT-8429. + S32 separator_index = mName.rfind(" "); + std::string name = mName.substr(0, separator_index); + ++separator_index; + std::string conference_word = mName.substr(separator_index, mName.length()); + + // additional check that session name is what we expected + if ("Conference" == conference_word) + { + LLStringUtil::format_map_t args; + args["[AGENT_NAME]"] = name; + LLTrans::findString(mName, "conference-title-incoming", args); + } + } } void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction) @@ -494,6 +495,11 @@ LLIMModel::LLIMSession* LLIMModel::findAdHocIMSession(const uuid_vec_t& ids) return NULL; } +bool LLIMModel::LLIMSession::isOutgoingAdHoc() +{ + return IM_SESSION_CONFERENCE_START == mType; +} + bool LLIMModel::LLIMSession::isAdHoc() { return IM_SESSION_CONFERENCE_START == mType || (IM_SESSION_INVITE == mType && !gAgent.isInGroup(mSessionID)); @@ -621,7 +627,10 @@ bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, co LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id, ids, voice); mId2SessionMap[session_id] = session; - LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, name, other_participant_id); + // When notifying observer, name of session is used instead of "name", because they may not be the + // same if it is an adhoc session (in this case name is localized in LLIMSession constructor). + std::string session_name = LLIMModel::getInstance()->getName(session_id); + LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, session_name, other_participant_id); return true; @@ -791,14 +800,14 @@ LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, } -const std::string& LLIMModel::getName(const LLUUID& session_id) const +const std::string LLIMModel::getName(const LLUUID& session_id) const { LLIMSession* session = findIMSession(session_id); if (!session) { llwarns << "session " << session_id << "does not exist " << llendl; - return NO_SESSION; + return LLTrans::getString("no_session_message"); } return session->mName; @@ -1028,24 +1037,25 @@ void LLIMModel::sendMessage(const std::string& utf8_text, // to Recent People to prevent showing of an item with (???)(???). See EXT-8246. // Concrete participants will be added into this list once they sent message in chat. if (IM_SESSION_INVITE == dialog) return; - // Add only online members to recent (EXT-8658) - LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(im_session_id); - LLSpeakerMgr::speaker_list_t speaker_list; - if(speaker_mgr != NULL) - { - speaker_mgr->getSpeakerList(&speaker_list, true); - } - for(LLSpeakerMgr::speaker_list_t::iterator it = speaker_list.begin(); it != speaker_list.end(); it++) - { - const LLPointer<LLSpeaker>& speakerp = *it; - - LLRecentPeople::instance().add(speakerp->mID); - } + addSpeakersToRecent(im_session_id); } } +} - +void LLIMModel::addSpeakersToRecent(const LLUUID& im_session_id) +{ + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(im_session_id); + LLSpeakerMgr::speaker_list_t speaker_list; + if(speaker_mgr != NULL) + { + speaker_mgr->getSpeakerList(&speaker_list, true); + } + for(LLSpeakerMgr::speaker_list_t::iterator it = speaker_list.begin(); it != speaker_list.end(); it++) + { + const LLPointer<LLSpeaker>& speakerp = *it; + LLRecentPeople::instance().add(speakerp->mID); + } } void session_starter_helper( diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 4ce94773bf..f7a4406f00 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -84,6 +84,7 @@ public: /** @deprecated */ static void chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata); + bool isOutgoingAdHoc(); bool isAdHoc(); bool isP2P(); bool isOtherParticipantAvaline(); @@ -230,7 +231,7 @@ public: * For an incoming ad-hoc chat - is received from the server and is in a from of "<Avatar's name> Conference" * It is updated in LLIMModel::LLIMSession's constructor to localize the "Conference". */ - const std::string& getName(const LLUUID& session_id) const; + const std::string getName(const LLUUID& session_id) const; /** * Get number of unread messages in a session with session_id @@ -273,6 +274,9 @@ public: static void sendMessage(const std::string& utf8_text, const LLUUID& im_session_id, const LLUUID& other_participant_id, EInstantMessage dialog); + // Adds people from speakers list (people with whom you are currently speaking) to the Recent People List + static void addSpeakersToRecent(const LLUUID& im_session_id); + void testMessages(); /** diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 02e7f0b9e2..569dfc08e2 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2471,6 +2471,10 @@ void LLFolderBridge::folderOptionsMenu() { disabled_items.push_back(std::string("Remove From Outfit")); } + if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID)) + { + disabled_items.push_back(std::string("Replace Outfit")); + } mItems.push_back(std::string("Outfit Separator")); } LLMenuGL* menup = dynamic_cast<LLMenuGL*>(mMenu.get()); @@ -2852,6 +2856,66 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response return false; } +// Returns true if the item can be moved to Current Outfit or any outfit folder. +static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit) +{ + if ((inv_item->getInventoryType() != LLInventoryType::IT_WEARABLE) && + (inv_item->getInventoryType() != LLInventoryType::IT_GESTURE) && + (inv_item->getInventoryType() != LLInventoryType::IT_OBJECT)) + { + return FALSE; + } + + if (move_is_into_current_outfit && get_is_item_worn(inv_item->getUUID())) + { + return FALSE; + } + + return TRUE; +} + +void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item) +{ + // use callback to rearrange favorite landmarks after adding + // to have new one placed before target (on which it was dropped). See EXT-4312. + LLPointer<AddFavoriteLandmarkCallback> cb = new AddFavoriteLandmarkCallback(); + LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); + LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL; + if (drag_over_item && drag_over_item->getListener()) + { + cb.get()->setTargetLandmarkId(drag_over_item->getListener()->getUUID()); + } + + copy_inventory_item( + gAgent.getID(), + inv_item->getPermissions().getOwner(), + inv_item->getUUID(), + mUUID, + std::string(), + cb); +} + +void LLFolderBridge::dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit) +{ + // BAP - should skip if dup. + if (move_is_into_current_outfit) + { + LLAppearanceMgr::instance().wearItemOnAvatar(inv_item->getUUID(), true, true); + } + else + { + LLPointer<LLInventoryCallback> cb = NULL; + link_inventory_item( + gAgent.getID(), + inv_item->getLinkedUUID(), + mUUID, + inv_item->getName(), + inv_item->getDescription(), + LLAssetType::AT_LINK, + cb); + } +} + // This is used both for testing whether an item can be dropped // into the folder, as well as performing the actual drop, depending // if drop == TRUE. @@ -2864,18 +2928,20 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, if(!isAgentInventory()) return FALSE; // cannot drag into library if (!isAgentAvatarValid()) return FALSE; + const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); + const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false); + + const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); + const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); + LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); BOOL accept = FALSE; LLViewerObject* object = NULL; if(LLToolDragAndDrop::SOURCE_AGENT == source) { const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH, false); - const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); - const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false); const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id); - const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); - const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); const BOOL move_is_outof_current_outfit = LLAppearanceMgr::instance().getIsInCOF(inv_item->getUUID()); const BOOL folder_allows_reorder = (mUUID == favorites_id); @@ -2927,14 +2993,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, accept = FALSE; if (move_is_into_current_outfit || move_is_into_outfit) { - if ((inv_item->getInventoryType() != LLInventoryType::IT_WEARABLE) && - (inv_item->getInventoryType() != LLInventoryType::IT_GESTURE) && - (inv_item->getInventoryType() != LLInventoryType::IT_OBJECT)) - accept = FALSE; - } - if (move_is_into_current_outfit && get_is_item_worn(inv_item->getUUID())) - { - accept = FALSE; + accept = can_move_to_outfit(inv_item, move_is_into_current_outfit); } if(accept && drop) @@ -2978,50 +3037,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // (copy the item) else if (favorites_id == mUUID) { - // use callback to rearrange favorite landmarks after adding - // to have new one placed before target (on which it was dropped). See EXT-4312. - LLPointer<AddFavoriteLandmarkCallback> cb = new AddFavoriteLandmarkCallback(); - LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); - LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL; - if (drag_over_item && drag_over_item->getListener()) - { - cb.get()->setTargetLandmarkId(drag_over_item->getListener()->getUUID()); - } - - copy_inventory_item( - gAgent.getID(), - inv_item->getPermissions().getOwner(), - inv_item->getUUID(), - mUUID, - std::string(), - cb); + dropToFavorites(inv_item); } // CURRENT OUTFIT or OUTFIT folder // (link the item) else if (move_is_into_current_outfit || move_is_into_outfit) { - if ((inv_item->getInventoryType() == LLInventoryType::IT_WEARABLE) || - (inv_item->getInventoryType() == LLInventoryType::IT_GESTURE) || - (inv_item->getInventoryType() == LLInventoryType::IT_OBJECT)) - { - // BAP - should skip if dup. - if (move_is_into_current_outfit) - { - LLAppearanceMgr::instance().wearItemOnAvatar(inv_item->getUUID(), true, true); - } - else - { - LLPointer<LLInventoryCallback> cb = NULL; - link_inventory_item( - gAgent.getID(), - inv_item->getLinkedUUID(), - mUUID, - inv_item->getName(), - inv_item->getDescription(), - LLAssetType::AT_LINK, - cb); - } - } + dropToOutfit(inv_item, move_is_into_current_outfit); } // NORMAL or TRASH folder // (move the item, restamp if into trash) @@ -3070,6 +3092,15 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, is_move = TRUE; accept = TRUE; } + + // Don't allow placing an original item into Current Outfit or an outfit folder + // because they must contain only links to wearable items. + // *TODO: Probably we should create a link to an item if it was dragged to outfit or COF. + if(move_is_into_current_outfit || move_is_into_outfit) + { + accept = FALSE; + } + if(drop && accept) { LLMoveInv* move_inv = new LLMoveInv; @@ -3109,15 +3140,36 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, if(item && item->isFinished()) { accept = TRUE; - if(drop) + + if (move_is_into_current_outfit || move_is_into_outfit) { - copy_inventory_item( - gAgent.getID(), - inv_item->getPermissions().getOwner(), - inv_item->getUUID(), - mUUID, - std::string(), - LLPointer<LLInventoryCallback>(NULL)); + accept = can_move_to_outfit(inv_item, move_is_into_current_outfit); + } + + if (accept && drop) + { + // FAVORITES folder + // (copy the item) + if (favorites_id == mUUID) + { + dropToFavorites(inv_item); + } + // CURRENT OUTFIT or OUTFIT folder + // (link the item) + else if (move_is_into_current_outfit || move_is_into_outfit) + { + dropToOutfit(inv_item, move_is_into_current_outfit); + } + else + { + copy_inventory_item( + gAgent.getID(), + inv_item->getPermissions().getOwner(), + inv_item->getUUID(), + mUUID, + std::string(), + LLPointer<LLInventoryCallback>(NULL)); + } } } } diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 14abdd76b9..5ac328dcef 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -295,6 +295,8 @@ protected: menuentry_vec_t getMenuItems() { return mItems; } // returns a copy of current menu items + void dropToFavorites(LLInventoryItem* inv_item); + void dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit); //-------------------------------------------------------------------- // Messy hacks for handling folder options diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp index 1ea91103f1..225d0288a9 100644 --- a/indra/newview/llinventorylistitem.cpp +++ b/indra/newview/llinventorylistitem.cpp @@ -302,7 +302,9 @@ LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem } else { - mIconCtrl = dynamic_cast<LLIconCtrl*>(LLUICtrlFactory::createDefaultWidget<LLIconCtrl>("item_icon")); + LLIconCtrl::Params icon_params; + icon_params.name = "item_icon"; + mIconCtrl = LLUICtrlFactory::create<LLIconCtrl>(icon_params); } LLTextBox::Params text_params(params.item_name); @@ -315,7 +317,9 @@ LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem } else { - mTitleCtrl = dynamic_cast<LLTextBox*>(LLUICtrlFactory::createDefaultWidget<LLTextBox>("item_title")); + LLTextBox::Params text_aprams; + text_params.name = "item_title"; + mTitleCtrl = LLUICtrlFactory::create<LLTextBox>(text_params); } } diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 820520df9e..50adae09c0 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -916,6 +916,8 @@ BOOL is_inventorysp_active() // static LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open) { + S32 z_min = S32_MAX; + LLInventoryPanel* res = NULL; // A. If the inventory side panel is open, use that preferably. if (is_inventorysp_active()) { @@ -925,11 +927,26 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open) return inventorySP->getActivePanel(); } } + // or if it is in floater undocked from sidetray get it and remember z order of floater to later compare it + // with other inventory floaters order. + else if (!LLSideTray::getInstance()->isTabAttached("sidebar_inventory")) + { + LLSidepanelInventory *inventorySP = + dynamic_cast<LLSidepanelInventory *>(LLSideTray::getInstance()->getPanel("sidepanel_inventory")); + LLFloater* inv_floater = LLFloaterReg::findInstance("side_bar_tab", LLSD("sidebar_inventory")); + if (inventorySP && inv_floater) + { + res = inventorySP->getActivePanel(); + z_min = gFloaterView->getZOrder(inv_floater); + } + else + { + llwarns << "Inventory tab is detached from sidetray, but either panel or floater were not found!" << llendl; + } + } // B. Iterate through the inventory floaters and return whichever is on top. LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); - S32 z_min = S32_MAX; - LLInventoryPanel* res = NULL; for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) { LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter); diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 7b2f5984a7..3def135fb4 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -47,6 +47,7 @@ #include "llfloaterreg.h" #include "llnotifications.h" #include "llwindow.h" +#include "llviewerwindow.h" #if LL_LINUX || LL_SOLARIS #include "lltrans.h" #endif @@ -102,6 +103,7 @@ void LLLoginInstance::reconnect() std::vector<std::string> uris; LLGridManager::getInstance()->getLoginURIs(uris); mLoginModule->connect(uris.front(), mRequestData); + gViewerWindow->setShowProgress(true); } void LLLoginInstance::disconnect() @@ -239,6 +241,7 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) LLSD data(LLSD::emptyMap()); data["message"] = message_response; data["reply_pump"] = TOS_REPLY_PUMP; + gViewerWindow->setShowProgress(FALSE); LLFloaterReg::showInstance("message_tos", data); LLEventPumps::instance().obtain(TOS_REPLY_PUMP) .listen(TOS_LISTENER_NAME, @@ -259,6 +262,7 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) data["certificate"] = response["certificate"]; } + gViewerWindow->setShowProgress(FALSE); LLFloaterReg::showInstance("message_critical", data); LLEventPumps::instance().obtain(TOS_REPLY_PUMP) .listen(TOS_LISTENER_NAME, @@ -402,6 +406,8 @@ void LLLoginInstance::updateApp(bool mandatory, const std::string& auth_msg) { mNotifications->add(notification_name, args, payload, boost::bind(&LLLoginInstance::updateDialogCallback, this, _1, _2)); + + gViewerWindow->setShowProgress(false); } } diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index a6ff76cf84..e84c9152b1 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -38,7 +38,6 @@ #include "llviewermedia.h" #include "llviewertexture.h" #include "llviewerwindow.h" -#include "llnotificationsutil.h" #include "llweb.h" #include "llrender.h" #include "llpluginclassmedia.h" @@ -48,6 +47,13 @@ // linden library includes #include "llfocusmgr.h" +#include "llsdutil.h" +#include "lllayoutstack.h" +#include "lliconctrl.h" +#include "lltextbox.h" +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "llnotifications.h" extern BOOL gRestoreGL; @@ -62,19 +68,21 @@ LLMediaCtrl::Params::Params() texture_width("texture_width", 1024), texture_height("texture_height", 1024), caret_color("caret_color"), - initial_mime_type("initial_mime_type") + initial_mime_type("initial_mime_type"), + media_id("media_id"), + trusted_content("trusted_content", false) { tab_stop(false); } LLMediaCtrl::LLMediaCtrl( const Params& p) : LLPanel( p ), + LLInstanceTracker<LLMediaCtrl, LLUUID>(LLUUID::generateNewID()), mTextureDepthBytes( 4 ), mBorder(NULL), mFrequentUpdates( true ), mForceUpdate( false ), mHomePageUrl( "" ), - mTrusted(false), mIgnoreUIScale( true ), mAlwaysRefresh( false ), mMediaSource( 0 ), @@ -88,7 +96,8 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) : mTextureWidth ( 1024 ), mTextureHeight ( 1024 ), mClearCache(false), - mHomePageMimeType(p.initial_mime_type) + mHomePageMimeType(p.initial_mime_type), + mTrusted(p.trusted_content) { { LLColor4 color = p.caret_color().get(); @@ -161,19 +170,10 @@ void LLMediaCtrl::setTakeFocusOnClick( bool take_focus ) } //////////////////////////////////////////////////////////////////////////////// -void LLMediaCtrl::setTrusted( bool valIn ) -{ - if(mMediaSource) - { - mMediaSource->setTrustedBrowser(valIn); - } - mTrusted = valIn; -} - -//////////////////////////////////////////////////////////////////////////////// // BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask ) { + if (LLPanel::handleHover(x, y, mask)) return TRUE; convertInputCoords(x, y); if (mMediaSource) @@ -189,6 +189,7 @@ BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask ) // BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks ) { + if (LLPanel::handleScrollWheel(x, y, clicks)) return TRUE; if (mMediaSource && mMediaSource->hasMedia()) mMediaSource->getMediaPlugin()->scrollEvent(0, clicks, gKeyboard->currentMask(TRUE)); @@ -199,6 +200,7 @@ BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks ) // BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask ) { + if (LLPanel::handleMouseUp(x, y, mask)) return TRUE; convertInputCoords(x, y); if (mMediaSource) @@ -223,6 +225,7 @@ BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask ) // BOOL LLMediaCtrl::handleMouseDown( S32 x, S32 y, MASK mask ) { + if (LLPanel::handleMouseDown(x, y, mask)) return TRUE; convertInputCoords(x, y); if (mMediaSource) @@ -242,6 +245,7 @@ BOOL LLMediaCtrl::handleMouseDown( S32 x, S32 y, MASK mask ) // BOOL LLMediaCtrl::handleRightMouseUp( S32 x, S32 y, MASK mask ) { + if (LLPanel::handleRightMouseUp(x, y, mask)) return TRUE; convertInputCoords(x, y); if (mMediaSource) @@ -266,6 +270,7 @@ BOOL LLMediaCtrl::handleRightMouseUp( S32 x, S32 y, MASK mask ) // BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask ) { + if (LLPanel::handleRightMouseDown(x, y, mask)) return TRUE; convertInputCoords(x, y); if (mMediaSource) @@ -285,6 +290,7 @@ BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask ) // BOOL LLMediaCtrl::handleDoubleClick( S32 x, S32 y, MASK mask ) { + if (LLPanel::handleDoubleClick(x, y, mask)) return TRUE; convertInputCoords(x, y); if (mMediaSource) @@ -339,6 +345,85 @@ void LLMediaCtrl::onFocusLost() // BOOL LLMediaCtrl::postBuild () { + LLLayoutStack::Params layout_p; + layout_p.name = "notification_stack"; + layout_p.rect = LLRect(0,getLocalRect().mTop,getLocalRect().mRight, 30); + layout_p.follows.flags = FOLLOWS_ALL; + layout_p.mouse_opaque = false; + layout_p.orientation = "vertical"; + + LLLayoutStack* stackp = LLUICtrlFactory::create<LLLayoutStack>(layout_p); + addChild(stackp); + + LLLayoutPanel::Params panel_p; + panel_p.rect = LLRect(0, 30, 800, 0); + panel_p.min_height = 30; + panel_p.name = "notification_area"; + panel_p.visible = false; + panel_p.user_resize = false; + panel_p.background_visible = true; + panel_p.bg_alpha_image.name = "Yellow_Gradient"; + panel_p.auto_resize = false; + LLLayoutPanel* notification_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p); + stackp->addChild(notification_panel); + + panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>(); + panel_p.auto_resize = true; + panel_p.mouse_opaque = false; + LLLayoutPanel* dummy_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p); + stackp->addChild(dummy_panel); + + layout_p = LLUICtrlFactory::getDefaultParams<LLLayoutStack>(); + layout_p.rect = LLRect(0, 30, 800, 0); + layout_p.follows.flags = FOLLOWS_ALL; + layout_p.orientation = "horizontal"; + stackp = LLUICtrlFactory::create<LLLayoutStack>(layout_p); + notification_panel->addChild(stackp); + + panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>(); + panel_p.rect.height = 30; + LLLayoutPanel* panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p); + stackp->addChild(panel); + + LLIconCtrl::Params icon_p; + icon_p.name = "notification_icon"; + icon_p.rect = LLRect(5, 23, 21, 8); + panel->addChild(LLUICtrlFactory::create<LLIconCtrl>(icon_p)); + + LLTextBox::Params text_p; + text_p.rect = LLRect(31, 20, 430, 0); + text_p.text_color = LLColor4::black; + text_p.font = LLFontGL::getFontSansSerif(); + text_p.font.style = "BOLD"; + text_p.name = "notification_text"; + text_p.use_ellipses = true; + panel->addChild(LLUICtrlFactory::create<LLTextBox>(text_p)); + + panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>(); + panel_p.auto_resize = false; + panel_p.user_resize = false; + panel_p.name="form_elements"; + panel_p.rect = LLRect(0, 30, 130, 0); + LLLayoutPanel* form_elements_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p); + stackp->addChild(form_elements_panel); + + panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>(); + panel_p.auto_resize = false; + panel_p.user_resize = false; + panel_p.rect = LLRect(0, 30, 25, 0); + LLLayoutPanel* close_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p); + stackp->addChild(close_panel); + + LLButton::Params button_p; + button_p.name = "close_notification"; + button_p.rect = LLRect(5, 23, 21, 7); + button_p.image_color=LLUIColorTable::instance().getColor("DkGray_66"); + button_p.image_unselected.name="Icon_Close_Foreground"; + button_p.image_selected.name="Icon_Close_Press"; + button_p.click_callback.function = boost::bind(&LLMediaCtrl::onCloseNotification, this); + + close_panel->addChild(LLUICtrlFactory::create<LLButton>(button_p)); + setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChange, this, _2)); return TRUE; } @@ -347,6 +432,7 @@ BOOL LLMediaCtrl::postBuild () // BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask ) { + if (LLPanel::handleKeyHere(key, mask)) return TRUE; BOOL result = FALSE; if (mMediaSource) @@ -372,6 +458,7 @@ void LLMediaCtrl::handleVisibilityChange ( BOOL new_visibility ) // BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char) { + if (LLPanel::handleUnicodeCharHere(uni_char)) return TRUE; BOOL result = FALSE; if (mMediaSource) @@ -572,6 +659,15 @@ void LLMediaCtrl::setHomePageUrl( const std::string& urlIn, const std::string& m } } +void LLMediaCtrl::setTarget(const std::string& target) +{ + mTarget = target; + if (mMediaSource) + { + mMediaSource->setTarget(mTarget); + } +} + //////////////////////////////////////////////////////////////////////////////// // bool LLMediaCtrl::setCaretColor(unsigned int red, unsigned int green, unsigned int blue) @@ -613,6 +709,7 @@ bool LLMediaCtrl::ensureMediaSourceExists() { mMediaSource->setUsedInUI(true); mMediaSource->setHomeURL(mHomePageUrl, mHomePageMimeType); + mMediaSource->setTarget(mTarget); mMediaSource->setVisible( getVisible() ); mMediaSource->addObserver( this ); mMediaSource->setBackgroundColor( getBackgroundColor() ); @@ -824,6 +921,10 @@ void LLMediaCtrl::draw() if ( mBorder && mBorder->getVisible() ) mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) ); + if (mCurNotification && !mCurNotification->isActive()) + { + hideNotification(); + } LLPanel::draw(); @@ -890,6 +991,7 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) case MEDIA_EVENT_NAVIGATE_BEGIN: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL; + hideNotification(); }; break; @@ -924,9 +1026,27 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) case MEDIA_EVENT_CLICK_LINK_HREF: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << self->getClickTarget() << "\", uri is " << self->getClickURL() << LL_ENDL; + // retrieve the event parameters + std::string url = self->getClickURL(); + std::string target = self->getClickTarget(); + std::string uuid = self->getClickUUID(); + + LLNotification::Params notify_params; + notify_params.name = "PopupAttempt"; + notify_params.payload = LLSD().with("target", target).with("url", url).with("uuid", uuid).with("media_id", getKey()); + notify_params.functor.function = boost::bind(&LLMediaCtrl::onPopup, this, _1, _2); + + if (mTrusted) + { + LLNotifications::instance().forceResponse(notify_params, 0); + } + else + { + LLNotifications::instance().add(notify_params); + } + break; }; - break; - + case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL; @@ -950,6 +1070,24 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAME_CHANGED" << LL_ENDL; }; break; + + case MEDIA_EVENT_CLOSE_REQUEST: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLOSE_REQUEST" << LL_ENDL; + } + break; + + case MEDIA_EVENT_PICK_FILE_REQUEST: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << LL_ENDL; + } + break; + + case MEDIA_EVENT_GEOMETRY_CHANGE: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL; + } + break; }; // chain all events to any potential observers of this object. @@ -963,3 +1101,113 @@ std::string LLMediaCtrl::getCurrentNavUrl() return mCurrentNavUrl; } +void LLMediaCtrl::onPopup(const LLSD& notification, const LLSD& response) +{ + if (response["open"]) + { + LLWeb::loadURL(notification["payload"]["url"], notification["payload"]["target"], notification["payload"]["uuid"]); + } + else + { + // Make sure the opening instance knows its window open request was denied, so it can clean things up. + LLViewerMedia::proxyWindowClosed(notification["payload"]["uuid"]); + } + +} + +void LLMediaCtrl::onCloseNotification() +{ + LLNotifications::instance().cancel(mCurNotification); +} + +void LLMediaCtrl::onClickIgnore(LLUICtrl* ctrl) +{ + bool check = ctrl->getValue().asBoolean(); + if (mCurNotification && mCurNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN) + { + // question was "show again" so invert value to get "ignore" + check = !check; + } + mCurNotification->setIgnored(check); +} + +void LLMediaCtrl::onClickNotificationButton(const std::string& name) +{ + if (!mCurNotification) return; + + LLSD response = mCurNotification->getResponseTemplate(); + response[name] = true; + + mCurNotification->respond(response); +} + +void LLMediaCtrl::showNotification(LLNotificationPtr notify) +{ + mCurNotification = notify; + + // add popup here + LLSD payload = notify->getPayload(); + + LLNotificationFormPtr formp = notify->getForm(); + LLLayoutPanel& panel = getChildRef<LLLayoutPanel>("notification_area"); + panel.setVisible(true); + panel.getChild<LLUICtrl>("notification_icon")->setValue(notify->getIcon()); + panel.getChild<LLUICtrl>("notification_text")->setValue(notify->getMessage()); + panel.getChild<LLUICtrl>("notification_text")->setToolTip(notify->getMessage()); + LLNotificationForm::EIgnoreType ignore_type = formp->getIgnoreType(); + LLLayoutPanel& form_elements = panel.getChildRef<LLLayoutPanel>("form_elements"); + form_elements.deleteAllChildren(); + + const S32 FORM_PADDING_HORIZONTAL = 10; + const S32 FORM_PADDING_VERTICAL = 3; + S32 cur_x = FORM_PADDING_HORIZONTAL; + + if (ignore_type != LLNotificationForm::IGNORE_NO) + { + LLCheckBoxCtrl::Params checkbox_p; + checkbox_p.name = "ignore_check"; + checkbox_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x, FORM_PADDING_VERTICAL); + checkbox_p.label = formp->getIgnoreMessage(); + checkbox_p.label_text.text_color = LLColor4::black; + checkbox_p.commit_callback.function = boost::bind(&LLMediaCtrl::onClickIgnore, this, _1); + checkbox_p.initial_value = formp->getIgnored(); + + LLCheckBoxCtrl* check = LLUICtrlFactory::create<LLCheckBoxCtrl>(checkbox_p); + check->setRect(check->getBoundingRect()); + form_elements.addChild(check); + cur_x = check->getRect().mRight + FORM_PADDING_HORIZONTAL; + } + + for (S32 i = 0; i < formp->getNumElements(); i++) + { + LLSD form_element = formp->getElement(i); + if (form_element["type"].asString() == "button") + { + LLButton::Params button_p; + button_p.name = form_element["name"]; + button_p.label = form_element["text"]; + button_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x, FORM_PADDING_VERTICAL); + button_p.click_callback.function = boost::bind(&LLMediaCtrl::onClickNotificationButton, this, form_element["name"].asString()); + button_p.auto_resize = true; + + LLButton* button = LLUICtrlFactory::create<LLButton>(button_p); + button->autoResize(); + form_elements.addChild(button); + + cur_x = button->getRect().mRight + FORM_PADDING_HORIZONTAL; + } + } + + + form_elements.reshape(cur_x, form_elements.getRect().getHeight()); + + //LLWeb::loadURL(payload["url"], payload["target"]); +} + +void LLMediaCtrl::hideNotification() +{ + LLLayoutPanel& panel = getChildRef<LLLayoutPanel>("notification_area"); + panel.setVisible(FALSE); + + mCurNotification.reset(); +} diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 755d1e1b04..65dfbbff78 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -40,7 +40,8 @@ class LLUICtrlFactory; class LLMediaCtrl : public LLPanel, public LLViewerMediaObserver, - public LLViewerMediaEventEmitter + public LLViewerMediaEventEmitter, + public LLInstanceTracker<LLMediaCtrl, LLUUID> { LOG_CLASS(LLMediaCtrl); public: @@ -51,7 +52,8 @@ public: Optional<bool> border_visible, ignore_ui_scale, hide_loading, - decouple_texture_size; + decouple_texture_size, + trusted_content; Optional<S32> texture_width, texture_height; @@ -59,6 +61,7 @@ public: Optional<LLUIColor> caret_color; Optional<std::string> initial_mime_type; + Optional<std::string> media_id; Params(); }; @@ -103,11 +106,11 @@ public: // Javascript or some other mechanism. However, we need the search // floater and login page to handle these URLs. Those are safe // because we control the page content. See DEV-9530. JC. - void setTrusted( bool valIn ); - void setHomePageUrl( const std::string& urlIn, const std::string& mime_type = LLStringUtil::null ); std::string getHomePageUrl(); + void setTarget(const std::string& target); + // set/clear URL to visit when a 404 page is reached void set404RedirectUrl( std::string redirect_url ); void clr404RedirectUrl(); @@ -140,6 +143,8 @@ public: void setTextureSize(S32 width, S32 height); + void showNotification(boost::shared_ptr<class LLNotification> notify); + void hideNotification(); // over-rides virtual BOOL handleKeyHere( KEY key, MASK mask); @@ -161,16 +166,21 @@ public: private: void onVisibilityChange ( const LLSD& new_visibility ); + void onPopup(const LLSD& notification, const LLSD& response); + void onCloseNotification(); + void onClickNotificationButton(const std::string& name); + void onClickIgnore(LLUICtrl* ctrl); const S32 mTextureDepthBytes; LLUUID mMediaTextureID; LLViewBorder* mBorder; bool mFrequentUpdates; bool mForceUpdate; - bool mTrusted; + const bool mTrusted; std::string mHomePageUrl; std::string mHomePageMimeType; std::string mCurrentNavUrl; + std::string mTarget; bool mIgnoreUIScale; bool mAlwaysRefresh; viewer_media_t mMediaSource; @@ -183,6 +193,7 @@ public: S32 mTextureWidth; S32 mTextureHeight; bool mClearCache; + boost::shared_ptr<class LLNotification> mCurNotification; }; #endif // LL_LLMediaCtrl_H diff --git a/indra/newview/llmorphview.h b/indra/newview/llmorphview.h index d135659ba2..1d8ee8e944 100644 --- a/indra/newview/llmorphview.h +++ b/indra/newview/llmorphview.h @@ -32,7 +32,6 @@ #include "llframetimer.h" class LLJoint; -class LLFloaterCustomize; class LLMorphView : public LLView { diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 3d0f4cc1ed..6658e1d7e8 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -39,7 +39,9 @@ #include "llvoavatarself.h" // to check gAgentAvatarp->isSitting() #include "llbottomtray.h" #include "llbutton.h" +#include "llfirstuse.h" #include "llfloaterreg.h" +#include "llhints.h" #include "lljoystickbutton.h" #include "lluictrlfactory.h" #include "llviewerwindow.h" @@ -161,6 +163,7 @@ void LLFloaterMove::setVisible(BOOL visible) if (visible) { + LLFirstUse::notMoving(false); // Attach the Stand/Stop Flying panel. LLPanelStandStopFlying* ssf_panel = LLPanelStandStopFlying::getInstance(); ssf_panel->reparent(this); @@ -560,6 +563,11 @@ void LLPanelStandStopFlying::setStandStopFlyingMode(EStandStopFlyingMode mode) { LLPanelStandStopFlying* panel = getInstance(); + if (mode == SSFM_STAND) + { + LLFirstUse::sit(); + LLFirstUse::notMoving(false); + } panel->mStandButton->setVisible(SSFM_STAND == mode); panel->mStopFlyingButton->setVisible(SSFM_STOP_FLYING == mode); @@ -590,6 +598,7 @@ BOOL LLPanelStandStopFlying::postBuild() mStandButton->setCommitCallback(boost::bind(&LLPanelStandStopFlying::onStandButtonClick, this)); mStandButton->setCommitCallback(boost::bind(&LLFloaterMove::enableInstance, TRUE)); mStandButton->setVisible(FALSE); + LLHints::registerHintTarget("stand_btn", mStandButton->getHandle()); mStopFlyingButton = getChild<LLButton>("stop_fly_btn"); //mStopFlyingButton->setCommitCallback(boost::bind(&LLFloaterMove::setFlyingMode, FALSE)); @@ -688,7 +697,7 @@ void LLPanelStandStopFlying::reparent(LLFloaterMove* move_view) LLPanelStandStopFlying* LLPanelStandStopFlying::getStandStopFlyingPanel() { LLPanelStandStopFlying* panel = new LLPanelStandStopFlying(); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_stand_stop_flying.xml"); + panel->buildFromFile("panel_stand_stop_flying.xml"); panel->setVisible(FALSE); //LLUI::getRootView()->addChild(panel); @@ -701,6 +710,8 @@ LLPanelStandStopFlying* LLPanelStandStopFlying::getStandStopFlyingPanel() void LLPanelStandStopFlying::onStandButtonClick() { + LLFirstUse::sit(false); + LLSelectMgr::getInstance()->deselectAllForStandingUp(); gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); diff --git a/indra/newview/llnamebox.cpp b/indra/newview/llnamebox.cpp index 74d4217899..c31da84f78 100644 --- a/indra/newview/llnamebox.cpp +++ b/indra/newview/llnamebox.cpp @@ -47,6 +47,7 @@ LLNameBox::LLNameBox(const Params& p) { mNameID = LLUUID::null; mLink = p.link; + mParseHTML = mLink; // STORM-215 mInitialValue = p.initial_value().asString(); LLNameBox::sInstances.insert(this); setText(LLStringUtil::null); @@ -119,7 +120,7 @@ void LLNameBox::setName(const std::string& name, BOOL is_group) std::string url; if (is_group) - url = "[secondlife:///app/group/" + LLURI::escape(name) + "/about " + name + "]"; + url = "[secondlife:///app/group/" + mNameID.asString() + "/about " + name + "]"; else url = "[secondlife:///app/agent/" + mNameID.asString() + "/about " + name + "]"; diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index e7e60f544c..6521ae3b1e 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -253,7 +253,8 @@ void LLNameListCtrl::addNameItem(LLNameListCtrl::NameItem& item, EAddPosition po LLScrollListItem* LLNameListCtrl::addElement(const LLSD& element, EAddPosition pos, void* userdata) { LLNameListCtrl::NameItem item_params; - LLParamSDParser::instance().readSD(element, item_params); + LLParamSDParser parser; + parser.readSD(element, item_params); item_params.userdata = userdata; return addNameItemRow(item_params, pos); } diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 18bba6e358..58849393b4 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -272,7 +272,7 @@ LLNavigationBar::LLNavigationBar() mPurgeTPHistoryItems(false), mSaveToLocationHistory(false) { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_navigation_bar.xml"); + buildFromFile( "panel_navigation_bar.xml"); // set a listener function for LoginComplete event LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLNavigationBar::handleLoginComplete, this)); diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 5f71d7100b..28aea7ae3d 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -115,7 +115,7 @@ void LLNearbyChat::applySavedVariables() { if (mRectControl.size() > 1) { - const LLRect& rect = LLUI::sSettingGroups["floater"]->getRect(mRectControl); + const LLRect& rect = LLFloater::getControlGroup()->getRect(mRectControl); if(!rect.isEmpty() && rect.isValid()) { reshape(rect.getWidth(), rect.getHeight()); @@ -124,7 +124,7 @@ void LLNearbyChat::applySavedVariables() } - if(!LLUI::sSettingGroups["floater"]->controlExists(mDocStateControl)) + if(!LLFloater::getControlGroup()->controlExists(mDocStateControl)) { setDocked(true); } @@ -132,7 +132,7 @@ void LLNearbyChat::applySavedVariables() { if (mDocStateControl.size() > 1) { - bool dockState = LLUI::sSettingGroups["floater"]->getBOOL(mDocStateControl); + bool dockState = LLFloater::getControlGroup()->getBOOL(mDocStateControl); setDocked(dockState); } } diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index a8e4a759b7..932ad75f29 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -32,6 +32,7 @@ #include "llfloaterreg.h" #include "lltrans.h" +#include "llfirstuse.h" #include "llnearbychatbar.h" #include "llbottomtray.h" #include "llagent.h" @@ -391,8 +392,7 @@ LLCtrlListInterface* LLGestureComboList::getListInterface() } LLNearbyChatBar::LLNearbyChatBar() - : LLPanel() - , mChatBox(NULL) +: mChatBox(NULL) { mSpeakerMgr = LLLocalSpeakerMgr::getInstance(); } @@ -484,6 +484,7 @@ BOOL LLNearbyChatBar::matchChatTypeTrigger(const std::string& in_str, std::strin void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata) { + LLFirstUse::otherAvatarChatFirst(false); LLNearbyChatBar* self = (LLNearbyChatBar *)userdata; @@ -873,14 +874,14 @@ public: } else { - S32 channel = tokens[0].asInteger(); + S32 channel = tokens[0].asInteger(); // VWR-19499 Restrict function to chat channels greater than 0. if ((channel > 0) && (channel < 2147483647)) { retval = true; - // Send unescaped message, see EXT-6353. - std::string unescaped_mesg (LLURI::unescape(tokens[1].asString())); - send_chat_from_viewer(unescaped_mesg, CHAT_TYPE_NORMAL, channel); + // Send unescaped message, see EXT-6353. + std::string unescaped_mesg (LLURI::unescape(tokens[1].asString())); + send_chat_from_viewer(unescaped_mesg, CHAT_TYPE_NORMAL, channel); } else { diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index a747c228a6..47d32e57fb 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -31,7 +31,9 @@ #include "llbottomtray.h" #include "llchatitemscontainerctrl.h" +#include "llfirstuse.h" #include "llfloaterscriptdebug.h" +#include "llhints.h" #include "llnearbychat.h" #include "llrecentpeople.h" @@ -54,8 +56,15 @@ LLToastPanelBase* createToastPanel() class LLNearbyChatScreenChannel: public LLScreenChannelBase { + LOG_CLASS(LLNearbyChatScreenChannel); public: - LLNearbyChatScreenChannel(const LLUUID& id):LLScreenChannelBase(id) { mStopProcessing = false;}; + typedef std::vector<LLHandle<LLToast> > toast_vec_t; + typedef std::list<LLHandle<LLToast> > toast_list_t; + + LLNearbyChatScreenChannel(const LLUUID& id):LLScreenChannelBase(id) + { + mStopProcessing = false; + } void addNotification (LLSD& notification); void arrangeToasts (); @@ -64,7 +73,7 @@ public: typedef boost::function<LLToastPanelBase* (void )> create_toast_panel_callback_t; void setCreatePanelCallback(create_toast_panel_callback_t value) { m_create_toast_panel_callback_t = value;} - void onToastDestroyed (LLToast* toast); + void onToastDestroyed (LLToast* toast, bool app_quitting); void onToastFade (LLToast* toast); void reshape (S32 width, S32 height, BOOL called_from_parent); @@ -75,33 +84,34 @@ public: } // hide all toasts from screen, but not remove them from a channel - virtual void hideToastsFromScreen() - { - }; // removes all toasts from a channel virtual void removeToastsFromChannel() { - for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it) + for(toast_vec_t::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it) { - addToToastPool((*it)); + addToToastPool(it->get()); } m_active_toasts.clear(); }; virtual void deleteAllChildren() { + LL_DEBUGS("NearbyChat") << "Clearing toast pool" << llendl; m_toast_pool.clear(); m_active_toasts.clear(); LLScreenChannelBase::deleteAllChildren(); } protected: + void deactivateToast(LLToast* toast); void addToToastPool(LLToast* toast) { + if (!toast) return; + LL_DEBUGS("NearbyChat") << "Pooling toast" << llendl; toast->setVisible(FALSE); toast->stopTimer(); toast->setIsHidden(true); - m_toast_pool.push_back(toast); + m_toast_pool.push_back(toast->getHandle()); } void createOverflowToast(S32 bottom, F32 timer); @@ -110,31 +120,85 @@ protected: bool createPoolToast(); - std::vector<LLToast*> m_active_toasts; - std::list<LLToast*> m_toast_pool; + toast_vec_t m_active_toasts; + toast_list_t m_toast_pool; bool mStopProcessing; }; +//----------------------------------------------------------------------------------------------- +// LLNearbyChatToast +//----------------------------------------------------------------------------------------------- + +// We're deriving from LLToast to be able to override onClose() +// in order to handle closing nearby chat toasts properly. +class LLNearbyChatToast : public LLToast +{ + LOG_CLASS(LLNearbyChatToast); +public: + LLNearbyChatToast(const LLToast::Params& p, LLNearbyChatScreenChannel* nc_channelp) + : LLToast(p), + mNearbyChatScreenChannelp(nc_channelp) + { + } + + /*virtual*/ void onClose(bool app_quitting); + +private: + LLNearbyChatScreenChannel* mNearbyChatScreenChannelp; +}; + +//----------------------------------------------------------------------------------------------- +// LLNearbyChatScreenChannel +//----------------------------------------------------------------------------------------------- + +void LLNearbyChatScreenChannel::deactivateToast(LLToast* toast) +{ + toast_vec_t::iterator pos = std::find(m_active_toasts.begin(), m_active_toasts.end(), toast->getHandle()); + + if (pos == m_active_toasts.end()) + { + llassert(pos == m_active_toasts.end()); + return; + } + + LL_DEBUGS("NearbyChat") << "Deactivating toast" << llendl; + m_active_toasts.erase(pos); +} + void LLNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer) { //we don't need overflow toast in nearby chat } -void LLNearbyChatScreenChannel::onToastDestroyed(LLToast* toast) +void LLNearbyChatScreenChannel::onToastDestroyed(LLToast* toast, bool app_quitting) { + LL_DEBUGS("NearbyChat") << "Toast destroyed (app_quitting=" << app_quitting << ")" << llendl; + + if (app_quitting) + { + // Viewer is quitting. + // Immediately stop processing chat messages (EXT-1419). mStopProcessing = true; } + else + { + // The toast is being closed by user (STORM-192). + // Remove it from the list of active toasts to prevent + // further references to the invalid pointer. + deactivateToast(toast); + } +} void LLNearbyChatScreenChannel::onToastFade(LLToast* toast) { + LL_DEBUGS("NearbyChat") << "Toast fading" << llendl; + //fade mean we put toast to toast pool if(!toast) return; - std::vector<LLToast*>::iterator pos = std::find(m_active_toasts.begin(),m_active_toasts.end(),toast); - if(pos!=m_active_toasts.end()) - m_active_toasts.erase(pos); + deactivateToast(toast); addToToastPool(toast); @@ -153,13 +217,13 @@ bool LLNearbyChatScreenChannel::createPoolToast() p.lifetime_secs = gSavedSettings.getS32("NearbyToastLifeTime"); p.fading_time_secs = gSavedSettings.getS32("NearbyToastFadingTime"); - LLToast* toast = new LLToast(p); + LLToast* toast = new LLNearbyChatToast(p, this); toast->setOnFadeCallback(boost::bind(&LLNearbyChatScreenChannel::onToastFade, this, _1)); - toast->setOnToastDestroyedCallback(boost::bind(&LLNearbyChatScreenChannel::onToastDestroyed, this, _1)); - - m_toast_pool.push_back(toast); + + LL_DEBUGS("NearbyChat") << "Creating and pooling toast" << llendl; + m_toast_pool.push_back(toast->getHandle()); return true; } @@ -177,17 +241,20 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification) { LLUUID fromID = notification["from_id"].asUUID(); // agent id or object id std::string from = notification["from"].asString(); - LLToast* toast = m_active_toasts[0]; - LLNearbyChatToastPanel* panel = dynamic_cast<LLNearbyChatToastPanel*>(toast->getPanel()); - - if(panel && panel->messageID() == fromID && panel->getFromName() == from && panel->canAddText()) + LLToast* toast = m_active_toasts[0].get(); + if (toast) { - panel->addMessage(notification); - toast->reshapeToPanel(); - toast->resetTimer(); - - arrangeToasts(); - return; + LLNearbyChatToastPanel* panel = dynamic_cast<LLNearbyChatToastPanel*>(toast->getPanel()); + + if(panel && panel->messageID() == fromID && panel->getFromName() == from && panel->canAddText()) + { + panel->addMessage(notification); + toast->reshapeToPanel(); + toast->resetTimer(); + + arrangeToasts(); + return; + } } } @@ -196,6 +263,7 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification) if(m_toast_pool.empty()) { //"pool" is empty - create one more panel + LL_DEBUGS("NearbyChat") << "Empty pool" << llendl; if(!createPoolToast())//created toast will go to pool. so next call will find it return; addNotification(notification); @@ -215,7 +283,8 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification) //take 1st element from pool, (re)initialize it, put it in active toasts - LLToast* toast = m_toast_pool.back(); + LL_DEBUGS("NearbyChat") << "Getting toast from pool" << llendl; + LLToast* toast = m_toast_pool.back().get(); m_toast_pool.pop_back(); @@ -228,25 +297,36 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification) toast->reshapeToPanel(); toast->resetTimer(); - m_active_toasts.push_back(toast); + m_active_toasts.push_back(toast->getHandle()); arrangeToasts(); } void LLNearbyChatScreenChannel::arrangeToasts() { - if(m_active_toasts.size() == 0 || isHovering()) - return; - - hideToastsFromScreen(); + if(!isHovering()) + { + showToastsBottom(); + } - showToastsBottom(); + if (m_active_toasts.empty()) + { + LLHints::registerHintTarget("incoming_chat", LLHandle<LLView>()); + } + else + { + LLToast* toast = m_active_toasts.front().get(); + if (toast) + { + LLHints::registerHintTarget("incoming_chat", m_active_toasts.front().get()->LLView::getHandle()); + } + } } -int sort_toasts_predicate(LLToast* first,LLToast* second) +int sort_toasts_predicate(LLHandle<LLToast> first, LLHandle<LLToast> second) { - F32 v1 = first->getTimer()->getEventTimer().getElapsedTimeF32(); - F32 v2 = second->getTimer()->getEventTimer().getElapsedTimeF32(); + F32 v1 = first.get()->getTimer()->getEventTimer().getElapsedTimeF32(); + F32 v2 = second.get()->getTimer()->getEventTimer().getElapsedTimeF32(); return v1 < v2; } @@ -264,20 +344,22 @@ void LLNearbyChatScreenChannel::showToastsBottom() //calc max visible item and hide other toasts. - for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it) + for(toast_vec_t::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it) { - S32 toast_top = bottom + (*it)->getRect().getHeight() + margin; + LLToast* toast = it->get(); + if (!toast) continue; + + S32 toast_top = bottom + toast->getRect().getHeight() + margin; if(toast_top > gFloaterView->getRect().getHeight()) { while(it!=m_active_toasts.end()) { - addToToastPool((*it)); + addToToastPool(it->get()); it=m_active_toasts.erase(it); } break; } - LLToast* toast = (*it); toast_rect = toast->getRect(); toast_rect.setLeftTopAndSize(getRect().mLeft , bottom + toast_rect.getHeight(), toast_rect.getWidth() ,toast_rect.getHeight()); @@ -288,14 +370,17 @@ void LLNearbyChatScreenChannel::showToastsBottom() // use reverse order to provide correct z-order and avoid toast blinking - for(std::vector<LLToast*>::reverse_iterator it = m_active_toasts.rbegin(); it != m_active_toasts.rend(); ++it) + for(toast_vec_t::reverse_iterator it = m_active_toasts.rbegin(); it != m_active_toasts.rend(); ++it) + { + LLToast* toast = it->get(); + if (toast) { - LLToast* toast = (*it); toast->setIsHidden(false); toast->setVisible(TRUE); + } + } } -} void LLNearbyChatScreenChannel::reshape (S32 width, S32 height, BOOL called_from_parent) { @@ -340,8 +425,6 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args) { if(chat_msg.mMuted == TRUE) return; - if(chat_msg.mSourceType == CHAT_SOURCE_AGENT && chat_msg.mFromID.notNull()) - LLRecentPeople::instance().add(chat_msg.mFromID); if(chat_msg.mText.empty()) return;//don't process empty messages @@ -445,6 +528,12 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args) channel->addNotification(notification); } + if(chat_msg.mSourceType == CHAT_SOURCE_AGENT + && chat_msg.mFromID.notNull() + && chat_msg.mFromID != gAgentID) + { + LLFirstUse::otherAvatarChatFirst(); + } } void LLNearbyChatHandler::onDeleteToast(LLToast* toast) @@ -452,4 +541,14 @@ void LLNearbyChatHandler::onDeleteToast(LLToast* toast) } +//----------------------------------------------------------------------------------------------- +// LLNearbyChatToast +//----------------------------------------------------------------------------------------------- + +// virtual +void LLNearbyChatToast::onClose(bool app_quitting) +{ + mNearbyChatScreenChannelp->onToastDestroyed(this, app_quitting); +} +// EOF diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp index dcbf6b64ce..9d824dcd59 100644 --- a/indra/newview/llnotificationalerthandler.cpp +++ b/indra/newview/llnotificationalerthandler.cpp @@ -133,7 +133,7 @@ bool LLAlertHandler::processNotification(const LLSD& notify) if(channel) channel->killToastByNotificationID(notification->getID()); } - return true; + return false; } //-------------------------------------------------------------------------- diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp index 9933a8a49c..9b7fdaef82 100644 --- a/indra/newview/llnotificationgrouphandler.cpp +++ b/indra/newview/llnotificationgrouphandler.cpp @@ -104,7 +104,7 @@ bool LLGroupHandler::processNotification(const LLSD& notify) { mChannel->killToastByNotificationID(notification->getID()); } - return true; + return false; } //-------------------------------------------------------------------------- diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index 060eccf5c7..28a69f2373 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -263,6 +263,29 @@ protected: void onRejectToast(LLUUID& id); }; +/** + * Handler for UI hints. + */ +class LLHintHandler : public LLSingleton<LLHintHandler> +{ +public: + LLHintHandler(); + virtual ~LLHintHandler(); + + // base interface functions + virtual bool processNotification(const LLSD& notify); +}; + +/** + * Handler for browser notifications + */ +class LLBrowserNotification : public LLSingleton<LLBrowserNotification> +{ +public: + virtual bool processNotification(const LLSD& notify); + +}; + class LLHandlerUtil { public: diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index b5683296eb..4231a73af1 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -353,7 +353,7 @@ void LLHandlerUtil::logGroupNoticeToIMGroup( if (!gAgent.getGroupData(payload["group_id"].asUUID(), groupData)) { llwarns - << "Group notice for unkown group: " + << "Group notice for unknown group: " << payload["group_id"].asUUID() << llendl; return; } diff --git a/indra/newview/llnotificationhinthandler.cpp b/indra/newview/llnotificationhinthandler.cpp new file mode 100644 index 0000000000..f7163cb04f --- /dev/null +++ b/indra/newview/llnotificationhinthandler.cpp @@ -0,0 +1,58 @@ +/** + * @file llnotificationhinthandler.cpp + * @brief Notification Handler Class for UI Hints + * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + + +#include "llviewerprecompiledheaders.h" // must be first include + +#include "llnotificationhandler.h" +#include "llhints.h" +#include "llnotifications.h" + +using namespace LLNotificationsUI; + +LLHintHandler::LLHintHandler() +{ +} + +LLHintHandler::~LLHintHandler() +{ +} + +bool LLHintHandler::processNotification(const LLSD& notify) +{ + LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); + + std::string sigtype = notify["sigtype"].asString(); + if (sigtype == "add" || sigtype == "load") + { + LLHints::show(notification); + } + else if (sigtype == "delete") + { + LLHints::hide(notification); + } + return false; +} diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp index 3bbf6cea16..6988227128 100644 --- a/indra/newview/llnotificationmanager.cpp +++ b/indra/newview/llnotificationmanager.cpp @@ -60,6 +60,8 @@ void LLNotificationManager::init() LLNotificationChannel::buildChannel("AlertModal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal")); LLNotificationChannel::buildChannel("IM Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytoast")); LLNotificationChannel::buildChannel("Offer", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "offer")); + LLNotificationChannel::buildChannel("Hints", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "hint")); + LLNotificationChannel::buildChannel("Browser", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "browser")); LLNotifications::instance().getChannel("Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); LLNotifications::instance().getChannel("NotificationTips")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); @@ -68,6 +70,8 @@ void LLNotificationManager::init() LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); LLNotifications::instance().getChannel("IM Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); LLNotifications::instance().getChannel("Offer")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1)); + LLNotifications::instance().getChannel("Hints")->connectChanged(boost::bind(&LLHintHandler::processNotification, LLHintHandler::getInstance(), _1)); + LLNotifications::instance().getChannel("Browser")->connectChanged(boost::bind(&LLBrowserNotification::processNotification, LLBrowserNotification::getInstance(), _1)); mNotifyHandlers["notify"] = boost::shared_ptr<LLEventHandler>(new LLScriptHandler(NT_NOTIFY, LLSD())); mNotifyHandlers["notifytip"] = boost::shared_ptr<LLEventHandler>(new LLTipHandler(NT_NOTIFY, LLSD())); diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp index 85f95bd0c7..68fd65be0f 100644 --- a/indra/newview/llnotificationofferhandler.cpp +++ b/indra/newview/llnotificationofferhandler.cpp @@ -179,7 +179,7 @@ bool LLOfferHandler::processNotification(const LLSD& notify) } } - return true; + return false; } //-------------------------------------------------------------------------- diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp index b4d28bb346..45590c3cdb 100644 --- a/indra/newview/llnotificationscripthandler.cpp +++ b/indra/newview/llnotificationscripthandler.cpp @@ -130,7 +130,7 @@ bool LLScriptHandler::processNotification(const LLSD& notify) mChannel->killToastByNotificationID(notification->getID()); } } - return true; + return false; } //-------------------------------------------------------------------------- diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp index 94612975a2..02b217fc94 100644 --- a/indra/newview/llnotificationtiphandler.cpp +++ b/indra/newview/llnotificationtiphandler.cpp @@ -96,7 +96,7 @@ bool LLTipHandler::processNotification(const LLSD& notify) LLNearbyChat>("nearby_chat", LLSD()); if (nearby_chat->getVisible()) { - return true; + return false; } } @@ -121,7 +121,7 @@ bool LLTipHandler::processNotification(const LLSD& notify) // don't spawn toast for inventory accepted/declined offers if respective IM window is open (EXT-5909) if (!LLHandlerUtil::canSpawnToast(notification)) { - return true; + return false; } LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification); @@ -144,7 +144,7 @@ bool LLTipHandler::processNotification(const LLSD& notify) { mChannel->killToastByNotificationID(notification->getID()); } - return true; + return false; } //-------------------------------------------------------------------------- diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index cf0b3d94bd..db9d386b6b 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -63,6 +63,39 @@ bool LLOutfitTabNameComparator::compare(const LLAccordionCtrlTab* tab1, const LL return name1 < name2; } +struct outfit_accordion_tab_params : public LLInitParam::Block<outfit_accordion_tab_params, LLAccordionCtrlTab::Params> +{ + Mandatory<LLWearableItemsList::Params> wearable_list; + + outfit_accordion_tab_params() + : wearable_list("wearable_items_list") + {} +}; + +const outfit_accordion_tab_params& get_accordion_tab_params() +{ + static outfit_accordion_tab_params tab_params; + static bool initialized = false; + if (!initialized) + { + initialized = true; + + LLXMLNodePtr xmlNode; + if (LLUICtrlFactory::getLayeredXMLNode("outfit_accordion_tab.xml", xmlNode)) + { + LLXUIParser parser; + parser.readXUI(xmlNode, tab_params, "outfit_accordion_tab.xml"); + } + else + { + llwarns << "Failed to read xml of Outfit's Accordion Tab from outfit_accordion_tab.xml" << llendl; + } + } + + return tab_params; +} + + ////////////////////////////////////////////////////////////////////////// class LLOutfitListGearMenu @@ -85,7 +118,7 @@ public: registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenu::onAdd, this)); - enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitsList::isActionEnabled, mOutfitList, _2)); + enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenu::onEnable, this, _2)); enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenu::onVisible, this, _2)); mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>( @@ -155,29 +188,13 @@ private: void onTakeOff() { - // Take off selected items if there are any - if (mOutfitList->hasItemSelected()) - { - uuid_vec_t selected_uuids; - mOutfitList->getSelectedItemsUUIDs(selected_uuids); - - for (uuid_vec_t::const_iterator it=selected_uuids.begin(); it != selected_uuids.end(); ++it) - { - if (get_is_item_worn(*it)) - { - LLAppearanceMgr::instance().removeItemFromAvatar(*it); - } - } - } - else // or take off the whole selected outfit if no items specified. - { + // Take off selected outfit. const LLUUID& selected_outfit_id = getSelectedOutfitID(); if (selected_outfit_id.notNull()) { LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id); } } - } void onRename() { @@ -209,6 +226,20 @@ private: LLAgentWearables::createWearable(type, true); } + bool onEnable(LLSD::String param) + { + // Handle the "Wear - Replace Current Outfit" menu option specially + // because LLOutfitList::isActionEnabled() checks whether it's allowed + // to wear selected outfit OR selected items, while we're only + // interested in the outfit (STORM-183). + if ("wear" == param) + { + return LLAppearanceMgr::instance().getCanReplaceCOF(mOutfitList->getSelectedOutfitUUID()); + } + + return mOutfitList->isActionEnabled(param); + } + bool onVisible(LLSD::String param) { const LLUUID& selected_outfit_id = getSelectedOutfitID(); @@ -437,9 +468,12 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) std::string name = cat->getName(); - static LLXMLNodePtr accordionXmlNode = getAccordionTabXMLNode(); - LLAccordionCtrlTab* tab = LLUICtrlFactory::defaultBuilder<LLAccordionCtrlTab>(accordionXmlNode, NULL, NULL); + outfit_accordion_tab_params tab_params(get_accordion_tab_params()); + LLAccordionCtrlTab* tab = LLUICtrlFactory::create<LLAccordionCtrlTab>(tab_params); if (!tab) continue; + LLWearableItemsList* wearable_list = LLUICtrlFactory::create<LLWearableItemsList>(tab_params.wearable_list); + wearable_list->setShape(tab->getLocalRect()); + tab->addChild(wearable_list); tab->setName(name); tab->setTitle(name); @@ -456,7 +490,7 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) mAccordion->removeCollapsibleCtrl(tab); // kill removed tab - tab->die(); + tab->die(); continue; } @@ -729,19 +763,6 @@ bool LLOutfitsList::hasItemSelected() ////////////////////////////////////////////////////////////////////////// // Private methods ////////////////////////////////////////////////////////////////////////// -LLXMLNodePtr LLOutfitsList::getAccordionTabXMLNode() -{ - LLXMLNodePtr xmlNode = NULL; - bool success = LLUICtrlFactory::getLayeredXMLNode("outfit_accordion_tab.xml", xmlNode); - if (!success) - { - llwarns << "Failed to read xml of Outfit's Accordion Tab from outfit_accordion_tab.xml" << llendl; - return NULL; - } - - return xmlNode; -} - void LLOutfitsList::computeDifference( const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index faf6f7ce1e..f73ae5bef2 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -111,12 +111,6 @@ public: bool hasItemSelected(); private: - /** - * Reads xml with accordion tab and Flat list from xml file. - * - * @return LLPointer to XMLNode with accordion tab and flat list. - */ - LLXMLNodePtr getAccordionTabXMLNode(); /** * Wrapper for LLCommonUtils::computeDifference. @see LLCommonUtils::computeDifference diff --git a/indra/newview/llpanelavatartag.cpp b/indra/newview/llpanelavatartag.cpp index d174b8da96..77d67c7b09 100644 --- a/indra/newview/llpanelavatartag.cpp +++ b/indra/newview/llpanelavatartag.cpp @@ -37,7 +37,7 @@ LLPanelAvatarTag::LLPanelAvatarTag(const LLUUID& key, const std::string im_time) , mAvatarId(LLUUID::null) // , mFadeTimer() { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_tag.xml"); + buildFromFile( "panel_avatar_tag.xml"); setLeftButtonClickCallback(boost::bind(&LLPanelAvatarTag::onClick, this)); setAvatarId(key); setTime(im_time); diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index bf7214eb3b..6889b98ab1 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -138,7 +138,7 @@ LLPanelClassifiedInfo::~LLPanelClassifiedInfo() LLPanelClassifiedInfo* LLPanelClassifiedInfo::create() { LLPanelClassifiedInfo* panel = new LLPanelClassifiedInfo(); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_classified_info.xml"); + panel->buildFromFile("panel_classified_info.xml"); return panel; } @@ -611,7 +611,7 @@ LLPanelClassifiedEdit::~LLPanelClassifiedEdit() LLPanelClassifiedEdit* LLPanelClassifiedEdit::create() { LLPanelClassifiedEdit* panel = new LLPanelClassifiedEdit(); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_edit_classified.xml"); + panel->buildFromFile("panel_edit_classified.xml"); return panel; } diff --git a/indra/newview/llpanelgenerictip.cpp b/indra/newview/llpanelgenerictip.cpp index 2660814afc..4ccdaa78f3 100644 --- a/indra/newview/llpanelgenerictip.cpp +++ b/indra/newview/llpanelgenerictip.cpp @@ -36,7 +36,7 @@ LLPanelGenericTip::LLPanelGenericTip( const LLNotificationPtr& notification) : LLPanelTipToast(notification) { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_generic_tip.xml"); + buildFromFile( "panel_generic_tip.xml"); getChild<LLUICtrl>("message")->setValue(notification->getMessage()); diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 62ed7acb15..76b85d5bec 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -597,7 +597,7 @@ void LLPanelGroup::showNotice(const std::string& subject, //static void LLPanelGroup::refreshCreatedGroup(const LLUUID& group_id) { - LLPanelGroup* panel = LLSideTray::getInstance()->findChild<LLPanelGroup>("panel_group_info_sidetray"); + LLPanelGroup* panel = LLSideTray::getInstance()->getPanel<LLPanelGroup>("panel_group_info_sidetray"); if(!panel) return; panel->setGroupID(group_id); @@ -612,7 +612,7 @@ void LLPanelGroup::showNotice(const std::string& subject, const std::string& inventory_name, LLOfferInfo* inventory_offer) { - LLPanelGroup* panel = LLSideTray::getInstance()->findChild<LLPanelGroup>("panel_group_info_sidetray"); + LLPanelGroup* panel = LLSideTray::getInstance()->getPanel<LLPanelGroup>("panel_group_info_sidetray"); if(!panel) return; diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 840b98213d..3a31d99598 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -740,7 +740,7 @@ void LLPanelGroupGeneral::updateMembers() sSDTime += sd_timer.getElapsedTimeF32(); element_timer.reset(); - LLScrollListItem* member_row = mListVisibleMembers->addElement(row);//, ADD_SORTED); + LLScrollListItem* member_row = mListVisibleMembers->addElement(row); if ( member->isOwner() ) { diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index 535b2a9e2d..b26bcc854c 100644 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -369,7 +369,7 @@ LLPanelGroupInvite::LLPanelGroupInvite(const LLUUID& group_id) mPendingUpdate(FALSE) { // Pass on construction of this panel to the control factory. - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_group_invite.xml"); + buildFromFile( "panel_group_invite.xml"); } LLPanelGroupInvite::~LLPanelGroupInvite() diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index d4736d22ae..8d8d9bc1c4 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -522,7 +522,7 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg) row["columns"][4]["column"] = "hidden"; row["columns"][4]["value"] = hidden; - mGroupParcelsp->addElement(row, ADD_SORTED); + mGroupParcelsp->addElement(row); } } } diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 579a271ce8..639364ff8d 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -1625,7 +1625,7 @@ void LLPanelGroupMembersSubTab::updateMembers() row["columns"][2]["value"] = mMemberProgress->second->getOnlineStatus(); row["columns"][2]["font"] = "SANSSERIF_SMALL"; - LLScrollListItem* member = mMembersList->addElement(row);//, ADD_SORTED); + LLScrollListItem* member = mMembersList->addElement(row); LLUUID id = member->getUUID(); mHasMatch = TRUE; diff --git a/indra/newview/llpanelhome.cpp b/indra/newview/llpanelhome.cpp index 93c4e0c9c7..b03bab3127 100644 --- a/indra/newview/llpanelhome.cpp +++ b/indra/newview/llpanelhome.cpp @@ -61,7 +61,6 @@ BOOL LLPanelHome::postBuild() std::string url = LLViewerHome::getHomeURL(); mBrowser->addObserver(this); - mBrowser->setTrusted(true); mBrowser->setHomePageUrl(url); } diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index ff15e3f08e..c4a484d368 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -197,7 +197,7 @@ LLLandmarksPanel::LLLandmarksPanel() mInventoryObserver = new LLLandmarksPanelObserver(this); gInventory.addObserver(mInventoryObserver); - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_landmarks.xml"); + buildFromFile( "panel_landmarks.xml"); } LLLandmarksPanel::~LLLandmarksPanel() @@ -965,12 +965,32 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const || "expand" == command_name ) { - return canSelectedBeModified(command_name); + if (!root_folder_view) return false; + + std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList(); + + // Allow to execute the command only if it can be applied to all selected items. + for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter) + { + LLFolderViewItem* item = root_folder_view->getItemByID(*iter); + + // If no item is found it might be a folder id. + if (!item) + { + item = root_folder_view->getFolderByID(*iter); + } + if (!item) return false; + + if (!canItemBeModified(command_name, item)) return false; + } + + return true; } else if ( "teleport" == command_name || "more_info" == command_name || "show_on_map" == command_name || "copy_slurl" == command_name + || "rename" == command_name ) { // disable some commands for multi-selection. EXT-1757 @@ -993,13 +1013,16 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const // Disable "Show on Map" if landmark loading is in progress. return !gLandmarkList.isAssetInLoadedCallbackMap(asset_uuid); - } - - return true; } else if ("rename" == command_name) { - return root_folder_view && root_folder_view->getSelectedCount() == 1 && canSelectedBeModified(command_name); + LLFolderViewItem* selected_item = getCurSelectedItem(); + if (!selected_item) return false; + + return canItemBeModified(command_name, selected_item); + } + + return true; } else if("category" == command_name) { @@ -1065,12 +1088,11 @@ Rules: 4. We can not paste folders from Clipboard (processed by LLFolderView::canPaste()) 5. Check LLFolderView/Inventory Bridges rules */ -bool LLLandmarksPanel::canSelectedBeModified(const std::string& command_name) const +bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const { // validate own rules first - LLFolderViewItem* selected = getCurSelectedItem(); - if (!selected) return false; + if (!item) return false; // nothing can be modified in Library if (mLibraryInventoryPanel == mCurrentSelectedList) return false; @@ -1078,7 +1100,7 @@ bool LLLandmarksPanel::canSelectedBeModified(const std::string& command_name) co bool can_be_modified = false; // landmarks can be modified in any other accordion... - if (isLandmarkSelected()) + if (item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK) { can_be_modified = true; @@ -1107,16 +1129,16 @@ bool LLLandmarksPanel::canSelectedBeModified(const std::string& command_name) co } else if ("collapse" == command_name) { - return selected->isOpen(); + return item->isOpen(); } else if ("expand" == command_name) { - return !selected->isOpen(); + return !item->isOpen(); } if (can_be_modified) { - LLFolderViewEventListener* listenerp = selected->getListener(); + LLFolderViewEventListener* listenerp = item->getListener(); if ("cut" == command_name) { @@ -1223,7 +1245,12 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark, landmark->getGlobalPos(landmark_global_pos); // let's toggle pick panel into panel places - LLPanel* panel_places = LLSideTray::getInstance()->getChild<LLPanel>("panel_places");//-> sidebar_places + LLPanel* panel_places = LLSideTray::getInstance()->getPanel("panel_places");//-> sidebar_places + if (!panel_places) + { + llassert(NULL != panel_places); + return; + } panel_places->addChild(panel_pick); LLRect paren_rect(panel_places->getRect()); panel_pick->reshape(paren_rect.getWidth(),paren_rect.getHeight(), TRUE); diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 2b398decce..0d4402d8cb 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -127,12 +127,12 @@ private: void onCustomAction(const LLSD& command_name); /** - * Determines if selected item can be modified via context/gear menu. + * Determines if an item can be modified via context/gear menu. * * It validates Places Landmarks rules first. And then LLFolderView permissions. * For now it checks cut/rename/delete/paste actions. */ - bool canSelectedBeModified(const std::string& command_name) const; + bool canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const; void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params); /** diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index be1afbd8d7..7c93d8a1f9 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -187,7 +187,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, // Logo mLogoImage = LLUI::getUIImage("startup_logo"); - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_login.xml"); + buildFromFile( "panel_login.xml"); #if USE_VIEWER_AUTH //leave room for the login menu bar @@ -257,13 +257,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, // Clear the browser's cache to avoid any potential for the cache messing up the login screen. web_browser->clearCache(); - // Need to handle login secondlife:///app/ URLs - web_browser->setTrusted( true ); - - // don't make it a tab stop until SL-27594 is fixed - web_browser->setTabStop(FALSE); - // web_browser->navigateToLocalPage( "loading", "loading.html" ); - reshapeBrowser(); // kick off a request to grab the url manually @@ -1104,9 +1097,10 @@ void LLPanelLogin::updateServerCombo() { if (!grid_choice->first.empty()) { - server_choice_combo->add(grid_choice->second, grid_choice->first, ADD_SORTED); + server_choice_combo->add(grid_choice->second, grid_choice->first); } } + server_choice_combo->sortByName(); server_choice_combo->addSeparator(ADD_TOP); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 27e054af34..5b07e4863b 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -642,7 +642,7 @@ LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* invento mPanelMainInventory(inventory_view), mFilter(inventory_view->getPanel()->getFilter()) { - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory_view_finder.xml", NULL); + buildFromFile("floater_inventory_view_finder.xml"); updateElementsFromFilter(); } diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index fb31206870..cf2cc14531 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -41,6 +41,7 @@ class LLFilterEditor; class LLTabContainer; class LLFloaterInventoryFinder; class LLMenuGL; +class LLFloater; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLPanelMainInventory diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp index 5cd4cea96d..36a3aae15f 100644 --- a/indra/newview/llpanelme.cpp +++ b/indra/newview/llpanelme.cpp @@ -162,7 +162,7 @@ void LLPanelMe::onCancelClicked() LLPanelMyProfileEdit::LLPanelMyProfileEdit() : LLPanelMyProfile() { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_edit_profile.xml"); + buildFromFile( "panel_edit_profile.xml"); setAvatarId(gAgent.getID()); } diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp index 92c8365a70..2856ea9db1 100644 --- a/indra/newview/llpanelmediasettingsgeneral.cpp +++ b/indra/newview/llpanelmediasettingsgeneral.cpp @@ -74,7 +74,7 @@ LLPanelMediaSettingsGeneral::LLPanelMediaSettingsGeneral() : mMediaEditable(false) { // build dialog from XML - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_general.xml"); + buildFromFile( "panel_media_settings_general.xml"); } //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llpanelmediasettingspermissions.cpp b/indra/newview/llpanelmediasettingspermissions.cpp index 339376cbf6..5378886b56 100644 --- a/indra/newview/llpanelmediasettingspermissions.cpp +++ b/indra/newview/llpanelmediasettingspermissions.cpp @@ -59,7 +59,7 @@ LLPanelMediaSettingsPermissions::LLPanelMediaSettingsPermissions() : mPermsWorldControl( 0 ) { // build dialog from XML - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_permissions.xml"); + buildFromFile( "panel_media_settings_permissions.xml"); } //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llpanelmediasettingssecurity.cpp b/indra/newview/llpanelmediasettingssecurity.cpp index a0d4c2f761..b588e8f930 100644 --- a/indra/newview/llpanelmediasettingssecurity.cpp +++ b/indra/newview/llpanelmediasettingssecurity.cpp @@ -53,7 +53,7 @@ LLPanelMediaSettingsSecurity::LLPanelMediaSettingsSecurity() : mCommitCallbackRegistrar.add("Media.whitelistDelete", boost::bind(&LLPanelMediaSettingsSecurity::onBtnDel, this)); // build dialog from XML - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_security.xml"); + buildFromFile( "panel_media_settings_security.xml"); } //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index 811d70ade3..fcc67d6840 100644 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -96,7 +96,7 @@ LLPanelNearByMedia::LLPanelNearByMedia() mCommitCallbackRegistrar.add("SelectedMediaCtrl.Zoom", boost::bind(&LLPanelNearByMedia::onClickSelectedMediaZoom, this)); mCommitCallbackRegistrar.add("SelectedMediaCtrl.Unzoom", boost::bind(&LLPanelNearByMedia::onClickSelectedMediaUnzoom, this)); - LLUICtrlFactory::instance().buildPanel(this, "panel_nearby_media.xml"); + buildFromFile( "panel_nearby_media.xml"); } LLPanelNearByMedia::~LLPanelNearByMedia() diff --git a/indra/newview/llpanelonlinestatus.cpp b/indra/newview/llpanelonlinestatus.cpp index 2f1300e0f2..8202dfe9a3 100644 --- a/indra/newview/llpanelonlinestatus.cpp +++ b/indra/newview/llpanelonlinestatus.cpp @@ -35,7 +35,7 @@ LLPanelOnlineStatus::LLPanelOnlineStatus( LLPanelTipToast(notification) { - LLUICtrlFactory::getInstance()->buildPanel(this, + buildFromFile( "panel_online_status_toast.xml"); diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 54b0805a6c..494db01f77 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -485,7 +485,7 @@ BOOL LLPanelOutfitEdit::postBuild() setVisibleCallback(boost::bind(&LLPanelOutfitEdit::onVisibilityChange, this, _2)); - mCOFWearables = getChild<LLCOFWearables>("cof_wearables_list"); + mCOFWearables = findChild<LLCOFWearables>("cof_wearables_list"); mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::filterWearablesBySelectedItem, this)); mCOFWearables->getCOFCallbacks().mAddWearable = boost::bind(&LLPanelOutfitEdit::onAddWearableClicked, this); @@ -912,7 +912,7 @@ void LLPanelOutfitEdit::onRemoveFromOutfitClicked(void) { LLUUID id_to_remove = mCOFWearables->getSelectedUUID(); LLWearableType::EType type = getWearableTypeByItemUUID(id_to_remove); - + LLAppearanceMgr::getInstance()->removeItemFromAvatar(id_to_remove); if (!mCOFWearables->getSelectedItem()) @@ -1031,7 +1031,7 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void) LLUUID selected_item_id = mWearableItemsList->getSelectedUUID(); LLViewerInventoryItem* item = gInventory.getLinkedItem(selected_item_id); if(item) - { + { showFilteredWearablesListView(item->getWearableType()); return; } diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index c6a7bd88a0..d6d8a38ebe 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -217,15 +217,6 @@ void LLPanelOutfitsInventory::onSave() //payload["ids"].append(*it); LLNotificationsUtil::add("SaveOutfitAs", args, payload, boost::bind(&LLPanelOutfitsInventory::onSaveCommit, this, _1, _2)); - - //) - -/* - LLOutfitSaveAsDialog* save_as_dialog = LLFloaterReg::showTypedInstance<LLOutfitSaveAsDialog>("outfit_save_as", LLSD(outfit_name), TRUE); - if (save_as_dialog) - { - save_as_dialog->setSaveAsCommit(boost::bind(&LLPanelOutfitsInventory::onSaveCommit, this, _1 )); - }*/ } //static @@ -302,10 +293,10 @@ bool LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata) void LLPanelOutfitsInventory::initTabPanels() { - mCurrentOutfitPanel = getChild<LLPanelWearing>(COF_TAB_NAME); + mCurrentOutfitPanel = findChild<LLPanelWearing>(COF_TAB_NAME); mCurrentOutfitPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this)); - mMyOutfitsPanel = getChild<LLOutfitsList>(OUTFITS_TAB_NAME); + mMyOutfitsPanel = findChild<LLOutfitsList>(OUTFITS_TAB_NAME); mMyOutfitsPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this)); mAppearanceTabs = getChild<LLTabContainer>("appearance_tabs"); diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp index 7615a93a49..271728220c 100644 --- a/indra/newview/llpanelpick.cpp +++ b/indra/newview/llpanelpick.cpp @@ -74,7 +74,7 @@ LLPanelPickInfo* LLPanelPickInfo::create() { LLPanelPickInfo* panel = new LLPanelPickInfo(); - LLUICtrlFactory::getInstance()->buildPanel(panel, XML_PANEL_PICK_INFO); + panel->buildFromFile(XML_PANEL_PICK_INFO); return panel; } @@ -344,7 +344,7 @@ void LLPanelPickInfo::onClickBack() LLPanelPickEdit* LLPanelPickEdit::create() { LLPanelPickEdit* panel = new LLPanelPickEdit(); - LLUICtrlFactory::getInstance()->buildPanel(panel, XML_PANEL_EDIT_PICK); + panel->buildFromFile(XML_PANEL_EDIT_PICK); return panel; } diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index a5c3c9faef..27787ac211 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -1039,7 +1039,7 @@ LLPickItem::LLPickItem() , mSnapshotID(LLUUID::null) , mNeedData(true) { - LLUICtrlFactory::getInstance()->buildPanel(this,"panel_pick_list_item.xml"); + buildFromFile("panel_pick_list_item.xml"); } LLPickItem::~LLPickItem() @@ -1169,7 +1169,7 @@ LLClassifiedItem::LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classi , mAvatarId(avatar_id) , mClassifiedId(classified_id) { - LLUICtrlFactory::getInstance()->buildPanel(this,"panel_classifieds_list_item.xml"); + buildFromFile("panel_classifieds_list_item.xml"); LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this); LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId()); diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index ee30c928c2..801db1e741 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -230,6 +230,11 @@ void LLPanelPlaceProfile::setInfoType(EInfoType type) break; } + if (mAccordionCtrl != NULL) + { + mAccordionCtrl->expandDefaultTab(); + } + LLPanelPlaceInfo::setInfoType(type); } @@ -274,11 +279,6 @@ void LLPanelPlaceProfile::handleVisibilityChange(BOOL new_visibility) parcel_mgr->deselectUnused(); } } - - if (mAccordionCtrl != NULL) - { - mAccordionCtrl->expandDefaultTab(); - } } void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 5aed1e55e3..f0e60386b6 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -37,6 +37,7 @@ #include "llcombobox.h" #include "llfiltereditor.h" +#include "llfirstuse.h" #include "llfloaterreg.h" #include "llnotificationsutil.h" #include "lltabcontainer.h" @@ -246,7 +247,7 @@ LLPanelPlaces::LLPanelPlaces() LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback( boost::bind(&LLPanelPlaces::updateVerbs, this)); - //LLUICtrlFactory::getInstance()->buildPanel(this, "panel_places.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() + //buildFromFile( "panel_places.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() } LLPanelPlaces::~LLPanelPlaces() @@ -321,8 +322,8 @@ BOOL LLPanelPlaces::postBuild() mFilterEditor->setCommitCallback(boost::bind(&LLPanelPlaces::onFilterEdit, this, _2, false)); } - mPlaceProfile = getChild<LLPanelPlaceProfile>("panel_place_profile"); - mLandmarkInfo = getChild<LLPanelLandmarkInfo>("panel_landmark_info"); + mPlaceProfile = findChild<LLPanelPlaceProfile>("panel_place_profile"); + mLandmarkInfo = findChild<LLPanelLandmarkInfo>("panel_landmark_info"); if (!mPlaceProfile || !mLandmarkInfo) return FALSE; @@ -346,6 +347,8 @@ BOOL LLPanelPlaces::postBuild() void LLPanelPlaces::onOpen(const LLSD& key) { + LLFirstUse::notUsingDestinationGuide(false); + if (!mPlaceProfile || !mLandmarkInfo) return; diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index f198a411a3..b04971f980 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -114,7 +114,7 @@ LLPanelPrimMediaControls::LLPanelPrimMediaControls() : mCommitCallbackRegistrar.add("MediaCtrl.SkipBack", boost::bind(&LLPanelPrimMediaControls::onClickSkipBack, this)); mCommitCallbackRegistrar.add("MediaCtrl.SkipForward", boost::bind(&LLPanelPrimMediaControls::onClickSkipForward, this)); - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_prim_media_controls.xml"); + buildFromFile( "panel_prim_media_controls.xml"); mInactivityTimer.reset(); mFadeTimer.stop(); mCurrentZoom = ZOOM_NONE; @@ -1173,7 +1173,7 @@ void LLPanelPrimMediaControls::setCurrentURL() // if (media_address_combo && mCurrentURL != "about:blank") // { // media_address_combo->remove(mCurrentURL); -// media_address_combo->add(mCurrentURL, ADD_SORTED); +// media_address_combo->add(mCurrentURL); // media_address_combo->selectByValue(mCurrentURL); // } #else // USE_COMBO_BOX_FOR_MEDIA_URL diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 65b9e76a4e..4e63563979 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -127,11 +127,11 @@ BOOL LLPanelProfile::postBuild() getTabCtrl()->setCommitCallback(boost::bind(&LLPanelProfile::onTabSelected, this, _2)); - LLPanelPicks* panel_picks = getChild<LLPanelPicks>(PANEL_PICKS); + LLPanelPicks* panel_picks = findChild<LLPanelPicks>(PANEL_PICKS); panel_picks->setProfilePanel(this); getTabContainer()[PANEL_PICKS] = panel_picks; - getTabContainer()[PANEL_PROFILE] = getChild<LLPanelAvatarProfile>(PANEL_PROFILE); + getTabContainer()[PANEL_PROFILE] = findChild<LLPanelAvatarProfile>(PANEL_PROFILE); return TRUE; } diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp index c0f504fef6..dba047660d 100644 --- a/indra/newview/llpanelprofileview.cpp +++ b/indra/newview/llpanelprofileview.cpp @@ -114,7 +114,7 @@ BOOL LLPanelProfileView::postBuild() { LLPanelProfile::postBuild(); - getTabContainer()[PANEL_NOTES] = getChild<LLPanelAvatarNotes>(PANEL_NOTES); + getTabContainer()[PANEL_NOTES] = findChild<LLPanelAvatarNotes>(PANEL_NOTES); //*TODO remove this, according to style guide we don't use status combobox getTabContainer()[PANEL_PROFILE]->getChildView("online_me_status_text")->setVisible( FALSE); diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index a7cbf52290..9b8167b15a 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -126,7 +126,7 @@ LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistor mRegionName(region_name), mHighlight(hl) { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_teleport_history_item.xml"); + buildFromFile( "panel_teleport_history_item.xml"); } LLTeleportHistoryFlatItem::~LLTeleportHistoryFlatItem() @@ -377,7 +377,7 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel() mLastSelectedFlatlList(NULL), mLastSelectedItemIndex(-1) { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_teleport_history.xml"); + buildFromFile( "panel_teleport_history.xml"); } LLTeleportHistoryPanel::~LLTeleportHistoryPanel() diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp index 0d17fb3e82..a9ca7314ce 100644 --- a/indra/newview/llpaneltopinfobar.cpp +++ b/indra/newview/llpaneltopinfobar.cpp @@ -66,7 +66,7 @@ LLPanelTopInfoBar::LLPanelTopInfoBar(): mParcelChangedObserver(0) LLUICtrl::CommitCallbackRegistry::currentRegistrar() .add("TopInfoBar.Action", boost::bind(&LLPanelTopInfoBar::onContextMenuItemClicked, this, _2)); - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_topinfo_bar.xml"); + buildFromFile( "panel_topinfo_bar.xml"); } LLPanelTopInfoBar::~LLPanelTopInfoBar() diff --git a/indra/newview/llfloatervoicedevicesettings.cpp b/indra/newview/llpanelvoicedevicesettings.cpp index 34277001ee..aef870d352 100644 --- a/indra/newview/llfloatervoicedevicesettings.cpp +++ b/indra/newview/llpanelvoicedevicesettings.cpp @@ -1,5 +1,5 @@ /** - * @file llfloatervoicedevicesettings.cpp + * @file llpanelvoicedevicesettings.cpp * @author Richard Nelson * @brief Voice communication set-up * @@ -27,13 +27,10 @@ #include "llviewerprecompiledheaders.h" -#include "llfloatervoicedevicesettings.h" +#include "llpanelvoicedevicesettings.h" // Viewer includes -#include "llbutton.h" #include "llcombobox.h" -#include "llfocusmgr.h" -#include "lliconctrl.h" #include "llsliderctrl.h" #include "llviewercontrol.h" #include "llvoiceclient.h" @@ -70,8 +67,10 @@ BOOL LLPanelVoiceDeviceSettings::postBuild() // set mic volume tuning slider based on last mic volume setting volume_slider->setValue(mMicVolume); - childSetCommitCallback("voice_input_device", onCommitInputDevice, this); - childSetCommitCallback("voice_output_device", onCommitOutputDevice, this); + getChild<LLComboBox>("voice_input_device")->setCommitCallback( + boost::bind(&LLPanelVoiceDeviceSettings::onCommitInputDevice, this)); + getChild<LLComboBox>("voice_output_device")->setCommitCallback( + boost::bind(&LLPanelVoiceDeviceSettings::onCommitOutputDevice, this)); return TRUE; } @@ -303,91 +302,20 @@ void LLPanelVoiceDeviceSettings::cleanup() LLVoiceChannel::resume(); } -// static -void LLPanelVoiceDeviceSettings::onCommitInputDevice(LLUICtrl* ctrl, void* user_data) +void LLPanelVoiceDeviceSettings::onCommitInputDevice() { if(LLVoiceClient::getInstance()) { - LLVoiceClient::getInstance()->setCaptureDevice(ctrl->getValue().asString()); + LLVoiceClient::getInstance()->setCaptureDevice( + getChild<LLComboBox>("voice_input_device")->getValue().asString()); } } -// static -void LLPanelVoiceDeviceSettings::onCommitOutputDevice(LLUICtrl* ctrl, void* user_data) +void LLPanelVoiceDeviceSettings::onCommitOutputDevice() { if(LLVoiceClient::getInstance()) { - LLVoiceClient::getInstance()->setRenderDevice(ctrl->getValue().asString()); + LLVoiceClient::getInstance()->setRenderDevice( + getChild<LLComboBox>("voice_input_device")->getValue().asString()); } } - -// -// LLFloaterVoiceDeviceSettings -// - -LLFloaterVoiceDeviceSettings::LLFloaterVoiceDeviceSettings(const LLSD& seed) - : LLFloater(seed), - mDevicePanel(NULL) -{ - mFactoryMap["device_settings"] = LLCallbackMap(createPanelVoiceDeviceSettings, this); - // do not automatically open singleton floaters (as result of getInstance()) -// BOOL no_open = FALSE; -// Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_device_settings.xml", no_open); -} -BOOL LLFloaterVoiceDeviceSettings::postBuild() -{ - center(); - return TRUE; -} - -// virtual -void LLFloaterVoiceDeviceSettings::onOpen(const LLSD& key) -{ - if(mDevicePanel) - { - mDevicePanel->initialize(); - } -} - -// virtual -void LLFloaterVoiceDeviceSettings::onClose(bool app_settings) -{ - if(mDevicePanel) - { - mDevicePanel->apply(); - mDevicePanel->cleanup(); - } -} - -void LLFloaterVoiceDeviceSettings::apply() -{ - if (mDevicePanel) - { - mDevicePanel->apply(); - } -} - -void LLFloaterVoiceDeviceSettings::cancel() -{ - if (mDevicePanel) - { - mDevicePanel->cancel(); - } -} - -void LLFloaterVoiceDeviceSettings::draw() -{ - if (mDevicePanel) - { - mDevicePanel->refresh(); - } - LLFloater::draw(); -} - -// static -void* LLFloaterVoiceDeviceSettings::createPanelVoiceDeviceSettings(void* user_data) -{ - LLFloaterVoiceDeviceSettings* floaterp = (LLFloaterVoiceDeviceSettings*)user_data; - floaterp->mDevicePanel = new LLPanelVoiceDeviceSettings(); - return floaterp->mDevicePanel; -} diff --git a/indra/newview/llfloatervoicedevicesettings.h b/indra/newview/llpanelvoicedevicesettings.h index 5f892972de..636b8b9948 100644 --- a/indra/newview/llfloatervoicedevicesettings.h +++ b/indra/newview/llpanelvoicedevicesettings.h @@ -25,10 +25,10 @@ * $/LicenseInfo$ */ -#ifndef LL_LLFLOATERVOICEDEVICESETTINGS_H -#define LL_LLFLOATERVOICEDEVICESETTINGS_H +#ifndef LL_LLPANELVOICEDEVICESETTINGS_H +#define LL_LLPANELVOICEDEVICESETTINGS_H -#include "llfloater.h" +#include "llpanel.h" class LLPanelVoiceDeviceSettings : public LLPanel { @@ -47,8 +47,8 @@ public: /*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); protected: - static void onCommitInputDevice(LLUICtrl* ctrl, void* user_data); - static void onCommitOutputDevice(LLUICtrl* ctrl, void* user_data); + void onCommitInputDevice(); + void onCommitOutputDevice(); F32 mMicVolume; std::string mInputDevice; @@ -58,26 +58,4 @@ protected: BOOL mDevicesUpdated; }; -class LLFloaterVoiceDeviceSettings : public LLFloater -{ - friend class LLFloaterReg; - -public: - - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_settings); - /*virtual*/ void draw(); - void apply(); - void cancel(); -private: - LLFloaterVoiceDeviceSettings(const LLSD& seed); - -protected: - static void* createPanelVoiceDeviceSettings(void* user_data); - -protected: - LLPanelVoiceDeviceSettings* mDevicePanel; -}; - -#endif // LL_LLFLOATERVOICEDEVICESETTINGS_H +#endif // LL_LLPANELVOICEDEVICESETTINGS_H diff --git a/indra/newview/llpanelvolumepulldown.cpp b/indra/newview/llpanelvolumepulldown.cpp index f2772b5d88..aea7b33d7f 100644 --- a/indra/newview/llpanelvolumepulldown.cpp +++ b/indra/newview/llpanelvolumepulldown.cpp @@ -54,7 +54,7 @@ LLPanelVolumePulldown::LLPanelVolumePulldown() mCommitCallbackRegistrar.add("Vol.setControlFalse", boost::bind(&LLPanelVolumePulldown::setControlFalse, this, _2)); mCommitCallbackRegistrar.add("Vol.GoAudioPrefs", boost::bind(&LLPanelVolumePulldown::onAdvancedButtonClick, this, _2)); - LLUICtrlFactory::instance().buildPanel(this, "panel_volume_pulldown.xml"); + buildFromFile( "panel_volume_pulldown.xml"); } BOOL LLPanelVolumePulldown::postBuild() diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp index b328f65349..8e8b530e13 100644 --- a/indra/newview/llpreviewanim.cpp +++ b/indra/newview/llpreviewanim.cpp @@ -43,7 +43,6 @@ extern LLAgent gAgent; LLPreviewAnim::LLPreviewAnim(const LLSD& key) : LLPreview( key ) { - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_animation.xml", FALSE); } // static diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 3f4edbaf97..16284d1a7e 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -311,9 +311,6 @@ LLPreviewGesture::LLPreviewGesture(const LLSD& key) NONE_LABEL = LLTrans::getString("---"); SHIFT_LABEL = LLTrans::getString("KBShift"); CTRL_LABEL = LLTrans::getString("KBCtrl"); - - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_gesture.xml", FALSE); - } diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index e85a6a7094..9f3ee6ac5d 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -71,7 +71,6 @@ LLPreviewNotecard::LLPreviewNotecard(const LLSD& key) //const LLUUID& item_id, { mAssetID = item->getAssetUUID(); } - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_notecard.xml", FALSE); } LLPreviewNotecard::~LLPreviewNotecard() diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index d280cf1625..cf2ea38288 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -138,6 +138,9 @@ public: LLScriptEdCore* getEditorCore() { return mEditorCore; } static LLFloaterScriptSearch* getInstance() { return sInstance; } + virtual bool hasAccelerators() const; + virtual BOOL handleKeyHere(KEY key, MASK mask); + private: LLScriptEdCore* mEditorCore; @@ -151,7 +154,7 @@ LLFloaterScriptSearch::LLFloaterScriptSearch(LLScriptEdCore* editor_core) : LLFloater(LLSD()), mEditorCore(editor_core) { - LLUICtrlFactory::getInstance()->buildFloater(this,"floater_script_search.xml", NULL); + buildFromFile("floater_script_search.xml"); sInstance = this; @@ -242,7 +245,24 @@ void LLFloaterScriptSearch::handleBtnReplaceAll() mEditorCore->mEditor->replaceTextAll(getChild<LLUICtrl>("search_text")->getValue().asString(), getChild<LLUICtrl>("replace_text")->getValue().asString(), caseChk->get()); } +bool LLFloaterScriptSearch::hasAccelerators() const +{ + if (mEditorCore) + { + return mEditorCore->hasAccelerators(); + } + return FALSE; +} + +BOOL LLFloaterScriptSearch::handleKeyHere(KEY key, MASK mask) +{ + if (mEditorCore) + { + return mEditorCore->handleKeyHere(key, mask); + } + return FALSE; +} /// --------------------------------------------------------------------------- /// LLScriptEdCore @@ -654,7 +674,7 @@ void LLScriptEdCore::onBtnDynamicHelp() if (!live_help_floater) { live_help_floater = new LLFloater(LLSD()); - LLUICtrlFactory::getInstance()->buildFloater(live_help_floater, "floater_lsl_guide.xml", NULL); + live_help_floater->buildFromFile("floater_lsl_guide.xml", NULL); LLFloater* parent = dynamic_cast<LLFloater*>(getParent()); llassert(parent); if (parent) @@ -942,7 +962,6 @@ LLPreviewLSL::LLPreviewLSL(const LLSD& key ) mPendingUploads(0) { mFactoryMap["script panel"] = LLCallbackMap(LLPreviewLSL::createScriptEdPanel, this); - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_script_preview.xml", FALSE); } // virtual @@ -1417,7 +1436,6 @@ LLLiveLSLEditor::LLLiveLSLEditor(const LLSD& key) : mIsNew(false) { mFactoryMap["script ed panel"] = LLCallbackMap(LLLiveLSLEditor::createScriptEdPanel, this); - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_live_lsleditor.xml", FALSE); } BOOL LLLiveLSLEditor::postBuild() diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index ef4f0d9c20..f4b31e5962 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -87,6 +87,8 @@ public: static void onBtnInsertSample(void*); static void onBtnInsertFunction(LLUICtrl*, void*); + virtual bool hasAccelerators() const { return true; } + private: void onBtnHelp(); void onBtnDynamicHelp(); diff --git a/indra/newview/llpreviewsound.cpp b/indra/newview/llpreviewsound.cpp index 6b53b45990..33d2d015ad 100644 --- a/indra/newview/llpreviewsound.cpp +++ b/indra/newview/llpreviewsound.cpp @@ -45,7 +45,6 @@ const F32 SOUND_GAIN = 1.0f; LLPreviewSound::LLPreviewSound(const LLSD& key) : LLPreview( key ) { - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_sound.xml", FALSE); } // virtual diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 1155f35de8..fd6b326ef1 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -77,7 +77,6 @@ LLPreviewTexture::LLPreviewTexture(const LLSD& key) { mPreviewToSave = TRUE; } - //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_texture.xml", FALSE); } LLPreviewTexture::~LLPreviewTexture() diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index cde99f8d7c..e9504cbba0 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -41,6 +41,7 @@ #include "llagent.h" #include "llbutton.h" #include "llfocusmgr.h" +#include "llnotifications.h" #include "llprogressbar.h" #include "llstartup.h" #include "llviewercontrol.h" @@ -90,6 +91,8 @@ BOOL LLProgressView::postBuild() // hidden initially, until we need it LLPanel::setVisible(FALSE); + LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLProgressView::onAlertModal, this, _1)); + sInstance = this; return TRUE; } @@ -128,15 +131,10 @@ void LLProgressView::setVisible(BOOL visible) if (getVisible() && !visible) { mFadeTimer.start(); - // hiding progress view, so show menu bars - LLUI::getRootView()->getChildView("menu_bar_holder")->setVisible(TRUE); } // showing progress view else if (!getVisible() && visible) { - // showing progress view, so hide menu bars - LLUI::getRootView()->getChildView("menu_bar_holder")->setVisible(FALSE); - setFocus(TRUE); mFadeTimer.stop(); mProgressTimer.start(); @@ -294,3 +292,18 @@ bool LLProgressView::handleUpdate(const LLSD& event_data) } return false; } + +bool LLProgressView::onAlertModal(const LLSD& notify) +{ + // if the progress view is visible, it will obscure the notification window + // in this case, we want to auto-accept WebLaunchExternalTarget notifications + if (isInVisibleChain() && notify["sigtype"].asString() == "add") + { + LLNotificationPtr notifyp = LLNotifications::instance().find(notify["id"].asUUID()); + if (notifyp && notifyp->getName() == "WebLaunchExternalTarget") + { + notifyp->respondWithDefault(); + } + } + return false; +} diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h index 01d5e16534..be1744f08a 100644 --- a/indra/newview/llprogressview.h +++ b/indra/newview/llprogressview.h @@ -59,6 +59,7 @@ public: static void onCancelButtonClicked( void* ); static void onClickMessage(void*); + bool onAlertModal(const LLSD& sd); protected: LLProgressBar* mProgressBar; diff --git a/indra/newview/llscrollingpanelparam.cpp b/indra/newview/llscrollingpanelparam.cpp index 2d8c9b0fec..05b273cd29 100644 --- a/indra/newview/llscrollingpanelparam.cpp +++ b/indra/newview/llscrollingpanelparam.cpp @@ -56,7 +56,7 @@ LLScrollingPanelParam::LLScrollingPanelParam( const LLPanel::Params& panel_param mAllowModify(allow_modify), mWearable(wearable) { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_scrolling_param.xml"); + buildFromFile( "panel_scrolling_param.xml"); // *HACK To avoid hard coding texture position, lets use border's position for texture. LLViewBorder* left_border = getChild<LLViewBorder>("left_border"); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index fb60b1ece7..da891d1c51 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -181,6 +181,7 @@ template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance(); //----------------------------------------------------------------------------- LLSelectMgr::LLSelectMgr() : mHideSelectedObjects(LLCachedControl<bool>(gSavedSettings, "HideSelectedObjects", FALSE)), + mRenderHighlightSelections(LLCachedControl<bool>(gSavedSettings, "RenderHighlightSelections", TRUE)), mAllowSelectAvatar( LLCachedControl<bool>(gSavedSettings, "AllowSelectAvatar", FALSE)), mDebugSelectMgr(LLCachedControl<bool>(gSavedSettings, "DebugSelectMgr", FALSE)) { @@ -4898,7 +4899,7 @@ void LLSelectMgr::updateSelectionSilhouette(LLObjectSelectionHandle object_handl } void LLSelectMgr::renderSilhouettes(BOOL for_hud) { - if (!mRenderSilhouettes) + if (!mRenderSilhouettes || !mRenderHighlightSelections) { return; } @@ -5058,23 +5059,13 @@ LLSelectNode::LLSelectNode(LLViewerObject* object, BOOL glow) mSilhouetteExists(FALSE), mDuplicated(FALSE), mTESelectMask(0), - mLastTESelected(0) + mLastTESelected(0), + mName(LLStringUtil::null), + mDescription(LLStringUtil::null), + mTouchName(LLStringUtil::null), + mSitName(LLStringUtil::null), + mCreationDate(0) { - mObject = object; - selectAllTEs(FALSE); - mIndividualSelection = FALSE; - mTransient = FALSE; - mValid = FALSE; - mPermissions = new LLPermissions(); - mInventorySerial = 0; - mName = LLStringUtil::null; - mDescription = LLStringUtil::null; - mTouchName = LLStringUtil::null; - mSitName = LLStringUtil::null; - mSilhouetteExists = FALSE; - mDuplicated = FALSE; - mCreationDate = 0; - saveColors(); } diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index e6db264377..7478ed5f9a 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -347,6 +347,7 @@ public: static LLColor4 sContextSilhouetteColor; LLCachedControl<bool> mHideSelectedObjects; + LLCachedControl<bool> mRenderHighlightSelections; LLCachedControl<bool> mAllowSelectAvatar; LLCachedControl<bool> mDebugSelectMgr; diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 7206e4fcaf..a3c6a7b6f1 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -286,6 +286,8 @@ void LLSidepanelAppearance::showOutfitsInventoryPanel() void LLSidepanelAppearance::showOutfitEditPanel() { + if (mOutfitEdit && mOutfitEdit->getVisible()) return; + // Accordion's state must be reset in all cases except the one when user // is returning back to the mOutfitEdit panel from the mEditWearable panel. // The simplest way to control this is to check the visibility state of the mEditWearable diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index b4c1516f71..31ea542743 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -31,6 +31,7 @@ #include "llappearancemgr.h" #include "llavataractions.h" #include "llbutton.h" +#include "llfirstuse.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" #include "llinventorypanel.h" @@ -50,7 +51,7 @@ LLSidepanelInventory::LLSidepanelInventory() mPanelMainInventory(NULL) { - //LLUICtrlFactory::getInstance()->buildPanel(this, "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() + //buildFromFile( "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() } LLSidepanelInventory::~LLSidepanelInventory() @@ -84,7 +85,7 @@ BOOL LLSidepanelInventory::postBuild() mOverflowBtn = mInventoryPanel->getChild<LLButton>("overflow_btn"); mOverflowBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onOverflowButtonClicked, this)); - mPanelMainInventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory"); + mPanelMainInventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); mPanelMainInventory->setSelectCallback(boost::bind(&LLSidepanelInventory::onSelectionChange, this, _1, _2)); LLTabContainer* tabs = mPanelMainInventory->getChild<LLTabContainer>("inventory filter tabs"); tabs->setCommitCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this)); @@ -102,7 +103,7 @@ BOOL LLSidepanelInventory::postBuild() // UI elements from item panel { - mItemPanel = getChild<LLSidepanelItemInfo>("sidepanel__item_panel"); + mItemPanel = findChild<LLSidepanelItemInfo>("sidepanel__item_panel"); LLButton* back_btn = mItemPanel->getChild<LLButton>("back_btn"); back_btn->setClickedCallback(boost::bind(&LLSidepanelInventory::onBackButtonClicked, this)); @@ -110,7 +111,7 @@ BOOL LLSidepanelInventory::postBuild() // UI elements from task panel { - mTaskPanel = getChild<LLSidepanelTaskInfo>("sidepanel__task_panel"); + mTaskPanel = findChild<LLSidepanelTaskInfo>("sidepanel__task_panel"); if (mTaskPanel) { LLButton* back_btn = mTaskPanel->getChild<LLButton>("back_btn"); @@ -123,6 +124,8 @@ BOOL LLSidepanelInventory::postBuild() void LLSidepanelInventory::onOpen(const LLSD& key) { + LLFirstUse::newInventory(false); + if(key.size() == 0) return; @@ -168,7 +171,7 @@ void LLSidepanelInventory::onShopButtonClicked() void LLSidepanelInventory::performActionOnSelection(const std::string &action) { - LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory"); + LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); LLFolderViewItem* current_item = panel_main_inventory->getActivePanel()->getRootFolder()->getCurSelectedItem(); if (!current_item) { @@ -179,8 +182,26 @@ void LLSidepanelInventory::performActionOnSelection(const std::string &action) void LLSidepanelInventory::onWearButtonClicked() { - performActionOnSelection("wear"); - performActionOnSelection("attach"); + LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); + if (!panel_main_inventory) + { + llassert(panel_main_inventory != NULL); + return; + } + + // Get selected items set. + const std::set<LLUUID> selected_uuids_set = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList(); + if (selected_uuids_set.empty()) return; // nothing selected + + // Convert the set to a vector. + uuid_vec_t selected_uuids_vec; + for (std::set<LLUUID>::const_iterator it = selected_uuids_set.begin(); it != selected_uuids_set.end(); ++it) + { + selected_uuids_vec.push_back(*it); + } + + // Wear all selected items. + wear_multiple(selected_uuids_vec, true); } void LLSidepanelInventory::onPlayButtonClicked() @@ -283,7 +304,7 @@ void LLSidepanelInventory::updateVerbs() case LLInventoryType::IT_OBJECT: case LLInventoryType::IT_ATTACHMENT: mWearBtn->setVisible(TRUE); - mWearBtn->setEnabled(get_can_item_be_worn(item->getLinkedUUID())); + mWearBtn->setEnabled(canWearSelected()); mShopBtn->setVisible(FALSE); break; case LLInventoryType::IT_SOUND: @@ -306,25 +327,46 @@ void LLSidepanelInventory::updateVerbs() bool LLSidepanelInventory::canShare() { LLPanelMainInventory* panel_main_inventory = - mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory"); + mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); - LLFolderView* root_folder = - panel_main_inventory->getActivePanel()->getRootFolder(); + if (!panel_main_inventory) + { + llwarns << "Failed to get the main inventory panel" << llendl; + return false; + } - LLFolderViewItem* current_item = root_folder->hasVisibleChildren() - ? root_folder->getCurSelectedItem() - : NULL; + LLInventoryPanel* active_panel = panel_main_inventory->getActivePanel(); + // Avoid flicker in the Recent tab while inventory is being loaded. + if (!active_panel->getRootFolder()->hasVisibleChildren()) return false; - LLInvFVBridge* bridge = current_item - ? dynamic_cast <LLInvFVBridge*> (current_item->getListener()) - : NULL; + return LLAvatarActions::canShareSelectedItems(active_panel); +} + +bool LLSidepanelInventory::canWearSelected() +{ + LLPanelMainInventory* panel_main_inventory = + mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); + + if (!panel_main_inventory) + { + llassert(panel_main_inventory != NULL); + return false; + } + + std::set<LLUUID> selected_uuids = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList(); + for (std::set<LLUUID>::const_iterator it = selected_uuids.begin(); + it != selected_uuids.end(); + ++it) + { + if (!get_can_item_be_worn(*it)) return false; + } - return bridge ? bridge->canShare() : false; + return true; } LLInventoryItem *LLSidepanelInventory::getSelectedItem() { - LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory"); + LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); LLFolderViewItem* current_item = panel_main_inventory->getActivePanel()->getRootFolder()->getCurSelectedItem(); if (!current_item) { @@ -337,7 +379,7 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem() U32 LLSidepanelInventory::getSelectedCount() { - LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory"); + LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); std::set<LLUUID> selection_list = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList(); return selection_list.size(); } diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index 4776dd7530..32c98bc034 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -65,6 +65,8 @@ protected: void performActionOnSelection(const std::string &action); void updateVerbs(); + bool canWearSelected(); // check whether selected items can be worn + // // UI Elements // diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp index 731079fb5d..b053432f9c 100644 --- a/indra/newview/llsidepaneliteminfo.cpp +++ b/indra/newview/llsidepaneliteminfo.cpp @@ -75,7 +75,40 @@ void LLItemPropertiesObserver::changed(U32 mask) } } +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLObjectInventoryObserver +// +// Helper class to watch for changes in an object inventory. +// Used to update item properties in LLSidepanelItemInfo. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLObjectInventoryObserver : public LLVOInventoryListener +{ +public: + LLObjectInventoryObserver(LLSidepanelItemInfo* floater, LLViewerObject* object) + : mFloater(floater) + { + registerVOInventoryListener(object, NULL); + } + virtual ~LLObjectInventoryObserver() + { + removeVOInventoryListener(); + } + /*virtual*/ void inventoryChanged(LLViewerObject* object, + LLInventoryObject::object_list_t* inventory, + S32 serial_num, + void* user_data); +private: + LLSidepanelItemInfo* mFloater; +}; +/*virtual*/ +void LLObjectInventoryObserver::inventoryChanged(LLViewerObject* object, + LLInventoryObject::object_list_t* inventory, + S32 serial_num, + void* user_data) +{ + mFloater->dirty(); +} ///---------------------------------------------------------------------------- /// Class LLSidepanelItemInfo @@ -86,10 +119,9 @@ static LLRegisterPanelClassWrapper<LLSidepanelItemInfo> t_item_info("sidepanel_i // Default constructor LLSidepanelItemInfo::LLSidepanelItemInfo() : mItemID(LLUUID::null) + , mObjectInventoryObserver(NULL) { mPropertiesObserver = new LLItemPropertiesObserver(this); - - //LLUICtrlFactory::getInstance()->buildFloater(this,"floater_inventory_item_properties.xml"); } // Destroys the object @@ -97,6 +129,8 @@ LLSidepanelItemInfo::~LLSidepanelItemInfo() { delete mPropertiesObserver; mPropertiesObserver = NULL; + + stopObjectInventoryObserver(); } // virtual @@ -134,6 +168,10 @@ BOOL LLSidepanelItemInfo::postBuild() void LLSidepanelItemInfo::setObjectID(const LLUUID& object_id) { mObjectID = object_id; + + // Start monitoring changes in the object inventory to update + // selected inventory item properties in Item Profile panel. See STORM-148. + startObjectInventoryObserver(); } void LLSidepanelItemInfo::setItemID(const LLUUID& item_id) @@ -147,6 +185,8 @@ void LLSidepanelItemInfo::reset() mObjectID = LLUUID::null; mItemID = LLUUID::null; + + stopObjectInventoryObserver(); } void LLSidepanelItemInfo::refresh() @@ -600,6 +640,33 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) } } +void LLSidepanelItemInfo::startObjectInventoryObserver() +{ + if (!mObjectInventoryObserver) + { + stopObjectInventoryObserver(); + + // Previous object observer should be removed before starting to observe a new object. + llassert(mObjectInventoryObserver == NULL); + } + + if (mObjectID.isNull()) + { + llwarns << "Empty object id passed to inventory observer" << llendl; + return; + } + + LLViewerObject* object = gObjectList.findObject(mObjectID); + + mObjectInventoryObserver = new LLObjectInventoryObserver(this, object); +} + +void LLSidepanelItemInfo::stopObjectInventoryObserver() +{ + delete mObjectInventoryObserver; + mObjectInventoryObserver = NULL; +} + void LLSidepanelItemInfo::onClickCreator() { LLViewerInventoryItem* item = findItem(); diff --git a/indra/newview/llsidepaneliteminfo.h b/indra/newview/llsidepaneliteminfo.h index 82ebbfa7ec..10e93dd7de 100644 --- a/indra/newview/llsidepaneliteminfo.h +++ b/indra/newview/llsidepaneliteminfo.h @@ -37,6 +37,7 @@ class LLButton; class LLViewerInventoryItem; class LLItemPropertiesObserver; +class LLObjectInventoryObserver; class LLViewerObject; class LLPermissions; @@ -63,9 +64,13 @@ protected: void refreshFromItem(LLViewerInventoryItem* item); private: + void startObjectInventoryObserver(); + void stopObjectInventoryObserver(); + LLUUID mItemID; // inventory UUID for the inventory item. LLUUID mObjectID; // in-world task UUID, or null if in agent inventory. LLItemPropertiesObserver* mPropertiesObserver; // for syncing changes to item + LLObjectInventoryObserver* mObjectInventoryObserver; // for syncing changes to items inside an object // // UI Elements diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 1d32b58948..71f3b0e491 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -32,6 +32,8 @@ #include "llappviewer.h" #include "llbottomtray.h" #include "llfloaterreg.h" +#include "llfirstuse.h" +#include "llhints.h" #include "llsidetray.h" #include "llviewerwindow.h" #include "llaccordionctrl.h" @@ -57,6 +59,8 @@ using namespace LLNotificationsUI; static LLRootViewRegistry::Register<LLSideTray> t1("side_tray"); static LLDefaultChildRegistry::Register<LLSideTrayTab> t2("sidetray_tab"); +static const S32 BOTTOM_BAR_PAD = 5; + static const std::string COLLAPSED_NAME = "<<"; static const std::string EXPANDED_NAME = ">>"; @@ -111,7 +115,7 @@ public: }; protected: LLSideTrayTab(const Params& params); - + void dock(); void undock(LLFloater* floater_tab); @@ -132,7 +136,7 @@ public: const std::string& getTabTitle() const { return mTabTitle;} void onOpen (const LLSD& key); - + void toggleTabDocked(); LLPanel *getPanel(); @@ -314,6 +318,10 @@ void LLSideTrayTab::undock(LLFloater* floater_tab) floater_tab->addChild(this); floater_tab->setTitle(mTabTitle); + floater_tab->setName(getName()); + + // Resize handles get obscured by added panel so move them to front. + floater_tab->moveResizeHandlesToFront(); // Reshape the floater if needed. LLRect floater_rect; @@ -326,13 +334,18 @@ void LLSideTrayTab::undock(LLFloater* floater_tab) { // Detaching for the first time. Reshape the floater. floater_rect = side_tray->getLocalRect(); + + // Reduce detached floater height by small BOTTOM_BAR_PAD not to make it flush with the bottom bar. + floater_rect.mBottom += LLBottomTray::getInstance()->getRect().getHeight() + BOTTOM_BAR_PAD; + floater_rect.makeValid(); floater_tab->reshape(floater_rect.getWidth(), floater_rect.getHeight()); } // Reshape the panel. { - LLRect panel_rect = floater_rect; + LLRect panel_rect = floater_tab->getLocalRect(); panel_rect.mTop -= floater_tab->getHeaderHeight(); + panel_rect.makeValid(); setRect(panel_rect); reshape(panel_rect.getWidth(), panel_rect.getHeight()); } @@ -568,7 +581,8 @@ void LLSideTray::toggleTabButton(LLSideTrayTab* tab) LLButton* btn = it->second; bool new_state = !btn->getToggleState(); btn->setToggleState(new_state); - btn->setImageOverlay( new_state ? tab->mImageSelected : tab->mImage ); + // Only highlight the tab if side tray is expanded (STORM-157). + btn->setImageOverlay( new_state && !getCollapsed() ? tab->mImageSelected : tab->mImage ); } } @@ -644,7 +658,7 @@ bool LLSideTray::selectTabByName(const std::string& name, bool keep_prev_visible { // Keep previously active tab visible if requested. if (keep_prev_visible) tab_to_keep_visible = mActiveTab; - toggleTabButton(mActiveTab); + toggleTabButton(mActiveTab); } //select new tab @@ -652,9 +666,9 @@ bool LLSideTray::selectTabByName(const std::string& name, bool keep_prev_visible if (mActiveTab) { - toggleTabButton(mActiveTab); - LLSD key;//empty - mActiveTab->onOpen(key); + toggleTabButton(mActiveTab); + LLSD key;//empty + mActiveTab->onOpen(key); } //arrange(); @@ -761,8 +775,15 @@ bool LLSideTray::removeTab(LLSideTrayTab* tab) // Deselect the tab. if (mActiveTab == tab) { - child_vector_iter_t next_tab_it = - (tab_it < (mTabs.end() - 1)) ? tab_it + 1 : mTabs.begin(); + // Select the next tab (or first one, if we're removing the last tab), + // skipping the fake open/close tab (STORM-155). + child_vector_iter_t next_tab_it = tab_it; + do + { + next_tab_it = (next_tab_it < (mTabs.end() - 1)) ? next_tab_it + 1 : mTabs.begin(); + } + while ((*next_tab_it)->getName() == "sidebar_openclose"); + selectTabByName((*next_tab_it)->getName(), true); // Don't hide the tab being removed. } @@ -859,6 +880,7 @@ void LLSideTray::createButtons () { mCollapseButton = createButton(name,sidebar_tab->mImage,sidebar_tab->getTabTitle(), boost::bind(&LLSideTray::onToggleCollapse, this)); + LLHints::registerHintTarget("side_panel_btn", mCollapseButton->getHandle()); } else { @@ -867,6 +889,8 @@ void LLSideTray::createButtons () mTabButtons[name] = button; } } + LLHints::registerHintTarget("inventory_btn", mTabButtons["sidebar_inventory"]->getHandle()); + LLHints::registerHintTarget("dest_guide_btn", mTabButtons["sidebar_places"]->getHandle()); } void LLSideTray::processTriState () @@ -905,6 +929,7 @@ void LLSideTray::onTabButtonClick(string name) void LLSideTray::onToggleCollapse() { + LLFirstUse::notUsingSidePanel(false); if(mCollapsed) { expandSideBar(); @@ -998,9 +1023,9 @@ void LLSideTray::detachTabs() std::string floater_ctrl_name = LLFloater::getControlName("side_bar_tab", LLSD(tab->getName())); std::string vis_ctrl_name = LLFloaterReg::getVisibilityControlName(floater_ctrl_name); - if (!LLUI::sSettingGroups["floater"]->controlExists(vis_ctrl_name)) continue; + if (!LLFloater::getControlGroup()->controlExists(vis_ctrl_name)) continue; - bool is_visible = LLUI::sSettingGroups["floater"]->getBOOL(vis_ctrl_name); + bool is_visible = LLFloater::getControlGroup()->getBOOL(vis_ctrl_name); if (!is_visible) continue; llassert(isTabAttached(tab->getName())); @@ -1109,11 +1134,11 @@ LLPanel* LLSideTray::showPanel (const std::string& panel_name, const LLSD& para { LLPanel* panel = openChildPanel(*child_it, panel_name, params); if (panel) return panel; - } + } // Look up the tab in the list of attached tabs. for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it) - { + { LLPanel* panel = openChildPanel(*child_it, panel_name, params); if (panel) return panel; } diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index 4e79007c13..4c23a1920b 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -109,6 +109,22 @@ public: LLPanel* getPanel (const std::string& panel_name); LLPanel* getActivePanel (); bool isPanelActive (const std::string& panel_name); + + /* + * get the panel of given type T (don't show it or do anything else with it) + */ + template <typename T> + T* getPanel(const std::string& panel_name) + { + T* panel = dynamic_cast<T*>(getPanel(panel_name)); + if (!panel) + { + llwarns << "Child named \"" << panel_name << "\" of type " << typeid(T*).name() << " not found" << llendl; + return NULL; + } + return panel; + } + /* * get currently active tab */ diff --git a/indra/newview/llsplitbutton.cpp b/indra/newview/llsplitbutton.cpp index 7db42214e1..790305103d 100644 --- a/indra/newview/llsplitbutton.cpp +++ b/indra/newview/llsplitbutton.cpp @@ -220,7 +220,7 @@ LLSplitButton::LLSplitButton(const LLSplitButton::Params& p) addChild(mItemsPanel); - LLInitParam::ParamIterator<ItemParams>::const_iterator it = p.items().begin(); + LLInitParam::ParamIterator<ItemParams>::const_iterator it = p.items.begin(); //processing shown item button mShownItem = prepareItemButton(*it); @@ -231,7 +231,7 @@ LLSplitButton::LLSplitButton(const LLSplitButton::Params& p) //processing hidden item buttons S32 item_top = mItemsPanel->getRect().getHeight(); - for (++it; it != p.items().end(); ++it) + for (++it; it != p.items.end(); ++it) { LLButton* hidden_button = prepareItemButton(*it); hidden_button->setRect(LLRect(btn_left, item_top, btn_right, item_top - rc.getHeight())); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 975d1f9f32..c56cacd12b 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -794,10 +794,6 @@ bool idle_startup() if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState()) { - // Move the progress view in front of the UI immediately when login is performed - // this allows not to see main menu after Alt+Tab was pressed while login. EXT-744. - gViewerWindow->moveProgressViewToFront(); - //reset the values that could have come in from a slurl // DEV-42215: Make sure they're not empty -- gUserCredential // might already have been set from gSavedSettings, and it's too bad @@ -1251,9 +1247,6 @@ bool idle_startup() if (!gNoRender) { - // Move the progress view in front of the UI - gViewerWindow->moveProgressViewToFront(); - // direct logging to the debug console's line buffer LLError::logToFixedBuffer(gDebugView->mDebugConsolep); diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index b622e98971..e9fc25404a 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -33,6 +33,7 @@ #include "llagentcamera.h" #include "llbutton.h" #include "llcommandhandler.h" +#include "llfirstuse.h" #include "llviewercontrol.h" #include "llfloaterbuycurrency.h" #include "llbuycurrencyhtml.h" @@ -41,6 +42,7 @@ #include "llpanelvolumepulldown.h" #include "llfloaterregioninfo.h" #include "llfloaterscriptdebug.h" +#include "llhints.h" #include "llhudicon.h" #include "llnavigationbar.h" #include "llkeyboard.h" @@ -107,10 +109,6 @@ const S32 TEXT_HEIGHT = 18; static void onClickVolume(void*); -std::vector<std::string> LLStatusBar::sDays; -std::vector<std::string> LLStatusBar::sMonths; -const U32 LLStatusBar::MAX_DATE_STRING_LENGTH = 2000; - LLStatusBar::LLStatusBar(const LLRect& rect) : LLPanel(), mTextTime(NULL), @@ -127,14 +125,10 @@ LLStatusBar::LLStatusBar(const LLRect& rect) // status bar can possible overlay menus? setMouseOpaque(FALSE); - // size of day of the weeks and year - sDays.reserve(7); - sMonths.reserve(12); - mBalanceTimer = new LLFrameTimer(); mHealthTimer = new LLFrameTimer(); - LLUICtrlFactory::getInstance()->buildPanel(this,"panel_status_bar.xml"); + buildFromFile("panel_status_bar.xml"); } LLStatusBar::~LLStatusBar() @@ -169,9 +163,6 @@ BOOL LLStatusBar::postBuild() { gMenuBarView->setRightMouseDownCallback(boost::bind(&show_navbar_context_menu, _1, _2, _3)); - // build date necessary data (must do after panel built) - setupDate(); - mTextTime = getChild<LLTextBox>("TimeText" ); getChild<LLUICtrl>("buyL")->setCommitCallback( @@ -185,6 +176,8 @@ BOOL LLStatusBar::postBuild() mMediaToggle->setClickedCallback( &LLStatusBar::onClickMediaToggle, this ); mMediaToggle->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterNearbyMedia, this)); + LLHints::registerHintTarget("linden_balance", getChild<LLView>("balance_bg")->getHandle()); + gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&LLStatusBar::onVolumeChanged, this, _2)); // Adding Net Stat Graph @@ -224,8 +217,6 @@ BOOL LLStatusBar::postBuild() mSGPacketLoss->mPerSec = FALSE; addChild(mSGPacketLoss); - getChild<LLTextBox>("stat_btn")->setClickedCallback(onClickStatGraph); - mPanelVolumePulldown = new LLPanelVolumePulldown(); addChild(mPanelVolumePulldown); mPanelVolumePulldown->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT); @@ -332,6 +323,11 @@ void LLStatusBar::creditBalance(S32 credit) void LLStatusBar::setBalance(S32 balance) { + if (balance > getBalance() && getBalance() != 0) + { + LLFirstUse::receiveLindens(); + } + std::string money_str = LLResMgr::getInstance()->getMonetaryString( balance ); LLTextBox* balance_box = getChild<LLTextBox>("balance"); @@ -454,6 +450,7 @@ void LLStatusBar::onClickBuyCurrency() // open a currency floater - actual one open depends on // value specified in settings.xml LLBuyCurrencyHTML::openCurrencyFloater(); + LLFirstUse::receiveLindens(false); } void LLStatusBar::onMouseEnterVolume() @@ -517,75 +514,6 @@ void LLStatusBar::onClickMediaToggle(void* data) LLViewerMedia::setAllMediaEnabled(enable); } -// sets the static variables necessary for the date -void LLStatusBar::setupDate() -{ - // fill the day array with what's in the xui - std::string day_list = getString("StatBarDaysOfWeek"); - size_t length = day_list.size(); - - // quick input check - if(length < MAX_DATE_STRING_LENGTH) - { - // tokenize it and put it in the array - std::string cur_word; - for(size_t i = 0; i < length; ++i) - { - if(day_list[i] == ':') - { - sDays.push_back(cur_word); - cur_word.clear(); - } - else - { - cur_word.append(1, day_list[i]); - } - } - sDays.push_back(cur_word); - } - - // fill the day array with what's in the xui - std::string month_list = getString( "StatBarMonthsOfYear" ); - length = month_list.size(); - - // quick input check - if(length < MAX_DATE_STRING_LENGTH) - { - // tokenize it and put it in the array - std::string cur_word; - for(size_t i = 0; i < length; ++i) - { - if(month_list[i] == ':') - { - sMonths.push_back(cur_word); - cur_word.clear(); - } - else - { - cur_word.append(1, month_list[i]); - } - } - sMonths.push_back(cur_word); - } - - // make sure we have at least 7 days and 12 months - if(sDays.size() < 7) - { - sDays.resize(7); - } - - if(sMonths.size() < 12) - { - sMonths.resize(12); - } -} - -// static -void LLStatusBar::onClickStatGraph(void* data) -{ - LLFloaterReg::showInstance("lagmeter"); -} - BOOL can_afford_transaction(S32 cost) { return((cost <= 0)||((gStatusBar) && (gStatusBar->getBalance() >=cost))); diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h index c8c86dfd8c..2388aeb0c8 100644 --- a/indra/newview/llstatusbar.h +++ b/indra/newview/llstatusbar.h @@ -85,16 +85,13 @@ public: LLPanelNearByMedia* getNearbyMediaPanel() { return mPanelNearByMedia; } private: - // simple method to setup the part that holds the date - void setupDate(); - + void onClickBuyCurrency(); void onVolumeChanged(const LLSD& newvalue); void onMouseEnterVolume(); void onMouseEnterNearbyMedia(); void onClickScreen(S32 x, S32 y); - static void onClickStatGraph(void* data); static void onClickMediaToggle(void* data); @@ -117,9 +114,6 @@ private: LLFrameTimer* mHealthTimer; LLPanelVolumePulldown* mPanelVolumePulldown; LLPanelNearByMedia* mPanelNearByMedia; - static std::vector<std::string> sDays; - static std::vector<std::string> sMonths; - static const U32 MAX_DATE_STRING_LENGTH; }; // *HACK: Status bar owns your cached money balance. JC diff --git a/indra/newview/llsyswellitem.cpp b/indra/newview/llsyswellitem.cpp index 4a107fefa8..057d80457c 100644 --- a/indra/newview/llsyswellitem.cpp +++ b/indra/newview/llsyswellitem.cpp @@ -38,7 +38,7 @@ LLSysWellItem::LLSysWellItem(const Params& p) : LLPanel(p), mTitle(NULL), mCloseBtn(NULL) { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_sys_well_item.xml"); + buildFromFile( "panel_sys_well_item.xml"); mTitle = getChild<LLTextBox>("title"); mCloseBtn = getChild<LLButton>("close_btn"); diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 750fbe54a7..99342bb564 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -249,7 +249,7 @@ LLIMWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId) : LLPanel(LLPanel::Params()), mChiclet(NULL), mParent(parent) { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_activeim_row.xml", NULL); + buildFromFile( "panel_activeim_row.xml", NULL); // Choose which of the pre-created chiclets (IM/group) to use. // The other one gets hidden. @@ -346,7 +346,7 @@ LLIMWellWindow::ObjectRowPanel::ObjectRowPanel(const LLUUID& notification_id, bo : LLPanel() , mChiclet(NULL) { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_active_object_row.xml", NULL); + buildFromFile( "panel_active_object_row.xml", NULL); initChiclet(notification_id); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 1625b4bafd..328298bda4 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -196,8 +196,8 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( mContextConeOpacity(0.f), mSelectedItemPinned( FALSE ) { + buildFromFile("floater_texture_ctrl.xml"); mCanApplyImmediately = can_apply_immediately; - LLUICtrlFactory::getInstance()->buildFloater(this,"floater_texture_ctrl.xml",NULL); setCanMinimize(FALSE); } diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 4e9ebce4d1..fafef84aa2 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -847,10 +847,16 @@ bool LLTextureFetchWorker::doWork(S32 param) if(mCanUseHTTP) { //NOTE: - //it seems ok to let sim control the UDP traffic - //so there is no throttle for http here. + //control the number of the http requests issued for: + //1, not openning too many file descriptors at the same time; + //2, control the traffic of http so udp gets bandwidth. // - + static const S32 MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE = 32 ; + if(mFetcher->getNumHTTPRequests() > MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE) + { + return false ; //wait. + } + mFetcher->removeFromNetworkQueue(this, false); S32 cur_size = 0; diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 749cf2c948..a9ab98da5f 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -77,7 +77,7 @@ LLToast::LLToast(const LLToast::Params& p) { mTimer.reset(new LLToastLifeTimer(this, p.lifetime_secs)); - LLUICtrlFactory::getInstance()->buildFloater(this, "panel_toast.xml", NULL); + buildFromFile("panel_toast.xml", NULL); setCanDrag(FALSE); diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h index b22f3b9d09..0a96c092a0 100644 --- a/indra/newview/lltoast.h +++ b/indra/newview/lltoast.h @@ -188,6 +188,8 @@ public: virtual S32 notifyParent(const LLSD& info); + LLHandle<LLToast> getHandle() { mHandle.bind(this); return mHandle; } + private: void onToastMouseEnter(); @@ -200,6 +202,8 @@ private: LLUUID mSessionID; LLNotificationPtr mNotification; + LLRootHandle<LLToast> mHandle; + LLPanel* mWrapperPanel; // timer counts a lifetime of a toast diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp index 4c75b07ae8..78cc96b353 100644 --- a/indra/newview/lltoastgroupnotifypanel.cpp +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -54,7 +54,7 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification : LLToastPanel(notification), mInventoryOffer(NULL) { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_group_notify.xml"); + buildFromFile( "panel_group_notify.xml"); const LLSD& payload = notification->getPayload(); LLGroupData groupData; if (!gAgent.getGroupData(payload["group_id"].asUUID(),groupData)) diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp index 82ccca4330..1d8b82ec1b 100644 --- a/indra/newview/lltoastimpanel.cpp +++ b/indra/newview/lltoastimpanel.cpp @@ -45,7 +45,7 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif mAvatarIcon(NULL), mAvatarName(NULL), mTime(NULL), mMessage(NULL), mGroupIcon(NULL) { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_instant_message.xml"); + buildFromFile( "panel_instant_message.xml"); mGroupIcon = getChild<LLGroupIconCtrl>("group_icon"); mAvatarIcon = getChild<LLAvatarIconCtrl>("avatar_icon"); diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index ca6efa9d2f..9017f5ec55 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -51,7 +51,7 @@ const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL; LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal; -LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification, const LLRect& rect) : +LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification, const LLRect& rect, bool show_images) : LLToastPanel(notification), mTextBox(NULL), mInfoPanel(NULL), @@ -61,7 +61,7 @@ mNumButtons(0), mAddedDefaultBtn(false), mCloseNotificationOnDestroy(true) { - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_notification.xml"); + buildFromFile( "panel_notification.xml"); if(rect != LLRect::null) { this->setShape(rect); @@ -120,6 +120,7 @@ mCloseNotificationOnDestroy(true) mTextBox->setMaxTextLength(MAX_LENGTH); mTextBox->setVisible(TRUE); + mTextBox->setPlainText(!show_images); mTextBox->setValue(notification->getMessage()); // add buttons for a script notification @@ -523,8 +524,9 @@ void LLToastNotifyPanel::disableRespondedOptions(LLNotificationPtr& notification ////////////////////////////////////////////////////////////////////////// -LLIMToastNotifyPanel::LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect /* = LLRect::null */) - : mSessionID(session_id), LLToastNotifyPanel(pNotification, rect) +LLIMToastNotifyPanel::LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect /* = LLRect::null */, + bool show_images /* = true */) + : mSessionID(session_id), LLToastNotifyPanel(pNotification, rect, show_images) { mTextBox->setFollowsAll(); } diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h index 9e1eac90b3..57711b3d80 100644 --- a/indra/newview/lltoastnotifypanel.h +++ b/indra/newview/lltoastnotifypanel.h @@ -60,7 +60,7 @@ public: * @deprecated if you intend to instantiate LLToastNotifyPanel - it's point to * implement right class for desired toast panel. @see LLGenericTipPanel as example. */ - LLToastNotifyPanel(LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null); + LLToastNotifyPanel(LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true); virtual ~LLToastNotifyPanel(); LLPanel * getControlPanel() { return mControlPanel; } @@ -137,7 +137,7 @@ class LLIMToastNotifyPanel : public LLToastNotifyPanel { public: - LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect = LLRect::null); + LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect = LLRect::null, bool show_images = true); ~LLIMToastNotifyPanel(); diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 54484a1dbb..6bb95168e2 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1445,6 +1445,43 @@ static void give_inventory_cb(const LLSD& notification, const LLSD& response) } } +static void show_item_sharing_confirmation(const std::string name, + LLViewerInventoryItem* inv_item, + const LLSD& dest, + const LLUUID& dest_agent, + const LLUUID& session_id = LLUUID::null) +{ + if (!inv_item) + { + llassert(NULL != inv_item); + return; + } + + LLSD substitutions; + substitutions["RESIDENTS"] = name; + substitutions["ITEMS"] = inv_item->getName(); + LLSD payload; + payload["agent_id"] = dest_agent; + payload["item_id"] = inv_item->getUUID(); + payload["session_id"] = session_id; + payload["d&d_dest"] = dest.asString(); + LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, payload, &give_inventory_cb); +} + +static void get_name_cb(const LLUUID& id, + const std::string& first_name, + const std::string& last_name, + LLViewerInventoryItem* inv_item, + const LLSD& dest, + const LLUUID& dest_agent) +{ + show_item_sharing_confirmation(first_name + " " + last_name, + inv_item, + dest, + id, + LLUUID::null); +} + // function used as drag-and-drop handler for simple agent give inventory requests //static bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_id, BOOL drop, @@ -1477,20 +1514,28 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ if (drop) { LLIMModel::LLIMSession * session = LLIMModel::instance().findIMSession(session_id); + + // If no IM session found get the destination agent's name by id. if (NULL == session) { - llassert(NULL != session); - return false; + std::string fullname; + + // If destination agent's name is found in cash proceed to showing the confirmation dialog. + // Otherwise set up a callback to show the dialog when the name arrives. + if (gCacheName->getFullName(dest_agent, fullname)) + { + show_item_sharing_confirmation(fullname, inv_item, dest, dest_agent, LLUUID::null); + } + else + { + gCacheName->get(dest_agent, FALSE, boost::bind(&get_name_cb, _1, _2, _3, inv_item, dest, dest_agent)); + } + + return true; } - LLSD substitutions; - substitutions["RESIDENTS"] = session->mName; - substitutions["ITEMS"] = inv_item->getName(); - LLSD payload; - payload["agent_id"] = dest_agent; - payload["item_id"] = inv_item->getUUID(); - payload["session_id"] = session_id; - payload["d&d_dest"] = dest.asString(); - LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, payload, &give_inventory_cb); + + // If an IM session with destination agent is found item offer will be logged in this session. + show_item_sharing_confirmation(session->mName, inv_item, dest, dest_agent, session_id); } } else diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index d8be70e546..864de018e0 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -619,6 +619,25 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask) return TRUE; } } + else if (gSavedSettings.getBOOL("DoubleClickTeleport")) + { + LLViewerObject* objp = mPick.getObject(); + LLViewerObject* parentp = objp ? objp->getRootEdit() : NULL; + + bool is_in_world = mPick.mObjectID.notNull() && objp && !objp->isHUDAttachment(); + bool is_land = mPick.mPickType == LLPickInfo::PICK_LAND; + bool pos_non_zero = !mPick.mPosGlobal.isExactlyZero(); + bool has_touch_handler = (objp && objp->flagHandleTouch()) || (parentp && parentp->flagHandleTouch()); + bool has_click_action = final_click_action(objp); + + if (pos_non_zero && (is_land || (is_in_world && !has_touch_handler && !has_click_action))) + { + LLVector3d pos = mPick.mPosGlobal; + pos.mdV[VZ] += gAgentAvatarp->getPelvisToFoot(); + gAgent.teleportViaLocationLookAt(pos); + return TRUE; + } + } return FALSE; } diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index 750bb224b1..b19c738ed2 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -114,10 +114,6 @@ void audio_update_volume(bool force_update) gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler")); gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff")); -#ifdef kAUDIO_ENABLE_WIND - gAudiop->enableWind(!mute_audio); -#endif - gAudiop->setMuted(mute_audio); if (force_update) diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index d0ad918c58..916cbe2267 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -85,6 +85,7 @@ LLPointer<LLViewerTexture> gDisconnectedImagep = NULL; // used to toggle renderer back on after teleport const F32 TELEPORT_RENDER_DELAY = 20.f; // Max time a teleport is allowed to take before we raise the curtain const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived. +const F32 TELEPORT_LOCAL_DELAY = 1.0f; // Delay to prevent teleports after starting an in-sim teleport. BOOL gTeleportDisplay = FALSE; LLFrameTimer gTeleportDisplayTimer; LLFrameTimer gTeleportArrivalTimer; @@ -406,6 +407,18 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) } break; + case LLAgent::TELEPORT_LOCAL: + // Short delay when teleporting in the same sim (progress screen active but not shown - did not + // fall-through from TELEPORT_START) + { + if( gTeleportDisplayTimer.getElapsedTimeF32() > TELEPORT_LOCAL_DELAY ) + { + //LLFirstUse::useTeleport(); + gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); + } + } + break; + case LLAgent::TELEPORT_NONE: // No teleport in progress gViewerWindow->setShowProgress(FALSE); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 606956024f..cd4e099c60 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -96,7 +96,6 @@ #include "llfloatertos.h" #include "llfloatertopobjects.h" #include "llfloateruipreview.h" -#include "llfloatervoicedevicesettings.h" #include "llfloatervoiceeffect.h" #include "llfloaterwater.h" #include "llfloaterwhitelistentry.h" @@ -203,7 +202,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("prefs_hardware_settings", "floater_hardware_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHardwareSettings>); LLFloaterReg::add("perm_prefs", "floater_perm_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPerms>); LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>); - LLFloaterReg::add("pref_voicedevicesettings", "floater_device_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceDeviceSettings>); LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview"); LLFloaterReg::add("preview_gesture", "floater_preview_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewGesture>, "preview"); LLFloaterReg::add("preview_notecard", "floater_preview_notecard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewNotecard>, "preview"); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 283669aaef..48ab122edf 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -51,6 +51,7 @@ #include "llvoavatarself.h" #include "llviewerregion.h" #include "llwebsharing.h" // For LLWebSharing::setOpenIDCookie(), *TODO: find a better way to do this! +#include "llfilepicker.h" #include "llevent.h" // LLSimpleListener #include "llnotificationsutil.h" @@ -60,6 +61,8 @@ //#include "llfirstuse.h" #include "llwindow.h" +#include "llfloatermediabrowser.h" // for handling window close requests and geometry change requests in media browser windows. + #include <boost/bind.hpp> // for SkinFolder listener #include <boost/signals2.hpp> @@ -1365,6 +1368,38 @@ void LLViewerMedia::openIDCookieResponse(const std::string &cookie) setOpenIDCookie(); } +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::proxyWindowOpened(const std::string &target, const std::string &uuid) +{ + if(uuid.empty()) + return; + + for (impl_list::iterator iter = sViewerMediaImplList.begin(); iter != sViewerMediaImplList.end(); iter++) + { + if((*iter)->mMediaSource && (*iter)->mMediaSource->pluginSupportsMediaBrowser()) + { + (*iter)->mMediaSource->proxyWindowOpened(target, uuid); + } + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::proxyWindowClosed(const std::string &uuid) +{ + if(uuid.empty()) + return; + + for (impl_list::iterator iter = sViewerMediaImplList.begin(); iter != sViewerMediaImplList.end(); iter++) + { + if((*iter)->mMediaSource && (*iter)->mMediaSource->pluginSupportsMediaBrowser()) + { + (*iter)->mMediaSource->proxyWindowClosed(uuid); + } + } +} + bool LLViewerMedia::hasInWorldMedia() { if (sInWorldMediaDisabled) return false; @@ -1598,7 +1633,7 @@ void LLViewerMediaImpl::setMediaType(const std::string& media_type) ////////////////////////////////////////////////////////////////////////////////////////// /*static*/ -LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height) +LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, const std::string target) { std::string plugin_basename = LLMIMETypes::implType(media_type); @@ -1654,7 +1689,9 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ // collect 'javascript enabled' setting from prefs and send to embedded browser bool javascript_enabled = gSavedSettings.getBOOL( "BrowserJavascriptEnabled" ); media_source->setJavascriptEnabled( javascript_enabled ); - + + media_source->setTarget(target); + if (media_source->init(launcher_name, plugin_name, gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins"))) { return media_source; @@ -1705,7 +1742,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type) // Save the MIME type that really caused the plugin to load mCurrentMimeType = mMimeType; - LLPluginClassMedia* media_source = newSourceFromMediaType(mMimeType, this, mMediaWidth, mMediaHeight); + LLPluginClassMedia* media_source = newSourceFromMediaType(mMimeType, this, mMediaWidth, mMediaHeight, mTarget); if (media_source) { @@ -2805,6 +2842,7 @@ bool LLViewerMediaImpl::isPlayable() const ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent event) { + bool pass_through = true; switch(event) { case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: @@ -2818,28 +2856,6 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla case MEDIA_EVENT_CLICK_LINK_HREF: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << plugin->getClickTarget() << "\", uri is " << plugin->getClickURL() << LL_ENDL; - // retrieve the event parameters - std::string url = plugin->getClickURL(); - U32 target_type = plugin->getClickTargetType(); - - switch (target_type) - { - case LLPluginClassMedia::TARGET_EXTERNAL: - // force url to external browser - LLWeb::loadURLExternal(url); - break; - case LLPluginClassMedia::TARGET_BLANK: - // open in SL media browser or external browser based on user pref - LLWeb::loadURL(url); - break; - case LLPluginClassMedia::TARGET_NONE: - // ignore this click and let media plugin handle it - break; - case LLPluginClassMedia::TARGET_OTHER: - LL_WARNS("LinkTarget") << "Unsupported link target type" << LL_ENDL; - break; - default: break; - } }; break; case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: @@ -2971,13 +2987,70 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla } break; + case LLViewerMediaObserver::MEDIA_EVENT_PICK_FILE_REQUEST: + { + // Display a file picker + std::string response; + + LLFilePicker& picker = LLFilePicker::instance(); + if (!picker.getOpenFile(LLFilePicker::FFLOAD_ALL)) + { + // The user didn't pick a file -- the empty response string will indicate this. + } + + response = picker.getFirstFile(); + + plugin->sendPickFileResponse(response); + } + break; + case LLViewerMediaObserver::MEDIA_EVENT_CLOSE_REQUEST: + { + std::string uuid = plugin->getClickUUID(); + + llinfos << "MEDIA_EVENT_CLOSE_REQUEST for uuid " << uuid << llendl; + + if(uuid.empty()) + { + // This close request is directed at this instance, let it fall through. + } + else + { + // This close request is directed at another instance + pass_through = false; + LLFloaterMediaBrowser::closeRequest(uuid); + } + } + break; + + case LLViewerMediaObserver::MEDIA_EVENT_GEOMETRY_CHANGE: + { + std::string uuid = plugin->getClickUUID(); + + llinfos << "MEDIA_EVENT_GEOMETRY_CHANGE for uuid " << uuid << llendl; + + if(uuid.empty()) + { + // This geometry change request is directed at this instance, let it fall through. + } + else + { + // This request is directed at another instance + pass_through = false; + LLFloaterMediaBrowser::geometryChanged(uuid, plugin->getGeometryX(), plugin->getGeometryY(), plugin->getGeometryWidth(), plugin->getGeometryHeight()); + } + } + break; + default: break; } - // Just chain the event to observers. - emitEvent(plugin, event); + if(pass_through) + { + // Just chain the event to observers. + emitEvent(plugin, event); + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index e0cc26fa29..4025a4484f 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -152,6 +152,9 @@ public: static void openIDSetup(const std::string &openid_url, const std::string &openid_token); static void openIDCookieResponse(const std::string &cookie); + static void proxyWindowOpened(const std::string &target, const std::string &uuid); + static void proxyWindowClosed(const std::string &uuid); + private: static void setOpenIDCookie(); static void onTeleportFinished(); @@ -271,8 +274,10 @@ public: ECursorType getLastSetCursor() { return mLastSetCursor; } + void setTarget(const std::string& target) { mTarget = target; } + // utility function to create a ready-to-use media instance from a desired media type. - static LLPluginClassMedia* newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height); + static LLPluginClassMedia* newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, const std::string target = LLStringUtil::null); // Internally set our desired browser user agent string, including // the Second Life version and skin name. Used because we can @@ -438,6 +443,7 @@ private: bool mNavigateSuspended; bool mNavigateSuspendedDeferred; bool mTrustedBrowser; + std::string mTarget; private: BOOL mIsUpdated ; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 261aa20f30..9521157ca6 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -62,6 +62,7 @@ #include "lllandmarkactions.h" #include "llgroupmgr.h" #include "lltooltip.h" +#include "llhints.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" #include "llimview.h" @@ -6573,6 +6574,16 @@ class LLToggleControl : public view_listener_t std::string control_name = userdata.asString(); BOOL checked = gSavedSettings.getBOOL( control_name ); gSavedSettings.setBOOL( control_name, !checked ); + + // Doubleclick actions - there can be only one + if ((control_name == "DoubleClickAutoPilot") && !checked) + { + gSavedSettings.setBOOL( "DoubleClickTeleport", FALSE ); + } + else if ((control_name == "DoubleClickTeleport") && !checked) + { + gSavedSettings.setBOOL( "DoubleClickAutoPilot", FALSE ); + } return true; } }; @@ -7262,7 +7273,7 @@ void handle_load_from_xml(void*) { std::string filename = picker.getFirstFile(); LLFloater* floater = new LLFloater(LLSD()); - LLUICtrlFactory::getInstance()->buildFloater(floater, filename, NULL); + floater->buildFromFile(filename); } } @@ -7740,6 +7751,18 @@ public: } }; +class LLToggleUIHints : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + bool ui_hints_enabled = gSavedSettings.getBOOL("EnableUIHints"); + // toggle + ui_hints_enabled = !ui_hints_enabled; + gSavedSettings.setBOOL("EnableUIHints", ui_hints_enabled); + return true; + } +}; + void LLUploadCostCalculator::calculateCost() { S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); @@ -8220,4 +8243,5 @@ void initialize_menus() view_listener_t::addMenu(new LLEditableSelected(), "EditableSelected"); view_listener_t::addMenu(new LLEditableSelectedMono(), "EditableSelectedMono"); + view_listener_t::addMenu(new LLToggleUIHints(), "ToggleUIHints"); } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 6d0cbbf8f2..26b7e0fb6d 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -50,6 +50,7 @@ #include "llagentcamera.h" #include "llcallingcard.h" #include "llbuycurrencyhtml.h" +#include "llfirstuse.h" #include "llfloaterbuyland.h" #include "llfloaterland.h" #include "llfloaterregioninfo.h" @@ -82,6 +83,7 @@ #include "lluri.h" #include "llviewergenericmessage.h" #include "llviewermenu.h" +#include "llviewerjoystick.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" #include "llviewerstats.h" @@ -931,6 +933,15 @@ protected: //one global instance to bind them LLOpenTaskOffer* gNewInventoryObserver=NULL; +class LLNewInventoryHintObserver : public LLInventoryAddedObserver +{ +protected: + /*virtual*/ void done() + { + LLFirstUse::newInventory(); + } +}; + void start_new_inventory_observer() { if (!gNewInventoryObserver) //task offer observer @@ -946,6 +957,8 @@ void start_new_inventory_observer() gInventoryMoveObserver = new LLViewerInventoryMoveFromWorldObserver; gInventory.addObserver(gInventoryMoveObserver); } + + gInventory.addObserver(new LLNewInventoryHintObserver()); } class LLDiscardAgentOffer : public LLInventoryFetchItemsObserver @@ -1872,6 +1885,8 @@ void inventory_offer_handler(LLOfferInfo* info) LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, false); } } + + LLFirstUse::newInventory(); } bool lure_callback(const LLSD& notification, const LLSD& response) @@ -3189,6 +3204,8 @@ void process_teleport_start(LLMessageSystem *msg, void**) U32 teleport_flags = 0x0; msg->getU32("Info", "TeleportFlags", teleport_flags); + LL_DEBUGS("Messaging") << "Got TeleportStart with TeleportFlags=" << teleport_flags << ". gTeleportDisplay: " << gTeleportDisplay << ", gAgent.mTeleportState: " << gAgent.getTeleportState() << LL_ENDL; + if (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL) { gViewerWindow->setProgressCancelButtonVisible(FALSE); @@ -3207,6 +3224,7 @@ void process_teleport_start(LLMessageSystem *msg, void**) gAgent.setTeleportState( LLAgent::TELEPORT_START ); make_ui_sound("UISndTeleportOut"); + LL_INFOS("Messaging") << "Teleport initiated by remote TeleportStart message with TeleportFlags: " << teleport_flags << LL_ENDL; // Don't call LLFirstUse::useTeleport here because this could be // due to being killed, which would send you home, not to a Telehub } @@ -3548,6 +3566,12 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) if( is_teleport ) { + if (gAgent.getTeleportKeepsLookAt()) + { + // *NOTE: the LookAt data we get from the sim here doesn't + // seem to be useful, so get it from the camera instead + look_at = LLViewerCamera::getInstance()->getAtAxis(); + } // Force the camera back onto the agent, don't animate. gAgentCamera.setFocusOnAvatar(TRUE, FALSE); gAgentCamera.slamLookAt(look_at); @@ -3594,7 +3618,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) { LLTracker::stopTracking(NULL); } - else if ( is_teleport ) + else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() ) { //look at the beacon LLVector3 global_agent_pos = agent_pos; @@ -4203,14 +4227,12 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data) // Don't play sounds from a region with maturity above current agent maturity LLVector3d pos_global = objectp->getPositionGlobal(); - if( !gAgent.canAccessMaturityAtGlobal( pos_global ) ) + if (gAgent.canAccessMaturityAtGlobal(pos_global)) { - return; - } - // Add audioData starts a transfer internally. sourcep->addAudioData(datap, FALSE); } +} void process_attached_sound(LLMessageSystem *msg, void **user_data) { @@ -5866,7 +5888,18 @@ void process_teleport_local(LLMessageSystem *msg,void**) if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE ) { - gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); + if( gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL ) + { + // To prevent TeleportStart messages re-activating the progress screen right + // after tp, keep the teleport state and let progress screen clear it after a short delay + // (progress screen is active but not visible) *TODO: remove when SVC-5290 is fixed + gTeleportDisplayTimer.reset(); + gTeleportDisplay = TRUE; + } + else + { + gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); + } } // Sim tells us whether the new position is off the ground @@ -5882,8 +5915,10 @@ void process_teleport_local(LLMessageSystem *msg,void**) gAgent.setPositionAgent(pos); gAgentCamera.slamLookAt(look_at); - // likewise make sure the camera is behind the avatar - gAgentCamera.resetView(TRUE, TRUE); + if ( !(gAgent.getTeleportKeepsLookAt() && LLViewerJoystick::getInstance()->getOverrideCamera()) ) + { + gAgentCamera.resetView(TRUE, TRUE); + } // send camera update to new region gAgentCamera.updateCamera(); @@ -6418,7 +6453,7 @@ void process_covenant_reply(LLMessageSystem* msg, void**) LLPanelLandCovenant::updateEstateOwnerName(owner_name); LLFloaterBuyLand::updateEstateOwnerName(owner_name); - LLPanelPlaceProfile* panel = LLSideTray::getInstance()->findChild<LLPanelPlaceProfile>("panel_place_profile"); + LLPanelPlaceProfile* panel = LLSideTray::getInstance()->getPanel<LLPanelPlaceProfile>("panel_place_profile"); if (panel) { panel->updateEstateName(estate_name); @@ -6552,7 +6587,7 @@ void onCovenantLoadComplete(LLVFS *vfs, LLPanelLandCovenant::updateCovenantText(covenant_text); LLFloaterBuyLand::updateCovenantText(covenant_text, asset_uuid); - LLPanelPlaceProfile* panel = LLSideTray::getInstance()->findChild<LLPanelPlaceProfile>("panel_place_profile"); + LLPanelPlaceProfile* panel = LLSideTray::getInstance()->getPanel<LLPanelPlaceProfile>("panel_place_profile"); if (panel) { panel->updateCovenantText(covenant_text); diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index 7f7c245717..b91e407c6d 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -304,7 +304,12 @@ void LLGridManager::initialize(const std::string& grid_file) addGrid(grid); } - gSavedSettings.getControl("CurrentGrid")->getSignal()->connect(boost::bind(&LLGridManager::updateIsInProductionGrid, this)); + LLControlVariablePtr grid_control = gSavedSettings.getControl("CurrentGrid"); + if (grid_control.notNull()) + { + grid_control->getSignal()->connect(boost::bind(&LLGridManager::updateIsInProductionGrid, this)); + } + // since above only triggers on changes, trigger the callback manually to initialize state updateIsInProductionGrid(); @@ -499,7 +504,8 @@ void LLGridManager::setGridChoice(const std::string& grid) addGrid(grid_data); } mGrid = grid; - gSavedSettings.setString("CurrentGrid", grid); + gSavedSettings.setString("CurrentGrid", grid); + updateIsInProductionGrid(); } std::string LLGridManager::getGridByLabel( const std::string &grid_label, bool case_sensitive) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 25cc24da95..fd3e80d755 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1844,7 +1844,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, if (cdp) { F32 ping_delay = 0.5f * mTimeDilation * ( ((F32)cdp->getPingDelay()) * 0.001f + gFrameDTClamped); - LLVector3 diff = getVelocity() * (0.5f*mTimeDilation*(gFrameDTClamped + ((F32)ping_delay)*0.001f)); + LLVector3 diff = getVelocity() * ping_delay; new_pos_parent += diff; } else @@ -4445,6 +4445,13 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow mAudioSourcep = NULL; } + if (mAudioSourcep && mAudioSourcep->isMuted() && + mAudioSourcep->getCurrentData() && mAudioSourcep->getCurrentData()->getID() == audio_uuid) + { + //llinfos << "Already having this sound as muted sound, ignoring" << llendl; + return; + } + getAudioSource(owner_id); if (mAudioSourcep) diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index e9a4c4dd0a..99e869dafc 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -568,6 +568,24 @@ void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAME_CHANGED" << LL_ENDL; }; break; + + case MEDIA_EVENT_CLOSE_REQUEST: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLOSE_REQUEST" << LL_ENDL; + } + break; + + case MEDIA_EVENT_PICK_FILE_REQUEST: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << LL_ENDL; + } + break; + + case MEDIA_EVENT_GEOMETRY_CHANGE: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL; + } + break; }; } diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 0ad54f238e..5c262838ae 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1820,7 +1820,7 @@ bool LLViewerFetchedTexture::updateFetch() S32 current_discard = getCurrentDiscardLevelForFetching() ; S32 desired_discard = getDesiredDiscardLevel(); F32 decode_priority = getDecodePriority(); - decode_priority = llmax(decode_priority, 0.0f); + decode_priority = llclamp(decode_priority, 0.0f, maxDecodePriority()); if (mIsFetching) { diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 456516ab6b..bbf7c8e60e 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1544,7 +1544,8 @@ bool LLUIImageList::initFromFile() } UIImageDeclarations images; - LLXUIParser::instance().readXUI(root, images, base_file_path); + LLXUIParser parser; + parser.readXUI(root, images, base_file_path); if (!images.validateBlock()) return false; @@ -1557,8 +1558,8 @@ bool LLUIImageList::initFromFile() for (S32 cur_pass = PASS_DECODE_NOW; cur_pass < NUM_PASSES; cur_pass++) { - for (LLInitParam::ParamIterator<UIImageDeclaration>::const_iterator image_it = images.textures().begin(); - image_it != images.textures().end(); + for (LLInitParam::ParamIterator<UIImageDeclaration>::const_iterator image_it = images.textures.begin(); + image_it != images.textures.end(); ++image_it) { std::string file_name = image_it->file_name.isProvided() ? image_it->file_name() : image_it->name(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 43d18c6d83..983a2d25c8 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -96,6 +96,7 @@ #include "llface.h" #include "llfeaturemanager.h" #include "llfilepicker.h" +#include "llfirstuse.h" #include "llfloater.h" #include "llfloaterbuildoptions.h" #include "llfloaterbuyland.h" @@ -1515,7 +1516,7 @@ void LLViewerWindow::initBase() // (But wait to add it as a child of the root view so that it will be in front of the // other views.) MainPanel* main_view = new MainPanel(); - LLUICtrlFactory::instance().buildPanel(main_view, "main_view.xml"); + main_view->buildFromFile("main_view.xml"); main_view->setShape(full_window); getRootView()->addChild(main_view); @@ -1523,7 +1524,8 @@ void LLViewerWindow::initBase() mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle(); mNonSideTrayView = main_view->getChildView("non_side_tray_view")->getHandle(); mFloaterViewHolder = main_view->getChildView("floater_view_holder")->getHandle(); - mPopupView = main_view->getChild<LLPopupView>("popup_holder"); + mPopupView = main_view->findChild<LLPopupView>("popup_holder"); + mHintHolder = main_view->getChild<LLView>("hint_holder")->getHandle(); // Constrain floaters to inside the menu and status bar regions. gFloaterView = main_view->getChild<LLFloaterView>("Floater View"); @@ -1561,7 +1563,7 @@ void LLViewerWindow::initBase() LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initBusyResponse)); // Add the progress bar view (startup view), which overrides everything - mProgressView = getRootView()->getChild<LLProgressView>("progress_view"); + mProgressView = getRootView()->findChild<LLProgressView>("progress_view"); setShowProgress(FALSE); setProgressCancelButtonVisible(FALSE); @@ -2134,10 +2136,20 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) return TRUE; } + LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); + // give menus a chance to handle modified (Ctrl, Alt) shortcut keys before current focus // as long as focus isn't locked if (mask & (MASK_CONTROL | MASK_ALT) && !gFocusMgr.focusLocked()) { + // Check the current floater's menu first, if it has one. + if (gFocusMgr.keyboardFocusHasAccelerators() + && keyboard_focus + && keyboard_focus->handleKey(key,mask,FALSE)) + { + return TRUE; + } + if ((gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask)) ||(gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask))) { @@ -2173,7 +2185,6 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) } // Traverses up the hierarchy - LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); if( keyboard_focus ) { LLLineEditor* chat_editor = LLBottomTray::instanceExists() ? LLBottomTray::getInstance()->getNearbyChatBar()->getChatBox() : NULL; @@ -2391,7 +2402,7 @@ void append_xui_tooltip(LLView* viewp, LLToolTip::Params& params) { if (viewp) { - if (!params.styled_message().empty()) + if (!params.styled_message.empty()) { params.styled_message.add().text("\n---------\n"); } @@ -2426,6 +2437,18 @@ void LLViewerWindow::updateUI() static std::string last_handle_msg; + if (gLoggedInTime.getStarted()) + { + if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("DestinationGuideHintTimeout")) + { + LLFirstUse::notUsingDestinationGuide(); + } + if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("SidePanelHintTimeout")) + { + LLFirstUse::notUsingSidePanel(); + } + } + LLConsole::updateClass(); // animate layout stacks so we have up to date rect for world view @@ -2486,6 +2509,17 @@ void LLViewerWindow::updateUI() // only update mouse hover set when UI is visible (since we shouldn't send hover events to invisible UI if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { + // include all ancestors of captor_view as automatically having mouse + if (captor_view) + { + LLView* captor_parent_view = captor_view->getParent(); + while(captor_parent_view) + { + mouse_hover_set.insert(captor_parent_view->getHandle()); + captor_parent_view = captor_parent_view->getParent(); + } + } + // aggregate visible views that contain mouse cursor in display order LLPopupView::popup_list_t popups = mPopupView->getCurrentPopups(); @@ -3913,7 +3947,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei } if(image_buffer_x > 0 && image_buffer_y > 0) { - raw->resize(image_buffer_x, image_buffer_y, 3); + raw->resize(image_buffer_x, image_buffer_y, 3); } else { @@ -4247,14 +4281,6 @@ BOOL LLViewerWindow::getShowProgress() const return (mProgressView && mProgressView->getVisible()); } -void LLViewerWindow::moveProgressViewToFront() -{ - if( mProgressView && mRootView ) - { - mRootView->sendChildToFront(mProgressView); - } -} - void LLViewerWindow::setProgressString(const std::string& string) { if (mProgressView) diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 21507699b0..633c3a41d2 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -271,7 +271,6 @@ public: void setShowProgress(const BOOL show); BOOL getShowProgress() const; - void moveProgressViewToFront(); void setProgressString(const std::string& string); void setProgressPercent(const F32 percent); void setProgressMessage(const std::string& msg); @@ -288,6 +287,7 @@ public: void updateWorldViewRect(bool use_full_window=false); LLView* getNonSideTrayView() { return mNonSideTrayView.get(); } LLView* getFloaterViewHolder() { return mFloaterViewHolder.get(); } + LLView* getHintHolder() { return mHintHolder.get(); } BOOL handleKey(KEY key, MASK mask); void handleScrollWheel (S32 clicks); @@ -447,6 +447,7 @@ protected: LLHandle<LLView> mWorldViewPlaceholder; // widget that spans the portion of screen dedicated to rendering the 3d world LLHandle<LLView> mNonSideTrayView; // parent of world view + bottom bar, etc...everything but the side tray LLHandle<LLView> mFloaterViewHolder; // container for floater_view + LLHandle<LLView> mHintHolder; // container for hints LLPopupView* mPopupView; // container for transient popups class LLDebugText* mDebugText; // Internal class for debug text diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index cab6fbdc93..c31714de5a 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -176,7 +176,7 @@ const F32 TIME_BEFORE_MESH_CLEANUP = 5.f; // seconds const S32 AVATAR_RELEASE_THRESHOLD = 10; // number of avatar instances before releasing memory const F32 FOOT_GROUND_COLLISION_TOLERANCE = 0.25f; const F32 AVATAR_LOD_TWEAK_RANGE = 0.7f; -const S32 MAX_BUBBLE_CHAT_LENGTH = 1023; +const S32 MAX_BUBBLE_CHAT_LENGTH = DB_CHAT_MSG_STR_LEN; const S32 MAX_BUBBLE_CHAT_UTTERANCES = 12; const F32 CHAT_FADE_TIME = 8.0; const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f; @@ -6089,9 +6089,9 @@ void LLVOAvatar::updateMeshTextures() // use the last-known good baked texture until it finish the first // render of the new layerset. - const BOOL layerset_invalid = !mBakedTextureDatas[i].mTexLayerSet - || !mBakedTextureDatas[i].mTexLayerSet->getComposite()->isInitialized() - || !mBakedTextureDatas[i].mTexLayerSet->isLocalTextureDataAvailable(); + const BOOL layerset_invalid = mBakedTextureDatas[i].mTexLayerSet + && ( !mBakedTextureDatas[i].mTexLayerSet->getComposite()->isInitialized() + || !mBakedTextureDatas[i].mTexLayerSet->isLocalTextureDataAvailable() ); use_lkg_baked_layer[i] = (!is_layer_baked[i] && (mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR) diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index ec5c95469e..e5cbf65682 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -43,7 +43,6 @@ #include "llhudeffecttrail.h" #include "llhudmanager.h" #include "llinventoryfunctions.h" -#include "llmenugl.h" #include "llnotificationsutil.h" #include "llselectmgr.h" #include "lltoolgrab.h" // for needsRenderBeam @@ -241,58 +240,58 @@ BOOL LLVOAvatarSelf::buildMenus() gAttachBodyPartPieMenus[0] = NULL; LLContextMenu::Params params; - params.label(LLTrans::getString("BodyPartsRightArm") + " " + LLMenuGL::BRANCH_SUFFIX); + params.label(LLTrans::getString("BodyPartsRightArm")); params.name(params.label); params.visible(false); gAttachBodyPartPieMenus[1] = LLUICtrlFactory::create<LLContextMenu> (params); - params.label(LLTrans::getString("BodyPartsHead") + " " + LLMenuGL::BRANCH_SUFFIX); + params.label(LLTrans::getString("BodyPartsHead")); params.name(params.label); gAttachBodyPartPieMenus[2] = LLUICtrlFactory::create<LLContextMenu> (params); - params.label(LLTrans::getString("BodyPartsLeftArm") + " " + LLMenuGL::BRANCH_SUFFIX); + params.label(LLTrans::getString("BodyPartsLeftArm")); params.name(params.label); gAttachBodyPartPieMenus[3] = LLUICtrlFactory::create<LLContextMenu> (params); gAttachBodyPartPieMenus[4] = NULL; - params.label(LLTrans::getString("BodyPartsLeftLeg") + " " + LLMenuGL::BRANCH_SUFFIX); + params.label(LLTrans::getString("BodyPartsLeftLeg")); params.name(params.label); gAttachBodyPartPieMenus[5] = LLUICtrlFactory::create<LLContextMenu> (params); - params.label(LLTrans::getString("BodyPartsTorso") + " " + LLMenuGL::BRANCH_SUFFIX); + params.label(LLTrans::getString("BodyPartsTorso")); params.name(params.label); gAttachBodyPartPieMenus[6] = LLUICtrlFactory::create<LLContextMenu> (params); - params.label(LLTrans::getString("BodyPartsRightLeg") + " " + LLMenuGL::BRANCH_SUFFIX); + params.label(LLTrans::getString("BodyPartsRightLeg")); params.name(params.label); gAttachBodyPartPieMenus[7] = LLUICtrlFactory::create<LLContextMenu> (params); gDetachBodyPartPieMenus[0] = NULL; - params.label(LLTrans::getString("BodyPartsRightArm") + " " + LLMenuGL::BRANCH_SUFFIX); + params.label(LLTrans::getString("BodyPartsRightArm")); params.name(params.label); gDetachBodyPartPieMenus[1] = LLUICtrlFactory::create<LLContextMenu> (params); - params.label(LLTrans::getString("BodyPartsHead") + " " + LLMenuGL::BRANCH_SUFFIX); + params.label(LLTrans::getString("BodyPartsHead")); params.name(params.label); gDetachBodyPartPieMenus[2] = LLUICtrlFactory::create<LLContextMenu> (params); - params.label(LLTrans::getString("BodyPartsLeftArm") + " " + LLMenuGL::BRANCH_SUFFIX); + params.label(LLTrans::getString("BodyPartsLeftArm")); params.name(params.label); gDetachBodyPartPieMenus[3] = LLUICtrlFactory::create<LLContextMenu> (params); gDetachBodyPartPieMenus[4] = NULL; - params.label(LLTrans::getString("BodyPartsLeftLeg") + " " + LLMenuGL::BRANCH_SUFFIX); + params.label(LLTrans::getString("BodyPartsLeftLeg")); params.name(params.label); gDetachBodyPartPieMenus[5] = LLUICtrlFactory::create<LLContextMenu> (params); - params.label(LLTrans::getString("BodyPartsTorso") + " " + LLMenuGL::BRANCH_SUFFIX); + params.label(LLTrans::getString("BodyPartsTorso")); params.name(params.label); gDetachBodyPartPieMenus[6] = LLUICtrlFactory::create<LLContextMenu> (params); - params.label(LLTrans::getString("BodyPartsRightLeg") + " " + LLMenuGL::BRANCH_SUFFIX); + params.label(LLTrans::getString("BodyPartsRightLeg")); params.name(params.label); gDetachBodyPartPieMenus[7] = LLUICtrlFactory::create<LLContextMenu> (params); diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 0b903e62b1..8bdb8e069e 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -44,25 +44,27 @@ BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes) //--------------------------------------------------------------------------- LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp) + : + mLocalID(local_id), + mCRC(crc), + mHitCount(0), + mDupeCount(0), + mCRCChangeCount(0) { - mLocalID = local_id; - mCRC = crc; - mHitCount = 0; - mDupeCount = 0; - mCRCChangeCount = 0; mBuffer = new U8[dp.getBufferSize()]; mDP.assignBuffer(mBuffer, dp.getBufferSize()); mDP = dp; } LLVOCacheEntry::LLVOCacheEntry() + : + mLocalID(0), + mCRC(0), + mHitCount(0), + mDupeCount(0), + mCRCChangeCount(0), + mBuffer(NULL) { - mLocalID = 0; - mCRC = 0; - mHitCount = 0; - mDupeCount = 0; - mCRCChangeCount = 0; - mBuffer = NULL; mDP.assignBuffer(mBuffer, 0); } @@ -73,7 +75,7 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) success = check_read(apr_file, &mLocalID, sizeof(U32)); if(success) -{ + { success = check_read(apr_file, &mCRC, sizeof(U32)); } if(success) @@ -83,27 +85,24 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) if(success) { success = check_read(apr_file, &mDupeCount, sizeof(S32)); -} + } if(success) -{ + { success = check_read(apr_file, &mCRCChangeCount, sizeof(S32)); } if(success) { success = check_read(apr_file, &size, sizeof(S32)); - // Corruption in the cache entries - if ((size > 10000) || (size < 1)) - { - // We've got a bogus size, skip reading it. - // We won't bother seeking, because the rest of this file - // is likely bogus, and will be tossed anyway. - llwarns << "Bogus cache entry, size " << size << ", aborting!" << llendl; - mLocalID = 0; - mCRC = 0; - mBuffer = NULL; - return; - } + // Corruption in the cache entries + if ((size > 10000) || (size < 1)) + { + // We've got a bogus size, skip reading it. + // We won't bother seeking, because the rest of this file + // is likely bogus, and will be tossed anyway. + llwarns << "Bogus cache entry, size " << size << ", aborting!" << llendl; + success = FALSE; + } } if(success && size > 0) { @@ -112,8 +111,8 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) if(success) { - mDP.assignBuffer(mBuffer, size); -} + mDP.assignBuffer(mBuffer, size); + } else { delete[] mBuffer ; @@ -125,6 +124,9 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) { mLocalID = 0; mCRC = 0; + mHitCount = 0; + mDupeCount = 0; + mCRCChangeCount = 0; mBuffer = NULL; } } @@ -257,7 +259,8 @@ void LLVOCache::destroyClass() LLVOCache::LLVOCache(): mInitialized(FALSE), mReadOnly(TRUE), - mNumEntries(0) + mNumEntries(0), + mCacheSize(1) { mLocalAPRFilePoolp = new LLVolatileAPRPool() ; } @@ -289,8 +292,8 @@ void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version) { LLFile::mkdir(mObjectCacheDirName); } - mCacheSize = llmin(size, MAX_NUM_OBJECT_ENTRIES) ; - mCacheSize = llmax(mCacheSize, NUM_ENTRIES_TO_PURGE); + mCacheSize = llclamp(size, + MAX_NUM_OBJECT_ENTRIES, NUM_ENTRIES_TO_PURGE); mMetaInfo.mVersion = cache_version; readCacheHeader(); diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index 9e3d61ae44..b692093fb9 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -497,14 +497,28 @@ void LLVoiceChannelGroup::activate() mURI, mCredentials); -#if 0 // *TODO if (!gAgent.isInGroup(mSessionID)) // ad-hoc channel { - // Add the party to the list of people with which we've recently interacted. - for (/*people in the chat*/) - LLRecentPeople::instance().add(buddy_id); + LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionID); + // Adding ad-hoc call participants to Recent People List. + // If it's an outgoing ad-hoc, we can use mInitialTargetIDs that holds IDs of people we + // called(both online and offline) as source to get people for recent (STORM-210). + if (session->isOutgoingAdHoc()) + { + for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin(); + it!=session->mInitialTargetIDs.end();++it) + { + const LLUUID id = *it; + LLRecentPeople::instance().add(id); + } + } + // If this ad-hoc is incoming then trying to get ids of people from mInitialTargetIDs + // would lead to EXT-8246. So in this case we get them from speakers list. + else + { + LLIMModel::addSpeakersToRecent(mSessionID); + } } -#endif //Mic default state is OFF on initiating/joining Ad-Hoc/Group calls if (LLVoiceClient::getInstance()->getUserPTTState() && LLVoiceClient::getInstance()->getPTTIsToggle()) diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 2e003dd2b8..e674fec053 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -386,7 +386,7 @@ LLVivoxVoiceClient::~LLVivoxVoiceClient() { } -//---------------------------------------------- +//--------------------------------------------------- void LLVivoxVoiceClient::init(LLPumpIO *pump) { @@ -400,7 +400,8 @@ void LLVivoxVoiceClient::terminate() { logout(); connectorShutdown(); - closeSocket(); // Need to do this now -- bad things happen if the destructor does it later. + closeSocket(); // Need to do this now -- bad things happen if the destructor does it later. + cleanUp(); } else { @@ -408,6 +409,18 @@ void LLVivoxVoiceClient::terminate() } } +//--------------------------------------------------- + +void LLVivoxVoiceClient::cleanUp() +{ + deleteAllSessions(); + deleteAllBuddies(); + deleteAllVoiceFonts(); + deleteVoiceFontTemplates(); +} + +//--------------------------------------------------- + const LLVoiceVersionInfo& LLVivoxVoiceClient::getVersion() { return mVoiceVersion; @@ -776,14 +789,10 @@ void LLVivoxVoiceClient::stateMachine() { //MARK: stateDisableCleanup case stateDisableCleanup: - // Clean up and reset everything. + // Clean up and reset everything. closeSocket(); - deleteAllSessions(); - deleteAllBuddies(); - deleteAllVoiceFonts(); - deleteVoiceFontTemplates(); + cleanUp(); - mConnectorHandle.clear(); mAccountHandle.clear(); mAccountPassword.clear(); mVoiceAccountServerURI.clear(); @@ -1675,12 +1684,9 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateLoggedOut case stateLoggedOut: // logout response received - // Once we're logged out, all these things are invalid. + // Once we're logged out, these things are invalid. mAccountHandle.clear(); - deleteAllSessions(); - deleteAllBuddies(); - deleteAllVoiceFonts(); - deleteVoiceFontTemplates(); + cleanUp(); if(mVoiceEnabled && !mRelogRequested) { @@ -1778,6 +1784,8 @@ void LLVivoxVoiceClient::closeSocket(void) { mSocket.reset(); mConnected = false; + mConnectorHandle.clear(); + mAccountHandle.clear(); } void LLVivoxVoiceClient::loginSendMessage() @@ -2370,8 +2378,7 @@ void LLVivoxVoiceClient::giveUp() { // All has failed. Clean up and stop trying. closeSocket(); - deleteAllSessions(); - deleteAllBuddies(); + cleanUp(); setState(stateJail); } diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index d10a562616..08f2f75a39 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -668,7 +668,10 @@ protected: private: LLVoiceVersionInfo mVoiceVersion; - + + /// Clean up objects created during a voice session. + void cleanUp(); + state mState; bool mSessionTerminateRequested; bool mRelogRequested; diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index 0ac6b9117b..6b3e7873a1 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -139,10 +139,10 @@ protected: ~LLSkyTex(); - static S32 getResolution() { return sResolution; } + static S32 getResolution() { return sResolution; } static S32 getCurrent() { return sCurrent; } - static S32 stepCurrent() { return (sCurrent = (sCurrent + 1) % 2); } - static S32 getNext() { return ((sCurrent+1) % 2); } + static S32 stepCurrent() { sCurrent++; sCurrent &= 1; return sCurrent; } + static S32 getNext() { return ((sCurrent+1) & 1); } static S32 getWhich(const BOOL curr) { return curr ? sCurrent : getNext(); } void initEmpty(const S32 tex); diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index 54accfe4ee..73a37a6993 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -78,36 +78,44 @@ void LLWeb::initClass() // static -void LLWeb::loadURL(const std::string& url) +void LLWeb::loadURL(const std::string& url, const std::string& target, const std::string& uuid) { - if (gSavedSettings.getBOOL("UseExternalBrowser")) + if(target == "_internal") + { + // Force load in the internal browser, as if with a blank target. + loadURLInternal(url, "", uuid); + } + else if (gSavedSettings.getBOOL("UseExternalBrowser") || (target == "_external")) { loadURLExternal(url); } else { - loadURLInternal(url); + loadURLInternal(url, target, uuid); } } // static -void LLWeb::loadURLInternal(const std::string &url) +void LLWeb::loadURLInternal(const std::string &url, const std::string& target, const std::string& uuid) { - LLFloaterReg::showInstance("media_browser", url); + LLFloaterMediaBrowser::create(url, target, uuid); } // static -void LLWeb::loadURLExternal(const std::string& url) +void LLWeb::loadURLExternal(const std::string& url, const std::string& uuid) { - loadURLExternal(url, true); + loadURLExternal(url, true, uuid); } // static -void LLWeb::loadURLExternal(const std::string& url, bool async) +void LLWeb::loadURLExternal(const std::string& url, bool async, const std::string& uuid) { + // Act like the proxy window was closed, since we won't be able to track targeted windows in the external browser. + LLViewerMedia::proxyWindowClosed(uuid); + LLSD payload; payload["url"] = url; LLNotificationsUtil::add( "WebLaunchExternalTarget", LLSD(), payload, boost::bind(on_load_url_external_response, _1, _2, async)); diff --git a/indra/newview/llweb.h b/indra/newview/llweb.h index 1ba856babe..2915376583 100644 --- a/indra/newview/llweb.h +++ b/indra/newview/llweb.h @@ -43,15 +43,19 @@ public: static void initClass(); /// Load the given url in the user's preferred web browser - static void loadURL(const std::string& url); + static void loadURL(const std::string& url, const std::string& target, const std::string& uuid = LLStringUtil::null); + static void loadURL(const std::string& url) { loadURL(url, LLStringUtil::null); } /// Load the given url in the user's preferred web browser - static void loadURL(const char* url) { loadURL( ll_safe_string(url) ); } + static void loadURL(const char* url, const std::string& target) { loadURL( ll_safe_string(url), target); } + static void loadURL(const char* url) { loadURL( ll_safe_string(url), LLStringUtil::null ); } /// Load the given url in the Second Life internal web browser - static void loadURLInternal(const std::string &url); + static void loadURLInternal(const std::string &url, const std::string& target, const std::string& uuid = LLStringUtil::null); + static void loadURLInternal(const std::string &url) { loadURLInternal(url, LLStringUtil::null); } /// Load the given url in the operating system's web browser, async if we want to return immediately /// before browser has spawned - static void loadURLExternal(const std::string& url); - static void loadURLExternal(const std::string& url, bool async); + static void loadURLExternal(const std::string& url) { loadURLExternal(url, LLStringUtil::null); }; + static void loadURLExternal(const std::string& url, const std::string& uuid); + static void loadURLExternal(const std::string& url, bool async, const std::string& uuid = LLStringUtil::null); /// Returns escaped url (eg, " " to "%20") - used by all loadURL methods static std::string escapeURL(const std::string& url); diff --git a/indra/newview/llwebsharing.cpp b/indra/newview/llwebsharing.cpp index 2b9e5cc8cb..43b1a320c3 100644 --- a/indra/newview/llwebsharing.cpp +++ b/indra/newview/llwebsharing.cpp @@ -3,31 +3,25 @@ * @author Aimee * @brief Web Snapshot Sharing * - * $LicenseInfo:firstyear=2010&license=viewergpl$ - * - * Copyright (c) 2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/newview/llwebsharing.h b/indra/newview/llwebsharing.h index 70046ff1d8..ad9c99c224 100644 --- a/indra/newview/llwebsharing.h +++ b/indra/newview/llwebsharing.h @@ -3,31 +3,25 @@ * @author Aimee * @brief Web Snapshot Sharing * - * $LicenseInfo:firstyear=2010&license=viewergpl$ - * - * Copyright (c) 2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 1ee3b84b5e..e69b0a2996 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4814,7 +4814,7 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color) void LLPipeline::disableLights() { enableLights(0); // no lighting (full bright) - //glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default + glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default } //============================================================================ diff --git a/indra/newview/skins/default/textures/ff_edit_mine.tga b/indra/newview/skins/default/textures/ff_edit_mine.tga Binary files differdeleted file mode 100644 index 8f0c35b98f..0000000000 --- a/indra/newview/skins/default/textures/ff_edit_mine.tga +++ /dev/null diff --git a/indra/newview/skins/default/textures/ff_edit_mine_button.tga b/indra/newview/skins/default/textures/ff_edit_mine_button.tga Binary files differdeleted file mode 100644 index 07627a65c5..0000000000 --- a/indra/newview/skins/default/textures/ff_edit_mine_button.tga +++ /dev/null diff --git a/indra/newview/skins/default/textures/ff_edit_theirs.tga b/indra/newview/skins/default/textures/ff_edit_theirs.tga Binary files differdeleted file mode 100644 index 005ada2dea..0000000000 --- a/indra/newview/skins/default/textures/ff_edit_theirs.tga +++ /dev/null diff --git a/indra/newview/skins/default/textures/ff_edit_theirs_button.tga b/indra/newview/skins/default/textures/ff_edit_theirs_button.tga Binary files differdeleted file mode 100644 index 798ef641d3..0000000000 --- a/indra/newview/skins/default/textures/ff_edit_theirs_button.tga +++ /dev/null diff --git a/indra/newview/skins/default/textures/ff_online_status_button.tga b/indra/newview/skins/default/textures/ff_online_status_button.tga Binary files differdeleted file mode 100644 index 9076df6b9e..0000000000 --- a/indra/newview/skins/default/textures/ff_online_status_button.tga +++ /dev/null diff --git a/indra/newview/skins/default/textures/ff_visible_map.tga b/indra/newview/skins/default/textures/ff_visible_map.tga Binary files differdeleted file mode 100644 index a4dad78dad..0000000000 --- a/indra/newview/skins/default/textures/ff_visible_map.tga +++ /dev/null diff --git a/indra/newview/skins/default/textures/ff_visible_map_button.tga b/indra/newview/skins/default/textures/ff_visible_map_button.tga Binary files differdeleted file mode 100644 index 8d13adee3f..0000000000 --- a/indra/newview/skins/default/textures/ff_visible_map_button.tga +++ /dev/null diff --git a/indra/newview/skins/default/textures/ff_visible_online.tga b/indra/newview/skins/default/textures/ff_visible_online.tga Binary files differdeleted file mode 100644 index 74e3a4e318..0000000000 --- a/indra/newview/skins/default/textures/ff_visible_online.tga +++ /dev/null diff --git a/indra/newview/skins/default/textures/ff_visible_online_button.tga b/indra/newview/skins/default/textures/ff_visible_online_button.tga Binary files differdeleted file mode 100644 index 08a6cbedd9..0000000000 --- a/indra/newview/skins/default/textures/ff_visible_online_button.tga +++ /dev/null diff --git a/indra/newview/skins/default/textures/icons/edit_mine.png b/indra/newview/skins/default/textures/icons/edit_mine.png Binary files differnew file mode 100644 index 0000000000..a0bc7efd25 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/edit_mine.png diff --git a/indra/newview/skins/default/textures/icons/edit_theirs.png b/indra/newview/skins/default/textures/icons/edit_theirs.png Binary files differnew file mode 100644 index 0000000000..ed36ad7cfc --- /dev/null +++ b/indra/newview/skins/default/textures/icons/edit_theirs.png diff --git a/indra/newview/skins/default/textures/icons/pop_up_caution.png b/indra/newview/skins/default/textures/icons/pop_up_caution.png Binary files differnew file mode 100644 index 0000000000..78b681cb33 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/pop_up_caution.png diff --git a/indra/newview/skins/default/textures/icons/see_me_online.png b/indra/newview/skins/default/textures/icons/see_me_online.png Binary files differnew file mode 100644 index 0000000000..52dc2ae74f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/see_me_online.png diff --git a/indra/newview/skins/default/textures/icons/see_on_map.png b/indra/newview/skins/default/textures/icons/see_on_map.png Binary files differnew file mode 100644 index 0000000000..200e649818 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/see_on_map.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 273531f9b2..925e2b5b04 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -360,10 +360,10 @@ with the same filename but different name <texture name="Pause_Over" file_name="icons/Pause_Over.png" preload="false" /> <texture name="Pause_Press" file_name="icons/Pause_Press.png" preload="false" /> - <texture name="Permission_Visible_Online" file_name="ff_visible_online_button.tga" preload="false" /> - <texture name="Permission_Visible_Map" file_name="ff_visible_map_button.tga" preload="false" /> - <texture name="Permission_Edit_Objects_Mine" file_name="ff_edit_mine_button.tga" preload="false" /> - <texture name="Permission_Edit_Objects_Theirs" file_name="ff_edit_theirs_button.tga" preload="false" /> + <texture name="Permission_Visible_Online" file_name="icons/see_me_online.png" preload="false" /> + <texture name="Permission_Visible_Map" file_name="icons/see_on_map.png" preload="false" /> + <texture name="Permission_Edit_Objects_Mine" file_name="icons/edit_mine.png" preload="false" /> + <texture name="Permission_Edit_Objects_Theirs" file_name="icons/edit_theirs.png" preload="false" /> <texture name="Play_Off" file_name="icons/Play_Off.png" preload="false" /> <texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" /> @@ -658,4 +658,13 @@ with the same filename but different name <texture name="buy_over" file_name="widgets/buy_over.png" preload="true" scale.left="2" scale.top="15" scale.right="67" scale.bottom="4"/> <texture name="buy_press" file_name="widgets/buy_press.png" preload="true" scale.left="2" scale.top="15" scale.right="67" scale.bottom="4"/> + <texture name="hint_background" file_name="windows/hint_background.png" preload="false" scale.left="8" scale.top="70" scale.right="195" scale.bottom="11"/> + <texture name="hint_arrow_left" file_name="windows/hint_arrow_left.png" preload="false"/> + <texture name="hint_arrow_right" file_name="windows/hint_arrow_right.png" preload="false"/> + <texture name="hint_arrow_up" file_name="windows/hint_arrow_up.png" preload="false"/> + <texture name="hint_arrow_down" file_name="windows/hint_arrow_down.png" preload="false"/> + <texture name="hint_arrow_lower_left" file_name="windows/hint_arrow_lower_left.png" preload="false"/> + + <texture name="Yellow_Gradient" file_name="windows/yellow_gradient.png"/> + <texture name="Popup_Caution" file_name="icons/pop_up_caution.png"/> </textures> diff --git a/indra/newview/skins/default/textures/windows/hint_arrow_down.png b/indra/newview/skins/default/textures/windows/hint_arrow_down.png Binary files differnew file mode 100644 index 0000000000..ddadef0978 --- /dev/null +++ b/indra/newview/skins/default/textures/windows/hint_arrow_down.png diff --git a/indra/newview/skins/default/textures/windows/hint_arrow_left.png b/indra/newview/skins/default/textures/windows/hint_arrow_left.png Binary files differnew file mode 100644 index 0000000000..2794b967e8 --- /dev/null +++ b/indra/newview/skins/default/textures/windows/hint_arrow_left.png diff --git a/indra/newview/skins/default/textures/windows/hint_arrow_lower_left.png b/indra/newview/skins/default/textures/windows/hint_arrow_lower_left.png Binary files differnew file mode 100644 index 0000000000..0dfc99898d --- /dev/null +++ b/indra/newview/skins/default/textures/windows/hint_arrow_lower_left.png diff --git a/indra/newview/skins/default/textures/windows/hint_arrow_right.png b/indra/newview/skins/default/textures/windows/hint_arrow_right.png Binary files differnew file mode 100644 index 0000000000..7ac57f805b --- /dev/null +++ b/indra/newview/skins/default/textures/windows/hint_arrow_right.png diff --git a/indra/newview/skins/default/textures/windows/hint_arrow_up.png b/indra/newview/skins/default/textures/windows/hint_arrow_up.png Binary files differnew file mode 100644 index 0000000000..bb3e1c07fa --- /dev/null +++ b/indra/newview/skins/default/textures/windows/hint_arrow_up.png diff --git a/indra/newview/skins/default/textures/windows/hint_background.png b/indra/newview/skins/default/textures/windows/hint_background.png Binary files differnew file mode 100644 index 0000000000..cfac5deacb --- /dev/null +++ b/indra/newview/skins/default/textures/windows/hint_background.png diff --git a/indra/newview/skins/default/textures/windows/yellow_gradient.png b/indra/newview/skins/default/textures/windows/yellow_gradient.png Binary files differnew file mode 100644 index 0000000000..5fd847aaef --- /dev/null +++ b/indra/newview/skins/default/textures/windows/yellow_gradient.png diff --git a/indra/newview/skins/default/xui/da/floater_customize.xml b/indra/newview/skins/default/xui/da/floater_customize.xml deleted file mode 100644 index a47e0d33df..0000000000 --- a/indra/newview/skins/default/xui/da/floater_customize.xml +++ /dev/null @@ -1,530 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater customize" title="UDSEENDE"> - <tab_container name="customize tab container"> - <text label="Krops Dele" name="body_parts_placeholder"> - Kropsdele - </text> - <panel label="Kropsbygning" name="Shape"> - <button label="Annullér" label_selected="Annullér" name="Revert"/> - <button label="Krop" label_selected="Krop" name="Body"/> - <button label="Hoved" label_selected="Hoved" name="Head"/> - <button label="Øjne" label_selected="Øjne" name="Eyes"/> - <button label="Ører" label_selected="Ører" name="Ears"/> - <button label="Næse" label_selected="Næse" name="Nose"/> - <button label="Mund" label_selected="Mund" name="Mouth"/> - <button label="Kinder" label_selected="Kinder" name="Chin"/> - <button label="Overkrop" label_selected="Overkrop" name="Torso"/> - <button label="Ben" label_selected="Ben" name="Legs"/> - <radio_group name="sex radio"> - <radio_item label="Kvinde" name="radio" value="0"/> - <radio_item label="Mand" name="radio2" value="1"/> - </radio_group> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: Kan ikke redigeres - </text> - <text name="title_loading"> - [DESC]: indlæser... - </text> - <text name="title_not_worn"> - [DESC]: ikke båret - </text> - <text name="path"> - Fundet i [PATH] - </text> - <text name="not worn instructions"> - Vælg en ny kropsbygning ved at trække en sådan fra din beholdning over på din avatar. Du kan også oprette en fra bunden og bagefter 'tage den på'. - </text> - <text name="no modify instructions"> - Du har ikke rettigheder til at redigere denne del. - </text> - <text name="Item Action Label"> - Figur: - </text> - <button label="Lav ny krop" label_selected="Lav ny krop" name="Create New"/> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Gem som..." label_selected="Gem som..." name="Save As"/> - </panel> - <panel label="Hud" name="Skin"> - <button label="Hudfarve" label_selected="Hudfarve" name="Skin Color"/> - <button label="Detaljer" label_selected="Detaljer" name="Face Detail"/> - <button label="Sminke" label_selected="Sminke" name="Makeup"/> - <button label="Kropsdetaljer" label_selected="Kropsdetaljer" name="Body Detail"/> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: Kan ikke redigeres - </text> - <text name="title_loading"> - [DESC]: indlæser... - </text> - <text name="title_not_worn"> - [DESC]: ikke båret - </text> - <text name="path"> - Fundet i [PATH] - </text> - <text name="not worn instructions"> - Vælg en ny hud ved at trække en sådan fra din beholdning over på din avatar. Du kan også oprette en fra bunden og bagefter 'tage den på'. - </text> - <text name="no modify instructions"> - Du har ikke rettigheder til at redigere denne del. - </text> - <text name="Item Action Label"> - Hud: - </text> - <texture_picker label="Tatoveringer hoved" name="Head Tattoos" tool_tip="Klik for at vælge et billede" width="98"/> - <texture_picker label="Tatover. overkrop" name="Upper Tattoos" tool_tip="Klik for at vælge et billede" width="98"/> - <texture_picker label="Tatover. underkrop" name="Lower Tattoos" tool_tip="Klik for at vælge et billede" width="98"/> - <button label="Lav ny hud" label_selected="Lav nyt hud" name="Create New"/> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Gem som..." label_selected="Gem som..." name="Save As"/> - <button label="Annullér" label_selected="Annullér" name="Revert"/> - </panel> - <panel label="Hår" name="Hair"> - <button label="Farve" label_selected="Farve" name="Color"/> - <button label="Stil" label_selected="Stil" name="Style"/> - <button label="Øjenbryn" label_selected="Øjenbryn" name="Eyebrows"/> - <button label="Skæg" label_selected="Skæg" name="Facial"/> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: kan ikke redigeres - </text> - <text name="title_loading"> - [DESC]: indlæser... - </text> - <text name="title_not_worn"> - [DESC]: ikke båret - </text> - <text name="path"> - Fundet i [PATH] - </text> - <text name="not worn instructions"> - Vælg et nyt hår ved at trække et sådant fra din beholdning over på din avatar. Du kan også oprette et fra bunden og bagefter 'tage det på'. - </text> - <text name="no modify instructions"> - Du har ikke rettigheder til at redigere denne del. - </text> - <text name="Item Action Label"> - Hår: - </text> - <texture_picker label="Tekstur" name="Texture" tool_tip="Klik for at vælge et billede"/> - <button label="Lav nyt hår" label_selected="Lav nyt hår" name="Create New"/> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Gem som..." label_selected="Gem som..." name="Save As"/> - <button label="Annullér" label_selected="Annullér" name="Revert"/> - </panel> - <panel label="Øjne" name="Eyes"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: Kan ikke redigeres - </text> - <text name="title_loading"> - [DESC]: indlæser... - </text> - <text name="title_not_worn"> - [DESC]: ikke båret - </text> - <text name="path"> - Fundet i [PATH] - </text> - <text name="not worn instructions"> - Vælg et nyt sæt øjne ved at trække et sådant par fra din beholdning over på din avatar. Du kan også oprette et par fra bunden og bagefter 'tage dem på'. - </text> - <text name="no modify instructions"> - Du har ikke rettigheder til at redigere denne del. - </text> - <text name="Item Action Label"> - Øjne: - </text> - <texture_picker label="Iris" name="Iris" tool_tip="Klik for at vælge et billede"/> - <button label="Lav nye øjne" label_selected="Lav nye øjne" name="Create New"/> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Gem som..." label_selected="Gem som..." name="Save As"/> - <button label="Annullér" label_selected="Annullér" name="Revert"/> - </panel> - <text label="Tøje" name="clothes_placeholder"> - Tøj - </text> - <panel label="Trøje" name="Shirt"> - <texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge et billede"/> - <color_swatch label="Farve" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/> - <button label="Tag af" label_selected="Tag af" name="Take Off"/> - <button label="Lav ny trøje" label_selected="Lav ny trøje" name="Create New"/> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Gem som..." label_selected="Gem som..." name="Save As"/> - <button label="Annullér" label_selected="Annullér" name="Revert"/> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: Kan ikke redigeres - </text> - <text name="title_loading"> - [DESC]: indlæser... - </text> - <text name="title_not_worn"> - [DESC]: ikke båret - </text> - <text name="path"> - Fundet i [PATH] - </text> - <text name="not worn instructions"> - Vælg en ny trøje ved at trække en fra din beholdning over på din avatar. Du kan også oprette en fra bunden og bagefter 'tage den på'. - </text> - <text name="no modify instructions"> - Du har ikke rettigheder til at redigere denne del. - </text> - <text name="Item Action Label"> - Trøje: - </text> - </panel> - <panel label="Bukser" name="Pants"> - <texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge et billede"/> - <color_swatch label="Farve" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/> - <button label="Tag af" label_selected="Tag af" name="Take Off"/> - <button label="Lav nye bukser" label_selected="Lav nye bukser" name="Create New"/> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Gem som..." label_selected="Gem som..." name="Save As"/> - <button label="Annullér" label_selected="Annullér" name="Revert"/> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: Kan ikke redigeres - </text> - <text name="title_loading"> - [DESC]: indlæser... - </text> - <text name="title_not_worn"> - [DESC]: ikke båret - </text> - <text name="path"> - Fundet i [PATH] - </text> - <text name="not worn instructions"> - Vælg et nyt par bukser ved at trække et par fra din beholdning over på din avatar. Du kan også oprette et par fra bunden og bagefter 'tage dem på'. - </text> - <text name="no modify instructions"> - Du har ikke rettigheder til at redigere denne del. - </text> - <text name="Item Action Label"> - Bukser: - </text> - </panel> - <panel label="Sko" name="Shoes"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: Kan ikke redigeres - </text> - <text name="title_loading"> - [DESC]: indlæser... - </text> - <text name="title_not_worn"> - [DESC]: ikke båret - </text> - <text name="path"> - Fundet i [PATH] - </text> - <text name="not worn instructions"> - Vælg et nyt par sko ved at trække et par fra din beholdning over på din avatar. Du kan også oprette et par fra bunden og bagefter 'tage dem på'. - </text> - <button label="Lav nye sko" label_selected="Lav nye sko" name="Create New"/> - <text name="no modify instructions"> - Du har ikke rettigheder til at redigere denne del. - </text> - <text name="Item Action Label"> - Sko: - </text> - <texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge et billede"/> - <color_swatch label="Farve" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/> - <button label="Tag af" label_selected="Tag af" name="Take Off"/> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Gem som..." label_selected="Gem som..." name="Save As"/> - <button label="Annullér" label_selected="Annullér" name="Revert"/> - </panel> - <panel label="Strømper" name="Socks"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: Kan ikke redigeres - </text> - <text name="title_loading"> - [DESC]: indlæser... - </text> - <text name="title_not_worn"> - [DESC]: ikke båret - </text> - <text name="path"> - Fundet i [PATH] - </text> - <text name="not worn instructions"> - Vælg et nyt par sokker ved at trække et par fra din beholdning over på din avatar. Du kan også oprette et par fra bunden og bagefter 'tage dem på'. - </text> - <button label="Lav nye strømper" label_selected="Lav nye strømper" name="Create New"/> - <text name="no modify instructions"> - Du har ikke rettigheder til at redigere denne del. - </text> - <text name="Item Action Label"> - Strømper: - </text> - <texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge et billede"/> - <color_swatch label="Farve" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/> - <button label="Tag af" label_selected="Tag af" name="Take Off"/> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Gem som..." label_selected="Gem som..." name="Save As"/> - <button label="Annullér" label_selected="Annullér" name="Revert"/> - </panel> - <panel label="Jakke" name="Jacket"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: Kan ikke redigeres - </text> - <text name="title_loading"> - [DESC]: indlæser... - </text> - <text name="title_not_worn"> - [DESC]: ikke båret - </text> - <text name="path"> - Fundet i [PATH] - </text> - <text name="not worn instructions"> - Vælg en ny jakke ved at trække en fra din beholdning over på din avatar. Du kan også oprette en fra bunden og bagefter 'tage den på'. - </text> - <button label="Lav ny jakke" label_selected="Lav ny jakke" name="Create New"/> - <text name="no modify instructions"> - Du har ikke rettigheder til at redigere denne del. - </text> - <text name="Item Action Label"> - Jakke: - </text> - <texture_picker label="Stof øverst" name="Upper Fabric" tool_tip="Klik for at vælge et billede"/> - <texture_picker label="Stof nederst" name="Lower Fabric" tool_tip="Klik for at vælge et billede"/> - <color_swatch label="Farve" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/> - <button label="Tag af" label_selected="Tag af" name="Take Off"/> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Gem som..." label_selected="Gem som..." name="Save As"/> - <button label="Annullér" label_selected="Annullér" name="Revert"/> - </panel> - <panel label="Handsker" name="Gloves"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: Kan ikke redigeres - </text> - <text name="title_loading"> - [DESC]: indlæser... - </text> - <text name="title_not_worn"> - [DESC]: ikke båret - </text> - <text name="path"> - Fundet i [PATH] - </text> - <text name="not worn instructions"> - Vælg et sæt nye handsker ved at trække et par fra din beholdning over på din avatar. Du kan også oprette et par fra bunden og bagefter 'tage dem på'. - </text> - <button label="Lav nye handsker" label_selected="Lav nye handsker" name="Create New"/> - <text name="no modify instructions"> - Du har ikke rettigheder til at redigere denne del. - </text> - <text name="Item Action Label"> - Handsker: - </text> - <texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge et billede"/> - <color_swatch label="Farve" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/> - <button label="Tag af" label_selected="Tag af" name="Take Off"/> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Gem som..." label_selected="Gem som..." name="Save As"/> - <button label="Annullér" label_selected="Annullér" name="Revert"/> - </panel> - <panel label="Undertrøje" name="Undershirt"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: Kan ikke redigeres - </text> - <text name="title_loading"> - [DESC]: indlæser... - </text> - <text name="title_not_worn"> - [DESC]: ikke båret - </text> - <text name="path"> - Fundet i [PATH] - </text> - <text name="not worn instructions"> - Vælg en ny undertrøje ved at trække en fra din beholdning over på din avatar. Du kan også oprette en fra bunden og bagefter 'tage den på'. - </text> - <button label="Lav ny undertrøje" label_selected="Lav ny undertrøje" name="Create New"/> - <text name="no modify instructions"> - Du har ikke rettigheder til at redigere denne del. - </text> - <text name="Item Action Label"> - Undertrøje: - </text> - <texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge et billede"/> - <color_swatch label="Farve" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/> - <button label="Tag af" label_selected="Tag af" name="Take Off"/> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Gem som..." label_selected="Gem som..." name="Save As"/> - <button label="Annullér" label_selected="Annullér" name="Revert"/> - </panel> - <panel label="Underbukser" name="Underpants"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: Kan ikke redigeres - </text> - <text name="title_loading"> - [DESC]: indlæser... - </text> - <text name="title_not_worn"> - [DESC]: ikke båret - </text> - <text name="path"> - Fundet i [PATH] - </text> - <text name="not worn instructions"> - Vælg et nyt par underbukser ved at trække et par fra din beholdning over på din avatar. Du kan også oprette et par fra bunden og bagefter 'tage dem på'. - </text> - <button label="Lav nye underbukser" label_selected="Lav nye underbukser" name="Create New"/> - <text name="no modify instructions"> - Du har ikke rettigheder til at redigere denne del. - </text> - <text name="Item Action Label"> - Underbukser: - </text> - <texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge et billede"/> - <color_swatch label="Farve" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/> - <button label="Tag af" label_selected="Tag af" name="Take Off"/> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Gem som..." label_selected="Gem som..." name="Save As"/> - <button label="Annullér" label_selected="Annullér" name="Revert"/> - </panel> - <panel label="Nederdel" name="Skirt"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: Kan ikke redigeres - </text> - <text name="title_loading"> - [DESC]: indlæser... - </text> - <text name="title_not_worn"> - [DESC]: ikke båret - </text> - <text name="path"> - Fundet i [PATH] - </text> - <text name="not worn instructions"> - Vælg en ny nederdel ved at trække en fra din beholdning over på din avatar. Du kan også oprette en fra bunden og bagefter 'tage den på'. - </text> - <button label="Lav ny nederdel" label_selected="Lav ny nederdel" name="Create New"/> - <text name="no modify instructions"> - Du har ikke rettigheder til at redigere denne del. - </text> - <text name="Item Action Label"> - Nederdel: - </text> - <texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge et billede"/> - <color_swatch label="Farve" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/> - <button label="Tag af" label_selected="Tag af" name="Take Off"/> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Gem som..." label_selected="Gem som..." name="Save As"/> - <button label="Annullér" label_selected="Annullér" name="Revert"/> - </panel> - <panel label="Tatovering" name="Tattoo"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: kan ikke ændre - </text> - <text name="title_loading"> - [DESC]: indlæser... - </text> - <text name="title_not_worn"> - [DESC]: ikke båret - </text> - <text name="path"> - Placeret i [PATH] - </text> - <text name="not worn instructions"> - Vælg en ny tatovering ved at trække en fra din beholdning over på din avatar. Du kan også oprette en fra bunden og bagefter 'tage den på'. - </text> - <button label="lav ny tatovering" label_selected="Lav ny tatovering" name="Create New"/> - <text name="no modify instructions"> - Du har ikke rettigheder til at ændre denne. - </text> - <text name="Item Action Label"> - Tatovering: - </text> - <texture_picker label="Tatovering - hovede" name="Head Tattoo" tool_tip="Klik for at vælge et billede"/> - <texture_picker label="Øvre tatovering" name="Upper Tattoo" tool_tip="Klik for at vælge et billede"/> - <texture_picker label="Nedre tatovering" name="Lower Tattoo" tool_tip="Klik for at vælge et billede"/> - <button label="Tag af" label_selected="Tag af" name="Take Off"/> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Gem som..." label_selected="Gem som..." name="Save As"/> - <button label="Vend tilbage" label_selected="Vend tilbage" name="Revert"/> - </panel> - <panel label="Alpha" name="Alpha"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: kan ikke ændre - </text> - <text name="title_loading"> - [DESC]: indlæser... - </text> - <text name="title_not_worn"> - [DESC]: ikke båret - </text> - <text name="path"> - Placeret i [PATH] - </text> - <text name="not worn instructions"> - Vælg en ny 'alpha maske' ved at trække en fra din beholdning over på din avatar. Du kan også oprette en fra bunden og bagefter 'tage den på'. - </text> - <button label="Lav ny "Alpha"" label_selected="Lav ny "Alpha"" name="Create New"/> - <text name="no modify instructions"> - Du har ikke rettigheder til at ændre denne. - </text> - <text name="Item Action Label"> - Alpha: - </text> - <texture_picker label="Alpha - nedre" name="Lower Alpha" tool_tip="Klik for at vælge et billede"/> - <texture_picker label="Øvre alpha" name="Upper Alpha" tool_tip="Klik for at vælge et billede"/> - <texture_picker label="Alpha - hoved" name="Head Alpha" tool_tip="Klik for at vælge et billede"/> - <texture_picker label="Alpha - øjne" name="Eye Alpha" tool_tip="Klik for at vælge et billede"/> - <texture_picker label="Alpha - hår" name="Hair Alpha" tool_tip="Klik for at vælge et billede"/> - <button label="Tag af" label_selected="Tag af" name="Take Off"/> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Gem som..." label_selected="Gem som..." name="Save As"/> - <button label="Vend tilbage" label_selected="Vend tilbage" name="Revert"/> - </panel> - </tab_container> - <scroll_container name="panel_container"/> - <button label="Script info" label_selected="Script info" name="script_info" tool_tip="Vis scripts vedhæftet på din avatar"/> - <button label="Lav sæt" label_selected="Lav sæt" name="make_outfit_btn"/> - <button label="Annullér" label_selected="Annullér" name="Cancel"/> - <button label="OK" label_selected="OK" name="Ok"/> -</floater> diff --git a/indra/newview/skins/default/xui/da/floater_device_settings.xml b/indra/newview/skins/default/xui/da/floater_device_settings.xml deleted file mode 100644 index 06d431a8f9..0000000000 --- a/indra/newview/skins/default/xui/da/floater_device_settings.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_device_settings" title="STEMME CHAT ENHEDSOPSÆTNING"/> diff --git a/indra/newview/skins/default/xui/da/floater_im.xml b/indra/newview/skins/default/xui/da/floater_im.xml deleted file mode 100644 index 776bc9ab13..0000000000 --- a/indra/newview/skins/default/xui/da/floater_im.xml +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<multi_floater name="im_floater" title="Personlig samtale (IM)"> - <string name="only_user_message"> - Du er den eneste beboer i denne session. - </string> - <string name="offline_message"> - [FIRST] [LAST] er ikke logget på. - </string> - <string name="invite_message"> - Tryk på [BUTTON NAME] knappen for at acceptére/tilslutte til denne stemme chat. - </string> - <string name="muted_message"> - Du har blokeret denne beboer. Hvis du sender en besked til beboeren vil dette automatisk medføre fjernelse af blokeringen - </string> - <string name="generic_request_error"> - Kunne ikke etablere forbindelse, prøv igen senere - </string> - <string name="insufficient_perms_error"> - Du har ikke de fornødne rettigheder. - </string> - <string name="session_does_not_exist_error"> - Denne samtale er lukket ned - </string> - <string name="no_ability_error"> - Du har ikke den mulighed. - </string> - <string name="not_a_mod_error"> - Du er ikke moderator for denne samtale. - </string> - <string name="muted_error"> - Du er blevet "blokeret". - </string> - <string name="add_session_event"> - Kunne ikke tilføje beboere til chat session med [RECIPIENT]. - </string> - <string name="message_session_event"> - Ikke muligt at sende din besked til samtalen med [RECIPIENT]. - </string> - <string name="removed_from_group"> - Du er blevet fjernet fra gruppen. - </string> - <string name="close_on_no_ability"> - Du har ikke længere mulighed for at deltage i samtalen - </string> -</multi_floater> diff --git a/indra/newview/skins/default/xui/da/floater_im_session.xml b/indra/newview/skins/default/xui/da/floater_im_session.xml index aa7df6ad2b..16df7e4b03 100644 --- a/indra/newview/skins/default/xui/da/floater_im_session.xml +++ b/indra/newview/skins/default/xui/da/floater_im_session.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="panel_im"> <layout_stack name="im_panels"> - <layout_panel label="IM kontrol panel" name="panel_im_control_panel"/> <layout_panel> <line_editor label="Til" name="chat_editor"/> </layout_panel> diff --git a/indra/newview/skins/default/xui/da/floater_my_friends.xml b/indra/newview/skins/default/xui/da/floater_my_friends.xml deleted file mode 100644 index c3db53ce63..0000000000 --- a/indra/newview/skins/default/xui/da/floater_my_friends.xml +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_my_friends" title="KONTAKTER"> - <tab_container name="friends_and_groups"> - <panel label="Venner" name="friends_panel"/> - <panel label="Grupper" name="groups_panel"/> - </tab_container> -</floater> diff --git a/indra/newview/skins/default/xui/da/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/da/floater_outfit_save_as.xml deleted file mode 100644 index 0bcb96b151..0000000000 --- a/indra/newview/skins/default/xui/da/floater_outfit_save_as.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="modal container" title="Gem sæt"> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Annullér" label_selected="Annullér" name="Cancel"/> - <text name="Save item as:"> - Gem hvad jeg har på som et nyt sæt: - </text> - <line_editor name="name ed"> - [DESC] (ny) - </line_editor> -</floater> diff --git a/indra/newview/skins/default/xui/da/floater_preview_classified.xml b/indra/newview/skins/default/xui/da/floater_preview_classified.xml deleted file mode 100644 index bc232f3e9f..0000000000 --- a/indra/newview/skins/default/xui/da/floater_preview_classified.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="classified_preview" title="ANNONCE INFORMATION"> - <floater.string name="Title"> - Annonce: [NAME] - </floater.string> -</floater> diff --git a/indra/newview/skins/default/xui/da/floater_preview_event.xml b/indra/newview/skins/default/xui/da/floater_preview_event.xml deleted file mode 100644 index 3e870b58ae..0000000000 --- a/indra/newview/skins/default/xui/da/floater_preview_event.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="event_preview" title="EVENT INFORMATION"> - <floater.string name="Title"> - Event: [NAME] - </floater.string> -</floater> diff --git a/indra/newview/skins/default/xui/da/floater_preview_gesture_info.xml b/indra/newview/skins/default/xui/da/floater_preview_gesture_info.xml deleted file mode 100644 index 9892a92e4c..0000000000 --- a/indra/newview/skins/default/xui/da/floater_preview_gesture_info.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Gesture" title="BEVÆGELSE GENVEJ"/> diff --git a/indra/newview/skins/default/xui/da/floater_preview_gesture_shortcut.xml b/indra/newview/skins/default/xui/da/floater_preview_gesture_shortcut.xml deleted file mode 100644 index 4d4cca1d90..0000000000 --- a/indra/newview/skins/default/xui/da/floater_preview_gesture_shortcut.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Gesture" title="GENVEJ BEVÆGELSER"> - <text name="trigger_label"> - Chat: - </text> - <text name="key_label"> - Tastatur: - </text> - <combo_box label="Intet" name="modifier_combo"/> - <combo_box label="Intet" name="key_combo"/> - <text name="replace_text" tool_tip="Erstat udløser ord med disse ord. For eksempel uløser "hello" erstat med "hej" vil ændre chat 'Jeg ville bare sige hello' til 'Jeg ville bare sige hej' samtidig med bevægelsen afspilles!"> - Erstat: - </text> - <line_editor name="replace_editor" tool_tip="Erstat udløser ord med disse ord. For eksempel uløser "hello" erstat med "hej" vil ændre chat 'Jeg ville bare sige hello' til 'Jeg ville bare sige hej' samtidig med bevægelsen afspilles!"/> -</floater> diff --git a/indra/newview/skins/default/xui/da/floater_preview_gesture_steps.xml b/indra/newview/skins/default/xui/da/floater_preview_gesture_steps.xml deleted file mode 100644 index 9892a92e4c..0000000000 --- a/indra/newview/skins/default/xui/da/floater_preview_gesture_steps.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Gesture" title="BEVÆGELSE GENVEJ"/> diff --git a/indra/newview/skins/default/xui/da/floater_statistics.xml b/indra/newview/skins/default/xui/da/floater_statistics.xml deleted file mode 100644 index 8c33f3ecb3..0000000000 --- a/indra/newview/skins/default/xui/da/floater_statistics.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="stats floater" title="STATISTIK"/> diff --git a/indra/newview/skins/default/xui/da/floater_voice_controls.xml b/indra/newview/skins/default/xui/da/floater_voice_controls.xml index 2e59dfd649..4c956f13a7 100644 --- a/indra/newview/skins/default/xui/da/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/da/floater_voice_controls.xml @@ -19,10 +19,12 @@ <layout_panel name="my_panel"> <text name="user_text" value="Min avatar:"/> </layout_panel> - <layout_stack name="voice_effect_and_leave_call_stack"> - <layout_panel name="leave_call_btn_panel"> - <button label="Forlad opkald" name="leave_call_btn"/> - </layout_panel> - </layout_stack> + <layout_panel name="leave_call_panel"> + <layout_stack name="voice_effect_and_leave_call_stack"> + <layout_panel name="leave_call_btn_panel"> + <button label="Forlad opkald" name="leave_call_btn"/> + </layout_panel> + </layout_stack> + </layout_panel> </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/da/floater_wearable_save_as.xml b/indra/newview/skins/default/xui/da/floater_wearable_save_as.xml deleted file mode 100644 index 17d5b9c205..0000000000 --- a/indra/newview/skins/default/xui/da/floater_wearable_save_as.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="modal container" title=""> - <button label="Gem" label_selected="Gem" name="Save"/> - <button label="Annullér" label_selected="Annullér" name="Cancel"/> - <text name="Save item as:"> - Gem genstand i min beholdning som: - </text> - <line_editor name="name ed"> - Ny [DESC] - </line_editor> -</floater> diff --git a/indra/newview/skins/default/xui/da/menu_avatar_self.xml b/indra/newview/skins/default/xui/da/menu_avatar_self.xml index ec85bd05a5..af4fdcc154 100644 --- a/indra/newview/skins/default/xui/da/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/da/menu_avatar_self.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Self Pie"> <menu_item_call label="Stå op" name="Stand Up"/> - <context_menu label="Tag af ▶" name="Take Off >"> - <context_menu label="Tøj ▶" name="Clothes >"> + <context_menu label="Tag af" name="Take Off >"> + <context_menu label="Tøj" name="Clothes >"> <menu_item_call label="Trøje" name="Shirt"/> <menu_item_call label="Bukser" name="Pants"/> <menu_item_call label="Nederdel" name="Skirt"/> @@ -16,8 +16,8 @@ <menu_item_call label="Alpha" name="Self Alpha"/> <menu_item_call label="Alt tøj" name="All Clothes"/> </context_menu> - <context_menu label="HUD ▶" name="Object Detach HUD"/> - <context_menu label="Tag af ▶" name="Object Detach"/> + <context_menu label="HUD" name="Object Detach HUD"/> + <context_menu label="Tag af" name="Object Detach"/> <menu_item_call label="Tag alt af" name="Detach All"/> </context_menu> <menu_item_call label="Skift sæt" name="Chenge Outfit"/> diff --git a/indra/newview/skins/default/xui/da/menu_object.xml b/indra/newview/skins/default/xui/da/menu_object.xml index f4f7eb0af8..3c96d62ce3 100644 --- a/indra/newview/skins/default/xui/da/menu_object.xml +++ b/indra/newview/skins/default/xui/da/menu_object.xml @@ -10,12 +10,12 @@ <menu_item_call label="Stå op" name="Object Stand Up"/> <menu_item_call label="Objekt profil" name="Object Inspect"/> <menu_item_call label="Zoom In" name="Zoom In"/> - <context_menu label="Tag på ▶" name="Put On"> + <context_menu label="Tag på" name="Put On"> <menu_item_call label="Tag på" name="Wear"/> - <context_menu label="Vedhæft ▶" name="Object Attach"/> - <context_menu label="Vedhæft HUD ▶" name="Object Attach HUD"/> + <context_menu label="Vedhæft" name="Object Attach"/> + <context_menu label="Vedhæft HUD" name="Object Attach HUD"/> </context_menu> - <context_menu label="Fjern ▶" name="Remove"> + <context_menu label="Fjern" name="Remove"> <menu_item_call label="Rapportér misbrug" name="Report Abuse..."/> <menu_item_call label="Blokér" name="Object Mute"/> <menu_item_call label="Returnér" name="Return..."/> diff --git a/indra/newview/skins/default/xui/da/menu_participant_list.xml b/indra/newview/skins/default/xui/da/menu_participant_list.xml index 2bd28e10de..0069dcbacb 100644 --- a/indra/newview/skins/default/xui/da/menu_participant_list.xml +++ b/indra/newview/skins/default/xui/da/menu_participant_list.xml @@ -11,7 +11,7 @@ <menu_item_check label="Se person ikoner" name="View Icons"/> <menu_item_check label="Blokér stemme" name="Block/Unblock"/> <menu_item_check label="Blokér tekst" name="MuteText"/> - <context_menu label="Moderator muligheder >" name="Moderator Options"> + <context_menu label="Moderator muligheder" name="Moderator Options"> <menu_item_check label="Tillad tekst chat" name="AllowTextChat"/> <menu_item_call label="Sluk for denne deltager" name="ModerateVoiceMuteSelected"/> <menu_item_call label="Fjern slukning for denne deltager" name="ModerateVoiceUnMuteSelected"/> diff --git a/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml index 00055c8932..0845f19b15 100644 --- a/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml +++ b/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml @@ -5,8 +5,8 @@ <menu_item_call label="Tilføj" name="wear_add"/> <menu_item_call label="Tag af" name="take_off_or_detach"/> <menu_item_call label="Tag af" name="detach"/> - <context_menu label="Vedhæft til ▶" name="wearable_attach_to"/> - <context_menu label="Vedhæft på HUD ▶" name="wearable_attach_to_hud"/> + <context_menu label="Vedhæft til" name="wearable_attach_to"/> + <context_menu label="Vedhæft på HUD" name="wearable_attach_to_hud"/> <menu_item_call label="Tag af" name="take_off"/> <menu_item_call label="Redigér" name="edit"/> <menu_item_call label="Objekt profil" name="object_profile"/> diff --git a/indra/newview/skins/default/xui/da/panel_audio_device.xml b/indra/newview/skins/default/xui/da/panel_audio_device.xml deleted file mode 100644 index f6d817540e..0000000000 --- a/indra/newview/skins/default/xui/da/panel_audio_device.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="device_settings"> - <text name="Audio Devices"> - Lydenheder - </text> - <text name="Input device (microphone):"> - Input enhed (mikrofon): - </text> - <text name="Output device (speakers):"> - Output enhed (højtalere): - </text> - <text name="Input level:"> - Input niveau - </text> - <text_editor name="voice_intro_text1"> - Med denne skyder kan du regulere hvor højt du lyder i forhold til andre beboere. for at test input niveau kan du blot tale i mikrofon. - </text_editor> - <volume_slider name="mic_volume_slider" tool_tip="Ændre lydstyrke med denne skyder" /> - <text name="wait_text"> - Vent venligst - </text> - <string name="default_text"> - Standard - </string> -</panel> diff --git a/indra/newview/skins/default/xui/da/panel_friends.xml b/indra/newview/skins/default/xui/da/panel_friends.xml deleted file mode 100644 index a1a25bdc77..0000000000 --- a/indra/newview/skins/default/xui/da/panel_friends.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="friends"> - <string name="Multiple"> - Flere venner - </string> - <scroll_list name="friend_list" tool_tip="Hold Shift eller Ctrl nede imens du klikker for at vælge flere venner"> - <column name="icon_online_status" tool_tip="Online status"/> - <column label="Name" name="friend_name" tool_tip="Navn"/> - <column name="icon_visible_online" tool_tip="Venner kan se at du er online"/> - <column name="icon_visible_map" tool_tip="Venner kan finde dig på kortet"/> - <column name="icon_edit_mine" tool_tip="Venner kan rette i, slette eller tage dine objekter"/> - <column name="icon_edit_theirs" tool_tip="Du kan rette i denne vens objekter"/> - </scroll_list> - <button label="IM" name="im_btn" tool_tip="Skriv en personlig besked (IM)"/> - <button label="Profil" name="profile_btn" tool_tip="Vis billede, grupper og anden information"/> - <button label="Teleport" name="offer_teleport_btn" tool_tip="Tilbyd denne ven at blive teleporteret til din nuværende position"/> - <button label="Betal" name="pay_btn" tool_tip="Giv Linden dollars (L$) til denne ven"/> - <button label="Fjern" name="remove_btn" tool_tip="Fjern denne beboer fra din venneliste"/> - <button label="Tilføj" name="add_btn" tool_tip="Tilbyd venskab til en beboer"/> -</panel> diff --git a/indra/newview/skins/default/xui/da/panel_groups.xml b/indra/newview/skins/default/xui/da/panel_groups.xml deleted file mode 100644 index 5877226e57..0000000000 --- a/indra/newview/skins/default/xui/da/panel_groups.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="groups"> - <scroll_list name="group list"> - <column label="" name="name" /> - </scroll_list> - <text name="groupdesc" width="300"> - Din nuværende aktive gruppe er fremhævet i listen. - </text> - <text name="groupcount" width="300"> - Du er medlem i [COUNT] grupper (ud af maksimalt [MAX]). - </text> - <button label="IM/Opkald" name="IM" tool_tip="Åbner IM session" /> - <button label="Info" name="Info" /> - <button label="Aktivér" name="Activate" /> - <button label="Forlad" name="Leave" /> - <button label="Opret..." name="Create" /> - <button label="Søg..." name="Search..." /> -</panel> diff --git a/indra/newview/skins/default/xui/da/panel_nearby_chat.xml b/indra/newview/skins/default/xui/da/panel_nearby_chat.xml deleted file mode 100644 index 7f94345976..0000000000 --- a/indra/newview/skins/default/xui/da/panel_nearby_chat.xml +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- All our XML is utf-8 encoded. --> -<panel name="nearby_chat"> - <panel name="chat_caption"> - <text name="sender_name"> - CHAT NÆRVED - </text> - </panel> -</panel> diff --git a/indra/newview/skins/default/xui/da/panel_notes.xml b/indra/newview/skins/default/xui/da/panel_notes.xml index 5b3a2d0906..00128497ba 100644 --- a/indra/newview/skins/default/xui/da/panel_notes.xml +++ b/indra/newview/skins/default/xui/da/panel_notes.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="Noter & Privatliv" name="panel_notes"> <layout_stack name="layout"> - <panel name="notes_stack"> + <layout_panel name="notes_stack"> <scroll_container name="profile_scroll"> <panel name="profile_scroll_panel"> <text name="status_message" value="Min private noter:"/> @@ -11,13 +11,13 @@ <check_box label="Editére, slette og tage mine objekter" name="objects_check"/> </panel> </scroll_container> - </panel> - <panel name="notes_buttons_panel"> + </layout_panel> + <layout_panel name="notes_buttons_panel"> <button label="Tilføj ven" name="add_friend" tool_tip="Tilbyd venskab til beboer"/> <button label="IM" name="im" tool_tip="Åben session med personlig besked (IM)"/> <button label="Kald" name="call" tool_tip="Opkald til denne beboer"/> <button label="Kort" name="show_on_map_btn" tool_tip="Vis beboer på kort"/> <button label="Teleport" name="teleport" tool_tip="Tilbyd teleport"/> - </panel> + </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/da/panel_online_status.xml b/indra/newview/skins/default/xui/da/panel_online_status.xml deleted file mode 100644 index fdc489f375..0000000000 --- a/indra/newview/skins/default/xui/da/panel_online_status.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="friend_online_status" name="friend_online_status"/> diff --git a/indra/newview/skins/default/xui/da/panel_preferences_chat.xml b/indra/newview/skins/default/xui/da/panel_preferences_chat.xml index 8caf56f47e..bea106bf28 100644 --- a/indra/newview/skins/default/xui/da/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/da/panel_preferences_chat.xml @@ -71,7 +71,7 @@ <combo_box.item label="Magyar (Ungarsk)" name="Hungarian" /> <combo_box.item label="Nederlands (Hollandsk)" name="Dutch" /> <combo_box.item label="Polski (Polsk)" name="Polish" /> - <combo_box.item label="Portugués (Portugisisk)" name="Portugese" /> + <combo_box.item label="Português (Portugisisk)" name="Portugese" /> <combo_box.item label="Русский (Russisk)" name="Russian" /> <combo_box.item label="Türkçe (Tyrkisk)" name="Turkish" /> <combo_box.item label="Українська (Ukrainsk)" name="Ukrainian" /> diff --git a/indra/newview/skins/default/xui/da/panel_preferences_general.xml b/indra/newview/skins/default/xui/da/panel_preferences_general.xml index e70cb48262..6a85cf4aae 100644 --- a/indra/newview/skins/default/xui/da/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/da/panel_preferences_general.xml @@ -11,7 +11,7 @@ <combo_box.item label="Español (Spansk) - Beta" name="Spanish"/> <combo_box.item label="Français (Fransk) - Beta" name="French"/> <combo_box.item label="Polski (Polsk) - Beta" name="Polish"/> - <combo_box.item label="Portugués (Portugisisk) - Beta" name="Portugese"/> + <combo_box.item label="Português (Portugisisk) - Beta" name="Portugese"/> <combo_box.item label="日本語 (Japansk) - Beta" name="(Japanese)"/> </combo_box> <text name="language_textbox2"> diff --git a/indra/newview/skins/default/xui/da/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/da/panel_prim_media_controls.xml index d3b3c7e21e..cfb32500c6 100644 --- a/indra/newview/skins/default/xui/da/panel_prim_media_controls.xml +++ b/indra/newview/skins/default/xui/da/panel_prim_media_controls.xml @@ -13,9 +13,9 @@ 50 </string> <layout_stack name="progress_indicator_area"> - <panel name="media_progress_indicator"> + <layout_panel name="media_progress_indicator"> <progress_bar name="media_progress_bar" tool_tip="Medie hentes"/> - </panel> + </layout_panel> </layout_stack> <layout_stack name="media_controls"> <layout_panel name="back"> diff --git a/indra/newview/skins/default/xui/da/panel_region_general_layout.xml b/indra/newview/skins/default/xui/da/panel_region_general_layout.xml deleted file mode 100644 index f3c32d6169..0000000000 --- a/indra/newview/skins/default/xui/da/panel_region_general_layout.xml +++ /dev/null @@ -1,43 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Region" name="General"> - <text name="region_text_lbl"> - Region: - </text> - <text name="region_text"> - ukendt - </text> - <text name="version_channel_text_lbl"> - Version: - </text> - <text name="version_channel_text"> - ukendt - </text> - <text name="region_type_lbl"> - Type: - </text> - <text name="region_type"> - ukendt - </text> - <check_box label="Blokér for redigering af terræn" name="block_terraform_check"/> - <check_box label="Blokér for flyvning" name="block_fly_check"/> - <check_box label="Tillad skader" name="allow_damage_check"/> - <check_box label="Begræns skubning" name="restrict_pushobject"/> - <check_box label="Tillad at sælge land" name="allow_land_resell_check"/> - <check_box label="Tillad at samle/dele land" name="allow_parcel_changes_check"/> - <check_box label="Blokér visning af land i Søgning" name="block_parcel_search_check" tool_tip="Lad beboere se denne region og dens parceller i søgeresultater"/> - <spinner label="Max besøgende" name="agent_limit_spin"/> - <spinner label="Objekt bonus" name="object_bonus_spin"/> - <text label="Rating" name="access_text"> - Rating: - </text> - <combo_box label="Moderat" name="access_combo"> - <combo_box.item label="Voksent" name="Adult"/> - <combo_box.item label="Moderat" name="Mature"/> - <combo_box.item label="Generel" name="PG"/> - </combo_box> - <button label="Gem" name="apply_btn"/> - <button label="Teleportér en beboer hjem..." name="kick_btn"/> - <button label="Teleportér alle beboere hjem..." name="kick_all_btn"/> - <button label="Send besked til region..." name="im_btn"/> - <button label="Vedligehold telehub..." name="manage_telehub_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml index 3152661fd4..712f6f8b50 100644 --- a/indra/newview/skins/default/xui/da/strings.xml +++ b/indra/newview/skins/default/xui/da/strings.xml @@ -1117,6 +1117,9 @@ <string name="InvFolder Favorite"> Favoritter </string> + <string name="InvFolder favorite"> + Favoritter + </string> <string name="InvFolder Current Outfit"> Nuværende sæt </string> diff --git a/indra/newview/skins/default/xui/de/floater_about_land.xml b/indra/newview/skins/default/xui/de/floater_about_land.xml index 5f00fc4f77..f9169ed748 100644 --- a/indra/newview/skins/default/xui/de/floater_about_land.xml +++ b/indra/newview/skins/default/xui/de/floater_about_land.xml @@ -259,18 +259,18 @@ werden. <text left="204" name="other_objects_text" width="48"> [COUNT] </text> - <button label="Anzeigen" label_selected="Anzeigen" name="ShowOther" right="-135" width="60"/> - <button label="Zurückgeben" label_selected="Zurückgeben..." name="ReturnOther..." right="-10" tool_tip="Objekte an ihre Eigentümer zurückgeben." width="119"/> - <text left="14" name="Selected / sat upon:" width="140"> + <button label="Anzeigen" label_selected="Anzeigen" name="ShowOther"/> + <button label="Zurückgeben" label_selected="Zurückgeben..." name="ReturnOther..." tool_tip="Objekte an ihre Eigentümer zurückgeben."/> + <text name="Selected / sat upon:"> Ausgewählt/gesessen auf: </text> - <text left="204" name="selected_objects_text" width="48"> + <text name="selected_objects_text"> [COUNT] </text> <text name="Autoreturn"> Objekte anderer Einwohner automatisch zurückgeben (Minuten, 0 für aus): </text> - <line_editor name="clean other time" right="-10" width="56"/> + <line_editor name="clean other time"/> <text name="Object Owners:"> Objekteigentümer: </text> @@ -279,7 +279,7 @@ werden. <name_list name="owner list"> <name_list.columns label="Typ" name="type"/> <name_list.columns label="Name" name="name"/> - <name_list.columns label="Anzahl" name="count" width="80"/> + <name_list.columns label="Anzahl" name="count"/> <name_list.columns label="Aktuellstes" name="mostrecent"/> </name_list> </panel> diff --git a/indra/newview/skins/default/xui/de/floater_bulk_perms.xml b/indra/newview/skins/default/xui/de/floater_bulk_perms.xml index d3f0d6d78f..8f99fc933c 100644 --- a/indra/newview/skins/default/xui/de/floater_bulk_perms.xml +++ b/indra/newview/skins/default/xui/de/floater_bulk_perms.xml @@ -43,7 +43,7 @@ Jeder: </text> <check_box label="Kopieren" name="everyone_copy"/> - <text name="NextOwnerLabel" top="160" left="10" width="200"> + <text name="NextOwnerLabel"> Nächster Eigentümer: </text> <check_box label="Bearbeiten" name="next_owner_modify"/> diff --git a/indra/newview/skins/default/xui/de/floater_customize.xml b/indra/newview/skins/default/xui/de/floater_customize.xml deleted file mode 100644 index 3651577797..0000000000 --- a/indra/newview/skins/default/xui/de/floater_customize.xml +++ /dev/null @@ -1,529 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater customize" title="AUSSEHEN"> - <tab_container name="customize tab container"> - <text label="Körperteile" name="body_parts_placeholder"> - Körperteile - </text> - <panel label="Form" name="Shape"> - <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> - <button label="Körper" label_selected="Körper" name="Body"/> - <button label="Kopf" label_selected="Kopf" name="Head"/> - <button label="Augen" label_selected="Augen" name="Eyes"/> - <button label="Ohren" label_selected="Ohren" name="Ears"/> - <button label="Nase" label_selected="Nase" name="Nose"/> - <button label="Mund" label_selected="Mund" name="Mouth"/> - <button label="Kinn" label_selected="Kinn" name="Chin"/> - <button label="Oberkörper" label_selected="Oberkörper" name="Torso"/> - <button label="Beine" label_selected="Beine" name="Legs"/> - <radio_group name="sex radio"> - <radio_item label="Weiblich" name="radio" value="0"/> - <radio_item label="Männlich" name="radio2" value="1"/> - </radio_group> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: bearbeiten nicht möglich - </text> - <text name="title_loading"> - [DESC]: wird geladen... - </text> - <text name="title_not_worn"> - [DESC]: nicht getragen - </text> - <text name="path"> - In [PATH] - </text> - <text name="not worn instructions"> - Ziehen Sie eine neue Form aus dem Inventar auf Ihren Avatar, um diese anzulegen. Sie können aber auch eine neue erstellen und diese anlegen. - </text> - <text name="no modify instructions"> - Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. - </text> - <text name="Item Action Label"> - Form: - </text> - <button label="Neue Form/Gestalt" label_selected="Neue Form/Gestalt" name="Create New"/> - <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" name="Save"/> - <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> - </panel> - <panel label="Haut" name="Skin"> - <button label="Hautfarbe" label_selected="Hautfarbe" left="2" name="Skin Color" width="92"/> - <button label="Gesichtsdetails" label_selected="Gesichtsdetails" left="2" name="Face Detail" width="92"/> - <button label="Make-Up" label_selected="Make-Up" left="2" name="Makeup" width="92"/> - <button label="Körperdetails" label_selected="Körperdetails" left="2" name="Body Detail" width="92"/> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: bearbeiten nicht möglich - </text> - <text name="title_loading"> - [DESC]: wird geladen... - </text> - <text name="title_not_worn"> - [DESC]: nicht getragen - </text> - <text name="path"> - In [PATH] - </text> - <text name="not worn instructions"> - Ziehen Sie eine neue Skin (Haut) aus dem Inventar auf Ihren Avatar, um diese anzulegen. Sie können aber auch eine neue erstellen und diese anlegen. - </text> - <text name="no modify instructions"> - Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. - </text> - <text name="Item Action Label" right="100"> - Haut: - </text> - <texture_picker label="Kopftattoo" name="Head Tattoos" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <texture_picker label="Obere Tattoos" name="Upper Tattoos" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <texture_picker label="Untere Tattoos" name="Lower Tattoos" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <button label="Neue Haut" label_selected="Neue Haut" name="Create New"/> - <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> - <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> - <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> - </panel> - <panel label="Haar" name="Hair"> - <button label="Farbe" label_selected="Farbe" name="Color"/> - <button label="Stil" label_selected="Stil" name="Style"/> - <button label="Augenbrauen" label_selected="Augenbrauen" name="Eyebrows"/> - <button label="Gesichtshaar" label_selected="Gesichtshaar" name="Facial"/> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: bearbeiten nicht möglich - </text> - <text name="title_loading"> - [DESC]: wird geladen... - </text> - <text name="title_not_worn"> - [DESC]: nicht getragen - </text> - <text name="path"> - In [PATH] - </text> - <text name="not worn instructions"> - Ziehen Sie Haar aus dem Inventar auf Ihren Avatar, um dieses anzulegen. Sie können aber auch neues Haar erstellen und anlegen. - </text> - <text name="no modify instructions"> - Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. - </text> - <text name="Item Action Label" right="100"> - Haare: - </text> - <texture_picker label="Textur" name="Texture" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <button label="Neue Haare" label_selected="Neue Haare" name="Create New"/> - <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> - <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> - <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> - </panel> - <panel label="Augen" name="Eyes"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: bearbeiten nicht möglich - </text> - <text name="title_loading"> - [DESC]: wird geladen... - </text> - <text name="title_not_worn"> - [DESC]: nicht getragen - </text> - <text name="path"> - In [PATH] - </text> - <text name="not worn instructions"> - Ziehen Sie neue Augen aus dem Inventar auf Ihren Avatar, um diese anzulegen. Sie können aber auch neue Augen erstellen und diese anlegen. - </text> - <text name="no modify instructions"> - Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. - </text> - <text name="Item Action Label" right="100"> - Augen: - </text> - <texture_picker label="Iris" name="Iris" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <button label="Neue Augen" label_selected="Neue Augen" name="Create New"/> - <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> - <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> - <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> - </panel> - <text label="Kleidung" name="clothes_placeholder"> - Kleidung - </text> - <panel label="Hemd" name="Shirt"> - <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> - <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> - <button label="Neues Hemd" label_selected="Neues Hemd" name="Create New"/> - <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> - <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> - <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: bearbeiten nicht möglich - </text> - <text name="title_loading"> - [DESC]: wird geladen... - </text> - <text name="title_not_worn"> - [DESC]: nicht getragen - </text> - <text name="path"> - In [PATH] - </text> - <text name="not worn instructions"> - Ziehen Sie ein neues Hemd aus dem Inventar auf Ihren Avatar, um dieses anzuziehen. Sie können aber auch ein neues Hemd erstellen und dieses anlegen. - </text> - <text name="no modify instructions"> - Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. - </text> - <text name="Item Action Label" right="100"> - Hemd: - </text> - </panel> - <panel label="Hose" name="Pants"> - <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> - <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> - <button label="Neue Hose" label_selected="Neue Hose" name="Create New"/> - <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> - <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> - <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: bearbeiten nicht möglich - </text> - <text name="title_loading"> - [DESC]: wird geladen... - </text> - <text name="title_not_worn"> - [DESC]: nicht getragen - </text> - <text name="path"> - In [PATH] - </text> - <text name="not worn instructions"> - Ziehen Sie eine neue Hose aus dem Inventar auf Ihren Avatar, um diese anzuziehen. Sie können aber auch eine neue erstellen und diese anziehen. - </text> - <text name="no modify instructions"> - Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. - </text> - <text name="Item Action Label" right="100"> - Hose: - </text> - </panel> - <panel label="Schuhe" name="Shoes"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: bearbeiten nicht möglich - </text> - <text name="title_loading"> - [DESC]: wird geladen... - </text> - <text name="title_not_worn"> - [DESC]: nicht getragen - </text> - <text name="path"> - In [PATH] - </text> - <text name="not worn instructions"> - Ziehen Sie neue Schuhe aus dem Inventar auf Ihren Avatar, um diese anzuziehen. Sie können aber auch neue Schuhe erstellen und diese anlegen. - </text> - <button label="Neue Schuhe" label_selected="Neue Schuhe" name="Create New"/> - <text name="no modify instructions"> - Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. - </text> - <text name="Item Action Label" right="100"> - Schuhe: - </text> - <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> - <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> - <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> - <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> - <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> - </panel> - <panel label="Socken" name="Socks"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: bearbeiten nicht möglich - </text> - <text name="title_loading"> - [DESC]: wird geladen... - </text> - <text name="title_not_worn"> - [DESC]: nicht getragen - </text> - <text name="path"> - In [PATH] - </text> - <text name="not worn instructions"> - Ziehen Sie neue Socken aus dem Inventar auf Ihren Avatar, um diese anzuziehen. Sie können aber auch neue erstellen und diese anziehen. - </text> - <button label="Neue Socken" label_selected="Neue Socken" name="Create New"/> - <text name="no modify instructions"> - Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. - </text> - <text name="Item Action Label" right="100"> - Socken: - </text> - <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> - <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> - <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> - <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> - <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> - </panel> - <panel label="Jacke" name="Jacket"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: bearbeiten nicht möglich - </text> - <text name="title_loading"> - [DESC]: wird geladen... - </text> - <text name="title_not_worn"> - [DESC]: nicht getragen - </text> - <text name="path"> - In [PATH] - </text> - <text name="not worn instructions"> - Ziehen Sie eine neue Jacke aus dem Inventar auf Ihren Avatar, um diese anzuziehen. Sie können aber auch eine neue erstellen und diese anziehen. - </text> - <button label="Neue Jacke" label_selected="Neue Jacke" name="Create New"/> - <text name="no modify instructions"> - Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. - </text> - <text name="Item Action Label" right="100"> - Jacke: - </text> - <texture_picker label="Stoff: oben" name="Upper Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <texture_picker label="Stoff: unten" name="Lower Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> - <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> - <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> - <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> - <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> - </panel> - <panel label="Handschuhe" name="Gloves"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: bearbeiten nicht möglich - </text> - <text name="title_loading"> - [DESC]: wird geladen... - </text> - <text name="title_not_worn"> - [DESC]: nicht getragen - </text> - <text name="path"> - In [PATH] - </text> - <text name="not worn instructions"> - Ziehen Sie neue Handschuhe aus dem Inventar auf Ihren Avatar, um diese anzuziehen. Sie können aber auch neue erstellen und diese anziehen. - </text> - <button label="Neue Handschuhe" label_selected="Neue Handschuhe" name="Create New"/> - <text name="no modify instructions"> - Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. - </text> - <text name="Item Action Label" right="100"> - Handschuhe: - </text> - <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> - <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> - <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> - <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> - <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> - </panel> - <panel label="Unterhemd" name="Undershirt"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: bearbeiten nicht möglich - </text> - <text name="title_loading"> - [DESC]: wird geladen... - </text> - <text name="title_not_worn"> - [DESC]: nicht getragen - </text> - <text name="path"> - In [PATH] - </text> - <text name="not worn instructions"> - Ziehen Sie ein neues Unterhemd aus dem Inventar auf Ihren Avatar, um dieses anzuziehen. Sie können aber auch ein neues Unterhemd erstellen und dieses anziehen. - </text> - <button label="Neues Unterhemd" label_selected="Neues Unterhemd" name="Create New"/> - <text name="no modify instructions"> - Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. - </text> - <text name="Item Action Label" right="100"> - Unterhemd: - </text> - <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> - <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> - <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> - <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> - <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> - </panel> - <panel label="Unterhose" name="Underpants"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: bearbeiten nicht möglich - </text> - <text name="title_loading"> - [DESC]: wird geladen... - </text> - <text name="title_not_worn"> - [DESC]: nicht getragen - </text> - <text name="path"> - In [PATH] - </text> - <text name="not worn instructions"> - Ziehen Sie eine neue Unterhose aus dem Inventar auf Ihren Avatar, um diese anzuziehen. Sie können aber auch eine neue erstellen und diese anziehen. - </text> - <button label="Neue Unterhose" label_selected="Neue Unterhose" name="Create New"/> - <text name="no modify instructions"> - Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. - </text> - <text name="Item Action Label" right="100"> - Unterhose: - </text> - <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> - <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> - <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> - <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> - <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> - </panel> - <panel label="Rock" name="Skirt"> - <text name="title"> - [DESC] - </text> - <text name="title_no_modify"> - [DESC]: bearbeiten nicht möglich - </text> - <text name="title_loading"> - [DESC]: wird geladen... - </text> - <text name="title_not_worn"> - [DESC]: nicht getragen - </text> - <text name="path"> - In [PATH] - </text> - <text name="not worn instructions"> - Ziehen Sie einen neuen Rock aus dem Inventar auf Ihren Avatar, um diesen anzuziehen. Sie können aber auch einen neuen Rock erstellen und diesen anziehen. - </text> - <button label="Neuer Rock" label_selected="Neuer Rock" name="Create New"/> - <text name="no modify instructions"> - Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. - </text> - <text name="Item Action Label" right="100"> - Rock: - </text> - <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> - <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> - <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> - <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> - <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> - </panel> - <panel label="Tätowierung" name="Tattoo"> - <text name="title"> - Tätowierung - </text> - <text name="title_no_modify"> - [BESCHR]: bearbeiten nicht möglich - </text> - <text name="title_loading"> - [BESCHR]: wird geladen... - </text> - <text name="title_not_worn"> - [BESCHR]: nicht getragen - </text> - <text name="path"> - Befindet sich in [PATH] - </text> - <text name="not worn instructions"> - Ziehen Sie eine neue Tätowierung aus dem Inventar auf Ihren Avatar, um diese anzulegen. Sie können aber auch eine neue erstellen und diese anlegen. - </text> - <button label="Neue Tätowierung erstellen" label_selected="Neue Tätowierung erstellen" name="Create New"/> - <text name="no modify instructions"> - Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. - </text> - <text name="Item Action Label"> - Tätowierung: - </text> - <texture_picker label="Kopftattoo" name="Head Tattoo" tool_tip="Zum Auswählen eines Bildes hier klicken"/> - <texture_picker label="Obere Tattoos" name="Upper Tattoo" tool_tip="Zum Auswählen eines Bildes hier klicken"/> - <texture_picker label="Untere Tattoos" name="Lower Tattoo" tool_tip="Zum Auswählen eines Bildes hier klicken"/> - <button label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> - <button label="Speichern" label_selected="Speichern" name="Save"/> - <button label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> - <button label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> - </panel> - <panel label="Alpha" name="Alpha"> - <text name="title"> - Alpha - </text> - <text name="title_no_modify"> - [BESCHR]: bearbeiten nicht möglich - </text> - <text name="title_loading"> - [BESCHR]: wird geladen... - </text> - <text name="title_not_worn"> - [BESCHR]: nicht getragen - </text> - <text name="path"> - Befindet sich in [PATH] - </text> - <text name="not worn instructions"> - Sie können eine neue Alpha-Maske anlegen, indem Sie eine von Ihrem Inventar auf Ihren Avatar ziehen. Sie können aber auch eine neue erstellen und diese anlegen. - </text> - <button label="Neue Alpha erstellen" label_selected="Neue Alpha erstellen" name="Create New"/> - <text name="no modify instructions"> - Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. - </text> - <text name="Item Action Label"> - Alpha: - </text> - <texture_picker label="Alpha: Unten" name="Lower Alpha" tool_tip="Zum Auswählen eines Bildes hier klicken"/> - <texture_picker label="Alpha: Oben" name="Upper Alpha" tool_tip="Zum Auswählen eines Bildes hier klicken"/> - <texture_picker label="Kopf: Alpha" name="Head Alpha" tool_tip="Zum Auswählen eines Bildes hier klicken"/> - <texture_picker label="Alpha: Augen" name="Eye Alpha" tool_tip="Zum Auswählen eines Bildes hier klicken"/> - <texture_picker label="Alpha: Haare" name="Hair Alpha" tool_tip="Zum Auswählen eines Bildes hier klicken"/> - <button label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> - <button label="Speichern" label_selected="Speichern" name="Save"/> - <button label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> - <button label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> - </panel> - </tab_container> - <button label="Skriptinfo" label_selected="Skriptinfo" name="script_info" tool_tip="Skripts, die an Ihren Avatar angehängt sind, anzeigen"/> - <button label="Outfit erstellen" label_selected="Outfit erstellen" name="make_outfit_btn"/> - <button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/> - <button label="OK" label_selected="OK" name="Ok"/> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_device_settings.xml b/indra/newview/skins/default/xui/de/floater_device_settings.xml deleted file mode 100644 index 3d7e9c96c1..0000000000 --- a/indra/newview/skins/default/xui/de/floater_device_settings.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_device_settings" title="EINSTELLUNGEN FÜR VOICE-CHAT"/> diff --git a/indra/newview/skins/default/xui/de/floater_first_time_tip.xml b/indra/newview/skins/default/xui/de/floater_first_time_tip.xml deleted file mode 100644 index 9546cc2c42..0000000000 --- a/indra/newview/skins/default/xui/de/floater_first_time_tip.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="set_name_in_the_cladd"> - <check_box label="Turn off Quick Tips" name="DontShowFirstTimeTip_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_im.xml b/indra/newview/skins/default/xui/de/floater_im.xml deleted file mode 100644 index 8ae8f120cf..0000000000 --- a/indra/newview/skins/default/xui/de/floater_im.xml +++ /dev/null @@ -1,46 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<multi_floater name="im_floater" title="Instant Message"> - <string name="only_user_message"> - Sie sind der einzige Einwohner in dieser Sitzung. - </string> - <string name="offline_message"> - [FIRST] [LAST] ist offline. - </string> - <string name="invite_message"> - Klicken Sie auf [BUTTON NAME], um eine Verbindung zu diesem Voice-Chat herzustellen. - </string> - <string name="muted_message"> - Sie haben diesen Einwohner ignoriert. Wenn Sie eine Nachricht senden, wird dieser freigeschaltet. - </string> - <string name="generic_request_error"> - Fehler bei Anfrage, bitte versuchen Sie es später. - </string> - <string name="insufficient_perms_error"> - Sie sind dazu nicht berechtigt. - </string> - <string name="session_does_not_exist_error"> - Die Sitzung ist abgelaufen - </string> - <string name="no_ability_error"> - Sie besitzen diese Fähigkeit nicht. - </string> - <string name="not_a_mod_error"> - Sie sind kein Sitzungsmoderator. - </string> - <string name="muted_error"> - Ein Gruppenmoderator hat Ihren Text-Chat deaktiviert. - </string> - <!-- ALL of the event strings should have [RECIPIENT] in them --> - <string name="add_session_event"> - Es konnten keine Einwohner zur Chat-Sitzung mit [RECIPIENT] hinzugefügt werden. - </string> - <string name="message_session_event"> - Ihre Nachricht konnte nicht an die Chat-Sitzung mit [RECIPIENT] gesendet werden. - </string> - <string name="removed_from_group"> - Sie wurden von der Gruppe ausgeschlossen. - </string> - <string name="close_on_no_ability"> - Sie haben nicht mehr die Berechtigung an der Chat-Sitzung teilzunehmen. - </string> -</multi_floater> diff --git a/indra/newview/skins/default/xui/de/floater_im_session.xml b/indra/newview/skins/default/xui/de/floater_im_session.xml index c69bb600ea..abaf275651 100644 --- a/indra/newview/skins/default/xui/de/floater_im_session.xml +++ b/indra/newview/skins/default/xui/de/floater_im_session.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="panel_im"> <layout_stack name="im_panels"> - <layout_panel label="IM Steuerkonsole" name="panel_im_control_panel"/> <layout_panel> <line_editor label="An" name="chat_editor"/> </layout_panel> diff --git a/indra/newview/skins/default/xui/de/floater_my_friends.xml b/indra/newview/skins/default/xui/de/floater_my_friends.xml deleted file mode 100644 index 61cb0d5c14..0000000000 --- a/indra/newview/skins/default/xui/de/floater_my_friends.xml +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_my_friends" title="KONTAKTE"> - <tab_container name="friends_and_groups"> - <panel label="Freunde" name="friends_panel"/> - <panel label="Gruppen" name="groups_panel"/> - </tab_container> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/de/floater_outfit_save_as.xml deleted file mode 100644 index 8c110e5516..0000000000 --- a/indra/newview/skins/default/xui/de/floater_outfit_save_as.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="modal container" title="Outfit speichern"> - <button label="Speichern" label_selected="Speichern" name="Save"/> - <button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/> - <text name="Save item as:"> - Meine aktuelle Kleidung -als neues Outfit speichern: - </text> - <line_editor name="name ed"> - [DESC] (neu) - </line_editor> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_preview_classified.xml b/indra/newview/skins/default/xui/de/floater_preview_classified.xml deleted file mode 100644 index 401758769d..0000000000 --- a/indra/newview/skins/default/xui/de/floater_preview_classified.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="classified_preview" title="INFORMATIONEN ÜBER ANZEIGE"> - <floater.string name="Title"> - Anzeige: [NAME] - </floater.string> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_preview_event.xml b/indra/newview/skins/default/xui/de/floater_preview_event.xml deleted file mode 100644 index 7e46bbab54..0000000000 --- a/indra/newview/skins/default/xui/de/floater_preview_event.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="event_preview" title="EVENT-INFORMATION"> - <floater.string name="Title"> - Veranstaltung: [NAME] - </floater.string> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_preview_gesture_info.xml b/indra/newview/skins/default/xui/de/floater_preview_gesture_info.xml deleted file mode 100644 index 0d0d28f96f..0000000000 --- a/indra/newview/skins/default/xui/de/floater_preview_gesture_info.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Gesture" title="GESTE - SCHNELLTASTE"/> diff --git a/indra/newview/skins/default/xui/de/floater_preview_gesture_shortcut.xml b/indra/newview/skins/default/xui/de/floater_preview_gesture_shortcut.xml deleted file mode 100644 index 0b5df13395..0000000000 --- a/indra/newview/skins/default/xui/de/floater_preview_gesture_shortcut.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Gesture" title="GESTE - SCHNELLTASTE"> - <text name="trigger_label"> - Chat: - </text> - <text name="key_label"> - Tastatur: - </text> - <combo_box label="Keiner" name="modifier_combo"/> - <combo_box label="Keiner" name="key_combo"/> - <text name="replace_text" tool_tip="Ersetzt den Auslösertext mit diesem Text. Wenn Sie zum Beispiel den Auslöser „hallo“ durch „wie geht's“ ersetzen, erscheint im Chat anstelle von „Ich wollte nur hallo sagen“ der Text „Ich wollte nur wie geht's sagen“ und die zugehörige Geste wird abgespielt."> - Ersetzen: - </text> - <line_editor name="replace_editor" tool_tip="Ersetzt den Auslösertext mit diesem Text. Wenn Sie zum Beispiel den Auslöser „hallo“ durch „wie geht's“ ersetzen, erscheint im Chat anstelle von „Ich wollte nur hallo sagen“ der Text „Ich wollte nur wie geht's sagen“ und die zugehörige Geste wird abgespielt."/> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_preview_gesture_steps.xml b/indra/newview/skins/default/xui/de/floater_preview_gesture_steps.xml deleted file mode 100644 index 0d0d28f96f..0000000000 --- a/indra/newview/skins/default/xui/de/floater_preview_gesture_steps.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Gesture" title="GESTE - SCHNELLTASTE"/> diff --git a/indra/newview/skins/default/xui/de/floater_statistics.xml b/indra/newview/skins/default/xui/de/floater_statistics.xml deleted file mode 100644 index 72a87a9566..0000000000 --- a/indra/newview/skins/default/xui/de/floater_statistics.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="stats floater" title="STATISTIKEN"/> diff --git a/indra/newview/skins/default/xui/de/floater_tools.xml b/indra/newview/skins/default/xui/de/floater_tools.xml index 12ae9898c3..3de3718f66 100644 --- a/indra/newview/skins/default/xui/de/floater_tools.xml +++ b/indra/newview/skins/default/xui/de/floater_tools.xml @@ -71,8 +71,8 @@ <text label="Beide Seiten dehnen" name="checkbox uniform label"> Beide Seiten dehnen </text> - <check_box initial_value="true" label="Texturen dehnen" name="checkbox stretch textures"/> - <check_box initial_value="true" label="An Raster ausrichten" name="checkbox snap to grid" top_pad="10"/> + <check_box initial_value="true" label="Texturen dehnen" name="checkbox stretch textures" top_pad="-5"/> + <check_box initial_value="true" label="An Raster ausrichten" name="checkbox snap to grid" top_pad="15"/> <combo_box name="combobox grid mode" tool_tip="Wählen Sie ein Rasterlineal zum Positionieren des Objekts aus."> <combo_box.item label="Globales Raster" name="World"/> <combo_box.item label="Lokales Raster" name="Local"/> diff --git a/indra/newview/skins/default/xui/de/floater_voice_controls.xml b/indra/newview/skins/default/xui/de/floater_voice_controls.xml index 07b7689cd0..22f2fd93ab 100644 --- a/indra/newview/skins/default/xui/de/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/de/floater_voice_controls.xml @@ -19,10 +19,12 @@ <layout_panel name="my_panel"> <text name="user_text" value="Mein Avatar:"/> </layout_panel> - <layout_stack name="voice_effect_and_leave_call_stack"> - <layout_panel name="leave_call_btn_panel"> - <button label="Anruf beenden" name="leave_call_btn"/> - </layout_panel> - </layout_stack> + <layout_panel name="leave_call_panel"> + <layout_stack name="voice_effect_and_leave_call_stack"> + <layout_panel name="leave_call_btn_panel"> + <button label="Anruf beenden" name="leave_call_btn"/> + </layout_panel> + </layout_stack> + </layout_panel> </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/de/floater_wearable_save_as.xml b/indra/newview/skins/default/xui/de/floater_wearable_save_as.xml deleted file mode 100644 index f9b3552e8b..0000000000 --- a/indra/newview/skins/default/xui/de/floater_wearable_save_as.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="modal container" title=" "> - <button label="Speichern" label_selected="Speichern" name="Save"/> - <button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/> - <text name="Save item as:"> - Objekt in meinem Inventar speichern als: - </text> - <line_editor name="name ed"> - Neu [DESC] - </line_editor> -</floater> diff --git a/indra/newview/skins/default/xui/de/menu_avatar_self.xml b/indra/newview/skins/default/xui/de/menu_avatar_self.xml index 160703bcf3..c74f646abb 100644 --- a/indra/newview/skins/default/xui/de/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/de/menu_avatar_self.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Self Pie"> <menu_item_call label="Aufstehen" name="Stand Up"/> - <context_menu label="Ausziehen ▶" name="Take Off >"> - <context_menu label="Kleidung ▶" name="Clothes >"> + <context_menu label="Ausziehen" name="Take Off >"> + <context_menu label="Kleidung" name="Clothes >"> <menu_item_call label="Hemd" name="Shirt"/> <menu_item_call label="Hose" name="Pants"/> <menu_item_call label="Rock" name="Skirt"/> @@ -16,8 +16,8 @@ <menu_item_call label="Alpha" name="Self Alpha"/> <menu_item_call label="Alle Kleider" name="All Clothes"/> </context_menu> - <context_menu label="HUD ▶" name="Object Detach HUD"/> - <context_menu label="Abnehmen ▶" name="Object Detach"/> + <context_menu label="HUD" name="Object Detach HUD"/> + <context_menu label="Abnehmen" name="Object Detach"/> <menu_item_call label="Alles abnehmen" name="Detach All"/> </context_menu> <menu_item_call label="Outfit ändern" name="Chenge Outfit"/> diff --git a/indra/newview/skins/default/xui/de/menu_object.xml b/indra/newview/skins/default/xui/de/menu_object.xml index 756b606d65..5003939fb6 100644 --- a/indra/newview/skins/default/xui/de/menu_object.xml +++ b/indra/newview/skins/default/xui/de/menu_object.xml @@ -10,12 +10,12 @@ <menu_item_call label="Aufstehen" name="Object Stand Up"/> <menu_item_call label="Objektprofil" name="Object Inspect"/> <menu_item_call label="Hineinzoomen" name="Zoom In"/> - <context_menu label="Anziehen ▶" name="Put On"> + <context_menu label="Anziehen" name="Put On"> <menu_item_call label="Anziehen" name="Wear"/> - <context_menu label="Anhängen ▶" name="Object Attach"/> - <context_menu label="HUD anhängen ▶" name="Object Attach HUD"/> + <context_menu label="Anhängen" name="Object Attach"/> + <context_menu label="HUD anhängen" name="Object Attach HUD"/> </context_menu> - <context_menu label="Entfernen ▶" name="Remove"> + <context_menu label="Entfernen" name="Remove"> <menu_item_call label="Missbrauch melden" name="Report Abuse..."/> <menu_item_call label="Ignorieren" name="Object Mute"/> <menu_item_call label="Zurückgeben" name="Return..."/> diff --git a/indra/newview/skins/default/xui/de/menu_participant_list.xml b/indra/newview/skins/default/xui/de/menu_participant_list.xml index d5281f0cb2..160f2f97be 100644 --- a/indra/newview/skins/default/xui/de/menu_participant_list.xml +++ b/indra/newview/skins/default/xui/de/menu_participant_list.xml @@ -11,7 +11,7 @@ <menu_item_check label="Symbole für Personen anzeigen" name="View Icons"/> <menu_item_check label="Voice ignorieren" name="Block/Unblock"/> <menu_item_check label="Text ignorieren" name="MuteText"/> - <context_menu label="Moderator-Optionen >" name="Moderator Options"> + <context_menu label="Moderator-Optionen" name="Moderator Options"> <menu_item_check label="Text-Chat zulassen" name="AllowTextChat"/> <menu_item_call label="Diesen Teilnehmer stummschalten" name="ModerateVoiceMuteSelected"/> <menu_item_call label="Stummschaltung für diesen Teilnehmer aufheben" name="ModerateVoiceUnMuteSelected"/> diff --git a/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml index 6c8fc69fc0..283e454a06 100644 --- a/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml +++ b/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml @@ -5,8 +5,8 @@ <menu_item_call label="Hinzufügen" name="wear_add"/> <menu_item_call label="Ausziehen / Abnehmen" name="take_off_or_detach"/> <menu_item_call label="Abnehmen" name="detach"/> - <context_menu label="Anhängen an ▶" name="wearable_attach_to"/> - <context_menu label="An HUD hängen ▶" name="wearable_attach_to_hud"/> + <context_menu label="Anhängen an" name="wearable_attach_to"/> + <context_menu label="An HUD hängen" name="wearable_attach_to_hud"/> <menu_item_call label="Ausziehen" name="take_off"/> <menu_item_call label="Bearbeiten" name="edit"/> <menu_item_call label="Objektprofil" name="object_profile"/> diff --git a/indra/newview/skins/default/xui/de/panel_audio_device.xml b/indra/newview/skins/default/xui/de/panel_audio_device.xml deleted file mode 100644 index 6ecd1f0241..0000000000 --- a/indra/newview/skins/default/xui/de/panel_audio_device.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="device_settings"> - <text name="Audio Devices"> - Audiogeräte - </text> - <text name="Output device (speakers):"> - Ausgabegerät (Lautsprecher): - </text> - <text name="Input device (microphone):"> - Eingabegerät (Mikro): - </text> - <text name="Input level:"> - Eingangslautstärke - </text> - <text_editor name="voice_intro_text1"> - Mit dem Regler steuern Sie, wie laut andere Einwohner Sie hören. Testen Sie die Eingangslautstärke, indem Sie in das Mikro sprechen. - </text_editor> - <volume_slider name="mic_volume_slider" tool_tip="Ändern Sie die Lautstärke mit dem Regler" /> - <text name="wait_text"> - Bitte warten - </text> - <text name="default_text"> - Standard - </text> -</panel> diff --git a/indra/newview/skins/default/xui/de/panel_friends.xml b/indra/newview/skins/default/xui/de/panel_friends.xml deleted file mode 100644 index 50013a2b24..0000000000 --- a/indra/newview/skins/default/xui/de/panel_friends.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="friends"> - <string name="Multiple"> - Mehrere Freunde - </string> - <scroll_list name="friend_list" tool_tip="Halten Sie die Tasten „Umschalt“ oder „Strg“ gedrückt, um durch Klicken mehrere Freunde auszuwählen."> - <column name="icon_online_status" tool_tip="Online-Status"/> - <column label="Name" name="friend_name" tool_tip="Name"/> - <column name="icon_visible_online" tool_tip="Freund kann sehen, wenn Sie online sind"/> - <column name="icon_visible_map" tool_tip="Freund kann Sie auf der Karte finden"/> - <column name="icon_edit_mine" tool_tip="Freunde können Objekte bearbeiten, löschen und an sich nehmen"/> - <column name="icon_edit_theirs" tool_tip="Sie können die Objekte dieses Freunds bearbeiten"/> - </scroll_list> - <panel name="rights_container"> - <text name="friend_name_label"> - Wählen Sie den/die Freund(e) aus, dessen/deren Rechte Sie ändern möchten... - </text> - <check_box label="Kann meinen Online-Status sehen" name="online_status_cb" tool_tip="Festlegen, ob dieser Freund meinen Online-Status auf seiner Freundesliste oder Visitenkarte einsehen kann"/> - <check_box label="Kann mich auf der Weltkarte sehen" name="map_status_cb" tool_tip="Festlegen, ob dieser Freund auf seiner Karte meinen Standort sehen kann"/> - <check_box label="Kann meine Objekte verändern" name="modify_status_cb" tool_tip="Festlegen, ob dieser Freund meine Objekte verändern kann"/> - <text name="process_rights_label"> - Rechte werden geändert... - </text> - </panel> - <button label="IM/Anruf" name="im_btn" tool_tip="Beginnt eine Instant Message-Sitzung"/> - <button label="Profil" name="profile_btn" tool_tip="Bilder, Gruppen und andere Informationen anzeigen"/> - <button label="Teleportieren" name="offer_teleport_btn" tool_tip="Bieten Sie diesem Freund einen Teleport an Ihre Position an"/> - <button label="Bezahlen" name="pay_btn" tool_tip="Diesem Freund Linden-Dollar (L$) geben"/> - <button label="Entfernen" name="remove_btn" tool_tip="Diese Person von Ihrer Freundesliste entfernen"/> - <button label="Hinzufügen" name="add_btn" tool_tip="Bieten Sie einem Einwohner die Freundschaft an"/> -</panel> diff --git a/indra/newview/skins/default/xui/de/panel_groups.xml b/indra/newview/skins/default/xui/de/panel_groups.xml deleted file mode 100644 index f857a6c7ac..0000000000 --- a/indra/newview/skins/default/xui/de/panel_groups.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="groups"> - <text name="groupdesc" width="300"> - Die derzeit aktive Gruppe ist fett hervorgehoben. - </text> - <text name="groupcount" width="360"> - Sie sind Mitglied bei [COUNT] Gruppen (von max. [MAX]). - </text> - <button label="IM/Anruf" name="IM" tool_tip="Beginnt eine Instant Message-Sitzung" /> - <button label="Info" name="Info" /> - <button label="Aktivieren" name="Activate" /> - <button label="Verlassen" name="Leave" /> - <button label="Erstellen..." name="Create" /> - <button label="Suchen..." name="Search..." /> -</panel> diff --git a/indra/newview/skins/default/xui/de/panel_nearby_chat.xml b/indra/newview/skins/default/xui/de/panel_nearby_chat.xml deleted file mode 100644 index 3f4f5a71b5..0000000000 --- a/indra/newview/skins/default/xui/de/panel_nearby_chat.xml +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- All our XML is utf-8 encoded. --> -<panel name="nearby_chat"> - <panel name="chat_caption"> - <text name="sender_name" width="200"> - CHAT IN DER NÄHE - </text> - </panel> -</panel> diff --git a/indra/newview/skins/default/xui/de/panel_notifications_channel.xml b/indra/newview/skins/default/xui/de/panel_notifications_channel.xml index e2166f7baf..35bd76ce70 100644 --- a/indra/newview/skins/default/xui/de/panel_notifications_channel.xml +++ b/indra/newview/skins/default/xui/de/panel_notifications_channel.xml @@ -1,15 +1,19 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="notifications_panel"> <layout_stack name="stack1"> - <scroll_list name="notifications_list"> - <column label="Name" name="name"/> - <column label="Inhalt" name="content"/> - <column label="Datum" name="date"/> - </scroll_list> - <scroll_list name="notification_rejects_list"> - <column label="Name" name="name"/> - <column label="Inhalt" name="content"/> - <column label="Datum" name="date"/> - </scroll_list> + <layout_panel name="notifications_list_panel" > + <scroll_list name="notifications_list"> + <column label="Name" name="name"/> + <column label="Inhalt" name="content"/> + <column label="Datum" name="date"/> + </scroll_list> + </layout_panel> + <layout_panel name="rejects_list_panel" > + <scroll_list name="notification_rejects_list"> + <column label="Name" name="name"/> + <column label="Inhalt" name="content"/> + <column label="Datum" name="date"/> + </scroll_list> + </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_online_status.xml b/indra/newview/skins/default/xui/de/panel_online_status.xml deleted file mode 100644 index 7c7448c061..0000000000 --- a/indra/newview/skins/default/xui/de/panel_online_status.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Freunde_online_Status" name="friend_online_status"/> diff --git a/indra/newview/skins/default/xui/de/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/de/panel_prim_media_controls.xml index 0a19483f8b..c85f2762b1 100644 --- a/indra/newview/skins/default/xui/de/panel_prim_media_controls.xml +++ b/indra/newview/skins/default/xui/de/panel_prim_media_controls.xml @@ -7,9 +7,9 @@ 0.2 </string> <layout_stack name="progress_indicator_area"> - <panel name="media_progress_indicator"> + <layout_panel name="media_progress_indicator"> <progress_bar name="media_progress_bar" tool_tip="Medien werden geladen"/> - </panel> + </layout_panel> </layout_stack> <layout_stack name="media_controls"> <layout_panel name="back"> diff --git a/indra/newview/skins/default/xui/de/panel_region_general_layout.xml b/indra/newview/skins/default/xui/de/panel_region_general_layout.xml deleted file mode 100644 index 09142ada6f..0000000000 --- a/indra/newview/skins/default/xui/de/panel_region_general_layout.xml +++ /dev/null @@ -1,43 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Region" name="General"> - <text name="region_text_lbl"> - Region: - </text> - <text name="region_text"> - unbekannt - </text> - <text name="version_channel_text_lbl"> - Version: - </text> - <text name="version_channel_text"> - unbekannt - </text> - <text name="region_type_lbl"> - Typ: - </text> - <text name="region_type"> - unbekannt - </text> - <check_box label="Terraformen blockieren" name="block_terraform_check"/> - <check_box label="Fliegen blockieren" name="block_fly_check"/> - <check_box label="Schaden zulassen" name="allow_damage_check"/> - <check_box label="Stoßen beschränken" name="restrict_pushobject"/> - <check_box label="Landwiederverkauf zulassen" name="allow_land_resell_check"/> - <check_box label="Zusammenlegen/Teilen von Land zulassen" name="allow_parcel_changes_check"/> - <check_box label="Landanzeige in Suche blockieren" name="block_parcel_search_check" tool_tip="Diese Region und ihre Parzellen in Suchergebnissen anzeigen"/> - <spinner label="Avatar-Limit" name="agent_limit_spin"/> - <spinner label="Objektbonus" name="object_bonus_spin"/> - <text label="Alterseinstufung" name="access_text"> - Einstufung: - </text> - <combo_box label="Moderat" name="access_combo"> - <combo_box.item label="Adult" name="Adult"/> - <combo_box.item label="Moderat" name="Mature"/> - <combo_box.item label="Allgemein" name="PG"/> - </combo_box> - <button label="Übernehmen" name="apply_btn"/> - <button label="Einen Einwohner nach Hause teleportieren..." name="kick_btn"/> - <button label="Alle Einwohner nach Hause teleportieren..." name="kick_all_btn"/> - <button label="Nachricht an Region senden..." name="im_btn"/> - <button label="Telehub verwalten..." name="manage_telehub_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index bf7d2ef3b3..1adc4e3db1 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -1147,6 +1147,9 @@ <string name="InvFolder Favorite"> Favoriten </string> + <string name="InvFolder favorite"> + Favoriten + </string> <string name="InvFolder Current Outfit"> Aktuelles Outfit </string> diff --git a/indra/newview/skins/default/xui/en/alert_check_box.xml b/indra/newview/skins/default/xui/en/alert_check_box.xml index 9f1bdb5193..5535a5dc2a 100644 --- a/indra/newview/skins/default/xui/en/alert_check_box.xml +++ b/indra/newview/skins/default/xui/en/alert_check_box.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <check_box - text_enabled_color="LabelTextColor" - text_disabled_color="LabelDisabledColor" + label_text.text_color="LabelTextColor" + label_text.text_readonly_color="LabelDisabledColor" font="SansSerif" follows="left|top" name="check"/>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/favorites_bar_button.xml b/indra/newview/skins/default/xui/en/favorites_bar_button.xml index b365040c20..e7dd62eb64 100644 --- a/indra/newview/skins/default/xui/en/favorites_bar_button.xml +++ b/indra/newview/skins/default/xui/en/favorites_bar_button.xml @@ -22,6 +22,6 @@ pad_right="9" scale_image="true" tab_stop="false" - top="0" + bottom="0" use_ellipses="true" width="140" /> diff --git a/indra/newview/skins/default/xui/en/floater_aaa.xml b/indra/newview/skins/default/xui/en/floater_aaa.xml index cae6146880..930bbaa8cb 100644 --- a/indra/newview/skins/default/xui/en/floater_aaa.xml +++ b/indra/newview/skins/default/xui/en/floater_aaa.xml @@ -20,7 +20,7 @@ <string name="nudge_parabuild" translate="false">Nudge 1</string> <string name="test_the_vlt">This string CHANGE2 is extracted.</string> <string name="testing_eli">Just a test. changes.</string> - <chat_history + <text_editor parse_urls="true" bg_readonly_color="ChatHistoryBgColor" bg_writeable_color="ChatHistoryBgColor" @@ -32,26 +32,51 @@ layout="topleft" height="260" name="chat_history" + max_length="200000" parse_highlights="true" text_color="ChatHistoryTextColor" text_readonly_color="ChatHistoryTextColor" translate="false" + track_end="true" + wrap="true" width="320"> -Really long line that is long enough to wrap once with jyg descenders. -Really long line that is long enough to wrap once with jyg descenders. -Really long line that is long enough to wrap once with jyg descenders. -Really long line that is long enough to wrap once with jyg descenders. -Really long line that is long enough to wrap once with jyg descenders. -Really long line that is long enough to wrap once with jyg descenders. -Really long line that is long enough to wrap once with jyg descenders. -Really long line that is long enough to wrap once with jyg descenders. -Really long line that is long enough to wrap once with jyg descenders. -Really long line that is long enough to wrap once with jyg descenders. -Really long line that is long enough to wrap once with jyg descenders. -Really long line that is long enough to wrap once with jyg descenders. -Really long line that is long enough to wrap once with jyg descenders. -Really long line that is long enough to wrap once with jyg descenders. -Really long line that is long enough to wrap once with jyg descenders. -Really long line that is long enough to wrap once with jyg descenders. - </chat_history> + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + Really long line that is long enough to wrap once with jyg descenders. + </text_editor> </floater> 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 99bf3e6bc1..e6f11cac60 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1044,7 +1044,7 @@ Leyla Linden </text> left="28" name="Selected / sat upon:" top_pad="5" - width="176"> + width="230"> Selected / sat upon: </text> <text @@ -1053,7 +1053,7 @@ Leyla Linden </text> follows="left|top" height="23" layout="topleft" - left_delta="172" + left_delta="220" name="selected_objects_text" top_delta="0" width="48"> @@ -1143,11 +1143,11 @@ Leyla Linden </text> <name_list.columns label="Count" name="count" - width="60" /> + width="67" /> <name_list.columns label="Most Recent" name="mostrecent" - width="170" /> + width="163" /> </name_list> </panel> <panel diff --git a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml index d007ceff98..457142f11c 100644 --- a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml +++ b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml @@ -7,7 +7,7 @@ name="floaterbulkperms" help_topic="floaterbulkperms" title="EDIT CONTENT PERMISSIONS" - width="270"> + width="300"> <floater.string name="nothing_to_modify_text"> Selection contains no editable contents. @@ -164,7 +164,7 @@ label="√ All" left="180" top="26" - width="70"> + width="115"> <button.commit_callback function="BulkPermission.CheckAll" /> </button> @@ -176,7 +176,7 @@ layout="topleft" top_pad="8" name="check_none" - width="70" > + width="115" > <button.commit_callback function="BulkPermission.UncheckAll"/> </button> @@ -199,10 +199,11 @@ length="1" follows="left|top" layout="topleft" - height="16" + height="28" left="10" name="GroupLabel" - width="88"> + width="92" + word_wrap="true"> Group: </text> <check_box @@ -212,17 +213,18 @@ layout="topleft" top_pad="0" name="share_with_group" - width="88" /> + width="92" /> <text type="string" length="1" follows="left|top" - height="16" + height="28" layout="topleft" name="AnyoneLabel" - left="100" + left="104" top="110" - width="88"> + width="92" + word_wrap="true"> Anyone: </text> <check_box @@ -232,17 +234,18 @@ layout="topleft" top_pad="0" name="everyone_copy" - width="88" /> + width="92" /> <text type="string" length="1" follows="left|top" - height="16" + height="28" layout="topleft" name="NextOwnerLabel" top="110" - left="185" - width="88"> + left="189" + width="92" + word_wrap="true"> Next owner: </text> <check_box @@ -252,7 +255,7 @@ layout="topleft" name="next_owner_modify" top_pad="0" - width="83" /> + width="92" /> <check_box control_name="BulkChangeNextOwnerCopy" height="16" @@ -260,7 +263,7 @@ layout="topleft" top_pad="0" name="next_owner_copy" - width="88"> + width="92"> <check_box.commit_callback function="BulkPermission.CommitCopy"/> </check_box> @@ -274,7 +277,7 @@ layout="topleft" name="next_owner_transfer" tool_tip="Next owner can give away or resell this object" - width="106" /> + width="92" /> <scroll_list enabled="false" follows="all" @@ -289,7 +292,7 @@ height="23" label="OK" layout="topleft" - left="65" + left="95" name="apply" top_pad="10" width="90"> diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml index 4b990fa566..b9c415633f 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml @@ -16,6 +16,7 @@ https://quick-buy.secondlife.com/[LANGUAGE]/display/?sa=[SPECIFIC_AMOUNT]&sum=[SUM]&msg=[MSG]&bal=[BAL] </floater.string> <web_browser + trusted_content="true" follows="all" layout="topleft" left="1" diff --git a/indra/newview/skins/default/xui/en/floater_customize.xml b/indra/newview/skins/default/xui/en/floater_customize.xml deleted file mode 100644 index 01bced81d0..0000000000 --- a/indra/newview/skins/default/xui/en/floater_customize.xml +++ /dev/null @@ -1,3389 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - can_minimize="false" - follows="left|top" - height="583" - layout="topleft" - left_delta="-3" - name="floater customize" - help_topic="floater_customize" - save_rect="true" - title="APPEARANCE" - top_delta="-185" - width="600"> - <tab_container - height="517" - layout="topleft" - left="10" - name="customize tab container" - tab_min_width="96" - tab_position="left" - tab_height="50" - top="26" - width="580"> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="5" - name="body_parts_placeholder" - font="SansSerifSmallBold" - top="10" - width="100"> - Body Parts - </text> - <placeholder /> - <panel - border="false" - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|top|right|bottom" - height="508" - label="Shape" - layout="topleft" - name="Shape" - help_topic="customize_shape_tab" - width="400"> - <icon - follows="top|right" - height="18" - image_name="Lock" - layout="topleft" - left="315" - mouse_opaque="true" - name="square" - top="4" - width="18" /> - <icon - height="16" - top="10" - left="10" - layout="topleft" - mouse_opaque="true" - width="16" /> - <button - follows="left|top" - height="23" - label="Create New Shape" - label_selected="Create New Shape" - layout="topleft" - left="10" - name="Create New" - top="104" - width="160" /> - <button - follows="left|top" - height="23" - label="Body" - label_selected="Body" - layout="topleft" - left="10" - name="Body" - top="63" - width="82" /> - <button - follows="left|top" - height="23" - label="Head" - label_selected="Head" - layout="topleft" - left_delta="0" - name="Head" - top_pad="4" - width="82" /> - <button - follows="left|top" - height="23" - label="Eyes" - label_selected="Eyes" - layout="topleft" - left_delta="0" - name="Eyes" - top_pad="4" - width="82" /> - <button - follows="left|top" - height="23" - label="Ears" - label_selected="Ears" - layout="topleft" - left_delta="0" - name="Ears" - top_pad="4" - width="82" /> - <button - follows="left|top" - height="23" - label="Nose" - label_selected="Nose" - layout="topleft" - left_delta="0" - name="Nose" - top_pad="4" - width="82" /> - <button - follows="left|top" - height="23" - label="Mouth" - label_selected="Mouth" - layout="topleft" - left_delta="0" - name="Mouth" - top_pad="4" - width="82" /> - <button - follows="left|top" - height="23" - label="Chin" - label_selected="Chin" - layout="topleft" - left_delta="0" - name="Chin" - top_pad="4" - width="82" /> - <button - follows="left|top" - height="23" - label="Torso" - label_selected="Torso" - layout="topleft" - left_delta="0" - name="Torso" - top_pad="4" - width="82" /> - <button - follows="left|top" - height="23" - label="Legs" - label_selected="Legs" - layout="topleft" - left_delta="0" - name="Legs" - top_pad="4" - width="82" /> - <radio_group - control_name="AvatarSex" - height="34" - layout="topleft" - name="sex radio" - top_pad="10" - width="82"> - <radio_item - height="16" - label="Female" - layout="topleft" - name="radio" - value="0" - width="82" /> - <radio_item - height="16" - label="Male" - layout="topleft" - name="radio2" - value="1" - width="82" /> - </radio_group> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title" - top="10" - width="355"> - [DESC] - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_no_modify" - top="10" - width="355"> - [DESC]: cannot modify - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_loading" - top="10" - width="355"> - [DESC]: loading... - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_not_worn" - top="10" - width="355"> - [DESC]: not worn - </text> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="10" - name="path" - top="36" - width="373"> - Located in [PATH] - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="not worn instructions" - top="31" - word_wrap="true" - width="373"> - Put on a new shape by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="no modify instructions" - top="31" - word_wrap="true" - width="373"> - You do not have permission to modify this wearable. - </text> - <text - type="string" - length="1" - top="488" - follows="left|top" - font="SansSerif" - halign="right" - height="23" - layout="topleft" - left="10" - name="Item Action Label" - width="130"> - Shape: - </text> - <button - follows="left|bottom" - height="23" - label="Save" - label_selected="Save" - layout="topleft" - name="Save" - left_pad="2" - top="477" - width="82" /> - <button - follows="left|bottom" - height="23" - label="Save As..." - label_selected="Save As..." - layout="topleft" - name="Save As" - top="477" - left_pad="3" - width="115" /> - <button - follows="left|bottom" - height="23" - label="Revert" - label_selected="Revert" - layout="topleft" - left_pad="3" - name="Revert" - top="477" - width="120" /> - </panel> - <panel - border="false" - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|top|right|bottom" - height="508" - label="Skin" - layout="topleft" - name="Skin" - help_topic="customize_skin_tab" - width="400"> - <icon - follows="top|right" - height="18" - image_name="Lock" - layout="topleft" - left="315" - mouse_opaque="true" - name="square" - top="4" - width="18" /> - <icon - height="16" - top="10" - left="10" - layout="topleft" - mouse_opaque="true" - width="16" /> - <button - follows="left|top" - height="23" - label="Create New Skin" - label_selected="Create New Skin" - layout="topleft" - left_delta="0" - name="Create New" - top_delta="-249" - width="160" /> - <button - follows="left|top" - height="23" - label="Skin Color" - label_selected="Skin Color" - layout="topleft" - left="10" - name="Skin Color" - top="63" - width="82" /> - <button - follows="left|top" - height="23" - label="Face Detail" - label_selected="Face Detail" - layout="topleft" - left_delta="0" - name="Face Detail" - top_pad="4" - width="82" /> - <button - follows="left|top" - height="23" - label="Makeup" - label_selected="Makeup" - layout="topleft" - left_delta="0" - name="Makeup" - top_pad="4" - width="82" /> - <button - follows="left|top" - height="23" - label="Body Detail" - label_selected="Body Detail" - layout="topleft" - left_delta="0" - name="Body Detail" - top_pad="4" - width="82" /> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title" - top="10" - width="355"> - [DESC] - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_no_modify" - top="10" - width="355"> - [DESC]: cannot modify - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_loading" - top="10" - width="355"> - [DESC]: loading... - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_not_worn" - top="10" - width="355"> - [DESC]: not worn - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="14" - layout="topleft" - left="10" - name="path" - top="36" - width="373"> - Located in [PATH] - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="not worn instructions" - top="31" - word_wrap="true" - width="373"> - Put on a new skin by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="no modify instructions" - top="31" - word_wrap="true" - width="373"> - You do not have permission to modify this wearable. - </text> - <texture_picker - allow_no_texture="true" - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Head Tattoos" - layout="topleft" - left="10" - name="Head Tattoos" - tool_tip="Click to choose a picture" - top="176" - width="82" /> - <texture_picker - allow_no_texture="true" - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Upper Tattoos" - layout="topleft" - left_delta="0" - name="Upper Tattoos" - tool_tip="Click to choose a picture" - top_delta="102" - width="82" /> - <texture_picker - allow_no_texture="true" - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Lower Tattoos" - layout="topleft" - left_delta="0" - name="Lower Tattoos" - tool_tip="Click to choose a picture" - top_delta="102" - width="82" /> - <text - type="string" - length="1" - top="488" - follows="left|top" - font="SansSerif" - halign="right" - height="23" - layout="topleft" - left="10" - name="Item Action Label" - width="130"> - Skin: - </text> - <button - follows="left|bottom" - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left_pad="2" - name="Save" - top="477" - width="82" /> - <button - follows="left|bottom" - height="23" - label="Save As..." - label_selected="Save As..." - layout="topleft" - left_pad="3" - name="Save As" - top="477" - width="115" /> - <button - follows="left|bottom" - height="23" - label="Revert" - label_selected="Revert" - layout="topleft" - left_pad="3" - name="Revert" - top="477" - width="120" /> - </panel> - <panel - border="false" - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|top|right|bottom" - height="508" - label="Hair" - layout="topleft" - name="Hair" - help_topic="customize_hair_tab" - width="400"> - <icon - follows="top|right" - height="18" - image_name="Lock" - layout="topleft" - left="315" - mouse_opaque="true" - name="square" - top="4" - width="18" /> - <icon - height="16" - top="10" - left="10" - layout="topleft" - mouse_opaque="true" - width="16" /> - <button - follows="left|top" - height="23" - label="Color" - label_selected="Color" - layout="topleft" - left="10" - name="Color" - top="63" - width="82" /> - <button - follows="left|top" - height="23" - label="Style" - label_selected="Style" - layout="topleft" - left_delta="0" - name="Style" - top_pad="4" - width="82" /> - <button - follows="left|top" - height="23" - label="Eyebrows" - label_selected="Eyebrows" - layout="topleft" - name="Eyebrows" - top_pad="4" - width="82" /> - <button - follows="left|top" - height="23" - label="Facial" - label_selected="Facial" - layout="topleft" - name="Facial" - top_pad="4" - width="82" /> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title" - top="10" - width="355"> - [DESC] - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_no_modify" - top="10" - width="355"> - [DESC]: cannot modify - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_loading" - top="10" - width="355"> - [DESC]: loading... - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_not_worn" - top="10" - width="355"> - [DESC]: not worn - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="14" - layout="topleft" - left="10" - name="path" - top="36" - width="373"> - Located in [PATH] - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="not worn instructions" - top="31" - word_wrap="true" - width="373"> - Put on a new hair by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="no modify instructions" - top="31" - word_wrap="true" - width="373"> - You do not have permission to modify this wearable. - </text> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Texture" - layout="topleft" - left="10" - name="Texture" - tool_tip="Click to choose a picture" - top="176" - width="82" /> - <button - follows="left|top" - height="23" - label="Create New Hair" - label_selected="Create New Hair" - layout="topleft" - left_delta="0" - name="Create New" - top_delta="-89" - width="160" /> - <text - type="string" - length="1" - top="488" - follows="left|top" - font="SansSerif" - halign="right" - height="23" - layout="topleft" - name="Item Action Label" - left="10" - width="130"> - Hair: - </text> - <button - follows="left|bottom" - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left_pad="2" - name="Save" - top="477" - width="82" /> - <button - follows="left|bottom" - height="23" - label="Save As..." - label_selected="Save As..." - layout="topleft" - left_pad="3" - name="Save As" - top="477" - width="115" /> - <button - follows="left|bottom" - height="23" - label="Revert" - label_selected="Revert" - layout="topleft" - left_pad="3" - name="Revert" - top="477" - width="120" /> - </panel> - <panel - border="false" - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|top|right|bottom" - height="508" - label="Eyes" - layout="topleft" - name="Eyes" - help_topic="customize_eyes_tab" - width="400"> - <icon - follows="top|right" - height="18" - image_name="Lock" - layout="topleft" - left="315" - mouse_opaque="true" - name="square" - top="4" - width="18" /> - <icon - height="16" - top="10" - left="10" - layout="topleft" - mouse_opaque="true" - width="16" /> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title" - top="10" - width="355"> - [DESC] - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_no_modify" - top="10" - width="355"> - [DESC]: cannot modify - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_loading" - top="10" - width="355"> - [DESC]: loading... - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_not_worn" - top="10" - width="355"> - [DESC]: not worn - </text> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="10" - name="path" - top="36" - width="373"> - Located in [PATH] - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="not worn instructions" - top="31" - word_wrap="true" - width="373"> - Put on a new set of eyes by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="no modify instructions" - top="31" - word_wrap="true" - width="373"> - You do not have permission to modify this wearable. - </text> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Iris" - layout="topleft" - left="10" - name="Iris" - tool_tip="Click to choose a picture" - top="66" - width="82" /> - <button - follows="left|top" - height="23" - label="Create New Eyes" - label_selected="Create New Eyes" - layout="topleft" - name="Create New" - top="66" - width="160" /> - <text - type="string" - length="1" - bottom="4" - follows="left|bottom" - font="SansSerif" - halign="right" - height="23" - layout="bottomleft" - name="Item Action Label" - left="10" - width="130"> - Eyes: - </text> - <button - follows="left|bottom" - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left_pad="2" - name="Save" - top="477" - width="82" /> - <button - follows="left|bottom" - height="23" - label="Save As..." - label_selected="Save As..." - layout="topleft" - left_pad="3" - name="Save As" - top="477" - width="115" /> - <button - follows="left|bottom" - height="23" - label="Revert" - label_selected="Revert" - layout="topleft" - left_pad="3" - name="Revert" - top="477" - width="120" /> - </panel> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="5" - name="clothes_placeholder" - font="SansSerifSmallBold" - top="125" - width="100"> - Clothes - </text> - <placeholder /> - <panel - border="false" - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|top|right|bottom" - height="508" - label="Shirt" - layout="topleft" - name="Shirt" - help_topic="customize_shirt_tab" - top_delta="0" - width="400"> - <icon - follows="top|left" - height="18" - image_name="Lock" - layout="topleft" - left="10" - mouse_opaque="true" - name="square" - top="10" - width="18" /> - <icon - height="16" - top="10" - left="10" - layout="topleft" - mouse_opaque="true" - width="16" /> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Fabric" - layout="topleft" - left="10" - name="Fabric" - tool_tip="Click to choose a picture" - top="66" - width="82" /> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="108" - label="Color/Tint" - layout="topleft" - name="Color/Tint" - tool_tip="Click to open color picker" - top_delta="102" - width="82" /> - <button - follows="left|top" - height="23" - label="Take Off" - label_selected="Take Off" - layout="topleft" - name="Take Off" - top_pad="4" - width="82" /> - <button - follows="left|top" - height="23" - label="Create New Shirt" - label_selected="Create New Shirt" - layout="topleft" - name="Create New" - top="66" - width="160" /> - <text - type="string" - length="1" - bottom="4" - follows="left|bottom" - font="SansSerif" - halign="right" - height="23" - layout="bottomleft" - name="Item Action Label" - left="10" - width="130"> - Shirt: - </text> - <button - follows="left|bottom" - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left_pad="2" - name="Save" - top="477" - width="82" /> - <button - follows="left|bottom" - height="23" - label="Save As..." - label_selected="Save As..." - layout="topleft" - left_pad="3" - name="Save As" - top="477" - width="115" /> - <button - follows="left|bottom" - height="23" - label="Revert" - label_selected="Revert" - layout="topleft" - left_pad="3" - name="Revert" - top="477" - width="120" /> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title" - top="10" - width="355"> - [DESC] - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_no_modify" - top="10" - width="355"> - [DESC]: cannot modify - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_loading" - top="10" - width="355"> - [DESC]: loading... - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_not_worn" - top="10" - width="355"> - [DESC]: not worn - </text> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="10" - name="path" - top="36" - width="373"> - Located in [PATH] - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="not worn instructions" - top="31" - word_wrap="true" - width="373"> - Put on a new shirt by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="no modify instructions" - top="31" - word_wrap="true" - width="373"> - You do not have permission to modify this wearable. - </text> - </panel> - <panel - border="false" - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|top|right|bottom" - height="508" - label="Pants" - layout="topleft" - name="Pants" - help_topic="customize_pants_tab" - width="400"> - <icon - follows="top|left" - height="18" - image_name="Lock" - layout="topleft" - left="10" - mouse_opaque="true" - name="square" - top="10" - width="18" /> - <icon - height="16" - layout="topleft" - left="10" - mouse_opaque="true" - top="10" - width="16" /> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Fabric" - layout="topleft" - left="10" - name="Fabric" - tool_tip="Click to choose a picture" - top="66" - width="82" /> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="108" - label="Color/Tint" - layout="topleft" - name="Color/Tint" - tool_tip="Click to open color picker" - top_delta="102" - width="82" /> - <button - follows="left|top" - height="23" - label="Take Off" - label_selected="Take Off" - layout="topleft" - name="Take Off" - top_pad="4" - width="82" /> - <button - follows="left|top" - height="23" - label="Create New Pants" - label_selected="Create New Pants" - layout="topleft" - name="Create New" - top="66" - width="160" /> - <text - type="string" - length="1" - bottom="4" - follows="left|bottom" - font="SansSerif" - halign="right" - height="23" - layout="bottomleft" - name="Item Action Label" - left="10" - width="130"> - Pants: - </text> - <button - follows="left|bottom" - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left_pad="2" - name="Save" - top="477" - width="82" /> - <button - follows="left|bottom" - height="23" - label="Save As..." - label_selected="Save As..." - layout="topleft" - left_pad="3" - name="Save As" - top="477" - width="115" /> - <button - follows="left|bottom" - height="23" - label="Revert" - label_selected="Revert" - layout="topleft" - left_pad="3" - name="Revert" - top="477" - width="120" /> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title" - top="10" - width="355"> - [DESC] - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_no_modify" - top="10" - width="355"> - [DESC]: cannot modify - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_loading" - top="10" - width="355"> - [DESC]: loading... - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_not_worn" - top="10" - width="355"> - [DESC]: not worn - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="14" - layout="topleft" - left="10" - name="path" - top="36" - width="373"> - Located in [PATH] - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="not worn instructions" - top="31" - word_wrap="true" - width="373"> - Put on new pants by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="no modify instructions" - top="31" - word_wrap="true" - width="373"> - You do not have permission to modify this wearable. - </text> - </panel> - <panel - border="false" - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|top|right|bottom" - height="508" - label="Shoes" - layout="topleft" - name="Shoes" - help_topic="customize_shoes_tab" - width="400"> - <icon - follows="top|left" - height="18" - image_name="Lock" - layout="topleft" - left="10" - mouse_opaque="true" - name="square" - top="10" - width="18" /> - <icon - height="16" - layout="topleft" - left="10" - mouse_opaque="true" - top="10" - width="16" /> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title" - top="10" - width="355"> - [DESC] - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_no_modify" - top="10" - width="355"> - [DESC]: cannot modify - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_loading" - top="10" - width="355"> - [DESC]: loading... - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_not_worn" - top="10" - width="355"> - [DESC]: not worn - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="14" - layout="topleft" - left="10" - name="path" - top="36" - width="373"> - Located in [PATH] - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="not worn instructions" - top="31" - word_wrap="true" - width="373"> - Put on a new pair of shoes by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. - </text> - <button - follows="left|top" - height="23" - label="Create New Shoes" - label_selected="Create New Shoes" - layout="topleft" - name="Create New" - top_pad="18" - width="160" /> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="no modify instructions" - top="31" - word_wrap="true" - width="373"> - You do not have permission to modify this wearable. - </text> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Fabric" - layout="topleft" - left="10" - name="Fabric" - tool_tip="Click to choose a picture" - top="66" - width="82" /> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="108" - label="Color/Tint" - layout="topleft" - name="Color/Tint" - tool_tip="Click to open color picker" - top_delta="102" - width="82" /> - <button - follows="left|top" - height="23" - label="Take Off" - label_selected="Take Off" - layout="topleft" - name="Take Off" - top_pad="4" - width="82" /> - <text - type="string" - length="1" - bottom="4" - follows="left|bottom" - font="SansSerif" - halign="right" - height="23" - layout="bottomleft" - left="10" - name="Item Action Label" - width="130"> - Shoes: - </text> - <button - follows="left|bottom" - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left_pad="2" - name="Save" - top="477" - width="82" /> - <button - follows="left|bottom" - height="23" - label="Save As..." - label_selected="Save As..." - layout="topleft" - left_pad="3" - name="Save As" - top="477" - width="115" /> - <button - follows="left|bottom" - height="23" - label="Revert" - label_selected="Revert" - layout="topleft" - left_pad="3" - name="Revert" - top="477" - width="120" /> - </panel> - <panel - border="false" - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|top|right|bottom" - height="508" - label="Socks" - layout="topleft" - name="Socks" - help_topic="customize_socks_tab" - width="400"> - <icon - follows="top|left" - height="18" - image_name="Lock" - layout="topleft" - left="10" - mouse_opaque="true" - name="square" - top="10" - width="18" /> - <icon - height="16" - layout="topleft" - left="10" - mouse_opaque="true" - top="10" - width="16" /> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title" - top="10" - width="355"> - [DESC] - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_no_modify" - top="10" - width="355"> - [DESC]: cannot modify - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_loading" - top="10" - width="355"> - [DESC]: loading... - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_not_worn" - top="10" - width="355"> - [DESC]: not worn - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="14" - layout="topleft" - left="10" - name="path" - top="36" - width="373"> - Located in [PATH] - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="not worn instructions" - top="31" - word_wrap="true" - width="373"> - Put on new socks by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. - </text> - <button - follows="left|top" - height="23" - label="Create New Socks" - label_selected="Create New Socks" - layout="topleft" - name="Create New" - top_pad="7" - width="160" /> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="no modify instructions" - top="31" - word_wrap="true" - width="373"> - You do not have permission to modify this wearable. - </text> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Fabric" - layout="topleft" - left="10" - name="Fabric" - tool_tip="Click to choose a picture" - top="66" - width="82" /> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="108" - label="Color/Tint" - layout="topleft" - name="Color/Tint" - tool_tip="Click to open color picker" - top_delta="102" - width="82" /> - <button - follows="left|top" - height="23" - label="Take Off" - label_selected="Take Off" - layout="topleft" - name="Take Off" - top_pad="4" - width="82" /> - <text - type="string" - length="1" - bottom="4" - follows="left|bottom" - font="SansSerif" - halign="right" - height="23" - layout="bottomleft" - left="10" - name="Item Action Label" - width="130"> - Socks: - </text> - <button - follows="left|bottom" - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left_pad="2" - name="Save" - top="477" - width="82" /> - <button - follows="left|bottom" - height="23" - label="Save As..." - label_selected="Save As..." - layout="topleft" - left_pad="3" - name="Save As" - top="477" - width="115" /> - <button - follows="left|bottom" - height="23" - label="Revert" - label_selected="Revert" - layout="topleft" - left_pad="3" - name="Revert" - top="477" - width="120" /> - </panel> - <panel - border="false" - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|top|right|bottom" - height="508" - label="Jacket" - layout="topleft" - name="Jacket" - help_topic="customize_jacket_tab" - width="400"> - <icon - follows="top|left" - height="18" - image_name="Lock" - layout="topleft" - left="10" - mouse_opaque="true" - name="square" - top="10" - width="18" /> - <icon - height="16" - layout="topleft" - left="10" - mouse_opaque="true" - top="10" - width="16" /> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title" - top="10" - width="355"> - [DESC] - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_no_modify" - top="10" - width="355"> - [DESC]: cannot modify - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_loading" - top="10" - width="355"> - [DESC]: loading... - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_not_worn" - top="10" - width="355"> - [DESC]: not worn - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="14" - layout="topleft" - left="10" - name="path" - top="36" - width="373"> - Located in [PATH] - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="not worn instructions" - top="31" - word_wrap="true" - width="373"> - Put on a new jacket by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. - </text> - <button - follows="left|top" - height="23" - label="Create New Jacket" - label_selected="Create New Jacket" - layout="topleft" - name="Create New" - top_pad="7" - width="160" /> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="no modify instructions" - top="31" - word_wrap="true" - width="373"> - You do not have permission to modify this wearable. - </text> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Upper Fabric" - layout="topleft" - left="10" - name="Upper Fabric" - tool_tip="Click to choose a picture" - top="66" - width="82" /> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Lower Fabric" - layout="topleft" - name="Lower Fabric" - tool_tip="Click to choose a picture" - top_delta="102" - width="82" /> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="108" - label="Color/Tint" - layout="topleft" - name="Color/Tint" - tool_tip="Click to open color picker" - top_delta="102" - width="82" /> - <button - follows="left|top" - height="23" - label="Take Off" - label_selected="Take Off" - layout="topleft" - name="Take Off" - top_pad="4" - width="82" /> - <text - type="string" - length="1" - bottom="4" - follows="left|bottom" - font="SansSerif" - halign="right" - height="23" - layout="bottomleft" - left="10" - name="Item Action Label" - width="130"> - Jacket: - </text> - <button - follows="left|bottom" - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left_pad="2" - name="Save" - top="477" - width="82" /> - <button - follows="left|bottom" - height="23" - label="Save As..." - label_selected="Save As..." - layout="topleft" - left_pad="3" - name="Save As" - top="477" - width="115" /> - <button - follows="left|bottom" - height="23" - label="Revert" - label_selected="Revert" - layout="topleft" - left_pad="3" - name="Revert" - top="477" - width="120" /> - </panel> - <panel - border="false" - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|top|right|bottom" - height="508" - label="Gloves" - layout="topleft" - name="Gloves" - help_topic="customize_gloves_tab" - width="400"> - <icon - follows="top|left" - height="18" - image_name="Lock" - layout="topleft" - left="10" - mouse_opaque="true" - name="square" - top="10" - width="18" /> - <icon - height="16" - layout="topleft" - left="10" - mouse_opaque="true" - top="10" - width="16" /> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title" - top="10" - width="355"> - [DESC] - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_no_modify" - top="10" - width="355"> - [DESC]: cannot modify - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_loading" - top="10" - width="355"> - [DESC]: loading... - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_not_worn" - top="10" - width="355"> - [DESC]: not worn - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="14" - layout="topleft" - left="10" - name="path" - top="36" - width="373"> - Located in [PATH] - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="not worn instructions" - top="31" - word_wrap="true" - width="373"> - Put on new gloves by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. - </text> - <button - follows="left|top" - height="23" - label="Create New Gloves" - label_selected="Create New Gloves" - layout="topleft" - name="Create New" - top_pad="7" - width="160" /> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="no modify instructions" - top="31" - word_wrap="true" - width="373"> - You do not have permission to modify this wearable. - </text> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Fabric" - layout="topleft" - left="10" - name="Fabric" - tool_tip="Click to choose a picture" - top="66" - width="82" /> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="108" - label="Color/Tint" - layout="topleft" - name="Color/Tint" - tool_tip="Click to open color picker" - top_delta="102" - width="82" /> - <button - follows="left|top" - height="23" - label="Take Off" - label_selected="Take Off" - layout="topleft" - name="Take Off" - top_pad="4" - width="82" /> - <text - type="string" - length="1" - bottom="4" - follows="left|bottom" - font="SansSerif" - halign="right" - height="23" - layout="bottomleft" - left="10" - name="Item Action Label" - width="130"> - Gloves: - </text> - <button - follows="left|bottom" - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left_pad="2" - name="Save" - top="477" - width="82" /> - <button - follows="left|bottom" - height="23" - label="Save As..." - label_selected="Save As..." - layout="topleft" - left_pad="3" - name="Save As" - top="477" - width="115" /> - <button - follows="left|bottom" - height="23" - label="Revert" - label_selected="Revert" - layout="topleft" - left_pad="3" - name="Revert" - top="477" - width="120" /> - </panel> - <panel - border="false" - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|top|right|bottom" - height="508" - label="Undershirt" - layout="topleft" - name="Undershirt" - help_topic="customize_undershirt_tab" - width="400"> - <icon - follows="top|left" - height="18" - image_name="Lock" - layout="topleft" - left="10" - mouse_opaque="true" - name="square" - top="10" - width="18" /> - <icon - height="16" - layout="topleft" - left="10" - mouse_opaque="true" - top="10" - width="16" /> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title" - top="10" - width="355"> - [DESC] - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_no_modify" - top="10" - width="355"> - [DESC]: cannot modify - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_loading" - top="10" - width="355"> - [DESC]: loading... - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_not_worn" - top="10" - width="355"> - [DESC]: not worn - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="14" - layout="topleft" - left="10" - name="path" - top="36" - width="373"> - Located in [PATH] - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="not worn instructions" - top="31" - word_wrap="true" - width="373"> - Put on a new undershirt by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. - </text> - <button - follows="left|top" - height="23" - label="Create New Undershirt" - label_selected="Create New Undershirt" - layout="topleft" - name="Create New" - top_pad="7" - width="160" /> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="no modify instructions" - top="31" - word_wrap="true" - width="373"> - You do not have permission to modify this wearable. - </text> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Fabric" - layout="topleft" - left="10" - name="Fabric" - tool_tip="Click to choose a picture" - top="66" - width="82" /> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="108" - label="Color/Tint" - layout="topleft" - name="Color/Tint" - tool_tip="Click to open color picker" - top_delta="102" - width="82" /> - <button - follows="left|top" - height="23" - label="Take Off" - label_selected="Take Off" - layout="topleft" - name="Take Off" - top_pad="4" - width="82" /> - <text - type="string" - length="1" - bottom="4" - follows="left|bottom" - font="SansSerif" - halign="right" - height="23" - layout="bottomleft" - left="10" - name="Item Action Label" - width="130"> - Undershirt: - </text> - <button - follows="left|bottom" - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left_pad="2" - name="Save" - top="477" - width="82" /> - <button - follows="left|bottom" - height="23" - label="Save As..." - label_selected="Save As..." - layout="topleft" - left_pad="3" - name="Save As" - top="477" - width="115" /> - <button - follows="left|bottom" - height="23" - label="Revert" - label_selected="Revert" - layout="topleft" - left_pad="3" - name="Revert" - top="477" - width="120" /> - </panel> - <panel - border="false" - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|top|right|bottom" - height="508" - label="Underpants" - layout="topleft" - name="Underpants" - help_topic="customize_underpants_tab" - width="400"> - <icon - follows="top|left" - height="18" - image_name="Lock" - layout="topleft" - left="10" - mouse_opaque="true" - name="square" - top="10" - width="18" /> - <icon - height="16" - layout="topleft" - left="10" - mouse_opaque="true" - top="10" - width="16" /> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title" - top="10" - width="355"> - [DESC] - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_no_modify" - top="10" - width="355"> - [DESC]: cannot modify - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_loading" - top="10" - width="355"> - [DESC]: loading... - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_not_worn" - top="10" - width="355"> - [DESC]: not worn - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="14" - layout="topleft" - left="10" - name="path" - top="36" - width="373"> - Located in [PATH] - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="not worn instructions" - top="31" - word_wrap="true" - width="373"> - Put on new underpants by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. - </text> - <button - follows="left|top" - height="23" - label="Create New Underpants" - label_selected="Create New Underpants" - layout="topleft" - name="Create New" - top_pad="7" - width="160" /> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="no modify instructions" - top="31" - word_wrap="true" - width="373"> - You do not have permission to modify this wearable. - </text> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Fabric" - layout="topleft" - left="10" - name="Fabric" - tool_tip="Click to choose a picture" - top="66" - width="82" /> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="108" - label="Color/Tint" - layout="topleft" - name="Color/Tint" - tool_tip="Click to open color picker" - top_delta="102" - width="82" /> - <button - follows="left|top" - height="23" - label="Take Off" - label_selected="Take Off" - layout="topleft" - name="Take Off" - top_pad="4" - width="82" /> - <text - type="string" - length="1" - bottom="4" - follows="left|bottom" - font="SansSerif" - halign="right" - height="23" - layout="bottomleft" - left="10" - name="Item Action Label" - width="130"> - Underpants: - </text> - <button - follows="left|bottom" - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left_pad="2" - name="Save" - top="477" - width="82" /> - <button - follows="left|bottom" - height="23" - label="Save As..." - label_selected="Save As..." - layout="topleft" - left_pad="3" - name="Save As" - top="477" - width="115" /> - <button - follows="left|bottom" - height="23" - label="Revert" - label_selected="Revert" - layout="topleft" - left_pad="3" - name="Revert" - top="477" - width="120" /> - </panel> - <panel - border="false" - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|top|right|bottom" - height="508" - label="Skirt" - layout="topleft" - name="Skirt" - help_topic="customize_skirt_tab" - width="400"> - <icon - follows="top|left" - height="18" - image_name="Lock" - layout="topleft" - left="10" - mouse_opaque="true" - name="square" - top="10" - width="18" /> - <icon - height="16" - layout="topleft" - left="10" - mouse_opaque="true" - top="10" - width="16" /> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title" - top="10" - width="355"> - [DESC] - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_no_modify" - top="10" - width="355"> - [DESC]: cannot modify - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_loading" - top="10" - width="355"> - [DESC]: loading... - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_not_worn" - top="10" - width="355"> - [DESC]: not worn - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="14" - layout="topleft" - left="10" - name="path" - top="36" - width="373"> - Located in [PATH] - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="not worn instructions" - top="31" - word_wrap="true" - width="373"> - Put on a new skirt by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. - </text> - <button - follows="left|top" - height="23" - label="Create New Skirt" - label_selected="Create New Skirt" - layout="topleft" - name="Create New" - top_pad="7" - width="160" /> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="no modify instructions" - top="31" - word_wrap="true" - width="373"> - You do not have permission to modify this wearable. - </text> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Fabric" - layout="topleft" - left="10" - name="Fabric" - tool_tip="Click to choose a picture" - top="66" - width="82" /> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="108" - label="Color/Tint" - layout="topleft" - name="Color/Tint" - tool_tip="Click to open color picker" - top_delta="102" - width="82" /> - <button - follows="left|top" - height="23" - label="Take Off" - label_selected="Take Off" - layout="topleft" - name="Take Off" - top_pad="4" - width="82" /> - <text - type="string" - length="1" - bottom="4" - follows="left|bottom" - font="SansSerif" - halign="right" - height="23" - layout="bottomleft" - left="10" - name="Item Action Label" - width="130"> - Skirt: - </text> - <button - follows="left|bottom" - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left_pad="2" - name="Save" - top="477" - width="82" /> - <button - follows="left|bottom" - height="23" - label="Save As..." - label_selected="Save As..." - layout="topleft" - left_pad="3" - name="Save As" - top="477" - width="115" /> - <button - follows="left|bottom" - height="23" - label="Revert" - label_selected="Revert" - layout="topleft" - left_pad="3" - name="Revert" - top="477" - width="120" /> - </panel> - <panel - border="false" - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|top|right|bottom" - height="508" - label="Tattoo" - layout="topleft" - name="Tattoo" - help_topic="customize_tattoo_tab" - width="400"> - <icon - follows="top|left" - height="18" - image_name="Lock" - layout="topleft" - left="10" - mouse_opaque="true" - name="square" - top="10" - width="18" /> - <icon - height="16" - layout="topleft" - left="10" - mouse_opaque="true" - top="10" - width="16" /> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title" - top="10" - width="355"> - [DESC] - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_no_modify" - top="10" - width="355"> - [DESC]: cannot modify - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_loading" - top="10" - width="355"> - [DESC]: loading... - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_not_worn" - top="10" - width="355"> - [DESC]: not worn - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="14" - layout="topleft" - left="10" - name="path" - top="36" - width="373"> - Located in [PATH] - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="not worn instructions" - top="31" - word_wrap="true" - width="373"> - Put on a new tattoo by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. - </text> - <button - follows="left|top" - height="23" - label="Create New Tattoo" - label_selected="Create New Tattoo" - layout="topleft" - name="Create New" - top_pad="7" - width="160" /> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="no modify instructions" - top="31" - word_wrap="true" - width="373"> - You do not have permission to modify this wearable. - </text> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Head Tattoo" - layout="topleft" - left="10" - name="Head Tattoo" - tool_tip="Click to choose a picture" - top="66" - width="82" /> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Upper Tattoo" - layout="topleft" - name="Upper Tattoo" - tool_tip="Click to choose a picture" - left_delta="90" - width="82" /> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Lower Tattoo" - layout="topleft" - name="Lower Tattoo" - tool_tip="Click to choose a picture" - left_delta="90" - width="82" /> - <button - follows="left|top" - height="23" - label="Take Off" - label_selected="Take Off" - layout="topleft" - name="Take Off" - top_pad="4" - left="10" - width="82" /> - <text - type="string" - length="1" - bottom="4" - follows="left|bottom" - font="SansSerif" - halign="right" - height="23" - layout="bottomleft" - left="10" - name="Item Action Label" - width="130"> - Tattoo: - </text> - <button - follows="left|bottom" - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left_pad="2" - name="Save" - top="477" - width="82" /> - <button - follows="left|bottom" - height="23" - label="Save As..." - label_selected="Save As..." - layout="topleft" - left_pad="3" - name="Save As" - top="477" - width="115" /> - <button - follows="left|bottom" - height="23" - label="Revert" - label_selected="Revert" - layout="topleft" - left_pad="3" - name="Revert" - top="477" - width="120" /> - </panel> - <panel - border="false" - background_visible="true" - bg_alpha_color="DkGray2" - follows="left|top|right|bottom" - height="508" - label="Alpha" - layout="topleft" - name="Alpha" - help_topic="customize_alpha_tab" - width="400"> - <icon - follows="top|left" - height="18" - image_name="Lock" - layout="topleft" - left="10" - mouse_opaque="true" - name="square" - top="10" - width="18" /> - <icon - height="16" - layout="topleft" - left="10" - mouse_opaque="true" - top="10" - width="16" /> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title" - top="10" - width="355"> - [DESC] - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_no_modify" - top="10" - width="355"> - [DESC]: cannot modify - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_loading" - top="10" - width="355"> - [DESC]: loading... - </text> - <text - type="string" - length="1" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left="31" - name="title_not_worn" - top="10" - width="355"> - [DESC]: not worn - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="14" - layout="topleft" - left="10" - name="path" - top="36" - width="373"> - Located in [PATH] - </text> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="not worn instructions" - top="31" - word_wrap="true" - width="373"> - Put on a new alpha mask by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. - </text> - <button - follows="left|top" - height="23" - label="Create New Alpha" - label_selected="Create New Alpha" - layout="topleft" - name="Create New" - top_pad="18" - width="160" /> - <text - type="string" - length="1" - follows="left|top|right" - height="28" - layout="topleft" - left="10" - name="no modify instructions" - top="31" - word_wrap="true" - width="373"> - You do not have permission to modify this wearable. - </text> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Lower Alpha" - layout="topleft" - left="10" - name="Lower Alpha" - tool_tip="Click to choose a picture" - top="66" - width="82" /> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Upper Alpha" - layout="topleft" - name="Upper Alpha" - tool_tip="Click to choose a picture" - left_delta="90" - width="82" /> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Head Alpha" - layout="topleft" - name="Head Alpha" - tool_tip="Click to choose a picture" - left_delta="90" - width="82" /> - <check_box - control_name="LowerAlphaTextureInvisible" - follows="left" - height="16" - layout="topleft" - left="43" - name="lower alpha texture invisible" - top_delta="96" - width="16" /> - <check_box - control_name="UpperAlphaTextureInvisible" - follows="left" - height="16" - layout="topleft" - left_pad="72" - name="upper alpha texture invisible" - width="16" /> - <check_box - control_name="HeadAlphaTextureInvisible" - follows="left" - height="16" - layout="topleft" - left_pad="72" - name="head alpha texture invisible" - width="16" /> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Eye Alpha" - layout="topleft" - name="Eye Alpha" - tool_tip="Click to choose a picture" - left="10" - top_pad="20" - width="82" /> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="108" - label="Hair Alpha" - layout="topleft" - name="Hair Alpha" - left_delta="90" - tool_tip="Click to choose a picture" - width="82" /> - <check_box - control_name="Eye AlphaTextureInvisible" - follows="left" - height="16" - layout="topleft" - left="43" - name="eye alpha texture invisible" - top_delta="96" - width="16" /> - <check_box - control_name="HairAlphaTextureInvisible" - follows="left" - height="16" - layout="topleft" - left_pad="72" - name="hair alpha texture invisible" - width="16" /> - <button - follows="left|top" - height="23" - label="Take Off" - label_selected="Take Off" - layout="topleft" - name="Take Off" - left="10" - top_pad="20" - width="82" /> - <text - type="string" - length="1" - bottom="4" - follows="left|bottom" - font="SansSerif" - halign="right" - height="23" - layout="bottomleft" - left="10" - name="Item Action Label" - width="130"> - Alpha: - </text> - <button - follows="left|bottom" - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left_pad="2" - name="Save" - top="477" - width="82" /> - <button - follows="left|bottom" - height="23" - label="Save As..." - label_selected="Save As..." - layout="topleft" - left_pad="3" - name="Save As" - top="477" - width="115" /> - <button - follows="left|bottom" - height="23" - label="Revert" - label_selected="Revert" - layout="topleft" - left_pad="3" - name="Revert" - top="477" - width="120" /> - </panel> - </tab_container> - <scroll_container - follows="left|top|right|bottom" - height="409" - layout="topleft" - left="247" - mouse_opaque="false" - name="panel_container" - top="92" - width="330"> - <scrolling_panel_list - follows="left|bottom" - layout="topleft" - name="panel_list" /> - </scroll_container> - <button - bottom="460" - follows="right|left" - height="23" - label="Script Info" - label_selected="Script Info" - layout="topleft" - name="script_info" - tool_tip="Show scripts attached to your avatar" - left="13" - width="90" ></button> - <button - bottom="574" - follows="right|bottom" - height="23" - label="Make Outfit" - label_selected="Make Outfit" - layout="topleft" - name="make_outfit_btn" - right="-218" - width="120" /> - <button - bottom="574" - follows="right|bottom" - height="23" - label="Cancel" - label_selected="Cancel" - layout="topleft" - name="Cancel" - right="-10" - width="100" /> - <button - bottom="574" - follows="right|bottom" - height="23" - label="OK" - label_selected="OK" - layout="topleft" - name="Ok" - right="-114" - width="100" /> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_day_cycle_options.xml b/indra/newview/skins/default/xui/en/floater_day_cycle_options.xml index 42a9ff551e..65e2462ef8 100644 --- a/indra/newview/skins/default/xui/en/floater_day_cycle_options.xml +++ b/indra/newview/skins/default/xui/en/floater_day_cycle_options.xml @@ -359,9 +359,9 @@ increment="1" initial_value="0" label="Hour" - label_width="30" + label_width="35" layout="topleft" - left_delta="25" + left_delta="20" max_val="100" name="WLCurKeyHour" top_pad="4" @@ -374,13 +374,13 @@ increment="5" initial_value="0" label="Min" - label_width="20" + label_width="45" layout="topleft" left_pad="5" max_val="55" name="WLCurKeyMin" top_delta="0" - width="60" /> + width="85" /> <text type="string" length="1" @@ -456,9 +456,9 @@ increment="1" initial_value="0" label="Hour" - label_width="30" + label_width="33" layout="topleft" - left_delta="0" + left_delta="-3" max_val="100" name="WLLengthOfDayHour" top_pad="4" @@ -471,13 +471,13 @@ increment="1" initial_value="0" label="Min" - label_width="20" + label_width="25" layout="topleft" - left_pad="5" + left_pad="2" max_val="59" name="WLLengthOfDayMin" top_delta="0" - width="60" /> + width="65" /> <spinner control_name="WLLengthOfDaySec" decimal_digits="0" @@ -486,13 +486,13 @@ increment="1" initial_value="24" label="Sec" - label_width="20" + label_width="25" layout="topleft" - left_pad="5" + left_pad="2" max_val="59" name="WLLengthOfDaySec" top_delta="0" - width="60"/> + width="65"/> <text type="string" halign="right" diff --git a/indra/newview/skins/default/xui/en/floater_device_settings.xml b/indra/newview/skins/default/xui/en/floater_device_settings.xml deleted file mode 100644 index 91a7a678da..0000000000 --- a/indra/newview/skins/default/xui/en/floater_device_settings.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - height="260" - layout="topleft" - name="floater_device_settings" - help_topic="floater_device_settings" - title="VOICE CHAT DEVICE SETTINGS" - width="405"> - <panel - bottom="260" - filename="panel_audio_device.xml" - layout="topleft" - left="2" - name="device_settings" - right="-5" - top="20" /> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_first_time_tip.xml b/indra/newview/skins/default/xui/en/floater_first_time_tip.xml deleted file mode 100644 index e4ac8fed77..0000000000 --- a/indra/newview/skins/default/xui/en/floater_first_time_tip.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - can_close="true" - can_minimize="false" - height="250" - layout="topleft" - name="set_name_in_the_cladd" - help_topic="set_name_in_the_cladd" - save_rect="true" - width="300"> - <check_box - height="20" - follows="left|bottom|right" - label="Turn off Quick Tips" - layout="topleft" - left="5" - name="DontShowFirstTimeTip_checkbox" - text_enabled_color="white" - top="225" - width="200" /> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_help_browser.xml b/indra/newview/skins/default/xui/en/floater_help_browser.xml index 214fb6ce54..837923bcf6 100644 --- a/indra/newview/skins/default/xui/en/floater_help_browser.xml +++ b/indra/newview/skins/default/xui/en/floater_help_browser.xml @@ -24,6 +24,7 @@ follows="left|right|top|bottom" layout="topleft" left="5" + orientation="vertical" name="stack1" top="20" width="640"> @@ -35,7 +36,8 @@ user_resize="false" width="620"> <web_browser - bottom="-11" + trusted_content="true" + bottom="-25" follows="left|right|top|bottom" layout="topleft" left="0" diff --git a/indra/newview/skins/default/xui/en/floater_im.xml b/indra/newview/skins/default/xui/en/floater_im.xml deleted file mode 100644 index 55efe83820..0000000000 --- a/indra/newview/skins/default/xui/en/floater_im.xml +++ /dev/null @@ -1,80 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<multi_floater - legacy_header_height="18" - can_resize="true" - follows="left|bottom" - height="422" - layout="topleft" - min_height="130" - min_width="350" - name="im_floater" - help_topic="im_floater" - save_rect="true" - title="Instant Message" - width="419"> - <multi_floater.string - name="only_user_message"> - You are the only Resident in this session. - </multi_floater.string> - <multi_floater.string - name="offline_message"> - [FIRST] [LAST] is offline. - </multi_floater.string> - <multi_floater.string - name="invite_message"> - Click the [BUTTON NAME] button to accept/connect to this voice chat. - </multi_floater.string> - <multi_floater.string - name="muted_message"> - You have blocked this Resident. Sending a message will automatically unblock them. - </multi_floater.string> - <multi_floater.string - name="generic_request_error"> - Error making request, please try again later. - </multi_floater.string> - <multi_floater.string - name="insufficient_perms_error"> - You do not have sufficient permissions. - </multi_floater.string> - <multi_floater.string - name="session_does_not_exist_error"> - The session no longer exists - </multi_floater.string> - <multi_floater.string - name="no_ability_error"> - You do not have that ability. - </multi_floater.string> - <multi_floater.string - name="not_a_mod_error"> - You are not a session moderator. - </multi_floater.string> - <multi_floater.string - name="muted_error"> - A group moderator disabled your text chat. - </multi_floater.string> - <multi_floater.string - name="add_session_event"> - Unable to add Residents to chat session with [RECIPIENT]. - </multi_floater.string> - <multi_floater.string - name="message_session_event"> - Unable to send your message to the chat session with [RECIPIENT]. - </multi_floater.string> - <multi_floater.string - name="removed_from_group"> - You have been removed from the group. - </multi_floater.string> - <multi_floater.string - name="close_on_no_ability"> - You no longer have the ability to be in the chat session. - </multi_floater.string> - <tab_container - follows="left|top|right|bottom" - height="406" - layout="topleft" - left="1" - name="Preview Tabs" - tab_position="bottom" - top="16" - width="417" /> -</multi_floater> diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index 6c1214f152..a371e98322 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -30,12 +30,19 @@ top="20" left="0"> <layout_panel - name="panel_im_control_panel" - layout="topleft" - follows="left" - min_width="115" + name="im_control_panel_holder" + min_width="115" + width="150" + height="320" auto_resize="false" - user_resize="true" /> + user_resize="false"> + <panel + name="panel_im_control_panel" + layout="topleft" + height="320" + width="150" + follows="all"/> + </layout_panel> <layout_panel default_tab_group="3" left="0" diff --git a/indra/newview/skins/default/xui/en/floater_media_browser.xml b/indra/newview/skins/default/xui/en/floater_media_browser.xml index c02d607586..4701d7eca8 100644 --- a/indra/newview/skins/default/xui/en/floater_media_browser.xml +++ b/indra/newview/skins/default/xui/en/floater_media_browser.xml @@ -9,7 +9,7 @@ name="floater_about" help_topic="floater_about" save_rect="true" - single_instance="true" + auto_tile="true" title="MEDIA BROWSER" width="820"> <floater.string @@ -26,10 +26,12 @@ layout="topleft" left="10" name="stack1" + orientation="vertical" top="20" width="800"> <layout_panel auto_resize="false" + default_tab_group="1" height="20" layout="topleft" left="0" @@ -77,11 +79,13 @@ <combo_box allow_text_entry="true" follows="left|top|right" + tab_group="1" height="20" layout="topleft" left_pad="5" max_chars="1024" name="address" + combo_editor.select_on_focus="true" top_delta="0" width="540"> <combo_box.commit_callback @@ -189,9 +193,9 @@ top_delta="0" user_resize="false" width="540"> - <web_browser + <web_browser bottom="-30" - follows="left|right|top|bottom" + follows="all" layout="topleft" left="0" name="browser" diff --git a/indra/newview/skins/default/xui/en/floater_my_friends.xml b/indra/newview/skins/default/xui/en/floater_my_friends.xml deleted file mode 100644 index e7efcc7844..0000000000 --- a/indra/newview/skins/default/xui/en/floater_my_friends.xml +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - can_close="false" - can_resize="true" - height="390" - layout="topleft" - min_height="240" - min_width="365" - name="floater_my_friends" - help_topic="floater_my_friends" - save_rect="true" - single_instance="true" - title="CONTACTS" - width="395"> - <tab_container - follows="all" - height="364" - layout="topleft" - left="4" - name="friends_and_groups" - tab_position="top" - tab_width="80" - top="20" - width="383"> - <panel - bottom="364" - filename="panel_friends.xml" - label="Friends" - layout="topleft" - left="0" - help_topic="my_friends_friends_tab" - name="friends_panel" - width="370" /> - <panel - bottom="364" - filename="panel_groups.xml" - label="Groups" - layout="topleft" - left="0" - help_topic="my_friends_groups_tab" - name="groups_panel" - width="370" /> - </tab_container> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_notifications_console.xml b/indra/newview/skins/default/xui/en/floater_notifications_console.xml index ca81b9bcf0..e243ccd2f9 100644 --- a/indra/newview/skins/default/xui/en/floater_notifications_console.xml +++ b/indra/newview/skins/default/xui/en/floater_notifications_console.xml @@ -36,6 +36,7 @@ follows="left|right|top|bottom" layout="topleft" left="5" + orientation="vertical" name="notification_channels" right="-5" top="42" /> diff --git a/indra/newview/skins/default/xui/en/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/en/floater_outfit_save_as.xml deleted file mode 100644 index 1d73d516d0..0000000000 --- a/indra/newview/skins/default/xui/en/floater_outfit_save_as.xml +++ /dev/null @@ -1,58 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - can_close="false" - can_minimize="false" - height="100" - layout="topleft" - title="Save Outfit" - name="modal container" - width="240"> - <button - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left="20" - name="Save" - top="70" - width="82" /> - <button - height="23" - label="Cancel" - label_selected="Cancel" - layout="topleft" - left_pad="36" - name="Cancel" - top_delta="0" - width="82" /> - <text - type="string" - length="1" - follows="left|top" - height="30" - layout="topleft" - left="20" - word_wrap="true" - name="Save item as:" - top="10" - width="200"> - Save what I'm wearing -as a new Outfit: - </text> - <line_editor - type="string" - length="1" - border_style="line" - border_thickness="1" - follows="left|top" - height="23" - layout="topleft" - left_delta="0" - show_text_as_tentative="false" - top_pad="0" - max_length="63" - name="name ed" - width="200"> - [DESC] (new) - </line_editor> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_preview_classified.xml b/indra/newview/skins/default/xui/en/floater_preview_classified.xml deleted file mode 100644 index 2017cf2bd1..0000000000 --- a/indra/newview/skins/default/xui/en/floater_preview_classified.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - auto_tile="true" - height="510" - layout="topleft" - name="classified_preview" - help_topic="classified_preview" - save_rect="true" - title="CLASSIFIED INFORMATION" - width="440"> - <floater.string - name="Title"> - Classified: [NAME] - </floater.string> - <panel - follows="bottom|left" - height="470" - layout="topleft" - left="0" - name="classified_details_panel" - top="20" - width="440" /> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_preview_event.xml b/indra/newview/skins/default/xui/en/floater_preview_event.xml deleted file mode 100644 index a4066b34c5..0000000000 --- a/indra/newview/skins/default/xui/en/floater_preview_event.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - auto_tile="true" - height="510" - layout="topleft" - name="event_preview" - help_topic="event_preview" - save_rect="true" - title="EVENT INFORMATION" - width="440"> - <floater.string - name="Title"> - Event: [NAME] - </floater.string> - <panel - follows="bottom|left" - height="470" - layout="topleft" - left="0" - name="event_details_panel" - top="20" - width="440" /> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture_info.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture_info.xml deleted file mode 100644 index 66408a5057..0000000000 --- a/indra/newview/skins/default/xui/en/floater_preview_gesture_info.xml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - can_minimize="false" - follows="left|top" - height="155" - layout="topleft" - name="Gesture" - help_topic="gesture" - save_rect="true" - title="GESTURE SHORTCUT" - width="260"> - <scroll_list - follows="top|left" - height="110" - layout="topleft" - left="10" - name="library_list" - top="10" - width="240"> - <scroll_list.rows - value="Animation" /> - <scroll_list.rows - value="Sound" /> - <scroll_list.rows - value="Chat" /> - <scroll_list.rows - value="Wait" /> - </scroll_list> - <!--button - follows="top|left" - height="20" - label="Preview" - layout="topleft" - left="20" - name="preview_btn" - top_pad="50" - width="80" /> - <button - follows="top|left" - height="20" - label="Save" - layout="topleft" - left_pad="5" - name="save_btn" - top_delta="0" - width="80" /> - <button - follows="top|left" - height="20" - label="Cancel (not working)" - layout="topleft" - left_pad="5" - name="save_btn" - top_delta="0" - width="80" /--> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture_shortcut.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture_shortcut.xml deleted file mode 100644 index 26252a7a16..0000000000 --- a/indra/newview/skins/default/xui/en/floater_preview_gesture_shortcut.xml +++ /dev/null @@ -1,88 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - can_minimize="false" - follows="left|top" - height="90" - layout="topleft" - name="Gesture" - help_topic="gesture" - save_rect="true" - title="GESTURE SHORTCUT" - width="260"> - <text - type="string" - length="1" - follows="top|left" - font="SansSerifSmall" - height="10" - layout="topleft" - left="10" - name="trigger_label" - top_pad="10" - width="100"> - Chat: - </text> - <line_editor - follows="left|top" - height="20" - layout="topleft" - left_pad="5" - max_length="31" - name="trigger_editor" - top_delta="-4" - width="135" /> - <text - type="string" - length="1" - follows="top|left" - font="SansSerifSmall" - height="10" - layout="topleft" - left="10" - name="key_label" - top_pad="10" - width="100"> - Keyboard: - </text> - <combo_box - height="20" - label="None" - layout="topleft" - left_pad="13" - name="modifier_combo" - top_delta="-4" - width="50" /> - <combo_box - height="20" - label="None" - layout="topleft" - left_pad="5" - name="key_combo" - top_delta="0" - width="45" /> - <text - type="string" - length="1" - follows="top|left" - font="SansSerifSmall" - 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_pad="10" - width="100"> - Replace: - </text> - <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" /> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture_steps.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture_steps.xml deleted file mode 100644 index 34f707cd2a..0000000000 --- a/indra/newview/skins/default/xui/en/floater_preview_gesture_steps.xml +++ /dev/null @@ -1,242 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - can_minimize="false" - follows="left|top" - height="155" - layout="topleft" - name="Gesture" - help_topic="gesture" - save_rect="true" - title="GESTURE SHORTCUT" - width="260"> - <scroll_list - follows="top|left" - height="110" - layout="topleft" - left="10" - name="step_list" - top_pad="10" - width="240" /> - <!--text - type="string" - length="1" - follows="top|left" - font="SansSerifSmall" - height="60" - layout="topleft" - left="10" - name="help_label" - top_pad="10" - width="200"> - All steps happen simultaneously, -unless you add wait steps. - </text--> - <!--text - follows="top|left" - height="60" - layout="topleft" - left="10" - name="options_text" - top_pad="10" - width="205" /--> - <!--combo_box - follows="top|left" - height="20" - layout="topleft" - left_delta="10" - name="animation_list" - top_pad="10" - width="100" /> - <combo_box - follows="top|left" - height="20" - layout="topleft" - left_delta="0" - name="sound_list" - top_delta="10" - width="100" /> - <line_editor - follows="top|left" - height="20" - layout="topleft" - left_delta="0" - max_length="127" - name="chat_editor" - top_pad="10" - width="100" /> - <radio_group - draw_border="false" - follows="top|left" - height="40" - layout="topleft" - left_pad="8" - name="animation_trigger_type" - top_pad="10" - width="80"> - <radio_item - height="16" - label="Start" - layout="topleft" - left="3" - name="start" - top="-11" - width="80" /> - <radio_item - height="16" - label="Stop" - layout="topleft" - left_delta="0" - name="stop" - top_pad="10" - width="80" /> - </radio_group> - <check_box - follows="top|left" - height="20" - label="until animations are done" - layout="topleft" - left="16" - name="wait_anim_check" - top_pad="10" - width="100" /> - <check_box - follows="top|left" - height="20" - label="time in seconds" - layout="topleft" - left_delta="0" - name="wait_time_check" - top_pad="10" - width="100" /> - <line_editor - follows="top|left" - height="20" - layout="topleft" - left_pad="5" - max_length="15" - name="wait_time_editor" - top_pad="10" - width="50" /--> - - - - <!--For pop out floater--> - <!--scroll_list - follows="top|left" - height="110" - layout="topleft" - left="10" - name="library_list" - top_pad="10" - width="260"> - <scroll_list.rows - value="Animation" /> - <scroll_list.rows - value="Sound" /> - <scroll_list.rows - value="Chat" /> - <scroll_list.rows - value="Wait" /> - </scroll_list> - <text - type="string" - length="1" - follows="top|left" - font="SansSerifSmall" - height="60" - layout="topleft" - left="10" - name="help_label" - top_pad="10" - width="200"> - All steps happen simultaneously, -unless you add wait steps. - </text> - <text - follows="top|left" - height="60" - layout="topleft" - left="10" - name="options_text" - top_pad="10" - width="205" /> - <combo_box - follows="top|left" - height="20" - layout="topleft" - left_delta="10" - name="animation_list" - top_pad="10" - width="100" /> - <combo_box - follows="top|left" - height="20" - layout="topleft" - left_delta="0" - name="sound_list" - top_delta="0" - width="100" /> - <line_editor - follows="top|left" - height="20" - layout="topleft" - left_delta="0" - max_length="127" - name="chat_editor" - top_delta="0" - width="100" /> - <radio_group - draw_border="false" - follows="top|left" - height="40" - layout="topleft" - left_pad="8" - name="animation_trigger_type" - top="445" - width="80"> - <radio_item - height="16" - label="Start" - layout="topleft" - left="3" - name="start" - top="-11" - width="80" /> - <radio_item - height="16" - label="Stop" - layout="topleft" - left_delta="0" - name="stop" - top_pad="10" - width="80" /> - </radio_group> - <check_box - follows="top|left" - height="20" - label="until animations are done" - layout="topleft" - left="16" - name="wait_anim_check" - top="430" - width="100" /> - <check_box - follows="top|left" - height="20" - label="time in seconds" - layout="topleft" - left_delta="0" - name="wait_time_check" - top_delta="20" - width="100" /> - <line_editor - follows="top|left" - height="20" - layout="topleft" - left_pad="5" - max_length="15" - name="wait_time_editor" - top_delta="0" - width="50" /--> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_search.xml b/indra/newview/skins/default/xui/en/floater_search.xml index 354f1de85e..8770ede7e9 100644 --- a/indra/newview/skins/default/xui/en/floater_search.xml +++ b/indra/newview/skins/default/xui/en/floater_search.xml @@ -38,6 +38,7 @@ user_resize="false" width="630"> <web_browser + trusted_content="true" follows="left|right|top|bottom" layout="topleft" left="0" diff --git a/indra/newview/skins/default/xui/en/floater_statistics.xml b/indra/newview/skins/default/xui/en/floater_statistics.xml deleted file mode 100644 index 3a4e845141..0000000000 --- a/indra/newview/skins/default/xui/en/floater_statistics.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - can_resize="true" - follows="right|top" - height="392" - layout="topleft" - mouse_opaque="false" - name="stats floater" - help_topic="stats_floater" - title="STATISTICS" - width="250" /> diff --git a/indra/newview/skins/default/xui/en/floater_test_checkbox.xml b/indra/newview/skins/default/xui/en/floater_test_checkbox.xml index 1935edfcc1..95aaadfcf3 100644 --- a/indra/newview/skins/default/xui/en/floater_test_checkbox.xml +++ b/indra/newview/skins/default/xui/en/floater_test_checkbox.xml @@ -41,7 +41,7 @@ layout="topleft" left_delta="0" name="text_enabled_color_checkbox" - text_enabled_color="EmphasisColor" + label_text.text_color="EmphasisColor" top_pad="14" width="150" /> <check_box @@ -51,7 +51,7 @@ layout="topleft" left_delta="0" name="text_disabled_color_checkbox" - text_disabled_color="EmphasisColor_35" + label_text.text_readonly_color="EmphasisColor_35" top_pad="14" width="150" /> <check_box diff --git a/indra/newview/skins/default/xui/en/floater_test_widgets.xml b/indra/newview/skins/default/xui/en/floater_test_widgets.xml index fb583114c0..13c850c86c 100644 --- a/indra/newview/skins/default/xui/en/floater_test_widgets.xml +++ b/indra/newview/skins/default/xui/en/floater_test_widgets.xml @@ -79,7 +79,7 @@ follows="top|left" left="10" height="16"> - For widget list see https://wiki.lindenlab.com/wiki/Viewer:UI/Widgets + For widget list see http://wiki.secondlife.com/wiki/XUI_Reference </text> <!-- First column --> diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 1d58e7a540..cea2ba2c7f 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -255,7 +255,7 @@ label="Edit linked" layout="topleft" name="checkbox edit linked parts" - top_pad="0"> + top_pad="2"> <check_box.commit_callback function="BuildTool.selectComponent"/> </check_box> @@ -267,7 +267,7 @@ left="13" name="RenderingCost" tool_tip="Shows the rendering cost calculated for this object" - top_pad="2" + top_pad="0" type="string" width="100"> þ: [COUNT] @@ -732,7 +732,7 @@ layout="topleft" right="-10" name="obj_count" - top_pad="5" + top_pad="7" width="143"> Objects: [COUNT] </text> @@ -758,7 +758,7 @@ tab_min_width="40" tab_position="top" tab_height="25" - top="170" + top="173" width="295"> <panel border="false" @@ -2022,12 +2022,13 @@ even though the user gets a free copy. type="string" length="1" follows="left|top" - height="10" + height="20" layout="topleft" left="10" name="select_single" top="5" - width="252"> + width="252" + word_wrap="true"> Select only one primitive to edit features. </text> <text @@ -2049,7 +2050,7 @@ even though the user gets a free copy. left="10" name="Flexible1D Checkbox Ctrl" tool_tip="Allows object to flex about the Z axis (Client-side only)" - top_pad="10" + top_pad="20" width="121" /> <spinner follows="left|top" diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml index cbfaac958b..af1617eb39 100644 --- a/indra/newview/skins/default/xui/en/floater_tos.xml +++ b/indra/newview/skins/default/xui/en/floater_tos.xml @@ -58,6 +58,7 @@ Please read the following Terms of Service and Privacy Policy carefully. To continue logging in to [SECOND_LIFE], you must accept the agreement. </text> <web_browser + trusted_content="true" follows="left|top" height="340" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml index bf5bd87ad6..1432099590 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml @@ -86,6 +86,7 @@ visible="true" width="20" /> </layout_panel> + <layout_panel name="leave_call_panel" height="26" auto_resize="false"> <layout_stack clip="true" auto_resize="false" @@ -96,11 +97,15 @@ name="voice_effect_and_leave_call_stack" orientation="horizontal" width="262"> - <panel - class="panel_voice_effect" - name="panel_voice_effect" - visiblity_control="VoiceMorphingEnabled" - filename="panel_voice_effect.xml" /> + <layout_panel + height="26" + width="200"> + <panel + class="panel_voice_effect" + name="panel_voice_effect" + visiblity_control="VoiceMorphingEnabled" + filename="panel_voice_effect.xml" /> + </layout_panel> <layout_panel auto_resize="false" user_resize="false" @@ -118,6 +123,7 @@ width="100" /> </layout_panel> </layout_stack> + </layout_panel> <layout_panel follows="all" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_wearable_save_as.xml b/indra/newview/skins/default/xui/en/floater_wearable_save_as.xml deleted file mode 100644 index 71812bd1a6..0000000000 --- a/indra/newview/skins/default/xui/en/floater_wearable_save_as.xml +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="0" - can_close="false" - can_minimize="false" - height="100" - layout="topleft" - name="modal container" - width="240"> - <button - height="23" - label="Save" - label_selected="Save" - layout="topleft" - left="20" - name="Save" - top="70" - width="82" /> - <button - height="23" - label="Cancel" - label_selected="Cancel" - layout="topleft" - left_pad="36" - name="Cancel" - top_delta="0" - width="82" /> - <text - type="string" - length="1" - follows="left|top" - height="30" - layout="topleft" - word_wrap="true" - left="20" - name="Save item as:" - top="10" - width="200"> - Save item to my inventory as: - </text> - <line_editor - type="string" - length="1" - border_style="line" - border_thickness="1" - follows="left|top" - height="23" - layout="topleft" - left_delta="0" - max_length="63" - name="name ed" - top_pad="0" - width="200"> - New [DESC] - </line_editor> -</floater> diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml index a1ca910cbb..8d9ebf6e06 100644 --- a/indra/newview/skins/default/xui/en/main_view.xml +++ b/indra/newview/skins/default/xui/en/main_view.xml @@ -20,6 +20,7 @@ mouse_opaque="false" name="nav_bar_container" tab_stop="false" + min_height="10" width="1024" user_resize="false" visible="false"> @@ -65,25 +66,24 @@ mouse_opaque="false" name="world_stack" orientation="vertical"> - <panel auto_resize="true" - follows="all" - height="500" - layout="topleft" - tab_stop="false" - mouse_opaque="false" - name="hud container" - width="500"> - <panel auto_resize="false" - follows="left|top" - height="19" - left="0" - mouse_opaque="false" - name="topinfo_bar_container" - tab_stop="false" - top="0" - user_resize="false" - visible="false" - width="1024"/> + <layout_panel auto_resize="true" + follows="all" + height="500" + layout="topleft" + tab_stop="false" + mouse_opaque="false" + user_resize="false" + name="hud container" + width="500"> + <panel follows="left|top" + height="19" + left="0" + mouse_opaque="false" + name="topinfo_bar_container" + tab_stop="false" + top="0" + visible="false" + width="1024"/> <panel follows="right|top|bottom" height="500" mouse_opaque="false" @@ -101,10 +101,10 @@ name="stand_stop_flying_container" visible="false" width="500"/> - </panel> + </layout_panel> <layout_panel auto_resize="false" - follows="all" min_height="33" + height="33" mouse_opaque="false" name="bottom_tray_container" visible="false"/> @@ -112,7 +112,7 @@ </layout_panel> <!-- side tray --> <layout_panel auto_resize="false" - follows="all" + follows="top|bottom" height="500" min_width="333" mouse_opaque="false" @@ -187,15 +187,6 @@ <panel top="0" follows="all" height="768" - mouse_opaque="true" - name="progress_view" - filename="panel_progress.xml" - class="progress_view" - width="1024" - visible="false"/> - <panel top="0" - follows="all" - height="768" mouse_opaque="false" name="popup_holder" class="popup_holder" @@ -208,6 +199,22 @@ bottom="-1" height="11" /> </panel> + <view top="0" + left="0" + width="1024" + height="768" + name="hint_holder" + mouse_opaque="false" + follows="all"/> + <panel top="0" + follows="all" + height="768" + mouse_opaque="true" + name="progress_view" + filename="panel_progress.xml" + class="progress_view" + width="1024" + visible="false"/> <menu_holder top="0" follows="all" height="768" diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml index 9059745f46..2afa29ec10 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml @@ -23,11 +23,11 @@ function="Self.EnableStandUp" /> </menu_item_call> <context_menu - label="Take Off ▶" + label="Take Off" layout="topleft" name="Take Off >"> <context_menu - label="Clothes ▶" + label="Clothes" layout="topleft" name="Clothes >"> <menu_item_call @@ -174,11 +174,11 @@ </menu_item_call> </context_menu> <context_menu - label="HUD ▶" + label="HUD" layout="topleft" name="Object Detach HUD" /> <context_menu - label="Detach ▶" + label="Detach" layout="topleft" name="Object Detach" /> <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml index 31f70d99ca..c751aa4e0c 100644 --- a/indra/newview/skins/default/xui/en/menu_object.xml +++ b/indra/newview/skins/default/xui/en/menu_object.xml @@ -72,7 +72,7 @@ </menu_item_call> <menu_item_separator layout="topleft" /> <context_menu - label="Put On ▶" + label="Put On" name="Put On" > <menu_item_call enabled="false" @@ -93,14 +93,14 @@ function="Object.EnableWear" /> </menu_item_call> <context_menu - label="Attach ▶" + label="Attach" name="Object Attach" /> <context_menu - label="Attach HUD ▶" + label="Attach HUD" name="Object Attach HUD" /> </context_menu> <context_menu - label="Remove ▶" + label="Remove" name="Remove"> <menu_item_call enabled="false" diff --git a/indra/newview/skins/default/xui/en/menu_participant_list.xml b/indra/newview/skins/default/xui/en/menu_participant_list.xml index 4ed5807808..2c32d9d303 100644 --- a/indra/newview/skins/default/xui/en/menu_participant_list.xml +++ b/indra/newview/skins/default/xui/en/menu_participant_list.xml @@ -130,7 +130,7 @@ layout="topleft" name="Moderator Options Separator"/> <context_menu - label="Moderator Options >" + label="Moderator Options" layout="topleft" name="Moderator Options"> <menu_item_check diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 6359f3dfed..6b92ec028d 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -670,6 +670,14 @@ <menu_item_call.on_enable function="Tools.EnableSaveToObjectInventory" /> </menu_item_call> + <menu_item_call + label="Return Object" + name="Return Object back to Owner"> + <menu_item_call.on_click + function="Object.Return" /> + <menu_item_call.on_enable + function="Object.EnableReturn" /> + </menu_item_call> </menu> <menu create_jump_keys="true" @@ -773,6 +781,16 @@ <menu_item_separator/> <menu_item_check + label="Show Selection Outlines" + name="Show Selection Outlines"> + <menu_item_check.on_check + function="CheckControl" + parameter="RenderHighlightSelections" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="RenderHighlightSelections" /> + </menu_item_check> + <menu_item_check label="Show Hidden Selection" name="Show Hidden Selection"> <menu_item_check.on_check @@ -950,6 +968,14 @@ function="Floater.Show" parameter="sl_about" /> </menu_item_call> + <menu_item_check + label="Enable Hints" + name="Enable Hints"> + <on_check + control="EnableUIHints"/> + <on_click + function="ToggleUIHints"/> + </menu_item_check> </menu> <menu create_jump_keys="true" @@ -1669,8 +1695,8 @@ </menu_item_call> <menu_item_separator visible="false"/> - <!-- Made invisible to avoid a dissonance: menu item toggle menu where it is located. EXT-8069. - Can't be removed to keep sortcut workable. + <!-- Made invisible to avoid a dissonance: menu item toggles the menu where it is located. EXT-8069. + Can't be removed, to keep shortcut workable. --> <menu_item_check label="Show Advanced Menu" @@ -2639,6 +2665,16 @@ parameter="DoubleClickAutoPilot" /> </menu_item_check> <menu_item_check + label="Double-Click Teleport" + name="DoubleClick Teleport"> + <menu_item_check.on_check + function="CheckControl" + parameter="DoubleClickTeleport" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="DoubleClickTeleport" /> + </menu_item_check> + <menu_item_check label="Region Debug Console" name="Region Debug Console" shortcut="control|shift|`" diff --git a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml index 5feac53c33..aa56b4ba63 100644 --- a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml +++ b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml @@ -37,11 +37,11 @@ function="Attachment.Detach" /> </menu_item_call> <context_menu - label="Attach to ▶" + label="Attach to" layout="topleft" name="wearable_attach_to" /> <context_menu - label="Attach to HUD ▶" + label="Attach to HUD" layout="topleft" name="wearable_attach_to_hud" /> <menu_item_call diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 609a9b09be..e1aecda151 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml |
