summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/CMakeLists.txt4
-rw-r--r--indra/llcommon/llerrorlegacy.h4
-rw-r--r--indra/llcommon/llfasttimer.h302
-rw-r--r--indra/llcommon/llfasttimer_class.cpp751
-rw-r--r--indra/llcommon/llfasttimer_class.h272
-rw-r--r--indra/llcommon/llpreprocessor.h15
-rw-r--r--indra/llrender/llimagegl.cpp43
-rw-r--r--indra/llrender/llimagegl.h2
-rw-r--r--indra/llui/llaccordionctrl.cpp75
-rw-r--r--indra/llui/llaccordionctrl.h9
-rw-r--r--indra/llui/llaccordionctrltab.cpp34
-rw-r--r--indra/llui/llaccordionctrltab.h1
-rw-r--r--indra/llui/lllineeditor.cpp6
-rw-r--r--indra/llui/llscrolllistctrl.cpp10
-rw-r--r--indra/llui/llscrolllistctrl.h1
-rw-r--r--indra/llui/llscrolllistitem.h2
-rw-r--r--indra/llui/lltextbase.cpp59
-rw-r--r--indra/llui/lltextbase.h8
-rw-r--r--indra/llui/lltexteditor.cpp14
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/app_settings/settings.xml22
-rw-r--r--indra/newview/gpu_table.txt10
-rw-r--r--indra/newview/llappearancemgr.cpp18
-rw-r--r--indra/newview/llavataractions.cpp20
-rw-r--r--indra/newview/llavataractions.h9
-rw-r--r--indra/newview/llavatarlistitem.cpp12
-rw-r--r--indra/newview/llavatarlistitem.h2
-rw-r--r--indra/newview/llcallfloater.cpp67
-rw-r--r--indra/newview/llcallfloater.h4
-rw-r--r--indra/newview/llchathistory.cpp5
-rw-r--r--indra/newview/llchathistory.h2
-rw-r--r--indra/newview/llcompilequeue.cpp14
-rw-r--r--indra/newview/llfloaterabout.cpp6
-rw-r--r--indra/newview/llfloatergroups.cpp2
-rw-r--r--indra/newview/llfloaterpreference.cpp38
-rw-r--r--indra/newview/llfloaterpreference.h4
-rw-r--r--indra/newview/llfloaterreporter.cpp2
-rw-r--r--indra/newview/llfloaterscriptlimits.cpp11
-rw-r--r--indra/newview/llgrouplist.cpp4
-rw-r--r--indra/newview/llimview.cpp58
-rw-r--r--indra/newview/llimview.h17
-rw-r--r--indra/newview/llinspectavatar.cpp1
-rw-r--r--indra/newview/llmoveview.cpp15
-rw-r--r--indra/newview/llmutelist.cpp76
-rw-r--r--indra/newview/llmutelist.h9
-rw-r--r--indra/newview/llnamelistctrl.cpp21
-rw-r--r--indra/newview/llnamelistctrl.h21
-rw-r--r--indra/newview/llnearbychat.cpp5
-rw-r--r--indra/newview/llnearbychathandler.cpp5
-rw-r--r--indra/newview/llnotificationhandlerutil.cpp9
-rw-r--r--indra/newview/llpanelavatar.cpp48
-rw-r--r--indra/newview/llpanelavatar.h16
-rw-r--r--indra/newview/llpanelgroup.cpp33
-rw-r--r--indra/newview/llpanelgroup.h8
-rw-r--r--indra/newview/llpanelgrouproles.cpp10
-rw-r--r--indra/newview/llpanelimcontrolpanel.cpp54
-rw-r--r--indra/newview/llpanelimcontrolpanel.h12
-rw-r--r--indra/newview/llpanellandmarkinfo.cpp8
-rw-r--r--indra/newview/llpanelme.cpp2
-rw-r--r--indra/newview/llpanelpeople.cpp45
-rw-r--r--indra/newview/llpanelpeople.h9
-rw-r--r--indra/newview/llpanelpeoplemenus.cpp15
-rw-r--r--indra/newview/llpanelplaceinfo.cpp18
-rw-r--r--indra/newview/llpanelplaceprofile.cpp80
-rw-r--r--indra/newview/llpanelplaces.cpp24
-rw-r--r--indra/newview/llpanelplaces.h6
-rw-r--r--indra/newview/llpanelprofileview.cpp54
-rw-r--r--indra/newview/llpanelprofileview.h20
-rw-r--r--indra/newview/llparticipantlist.cpp10
-rw-r--r--indra/newview/llspeakers.cpp2
-rw-r--r--indra/newview/lltoolpie.cpp3
-rw-r--r--indra/newview/lltransientdockablefloater.cpp24
-rw-r--r--indra/newview/lltransientfloatermgr.cpp4
-rw-r--r--indra/newview/lltransientfloatermgr.h2
-rw-r--r--indra/newview/llviewerfloaterreg.cpp1
-rw-r--r--indra/newview/llviewerhelp.cpp40
-rw-r--r--indra/newview/llviewerinventory.h2
-rw-r--r--indra/newview/llviewermedia.cpp2
-rw-r--r--indra/newview/llviewermenu.cpp15
-rw-r--r--indra/newview/llviewermessage.cpp58
-rw-r--r--indra/newview/llviewerparcelmedia.cpp2
-rw-r--r--indra/newview/llviewertexture.cpp1
-rw-r--r--indra/newview/llvoicechannel.cpp12
-rw-r--r--indra/newview/llvoiceclient.cpp127
-rw-r--r--indra/newview/llvoiceclient.h2
-rw-r--r--indra/newview/skins/default/xui/en/floater_aaa.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_search.xml8
-rw-r--r--indra/newview/skins/default/xui/en/floater_voice_controls.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_attachment_other.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_avatar_other.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_login.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_participant_list.xml3
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_avatar_list_item.xml28
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_land_money.xml90
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_privacy.xml20
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_teleport_history_item.xml1
-rw-r--r--indra/newview/skins/default/xui/fr/floater_bulk_perms.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_buy_currency.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/menu_viewer.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_edit_skin.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/panel_main_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_notes.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/panel_people.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_preferences_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/panel_preferences_general.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_view.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/strings.xml58
115 files changed, 2278 insertions, 877 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index ac7cc2cdac..9ead183a9e 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -50,7 +50,7 @@ set(llcommon_SOURCE_FILES
lleventdispatcher.cpp
lleventfilter.cpp
llevents.cpp
- llfasttimer.cpp
+ llfasttimer_class.cpp
llfile.cpp
llfindlocale.cpp
llfixedbuffer.cpp
@@ -250,7 +250,7 @@ list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
if(LLCOMMON_LINK_SHARED)
add_library (llcommon SHARED ${llcommon_SOURCE_FILES})
- ll_stage_sharedlib(llcommon)
+ ll_stage_sharedlib(llcommon)
else(LLCOMMON_LINK_SHARED)
add_library (llcommon ${llcommon_SOURCE_FILES})
endif(LLCOMMON_LINK_SHARED)
diff --git a/indra/llcommon/llerrorlegacy.h b/indra/llcommon/llerrorlegacy.h
index 9920921a58..476d75380f 100644
--- a/indra/llcommon/llerrorlegacy.h
+++ b/indra/llcommon/llerrorlegacy.h
@@ -34,7 +34,7 @@
#ifndef LL_LLERRORLEGACY_H
#define LL_LLERRORLEGACY_H
-
+#include "llpreprocessor.h"
/*
LEGACY -- DO NOT USE THIS STUFF ANYMORE
@@ -107,7 +107,7 @@ const int LL_ERR_PRICE_MISMATCH = -23018;
#define llwarning(msg, num) llwarns << "Warning # " << num << ": " << msg << llendl;
-#define llassert_always(func) if (!(func)) llerrs << "ASSERT (" << #func << ")" << llendl;
+#define llassert_always(func) if (LL_UNLIKELY(!(func))) llerrs << "ASSERT (" << #func << ")" << llendl;
#ifdef SHOW_ASSERT
#define llassert(func) llassert_always(func)
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 8af79c90fd..48461df6ae 100644
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -1,6 +1,6 @@
/**
* @file llfasttimer.h
- * @brief Declaration of a fast timer.
+ * @brief Inline implementations of fast timers.
*
* $LicenseInfo:firstyear=2004&license=viewergpl$
*
@@ -33,13 +33,13 @@
#ifndef LL_FASTTIMER_H
#define LL_FASTTIMER_H
-#include "llinstancetracker.h"
-
-#define FAST_TIMER_ON 1
-#define TIME_FAST_TIMERS 0
+// pull in the actual class definition
+#include "llfasttimer_class.h"
#if LL_WINDOWS
-#define LL_INLINE __forceinline
+//
+// Windows implementation of CPU clock
+//
//
// NOTE: put back in when we aren't using platform sdk anymore
@@ -52,21 +52,21 @@
//#undef _interlockedbittestandset
//#undef _interlockedbittestandreset
-//inline U32 get_cpu_clock_count_32()
+//inline U32 LLFastTimer::getCPUClockCount32()
//{
// U64 time_stamp = __rdtsc();
// return (U32)(time_stamp >> 8);
//}
//
//// return full timer value, *not* shifted by 8 bits
-//inline U64 get_cpu_clock_count_64()
+//inline U64 LLFastTimer::getCPUClockCount64()
//{
// return __rdtsc();
//}
// shift off lower 8 bits for lower resolution but longer term timing
// on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing
-inline U32 get_cpu_clock_count_32()
+inline U32 LLFastTimer::getCPUClockCount32()
{
U32 ret_val;
__asm
@@ -82,7 +82,7 @@ inline U32 get_cpu_clock_count_32()
}
// return full timer value, *not* shifted by 8 bits
-inline U64 get_cpu_clock_count_64()
+inline U64 LLFastTimer::getCPUClockCount64()
{
U64 ret_val;
__asm
@@ -96,269 +96,71 @@ inline U64 get_cpu_clock_count_64()
}
return ret_val;
}
-#else
-#define LL_INLINE
#endif
-#if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__))
-inline U32 get_cpu_clock_count_32()
+
+#if LL_LINUX || LL_SOLARIS
+//
+// Linux and Solaris implementation of CPU clock - all architectures.
+//
+// Try to use the MONOTONIC clock if available, this is a constant time counter
+// with nanosecond resolution (but not necessarily accuracy) and attempts are made
+// to synchronize this value between cores at kernel start. It should not be affected
+// by CPU frequency. If not available use the REALTIME clock, but this may be affected by
+// NTP adjustments or other user activity affecting the system time.
+inline U64 LLFastTimer::getCPUClockCount64()
+{
+ struct timespec tp;
+
+#ifdef CLOCK_MONOTONIC // MONOTONIC supported at build-time?
+ if (-1 == clock_gettime(CLOCK_MONOTONIC,&tp)) // if MONOTONIC isn't supported at runtime then ouch, try REALTIME
+#endif
+ clock_gettime(CLOCK_REALTIME,&tp);
+
+ return (tp.tv_sec*LLFastTimer::sClockResolution)+tp.tv_nsec;
+}
+
+inline U32 LLFastTimer::getCPUClockCount32()
+{
+ return (U32)(LLFastTimer::getCPUClockCount64() >> 8);
+}
+#endif // (LL_LINUX || LL_SOLARIS))
+
+
+#if (LL_DARWIN) && (defined(__i386__) || defined(__amd64__))
+//
+// Mac x86 implementation of CPU clock
+inline U32 LLFastTimer::getCPUClockCount32()
{
U64 x;
__asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
- return (U32)x >> 8;
+ return (U32)(x >> 8);
}
-inline U32 get_cpu_clock_count_64()
+inline U64 LLFastTimer::getCPUClockCount64()
{
U64 x;
__asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
- return x >> 8;
+ return x;
}
#endif
-#if ( LL_DARWIN && !(defined(__i386__) || defined(__amd64__))) || (LL_SOLARIS && defined(__sparc__))
+
+#if ( LL_DARWIN && !(defined(__i386__) || defined(__amd64__)))
//
-// Mac PPC (deprecated) & Solaris SPARC implementation of CPU clock
+// Mac PPC (deprecated) implementation of CPU clock
//
// Just use gettimeofday implementation for now
-inline U32 get_cpu_clock_count_32()
+inline U32 LLFastTimer::getCPUClockCount32()
{
- return (U32)get_clock_count();
+ return (U32)(get_clock_count()>>8);
}
-inline U32 get_cpu_clock_count_64()
+inline U64 LLFastTimer::getCPUClockCount64()
{
return get_clock_count();
}
#endif
-class LLMutex;
-
-#include <queue>
-#include "llsd.h"
-
-class LL_COMMON_API LLFastTimer
-{
-public:
-
- class NamedTimer;
-
- struct LL_COMMON_API FrameState
- {
- FrameState(NamedTimer* timerp);
-
- U32 mSelfTimeCounter;
- U32 mCalls;
- FrameState* mParent; // info for caller timer
- FrameState* mLastCaller; // used to bootstrap tree construction
- NamedTimer* mTimer;
- U16 mActiveCount; // number of timers with this ID active on stack
- bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame
- };
-
- // stores a "named" timer instance to be reused via multiple LLFastTimer stack instances
- class LL_COMMON_API NamedTimer
- : public LLInstanceTracker<NamedTimer>
- {
- friend class DeclareTimer;
- public:
- ~NamedTimer();
-
- enum { HISTORY_NUM = 60 };
-
- const std::string& getName() const { return mName; }
- NamedTimer* getParent() const { return mParent; }
- void setParent(NamedTimer* parent);
- S32 getDepth();
- std::string getToolTip(S32 history_index = -1);
-
- typedef std::vector<NamedTimer*>::const_iterator child_const_iter;
- child_const_iter beginChildren();
- child_const_iter endChildren();
- std::vector<NamedTimer*>& getChildren();
-
- void setCollapsed(bool collapsed) { mCollapsed = collapsed; }
- bool getCollapsed() const { return mCollapsed; }
-
- U32 getCountAverage() const { return mCountAverage; }
- U32 getCallAverage() const { return mCallAverage; }
-
- U32 getHistoricalCount(S32 history_index = 0) const;
- U32 getHistoricalCalls(S32 history_index = 0) const;
-
- static NamedTimer& getRootNamedTimer();
-
- S32 getFrameStateIndex() const { return mFrameStateIndex; }
-
- FrameState& getFrameState() const;
-
- private:
- friend class LLFastTimer;
- friend class NamedTimerFactory;
-
- //
- // methods
- //
- NamedTimer(const std::string& name);
- // recursive call to gather total time from children
- static void accumulateTimings();
-
- // updates cumulative times and hierarchy,
- // can be called multiple times in a frame, at any point
- static void processTimes();
-
- static void buildHierarchy();
- static void resetFrame();
- static void reset();
-
- //
- // members
- //
- S32 mFrameStateIndex;
-
- std::string mName;
-
- U32 mTotalTimeCounter;
-
- U32 mCountAverage;
- U32 mCallAverage;
-
- U32* mCountHistory;
- U32* mCallHistory;
-
- // tree structure
- NamedTimer* mParent; // NamedTimer of caller(parent)
- std::vector<NamedTimer*> mChildren;
- bool mCollapsed; // don't show children
- bool mNeedsSorting; // sort children whenever child added
- };
-
- // used to statically declare a new named timer
- class LL_COMMON_API DeclareTimer
- : public LLInstanceTracker<DeclareTimer>
- {
- friend class LLFastTimer;
- public:
- DeclareTimer(const std::string& name, bool open);
- DeclareTimer(const std::string& name);
-
- static void updateCachedPointers();
-
- private:
- NamedTimer& mTimer;
- FrameState* mFrameState;
- };
-
-public:
- LLFastTimer(LLFastTimer::FrameState* state);
-
- LL_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer)
- : mFrameState(timer.mFrameState)
- {
-#if TIME_FAST_TIMERS
- U64 timer_start = get_cpu_clock_count_64();
-#endif
-#if FAST_TIMER_ON
- LLFastTimer::FrameState* frame_state = mFrameState;
- mStartTime = get_cpu_clock_count_32();
-
- frame_state->mActiveCount++;
- frame_state->mCalls++;
- // keep current parent as long as it is active when we are
- frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0);
-
- LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData;
- mLastTimerData = *cur_timer_data;
- cur_timer_data->mCurTimer = this;
- cur_timer_data->mFrameState = frame_state;
- cur_timer_data->mChildTime = 0;
-#endif
-#if TIME_FAST_TIMERS
- U64 timer_end = get_cpu_clock_count_64();
- sTimerCycles += timer_end - timer_start;
-#endif
- }
-
- LL_INLINE ~LLFastTimer()
- {
-#if TIME_FAST_TIMERS
- U64 timer_start = get_cpu_clock_count_64();
-#endif
-#if FAST_TIMER_ON
- LLFastTimer::FrameState* frame_state = mFrameState;
- U32 total_time = get_cpu_clock_count_32() - mStartTime;
-
- frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime;
- frame_state->mActiveCount--;
-
- // store last caller to bootstrap tree creation
- // do this in the destructor in case of recursion to get topmost caller
- frame_state->mLastCaller = mLastTimerData.mFrameState;
-
- // we are only tracking self time, so subtract our total time delta from parents
- mLastTimerData.mChildTime += total_time;
-
- LLFastTimer::sCurTimerData = mLastTimerData;
-#endif
-#if TIME_FAST_TIMERS
- U64 timer_end = get_cpu_clock_count_64();
- sTimerCycles += timer_end - timer_start;
- sTimerCalls++;
-#endif
- }
-
-public:
- static LLMutex* sLogLock;
- static std::queue<LLSD> sLogQueue;
- static BOOL sLog;
- static BOOL sMetricLog;
- static bool sPauseHistory;
- static bool sResetHistory;
- static U64 sTimerCycles;
- static U32 sTimerCalls;
-
- typedef std::vector<FrameState> info_list_t;
- static info_list_t& getFrameStateList();
-
-
- // call this once a frame to reset timers
- static void nextFrame();
-
- // dumps current cumulative frame stats to log
- // call nextFrame() to reset timers
- static void dumpCurTimes();
-
- // call this to reset timer hierarchy, averages, etc.
- static void reset();
-
- static U64 countsPerSecond();
- static S32 getLastFrameIndex() { return sLastFrameIndex; }
- static S32 getCurFrameIndex() { return sCurFrameIndex; }
-
- static void writeLog(std::ostream& os);
- static const NamedTimer* getTimerByName(const std::string& name);
-
- struct CurTimerData
- {
- LLFastTimer* mCurTimer;
- FrameState* mFrameState;
- U32 mChildTime;
- };
- static CurTimerData sCurTimerData;
-
-private:
- static S32 sCurFrameIndex;
- static S32 sLastFrameIndex;
- static U64 sLastFrameTime;
- static info_list_t* sTimerInfos;
-
- U32 mStartTime;
- LLFastTimer::FrameState* mFrameState;
- LLFastTimer::CurTimerData mLastTimerData;
-
-};
-
-typedef class LLFastTimer LLFastTimer;
-
#endif // LL_LLFASTTIMER_H
diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer_class.cpp
new file mode 100644
index 0000000000..fae0a66873
--- /dev/null
+++ b/indra/llcommon/llfasttimer_class.cpp
@@ -0,0 +1,751 @@
+/**
+ * @file llfasttimer_class.cpp
+ * @brief Implementation of the fast timer.
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS."LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "linden_common.h"
+
+#include "llfasttimer.h"
+
+#include "llmemory.h"
+#include "llprocessor.h"
+#include "llsingleton.h"
+#include "lltreeiterators.h"
+#include "llsdserialize.h"
+
+#include <boost/bind.hpp>
+
+#if LL_WINDOWS
+#elif LL_LINUX || LL_SOLARIS
+#include <sys/time.h>
+#include <sched.h>
+#elif LL_DARWIN
+#include <sys/time.h>
+#include "lltimer.h" // get_clock_count()
+#else
+#error "architecture not supported"
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// statics
+
+S32 LLFastTimer::sCurFrameIndex = -1;
+S32 LLFastTimer::sLastFrameIndex = -1;
+U64 LLFastTimer::sLastFrameTime = LLFastTimer::getCPUClockCount64();
+bool LLFastTimer::sPauseHistory = 0;
+bool LLFastTimer::sResetHistory = 0;
+LLFastTimer::CurTimerData LLFastTimer::sCurTimerData;
+BOOL LLFastTimer::sLog = FALSE;
+BOOL LLFastTimer::sMetricLog = FALSE;
+LLMutex* LLFastTimer::sLogLock = NULL;
+std::queue<LLSD> LLFastTimer::sLogQueue;
+
+#if LL_LINUX || LL_SOLARIS
+U64 LLFastTimer::sClockResolution = 1000000000; // Nanosecond resolution
+#else
+U64 LLFastTimer::sClockResolution = 1000000; // Microsecond resolution
+#endif
+
+std::vector<LLFastTimer::FrameState>* LLFastTimer::sTimerInfos = NULL;
+U64 LLFastTimer::sTimerCycles = 0;
+U32 LLFastTimer::sTimerCalls = 0;
+
+
+// FIXME: move these declarations to the relevant modules
+
+// helper functions
+typedef LLTreeDFSPostIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_bottom_up_iterator_t;
+
+static timer_tree_bottom_up_iterator_t begin_timer_tree_bottom_up(LLFastTimer::NamedTimer& id)
+{
+ return timer_tree_bottom_up_iterator_t(&id,
+ boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),
+ boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
+}
+
+static timer_tree_bottom_up_iterator_t end_timer_tree_bottom_up()
+{
+ return timer_tree_bottom_up_iterator_t();
+}
+
+typedef LLTreeDFSIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_dfs_iterator_t;
+
+
+static timer_tree_dfs_iterator_t begin_timer_tree(LLFastTimer::NamedTimer& id)
+{
+ return timer_tree_dfs_iterator_t(&id,
+ boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),
+ boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
+}
+
+static timer_tree_dfs_iterator_t end_timer_tree()
+{
+ return timer_tree_dfs_iterator_t();
+}
+
+
+
+// factory class that creates NamedTimers via static DeclareTimer objects
+class NamedTimerFactory : public LLSingleton<NamedTimerFactory>
+{
+public:
+ NamedTimerFactory()
+ {}
+
+ /*virtual */ void initSingleton()
+ {
+ mTimerRoot = new LLFastTimer::NamedTimer("root");
+
+ mActiveTimerRoot = new LLFastTimer::NamedTimer("Frame");
+ mActiveTimerRoot->setCollapsed(false);
+
+ mRootFrameState = new LLFastTimer::FrameState(mActiveTimerRoot);
+ mRootFrameState->mParent = &mTimerRoot->getFrameState();
+ mActiveTimerRoot->setParent(mTimerRoot);
+
+ mAppTimer = new LLFastTimer(mRootFrameState);
+ }
+
+ ~NamedTimerFactory()
+ {
+ std::for_each(mTimers.begin(), mTimers.end(), DeletePairedPointer());
+
+ delete mAppTimer;
+ delete mActiveTimerRoot;
+ delete mTimerRoot;
+ delete mRootFrameState;
+ }
+
+ LLFastTimer::NamedTimer& createNamedTimer(const std::string& name)
+ {
+ timer_map_t::iterator found_it = mTimers.find(name);
+ if (found_it != mTimers.end())
+ {
+ return *found_it->second;
+ }
+
+ LLFastTimer::NamedTimer* timer = new LLFastTimer::NamedTimer(name);
+ timer->setParent(mTimerRoot);
+ mTimers.insert(std::make_pair(name, timer));
+
+ return *timer;
+ }
+
+ LLFastTimer::NamedTimer* getTimerByName(const std::string& name)
+ {
+ timer_map_t::iterator found_it = mTimers.find(name);
+ if (found_it != mTimers.end())
+ {
+ return found_it->second;
+ }
+ return NULL;
+ }
+
+ LLFastTimer::NamedTimer* getActiveRootTimer() { return mActiveTimerRoot; }
+ LLFastTimer::NamedTimer* getRootTimer() { return mTimerRoot; }
+ const LLFastTimer* getAppTimer() { return mAppTimer; }
+ LLFastTimer::FrameState& getRootFrameState() { return *mRootFrameState; }
+
+ typedef std::map<std::string, LLFastTimer::NamedTimer*> timer_map_t;
+ timer_map_t::iterator beginTimers() { return mTimers.begin(); }
+ timer_map_t::iterator endTimers() { return mTimers.end(); }
+ S32 timerCount() { return mTimers.size(); }
+
+private:
+ timer_map_t mTimers;
+
+ LLFastTimer::NamedTimer* mActiveTimerRoot;
+ LLFastTimer::NamedTimer* mTimerRoot;
+ LLFastTimer* mAppTimer;
+ LLFastTimer::FrameState* mRootFrameState;
+};
+
+void update_cached_pointers_if_changed()
+{
+ // detect when elements have moved and update cached pointers
+ static LLFastTimer::FrameState* sFirstTimerAddress = NULL;
+ if (&*(LLFastTimer::getFrameStateList().begin()) != sFirstTimerAddress)
+ {
+ LLFastTimer::DeclareTimer::updateCachedPointers();
+ }
+ sFirstTimerAddress = &*(LLFastTimer::getFrameStateList().begin());
+}
+
+LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name, bool open )
+: mTimer(NamedTimerFactory::instance().createNamedTimer(name))
+{
+ mTimer.setCollapsed(!open);
+ mFrameState = &mTimer.getFrameState();
+ update_cached_pointers_if_changed();
+}
+
+LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name)
+: mTimer(NamedTimerFactory::instance().createNamedTimer(name))
+{
+ mFrameState = &mTimer.getFrameState();
+ update_cached_pointers_if_changed();
+}
+
+// static
+void LLFastTimer::DeclareTimer::updateCachedPointers()
+{
+ // propagate frame state pointers to timer declarations
+ for (DeclareTimer::instance_iter it = DeclareTimer::beginInstances();
+ it != DeclareTimer::endInstances();
+ ++it)
+ {
+ // update cached pointer
+ it->mFrameState = &it->mTimer.getFrameState();
+ }
+}
+
+//static
+#if LL_LINUX || LL_SOLARIS || ( LL_DARWIN && !(defined(__i386__) || defined(__amd64__)) )
+U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer
+{
+ return sClockResolution >> 8;
+}
+#else // windows or x86-mac
+U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer
+{
+ static U64 sCPUClockFrequency = U64(CProcessor().GetCPUFrequency(50));
+
+ // we drop the low-order byte in out timers, so report a lower frequency
+ return sCPUClockFrequency >> 8;
+}
+#endif
+
+LLFastTimer::FrameState::FrameState(LLFastTimer::NamedTimer* timerp)
+: mActiveCount(0),
+ mCalls(0),
+ mSelfTimeCounter(0),
+ mParent(NULL),
+ mLastCaller(NULL),
+ mMoveUpTree(false),
+ mTimer(timerp)
+{}
+
+
+LLFastTimer::NamedTimer::NamedTimer(const std::string& name)
+: mName(name),
+ mCollapsed(true),
+ mParent(NULL),
+ mTotalTimeCounter(0),
+ mCountAverage(0),
+ mCallAverage(0),
+ mNeedsSorting(false)
+{
+ info_list_t& frame_state_list = getFrameStateList();
+ mFrameStateIndex = frame_state_list.size();
+ getFrameStateList().push_back(FrameState(this));
+
+ mCountHistory = new U32[HISTORY_NUM];
+ memset(mCountHistory, 0, sizeof(U32) * HISTORY_NUM);
+ mCallHistory = new U32[HISTORY_NUM];
+ memset(mCallHistory, 0, sizeof(U32) * HISTORY_NUM);
+}
+
+LLFastTimer::NamedTimer::~NamedTimer()
+{
+ delete[] mCountHistory;
+ delete[] mCallHistory;
+}
+
+std::string LLFastTimer::NamedTimer::getToolTip(S32 history_idx)
+{
+ if (history_idx < 0)
+ {
+ // by default, show average number of calls
+ return llformat("%s (%d calls)", getName().c_str(), (S32)getCallAverage());
+ }
+ else
+ {
+ return llformat("%s (%d calls)", getName().c_str(), (S32)getHistoricalCalls(history_idx));
+ }
+}
+
+void LLFastTimer::NamedTimer::setParent(NamedTimer* parent)
+{
+ llassert_always(parent != this);
+ llassert_always(parent != NULL);
+
+ if (mParent)
+ {
+ // subtract our accumulated from previous parent
+ for (S32 i = 0; i < HISTORY_NUM; i++)
+ {
+ mParent->mCountHistory[i] -= mCountHistory[i];
+ }
+
+ // subtract average timing from previous parent
+ mParent->mCountAverage -= mCountAverage;
+
+ std::vector<NamedTimer*>& children = mParent->getChildren();
+ std::vector<NamedTimer*>::iterator found_it = std::find(children.begin(), children.end(), this);
+ if (found_it != children.end())
+ {
+ children.erase(found_it);
+ }
+ }
+
+ mParent = parent;
+ if (parent)
+ {
+ getFrameState().mParent = &parent->getFrameState();
+ parent->getChildren().push_back(this);
+ parent->mNeedsSorting = true;
+ }
+}
+
+S32 LLFastTimer::NamedTimer::getDepth()
+{
+ S32 depth = 0;
+ NamedTimer* timerp = mParent;
+ while(timerp)
+ {
+ depth++;
+ timerp = timerp->mParent;
+ }
+ return depth;
+}
+
+// static
+void LLFastTimer::NamedTimer::processTimes()
+{
+ if (sCurFrameIndex < 0) return;
+
+ buildHierarchy();
+ accumulateTimings();
+}
+
+// sort timer info structs by depth first traversal order
+struct SortTimersDFS
+{
+ bool operator()(const LLFastTimer::FrameState& i1, const LLFastTimer::FrameState& i2)
+ {
+ return i1.mTimer->getFrameStateIndex() < i2.mTimer->getFrameStateIndex();
+ }
+};
+
+// sort child timers by name
+struct SortTimerByName
+{
+ bool operator()(const LLFastTimer::NamedTimer* i1, const LLFastTimer::NamedTimer* i2)
+ {
+ return i1->getName() < i2->getName();
+ }
+};
+
+//static
+void LLFastTimer::NamedTimer::buildHierarchy()
+{
+ if (sCurFrameIndex < 0 ) return;
+
+ // set up initial tree
+ for (instance_iter it = NamedTimer::beginInstances();
+ it != endInstances();
+ ++it)
+ {
+ NamedTimer& timer = *it;
+ if (&timer == NamedTimerFactory::instance().getRootTimer()) continue;
+
+ // bootstrap tree construction by attaching to last timer to be on stack
+ // when this timer was called
+ if (timer.getFrameState().mLastCaller && timer.mParent == NamedTimerFactory::instance().getRootTimer())
+ {
+ timer.setParent(timer.getFrameState().mLastCaller->mTimer);
+ // no need to push up tree on first use, flag can be set spuriously
+ timer.getFrameState().mMoveUpTree = false;
+ }
+ }
+
+ // bump timers up tree if they've been flagged as being in the wrong place
+ // do this in a bottom up order to promote descendants first before promoting ancestors
+ // this preserves partial order derived from current frame's observations
+ for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getRootTimer());
+ it != end_timer_tree_bottom_up();
+ ++it)
+ {
+ NamedTimer* timerp = *it;
+ // skip root timer
+ if (timerp == NamedTimerFactory::instance().getRootTimer()) continue;
+
+ if (timerp->getFrameState().mMoveUpTree)
+ {
+ // since ancestors have already been visited, reparenting won't affect tree traversal
+ //step up tree, bringing our descendants with us
+ //llinfos << "Moving " << timerp->getName() << " from child of " << timerp->getParent()->getName() <<
+ // " to child of " << timerp->getParent()->getParent()->getName() << llendl;
+ timerp->setParent(timerp->getParent()->getParent());
+ timerp->getFrameState().mMoveUpTree = false;
+
+ // don't bubble up any ancestors until descendants are done bubbling up
+ it.skipAncestors();
+ }
+ }
+
+ // sort timers by time last called, so call graph makes sense
+ for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer());
+ it != end_timer_tree();
+ ++it)
+ {
+ NamedTimer* timerp = (*it);
+ if (timerp->mNeedsSorting)
+ {
+ std::sort(timerp->getChildren().begin(), timerp->getChildren().end(), SortTimerByName());
+ }
+ timerp->mNeedsSorting = false;
+ }
+}
+
+//static
+void LLFastTimer::NamedTimer::accumulateTimings()
+{
+ U32 cur_time = getCPUClockCount32();
+
+ // walk up stack of active timers and accumulate current time while leaving timing structures active
+ LLFastTimer* cur_timer = sCurTimerData.mCurTimer;
+ // root defined by parent pointing to self
+ CurTimerData* cur_data = &sCurTimerData;
+ while(cur_timer->mLastTimerData.mCurTimer != cur_timer)
+ {
+ U32 cumulative_time_delta = cur_time - cur_timer->mStartTime;
+ U32 self_time_delta = cumulative_time_delta - cur_data->mChildTime;
+ cur_data->mChildTime = 0;
+ cur_timer->mFrameState->mSelfTimeCounter += self_time_delta;
+ cur_timer->mStartTime = cur_time;
+
+ cur_data = &cur_timer->mLastTimerData;
+ cur_data->mChildTime += cumulative_time_delta;
+
+ cur_timer = cur_timer->mLastTimerData.mCurTimer;
+ }
+
+ // traverse tree in DFS post order, or bottom up
+ for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getActiveRootTimer());
+ it != end_timer_tree_bottom_up();
+ ++it)
+ {
+ NamedTimer* timerp = (*it);
+ timerp->mTotalTimeCounter = timerp->getFrameState().mSelfTimeCounter;
+ for (child_const_iter child_it = timerp->beginChildren(); child_it != timerp->endChildren(); ++child_it)
+ {
+ timerp->mTotalTimeCounter += (*child_it)->mTotalTimeCounter;
+ }
+
+ S32 cur_frame = sCurFrameIndex;
+ if (cur_frame >= 0)
+ {
+ // update timer history
+ int hidx = cur_frame % HISTORY_NUM;
+
+ timerp->mCountHistory[hidx] = timerp->mTotalTimeCounter;
+ timerp->mCountAverage = (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);
+ }
+ }
+}
+
+// static
+void LLFastTimer::NamedTimer::resetFrame()
+{
+ if (sLog)
+ { //output current frame counts to performance log
+ F64 iclock_freq = 1000.0 / countsPerSecond(); // good place to calculate clock frequency
+
+ F64 total_time = 0;
+ LLSD sd;
+
+ for (NamedTimer::instance_iter it = NamedTimer::beginInstances();
+ it != NamedTimer::endInstances();
+ ++it)
+ {
+ NamedTimer& timer = *it;
+ FrameState& info = timer.getFrameState();
+ sd[timer.getName()]["Time"] = (LLSD::Real) (info.mSelfTimeCounter*iclock_freq);
+ sd[timer.getName()]["Calls"] = (LLSD::Integer) info.mCalls;
+
+ // computing total time here because getting the root timer's getCountHistory
+ // doesn't work correctly on the first frame
+ total_time = total_time + info.mSelfTimeCounter * iclock_freq;
+ }
+
+ sd["Total"]["Time"] = (LLSD::Real) total_time;
+ sd["Total"]["Calls"] = (LLSD::Integer) 1;
+
+ {
+ LLMutexLock lock(sLogLock);
+ sLogQueue.push(sd);
+ }
+ }
+
+
+ // tag timers by position in depth first traversal of tree
+ S32 index = 0;
+ for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer());
+ it != end_timer_tree();
+ ++it)
+ {
+ NamedTimer* timerp = (*it);
+
+ timerp->mFrameStateIndex = index;
+ index++;
+
+ llassert_always(timerp->mFrameStateIndex < (S32)getFrameStateList().size());
+ }
+
+ // sort timers by dfs traversal order to improve cache coherency
+ std::sort(getFrameStateList().begin(), getFrameStateList().end(), SortTimersDFS());
+
+ // update pointers into framestatelist now that we've sorted it
+ DeclareTimer::updateCachedPointers();
+
+ // reset for next frame
+ for (NamedTimer::instance_iter it = NamedTimer::beginInstances();
+ it != NamedTimer::endInstances();
+ ++it)
+ {
+ NamedTimer& timer = *it;
+
+ FrameState& info = timer.getFrameState();
+ info.mSelfTimeCounter = 0;
+ info.mCalls = 0;
+ info.mLastCaller = NULL;
+ info.mMoveUpTree = false;
+ // update parent pointer in timer state struct
+ if (timer.mParent)
+ {
+ info.mParent = &timer.mParent->getFrameState();
+ }
+ }
+
+ //sTimerCycles = 0;
+ //sTimerCalls = 0;
+}
+
+//static
+void LLFastTimer::NamedTimer::reset()
+{
+ resetFrame(); // reset frame data
+
+ // walk up stack of active timers and reset start times to current time
+ // effectively zeroing out any accumulated time
+ U32 cur_time = getCPUClockCount32();
+
+ // root defined by parent pointing to self
+ CurTimerData* cur_data = &sCurTimerData;
+ LLFastTimer* cur_timer = cur_data->mCurTimer;
+ while(cur_timer->mLastTimerData.mCurTimer != cur_timer)
+ {
+ cur_timer->mStartTime = cur_time;
+ cur_data->mChildTime = 0;
+
+ cur_data = &cur_timer->mLastTimerData;
+ cur_timer = cur_data->mCurTimer;
+ }
+
+ // reset all history
+ for (NamedTimer::instance_iter it = NamedTimer::beginInstances();
+ it != NamedTimer::endInstances();
+ ++it)
+ {
+ NamedTimer& timer = *it;
+ if (&timer != NamedTimerFactory::instance().getRootTimer())
+ {
+ timer.setParent(NamedTimerFactory::instance().getRootTimer());
+ }
+
+ timer.mCountAverage = 0;
+ timer.mCallAverage = 0;
+ memset(timer.mCountHistory, 0, sizeof(U32) * HISTORY_NUM);
+ memset(timer.mCallHistory, 0, sizeof(U32) * HISTORY_NUM);
+ }
+
+ sLastFrameIndex = 0;
+ sCurFrameIndex = 0;
+}
+
+//static
+LLFastTimer::info_list_t& LLFastTimer::getFrameStateList()
+{
+ if (!sTimerInfos)
+ {
+ sTimerInfos = new info_list_t();
+ }
+ return *sTimerInfos;
+}
+
+
+U32 LLFastTimer::NamedTimer::getHistoricalCount(S32 history_index) const
+{
+ S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM;
+ return mCountHistory[history_idx];
+}
+
+U32 LLFastTimer::NamedTimer::getHistoricalCalls(S32 history_index ) const
+{
+ S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM;
+ return mCallHistory[history_idx];
+}
+
+LLFastTimer::FrameState& LLFastTimer::NamedTimer::getFrameState() const
+{
+ llassert_always(mFrameStateIndex >= 0);
+ if (this == NamedTimerFactory::instance().getActiveRootTimer())
+ {
+ return NamedTimerFactory::instance().getRootFrameState();
+ }
+ return getFrameStateList()[mFrameStateIndex];
+}
+
+// static
+LLFastTimer::NamedTimer& LLFastTimer::NamedTimer::getRootNamedTimer()
+{
+ return *NamedTimerFactory::instance().getActiveRootTimer();
+}
+
+std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::beginChildren()
+{
+ return mChildren.begin();
+}
+
+std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::endChildren()
+{
+ return mChildren.end();
+}
+
+std::vector<LLFastTimer::NamedTimer*>& LLFastTimer::NamedTimer::getChildren()
+{
+ return mChildren;
+}
+
+//static
+void LLFastTimer::nextFrame()
+{
+ countsPerSecond(); // good place to calculate clock frequency
+ U64 frame_time = getCPUClockCount64();
+ if ((frame_time - sLastFrameTime) >> 8 > 0xffffffff)
+ {
+ llinfos << "Slow frame, fast timers inaccurate" << llendl;
+ }
+
+ if (sPauseHistory)
+ {
+ sResetHistory = true;
+ }
+ else if (sResetHistory)
+ {
+ sLastFrameIndex = 0;
+ sCurFrameIndex = 0;
+ sResetHistory = false;
+ }
+ else // not paused
+ {
+ NamedTimer::processTimes();
+ sLastFrameIndex = sCurFrameIndex++;
+ }
+
+ // get ready for next frame
+ NamedTimer::resetFrame();
+ sLastFrameTime = frame_time;
+}
+
+//static
+void LLFastTimer::dumpCurTimes()
+{
+ // accumulate timings, etc.
+ NamedTimer::processTimes();
+
+ F64 clock_freq = (F64)countsPerSecond();
+ F64 iclock_freq = 1000.0 / clock_freq; // clock_ticks -> milliseconds
+
+ // walk over timers in depth order and output timings
+ for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer());
+ it != end_timer_tree();
+ ++it)
+ {
+ NamedTimer* timerp = (*it);
+ F64 total_time_ms = ((F64)timerp->getHistoricalCount(0) * iclock_freq);
+ // Don't bother with really brief times, keep output concise
+ if (total_time_ms < 0.1) continue;
+
+ std::ostringstream out_str;
+ for (S32 i = 0; i < timerp->getDepth(); i++)
+ {
+ out_str << "\t";
+ }
+
+
+ out_str << timerp->getName() << " "
+ << std::setprecision(3) << total_time_ms << " ms, "
+ << timerp->getHistoricalCalls(0) << " calls";
+
+ llinfos << out_str.str() << llendl;
+ }
+}
+
+//static
+void LLFastTimer::reset()
+{
+ NamedTimer::reset();
+}
+
+
+//static
+void LLFastTimer::writeLog(std::ostream& os)
+{
+ while (!sLogQueue.empty())
+ {
+ LLSD& sd = sLogQueue.front();
+ LLSDSerialize::toXML(sd, os);
+ LLMutexLock lock(sLogLock);
+ sLogQueue.pop();
+ }
+}
+
+//static
+const LLFastTimer::NamedTimer* LLFastTimer::getTimerByName(const std::string& name)
+{
+ return NamedTimerFactory::instance().getTimerByName(name);
+}
+
+LLFastTimer::LLFastTimer(LLFastTimer::FrameState* state)
+: mFrameState(state)
+{
+ U32 start_time = getCPUClockCount32();
+ mStartTime = start_time;
+ mFrameState->mActiveCount++;
+ LLFastTimer::sCurTimerData.mCurTimer = this;
+ LLFastTimer::sCurTimerData.mFrameState = mFrameState;
+ LLFastTimer::sCurTimerData.mChildTime = 0;
+ mLastTimerData = LLFastTimer::sCurTimerData;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
diff --git a/indra/llcommon/llfasttimer_class.h b/indra/llcommon/llfasttimer_class.h
new file mode 100644
index 0000000000..ddb1a74793
--- /dev/null
+++ b/indra/llcommon/llfasttimer_class.h
@@ -0,0 +1,272 @@
+/**
+ * @file llfasttimer_class.h
+ * @brief Declaration of a fast timer.
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_FASTTIMER_CLASS_H
+#define LL_FASTTIMER_CLASS_H
+
+#include "llinstancetracker.h"
+
+#define FAST_TIMER_ON 1
+#define TIME_FAST_TIMERS 0
+
+class LLMutex;
+
+#include <queue>
+#include "llsd.h"
+
+class LL_COMMON_API LLFastTimer
+{
+public:
+ class NamedTimer;
+
+ struct LL_COMMON_API FrameState
+ {
+ FrameState(NamedTimer* timerp);
+
+ U32 mSelfTimeCounter;
+ U32 mCalls;
+ FrameState* mParent; // info for caller timer
+ FrameState* mLastCaller; // used to bootstrap tree construction
+ NamedTimer* mTimer;
+ U16 mActiveCount; // number of timers with this ID active on stack
+ bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame
+ };
+
+ // stores a "named" timer instance to be reused via multiple LLFastTimer stack instances
+ class LL_COMMON_API NamedTimer
+ : public LLInstanceTracker<NamedTimer>
+ {
+ friend class DeclareTimer;
+ public:
+ ~NamedTimer();
+
+ enum { HISTORY_NUM = 60 };
+
+ const std::string& getName() const { return mName; }
+ NamedTimer* getParent() const { return mParent; }
+ void setParent(NamedTimer* parent);
+ S32 getDepth();
+ std::string getToolTip(S32 history_index = -1);
+
+ typedef std::vector<NamedTimer*>::const_iterator child_const_iter;
+ child_const_iter beginChildren();
+ child_const_iter endChildren();
+ std::vector<NamedTimer*>& getChildren();
+
+ void setCollapsed(bool collapsed) { mCollapsed = collapsed; }
+ bool getCollapsed() const { return mCollapsed; }
+
+ U32 getCountAverage() const { return mCountAverage; }
+ U32 getCallAverage() const { return mCallAverage; }
+
+ U32 getHistoricalCount(S32 history_index = 0) const;
+ U32 getHistoricalCalls(S32 history_index = 0) const;
+
+ static NamedTimer& getRootNamedTimer();
+
+ S32 getFrameStateIndex() const { return mFrameStateIndex; }
+
+ FrameState& getFrameState() const;
+
+ private:
+ friend class LLFastTimer;
+ friend class NamedTimerFactory;
+
+ //
+ // methods
+ //
+ NamedTimer(const std::string& name);
+ // recursive call to gather total time from children
+ static void accumulateTimings();
+
+ // updates cumulative times and hierarchy,
+ // can be called multiple times in a frame, at any point
+ static void processTimes();
+
+ static void buildHierarchy();
+ static void resetFrame();
+ static void reset();
+
+ //
+ // members
+ //
+ S32 mFrameStateIndex;
+
+ std::string mName;
+
+ U32 mTotalTimeCounter;
+
+ U32 mCountAverage;
+ U32 mCallAverage;
+
+ U32* mCountHistory;
+ U32* mCallHistory;
+
+ // tree structure
+ NamedTimer* mParent; // NamedTimer of caller(parent)
+ std::vector<NamedTimer*> mChildren;
+ bool mCollapsed; // don't show children
+ bool mNeedsSorting; // sort children whenever child added
+ };
+
+ // used to statically declare a new named timer
+ class LL_COMMON_API DeclareTimer
+ : public LLInstanceTracker<DeclareTimer>
+ {
+ friend class LLFastTimer;
+ public:
+ DeclareTimer(const std::string& name, bool open);
+ DeclareTimer(const std::string& name);
+
+ static void updateCachedPointers();
+
+ private:
+ NamedTimer& mTimer;
+ FrameState* mFrameState;
+ };
+
+public:
+ LLFastTimer(LLFastTimer::FrameState* state);
+
+ LL_FORCE_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer)
+ : mFrameState(timer.mFrameState)
+ {
+#if TIME_FAST_TIMERS
+ U64 timer_start = getCPUClockCount64();
+#endif
+#if FAST_TIMER_ON
+ LLFastTimer::FrameState* frame_state = mFrameState;
+ mStartTime = getCPUClockCount32();
+
+ frame_state->mActiveCount++;
+ frame_state->mCalls++;
+ // keep current parent as long as it is active when we are
+ frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0);
+
+ LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData;
+ mLastTimerData = *cur_timer_data;
+ cur_timer_data->mCurTimer = this;
+ cur_timer_data->mFrameState = frame_state;
+ cur_timer_data->mChildTime = 0;
+#endif
+#if TIME_FAST_TIMERS
+ U64 timer_end = getCPUClockCount64();
+ sTimerCycles += timer_end - timer_start;
+#endif
+ }
+
+ LL_FORCE_INLINE ~LLFastTimer()
+ {
+#if TIME_FAST_TIMERS
+ U64 timer_start = getCPUClockCount64();
+#endif
+#if FAST_TIMER_ON
+ LLFastTimer::FrameState* frame_state = mFrameState;
+ U32 total_time = getCPUClockCount32() - mStartTime;
+
+ frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime;
+ frame_state->mActiveCount--;
+
+ // store last caller to bootstrap tree creation
+ // do this in the destructor in case of recursion to get topmost caller
+ frame_state->mLastCaller = mLastTimerData.mFrameState;
+
+ // we are only tracking self time, so subtract our total time delta from parents
+ mLastTimerData.mChildTime += total_time;
+
+ LLFastTimer::sCurTimerData = mLastTimerData;
+#endif
+#if TIME_FAST_TIMERS
+ U64 timer_end = getCPUClockCount64();
+ sTimerCycles += timer_end - timer_start;
+ sTimerCalls++;
+#endif
+ }
+
+public:
+ static LLMutex* sLogLock;
+ static std::queue<LLSD> sLogQueue;
+ static BOOL sLog;
+ static BOOL sMetricLog;
+ static bool sPauseHistory;
+ static bool sResetHistory;
+ static U64 sTimerCycles;
+ static U32 sTimerCalls;
+
+ typedef std::vector<FrameState> info_list_t;
+ static info_list_t& getFrameStateList();
+
+
+ // call this once a frame to reset timers
+ static void nextFrame();
+
+ // dumps current cumulative frame stats to log
+ // call nextFrame() to reset timers
+ static void dumpCurTimes();
+
+ // call this to reset timer hierarchy, averages, etc.
+ static void reset();
+
+ static U64 countsPerSecond();
+ static S32 getLastFrameIndex() { return sLastFrameIndex; }
+ static S32 getCurFrameIndex() { return sCurFrameIndex; }
+
+ static void writeLog(std::ostream& os);
+ static const NamedTimer* getTimerByName(const std::string& name);
+
+ struct CurTimerData
+ {
+ LLFastTimer* mCurTimer;
+ FrameState* mFrameState;
+ U32 mChildTime;
+ };
+ static CurTimerData sCurTimerData;
+
+private:
+ static U32 getCPUClockCount32();
+ static U64 getCPUClockCount64();
+ static U64 sClockResolution;
+
+ static S32 sCurFrameIndex;
+ static S32 sLastFrameIndex;
+ static U64 sLastFrameTime;
+ static info_list_t* sTimerInfos;
+
+ U32 mStartTime;
+ LLFastTimer::FrameState* mFrameState;
+ LLFastTimer::CurTimerData mLastTimerData;
+
+};
+
+typedef class LLFastTimer LLFastTimer;
+
+#endif // LL_LLFASTTIMER_CLASS_H
diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index 5eefa6a16b..1c1503ca7b 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -55,13 +55,28 @@
#define LL_BIG_ENDIAN 1
#endif
+
// Per-compiler switches
+
#ifdef __GNUC__
#define LL_FORCE_INLINE inline __attribute__((always_inline))
#else
#define LL_FORCE_INLINE __forceinline
#endif
+// Mark-up expressions with branch prediction hints. Do NOT use
+// this with reckless abandon - it's an obfuscating micro-optimization
+// outside of inner loops or other places where you are OVERWHELMINGLY
+// sure which way an expression almost-always evaluates.
+#if __GNUC__ >= 3
+# define LL_LIKELY(EXPR) __builtin_expect (!!(EXPR), true)
+# define LL_UNLIKELY(EXPR) __builtin_expect (!!(EXPR), false)
+#else
+# define LL_LIKELY(EXPR) (EXPR)
+# define LL_UNLIKELY(EXPR) (EXPR)
+#endif
+
+
// Figure out differences between compilers
#if defined(__GNUC__)
#define GCC_VERSION (__GNUC__ * 10000 \
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index cd493481d5..46478ba3c9 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -436,6 +436,8 @@ void LLImageGL::init(BOOL usemipmaps)
mLastBindTime = 0.f;
mPickMask = NULL;
+ mPickMaskWidth = 0;
+ mPickMaskHeight = 0;
mUseMipMaps = usemipmaps;
mHasExplicitFormat = FALSE;
mAutoGenMips = FALSE;
@@ -527,7 +529,12 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents)
// llwarns << "Setting Size of LLImageGL with existing mTexName = " << mTexName << llendl;
destroyGLTexture();
}
-
+
+ // pickmask validity depends on old image size, delete it
+ delete [] mPickMask;
+ mPickMask = NULL;
+ mPickMaskWidth = mPickMaskHeight = 0;
+
mWidth = width;
mHeight = height;
mComponents = ncomponents;
@@ -1675,12 +1682,14 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
return ;
}
+ delete [] mPickMask;
+ mPickMask = NULL;
+ mPickMaskWidth = mPickMaskHeight = 0;
+
if (mFormatType != GL_UNSIGNED_BYTE ||
mFormatPrimary != GL_RGBA)
{
//cannot generate a pick mask for this texture
- delete [] mPickMask;
- mPickMask = NULL;
return;
}
@@ -1688,11 +1697,10 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
U32 pick_height = height/2;
U32 size = llmax(pick_width, (U32) 1) * llmax(pick_height, (U32) 1);
-
size = size/8 + 1;
-
- delete[] mPickMask;
mPickMask = new U8[size];
+ mPickMaskWidth = pick_width;
+ mPickMaskHeight = pick_height;
memset(mPickMask, 0, sizeof(U8) * size);
@@ -1727,35 +1735,34 @@ BOOL LLImageGL::getMask(const LLVector2 &tc)
if (mPickMask)
{
- S32 width = getWidth()/2;
- S32 height = getHeight()/2;
-
F32 u = tc.mV[0] - floorf(tc.mV[0]);
F32 v = tc.mV[1] - floorf(tc.mV[1]);
- if (u < 0.f || u > 1.f ||
- v < 0.f || v > 1.f)
+ if (LL_UNLIKELY(u < 0.f || u > 1.f ||
+ v < 0.f || v > 1.f))
{
LL_WARNS_ONCE("render") << "Ugh, u/v out of range in image mask pick" << LL_ENDL;
u = v = 0.f;
llassert(false);
}
+
+ llassert(mPickMaskWidth > 0 && mPickMaskHeight > 0);
- S32 x = (S32)(u * width);
- S32 y = (S32)(v * height);
+ S32 x = (S32)(u * mPickMaskWidth);
+ S32 y = (S32)(v * mPickMaskHeight);
- if (x >= width)
+ if (LL_UNLIKELY(x >= mPickMaskWidth))
{
LL_WARNS_ONCE("render") << "Ooh, width overrun on pick mask read, that coulda been bad." << LL_ENDL;
- x = llmax(0, width-1);
+ x = llmax(0, mPickMaskWidth-1);
}
- if (y >= height)
+ if (LL_UNLIKELY(y >= mPickMaskHeight))
{
LL_WARNS_ONCE("render") << "Ooh, height overrun on pick mask read, that woulda been bad." << LL_ENDL;
- y = llmax(0, height-1);
+ y = llmax(0, mPickMaskHeight-1);
}
- S32 idx = y*width+x;
+ S32 idx = y*mPickMaskWidth+x;
S32 offset = idx%8;
res = mPickMask[idx/8] & (1 << offset) ? TRUE : FALSE;
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index facfb7bd62..f0870c3fc4 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -193,6 +193,8 @@ public:
private:
LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel
+ U16 mPickMaskWidth;
+ U16 mPickMaskHeight;
S8 mUseMipMaps;
S8 mHasExplicitFormat; // If false (default), GL format is f(mComponents)
S8 mAutoGenMips;
diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp
index b5e870228a..d0c73fbfbc 100644
--- a/indra/llui/llaccordionctrl.cpp
+++ b/indra/llui/llaccordionctrl.cpp
@@ -63,6 +63,8 @@ static LLDefaultChildRegistry::Register<LLAccordionCtrl> t2("accordion");
LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)
, mFitParent(params.fit_parent)
+ , mAutoScrolling( false )
+ , mAutoScrollRate( 0.f )
{
mSingleExpansion = params.single_expansion;
if(mFitParent && !mSingleExpansion)
@@ -72,6 +74,8 @@ LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)
}
LLAccordionCtrl::LLAccordionCtrl() : LLPanel()
+ , mAutoScrolling( false )
+ , mAutoScrollRate( 0.f )
{
mSingleExpansion = false;
mFitParent = false;
@@ -81,6 +85,19 @@ LLAccordionCtrl::LLAccordionCtrl() : LLPanel()
//---------------------------------------------------------------------------------
void LLAccordionCtrl::draw()
{
+ if (mAutoScrolling)
+ {
+ // add acceleration to autoscroll
+ mAutoScrollRate = llmin(mAutoScrollRate + (LLFrameTimer::getFrameDeltaTimeF32() * AUTO_SCROLL_RATE_ACCEL), MAX_AUTO_SCROLL_RATE);
+ }
+ else
+ {
+ // reset to minimum for next time
+ mAutoScrollRate = MIN_AUTO_SCROLL_RATE;
+ }
+ // clear this flag to be set on next call to autoScroll
+ mAutoScrolling = false;
+
LLRect local_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
LLLocalClipRect clip(local_rect);
@@ -420,6 +437,64 @@ BOOL LLAccordionCtrl::handleKeyHere (KEY key, MASK mask)
return LLPanel::handleKeyHere(key,mask);
}
+BOOL LLAccordionCtrl::handleDragAndDrop (S32 x, S32 y, MASK mask,
+ BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ // Scroll folder view if needed. Never accepts a drag or drop.
+ *accept = ACCEPT_NO;
+ BOOL handled = autoScroll(x, y);
+
+ if( !handled )
+ {
+ handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type,
+ cargo_data, accept, tooltip_msg) != NULL;
+ }
+ return TRUE;
+}
+
+BOOL LLAccordionCtrl::autoScroll (S32 x, S32 y)
+{
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+
+ bool scrolling = false;
+ if( mScrollbar->getVisible() )
+ {
+ LLRect rect_local( 0, getRect().getHeight(), getRect().getWidth() - scrollbar_size, 0 );
+ LLRect screen_local_extents;
+
+ // clip rect against root view
+ screenRectToLocal(getRootView()->getLocalRect(), &screen_local_extents);
+ rect_local.intersectWith(screen_local_extents);
+
+ // autoscroll region should take up no more than one third of visible scroller area
+ S32 auto_scroll_region_height = llmin(rect_local.getHeight() / 3, 10);
+ S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32());
+
+ LLRect bottom_scroll_rect = screen_local_extents;
+ bottom_scroll_rect.mTop = rect_local.mBottom + auto_scroll_region_height;
+ if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar->getDocPos() < mScrollbar->getDocPosMax()) )
+ {
+ mScrollbar->setDocPos( mScrollbar->getDocPos() + auto_scroll_speed );
+ mAutoScrolling = true;
+ scrolling = true;
+ }
+
+ LLRect top_scroll_rect = screen_local_extents;
+ top_scroll_rect.mBottom = rect_local.mTop - auto_scroll_region_height;
+ if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar->getDocPos() > 0) )
+ {
+ mScrollbar->setDocPos( mScrollbar->getDocPos() - auto_scroll_speed );
+ mAutoScrolling = true;
+ scrolling = true;
+ }
+ }
+ return scrolling;
+}
+
void LLAccordionCtrl::updateLayout (S32 width, S32 height)
{
S32 panel_top = height - BORDER_MARGIN ;
diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h
index 4cb0f38281..d57a42df32 100644
--- a/indra/llui/llaccordionctrl.h
+++ b/indra/llui/llaccordionctrl.h
@@ -81,6 +81,11 @@ public:
virtual BOOL handleRightMouseDown ( S32 x, S32 y, MASK mask);
virtual BOOL handleScrollWheel ( S32 x, S32 y, S32 clicks );
virtual BOOL handleKeyHere (KEY key, MASK mask);
+ virtual BOOL handleDragAndDrop (S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
//
// Call reshape after changing splitter's size
@@ -112,11 +117,15 @@ private:
void showScrollbar (S32 width, S32 height);
void hideScrollbar (S32 width, S32 height);
+ BOOL autoScroll (S32 x, S32 y);
+
private:
LLRect mInnerRect;
LLScrollbar* mScrollbar;
bool mSingleExpansion;
bool mFitParent;
+ bool mAutoScrolling;
+ F32 mAutoScrollRate;
};
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 4bfe44135a..daa9e08f14 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -45,6 +45,7 @@ static const std::string DD_HEADER_NAME = "dd_header";
static const S32 HEADER_HEIGHT = 20;
static const S32 HEADER_IMAGE_LEFT_OFFSET = 5;
static const S32 HEADER_TEXT_LEFT_OFFSET = 30;
+static const F32 AUTO_OPEN_TIME = 1.f;
static LLDefaultChildRegistry::Register<LLAccordionCtrlTab> t1("accordion_tab");
@@ -73,6 +74,11 @@ public:
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
+ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
private:
LLTextBox* mHeaderTextbox;
@@ -92,6 +98,8 @@ private:
LLUIColor mHeaderBGColor;
bool mNeedsHighlight;
+
+ LLFrameTimer mAutoOpenTimer;
};
LLAccordionCtrlTab::LLAccordionCtrlTabHeader::Params::Params()
@@ -209,6 +217,7 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::onMouseLeave(S32 x, S32 y, MA
{
LLUICtrl::onMouseLeave(x, y, mask);
mNeedsHighlight = false;
+ mAutoOpenTimer.stop();
}
BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::handleKey(KEY key, MASK mask, BOOL called_from_parent)
{
@@ -218,8 +227,33 @@ BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::handleKey(KEY key, MASK mask,
}
return LLUICtrl::handleKey(key, mask, called_from_parent);
}
+BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::handleDragAndDrop(S32 x, S32 y, MASK mask,
+ BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ LLAccordionCtrlTab* parent = dynamic_cast<LLAccordionCtrlTab*>(getParent());
+ if ( parent && !parent->getDisplayChildren() && parent->getCollapsible() && parent->canOpenClose() )
+ {
+ if (mAutoOpenTimer.getStarted())
+ {
+ if (mAutoOpenTimer.getElapsedTimeF32() > AUTO_OPEN_TIME)
+ {
+ parent->changeOpenClose(false);
+ mAutoOpenTimer.stop();
+ return TRUE;
+ }
+ }
+ else
+ mAutoOpenTimer.start();
+ }
+ return LLUICtrl::handleDragAndDrop(x, y, mask, drop, cargo_type,
+ cargo_data, accept, tooltip_msg);
+}
LLAccordionCtrlTab::Params::Params()
: title("title")
,display_children("expanded", true)
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index b200d43438..2e0260ab16 100644
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
@@ -115,6 +115,7 @@ public:
void changeOpenClose(bool is_open);
void canOpenClose(bool can_open_close) { mCanOpenClose = can_open_close;};
+ bool canOpenClose() const { return mCanOpenClose; };
virtual BOOL postBuild();
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 73e4d126f3..cb5aea272d 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -70,6 +70,8 @@ const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing
const F32 AUTO_SCROLL_TIME = 0.05f;
const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click. *TODO: make this equal to the double click interval?
+const std::string PASSWORD_ASTERISK( "\xE2\x97\x8F" ); // U+25CF BLACK CIRCLE
+
static LLDefaultChildRegistry::Register<LLLineEditor> r1("line_editor");
// Compiler optimization, generate extern template
@@ -401,7 +403,7 @@ void LLLineEditor::setCursorAtLocalPos( S32 local_mouse_x )
{
for (S32 i = 0; i < mText.length(); i++)
{
- asterix_text += '*';
+ asterix_text += utf8str_to_wstring(PASSWORD_ASTERISK);
}
wtext = asterix_text.c_str();
}
@@ -1599,7 +1601,7 @@ void LLLineEditor::draw()
std::string text;
for (S32 i = 0; i < mText.length(); i++)
{
- text += '*';
+ text += PASSWORD_ASTERISK;
}
mText = text;
}
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 4e84013db0..78386220d9 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -498,7 +498,7 @@ void LLScrollListCtrl::fitContents(S32 max_width, S32 max_height)
{
S32 height = llmin( getRequiredRect().getHeight(), max_height );
if(mPageLines)
- height = llmin( mPageLines * mLineHeight + (mDisplayColumnHeaders ? mHeadingHeight : 0), height );
+ height = llmin( mPageLines * mLineHeight + 2*mBorderThickness + (mDisplayColumnHeaders ? mHeadingHeight : 0), height );
S32 width = getRect().getWidth();
@@ -2760,9 +2760,13 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& element, EAddPosition
LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_p, EAddPosition pos)
{
- if (!item_p.validateBlock()) return NULL;
-
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)
+{
+ if (!item_p.validateBlock() || !new_item) return NULL;
new_item->setNumColumns(mColumns.size());
// Add any columns we don't already have
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 907dc90bea..d2d2379328 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -148,6 +148,7 @@ public:
// "columns" => [ "column" => column name, "value" => value, "type" => type, "font" => font, "font-style" => style ], "id" => uuid
// Creates missing columns automatically.
virtual LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL);
+ virtual LLScrollListItem* addRow(LLScrollListItem *new_item, const LLScrollListItem::Params& value, EAddPosition pos = ADD_BOTTOM);
virtual LLScrollListItem* addRow(const LLScrollListItem::Params& value, EAddPosition pos = ADD_BOTTOM);
// Simple add element. Takes a single array of:
// [ "value" => value, "font" => font, "font-style" => style ]
diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h
index 15b86cc945..25ce846d90 100644
--- a/indra/llui/llscrolllistitem.h
+++ b/indra/llui/llscrolllistitem.h
@@ -95,7 +95,7 @@ public:
void setUserdata( void* userdata ) { mUserdata = userdata; }
void* getUserdata() const { return mUserdata; }
- LLUUID getUUID() const { return mItemValue.asUUID(); }
+ virtual LLUUID getUUID() const { return mItemValue.asUUID(); }
LLSD getValue() const { return mItemValue; }
void setRect(LLRect rect) { mRectangle = rect; }
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 17aecaf32f..8abbc833e5 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -244,7 +244,8 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
LLTextBase::~LLTextBase()
{
- delete mPopupMenu;
+ // Menu, like any other LLUICtrl, is deleted by its parent - gMenuHolder
+
clearSegments();
}
@@ -1009,6 +1010,16 @@ void LLTextBase::draw()
void LLTextBase::setColor( const LLColor4& c )
{
mFgColor = c;
+ //textsegments have own style property ,
+ //so we have to update it also to apply changes, EXT-4433
+ for(segment_set_t::iterator it = mSegments.begin(); it != mSegments.end(); it++)
+ {
+ LLTextSegment* segment = it->get();
+ if(segment)
+ {
+ segment->setColor(mFgColor);
+ }
+ }
}
//virtual
@@ -1501,6 +1512,25 @@ void LLTextBase::setText(const LLStringExplicit &utf8str, const LLStyle::Params&
onValueChange(0, getLength());
}
+void LLTextBase::addBlackListUrl(const std::string &url)
+{
+ mBlackListUrls.push_back(url);
+}
+
+bool LLTextBase::isBlackListUrl(const std::string &url) const
+{
+ std::vector<std::string>::const_iterator it;
+ for (it = mBlackListUrls.begin(); it != mBlackListUrls.end(); ++it)
+ {
+ const std::string &blacklist_url = *it;
+ if (url.find(blacklist_url) != std::string::npos)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
//virtual
std::string LLTextBase::getText() const
{
@@ -1575,20 +1605,29 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
prepend_newline = false;
}
}
- // output the styled Url
- appendAndHighlightText(match.getLabel(), prepend_newline, part, link_params);
- prepend_newline = false;
- // set the tooltip for the Url label
- if (! match.getTooltip().empty())
+ // output the styled Url (unless we've been asked to suppress it)
+ if (isBlackListUrl(match.getUrl()))
{
- segment_set_t::iterator it = getSegIterContaining(getLength()-1);
- if (it != mSegments.end())
+ std::string orig_url = text.substr(start, end-start);
+ appendAndHighlightText(orig_url, prepend_newline, part, style_params);
+ }
+ else
+ {
+ appendAndHighlightText(match.getLabel(), prepend_newline, part, link_params);
+
+ // set the tooltip for the Url label
+ if (! match.getTooltip().empty())
{
- LLTextSegmentPtr segment = *it;
- segment->setToolTip(match.getTooltip());
+ segment_set_t::iterator it = getSegIterContaining(getLength()-1);
+ if (it != mSegments.end())
+ {
+ LLTextSegmentPtr segment = *it;
+ segment->setToolTip(match.getTooltip());
+ }
}
}
+ prepend_newline = false;
// move on to the rest of the text after the Url
if (end < (S32)text.length())
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 038b9eaa62..e1c6cc36ab 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -41,6 +41,7 @@
#include "llpanel.h"
#include <string>
+#include <vector>
#include <set>
#include <boost/signals2.hpp>
@@ -186,6 +187,9 @@ public:
const LLFontGL* getDefaultFont() const { return mDefaultFont; }
LLStyle::Params getDefaultStyle();
+ // tell the text object to suppress auto highlighting of a specific URL
+ void addBlackListUrl(const std::string &url);
+
public:
// Fired when a URL link is clicked
commit_signal_t mURLClickSignal;
@@ -308,6 +312,7 @@ protected:
void updateRects();
void needsScroll() { mScrollNeeded = TRUE; }
void replaceUrlLabel(const std::string &url, const std::string &label);
+ bool isBlackListUrl(const std::string &url) const;
protected:
// text segmentation and flow
@@ -359,6 +364,9 @@ protected:
LLView* mDocumentView;
class LLScrollContainer* mScroller;
+ // list of URLs to suppress from automatic hyperlinking
+ std::vector<std::string> mBlackListUrls;
+
// transient state
bool mReflowNeeded; // need to reflow text because of change to text contents or display region
bool mScrollNeeded; // need to change scroll region because of change to cursor position
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index f2c3879a6c..06ba0d80e9 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2040,6 +2040,20 @@ void LLTextEditor::showContextMenu(S32 x, S32 y)
LLMenuHolderGL::child_registry_t::instance());
}
+ // Route menu to this class
+ // previously this was done in ::handleRightMoseDown:
+ //if(hasTabStop())
+ // setFocus(TRUE) - why? weird...
+ // and then inside setFocus
+ // ....
+ // gEditMenuHandler = this;
+ // ....
+ // but this didn't work in all cases and just weird...
+ //why not here?
+ // (all this was done for EXT-4443)
+
+ gEditMenuHandler = this;
+
S32 screen_x, screen_y;
localPointToScreen(x, y, &screen_x, &screen_y);
mContextMenu->show(screen_x, screen_y);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 2701c0b3c1..c8db67d3d5 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -351,7 +351,6 @@ set(viewer_SOURCE_FILES
llpanelprimmediacontrols.cpp
llpanelprofile.cpp
llpanelprofileview.cpp
- llpanelshower.cpp
llpanelteleporthistory.cpp
llpanelvolume.cpp
llpanelvolumepulldown.cpp
@@ -858,7 +857,6 @@ set(viewer_HEADER_FILES
llpanelprimmediacontrols.h
llpanelprofile.h
llpanelprofileview.h
- llpanelshower.h
llpanelteleporthistory.h
llpanelvolume.h
llpanelvolumepulldown.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index ffe8762f03..a73c75da88 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -298,17 +298,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>AudioStreamingVideo</key>
- <map>
- <key>Comment</key>
- <string>Enable streaming video</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>AuditTexture</key>
<map>
<key>Comment</key>
@@ -10337,6 +10326,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>VoiceDefaultInternalLevel</key>
+ <map>
+ <key>Comment</key>
+ <string>Internal level of voice set by default. Is equivalent to 0.5 (from 0.0-1.0 range) external voice level (internal = 400 * external^2).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>100</integer>
+ </map>
<key>VoiceEarLocation</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt
index cc8f6780e3..887dab66d1 100644
--- a/indra/newview/gpu_table.txt
+++ b/indra/newview/gpu_table.txt
@@ -192,9 +192,9 @@ NVIDIA GeForce 7100 .*NVIDIA.*GeForce 71.* 0 1
NVIDIA GeForce 7200 .*NVIDIA.*GeForce 72.* 1 1
NVIDIA GeForce 7300 .*NVIDIA.*GeForce 73.* 1 1
NVIDIA GeForce 7500 .*NVIDIA.*GeForce 75.* 1 1
-NVIDIA GeForce 7600 .*NVIDIA.*GeForce 76.* 2 1
-NVIDIA GeForce 7800 .*NVIDIA.*GeForce.*78.* 2 1
-NVIDIA GeForce 7900 .*NVIDIA.*GeForce.*79.* 2 1
+NVIDIA GeForce 7600 .*NVIDIA.*GeForce 76.* 3 1
+NVIDIA GeForce 7800 .*NVIDIA.*GeForce.*78.* 3 1
+NVIDIA GeForce 7900 .*NVIDIA.*GeForce.*79.* 3 1
NVIDIA GeForce 8100 .*NVIDIA.*GeForce 81.* 1 1
NVIDIA GeForce 8200 .*NVIDIA.*GeForce 82.* 1 1
NVIDIA GeForce 8300 .*NVIDIA.*GeForce 83.* 1 1
@@ -207,8 +207,8 @@ NVIDIA GeForce 8800 .*NVIDIA.*GeForce 88.* 3 1
NVIDIA GeForce 9300M .*NVIDIA.*GeForce 9300M.* 1 1
NVIDIA GeForce 9400M .*NVIDIA.*GeForce 9400M.* 1 1
NVIDIA GeForce 9500M .*NVIDIA.*GeForce 9500M.* 2 1
-NVIDIA GeForce 9600M .*NVIDIA.*GeForce 9600M.* 2 1
-NVIDIA GeForce 9700M .*NVIDIA.*GeForce 9700M.* 2 1
+NVIDIA GeForce 9600M .*NVIDIA.*GeForce 9600M.* 3 1
+NVIDIA GeForce 9700M .*NVIDIA.*GeForce 9700M.* 3 1
NVIDIA GeForce 9300 .*NVIDIA.*GeForce 93.* 1 1
NVIDIA GeForce 9400 .*GeForce 94.* 1 1
NVIDIA GeForce 9500 .*NVIDIA.*GeForce 95.* 2 1
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 03180b6a9d..1dec8c7bd8 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -35,6 +35,7 @@
#include "llagent.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
+#include "llcommandhandler.h"
#include "llfloatercustomize.h"
#include "llgesturemgr.h"
#include "llinventorybridge.h"
@@ -47,6 +48,23 @@
#include "llviewerregion.h"
#include "llwearablelist.h"
+// support for secondlife:///app/appearance SLapps
+class LLAppearanceHandler : public LLCommandHandler
+{
+public:
+ // requests will be throttled from a non-trusted browser
+ LLAppearanceHandler() : LLCommandHandler("appearance", UNTRUSTED_THROTTLE) {}
+
+ bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
+ {
+ // support secondlife:///app/appearance/show, but for now we just
+ // make all secondlife:///app/appearance SLapps behave this way
+ LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD());
+ return true;
+ }
+};
+LLAppearanceHandler gAppearanceHandler;
+
class LLWearInventoryCategoryCallback : public LLInventoryCallback
{
public:
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 40c9bb6afa..7eed2e7b9a 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -250,31 +250,25 @@ void LLAvatarActions::startAdhocCall(const std::vector<LLUUID>& ids)
make_ui_sound("UISndStartIM");
}
+/* AD *TODO: Is this function needed any more?
+ I fixed it a bit(added check for canCall), but it appears that it is not used
+ anywhere. Maybe it should be removed?
// static
bool LLAvatarActions::isCalling(const LLUUID &id)
{
- if (id.isNull())
+ if (id.isNull() || !canCall())
{
return false;
}
LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, id);
return (LLIMModel::getInstance()->findIMSession(session_id) != NULL);
-}
+}*/
//static
-bool LLAvatarActions::canCall(const LLUUID &id)
+bool LLAvatarActions::canCall()
{
- // For now we do not need to check whether passed UUID is ID of agent's friend.
- // Use common check of Voice Client state.
- {
- // don't need to check online/offline status because "usual resident" (resident that is not a friend)
- // can be only ONLINE. There is no way to see "usual resident" in OFFLINE status. If we see "usual
- // resident" it automatically means that the resident is ONLINE. So to make a call to the "usual resident"
- // we need to check only that "our" voice is enabled.
- return LLVoiceClient::voiceEnabled();
- }
-
+ return LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking();
}
// static
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index a4504ae679..c751661acf 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -126,13 +126,16 @@ public:
/**
* Return true if the avatar is in a P2P voice call with a given user
*/
- static bool isCalling(const LLUUID &id);
+ /* AD *TODO: Is this function needed any more?
+ I fixed it a bit(added check for canCall), but it appears that it is not used
+ anywhere. Maybe it should be removed?
+ static bool isCalling(const LLUUID &id);*/
/**
- * @return true if call to the resident can be made (resident is online and voice is enabled)
+ * @return true if call to the resident can be made
*/
- static bool canCall(const LLUUID &id);
+ static bool canCall();
/**
* Invite avatar to a group.
*/
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 66ab32f3e8..2bcd097717 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -440,17 +440,17 @@ LLAvatarListItem::icon_color_map_t& LLAvatarListItem::getItemIconColorMap()
// static
void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item)
{
+ //speaking indicator width + padding
+ S32 speaking_indicator_width = avatar_item->getRect().getWidth() - avatar_item->mSpeakingIndicator->getRect().mLeft;
+
//profile btn width + padding
- S32 profile_btn_width = avatar_item->getRect().getWidth() - avatar_item->mProfileBtn->getRect().mLeft;
+ S32 profile_btn_width = avatar_item->mSpeakingIndicator->getRect().mLeft - avatar_item->mProfileBtn->getRect().mLeft;
//info btn width + padding
S32 info_btn_width = avatar_item->mProfileBtn->getRect().mLeft - avatar_item->mInfoBtn->getRect().mLeft;
- //speaking indicator width + padding
- S32 speaking_indicator_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mSpeakingIndicator->getRect().mLeft;
-
// last interaction time textbox width + padding
- S32 last_interaction_time_width = avatar_item->mSpeakingIndicator->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft;
+ S32 last_interaction_time_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft;
// icon width + padding
S32 icon_width = avatar_item->mAvatarName->getRect().mLeft - avatar_item->mAvatarIcon->getRect().mLeft;
@@ -462,9 +462,9 @@ 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] = speaking_indicator_width;
sChildrenWidths[--index] = info_btn_width;
sChildrenWidths[--index] = profile_btn_width;
+ sChildrenWidths[--index] = speaking_indicator_width;
}
void LLAvatarListItem::updateChildren()
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index 479a4833cb..61c0a8660e 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -129,9 +129,9 @@ private:
* @see updateChildren()
*/
typedef enum e_avatar_item_child {
+ ALIC_SPEAKER_INDICATOR,
ALIC_PROFILE_BUTTON,
ALIC_INFO_BUTTON,
- ALIC_SPEAKER_INDICATOR,
ALIC_INTERACTION_TIME,
ALIC_NAME,
ALIC_ICON,
diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp
index d4c8adadc6..f62fd44bc0 100644
--- a/indra/newview/llcallfloater.cpp
+++ b/indra/newview/llcallfloater.cpp
@@ -43,6 +43,7 @@
#include "llavatariconctrl.h"
#include "llavatarlist.h"
#include "llbottomtray.h"
+#include "lldraghandle.h"
#include "llimfloater.h"
#include "llfloaterreg.h"
#include "llparticipantlist.h"
@@ -158,6 +159,13 @@ BOOL LLCallFloater::postBuild()
connectToChannel(LLVoiceChannel::getCurrentVoiceChannel());
+ setIsChrome(true);
+ //chrome="true" hides floater caption
+ if (mDragHandle)
+ mDragHandle->setTitleVisible(TRUE);
+
+ updateSession();
+
return TRUE;
}
@@ -240,7 +248,7 @@ void LLCallFloater::updateSession()
}
}
- const LLUUID& session_id = voice_channel->getSessionID();
+ const LLUUID& session_id = voice_channel ? voice_channel->getSessionID() : LLUUID::null;
lldebugs << "Set speaker manager for session: " << session_id << llendl;
LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id);
@@ -562,33 +570,46 @@ void LLCallFloater::updateParticipantsVoiceState()
if (!found)
{
- // If an avatarID is not found in a speakers list from VoiceClient and
- // a panel with this ID has a JOINED status this means that this person
- // HAS LEFT the call.
- if ((getState(participant_id) == STATE_JOINED))
- {
- setState(item, STATE_LEFT);
+ updateNotInVoiceParticipantState(item);
+ }
+ }
+}
- LLPointer<LLSpeaker> speaker = mSpeakerManager->findSpeaker(item->getAvatarId());
- if (speaker.isNull())
- {
- continue;
- }
+void LLCallFloater::updateNotInVoiceParticipantState(LLAvatarListItem* item)
+{
+ LLUUID participant_id = item->getAvatarId();
+ ESpeakerState current_state = getState(participant_id);
- speaker->mHasLeftCurrentCall = TRUE;
- }
- // If an avatarID is not found in a speakers list from VoiceClient and
- // a panel with this ID has a LEFT status this means that this person
- // HAS ENTERED session but it is not in voice chat yet. So, set INVITED status
- else if ((getState(participant_id) != STATE_LEFT))
- {
- setState(item, STATE_INVITED);
- }
- else
+ switch (current_state)
+ {
+ case STATE_JOINED:
+ // If an avatarID is not found in a speakers list from VoiceClient and
+ // a panel with this ID has a JOINED status this means that this person
+ // HAS LEFT the call.
+ setState(item, STATE_LEFT);
+
+ {
+ LLPointer<LLSpeaker> speaker = mSpeakerManager->findSpeaker(participant_id);
+ if (speaker.notNull())
{
- llwarns << "Unsupported (" << getState(participant_id) << ") state: " << item->getAvatarName() << llendl;
+ speaker->mHasLeftCurrentCall = TRUE;
}
}
+ break;
+ case STATE_INVITED:
+ case STATE_LEFT:
+ // nothing to do. These states should not be changed.
+ break;
+ case STATE_UNKNOWN:
+ // If an avatarID is not found in a speakers list from VoiceClient and
+ // a panel with this ID has an UNKNOWN status this means that this person
+ // HAS ENTERED session but it is not in voice chat yet. So, set INVITED status
+ setState(item, STATE_INVITED);
+ break;
+ default:
+ // for possible new future states.
+ llwarns << "Unsupported (" << getState(participant_id) << ") state for: " << item->getAvatarName() << llendl;
+ break;
}
}
diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h
index eded3a426b..766191379b 100644
--- a/indra/newview/llcallfloater.h
+++ b/indra/newview/llcallfloater.h
@@ -145,6 +145,10 @@ private:
*/
void updateParticipantsVoiceState();
+ /**
+ * Updates voice state of participant not in current voice channel depend on its current state.
+ */
+ void updateNotInVoiceParticipantState(LLAvatarListItem* item);
void setState(LLAvatarListItem* item, ESpeakerState state);
void setState(const LLUUID& speaker_id, ESpeakerState state)
{
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index a46cd84b60..d6a7edee5b 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -550,8 +550,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_
if (mLastFromName == chat.mFromName
&& mLastFromID == chat.mFromID
&& mLastMessageTime.notNull()
- && (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0
- )
+ && (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0
+ && mLastMessageTimeStr.size() == chat.mTimeStr.size()) //*HACK to distinguish between current and previous chat session's histories
{
view = getSeparator();
p.top_pad = mTopSeparatorPad;
@@ -585,6 +585,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_
mLastFromName = chat.mFromName;
mLastFromID = chat.mFromID;
mLastMessageTime = new_message_time;
+ mLastMessageTimeStr = chat.mTimeStr;
}
std::string message = irc_me ? chat.mText.substr(3) : chat.mText;
diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h
index f2d403f639..c2c60e60cf 100644
--- a/indra/newview/llchathistory.h
+++ b/indra/newview/llchathistory.h
@@ -125,6 +125,8 @@ class LLChatHistory : public LLUICtrl
std::string mLastFromName;
LLUUID mLastFromID;
LLDate mLastMessageTime;
+ std::string mLastMessageTimeStr;
+
std::string mMessageHeaderFilename;
std::string mMessageSeparatorFilename;
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 47f1b7c9f5..5c05a54120 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -446,19 +446,17 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status )
{
- //TODO* CHAT: how to show this?
- //LLSD args;
- //args["MESSAGE"] = LLTrans::getString("CompileQueueScriptNotFound);
- //LLNotificationsUtil::add("SystemMessage", args);
+ LLSD args;
+ args["MESSAGE"] = LLTrans::getString("CompileQueueScriptNotFound");
+ LLNotificationsUtil::add("SystemMessage", args);
buffer = LLTrans::getString("CompileQueueProblemDownloading") + (": ") + data->mScriptName;
}
else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
{
- //TODO* CHAT: how to show this?
- //LLSD args;
- //args["MESSAGE"] = LLTrans::getString("CompileQueueScriptNotFound);
- //LLNotificationsUtil::add("SystemMessage", args);
+ LLSD args;
+ args["MESSAGE"] = LLTrans::getString("CompileQueueInsufficientPermDownload");
+ LLNotificationsUtil::add("SystemMessage", args);
buffer = LLTrans::getString("CompileQueueInsufficientPermFor") + (": ") + data->mScriptName;
}
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index ef69f39ad2..04f4ddf996 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -187,6 +187,12 @@ BOOL LLFloaterAbout::postBuild()
support << '\n' << getString("AboutTraffic", args);
}
+ // don't make the sim hostname be a hyperlink
+ if (info.has("HOSTNAME"))
+ {
+ support_widget->addBlackListUrl(info["HOSTNAME"].asString());
+ }
+
support_widget->appendText(support.str(),
FALSE,
LLStyle::Params()
diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp
index 29f415bd43..c71764c2e5 100644
--- a/indra/newview/llfloatergroups.cpp
+++ b/indra/newview/llfloatergroups.cpp
@@ -75,7 +75,7 @@ LLFloaterGroupPicker::~LLFloaterGroupPicker()
void LLFloaterGroupPicker::setPowersMask(U64 powers_mask)
{
mPowersMask = powers_mask;
- postBuild();
+ init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID(), mPowersMask);
}
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index fc036cb354..e77c93b5f8 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -327,6 +327,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.AutoDetectAspect", boost::bind(&LLFloaterPreference::onCommitAutoDetectAspect, this));
mCommitCallbackRegistrar.add("Pref.ParcelMediaAutoPlayEnable", boost::bind(&LLFloaterPreference::onCommitParcelMediaAutoPlayEnable, this));
mCommitCallbackRegistrar.add("Pref.MediaEnabled", boost::bind(&LLFloaterPreference::onCommitMediaEnabled, this));
+ mCommitCallbackRegistrar.add("Pref.MusicEnabled", boost::bind(&LLFloaterPreference::onCommitMusicEnabled, this));
mCommitCallbackRegistrar.add("Pref.onSelectAspectRatio", boost::bind(&LLFloaterPreference::onKeystrokeAspectRatio, this));
mCommitCallbackRegistrar.add("Pref.QualityPerformance", boost::bind(&LLFloaterPreference::onChangeQuality, this, _2));
mCommitCallbackRegistrar.add("Pref.applyUIColor", boost::bind(&LLFloaterPreference::applyUIColor, this ,_1, _2));
@@ -1001,12 +1002,14 @@ void LLFloaterPreference::onCommitMediaEnabled()
{
LLCheckBoxCtrl *media_enabled_ctrl = getChild<LLCheckBoxCtrl>("media_enabled");
bool enabled = media_enabled_ctrl->get();
- gSavedSettings.setBOOL("AudioStreamingVideo", enabled);
- gSavedSettings.setBOOL("AudioStreamingMusic", enabled);
gSavedSettings.setBOOL("AudioStreamingMedia", enabled);
- media_enabled_ctrl->setTentative(false);
- // Update enabled state of the "autoplay" checkbox
- getChild<LLCheckBoxCtrl>("autoplay_enabled")->setEnabled(enabled);
+}
+
+void LLFloaterPreference::onCommitMusicEnabled()
+{
+ LLCheckBoxCtrl *music_enabled_ctrl = getChild<LLCheckBoxCtrl>("music_enabled");
+ bool enabled = music_enabled_ctrl->get();
+ gSavedSettings.setBOOL("AudioStreamingMusic", enabled);
}
void LLFloaterPreference::refresh()
@@ -1424,17 +1427,16 @@ BOOL LLPanelPreference::postBuild()
}
//////////////////////PanelPrivacy ///////////////////
- if(hasChild("media_enabled"))
+ if (hasChild("media_enabled"))
{
- bool video_enabled = gSavedSettings.getBOOL("AudioStreamingVideo");
- bool music_enabled = gSavedSettings.getBOOL("AudioStreamingMusic");
bool media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia");
- bool enabled = video_enabled || music_enabled || media_enabled;
-
- LLCheckBoxCtrl *media_enabled_ctrl = getChild<LLCheckBoxCtrl>("media_enabled");
- media_enabled_ctrl->set(enabled);
- media_enabled_ctrl->setTentative(!(video_enabled == music_enabled == media_enabled));
- getChild<LLCheckBoxCtrl>("autoplay_enabled")->setEnabled(enabled);
+ getChild<LLCheckBoxCtrl>("voice_call_friends_only_check")->setCommitCallback(boost::bind(&showFriendsOnlyWarning, _1, _2));
+ getChild<LLCheckBoxCtrl>("media_enabled")->set(media_enabled);
+ getChild<LLCheckBoxCtrl>("autoplay_enabled")->setEnabled(media_enabled);
+ }
+ if (hasChild("music_enabled"))
+ {
+ getChild<LLCheckBoxCtrl>("music_enabled")->set(gSavedSettings.getBOOL("AudioStreamingMusic"));
}
apply();
@@ -1485,6 +1487,14 @@ void LLPanelPreference::saveSettings()
}
}
+void LLPanelPreference::showFriendsOnlyWarning(LLUICtrl* checkbox, const LLSD& value)
+{
+ if (checkbox && checkbox->getValue())
+ {
+ LLNotificationsUtil::add("FriendsAndGroupsOnly");
+ }
+}
+
void LLPanelPreference::cancel()
{
for (control_values_map_t::iterator iter = mSavedValues.begin();
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 6f382620ee..8778d76a5a 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -134,6 +134,7 @@ public:
void onCommitAutoDetectAspect();
void onCommitParcelMediaAutoPlayEnable();
void onCommitMediaEnabled();
+ void onCommitMusicEnabled();
void applyResolution();
void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
void getUIColor(LLUICtrl* ctrl, const LLSD& param);
@@ -166,6 +167,9 @@ public:
virtual void saveSettings();
private:
+ //for "Only friends and groups can call or IM me"
+ static void showFriendsOnlyWarning(LLUICtrl*, const LLSD&);
+
typedef std::map<LLControlVariable*, LLSD> control_values_map_t;
control_values_map_t mSavedValues;
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 2efae0c8db..4a1eb51dbe 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -324,7 +324,7 @@ void LLFloaterReporter::setFromAvatar(const LLUUID& avatar_id, const std::string
std::string avatar_link = LLSLURL::buildCommand("agent", mObjectID, "inspect");
childSetText("owner_name", avatar_link);
- childSetText("object_name", avatar_name); // name
+ childSetText("object_name", avatar_name);
childSetText("abuser_name_edit", avatar_name);
}
diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp
index 0964ad7f91..8875e35821 100644
--- a/indra/newview/llfloaterscriptlimits.cpp
+++ b/indra/newview/llfloaterscriptlimits.cpp
@@ -528,7 +528,16 @@ BOOL LLPanelScriptLimitsRegionMemory::postBuild()
std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting");
childSetValue("loading_text", LLSD(msg_waiting));
-
+
+ LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list");
+
+ //set all columns to resizable mode even if some columns will be empty
+ for(S32 column = 0; column < list->getNumColumns(); column++)
+ {
+ LLScrollListColumn* columnp = list->getColumn(column);
+ columnp->mHeader->setHasResizableElement(TRUE);
+ }
+
return StartRequestChain();
}
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index e75d35bea4..e01709aa3a 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -48,6 +48,7 @@
#include "lltextutil.h"
#include "llviewercontrol.h" // for gSavedSettings
#include "llviewermenu.h" // for gMenuHolder
+#include "llvoiceclient.h"
static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
S32 LLGroupListItem::sIconWidth = 0;
@@ -271,6 +272,9 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)
if (userdata.asString() == "activate")
return gAgent.getGroupID() != selected_group_id;
+ if (userdata.asString() == "call")
+ return LLVoiceClient::voiceEnabled()&&gVoiceClient->voiceWorking();
+
return real_group_selected;
}
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index c2a7969c0d..f90a51c3f3 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -95,7 +95,8 @@ void toast_callback(const LLSD& msg){
}
// check whether incoming IM belongs to an active session or not
- if (LLIMModel::getInstance()->getActiveSessionID() == msg["session_id"])
+ if (LLIMModel::getInstance()->getActiveSessionID().notNull()
+ && LLIMModel::getInstance()->getActiveSessionID() == msg["session_id"])
{
return;
}
@@ -1577,7 +1578,7 @@ void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id)
}
}
-bool LLOutgoingCallDialog::lifetimeHasExpired()
+bool LLCallDialog::lifetimeHasExpired()
{
if (mLifetimeTimer.getStarted())
{
@@ -1590,7 +1591,7 @@ bool LLOutgoingCallDialog::lifetimeHasExpired()
return false;
}
-void LLOutgoingCallDialog::onLifetimeExpired()
+void LLCallDialog::onLifetimeExpired()
{
mLifetimeTimer.stop();
closeFloater();
@@ -1680,6 +1681,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
case LLVoiceChannel::STATE_ERROR :
getChild<LLTextBox>("noanswer")->setVisible(true);
getChild<LLButton>("Cancel")->setVisible(false);
+ setCanClose(true);
mLifetimeTimer.start();
break;
case LLVoiceChannel::STATE_HUNG_UP :
@@ -1692,6 +1694,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
getChild<LLTextBox>("nearby")->setVisible(true);
}
getChild<LLButton>("Cancel")->setVisible(false);
+ setCanClose(true);
mLifetimeTimer.start();
}
@@ -1742,19 +1745,6 @@ LLCallDialog(payload)
{
}
-bool LLIncomingCallDialog::lifetimeHasExpired()
-{
- if (mLifetimeTimer.getStarted())
- {
- F32 elapsed_time = mLifetimeTimer.getElapsedTimeF32();
- if (elapsed_time > mLifetime)
- {
- return true;
- }
- }
- return false;
-}
-
void LLIncomingCallDialog::onLifetimeExpired()
{
// check whether a call is valid or not
@@ -3216,6 +3206,42 @@ public:
}
};
+LLCallInfoDialog::LLCallInfoDialog(const LLSD& payload) : LLCallDialog(payload)
+{
+}
+
+BOOL LLCallInfoDialog::postBuild()
+{
+ // init notification's lifetime
+ std::istringstream ss( getString("lifetime") );
+ if (!(ss >> mLifetime))
+ {
+ mLifetime = DEFAULT_LIFETIME;
+ }
+ return LLCallDialog::postBuild();
+}
+
+void LLCallInfoDialog::onOpen(const LLSD& key)
+{
+ if(key.has("msg"))
+ {
+ std::string msg = key["msg"];
+ getChild<LLTextBox>("msg")->setValue(msg);
+ }
+
+ mLifetimeTimer.start();
+}
+
+void LLCallInfoDialog::show(const std::string& status_name, const LLSD& args)
+{
+ LLUIString message = LLTrans::getString(status_name);
+ message.setArgs(args);
+
+ LLSD payload;
+ payload["msg"] = message;
+ LLFloaterReg::showInstance("call_info", payload);
+}
+
LLHTTPRegistration<LLViewerChatterBoxSessionStartReply>
gHTTPRegistrationMessageChatterboxsessionstartreply(
"/message/ChatterBoxSessionStartReply");
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index a3b4f78af0..0386ff234d 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -512,8 +512,8 @@ protected:
// notification's lifetime in seconds
S32 mLifetime;
static const S32 DEFAULT_LIFETIME = 5;
- virtual bool lifetimeHasExpired() {return false;};
- virtual void onLifetimeExpired() {};
+ virtual bool lifetimeHasExpired();
+ virtual void onLifetimeExpired();
virtual void getAllowedRect(LLRect& rect);
@@ -543,7 +543,6 @@ public:
static void onStartIM(void* user_data);
private:
- /*virtual*/ bool lifetimeHasExpired();
/*virtual*/ void onLifetimeExpired();
void processCallResponse(S32 response);
};
@@ -562,8 +561,16 @@ public:
private:
// hide all text boxes
void hideAllText();
- /*virtual*/ bool lifetimeHasExpired();
- /*virtual*/ void onLifetimeExpired();
+};
+
+class LLCallInfoDialog : public LLCallDialog
+{
+public:
+ LLCallInfoDialog(const LLSD& payload);
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
+
+ static void show(const std::string& status_name, const LLSD& args);
};
// Globals
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 4b0539337b..3a41aebf28 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -229,6 +229,7 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd)
mEnableCallbackRegistrar.add("InspectAvatar.VisibleZoomIn",
boost::bind(&LLInspectAvatar::onVisibleZoomIn, this));
mEnableCallbackRegistrar.add("InspectAvatar.Gear.Enable", boost::bind(&LLInspectAvatar::isNotFriend, this));
+ mEnableCallbackRegistrar.add("InspectAvatar.Gear.EnableCall", boost::bind(&LLAvatarActions::canCall));
mEnableCallbackRegistrar.add("InspectAvatar.EnableMute", boost::bind(&LLInspectAvatar::enableMute, this));
mEnableCallbackRegistrar.add("InspectAvatar.EnableUnmute", boost::bind(&LLInspectAvatar::enableUnmute, this));
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 0ab3b07aea..5981baab60 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -589,8 +589,16 @@ void LLPanelStandStopFlying::setVisible(BOOL visible)
updatePosition();
}
- //change visibility of parent layout_panel to animate in/out
- if (getParent()) getParent()->setVisible(visible);
+ // do not change parent visibility in case panel is attached into Move Floater: EXT-3632, EXT-4646
+ if (!mAttached)
+ {
+ //change visibility of parent layout_panel to animate in/out. EXT-2504
+ if (getParent()) getParent()->setVisible(visible);
+ }
+
+ // also change own visibility to avoid displaying the panel in mouselook (broken when EXT-2504 was implemented).
+ // See EXT-4718.
+ LLPanel::setVisible(visible);
}
BOOL LLPanelStandStopFlying::handleToolTip(S32 x, S32 y, MASK mask)
@@ -614,7 +622,7 @@ void LLPanelStandStopFlying::reparent(LLFloaterMove* move_view)
LLPanel* parent = dynamic_cast<LLPanel*>(getParent());
if (!parent)
{
- llwarns << "Stand/stop flying panel parent is unset" << llendl;
+ llwarns << "Stand/stop flying panel parent is unset, already attached?: " << mAttached << ", new parent: " << (move_view == NULL ? "NULL" : "Move Floater") << llendl;
return;
}
@@ -684,6 +692,7 @@ void LLPanelStandStopFlying::onStopFlyingButtonClick()
gAgent.setFlying(FALSE);
setFocus(FALSE); // EXT-482
+ setVisible(FALSE);
}
/**
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 7ee4c64f8f..c1666f5666 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -52,23 +52,15 @@
#include <boost/tokenizer.hpp>
-#include "llcrc.h"
-#include "lldir.h"
#include "lldispatcher.h"
-#include "llsdserialize.h"
#include "llxfermanager.h"
-#include "message.h"
#include "llagent.h"
#include "llviewergenericmessage.h" // for gGenericDispatcher
-#include "llviewerwindow.h"
#include "llworld.h" //for particle system banning
-#include "llchat.h"
#include "llimpanel.h"
#include "llimview.h"
#include "llnotifications.h"
-#include "lluistring.h"
-#include "llviewerobject.h"
#include "llviewerobjectlist.h"
#include "lltrans.h"
@@ -219,61 +211,17 @@ LLMuteList* LLMuteList::getInstance()
// LLMuteList()
//-----------------------------------------------------------------------------
LLMuteList::LLMuteList() :
- mIsLoaded(FALSE),
- mUserVolumesLoaded(FALSE)
+ mIsLoaded(FALSE)
{
gGenericDispatcher.addHandler("emptymutelist", &sDispatchEmptyMuteList);
}
-void LLMuteList::loadUserVolumes()
-{
- // call once, after LLDir::setLindenUserDir() has been called
- if (mUserVolumesLoaded)
- return;
- mUserVolumesLoaded = TRUE;
-
- // load per-resident voice volume information
- // conceptually, this is part of the mute list information, although it is only stored locally
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "volume_settings.xml");
-
- LLSD settings_llsd;
- llifstream file;
- file.open(filename);
- if (file.is_open())
- {
- LLSDSerialize::fromXML(settings_llsd, file);
- }
-
- for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
- iter != settings_llsd.endMap(); ++iter)
- {
- mUserVolumeSettings.insert(std::make_pair(LLUUID(iter->first), (F32)iter->second.asReal()));
- }
-}
-
//-----------------------------------------------------------------------------
// ~LLMuteList()
//-----------------------------------------------------------------------------
LLMuteList::~LLMuteList()
{
- // If we quit from the login screen we will not have an SL account
- // name. Don't try to save, otherwise we'll dump a file in
- // C:\Program Files\SecondLife\ or similar. JC
- std::string user_dir = gDirUtilp->getLindenUserDir();
- if (!user_dir.empty())
- {
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "volume_settings.xml");
- LLSD settings_llsd;
-
- for(user_volume_map_t::iterator iter = mUserVolumeSettings.begin(); iter != mUserVolumeSettings.end(); ++iter)
- {
- settings_llsd[iter->first.asString()] = iter->second;
- }
- llofstream file;
- file.open(filename);
- LLSDSerialize::toPrettyXML(settings_llsd, file);
- }
}
BOOL LLMuteList::isLinden(const std::string& name) const
@@ -715,8 +663,6 @@ BOOL LLMuteList::isMuted(const LLUUID& id, const std::string& name, U32 flags) c
//-----------------------------------------------------------------------------
void LLMuteList::requestFromServer(const LLUUID& agent_id)
{
- loadUserVolumes();
-
std::string agent_id_string;
std::string filename;
agent_id.toString(agent_id_string);
@@ -751,26 +697,6 @@ void LLMuteList::cache(const LLUUID& agent_id)
}
}
-void LLMuteList::setSavedResidentVolume(const LLUUID& id, F32 volume)
-{
- // store new value in volume settings file
- mUserVolumeSettings[id] = volume;
-}
-
-F32 LLMuteList::getSavedResidentVolume(const LLUUID& id)
-{
- const F32 DEFAULT_VOLUME = 0.5f;
-
- user_volume_map_t::iterator found_it = mUserVolumeSettings.find(id);
- if (found_it != mUserVolumeSettings.end())
- {
- return found_it->second;
- }
- //FIXME: assumes default, should get this from somewhere
- return DEFAULT_VOLUME;
-}
-
-
//-----------------------------------------------------------------------------
// Static message handlers
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h
index 409b637bf2..e1e81a24b4 100644
--- a/indra/newview/llmutelist.h
+++ b/indra/newview/llmutelist.h
@@ -127,12 +127,7 @@ public:
// call this method on logout to save everything.
void cache(const LLUUID& agent_id);
- void setSavedResidentVolume(const LLUUID& id, F32 volume);
- F32 getSavedResidentVolume(const LLUUID& id);
-
private:
- void loadUserVolumes();
-
BOOL loadFromFile(const std::string& filename);
BOOL saveToFile(const std::string& filename);
@@ -179,12 +174,8 @@ private:
observer_set_t mObservers;
BOOL mIsLoaded;
- BOOL mUserVolumesLoaded;
friend class LLDispatchEmptyMuteList;
-
- typedef std::map<LLUUID, F32> user_volume_map_t;
- user_volume_map_t mUserVolumeSettings;
};
class LLMuteListObserver
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 6375362ae2..9f04558d50 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -148,7 +148,7 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
&& column_index == mNameColumnIndex)
{
// ...this is the column with the avatar name
- LLUUID avatar_id = getItemId(hit_item);
+ LLUUID avatar_id = hit_item->getUUID();
if (avatar_id.notNull())
{
// ...valid avatar id
@@ -230,14 +230,15 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
std::string& suffix)
{
LLUUID id = name_item.value().asUUID();
- LLScrollListItem* item = NULL;
+ LLNameListItem* item = NULL;
// Store item type so that we can invoke the proper inspector.
// *TODO Vadim: Is there a more proper way of storing additional item data?
{
- LLNameListCtrl::NameItem name_item_(name_item);
- name_item_.value = LLSD().with("uuid", id).with("is_group", name_item.target() == GROUP);
- item = LLScrollListCtrl::addRow(name_item_, pos);
+ LLNameListCtrl::NameItem item_p(name_item);
+ item_p.value = LLSD().with("uuid", id).with("is_group", name_item.target() == GROUP);
+ item = new LLNameListItem(item_p);
+ LLScrollListCtrl::addRow(item, item_p, pos);
}
if (!item) return NULL;
@@ -298,7 +299,7 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id)
for (item_list::iterator it = getItemList().begin(); it != getItemList().end(); it++)
{
LLScrollListItem* item = *it;
- if (getItemId(item) == agent_id)
+ if (item->getUUID() == agent_id)
{
idx = getItemIndex(item);
break;
@@ -335,7 +336,7 @@ void LLNameListCtrl::refresh(const LLUUID& id, const std::string& first,
for (iter = getItemList().begin(); iter != getItemList().end(); iter++)
{
LLScrollListItem* item = *iter;
- if (getItemId(item) == id)
+ if (item->getUUID() == id)
{
LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(0);
cell = item->getColumn(mNameColumnIndex);
@@ -375,9 +376,3 @@ void LLNameListCtrl::updateColumns()
}
}
}
-
-// static
-LLUUID LLNameListCtrl::getItemId(LLScrollListItem* item)
-{
- return item->getValue()["uuid"].asUUID();
-}
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index 192a3a5afa..23b1cb6897 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -122,7 +122,6 @@ public:
/*virtual*/ void updateColumns();
private:
void showInspector(const LLUUID& avatar_id, bool is_group);
- static LLUUID getItemId(LLScrollListItem* item);
private:
S32 mNameColumnIndex;
@@ -130,4 +129,24 @@ private:
BOOL mAllowCallingCardDrop;
};
+/**
+ * LLNameListCtrl item
+ *
+ * We don't use LLScrollListItem to be able to override getUUID(), which is needed
+ * because the name list item value is not simply an UUID but a map (uuid, is_group).
+ */
+class LLNameListItem : public LLScrollListItem
+{
+public:
+ LLUUID getUUID() const { return getValue()["uuid"].asUUID(); }
+
+protected:
+ friend class LLNameListCtrl;
+
+ LLNameListItem( const LLScrollListItem::Params& p )
+ : LLScrollListItem(p)
+ {
+ }
+};
+
#endif
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index a7c1e73328..0a8d020b4f 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -101,6 +101,11 @@ BOOL LLNearbyChat::postBuild()
getDockTongue(), LLDockControl::TOP, boost::bind(&LLNearbyChat::getAllowedRect, this, _1)));
}
+ setIsChrome(true);
+ //chrome="true" hides floater caption
+ if (mDragHandle)
+ mDragHandle->setTitleVisible(TRUE);
+
return true;
}
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index c50e049d4c..a1a9d84c14 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -356,12 +356,17 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg)
initChannel();
}
+ /*
+ //comment all this due to EXT-4432
+ ..may clean up after some time...
+
//only messages from AGENTS
if(CHAT_SOURCE_OBJECT == chat_msg.mSourceType)
{
if(chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG)
return;//ok for now we don't skip messeges from object, so skip only debug messages
}
+ */
LLUUID id;
id.generate();
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index fba5773602..02f948eca9 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -123,7 +123,14 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
message);
// restore active session id
- LLIMModel::instance().setActiveSessionID(active_session_id);
+ if (active_session_id.isNull())
+ {
+ LLIMModel::instance().resetActiveSessionID();
+ }
+ else
+ {
+ LLIMModel::instance().setActiveSessionID(active_session_id);
+ }
}
}
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 85e95ca1d6..fe5b20813a 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -165,6 +165,8 @@ BOOL LLPanelAvatarNotes::postBuild()
resetControls();
resetData();
+ gVoiceClient->addObserver((LLVoiceClientStatusObserver*)this);
+
return TRUE;
}
@@ -337,6 +339,8 @@ LLPanelAvatarNotes::~LLPanelAvatarNotes()
if(getAvatarId().notNull())
{
LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
+ if(LLVoiceClient::getInstance())
+ LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);
}
}
@@ -346,6 +350,17 @@ void LLPanelAvatarNotes::changed(U32 mask)
childSetEnabled("teleport", LLAvatarTracker::instance().isBuddyOnline(getAvatarId()));
}
+// virtual
+void LLPanelAvatarNotes::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+ {
+ return;
+ }
+
+ childSetEnabled("call", LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking());
+}
+
void LLPanelAvatarNotes::setAvatarId(const LLUUID& id)
{
if(id.notNull())
@@ -437,7 +452,6 @@ void LLPanelProfileTab::updateButtons()
bool enable_map_btn = is_avatar_online && gAgent.isGodlike() || is_agent_mappable(getAvatarId());
childSetEnabled("show_on_map_btn", enable_map_btn);
- childSetEnabled("call", LLAvatarActions::canCall(getAvatarId()));
}
//////////////////////////////////////////////////////////////////////////
@@ -485,6 +499,8 @@ BOOL LLPanelAvatarProfile::postBuild()
pic = getChild<LLTextureCtrl>("real_world_pic");
pic->setFallbackImageName("default_profile_picture.j2c");
+ gVoiceClient->addObserver((LLVoiceClientStatusObserver*)this);
+
resetControls();
resetData();
@@ -568,8 +584,6 @@ void LLPanelAvatarProfile::processProfileProperties(const LLAvatarData* avatar_d
fillPartnerData(avatar_data);
- fillOnlineStatus(avatar_data);
-
fillAccountStatus(avatar_data);
}
@@ -637,21 +651,6 @@ void LLPanelAvatarProfile::fillPartnerData(const LLAvatarData* avatar_data)
}
}
-void LLPanelAvatarProfile::fillOnlineStatus(const LLAvatarData* avatar_data)
-{
- bool online = avatar_data->flags & AVATAR_ONLINE;
- if(LLAvatarActions::isFriend(avatar_data->avatar_id))
- {
- // Online status NO could be because they are hidden
- // If they are a friend, we may know the truth!
- online = LLAvatarTracker::instance().isBuddyOnline(avatar_data->avatar_id);
- }
- childSetValue("online_status", online ?
- "Online" : "Offline");
- childSetColor("online_status", online ?
- LLColor4::green : LLColor4::red);
-}
-
void LLPanelAvatarProfile::fillAccountStatus(const LLAvatarData* avatar_data)
{
LLStringUtil::format_map_t args;
@@ -757,6 +756,8 @@ LLPanelAvatarProfile::~LLPanelAvatarProfile()
if(getAvatarId().notNull())
{
LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
+ if(LLVoiceClient::getInstance())
+ LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);
}
}
@@ -766,6 +767,17 @@ void LLPanelAvatarProfile::changed(U32 mask)
childSetEnabled("teleport", LLAvatarTracker::instance().isBuddyOnline(getAvatarId()));
}
+// virtual
+void LLPanelAvatarProfile::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+ {
+ return;
+ }
+
+ childSetEnabled("call", LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking());
+}
+
void LLPanelAvatarProfile::setAvatarId(const LLUUID& id)
{
if(id.notNull())
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index 22efa5dc35..ce59f1e93d 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -36,6 +36,7 @@
#include "llpanel.h"
#include "llavatarpropertiesprocessor.h"
#include "llcallingcard.h"
+#include "llvoiceclient.h"
class LLComboBox;
class LLLineEditor;
@@ -122,6 +123,7 @@ private:
class LLPanelAvatarProfile
: public LLPanelProfileTab
, public LLFriendObserver
+ , public LLVoiceClientStatusObserver
{
public:
LLPanelAvatarProfile();
@@ -134,6 +136,10 @@ public:
*/
virtual void changed(U32 mask);
+ // Implements LLVoiceClientStatusObserver::onChange() to enable the call
+ // button when voice is available
+ /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
/*virtual*/ void setAvatarId(const LLUUID& id);
/**
@@ -172,11 +178,6 @@ protected:
virtual void fillPartnerData(const LLAvatarData* avatar_data);
/**
- * Fills Avatar's online status.
- */
- virtual void fillOnlineStatus(const LLAvatarData* avatar_data);
-
- /**
* Fills account status.
*/
virtual void fillAccountStatus(const LLAvatarData* avatar_data);
@@ -257,6 +258,7 @@ private:
class LLPanelAvatarNotes
: public LLPanelProfileTab
, public LLFriendObserver
+ , public LLVoiceClientStatusObserver
{
public:
LLPanelAvatarNotes();
@@ -269,6 +271,10 @@ public:
*/
virtual void changed(U32 mask);
+ // Implements LLVoiceClientStatusObserver::onChange() to enable the call
+ // button when voice is available
+ /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ BOOL postBuild();
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index c30ef3221d..1d447a22d7 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -101,6 +101,8 @@ LLPanelGroup::LLPanelGroup()
LLPanelGroup::~LLPanelGroup()
{
LLGroupMgr::getInstance()->removeObserver(this);
+ if(LLVoiceClient::getInstance())
+ LLVoiceClient::getInstance()->removeObserver(this);
}
void LLPanelGroup::onOpen(const LLSD& key)
@@ -188,6 +190,8 @@ BOOL LLPanelGroup::postBuild()
if(panel_general)
panel_general->setupCtrls(this);
+
+ gVoiceClient->addObserver(this);
return TRUE;
}
@@ -300,6 +304,17 @@ void LLPanelGroup::changed(LLGroupChange gc)
update(gc);
}
+// virtual
+void LLPanelGroup::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+ {
+ return;
+ }
+
+ childSetEnabled("btn_call", LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking());
+}
+
void LLPanelGroup::notifyObservers()
{
changed(GC_ALL);
@@ -356,6 +371,13 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
(*it)->setGroupID(group_id);
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
+ if(gdatap)
+ {
+ childSetValue("group_name", gdatap->mName);
+ childSetToolTip("group_name",gdatap->mName);
+ }
+
LLButton* button_apply = findChild<LLButton>("btn_apply");
LLButton* button_refresh = findChild<LLButton>("btn_refresh");
LLButton* button_create = findChild<LLButton>("btn_create");
@@ -457,17 +479,6 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
}
reposButtons();
-
- LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
-
- if(gdatap)
- {
- childSetValue("group_name", gdatap->mName);
- childSetToolTip("group_name",gdatap->mName);
-
- //group data is already present, call update manually
- update(GC_ALL);
- }
}
bool LLPanelGroup::apply(LLPanelGroupTab* tab)
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index 7ea5e67b44..8c84695677 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -35,6 +35,7 @@
#include "llgroupmgr.h"
#include "llpanel.h"
#include "lltimer.h"
+#include "llvoiceclient.h"
struct LLOfferInfo;
@@ -47,7 +48,8 @@ class LLAgent;
class LLPanelGroup : public LLPanel,
- public LLGroupMgrObserver
+ public LLGroupMgrObserver,
+ public LLVoiceClientStatusObserver
{
public:
LLPanelGroup();
@@ -64,6 +66,10 @@ public:
// Group manager observer trigger.
virtual void changed(LLGroupChange gc);
+ // Implements LLVoiceClientStatusObserver::onChange() to enable the call
+ // button when voice is available
+ /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
void showNotice(const std::string& subject,
const std::string& message,
const bool& has_inventory,
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 45f0381d6f..c6287472fe 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -867,7 +867,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()
for (itor = selection.begin();
itor != selection.end(); ++itor)
{
- LLUUID member_id = (*itor)->getValue()["uuid"];
+ LLUUID member_id = (*itor)->getUUID();
selected_members.push_back( member_id );
// Get this member's power mask including any unsaved changes
@@ -1093,7 +1093,7 @@ void LLPanelGroupMembersSubTab::handleEjectMembers()
for (itor = selection.begin() ;
itor != selection.end(); ++itor)
{
- LLUUID member_id = (*itor)->getValue()["uuid"];
+ LLUUID member_id = (*itor)->getUUID();
selected_members.push_back( member_id );
}
@@ -1151,7 +1151,7 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id,
itor != selection.end(); ++itor)
{
- member_id = (*itor)->getValue()["uuid"];
+ member_id = (*itor)->getUUID();
//see if we requested a change for this member before
if ( mMemberRoleChangeData.find(member_id) == mMemberRoleChangeData.end() )
@@ -1242,7 +1242,7 @@ void LLPanelGroupMembersSubTab::handleMemberDoubleClick()
LLScrollListItem* selected = mMembersList->getFirstSelected();
if (selected)
{
- LLUUID member_id = selected->getValue()["uuid"];
+ LLUUID member_id = selected->getUUID();
LLAvatarActions::showProfile( member_id );
}
}
@@ -1632,7 +1632,7 @@ void LLPanelGroupMembersSubTab::updateMembers()
LLScrollListItem* member = mMembersList->addElement(row);//, ADD_SORTED);
- LLUUID id = member->getValue()["uuid"];
+ LLUUID id = member->getUUID();
mHasMatch = TRUE;
}
}
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index a334eb9d68..ff1e43b526 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -64,21 +64,52 @@ void LLPanelChatControlPanel::onOpenVoiceControlsClicked()
LLFloaterReg::showInstance("voice_controls");
}
+void LLPanelChatControlPanel::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+ {
+ return;
+ }
+
+ updateCallButton();
+}
+
void LLPanelChatControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
{
updateButtons(new_state >= LLVoiceChannel::STATE_CALL_STARTED);
}
+void LLPanelChatControlPanel::updateCallButton()
+{
+ // hide/show call button
+ bool voice_enabled = LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking();
+
+ LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionId);
+ if (!session) return;
+
+ bool session_initialized = session->mSessionInitialized;
+ bool callback_enabled = session->mCallBackEnabled;
+
+ BOOL enable_connect = session_initialized
+ && voice_enabled
+ && callback_enabled;
+ childSetEnabled("call_btn", enable_connect);
+}
+
void LLPanelChatControlPanel::updateButtons(bool is_call_started)
{
childSetVisible("end_call_btn_panel", is_call_started);
childSetVisible("voice_ctrls_btn_panel", is_call_started);
childSetVisible("call_btn_panel", ! is_call_started);
+ updateCallButton();
+
}
LLPanelChatControlPanel::~LLPanelChatControlPanel()
{
mVoiceChannelStateChangeConnection.disconnect();
+ if(LLVoiceClient::getInstance())
+ LLVoiceClient::getInstance()->removeObserver(this);
}
BOOL LLPanelChatControlPanel::postBuild()
@@ -87,26 +118,9 @@ BOOL LLPanelChatControlPanel::postBuild()
childSetAction("end_call_btn", boost::bind(&LLPanelChatControlPanel::onEndCallButtonClicked, this));
childSetAction("voice_ctrls_btn", boost::bind(&LLPanelChatControlPanel::onOpenVoiceControlsClicked, this));
- return TRUE;
-}
-
-void LLPanelChatControlPanel::draw()
-{
- // hide/show start call and end call buttons
- bool voice_enabled = LLVoiceClient::voiceEnabled();
-
- LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionId);
- if (!session) return;
+ gVoiceClient->addObserver(this);
- bool session_initialized = session->mSessionInitialized;
- bool callback_enabled = session->mCallBackEnabled;
-
- BOOL enable_connect = session_initialized
- && voice_enabled
- && callback_enabled;
- childSetEnabled("call_btn", enable_connect);
-
- LLPanel::draw();
+ return TRUE;
}
void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id)
@@ -266,6 +280,8 @@ void LLPanelGroupControlPanel::draw()
// Need to resort the participant list if it's in sort by recent speaker order.
if (mParticipantList)
mParticipantList->updateRecentSpeakersOrder();
+ //* TODO: find better way to properly enable call button for group and remove this call from draw()
+ updateCallButton();
LLPanelChatControlPanel::draw();
}
diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h
index 25fdf944c9..3ab505a084 100644
--- a/indra/newview/llpanelimcontrolpanel.h
+++ b/indra/newview/llpanelimcontrolpanel.h
@@ -39,7 +39,9 @@
class LLParticipantList;
-class LLPanelChatControlPanel : public LLPanel
+class LLPanelChatControlPanel
+ : public LLPanel
+ , public LLVoiceClientStatusObserver
{
public:
LLPanelChatControlPanel() :
@@ -47,15 +49,21 @@ public:
~LLPanelChatControlPanel();
virtual BOOL postBuild();
- virtual void draw();
void onCallButtonClicked();
void onEndCallButtonClicked();
void onOpenVoiceControlsClicked();
+ // Implements LLVoiceClientStatusObserver::onChange() to enable the call
+ // button when voice is available
+ /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
virtual void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
void updateButtons(bool is_call_started);
+
+ // Enables/disables call button depending on voice availability
+ void updateCallButton();
virtual void setSessionId(const LLUUID& session_id);
const LLUUID& getSessionId() { return mSessionId; }
diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp
index 9654e17659..c792fd4fe3 100644
--- a/indra/newview/llpanellandmarkinfo.cpp
+++ b/indra/newview/llpanellandmarkinfo.cpp
@@ -98,10 +98,10 @@ void LLPanelLandmarkInfo::resetLocation()
{
LLPanelPlaceInfo::resetLocation();
- std::string not_available = getString("not_available");
- mCreator->setText(not_available);
- mOwner->setText(not_available);
- mCreated->setText(not_available);
+ std::string loading = LLTrans::getString("LoadingData");
+ mCreator->setText(loading);
+ mOwner->setText(loading);
+ mCreated->setText(loading);
mLandmarkTitle->setText(LLStringUtil::null);
mLandmarkTitleEditor->setText(LLStringUtil::null);
mNotesEditor->setText(LLStringUtil::null);
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
index ece93125b3..0f0fb4b94e 100644
--- a/indra/newview/llpanelme.cpp
+++ b/indra/newview/llpanelme.cpp
@@ -198,8 +198,6 @@ void LLPanelMyProfileEdit::processProfileProperties(const LLAvatarData* avatar_d
{
fillCommonData(avatar_data);
- fillOnlineStatus(avatar_data);
-
fillPartnerData(avatar_data);
fillAccountStatus(avatar_data);
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index c14b282488..b01cdcc832 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -462,6 +462,9 @@ LLPanelPeople::~LLPanelPeople()
delete mFriendListUpdater;
delete mRecentListUpdater;
+ if(LLVoiceClient::getInstance())
+ LLVoiceClient::getInstance()->removeObserver(this);
+
LLView::deleteViewByHandle(mGroupPlusMenuHandle);
LLView::deleteViewByHandle(mNearbyViewSortMenuHandle);
LLView::deleteViewByHandle(mFriendsViewSortMenuHandle);
@@ -612,6 +615,8 @@ BOOL LLPanelPeople::postBuild()
if(recent_view_sort)
mRecentViewSortMenuHandle = recent_view_sort->getHandle();
+ gVoiceClient->addObserver(this);
+
// call this method in case some list is empty and buttons can be in inconsistent state
updateButtons();
@@ -621,6 +626,17 @@ BOOL LLPanelPeople::postBuild()
return TRUE;
}
+// virtual
+void LLPanelPeople::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+ {
+ return;
+ }
+
+ updateButtons();
+}
+
void LLPanelPeople::updateFriendList()
{
if (!mOnlineFriendList || !mAllFriendList)
@@ -775,41 +791,20 @@ void LLPanelPeople::updateButtons()
}
}
+ bool enable_calls = gVoiceClient->voiceWorking() && gVoiceClient->voiceEnabled();
+
buttonSetEnabled("teleport_btn", friends_tab_active && item_selected && isFriendOnline(selected_uuids.front()));
buttonSetEnabled("view_profile_btn", item_selected);
buttonSetEnabled("im_btn", multiple_selected); // allow starting the friends conference for multiple selection
- buttonSetEnabled("call_btn", multiple_selected && canCall());
+ buttonSetEnabled("call_btn", multiple_selected && enable_calls);
buttonSetEnabled("share_btn", item_selected); // not implemented yet
bool none_group_selected = item_selected && selected_id.isNull();
buttonSetEnabled("group_info_btn", !none_group_selected);
- buttonSetEnabled("group_call_btn", !none_group_selected);
+ buttonSetEnabled("group_call_btn", !none_group_selected && enable_calls);
buttonSetEnabled("chat_btn", !none_group_selected);
}
-bool LLPanelPeople::canCall()
-{
- std::vector<LLUUID> selected_uuids;
- getCurrentItemIDs(selected_uuids);
-
- bool result = false;
-
- std::vector<LLUUID>::const_iterator
- id = selected_uuids.begin(),
- uuids_end = selected_uuids.end();
-
- for (;id != uuids_end; ++id)
- {
- if (LLAvatarActions::canCall(*id))
- {
- result = true;
- break;
- }
- }
-
- return result;
-}
-
std::string LLPanelPeople::getActiveTabName() const
{
return mTabContainer->getCurrentPanel()->getName();
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 7580fdbeef..6d3d436156 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -36,13 +36,16 @@
#include <llpanel.h>
#include "llcallingcard.h" // for avatar tracker
+#include "llvoiceclient.h"
class LLFilterEditor;
class LLTabContainer;
class LLAvatarList;
class LLGroupList;
-class LLPanelPeople : public LLPanel
+class LLPanelPeople
+ : public LLPanel
+ , public LLVoiceClientStatusObserver
{
LOG_CLASS(LLPanelPeople);
public:
@@ -52,6 +55,9 @@ public:
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ bool notifyChildren(const LLSD& info);
+ // Implements LLVoiceClientStatusObserver::onChange() to enable call buttons
+ // when voice is available
+ /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
// internals
class Updater;
@@ -73,7 +79,6 @@ private:
bool isFriendOnline(const LLUUID& id);
bool isItemsFreeOfFriends(const std::vector<LLUUID>& uuids);
- bool canCall();
void updateButtons();
std::string getActiveTabName() const;
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index c1c10e6022..d9651a6045 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -183,20 +183,7 @@ bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
}
else if (item == std::string("can_call"))
{
- bool result = false;
- std::vector<LLUUID>::const_iterator
- id = mUUIDs.begin(),
- uuids_end = mUUIDs.end();
-
- for (;id != uuids_end; ++id)
- {
- if (LLAvatarActions::canCall(*id))
- {
- result = true;
- break;
- }
- }
- return result;
+ return LLAvatarActions::canCall();
}
return false;
}
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 0c10f11bfc..5f75668722 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -43,6 +43,8 @@
#include "lliconctrl.h"
#include "lltextbox.h"
+#include "lltrans.h"
+
#include "llagent.h"
#include "llexpandabletextbox.h"
#include "llpanelpick.h"
@@ -99,12 +101,12 @@ void LLPanelPlaceInfo::resetLocation()
mRequestedID.setNull();
mPosRegion.clearVec();
- std::string not_available = getString("not_available");
- mMaturityRatingIcon->setValue(not_available);
- mMaturityRatingText->setValue(not_available);
- mRegionName->setText(not_available);
- mParcelName->setText(not_available);
- mDescEditor->setText(not_available);
+ std::string loading = LLTrans::getString("LoadingData");
+ mMaturityRatingIcon->setValue(loading);
+ mMaturityRatingText->setValue(loading);
+ mRegionName->setText(loading);
+ mParcelName->setText(loading);
+ mDescEditor->setText(loading);
mSnapshotCtrl->setImageAssetID(LLUUID::null);
mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c");
@@ -206,6 +208,10 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
{
mDescEditor->setText(parcel_data.desc);
}
+ else
+ {
+ mDescEditor->setText(getString("not_available"));
+ }
S32 region_x;
S32 region_y;
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index d892e2885b..3c798639d4 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -42,6 +42,8 @@
#include "lltextbox.h"
#include "lltexteditor.h"
+#include "lltrans.h"
+
#include "llaccordionctrl.h"
#include "llaccordionctrltab.h"
#include "llagent.h"
@@ -163,45 +165,45 @@ void LLPanelPlaceProfile::resetLocation()
mForSalePanel->setVisible(FALSE);
mYouAreHerePanel->setVisible(FALSE);
- std::string not_available = getString("not_available");
- mParcelOwner->setValue(not_available);
-
- mParcelRatingIcon->setValue(not_available);
- mParcelRatingText->setText(not_available);
- mVoiceIcon->setValue(not_available);
- mVoiceText->setText(not_available);
- mFlyIcon->setValue(not_available);
- mFlyText->setText(not_available);
- mPushIcon->setValue(not_available);
- mPushText->setText(not_available);
- mBuildIcon->setValue(not_available);
- mBuildText->setText(not_available);
- mScriptsIcon->setValue(not_available);
- mScriptsText->setText(not_available);
- mDamageIcon->setValue(not_available);
- mDamageText->setText(not_available);
-
- mRegionNameText->setValue(not_available);
- mRegionTypeText->setValue(not_available);
- mRegionRatingIcon->setValue(not_available);
- mRegionRatingText->setValue(not_available);
- mRegionOwnerText->setValue(not_available);
- mRegionGroupText->setValue(not_available);
-
- mEstateNameText->setValue(not_available);
- mEstateRatingText->setValue(not_available);
- mEstateOwnerText->setValue(not_available);
- mCovenantText->setValue(not_available);
-
- mSalesPriceText->setValue(not_available);
- mAreaText->setValue(not_available);
- mTrafficText->setValue(not_available);
- mPrimitivesText->setValue(not_available);
- mParcelScriptsText->setValue(not_available);
- mTerraformLimitsText->setValue(not_available);
- mSubdivideText->setValue(not_available);
- mResaleText->setValue(not_available);
- mSaleToText->setValue(not_available);
+ std::string loading = LLTrans::getString("LoadingData");
+ mParcelOwner->setValue(loading);
+
+ mParcelRatingIcon->setValue(loading);
+ mParcelRatingText->setText(loading);
+ mVoiceIcon->setValue(loading);
+ mVoiceText->setText(loading);
+ mFlyIcon->setValue(loading);
+ mFlyText->setText(loading);
+ mPushIcon->setValue(loading);
+ mPushText->setText(loading);
+ mBuildIcon->setValue(loading);
+ mBuildText->setText(loading);
+ mScriptsIcon->setValue(loading);
+ mScriptsText->setText(loading);
+ mDamageIcon->setValue(loading);
+ mDamageText->setText(loading);
+
+ mRegionNameText->setValue(loading);
+ mRegionTypeText->setValue(loading);
+ mRegionRatingIcon->setValue(loading);
+ mRegionRatingText->setValue(loading);
+ mRegionOwnerText->setValue(loading);
+ mRegionGroupText->setValue(loading);
+
+ mEstateNameText->setValue(loading);
+ mEstateRatingText->setValue(loading);
+ mEstateOwnerText->setValue(loading);
+ mCovenantText->setValue(loading);
+
+ mSalesPriceText->setValue(loading);
+ mAreaText->setValue(loading);
+ mTrafficText->setValue(loading);
+ mPrimitivesText->setValue(loading);
+ mParcelScriptsText->setValue(loading);
+ mTerraformLimitsText->setValue(loading);
+ mSubdivideText->setValue(loading);
+ mResaleText->setValue(loading);
+ mSaleToText->setValue(loading);
}
// virtual
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index a4f0e55a93..7272a8a652 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -34,7 +34,7 @@
#include "llpanelplaces.h"
#include "llassettype.h"
-#include "llwindow.h"
+#include "lltimer.h"
#include "llinventory.h"
#include "lllandmark.h"
@@ -49,6 +49,8 @@
#include "lltrans.h"
#include "lluictrlfactory.h"
+#include "llwindow.h"
+
#include "llagent.h"
#include "llagentpicksinfo.h"
#include "llavatarpropertiesprocessor.h"
@@ -73,6 +75,7 @@
#include "llviewerwindow.h"
static const S32 LANDMARK_FOLDERS_MENU_WIDTH = 250;
+static const F32 PLACE_INFO_UPDATE_INTERVAL = 3.0;
static const std::string AGENT_INFO_TYPE = "agent";
static const std::string CREATE_LANDMARK_INFO_TYPE = "create_landmark";
static const std::string LANDMARK_INFO_TYPE = "landmark";
@@ -384,6 +387,10 @@ void LLPanelPlaces::onOpen(const LLSD& key)
// Otherwise stop using land selection and deselect land.
if (mPlaceInfoType == AGENT_INFO_TYPE)
{
+ // We don't know if we are already added to LLViewerParcelMgr observers list
+ // so try to remove observer not to add an extra one.
+ parcel_mgr->removeObserver(mParcelObserver);
+
parcel_mgr->addObserver(mParcelObserver);
parcel_mgr->selectParcelAt(gAgent.getPositionGlobal());
}
@@ -826,6 +833,10 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
{
mPlaceProfile->resetLocation();
+ // Do not reset location info until mResetInfoTimer has expired
+ // to avoid text blinking.
+ mResetInfoTimer.setTimerExpirySec(PLACE_INFO_UPDATE_INTERVAL);
+
LLRect rect = getRect();
LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom);
mPlaceProfile->reshape(new_rect.getWidth(), new_rect.getHeight());
@@ -898,6 +909,8 @@ void LLPanelPlaces::changedParcelSelection()
if (!region || !parcel)
return;
+ LLVector3d prev_pos_global = mPosGlobal;
+
// If agent is inside the selected parcel show agent's region<X, Y, Z>,
// otherwise show region<X, Y, Z> of agent's selection point.
bool is_current_parcel = is_agent_in_selected_parcel(parcel);
@@ -914,7 +927,14 @@ void LLPanelPlaces::changedParcelSelection()
}
}
- mPlaceProfile->resetLocation();
+ // Reset location info only if global position has changed
+ // and update timer has expired to reduce unnecessary text and icons updates.
+ if (prev_pos_global != mPosGlobal && mResetInfoTimer.hasExpired())
+ {
+ mPlaceProfile->resetLocation();
+ mResetInfoTimer.setTimerExpirySec(PLACE_INFO_UPDATE_INTERVAL);
+ }
+
mPlaceProfile->displaySelectedParcelInfo(parcel, region, mPosGlobal, is_current_parcel);
updateVerbs();
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 0eba7f3afc..a098974659 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -34,6 +34,8 @@
#include "llpanel.h"
+class LLTimer;
+
class LLInventoryItem;
class LLFilterEditor;
class LLLandmark;
@@ -132,6 +134,10 @@ private:
// be available (hence zero)
LLVector3d mPosGlobal;
+ // Sets a period of time during which the requested place information
+ // is expected to be updated and doesn't need to be reset.
+ LLTimer mResetInfoTimer;
+
// Information type currently shown in Place Information panel
std::string mPlaceInfoType;
diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp
index 7832f63e6a..044036ea50 100644
--- a/indra/newview/llpanelprofileview.cpp
+++ b/indra/newview/llpanelprofileview.cpp
@@ -101,8 +101,6 @@ void LLPanelProfileView::onOpen(const LLSD& key)
id = key["id"];
}
- // subscribe observer to get online status. Request will be sent by LLPanelAvatarProfile itself
- mAvatarStatusObserver->subscribe();
if(id.notNull() && getAvatarId() != id)
{
setAvatarId(id);
@@ -111,12 +109,9 @@ void LLPanelProfileView::onOpen(const LLSD& key)
// Update the avatar name.
gCacheName->get(getAvatarId(), FALSE,
boost::bind(&LLPanelProfileView::onAvatarNameCached, this, _1, _2, _3, _4));
-/*
-// disable this part of code according to EXT-2022. See processOnlineStatus
- // status should only show if viewer has permission to view online/offline. EXT-453
- mStatusText->setVisible(isGrantedToSeeOnlineStatus());
+
updateOnlineStatus();
-*/
+
LLPanelProfile::onOpen(key);
}
@@ -164,27 +159,43 @@ bool LLPanelProfileView::isGrantedToSeeOnlineStatus()
// *NOTE: GRANT_ONLINE_STATUS is always set to false while changing any other status.
// When avatar disallow me to see her online status processOfflineNotification Message is received by the viewer
// see comments for ChangeUserRights template message. EXT-453.
-// return relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS);
- return true;
+ // If GRANT_ONLINE_STATUS flag is changed it will be applied when viewer restarts. EXT-3880
+ return relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS);
}
+// method was disabled according to EXT-2022. Re-enabled & improved according to EXT-3880
void LLPanelProfileView::updateOnlineStatus()
{
+ // set text box visible to show online status for non-friends who has not set in Preferences
+ // "Only Friends & Groups can see when I am online"
+ mStatusText->setVisible(TRUE);
+
const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
if (NULL == relationship)
- return;
+ {
+ // this is non-friend avatar. Status will be updated from LLAvatarPropertiesProcessor.
+ // in LLPanelProfileView::processOnlineStatus()
- bool online = relationship->isOnline();
+ // subscribe observer to get online status. Request will be sent by LLPanelAvatarProfile itself.
+ // do not subscribe for friend avatar because online status can be wrong overridden
+ // via LLAvatarData::flags if Preferences: "Only Friends & Groups can see when I am online" is set.
+ mAvatarStatusObserver->subscribe();
+ return;
+ }
+ // For friend let check if he allowed me to see his status
- std::string status = getString(online ? "status_online" : "status_offline");
+ // status should only show if viewer has permission to view online/offline. EXT-453, EXT-3880
+ mStatusText->setVisible(isGrantedToSeeOnlineStatus());
- mStatusText->setValue(status);
+ bool online = relationship->isOnline();
+ processOnlineStatus(online);
}
void LLPanelProfileView::processOnlineStatus(bool online)
{
- mAvatarIsOnline = online;
- mStatusText->setVisible(online);
+ std::string status = getString(online ? "status_online" : "status_offline");
+
+ mStatusText->setValue(status);
}
void LLPanelProfileView::onAvatarNameCached(const LLUUID& id, const std::string& first_name, const std::string& last_name, BOOL is_group)
@@ -193,17 +204,4 @@ void LLPanelProfileView::onAvatarNameCached(const LLUUID& id, const std::string&
getChild<LLUICtrl>("user_name", FALSE)->setValue(first_name + " " + last_name);
}
-void LLPanelProfileView::togglePanel(LLPanel* panel, const LLSD& key)
-{
- // *TODO: unused method?
-
- LLPanelProfile::togglePanel(panel);
- if(FALSE == panel->getVisible())
- {
- // LLPanelProfile::togglePanel shows/hides all children,
- // we don't want to display online status for non friends, so re-hide it here
- mStatusText->setVisible(mAvatarIsOnline);
- }
-}
-
// EOF
diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h
index 5dc617d4a0..9b87e146a8 100644
--- a/indra/newview/llpanelprofileview.h
+++ b/indra/newview/llpanelprofileview.h
@@ -64,8 +64,6 @@ public:
/*virtual*/ BOOL postBuild();
- /*virtual*/ void togglePanel(LLPanel* panel, const LLSD& key = LLSD());
-
BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop, EDragAndDropType cargo_type,
void *cargo_data, EAcceptance *accept,
@@ -81,8 +79,21 @@ public:
protected:
void onBackBtnClick();
- bool isGrantedToSeeOnlineStatus(); // deprecated after EXT-2022 is implemented
- void updateOnlineStatus(); // deprecated after EXT-2022 is implemented
+ bool isGrantedToSeeOnlineStatus();
+
+ /**
+ * Displays avatar's online status if possible.
+ *
+ * Requirements from EXT-3880:
+ * For friends:
+ * - Online when online and privacy settings allow to show
+ * - Offline when offline and privacy settings allow to show
+ * - Else: nothing
+ * For other avatars:
+ * - Online when online and was not set in Preferences/"Only Friends & Groups can see when I am online"
+ * - Else: Offline
+ */
+ void updateOnlineStatus();
void processOnlineStatus(bool online);
private:
@@ -96,7 +107,6 @@ private:
LLTextBox* mStatusText;
AvatarStatusObserver* mAvatarStatusObserver;
- bool mAvatarIsOnline;
};
#endif //LL_LLPANELPROFILEVIEW_H
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 88b706fb6b..d54cbfe203 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -433,6 +433,12 @@ LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu()
LLContextMenu* main_menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
"menu_participant_list.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
+ // AD *TODO: This is workaround for EXT-4725- way to properly enable/disable "Call" menu item in
+ // enableContextMenuItem() should be found.
+ bool not_agent = mUUIDs.front() != gAgentID;
+ bool can_call = not_agent && LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking();
+ main_menu->setItemEnabled("Call", can_call);
+
// Don't show sort options for P2P chat
bool is_sort_visible = (mParent.mAvatarList && mParent.mAvatarList->size() > 1);
main_menu->setItemVisible("SortByName", is_sort_visible);
@@ -628,7 +634,9 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD&
}
else if (item == "can_call")
{
- return LLVoiceClient::voiceEnabled();
+ bool not_agent = mUUIDs.front() != gAgentID;
+ bool can_call = not_agent && LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking();
+ return can_call;
}
return true;
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 9608cd1263..6f9a1ccdbe 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -70,8 +70,6 @@ LLSpeaker::LLSpeaker(const LLUUID& id, const std::string& name, const ESpeakerTy
{
mDisplayName = name;
}
-
- gVoiceClient->setUserVolume(id, LLMuteList::getInstance()->getSavedResidentVolume(id));
}
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index a08e77e3d8..c79a66892d 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -68,7 +68,6 @@
#include "llviewermedia.h"
#include "llvoavatarself.h"
#include "llviewermediafocus.h"
-#include "llvovolume.h"
#include "llworld.h"
#include "llui.h"
#include "llweb.h"
@@ -630,14 +629,12 @@ static bool needs_tooltip(LLSelectNode* nodep)
return false;
LLViewerObject* object = nodep->getObject();
- LLVOVolume* vovolume = dynamic_cast<LLVOVolume*>(object);
LLViewerObject *parent = (LLViewerObject *)object->getParent();
if (object->flagHandleTouch()
|| (parent && parent->flagHandleTouch())
|| object->flagTakesMoney()
|| (parent && parent->flagTakesMoney())
|| object->flagAllowInventoryAdd()
- || (vovolume && vovolume->hasMedia())
)
{
return true;
diff --git a/indra/newview/lltransientdockablefloater.cpp b/indra/newview/lltransientdockablefloater.cpp
index c9bfe178ce..9d39aa5182 100644
--- a/indra/newview/lltransientdockablefloater.cpp
+++ b/indra/newview/lltransientdockablefloater.cpp
@@ -48,6 +48,14 @@ LLTransientDockableFloater::LLTransientDockableFloater(LLDockControl* dockContro
LLTransientDockableFloater::~LLTransientDockableFloater()
{
LLTransientFloaterMgr::getInstance()->unregisterTransientFloater(this);
+ LLView* dock = getDockWidget();
+ LLTransientFloaterMgr::getInstance()->removeControlView(
+ LLTransientFloaterMgr::DOCKED, this);
+ if (dock != NULL)
+ {
+ LLTransientFloaterMgr::getInstance()->removeControlView(
+ LLTransientFloaterMgr::DOCKED, dock);
+ }
}
void LLTransientDockableFloater::setVisible(BOOL visible)
@@ -55,18 +63,18 @@ void LLTransientDockableFloater::setVisible(BOOL visible)
LLView* dock = getDockWidget();
if(visible && isDocked())
{
- LLTransientFloaterMgr::getInstance()->addControlView(this);
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, this);
if (dock != NULL)
{
- LLTransientFloaterMgr::getInstance()->addControlView(dock);
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, dock);
}
}
else
{
- LLTransientFloaterMgr::getInstance()->removeControlView(this);
+ LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, this);
if (dock != NULL)
{
- LLTransientFloaterMgr::getInstance()->removeControlView(dock);
+ LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, dock);
}
}
@@ -78,18 +86,18 @@ void LLTransientDockableFloater::setDocked(bool docked, bool pop_on_undock)
LLView* dock = getDockWidget();
if(docked)
{
- LLTransientFloaterMgr::getInstance()->addControlView(this);
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, this);
if (dock != NULL)
{
- LLTransientFloaterMgr::getInstance()->addControlView(dock);
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, dock);
}
}
else
{
- LLTransientFloaterMgr::getInstance()->removeControlView(this);
+ LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, this);
if (dock != NULL)
{
- LLTransientFloaterMgr::getInstance()->removeControlView(dock);
+ LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, dock);
}
}
diff --git a/indra/newview/lltransientfloatermgr.cpp b/indra/newview/lltransientfloatermgr.cpp
index 8f1a738453..d82403070b 100644
--- a/indra/newview/lltransientfloatermgr.cpp
+++ b/indra/newview/lltransientfloatermgr.cpp
@@ -46,6 +46,7 @@ LLTransientFloaterMgr::LLTransientFloaterMgr()
&LLTransientFloaterMgr::leftMouseClickCallback, this, _1, _2, _3));
mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(GLOBAL, std::set<LLView*>()));
+ mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(DOCKED, std::set<LLView*>()));
mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(IM, std::set<LLView*>()));
}
@@ -132,7 +133,8 @@ void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y,
return;
}
- bool hide = isControlClicked(mGroupControls.find(GLOBAL)->second, x, y);
+ bool hide = isControlClicked(mGroupControls.find(DOCKED)->second, x, y)
+ && isControlClicked(mGroupControls.find(GLOBAL)->second, x, y);
if (hide)
{
hideTransientFloaters(x, y);
diff --git a/indra/newview/lltransientfloatermgr.h b/indra/newview/lltransientfloatermgr.h
index 1f99325a7f..9c5ae295f2 100644
--- a/indra/newview/lltransientfloatermgr.h
+++ b/indra/newview/lltransientfloatermgr.h
@@ -51,7 +51,7 @@ protected:
public:
enum ETransientGroup
{
- GLOBAL, IM
+ GLOBAL, DOCKED, IM
};
void registerTransientFloater(LLTransientFloater* floater);
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index f650bdbbd1..2d9e2ef7c9 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -208,6 +208,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);
LLFloaterReg::add("outgoing_call", "floater_outgoing_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLOutgoingCallDialog>);
+ LLFloaterReg::add("call_info", "floater_call_info.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallInfoDialog>);
LLFloaterReg::add("parcel_info", "floater_preview_url.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterParcelInfo>);
LLFloaterPayUtil::registerFloater();
diff --git a/indra/newview/llviewerhelp.cpp b/indra/newview/llviewerhelp.cpp
index 5af79b4fd3..b82538dacb 100644
--- a/indra/newview/llviewerhelp.cpp
+++ b/indra/newview/llviewerhelp.cpp
@@ -33,6 +33,7 @@
#include "llviewerprecompiledheaders.h"
+#include "llcommandhandler.h"
#include "llfloaterhelpbrowser.h"
#include "llfloaterreg.h"
#include "llfocusmgr.h"
@@ -43,6 +44,33 @@
#include "llviewerhelputil.h"
#include "llviewerhelp.h"
+// support for secondlife:///app/help/{TOPIC} SLapps
+class LLHelpHandler : public LLCommandHandler
+{
+public:
+ // requests will be throttled from a non-trusted browser
+ LLHelpHandler() : LLCommandHandler("help", UNTRUSTED_THROTTLE) {}
+
+ bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
+ {
+ LLViewerHelp* vhelp = LLViewerHelp::getInstance();
+ if (! vhelp)
+ {
+ return false;
+ }
+
+ // get the requested help topic name, or use the fallback if none
+ std::string help_topic = vhelp->defaultTopic();
+ if (params.size() >= 1)
+ {
+ help_topic = params[0].asString();
+ }
+
+ vhelp->showTopic(help_topic);
+ return true;
+ }
+};
+LLHelpHandler gHelpHandler;
//////////////////////////////
// implement LLHelp interface
@@ -65,18 +93,16 @@ void LLViewerHelp::showTopic(const std::string &topic)
help_topic = defaultTopic();
}
- // f1 help topic means: if user not logged in yet, show the
- // pre-login topic, otherwise show help for the focused item
+ // f1 help topic means: if the user is not logged in yet, show
+ // the pre-login topic instead of the default fallback topic,
+ // otherwise show help for the focused item
if (help_topic == f1HelpTopic())
{
- if (! LLLoginInstance::getInstance()->authSuccess())
+ help_topic = getTopicFromFocus();
+ if (help_topic == defaultTopic() && ! LLLoginInstance::getInstance()->authSuccess())
{
help_topic = preLoginTopic();
}
- else
- {
- help_topic = getTopicFromFocus();
- }
}
// work out the URL for this topic and display it
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 917b8747ea..7f3f019b07 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -58,7 +58,6 @@ public:
protected:
~LLViewerInventoryItem( void ); // ref counted
BOOL extractSortFieldAndDisplayName(S32* sortField, std::string* displayName) const { return extractSortFieldAndDisplayName(mName, sortField, displayName); }
- static char getSeparator() { return '@'; }
mutable std::string mDisplayName;
public:
@@ -67,6 +66,7 @@ public:
virtual const std::string& getName() const;
virtual const std::string& getDisplayName() const;
static std::string getDisplayName(const std::string& name);
+ static char getSeparator() { return '@'; }
virtual S32 getSortField() const;
virtual void setSortField(S32 sortField);
virtual void rename(const std::string& new_name);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index d712446d83..98d8780b34 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -940,7 +940,6 @@ bool LLViewerMedia::firstRunCallback(const LLSD& notification, const LLSD& respo
{
// user has elected to automatically play media.
gSavedSettings.setBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING, TRUE);
- gSavedSettings.setBOOL("AudioStreamingVideo", TRUE);
gSavedSettings.setBOOL("AudioStreamingMusic", TRUE);
gSavedSettings.setBOOL("AudioStreamingMedia", TRUE);
@@ -961,7 +960,6 @@ bool LLViewerMedia::firstRunCallback(const LLSD& notification, const LLSD& respo
{
gSavedSettings.setBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING, FALSE);
gSavedSettings.setBOOL("AudioStreamingMedia", FALSE);
- gSavedSettings.setBOOL("AudioStreamingVideo", FALSE);
gSavedSettings.setBOOL("AudioStreamingMusic", FALSE);
}
return false;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 79aae9463b..0801e53fbf 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -6389,10 +6389,9 @@ void handle_selected_texture_info(void*)
msg.assign("Texture info for: ");
msg.append(node->mName);
- //TODO* CHAT: how to show this?
- //LLSD args;
- //args["MESSAGE"] = msg;
- //LLNotificationsUtil::add("SystemMessage", args);
+ LLSD args;
+ args["MESSAGE"] = msg;
+ LLNotificationsUtil::add("SystemMessage", args);
U8 te_count = node->getObject()->getNumTEs();
// map from texture ID to list of faces using it
@@ -6425,10 +6424,9 @@ void handle_selected_texture_info(void*)
msg.append( llformat("%d ", (S32)(it->second[i])));
}
- //TODO* CHAT: how to show this?
- //LLSD args;
- //args["MESSAGE"] = msg;
- //LLNotificationsUtil::add("SystemMessage", args);
+ LLSD args;
+ args["MESSAGE"] = msg;
+ LLNotificationsUtil::add("SystemMessage", args);
}
}
}
@@ -7959,6 +7957,7 @@ void initialize_menus()
commit.add("Avatar.Eject", boost::bind(&handle_avatar_eject, LLSD()));
view_listener_t::addMenu(new LLAvatarSendIM(), "Avatar.SendIM");
view_listener_t::addMenu(new LLAvatarCall(), "Avatar.Call");
+ enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall));
view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse");
view_listener_t::addMenu(new LLAvatarEnableAddFriend(), "Avatar.EnableAddFriend");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index c463beb375..79c887844a 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1365,10 +1365,9 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
if (check_offer_throttle(mFromName, true))
{
log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString(".");
- //TODO* CHAT: how to show this?
- //LLSD args;
- //args["MESSAGE"] = log_message;
- //LLNotificationsUtil::add("SystemMessage", args);
+ LLSD args;
+ args["MESSAGE"] = log_message;
+ LLNotificationsUtil::add("SystemMessage", args);
}
// we will want to open this item when it comes back.
@@ -1410,11 +1409,10 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
// send the message
msg->sendReliable(mHost);
- //TODO* CHAT: how to show this?
- //log_message = LLTrans::getString("InvOfferYouDecline") + " " + mDesc + " " + LLTrans::getString("InvOfferFrom") + " " + mFromName +".";
- //LLSD args;
- //args["MESSAGE"] = log_message;
- //LLNotificationsUtil::add("SystemMessage", args);
+ log_message = LLTrans::getString("InvOfferYouDecline") + " " + mDesc + " " + LLTrans::getString("InvOfferFrom") + " " + mFromName +".";
+ LLSD args;
+ args["MESSAGE"] = log_message;
+ LLNotificationsUtil::add("SystemMessage", args);
if (busy && (!mFromGroup && !mFromObject))
{
@@ -1436,6 +1434,31 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
return false;
}
+std::string get_display_name(const std::string& name)
+{
+ // We receive landmark name as \'<n>@name\' where <n> is a number
+ // LLViewerInventoryItem::getDisplayName will remove \'<n>@ though we need the \'
+ // Lets save all chars preceding @ and insert them back after <n>@ was removed
+
+ std::string saved;
+
+ if(std::string::npos != name.find(LLViewerInventoryItem::getSeparator()))
+ {
+ int n = 0;
+ while(!isdigit(name[n]) && LLViewerInventoryItem::getSeparator() != name[n])
+ {
+ ++n;
+ }
+ saved = name.substr(0, n);
+ }
+
+ std::string d_name = LLViewerInventoryItem::getDisplayName(name);
+ d_name.insert(0, saved);
+ LLStringUtil::trim(d_name);
+
+ return d_name;
+}
+
void inventory_offer_handler(LLOfferInfo* info)
{
//Until throttling is implmented, busy mode should reject inventory instead of silently
@@ -1475,7 +1498,7 @@ void inventory_offer_handler(LLOfferInfo* info)
if(LLAssetType::AT_LANDMARK == info->mType)
{
- msg = LLViewerInventoryItem::getDisplayName(msg);
+ msg = get_display_name(msg);
}
LLSD args;
@@ -1843,11 +1866,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// history. Pretend the chat is from a local agent,
// so it will go into the history but not be shown on screen.
- //TODO* CHAT: how to show this?
- //and this is not system message...
- //LLSD args;
- //args["MESSAGE"] = buffer;
- //LLNotificationsUtil::add("SystemMessage", args);
+ LLSD args;
+ args["MESSAGE"] = buffer;
+ LLNotificationsUtil::add("SystemMessageTip", args);
}
}
break;
@@ -3078,10 +3099,9 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
{
// Chat the "back" SLURL. (DEV-4907)
- //TODO* CHAT: how to show this?
- //LLSD args;
- //args["MESSAGE"] = message;
- //LLNotificationsUtil::add("SystemMessage", args);
+ LLSD args;
+ args["MESSAGE"] = "Teleport completed from " + gAgent.getTeleportSourceSLURL();
+ LLNotificationsUtil::add("SystemMessageTip", args);
// Set the new position
avatarp->setPositionAgent(agent_pos);
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index e87dbe5c07..c4fc2e5cab 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -179,7 +179,7 @@ void LLViewerParcelMedia::play(LLParcel* parcel)
if (!parcel) return;
- if (!gSavedSettings.getBOOL("AudioStreamingMedia") || !gSavedSettings.getBOOL("AudioStreamingVideo"))
+ if (!gSavedSettings.getBOOL("AudioStreamingMedia"))
return;
std::string media_url = parcel->getMediaURL();
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 73dc9745cb..7e6a4c00c6 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -2777,7 +2777,6 @@ void LLViewerMediaTexture::updateClass()
#if 0
//force to play media.
gSavedSettings.setBOOL("AudioStreamingMedia", true) ;
- gSavedSettings.setBOOL("AudioStreamingVideo", true) ;
#endif
for(media_map_t::iterator iter = sMediaMap.begin() ; iter != sMediaMap.end(); )
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index 917d69fe16..589999c026 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -389,13 +389,13 @@ void LLVoiceChannel::setState(EState state)
switch(state)
{
case STATE_RINGING:
- gIMMgr->addSystemMessage(mSessionID, "ringing", mNotifyArgs);
+ LLCallInfoDialog::show("ringing", mNotifyArgs);
break;
case STATE_CONNECTED:
- gIMMgr->addSystemMessage(mSessionID, "connected", mNotifyArgs);
+ LLCallInfoDialog::show("connected", mNotifyArgs);
break;
case STATE_HUNG_UP:
- gIMMgr->addSystemMessage(mSessionID, "hang_up", mNotifyArgs);
+ LLCallInfoDialog::show("hang_up", mNotifyArgs);
break;
default:
break;
@@ -635,7 +635,7 @@ void LLVoiceChannelGroup::setState(EState state)
case STATE_RINGING:
if ( !mIsRetrying )
{
- gIMMgr->addSystemMessage(mSessionID, "ringing", mNotifyArgs);
+ LLCallInfoDialog::show("ringing", mNotifyArgs);
}
doSetState(state);
@@ -698,7 +698,7 @@ void LLVoiceChannelProximal::handleStatusChange(EStatusType status)
// do not notify user when leaving proximal channel
return;
case STATUS_VOICE_DISABLED:
- gIMMgr->addSystemMessage(LLUUID::null, "unavailable", mNotifyArgs);
+ LLCallInfoDialog::show("unavailable", mNotifyArgs);
return;
default:
break;
@@ -897,7 +897,7 @@ void LLVoiceChannelP2P::setState(EState state)
// so provide a special purpose message here
if (mReceivedCall && state == STATE_RINGING)
{
- gIMMgr->addSystemMessage(mSessionID, "answering", mNotifyArgs);
+ LLCallInfoDialog::show("answering", mNotifyArgs);
doSetState(state);
return;
}
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index c84afa5af1..8ca0fd6ef6 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -37,8 +37,10 @@
// library includes
#include "llnotificationsutil.h"
+#include "llsdserialize.h"
#include "llsdutil.h"
+
// project includes
#include "llvoavatar.h"
#include "llbufferstream.h"
@@ -1092,6 +1094,119 @@ static void killGateway()
#endif
+class LLSpeakerVolumeStorage : public LLSingleton<LLSpeakerVolumeStorage>
+{
+ LOG_CLASS(LLSpeakerVolumeStorage);
+public:
+
+ /**
+ * Sets internal voluem level for specified user.
+ *
+ * @param[in] speaker_id - LLUUID of user to store volume level for
+ * @param[in] volume - internal volume level to be stored for user.
+ */
+ void storeSpeakerVolume(const LLUUID& speaker_id, S32 volume);
+
+ /**
+ * Gets stored internal volume level for specified speaker.
+ *
+ * If specified user is not found default level will be returned. It is equivalent of
+ * external level 0.5 from the 0.0..1.0 range.
+ * Default internal level is calculated as: internal = 400 * external^2
+ * Maps 0.0 to 1.0 to internal values 0-400 with default 0.5 == 100
+ *
+ * @param[in] speaker_id - LLUUID of user to get his volume level
+ */
+ S32 getSpeakerVolume(const LLUUID& speaker_id);
+
+private:
+ friend class LLSingleton<LLSpeakerVolumeStorage>;
+ LLSpeakerVolumeStorage();
+ ~LLSpeakerVolumeStorage();
+
+ const static std::string SETTINGS_FILE_NAME;
+
+ void load();
+ void save();
+
+ typedef std::map<LLUUID, S32> speaker_data_map_t;
+ speaker_data_map_t mSpeakersData;
+};
+
+const std::string LLSpeakerVolumeStorage::SETTINGS_FILE_NAME = "volume_settings.xml";
+
+LLSpeakerVolumeStorage::LLSpeakerVolumeStorage()
+{
+ load();
+}
+
+LLSpeakerVolumeStorage::~LLSpeakerVolumeStorage()
+{
+ save();
+}
+
+void LLSpeakerVolumeStorage::storeSpeakerVolume(const LLUUID& speaker_id, S32 volume)
+{
+ mSpeakersData[speaker_id] = volume;
+}
+
+S32 LLSpeakerVolumeStorage::getSpeakerVolume(const LLUUID& speaker_id)
+{
+ // default internal level of user voice.
+ const static LLUICachedControl<S32> DEFAULT_INTERNAL_VOLUME_LEVEL("VoiceDefaultInternalLevel", 100);
+ S32 ret_val = DEFAULT_INTERNAL_VOLUME_LEVEL;
+ speaker_data_map_t::const_iterator it = mSpeakersData.find(speaker_id);
+
+ if (it != mSpeakersData.end())
+ {
+ ret_val = it->second;
+ }
+ return ret_val;
+}
+
+void LLSpeakerVolumeStorage::load()
+{
+ // load per-resident voice volume information
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SETTINGS_FILE_NAME);
+
+ LLSD settings_llsd;
+ llifstream file;
+ file.open(filename);
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXML(settings_llsd, file);
+ }
+
+ for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
+ iter != settings_llsd.endMap(); ++iter)
+ {
+ mSpeakersData.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
+ }
+}
+
+void LLSpeakerVolumeStorage::save()
+{
+ // If we quit from the login screen we will not have an SL account
+ // name. Don't try to save, otherwise we'll dump a file in
+ // C:\Program Files\SecondLife\ or similar. JC
+ std::string user_dir = gDirUtilp->getLindenUserDir();
+ if (!user_dir.empty())
+ {
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SETTINGS_FILE_NAME);
+ LLSD settings_llsd;
+
+ for(speaker_data_map_t::const_iterator iter = mSpeakersData.begin(); iter != mSpeakersData.end(); ++iter)
+ {
+ settings_llsd[iter->first.asString()] = iter->second;
+ }
+
+ llofstream file;
+ file.open(filename);
+ LLSDSerialize::toPrettyXML(settings_llsd, file);
+ }
+}
+
+
///////////////////////////////////////////////////////////////////////////////////////////////
LLVoiceClient::LLVoiceClient() :
@@ -4914,7 +5029,9 @@ LLVoiceClient::participantState *LLVoiceClient::sessionState::addParticipant(con
}
mParticipantsByUUID.insert(participantUUIDMap::value_type(&(result->mAvatarID), result));
-
+
+ result->mUserVolume = LLSpeakerVolumeStorage::getInstance()->getSpeakerVolume(result->mAvatarID);
+
LL_DEBUGS("Voice") << "participant \"" << result->mURI << "\" added." << LL_ENDL;
}
@@ -5853,6 +5970,11 @@ bool LLVoiceClient::voiceEnabled()
return gSavedSettings.getBOOL("EnableVoiceChat") && !gSavedSettings.getBOOL("CmdLineDisableVoice");
}
+bool LLVoiceClient::voiceWorking()
+{
+ return (stateLoggedIn <= mState) && (mState <= stateLeavingSession);
+}
+
void LLVoiceClient::setLipSyncEnabled(BOOL enabled)
{
mLipSyncEnabled = enabled;
@@ -6158,6 +6280,9 @@ void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume)
participant->mUserVolume = llclamp(ivol, 0, 400);
participant->mVolumeDirty = TRUE;
mAudioSession->mVolumeDirty = TRUE;
+
+ // store this volume setting for future sessions
+ LLSpeakerVolumeStorage::getInstance()->storeSpeakerVolume(id, participant->mUserVolume);
}
}
}
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index 6231c6ba29..8f668dff19 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -191,6 +191,8 @@ static void updatePosition(void);
void inputUserControlState(bool down); // interpret any sort of up-down mic-open control input according to ptt-toggle prefs
void setVoiceEnabled(bool enabled);
static bool voiceEnabled();
+ // Checks is voice working judging from mState
+ bool voiceWorking();
void setUsePTT(bool usePTT);
void setPTTIsToggle(bool PTTIsToggle);
bool getPTTIsToggle();
diff --git a/indra/newview/skins/default/xui/en/floater_aaa.xml b/indra/newview/skins/default/xui/en/floater_aaa.xml
index 0b48ba9321..b4d2dabc5c 100644
--- a/indra/newview/skins/default/xui/en/floater_aaa.xml
+++ b/indra/newview/skins/default/xui/en/floater_aaa.xml
@@ -18,7 +18,8 @@
single_instance="true"
width="320">
<string name="nudge_parabuild">Nudge 1</string>
- <string name="test_the_vlt">This string CHANGE is extracted.</string>
+ <string name="test_the_vlt">This string CHANGE2 is extracted.</string>
+ <string name="testing_eli">Just a test. change here. more change.</string>
<chat_history
allow_html="true"
bg_readonly_color="ChatHistoryBgColor"
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 613530b7aa..d2e5473157 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -11,7 +11,7 @@
can_dock="false"
can_minimize="true"
can_close="true"
- visible="true"
+ visible="false"
width="360"
can_resize="true"
min_width="250"
diff --git a/indra/newview/skins/default/xui/en/floater_search.xml b/indra/newview/skins/default/xui/en/floater_search.xml
index b0bb282abd..775e7d66f7 100644
--- a/indra/newview/skins/default/xui/en/floater_search.xml
+++ b/indra/newview/skins/default/xui/en/floater_search.xml
@@ -2,9 +2,9 @@
<floater
legacy_header_height="13"
can_resize="true"
- height="646"
+ height="546"
layout="topleft"
- min_height="646"
+ min_height="546"
min_width="670"
name="floater_search"
help_topic="floater_search"
@@ -21,7 +21,7 @@
Done
</floater.string>
<layout_stack
- bottom="641"
+ bottom="541"
follows="left|right|top|bottom"
layout="topleft"
left="10"
@@ -42,7 +42,7 @@
left="0"
name="browser"
top="0"
- height="600"
+ height="500"
width="650" />
<text
follows="bottom|left"
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 f473a51ff6..c4411db8c5 100644
--- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
@@ -56,7 +56,7 @@
height="18"
default_icon_name="Generic_Person"
layout="topleft"
- left="0"
+ left="5"
name="user_icon"
top="0"
width="18" />
@@ -78,6 +78,7 @@
follows="top|right"
height="16"
layout="topleft"
+ right="-3"
name="speaking_indicator"
left_pad="5"
visible="true"
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
index 5b94645b60..c5b31c7f63 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
@@ -30,6 +30,8 @@
name="Call">
<menu_item_call.on_click
function="Avatar.Call" />
+ <menu_item_call.on_enable
+ function="Avatar.EnableCall" />
</menu_item_call>
<menu_item_call
label="Invite to Group"
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
index 0ad41546d2..ac9101cfd9 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
@@ -30,6 +30,8 @@
name="Call">
<menu_item_call.on_click
function="Avatar.Call" />
+ <menu_item_call.on_enable
+ function="Avatar.EnableCall" />
</menu_item_call>
<menu_item_call
label="Invite to Group"
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
index dde92f23b6..85ec174829 100644
--- a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
@@ -32,6 +32,8 @@
name="call">
<menu_item_call.on_click
function="InspectAvatar.Call"/>
+ <menu_item_call.on_enable
+ function="InspectAvatar.Gear.EnableCall"/>
</menu_item_call>
<menu_item_call
label="Teleport"
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index a0dec346a4..5f38522758 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -10,6 +10,7 @@
<menu
create_jump_keys="true"
label="Me"
+ tear_off="true"
name="File">
<menu_item_call
label="Preferences"
@@ -39,6 +40,7 @@
<menu
create_jump_keys="true"
label="Help"
+ tear_off="true"
name="Help">
<menu_item_call
label="[SECOND_LIFE] Help"
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 805ffbae66..04e02d0f6c 100644
--- a/indra/newview/skins/default/xui/en/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/en/menu_participant_list.xml
@@ -57,9 +57,6 @@
name="Call">
<menu_item_call.on_click
function="Avatar.Call" />
- <menu_item_call.on_enable
- function="ParticipantList.EnableItem"
- parameter="can_call" />
</menu_item_call>
<menu_item_call
enabled="true"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 4279097f62..0fe4e19bf1 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -244,6 +244,16 @@ Save all changes to clothing/body parts?
<notification
icon="alertmodal.tga"
+ name="FriendsAndGroupsOnly"
+ type="alertmodal">
+ Non-friends won't know that you've choosen to ignore their calls and instant messages.
+ <usetemplate
+ name="okbutton"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="GrantModifyRights"
type="alertmodal">
Granting modify rights to another Resident allows them to change, delete or take ANY objects you may have in-world. Be VERY careful when handing out this permission.
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index 615ade99a2..c605975c8e 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -65,28 +65,18 @@
height="15"
layout="topleft"
left_pad="5"
+ right="-72"
name="last_interaction"
text_color="LtGray_50"
value="0s"
width="24" />
- <output_monitor
- auto_update="true"
- follows="right"
- draw_border="false"
- height="16"
- layout="topleft"
- left_pad="5"
- mouse_opaque="true"
- name="speaking_indicator"
- visible="true"
- width="20" />
<button
follows="right"
height="16"
image_pressed="Info_Press"
image_unselected="Info_Over"
left_pad="3"
- right="-31"
+ right="-53"
name="info_btn"
top_delta="-2"
width="16" />
@@ -96,9 +86,21 @@
image_overlay="ForwardArrow_Off"
layout="topleft"
left_pad="5"
- right="-3"
+ right="-28"
name="profile_btn"
tool_tip="View profile"
top_delta="-2"
width="20" />
+ <output_monitor
+ auto_update="true"
+ follows="right"
+ draw_border="false"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ right="-3"
+ mouse_opaque="true"
+ name="speaking_indicator"
+ visible="true"
+ width="20" />
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
index 2075d7e05b..db156f7877 100644
--- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
@@ -2,7 +2,7 @@
<panel
border="false"
follows="all"
- height="380"
+ height="420"
label="Land &amp; L$"
layout="topleft"
left="0"
@@ -237,7 +237,7 @@
</text>
<tab_container
follows="all"
- height="173"
+ height="180"
halign="center"
layout="topleft"
left="0"
@@ -250,7 +250,7 @@
<panel
border="false"
follows="all"
- height="173"
+ height="180"
label="PLANNING"
layout="topleft"
left="0"
@@ -275,7 +275,7 @@
<panel
border="false"
follows="all"
- height="173"
+ height="180"
label="DETAILS"
layout="topleft"
left="0"
@@ -296,41 +296,44 @@
word_wrap="true">
Loading...
</text_editor>
+
+ <button
+ height="20"
+ image_overlay="Arrow_Left_Off"
+ layout="topleft"
+ left="5"
+ name="earlier_details_button"
+ tool_tip="Go back in time"
+ top_pad="10"
+ width="25" />
<button
- follows="left|top"
- height="18"
- image_overlay="Arrow_Left_Off"
- layout="topleft"
- name="earlier_details_button"
- tool_tip="Back"
- right="-45"
- bottom="0"
- width="25" />
- <button
- follows="left|top"
- height="18"
- image_overlay="Arrow_Right_Off"
- layout="topleft"
- left_pad="10"
- name="later_details_button"
- tool_tip="Next"
- width="25" />
- </panel>
+ height="20"
+ image_overlay="Arrow_Right_Off"
+ layout="topleft"
+ left_pad="5"
+ name="later_details_button"
+ tool_tip="Go forward in time"
+ top_delta="0"
+ width="25" />
+
+
+ </panel>
<panel
border="false"
follows="all"
- height="173"
+ height="180"
label="SALES"
layout="topleft"
left_delta="0"
help_topic="group_money_sales_tab"
+ mouse_opaque="false"
name="group_money_sales_tab"
top="0"
width="300">
<text_editor
type="string"
follows="all"
- height="140"
+ height="130"
layout="topleft"
left="0"
max_length="4096"
@@ -340,25 +343,24 @@
word_wrap="true">
Loading...
</text_editor>
- <button
- bottom="0"
- follows="left|top"
- height="18"
- image_overlay="Arrow_Left_Off"
- layout="topleft"
- name="earlier_sales_button"
- tool_tip="Back"
- right="-45"
- width="25" />
- <button
- follows="left|top"
- height="18"
- image_overlay="Arrow_Right_Off"
- layout="topleft"
- left_pad="10"
- name="later_sales_button"
- tool_tip="Next"
- width="25" />
+ <button
+ height="20"
+ image_overlay="Arrow_Left_Off"
+ layout="topleft"
+ left="5"
+ name="earlier_sales_button"
+ tool_tip="Go back in time"
+ top_pad="10"
+ width="25" />
+ <button
+ height="20"
+ image_overlay="Arrow_Right_Off"
+ layout="topleft"
+ left_pad="5"
+ name="later_sales_button"
+ tool_tip="Go forward in time"
+ top_delta="0"
+ width="25" />
</panel>
</tab_container>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
index a8e24366f2..0aaeb6114e 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
@@ -78,19 +78,19 @@
top_pad="10"
width="350" />
<check_box
- control_name="MediaEnabled"
+ name="media_enabled"
+ control_name="AudioStreamingMedia"
height="16"
label="Media Enabled"
layout="topleft"
left="30"
- name="media_enabled"
top_pad="10"
width="350">
<check_box.commit_callback
function="Pref.MediaEnabled" />
</check_box>
<check_box
- enabled_control="MediaEnabled"
+ enabled_control="AudioStreamingMedia"
control_name="ParcelMediaAutoPlayEnable"
height="16"
label="Allow Media to auto-play"
@@ -102,7 +102,19 @@
<check_box.commit_callback
function="Pref.ParcelMediaAutoPlayEnable" />
</check_box>
- <text
+ <check_box
+ control_name="AudioStreamingMusic"
+ height="16"
+ label="Music Enabled"
+ layout="topleft"
+ left="30"
+ name="music_enabled"
+ top_pad="10"
+ width="350">
+ <check_box.commit_callback
+ function="Pref.MusicEnabled" />
+ </check_box>
+ <text
type="string"
length="1"
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
index 17ababe854..8723e0a832 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -279,7 +279,7 @@
width="480" />
<radio_item
height="20"
- label="Use my browser (IE, Firefox)"
+ label="Use my browser (IE, Firefox, Safari)"
layout="topleft"
left_delta="0"
name="external"
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml
index 4f40e00815..c5f3fcc27d 100644
--- a/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml
@@ -41,6 +41,7 @@
height="20"
layout="topleft"
left_pad="5"
+ allow_html="false"
use_ellipses="true"
name="region"
text_color="white"
diff --git a/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml b/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml
index ad3872587c..0552cd3108 100644
--- a/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml
@@ -33,7 +33,7 @@
<button label="√ Tout" label_selected="Tout" name="check_all"/>
<button label="Effacer" label_selected="Aucun" name="check_none"/>
<text name="newperms">
- Nouvelles permissions relatives au contenu
+ Nouvelles permissions
</text>
<text name="GroupLabel">
Groupe :
diff --git a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
index 5d3a2e6312..4ca251f3d9 100644
--- a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
@@ -28,7 +28,7 @@
1234
</line_editor>
<text name="buying_label">
- Pour le prix
+ Pour
</text>
<text left_delta="68" name="currency_est" width="138">
environ [LOCALAMOUNT]
@@ -57,7 +57,7 @@
<text bottom_delta="16" name="purchase_warning_notenough">
Vous n&apos;achetez pas assez de L$. Veuillez augmenter le montant.
</text>
- <button label="Acheter maintenant" name="buy_btn"/>
+ <button label="Acheter" name="buy_btn"/>
<button label="Annuler" name="cancel_btn"/>
<text left="5" name="info_cannot_buy" right="-5">
Achat impossible
diff --git a/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml
index 7727e1b657..52f8597dc2 100644
--- a/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml
@@ -13,8 +13,7 @@
<check_box label="Photos" name="check_snapshot"/>
<button label="Tout" label_selected="Tout" name="All" width="70"/>
<button bottom_delta="0" label="Aucun" label_selected="Aucun" left="83" name="None" width="70"/>
- <check_box bottom_delta="-20" label="Toujours montrer
-les dossiers" name="check_show_empty"/>
+ <check_box bottom_delta="-20" label="Toujours montrer les dossiers" name="check_show_empty"/>
<check_box bottom_delta="-36" label="Depuis la déconnexion" name="check_since_logoff"/>
<text name="- OR -">
Ou il y a...
diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml
index 2d5def55f3..9639e8415d 100644
--- a/indra/newview/skins/default/xui/fr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml
@@ -49,7 +49,7 @@
<menu_item_check label="Mini-carte" name="Mini-Map"/>
<menu_item_check label="Carte du monde" name="World Map"/>
<menu_item_call label="Photo" name="Take Snapshot"/>
- <menu label="Soleil" name="Environment Settings">
+ <menu label="Luminosité" name="Environment Settings">
<menu_item_call label="Aube" name="Sunrise"/>
<menu_item_call label="Milieu de journée" name="Noon"/>
<menu_item_call label="Coucher de soleil" name="Sunset"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_skin.xml b/indra/newview/skins/default/xui/fr/panel_edit_skin.xml
index 5f9f49c9e8..649b91d66d 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_skin.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_skin_panel">
<panel name="avatar_skin_color_panel">
- <texture_picker label="Tatouages tête" name="Head Tattoos" tool_tip="Cliquez pour sélectionner une image"/>
- <texture_picker label="Tatouages haut" name="Upper Tattoos" tool_tip="Cliquez pour sélectionner une image"/>
- <texture_picker label="Tatouages bas" name="Lower Tattoos" tool_tip="Cliquez pour sélectionner une image"/>
+ <texture_picker label="Tatouage tête" name="Head Tattoos" tool_tip="Cliquez pour sélectionner une image"/>
+ <texture_picker label="Tatouage haut" name="Upper Tattoos" tool_tip="Cliquez pour sélectionner une image"/>
+ <texture_picker label="Tatouage bas" name="Lower Tattoos" tool_tip="Cliquez pour sélectionner une image"/>
</panel>
<accordion name="wearable_accordion">
<accordion_tab name="skin_color_tab" title="Couleur de peau"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_main_inventory.xml b/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
index ea6cee1da5..9a98581cb4 100644
--- a/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
@@ -15,7 +15,7 @@
</panel>
<menu_bar name="Inventory Menu">
<menu label="Fichier" name="File">
- <menu_item_call label="Ouvert" name="Open"/>
+ <menu_item_call label="Ouvrir" name="Open"/>
<menu label="Charger" name="upload">
<menu_item_call label="Image ([COST] L$)..." name="Upload Image"/>
<menu_item_call label="Son ([COST] L$)..." name="Upload Sound"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_notes.xml b/indra/newview/skins/default/xui/fr/panel_notes.xml
index 7fa583c32b..0195118fd8 100644
--- a/indra/newview/skins/default/xui/fr/panel_notes.xml
+++ b/indra/newview/skins/default/xui/fr/panel_notes.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Notes et vie privée" name="panel_notes">
+<panel label="Notes/Perso" name="panel_notes">
<layout_stack name="layout">
<panel name="notes_stack">
<scroll_container name="profile_scroll">
<panel name="profile_scroll_panel">
- <text name="status_message" value="Mes notes privées :"/>
+ <text name="status_message" value="Mes notes perso :"/>
<text name="status_message2" value="Autoriser cette personne à :"/>
<check_box label="Afficher mon statut en ligne" name="status_check"/>
<check_box label="Me situer sur la carte" name="map_check"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_people.xml b/indra/newview/skins/default/xui/fr/panel_people.xml
index fb669f129b..ae2b96da3c 100644
--- a/indra/newview/skins/default/xui/fr/panel_people.xml
+++ b/indra/newview/skins/default/xui/fr/panel_people.xml
@@ -10,7 +10,7 @@
<string name="groups_filter_label" value="Filtrer les groupes"/>
<filter_editor label="Filtre" name="filter_input"/>
<tab_container name="tabs">
- <panel label="PROCHES" name="nearby_panel">
+ <panel label="PRÈS DE VOUS" name="nearby_panel">
<panel label="bottom_panel" name="bottom_panel">
<button name="nearby_view_sort_btn" tool_tip="Options"/>
<button name="add_friend_btn" tool_tip="Ajouter le résident sélectionné à votre liste d&apos;amis"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_picks.xml b/indra/newview/skins/default/xui/fr/panel_picks.xml
index 63a518f8a6..cf110c27b5 100644
--- a/indra/newview/skins/default/xui/fr/panel_picks.xml
+++ b/indra/newview/skins/default/xui/fr/panel_picks.xml
@@ -10,7 +10,7 @@
<accordion_tab name="tab_classifieds" title="Petites annonces"/>
</accordion>
<panel label="bottom_panel" name="edit_panel">
- <button name="new_btn" tool_tip="Ajouter cet endroit à mes Favoris"/>
+ <button name="new_btn" tool_tip="Ajouter cet endroit à mes Préférences"/>
</panel>
<panel name="buttons_cucks">
<button label="Infos" name="info_btn"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
index 13b467d205..d292b002f6 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Chat écrit" name="chat">
<radio_group name="chat_font_size">
- <radio_item label="Petite" name="radio"/>
+ <radio_item label="Moins" name="radio"/>
<radio_item label="Moyenne" name="radio2"/>
- <radio_item label="Grande" name="radio3"/>
+ <radio_item label="Plus" name="radio3"/>
</radio_group>
<color_swatch label="Vous" name="user"/>
<text name="text_box1">
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
index 783bd3bcba..6d331704ea 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
@@ -38,15 +38,15 @@
</combo_box>
<check_box initial_value="true" label="Afficher à la connexion" name="show_location_checkbox"/>
<text name="name_tags_textbox">
- Étiquettes :
+ Affichage des noms :
</text>
<radio_group name="Name_Tag_Preference">
- <radio_item label="Désactivée" name="radio"/>
- <radio_item label="Activée" name="radio2"/>
+ <radio_item label="Désactivé" name="radio"/>
+ <radio_item label="Activé" name="radio2"/>
<radio_item label="Afficher brièvement" name="radio3"/>
</radio_group>
<check_box label="Afficher mon nom" name="show_my_name_checkbox1"/>
- <check_box initial_value="true" label="Étiquettes courtes" name="small_avatar_names_checkbox"/>
+ <check_box initial_value="true" label="Affichage en petit" name="small_avatar_names_checkbox"/>
<check_box label="Afficher les titres de groupe" name="show_all_title_checkbox1"/>
<text name="effects_color_textbox">
Mes effets :
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
index b4b1783190..4459244395 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
@@ -12,7 +12,7 @@
<combo_box.item label="1024 x 768" name="1024x768"/>
</combo_box>
<text name="UI Size:">
- Taille de l&apos;UI :
+ Taille de l&apos;interface :
</text>
<text name="QualitySpeed">
Qualité et vitesse :
@@ -21,7 +21,7 @@
Plus rapide
</text>
<text name="BetterText">
- Mieux
+ Meilleur
</text>
<text name="ShadersPrefText">
Faible
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml
index c86a6da037..4bb6c76617 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml
@@ -21,7 +21,7 @@
<check_box label="Inclure les heures" name="show_timestamps_check_im"/>
<line_editor left="308" name="log_path_string" right="-20"/>
<text name="log_path_desc">
- Emplacement des journaux
+ Emplacement
</text>
<button label="Parcourir" label_selected="Parcourir" name="log_path_button" width="150"/>
<button label="Liste des ignorés" name="block_list"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_view.xml b/indra/newview/skins/default/xui/fr/panel_profile_view.xml
index 146095a25f..8f57dd89c7 100644
--- a/indra/newview/skins/default/xui/fr/panel_profile_view.xml
+++ b/indra/newview/skins/default/xui/fr/panel_profile_view.xml
@@ -11,6 +11,6 @@
<tab_container name="tabs">
<panel label="PROFIL" name="panel_profile"/>
<panel label="FAVORIS" name="panel_picks"/>
- <panel label="NOTES ET VIE PRIVÉE" name="panel_notes"/>
+ <panel label="NOTES/PERSO" name="panel_notes"/>
</tab_container>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index a8e3ff1442..b45a016822 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -1729,7 +1729,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Taille du ventre
</string>
<string name="Big">
- Maxi
+ Plus
</string>
<string name="Big Butt">
Grosses fesses
@@ -1858,7 +1858,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Favoris
</string>
<string name="Chin Depth">
- Profondeur du menton
+ Profondeur
</string>
<string name="Chin Heavy">
Menton lourd
@@ -1873,7 +1873,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Menton-cou
</string>
<string name="Clear">
- Effacer
+ Clair
</string>
<string name="Cleft">
Fendu
@@ -1987,7 +1987,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Arc
</string>
<string name="Eyebrow Density">
- Épaisseur
+ Épaisseur sourcils
</string>
<string name="Eyebrow Height">
Hauteur
@@ -2041,7 +2041,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Jambes larges
</string>
<string name="Flat">
- Plates
+ Plat
</string>
<string name="Flat Butt">
Fesses plates
@@ -2107,13 +2107,13 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Sens de la coiffure
</string>
<string name="Hair Thickess">
- Épaisseur
+ Épaisseur cheveux
</string>
<string name="Hair Thickness">
- Épaisseur
+ Épaisseur cheveux
</string>
<string name="Hair Tilt">
- Inclinaison des cheveux
+ Inclinaison
</string>
<string name="Hair Tilted Left">
Vers la gauche
@@ -2200,7 +2200,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Plis de la veste
</string>
<string name="Jaw Angle">
- Angle de la mâchoire
+ Angle mâchoire
</string>
<string name="Jaw Jut">
Saillie de la mâchoire
@@ -2221,7 +2221,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Genoux rapprochés
</string>
<string name="Large">
- Grand
+ Plus
</string>
<string name="Large Hands">
Grandes mains
@@ -2230,16 +2230,16 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Raie à gauche
</string>
<string name="Leg Length">
- Longueur de la jambe
+ Longueur
</string>
<string name="Leg Muscles">
- Muscles de la jambe
+ Muscles
</string>
<string name="Less">
Moins
</string>
<string name="Less Body Fat">
- Moins de graisse
+ Moins
</string>
<string name="Less Curtains">
Moins
@@ -2266,13 +2266,13 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Moins
</string>
<string name="Less Round">
- Moins
+ Moins ronde
</string>
<string name="Less Saddle">
Moins
</string>
<string name="Less Square">
- Moins
+ Moins carrée
</string>
<string name="Less Volume">
Moins
@@ -2299,10 +2299,10 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Proportion des lèvres
</string>
<string name="Lip Thickness">
- Épaisseur des lèvres
+ Épaisseur
</string>
<string name="Lip Width">
- Largeur des lèvres
+ Largeur
</string>
<string name="Lipgloss">
Brillant à lèvres
@@ -2545,7 +2545,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Épaisseur du nez
</string>
<string name="Nose Tip Angle">
- Angle du bout du nez
+ Bout du nez
</string>
<string name="Nose Tip Shape">
Bout du nez
@@ -2629,7 +2629,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Raie
</string>
<string name="Part Bangs">
- Séparation de la frange
+ Séparation frange
</string>
<string name="Pectorals">
Pectoraux
@@ -2677,7 +2677,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Paupières
</string>
<string name="Rainbow Color">
- Couleur de l&apos;arc en ciel
+ Couleur arc en ciel
</string>
<string name="Red Hair">
Cheveux roux
@@ -2725,10 +2725,10 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Front
</string>
<string name="Shear Left Up">
- Haut gauche dégagé
+ Haut gauche décalé
</string>
<string name="Shear Right Up">
- Haut droit dégagé
+ Haut droit décalé
</string>
<string name="Sheared Back">
Dégagé derrière
@@ -2758,7 +2758,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Hauteur
</string>
<string name="Short">
- Mini
+ Moins
</string>
<string name="Short Arms">
Bras courts
@@ -2833,7 +2833,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Fente : Droite
</string>
<string name="Small">
- Mini
+ Moins
</string>
<string name="Small Hands">
Petites mains
@@ -2842,7 +2842,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Petite tête
</string>
<string name="Smooth">
- Lisse
+ Lisses
</string>
<string name="Smooth Hair">
Cheveux lisses
@@ -2887,13 +2887,13 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Vers l&apos;avant
</string>
<string name="Tall">
- Maxi
+ Plus
</string>
<string name="Taper Back">
- Biseauter à l&apos;arrière
+ Arrière
</string>
<string name="Taper Front">
- Biseauter à l&apos;avant
+ Avant
</string>
<string name="Thick Heels">
Talons épais
@@ -2980,7 +2980,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Très rouge
</string>
<string name="Waist Height">
- Hauteur de la taille
+ Hauteur taille
</string>
<string name="Well-Fed">
Ronde