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/lldictionary.h9
-rw-r--r--indra/llcommon/llerrorlegacy.h8
-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/llfoldertype.cpp5
-rw-r--r--indra/llcommon/llpreprocessor.h15
-rw-r--r--indra/llimage/llimage.cpp6
-rw-r--r--indra/llmessage/llcurl.cpp20
-rw-r--r--indra/llmessage/llcurl.h11
-rw-r--r--indra/llmessage/llhttpclient.cpp2
-rw-r--r--indra/llmessage/llurlrequest.cpp1
-rw-r--r--indra/llrender/llimagegl.cpp50
-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/llbutton.cpp14
-rw-r--r--indra/llui/llbutton.h1
-rw-r--r--indra/llui/llfloater.cpp1
-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/lltabcontainer.cpp31
-rw-r--r--indra/llui/lltabcontainer.h1
-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.txt7
-rw-r--r--indra/newview/app_settings/keywords.ini4
-rw-r--r--indra/newview/app_settings/settings.xml47
-rw-r--r--indra/newview/gpu_table.txt10
-rw-r--r--indra/newview/llappearancemgr.cpp254
-rw-r--r--indra/newview/llappearancemgr.h48
-rw-r--r--indra/newview/llappviewer.cpp4
-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/llbottomtray.cpp2
-rw-r--r--indra/newview/llcallfloater.cpp236
-rw-r--r--indra/newview/llcallfloater.h55
-rw-r--r--indra/newview/llchathistory.cpp5
-rw-r--r--indra/newview/llchathistory.h2
-rw-r--r--indra/newview/llchiclet.cpp3
-rw-r--r--indra/newview/llcompilequeue.cpp14
-rw-r--r--indra/newview/llfavoritesbar.cpp5
-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.cpp43
-rw-r--r--indra/newview/llfloaterreporter.h4
-rw-r--r--indra/newview/llfloaterscriptlimits.cpp11
-rw-r--r--indra/newview/llfolderview.cpp1
-rw-r--r--indra/newview/llgesturemgr.cpp35
-rw-r--r--indra/newview/llgesturemgr.h3
-rw-r--r--indra/newview/llgrouplist.cpp4
-rw-r--r--indra/newview/llimfloater.cpp20
-rw-r--r--indra/newview/llimfloater.h2
-rw-r--r--indra/newview/llimfloatercontainer.cpp84
-rw-r--r--indra/newview/llimfloatercontainer.h21
-rw-r--r--indra/newview/llimpanel.cpp1
-rw-r--r--indra/newview/llimview.cpp156
-rw-r--r--indra/newview/llimview.h42
-rw-r--r--indra/newview/llinspectavatar.cpp3
-rw-r--r--indra/newview/llinventorybridge.cpp62
-rw-r--r--indra/newview/llinventorybridge.h1
-rw-r--r--indra/newview/llinventorymodel.cpp4
-rw-r--r--indra/newview/llinventoryobserver.h5
-rw-r--r--indra/newview/llinventorypanel.cpp8
-rw-r--r--indra/newview/llinventorypanel.h2
-rw-r--r--indra/newview/lllocationinputctrl.cpp52
-rw-r--r--indra/newview/lllocationinputctrl.h23
-rw-r--r--indra/newview/lllogchat.cpp6
-rw-r--r--indra/newview/lllogchat.h2
-rw-r--r--indra/newview/llmediactrl.cpp109
-rw-r--r--indra/newview/llmediactrl.h1
-rw-r--r--indra/newview/llmoveview.cpp15
-rw-r--r--indra/newview/llmutelist.cpp77
-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/llpanelface.cpp40
-rw-r--r--indra/newview/llpanelgroup.cpp24
-rw-r--r--indra/newview/llpanelgroup.h8
-rw-r--r--indra/newview/llpanelgrouproles.cpp39
-rw-r--r--indra/newview/llpanelgrouproles.h2
-rw-r--r--indra/newview/llpanelimcontrolpanel.cpp64
-rw-r--r--indra/newview/llpanelimcontrolpanel.h15
-rw-r--r--indra/newview/llpanellandaudio.cpp62
-rw-r--r--indra/newview/llpanellandaudio.h4
-rw-r--r--indra/newview/llpanellandmarkinfo.cpp8
-rw-r--r--indra/newview/llpanellandmarks.cpp53
-rw-r--r--indra/newview/llpanellandmarks.h16
-rw-r--r--indra/newview/llpanelme.cpp2
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp40
-rw-r--r--indra/newview/llpaneloutfitsinventory.h24
-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.cpp45
-rw-r--r--indra/newview/llpanelplaceinfo.h1
-rw-r--r--indra/newview/llpanelplaceprofile.cpp99
-rw-r--r--indra/newview/llpanelplaceprofile.h2
-rw-r--r--indra/newview/llpanelplaces.cpp225
-rw-r--r--indra/newview/llpanelplaces.h8
-rw-r--r--indra/newview/llpanelprofileview.cpp54
-rw-r--r--indra/newview/llpanelprofileview.h20
-rw-r--r--indra/newview/llpanelteleporthistory.cpp2
-rw-r--r--indra/newview/llparticipantlist.cpp21
-rw-r--r--indra/newview/llpreviewtexture.cpp143
-rw-r--r--indra/newview/llspeakers.cpp154
-rw-r--r--indra/newview/llspeakers.h94
-rw-r--r--indra/newview/llstartup.cpp59
-rw-r--r--indra/newview/lltexlayer.cpp4
-rw-r--r--indra/newview/lltexturectrl.cpp10
-rw-r--r--indra/newview/lltexturectrl.h3
-rw-r--r--indra/newview/lltoolpie.cpp572
-rw-r--r--indra/newview/lltoolpie.h4
-rw-r--r--indra/newview/lltransientdockablefloater.cpp25
-rw-r--r--indra/newview/lltransientdockablefloater.h4
-rw-r--r--indra/newview/lltransientfloatermgr.cpp77
-rw-r--r--indra/newview/lltransientfloatermgr.h47
-rw-r--r--indra/newview/llviewerdisplay.cpp5
-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.cpp7
-rw-r--r--indra/newview/llviewermenu.cpp28
-rw-r--r--indra/newview/llviewermessage.cpp72
-rw-r--r--indra/newview/llviewerparcelmedia.cpp17
-rw-r--r--indra/newview/llviewertexture.cpp7
-rw-r--r--indra/newview/llviewertexturelist.cpp10
-rw-r--r--indra/newview/llvoicechannel.cpp12
-rw-r--r--indra/newview/llvoiceclient.cpp128
-rw-r--r--indra/newview/llvoiceclient.h2
-rw-r--r--indra/newview/llvovolume.cpp10
-rw-r--r--indra/newview/llxmlrpctransaction.cpp5
-rw-r--r--indra/newview/skins/default/textures/bottomtray/WellButton_Lit.pngbin490 -> 309 bytes
-rw-r--r--indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.pngbin302 -> 309 bytes
-rw-r--r--indra/newview/skins/default/xui/da/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_edit_profile.xml2
-rw-r--r--indra/newview/skins/default/xui/en/favorites_bar_button.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_aaa.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_buy_currency.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_customize.xml1490
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_container.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_media_browser.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_search.xml8
-rw-r--r--indra/newview/skins/default/xui/en/floater_sys_well.xml8
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_checkbox.xml79
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml10
-rw-r--r--indra/newview/skins/default/xui/en/floater_voice_controls.xml13
-rw-r--r--indra/newview/skins/default/xui/en/inspect_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/en/main_view.xml20
-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.xml12
-rw-r--r--indra/newview/skins/default/xui/en/panel_avatar_list_item.xml28
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml23
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_land_money.xml90
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_roles.xml24
-rw-r--r--indra/newview/skins/default/xui/en/panel_my_profile.xml15
-rw-r--r--indra/newview/skins/default/xui/en/panel_navigation_bar.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_notes.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfits_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_info.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_picks.xml4
-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.xml646
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile.xml19
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_view.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_teleport_history_item.xml1
-rw-r--r--indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml18
-rw-r--r--indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml20
-rw-r--r--indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml20
-rw-r--r--indra/newview/skins/default/xui/en/widgets/chiclet_offer.xml16
-rw-r--r--indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml4
-rw-r--r--indra/newview/skins/default/xui/en/widgets/chiclet_script.xml12
-rw-r--r--indra/newview/skins/default/xui/en/widgets/color_swatch.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_about.xml2
-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_profile.xml4
-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
-rw-r--r--indra/newview/skins/default/xui/it/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_edit_profile.xml2
-rw-r--r--indra/newview/skins/default/xui/nl/floater_about.xml2
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_about.xml2
-rwxr-xr-xindra/newview/viewer_manifest.py6
222 files changed, 5428 insertions, 3296 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/lldictionary.h b/indra/llcommon/lldictionary.h
index 95178b41e7..4a2bfb9f3f 100644
--- a/indra/llcommon/lldictionary.h
+++ b/indra/llcommon/lldictionary.h
@@ -76,11 +76,16 @@ public:
return dictionary_iter->first;
}
}
- llassert(false);
- return Index(-1);
+ return notFound();
}
protected:
+ virtual Index notFound() const
+ {
+ // default is to assert
+ llassert(false);
+ return Index(-1);
+ }
void addEntry(Index index, Entry *entry)
{
if (lookup(index))
diff --git a/indra/llcommon/llerrorlegacy.h b/indra/llcommon/llerrorlegacy.h
index 7a970b1466..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
@@ -75,6 +75,10 @@ const int LL_ERR_PRICE_MISMATCH = -23018;
#define SHOW_ASSERT
#else // _DEBUG
+#ifdef LL_RELEASE_WITH_DEBUG_INFO
+#define SHOW_ASSERT
+#endif // LL_RELEASE_WITH_DEBUG_INFO
+
#ifdef RELEASE_SHOW_DEBUG
#define SHOW_DEBUG
#endif
@@ -103,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/llfoldertype.cpp b/indra/llcommon/llfoldertype.cpp
index 079e670b1a..2610fe9e6a 100644
--- a/indra/llcommon/llfoldertype.cpp
+++ b/indra/llcommon/llfoldertype.cpp
@@ -59,6 +59,11 @@ class LLFolderDictionary : public LLSingleton<LLFolderDictionary>,
{
public:
LLFolderDictionary();
+protected:
+ virtual LLFolderType::EType notFound() const
+ {
+ return LLFolderType::FT_NONE;
+ }
};
LLFolderDictionary::LLFolderDictionary()
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/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 575ad5363d..e02be6c8c1 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -668,6 +668,12 @@ void LLImageRaw::fill( const LLColor4U& color )
// Src and dst can be any size. Src and dst can each have 3 or 4 components.
void LLImageRaw::copy(LLImageRaw* src)
{
+ if (!src)
+ {
+ llwarns << "LLImageRaw::copy called with a null src pointer" << llendl;
+ return;
+ }
+
LLImageRaw* dst = this; // Just for clarity.
llassert( (3 == src->getComponents()) || (4 == src->getComponents()) );
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index dc02367a62..024e17a777 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -89,6 +89,10 @@ S32 gCurlMultiCount = 0;
std::vector<LLMutex*> LLCurl::sSSLMutex;
std::string LLCurl::sCAPath;
std::string LLCurl::sCAFile;
+// Verify SSL certificates by default (matches libcurl default). The ability
+// to alter this flag is only to allow us to suppress verification if it's
+// broken for some reason.
+bool LLCurl::sSSLVerify = true;
//static
void LLCurl::setCAPath(const std::string& path)
@@ -103,6 +107,18 @@ void LLCurl::setCAFile(const std::string& file)
}
//static
+void LLCurl::setSSLVerify(bool verify)
+{
+ sSSLVerify = verify;
+}
+
+//static
+bool LLCurl::getSSLVerify()
+{
+ return sSSLVerify;
+}
+
+//static
std::string LLCurl::getVersionString()
{
return std::string(curl_version());
@@ -465,7 +481,8 @@ void LLCurl::Easy::prepRequest(const std::string& url,
setErrorBuffer();
setCA();
- setopt(CURLOPT_SSL_VERIFYPEER, true);
+ setopt(CURLOPT_SSL_VERIFYPEER, LLCurl::getSSLVerify());
+ setopt(CURLOPT_SSL_VERIFYHOST, LLCurl::getSSLVerify()? 2 : 0);
setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT);
setoptString(CURLOPT_URL, url);
@@ -1044,4 +1061,3 @@ void LLCurl::cleanupClass()
#endif
curl_global_cleanup();
}
-
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 1bc1767966..caf02cccd9 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -158,6 +158,16 @@ public:
static const std::string& getCAPath() { return sCAPath; }
/**
+ * @ brief Set flag controlling whether to verify HTTPS certs.
+ */
+ static void setSSLVerify(bool verify);
+
+ /**
+ * @ brief Get flag controlling whether to verify HTTPS certs.
+ */
+ static bool getSSLVerify();
+
+ /**
* @ brief Initialize LLCurl class
*/
static void initClass();
@@ -182,6 +192,7 @@ public:
private:
static std::string sCAPath;
static std::string sCAFile;
+ static bool sSSLVerify;
};
namespace boost
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index 12ecbb36eb..dd56e18caf 100644
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -222,7 +222,7 @@ static void request(
LLPumpIO::chain_t chain;
LLURLRequest* req = new LLURLRequest(method, url);
- req->checkRootCertificate(true);
+ req->checkRootCertificate(LLCurl::getSSLVerify());
lldebugs << LLURLRequest::actionAsVerb(method) << " " << url << " "
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index 81b7761ed5..4e7ceff984 100644
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -163,6 +163,7 @@ void LLURLRequest::setBodyLimit(U32 size)
void LLURLRequest::checkRootCertificate(bool check)
{
mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, (check? TRUE : FALSE));
+ mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, (check? 2 : 0));
mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, "");
}
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index d873005fd9..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,22 +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))
{
- llerrs << "WTF?" << llendl;
+ 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 (LL_UNLIKELY(x >= mPickMaskWidth))
+ {
+ LL_WARNS_ONCE("render") << "Ooh, width overrun on pick mask read, that coulda been bad." << LL_ENDL;
+ x = llmax(0, mPickMaskWidth-1);
+ }
+ 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, 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/llbutton.cpp b/indra/llui/llbutton.cpp
index e9f6288f44..9ce8ce8d55 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -1022,6 +1022,20 @@ void LLButton::setImageOverlay(const std::string& image_name, LLFontGL::HAlign a
}
}
+void LLButton::setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignment, const LLColor4& color)
+{
+ if (image_id.isNull())
+ {
+ mImageOverlay = NULL;
+ }
+ else
+ {
+ mImageOverlay = LLUI::getUIImageByID(image_id);
+ mImageOverlayAlignment = alignment;
+ mImageOverlayColor = color;
+ }
+}
+
void LLButton::onMouseCaptureLost()
{
resetMouseDownTimer();
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 5e28b8cdff..cd149e3113 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -200,6 +200,7 @@ public:
void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; }
void setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
+ void setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
LLPointer<LLUIImage> getImageOverlay() { return mImageOverlay; }
void autoResize(); // resize with label of current btn state
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 4f519afa06..79d8f90fec 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -1360,6 +1360,7 @@ void LLFloater::bringToFront( S32 x, S32 y )
// virtual
void LLFloater::setVisibleAndFrontmost(BOOL take_focus)
{
+ gFocusMgr.setTopCtrl(NULL);
setVisible(TRUE);
setFrontmost(take_focus);
}
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/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 327dd01612..43c44f2253 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -1507,6 +1507,37 @@ void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const L
}
}
+void LLTabContainer::setTabImage(LLPanel* child, const LLUUID& image_id, const LLColor4& color)
+{
+ static LLUICachedControl<S32> tab_padding ("UITabPadding", 0);
+ LLTabTuple* tuple = getTabByPanel(child);
+ if( tuple )
+ {
+ tuple->mButton->setImageOverlay(image_id, LLFontGL::RIGHT, color);
+
+ if (!mIsVertical)
+ {
+ // remove current width from total tab strip width
+ mTotalTabWidth -= tuple->mButton->getRect().getWidth();
+
+ S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ?
+ tuple->mButton->getImageOverlay()->getImage()->getWidth(0) :
+ 0;
+
+ tuple->mPadding = image_overlay_width;
+
+ tuple->mButton->setRightHPad(6);
+ tuple->mButton->reshape(llclamp(mFont->getWidth(tuple->mButton->getLabelSelected()) + tab_padding + tuple->mPadding, mMinTabWidth, mMaxTabWidth),
+ tuple->mButton->getRect().getHeight());
+ // add back in button width to total tab strip width
+ mTotalTabWidth += tuple->mButton->getRect().getWidth();
+
+ // tabs have changed size, might need to scroll to see current tab
+ updateMaxScrollPos();
+ }
+ }
+}
+
void LLTabContainer::setTitle(const std::string& title)
{
if (mTitleBox)
diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h
index 5d0f194bf9..33c49e0d6f 100644
--- a/indra/llui/lltabcontainer.h
+++ b/indra/llui/lltabcontainer.h
@@ -172,6 +172,7 @@ public:
BOOL getTabPanelFlashing(LLPanel* child);
void setTabPanelFlashing(LLPanel* child, BOOL state);
void setTabImage(LLPanel* child, std::string img_name, const LLColor4& color = LLColor4::white);
+ void setTabImage(LLPanel* child, const LLUUID& img_id, const LLColor4& color = LLColor4::white);
void setTitle( const std::string& title );
const std::string getPanelTitle(S32 index);
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 5373556c20..7ddeb90d29 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -343,7 +343,6 @@ set(viewer_SOURCE_FILES
llpanelprimmediacontrols.cpp
llpanelprofile.cpp
llpanelprofileview.cpp
- llpanelshower.cpp
llpanelteleporthistory.cpp
llpanelvolume.cpp
llpanelvolumepulldown.cpp
@@ -846,7 +845,6 @@ set(viewer_HEADER_FILES
llpanelprimmediacontrols.h
llpanelprofile.h
llpanelprofileview.h
- llpanelshower.h
llpanelteleporthistory.h
llpanelvolume.h
llpanelvolumepulldown.h
@@ -1580,7 +1578,10 @@ if (WINDOWS)
DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
)
- add_custom_target(package ALL DEPENDS ${CMAKE_CFG_INTDIR}/touched.bat)
+ add_custom_target(package ALL DEPENDS
+ ${CMAKE_CFG_INTDIR}/touched.bat
+ windows-setup-build-all
+ )
# temporarily disable packaging of event_host until hg subrepos get
# sorted out on the parabuild cluster...
#${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2)
diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini
index 14025c8061..0805e94b10 100644
--- a/indra/newview/app_settings/keywords.ini
+++ b/indra/newview/app_settings/keywords.ini
@@ -268,8 +268,8 @@ ATTACH_LHIP Passed to llAttachToAvatar to attach task to left hip
ATTACH_LULEG Passed to llAttachToAvatar to attach task to left upper leg
ATTACH_LLLEG Passed to llAttachToAvatar to attach task to left lower leg
ATTACH_BELLY Passed to llAttachToAvatar to attach task to belly
-ATTACH_RPEC Passed to llAttachToAvatar to attach task to right pectoral
-ATTACH_LPEC Passed to llAttachToAvatar to attach task to left pectoral
+ATTACH_LEFT_PEC Passed to llAttachToAvatar to attach task to left pectoral
+ATTACH_RIGHT_PEC Passed to llAttachToAvatar to attach task to right pectoral
LAND_LEVEL Passed to llModifyLand to level terrain
LAND_RAISE Passed to llModifyLand to raise terrain
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 53ac1dc0b9..093e4f4894 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>
@@ -1145,17 +1134,6 @@
<key>Value</key>
<integer>5</integer>
</map>
- <key>CallFloaterMaxItems</key>
- <map>
- <key>Comment</key>
- <string>Max number of visible participants in voice controls window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>CameraAngle</key>
<map>
<key>Comment</key>
@@ -3629,7 +3607,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>http://int.searchwww-phx0.damballah.lindenlab.com/viewer/[CATEGORY]?q=[QUERY]&amp;p=[AUTH_TOKEN]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]</string>
+ <string>http://search.secondlife.com/viewer/[CATEGORY]?q=[QUERY]&amp;p=[AUTH_TOKEN]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]</string>
</map>
<key>HighResSnapshot</key>
<map>
@@ -10081,6 +10059,18 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>SpeakerParticipantRemoveDelay</key>
+ <map>
+ <key>Comment</key>
+ <string>Timeout to remove participants who is not in channel before removed from list of active speakers (text/voice chat)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>10.0</real>
+ </map>
+
<key>UseStartScreen</key>
<map>
<key>Comment</key>
@@ -10313,6 +10303,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 748d8bdfbf..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:
@@ -274,6 +292,7 @@ private:
struct LLFoundData
{
+ LLFoundData() {}
LLFoundData(const LLUUID& item_id,
const LLUUID& asset_id,
const std::string& name,
@@ -292,20 +311,94 @@ struct LLFoundData
};
-struct LLWearableHoldingPattern
+class LLWearableHoldingPattern
{
- LLWearableHoldingPattern() : mResolved(0) {}
- ~LLWearableHoldingPattern()
- {
- for_each(mFoundList.begin(), mFoundList.end(), DeletePointer());
- mFoundList.clear();
- }
- typedef std::list<LLFoundData*> found_list_t;
+public:
+ LLWearableHoldingPattern();
+ ~LLWearableHoldingPattern();
+
+ bool pollCompletion();
+ bool isDone();
+ bool isTimedOut();
+
+ typedef std::list<LLFoundData> found_list_t;
found_list_t mFoundList;
+ LLInventoryModel::item_array_t mObjItems;
+ LLInventoryModel::item_array_t mGestItems;
S32 mResolved;
- bool append;
+ LLTimer mWaitTime;
};
+LLWearableHoldingPattern::LLWearableHoldingPattern():
+ mResolved(0)
+{
+}
+
+LLWearableHoldingPattern::~LLWearableHoldingPattern()
+{
+}
+
+bool LLWearableHoldingPattern::isDone()
+{
+ if (mResolved >= (S32)mFoundList.size())
+ return true; // have everything we were waiting for
+ else if (isTimedOut())
+ {
+ llwarns << "Exceeded max wait time, updating appearance based on what has arrived" << llendl;
+ return true;
+ }
+ return false;
+
+}
+
+bool LLWearableHoldingPattern::isTimedOut()
+{
+ static F32 max_wait_time = 15.0; // give up if wearable fetches haven't completed in max_wait_time seconds.
+ return mWaitTime.getElapsedTimeF32() > max_wait_time;
+}
+
+bool LLWearableHoldingPattern::pollCompletion()
+{
+ bool done = isDone();
+ llinfos << "polling, done status: " << done << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl;
+ if (done)
+ {
+ // Activate all gestures in this folder
+ if (mGestItems.count() > 0)
+ {
+ llinfos << "Activating " << mGestItems.count() << " gestures" << llendl;
+
+ LLGestureManager::instance().activateGestures(mGestItems);
+
+ // Update the inventory item labels to reflect the fact
+ // they are active.
+ LLViewerInventoryCategory* catp =
+ gInventory.getCategory(LLAppearanceManager::instance().getCOF());
+
+ if (catp)
+ {
+ gInventory.updateCategory(catp);
+ gInventory.notifyObservers();
+ }
+ }
+
+ // Update wearables.
+ llinfos << "Updating agent wearables with " << mResolved << " wearable items " << llendl;
+ LLAppearanceManager::instance().updateAgentWearables(this, false);
+
+ // Update attachments to match those requested.
+ LLVOAvatar* avatar = gAgent.getAvatarObject();
+ if( avatar )
+ {
+ llinfos << "Updating " << mObjItems.count() << " attachments" << llendl;
+ LLAgentWearables::userUpdateAttachments(mObjItems);
+ }
+
+ delete this;
+ }
+ return done;
+}
+
static void removeDuplicateItems(LLInventoryModel::item_array_t& items)
{
LLInventoryModel::item_array_t new_items;
@@ -336,29 +429,24 @@ static void removeDuplicateItems(LLInventoryModel::item_array_t& items)
static void onWearableAssetFetch(LLWearable* wearable, void* data)
{
LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data;
- bool append = holder->append;
if(wearable)
{
for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin();
iter != holder->mFoundList.end(); ++iter)
{
- LLFoundData* data = *iter;
- if(wearable->getAssetID() == data->mAssetID)
+ LLFoundData& data = *iter;
+ if(wearable->getAssetID() == data.mAssetID)
{
- data->mWearable = wearable;
+ data.mWearable = wearable;
break;
}
}
}
holder->mResolved += 1;
- if(holder->mResolved >= (S32)holder->mFoundList.size())
- {
- LLAppearanceManager::instance().updateAgentWearables(holder, append);
- }
}
-LLUUID LLAppearanceManager::getCOF()
+const LLUUID LLAppearanceManager::getCOF() const
{
return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
}
@@ -662,12 +750,12 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder,
for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin();
iter != holder->mFoundList.end(); ++iter)
{
- LLFoundData* data = *iter;
- LLWearable* wearable = data->mWearable;
+ LLFoundData& data = *iter;
+ LLWearable* wearable = data.mWearable;
if( wearable && ((S32)wearable->getType() == i) )
{
LLViewerInventoryItem* item;
- item = (LLViewerInventoryItem*)gInventory.getItem(data->mItemID);
+ item = (LLViewerInventoryItem*)gInventory.getItem(data.mItemID);
if( item && (item->getAssetUUID() == wearable->getAssetID()) )
{
items.put(item);
@@ -683,8 +771,6 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder,
gAgentWearables.setWearableOutfit(items, wearables, !append);
}
- delete holder;
-
// dec_busy_count();
}
@@ -706,86 +792,66 @@ void LLAppearanceManager::updateAppearanceFromCOF()
LLInventoryModel::item_array_t gest_items;
getUserDescendents(current_outfit_id, wear_items, obj_items, gest_items, follow_folder_links);
- if( !wear_items.count() && !obj_items.count() && !gest_items.count())
+ if(!wear_items.count())
{
LLNotificationsUtil::add("CouldNotPutOnOutfit");
return;
}
-
- // Processes that take time should show the busy cursor
- //inc_busy_count(); // BAP this is currently a no-op in llinventorybridge.cpp - do we need it?
-
- // Activate all gestures in this folder
- if (gest_items.count() > 0)
- {
- llinfos << "Activating " << gest_items.count() << " gestures" << llendl;
- LLGestureManager::instance().activateGestures(gest_items);
+ LLWearableHoldingPattern* holder = new LLWearableHoldingPattern;
- // Update the inventory item labels to reflect the fact
- // they are active.
- LLViewerInventoryCategory* catp = gInventory.getCategory(current_outfit_id);
- if (catp)
+ holder->mObjItems = obj_items;
+ holder->mGestItems = gest_items;
+
+ // Note: can't do normal iteration, because if all the
+ // wearables can be resolved immediately, then the
+ // callback will be called (and this object deleted)
+ // before the final getNextData().
+ LLDynamicArray<LLFoundData> found_container;
+ for(S32 i = 0; i < wear_items.count(); ++i)
+ {
+ LLViewerInventoryItem *item = wear_items.get(i);
+ LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
+ if (item && linked_item)
{
- gInventory.updateCategory(catp);
- gInventory.notifyObservers();
+ LLFoundData found(linked_item->getUUID(),
+ linked_item->getAssetUUID(),
+ linked_item->getName(),
+ linked_item->getType());
+ holder->mFoundList.push_front(found);
+ found_container.put(found);
}
- }
-
- if(wear_items.count() > 0)
- {
- // Note: can't do normal iteration, because if all the
- // wearables can be resolved immediately, then the
- // callback will be called (and this object deleted)
- // before the final getNextData().
- LLWearableHoldingPattern* holder = new LLWearableHoldingPattern;
- LLFoundData* found;
- LLDynamicArray<LLFoundData*> found_container;
- for(S32 i = 0; i < wear_items.count(); ++i)
+ else
{
- LLViewerInventoryItem *item = wear_items.get(i);
- LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
- if (item && linked_item)
+ if (!item)
{
- found = new LLFoundData(linked_item->getUUID(),
- linked_item->getAssetUUID(),
- linked_item->getName(),
- linked_item->getType());
- holder->mFoundList.push_front(found);
- found_container.put(found);
+ llwarns << "attempt to wear a null item " << llendl;
}
- else
+ else if (!linked_item)
{
- if (!item)
- {
- llwarns << "attempt to wear a null item " << llendl;
- }
- else if (!linked_item)
- {
- llwarns << "attempt to wear a broken link " << item->getName() << llendl;
- }
+ llwarns << "attempt to wear a broken link " << item->getName() << llendl;
}
}
- for(S32 i = 0; i < found_container.count(); ++i)
- {
- holder->append = false;
- found = found_container.get(i);
+ }
+
+ for(S32 i = 0; i < found_container.count(); ++i)
+ {
+ LLFoundData& found = found_container.get(i);
- // Fetch the wearables about to be worn.
- LLWearableList::instance().getAsset(found->mAssetID,
- found->mName,
- found->mAssetType,
- onWearableAssetFetch,
- (void*)holder);
- }
+ // Fetch the wearables about to be worn.
+ LLWearableList::instance().getAsset(found.mAssetID,
+ found.mName,
+ found.mAssetType,
+ onWearableAssetFetch,
+ (void*)holder);
+
}
- // Update attachments to match those requested.
- LLVOAvatar* avatar = gAgent.getAvatarObject();
- if( avatar )
+ if (!holder->pollCompletion())
{
- LLAgentWearables::userUpdateAttachments(obj_items);
+ doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollCompletion,holder));
}
+
}
void LLAppearanceManager::getDescendentsOfAssetType(const LLUUID& category,
@@ -1263,3 +1329,23 @@ void LLAppearanceManager::linkRegisteredAttachments()
}
mRegisteredAttachments.clear();
}
+
+BOOL LLAppearanceManager::getIsInCOF(const LLUUID& obj_id) const
+{
+ return gInventory.isObjectDescendentOf(obj_id, getCOF());
+}
+
+BOOL LLAppearanceManager::getIsProtectedCOFItem(const LLUUID& obj_id) const
+{
+ if (!getIsInCOF(obj_id)) return FALSE;
+ const LLInventoryObject *obj = gInventory.getObject(obj_id);
+ if (!obj) return FALSE;
+
+ // Can't delete bodyparts, since this would be equivalent to removing the item.
+ if (obj->getType() == LLAssetType::AT_BODYPART) return TRUE;
+
+ // Can't delete the folder link, since this is saved for bookkeeping.
+ if (obj->getActualType() == LLAssetType::AT_LINK_FOLDER) return TRUE;
+
+ return FALSE;
+}
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 20745b70e4..dd50b482cf 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -39,7 +39,7 @@
#include "llcallbacklist.h"
class LLWearable;
-struct LLWearableHoldingPattern;
+class LLWearableHoldingPattern;
class LLAppearanceManager: public LLSingleton<LLAppearanceManager>
{
@@ -59,7 +59,7 @@ public:
LLPointer<LLInventoryCallback> cb);
// Find the Current Outfit folder.
- LLUUID getCOF();
+ const LLUUID getCOF() const;
// Finds the folder link to the currently worn outfit
const LLViewerInventoryItem *getBaseOutfitLink();
@@ -132,6 +132,14 @@ private:
std::set<LLUUID> mRegisteredAttachments;
bool mAttachmentInvLinkEnabled;
bool mOutfitIsDirty;
+
+ //////////////////////////////////////////////////////////////////////////////////
+ // Item-specific convenience functions
+public:
+ // Is this in the COF?
+ BOOL getIsInCOF(const LLUUID& obj_id) const;
+ // Is this in the COF and can the user delete it from the COF?
+ BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const;
};
#define SUPPORT_ENSEMBLES 0
@@ -168,4 +176,40 @@ void doOnIdle(T callable)
gIdleCallbacks.addFunction(&OnIdleCallback<T>::onIdle,cb_functor);
}
+// Shim class and template function to allow arbitrary boost::bind
+// expressions to be run as recurring idle callbacks.
+template <typename T>
+class OnIdleCallbackRepeating
+{
+public:
+ OnIdleCallbackRepeating(T callable):
+ mCallable(callable)
+ {
+ }
+ // Will keep getting called until the callable returns false.
+ static void onIdle(void *data)
+ {
+ OnIdleCallbackRepeating<T>* self = reinterpret_cast<OnIdleCallbackRepeating<T>*>(data);
+ bool done = self->call();
+ if (done)
+ {
+ gIdleCallbacks.deleteFunction(onIdle, data);
+ delete self;
+ }
+ }
+ bool call()
+ {
+ return mCallable();
+ }
+private:
+ T mCallable;
+};
+
+template <typename T>
+void doOnIdleRepeating(T callable)
+{
+ OnIdleCallbackRepeating<T>* cb_functor = new OnIdleCallbackRepeating<T>(callable);
+ gIdleCallbacks.addFunction(&OnIdleCallbackRepeating<T>::onIdle,cb_functor);
+}
+
#endif
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 638a8f759d..0e248ff88b 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -926,7 +926,6 @@ bool LLAppViewer::mainLoop()
{
LLMemType mt1(LLMemType::MTYPE_MAIN);
mMainloopTimeout = new LLWatchdogTimeout();
- // *FIX:Mani - Make this a setting, once new settings exist in this branch.
//-------------------------------------------
// Run main loop until time to quit
@@ -936,12 +935,13 @@ bool LLAppViewer::mainLoop()
gServicePump = new LLPumpIO(gAPRPoolp);
LLHTTPClient::setPump(*gServicePump);
LLCurl::setCAFile(gDirUtilp->getCAFile());
+ LLCurl::setSSLVerify(! gSavedSettings.getBOOL("NoVerifySSLCert"));
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
LLVoiceChannel::initClass();
LLVoiceClient::init(gServicePump);
-
+
LLTimer frameTimer,idleTimer;
LLTimer debugTime;
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
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/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 988867ef84..bd68d52868 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -322,7 +322,7 @@ void LLBottomTray::setVisible(BOOL visible)
// Chat bar and gesture button are shown even in mouselook mode.
// But the move, camera and snapshot buttons shouldn't be displayed. See EXT-3988.
- if ("chat_bar" == name || "gesture_panel" == name)
+ if ("chat_bar" == name || "gesture_panel" == name || (visibility && ("movement_panel" == name || "cam_panel" == name || "snapshot_panel" == name)))
continue;
else
{
diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp
index 6317a6a392..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"
@@ -51,9 +52,9 @@
#include "lltransientfloatermgr.h"
#include "llviewerwindow.h"
#include "llvoicechannel.h"
-#include "lllayoutstack.h"
static void get_voice_participants_uuids(std::vector<LLUUID>& speakers_uuids);
+void reshape_floater(LLCallFloater* floater, S32 delta_height);
class LLNonAvatarCaller : public LLAvatarListItem
{
@@ -93,22 +94,6 @@ static void* create_non_avatar_caller(void*)
return new LLNonAvatarCaller;
}
-LLCallFloater::LLAvatarListItemRemoveTimer::LLAvatarListItemRemoveTimer(callback_t remove_cb, F32 period, const LLUUID& speaker_id)
-: LLEventTimer(period)
-, mRemoveCallback(remove_cb)
-, mSpeakerId(speaker_id)
-{
-}
-
-BOOL LLCallFloater::LLAvatarListItemRemoveTimer::tick()
-{
- if (mRemoveCallback)
- {
- mRemoveCallback(mSpeakerId);
- }
- return TRUE;
-}
-
LLVoiceChannel* LLCallFloater::sCurrentVoiceCanel = NULL;
LLCallFloater::LLCallFloater(const LLSD& key)
@@ -122,10 +107,9 @@ LLCallFloater::LLCallFloater(const LLSD& key)
, mSpeakingIndicator(NULL)
, mIsModeratorMutedVoice(false)
, mInitParticipantsVoiceState(false)
-, mVoiceLeftRemoveDelay(10)
{
static LLUICachedControl<S32> voice_left_remove_delay ("VoiceParticipantLeftRemoveDelay", 10);
- mVoiceLeftRemoveDelay = voice_left_remove_delay;
+ mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLCallFloater::removeVoiceLeftParticipant, this, _1), voice_left_remove_delay);
mFactoryMap["non_avatar_caller"] = LLCallbackMap(create_non_avatar_caller, NULL);
LLVoiceClient::getInstance()->addObserver(this);
@@ -135,6 +119,7 @@ LLCallFloater::LLCallFloater(const LLSD& key)
LLCallFloater::~LLCallFloater()
{
resetVoiceRemoveTimers();
+ delete mSpeakerDelayRemover;
delete mParticipants;
mParticipants = NULL;
@@ -174,6 +159,13 @@ BOOL LLCallFloater::postBuild()
connectToChannel(LLVoiceChannel::getCurrentVoiceChannel());
+ setIsChrome(true);
+ //chrome="true" hides floater caption
+ if (mDragHandle)
+ mDragHandle->setTitleVisible(TRUE);
+
+ updateSession();
+
return TRUE;
}
@@ -225,16 +217,6 @@ void LLCallFloater::onChange()
}
}
-S32 LLCallFloater::notifyParent(const LLSD& info)
-{
- if("size_changes" == info["action"])
- {
- reshapeToFitContent();
- return 1;
- }
- return LLDockableFloater::notifyParent(info);
-}
-
//////////////////////////////////////////////////////////////////////////
/// PRIVATE SECTION
//////////////////////////////////////////////////////////////////////////
@@ -266,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);
@@ -316,7 +298,7 @@ void LLCallFloater::updateSession()
//hide "Leave Call" button for nearby chat
bool is_local_chat = mVoiceType == VC_LOCAL_CHAT;
childSetVisible("leave_call_btn_panel", !is_local_chat);
-
+
refreshParticipantList();
updateAgentModeratorState();
@@ -588,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;
}
}
@@ -658,33 +653,11 @@ void LLCallFloater::setState(LLAvatarListItem* item, ESpeakerState state)
void LLCallFloater::setVoiceRemoveTimer(const LLUUID& voice_speaker_id)
{
-
- // If there is already a started timer for the current panel don't do anything.
- bool no_timer_for_current_panel = true;
- if (mVoiceLeftTimersMap.size() > 0)
- {
- timers_map::iterator found_it = mVoiceLeftTimersMap.find(voice_speaker_id);
- if (found_it != mVoiceLeftTimersMap.end())
- {
- no_timer_for_current_panel = false;
- }
- }
-
- if (no_timer_for_current_panel)
- {
- // Starting a timer to remove an avatar row panel after timeout
- mVoiceLeftTimersMap.insert(timer_pair(voice_speaker_id,
- new LLAvatarListItemRemoveTimer(boost::bind(&LLCallFloater::removeVoiceLeftParticipant, this, _1), mVoiceLeftRemoveDelay, voice_speaker_id)));
- }
+ mSpeakerDelayRemover->setActionTimer(voice_speaker_id);
}
-void LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id)
+bool LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id)
{
- if (mVoiceLeftTimersMap.size() > 0)
- {
- mVoiceLeftTimersMap.erase(mVoiceLeftTimersMap.find(voice_speaker_id));
- }
-
LLAvatarList::uuid_vector_t& speaker_uuids = mAvatarList->getIDs();
LLAvatarList::uuid_vector_t::iterator pos = std::find(speaker_uuids.begin(), speaker_uuids.end(), voice_speaker_id);
if(pos != speaker_uuids.end())
@@ -692,34 +665,19 @@ void LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id)
speaker_uuids.erase(pos);
mAvatarList->setDirty();
}
+
+ return false;
}
void LLCallFloater::resetVoiceRemoveTimers()
{
- if (mVoiceLeftTimersMap.size() > 0)
- {
- for (timers_map::iterator iter = mVoiceLeftTimersMap.begin();
- iter != mVoiceLeftTimersMap.end(); ++iter)
- {
- delete iter->second;
- }
- }
- mVoiceLeftTimersMap.clear();
+ mSpeakerDelayRemover->removeAllTimers();
}
void LLCallFloater::removeVoiceRemoveTimer(const LLUUID& voice_speaker_id)
{
- // Remove the timer if it has been already started
- if (mVoiceLeftTimersMap.size() > 0)
- {
- timers_map::iterator found_it = mVoiceLeftTimersMap.find(voice_speaker_id);
- if (found_it != mVoiceLeftTimersMap.end())
- {
- delete found_it->second;
- mVoiceLeftTimersMap.erase(found_it);
- }
- }
+ mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id);
}
bool LLCallFloater::validateSpeaker(const LLUUID& speaker_id)
@@ -798,90 +756,4 @@ void LLCallFloater::reset()
mSpeakerManager = NULL;
}
-void reshape_floater(LLCallFloater* floater, S32 delta_height)
-{
- // Try to update floater top side if it is docked(to bottom bar).
- // Try to update floater bottom side or top side if it is un-docked.
- // If world rect is too small, floater will not be reshaped at all.
-
- LLRect floater_rect = floater->getRect();
- LLRect world_rect = gViewerWindow->getWorldViewRectScaled();
-
- // floater is docked to bottom bar
- if(floater->isDocked())
- {
- // can update floater top side
- if(floater_rect.mTop + delta_height < world_rect.mTop)
- {
- floater_rect.set(floater_rect.mLeft, floater_rect.mTop + delta_height,
- floater_rect.mRight, floater_rect.mBottom);
- }
- }
- // floater is un-docked
- else
- {
- // can update floater bottom side
- if( floater_rect.mBottom - delta_height >= world_rect.mBottom )
- {
- floater_rect.set(floater_rect.mLeft, floater_rect.mTop,
- floater_rect.mRight, floater_rect.mBottom - delta_height);
- }
- // could not update floater bottom side, check if we can update floater top side
- else if( floater_rect.mTop + delta_height < world_rect.mTop )
- {
- floater_rect.set(floater_rect.mLeft, floater_rect.mTop + delta_height,
- floater_rect.mRight, floater_rect.mBottom);
- }
- }
-
- floater->setShape(floater_rect);
- floater->getChild<LLLayoutStack>("my_call_stack")->updateLayout(FALSE);
-}
-
-void LLCallFloater::reshapeToFitContent()
-{
- const S32 ITEM_HEIGHT = getParticipantItemHeight();
- static const S32 MAX_VISIBLE_ITEMS = getMaxVisibleItems();
-
- static S32 items_pad = mAvatarList->getItemsPad();
- S32 list_height = mAvatarList->getRect().getHeight();
- S32 items_height = mAvatarList->getItemsRect().getHeight();
- if(items_height <= 0)
- {
- // make "no one near" text visible
- items_height = ITEM_HEIGHT + items_pad;
- }
- S32 max_list_height = MAX_VISIBLE_ITEMS * ITEM_HEIGHT + items_pad * (MAX_VISIBLE_ITEMS - 1);
- max_list_height += 2* mAvatarList->getBorderWidth();
-
- S32 delta = items_height - list_height;
- // too many items, don't reshape floater anymore, let scroll bar appear.
- if(items_height > max_list_height)
- {
- delta = max_list_height - list_height;
- }
-
- reshape_floater(this, delta);
-}
-
-S32 LLCallFloater::getParticipantItemHeight()
-{
- std::vector<LLPanel*> items;
- mAvatarList->getItems(items);
- if(items.size() > 0)
- {
- return items[0]->getRect().getHeight();
- }
- else
- {
- return getChild<LLPanel>("non_avatar_caller")->getRect().getHeight();
- }
-}
-
-S32 LLCallFloater::getMaxVisibleItems()
-{
- static LLCachedControl<S32> max_visible_items(*LLUI::sSettingGroups["config"],"CallFloaterMaxItems");
- return max_visible_items;
-}
-
//EOF
diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h
index 2b40225906..766191379b 100644
--- a/indra/newview/llcallfloater.h
+++ b/indra/newview/llcallfloater.h
@@ -44,6 +44,8 @@ class LLNonAvatarCaller;
class LLOutputMonitorCtrl;
class LLParticipantList;
class LLSpeakerMgr;
+class LLSpeakersDelayActionsStorage;
+
/**
* The Voice Control Panel is an ambient window summoned by clicking the flyout chevron on the Speak button.
* It can be torn-off and freely positioned onscreen.
@@ -75,11 +77,6 @@ public:
*/
/*virtual*/ void onChange();
- /**
- * Will reshape floater when participant list size changes
- */
- /*virtual*/ S32 notifyParent(const LLSD& info);
-
static void sOnCurrentChannelChanged(const LLUUID& session_id);
private:
@@ -148,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)
{
@@ -174,7 +175,7 @@ private:
*
* @param voice_speaker_id LLUUID of Avatar List item to be removed from the list.
*/
- void removeVoiceLeftParticipant(const LLUUID& voice_speaker_id);
+ bool removeVoiceLeftParticipant(const LLUUID& voice_speaker_id);
/**
* Deletes all timers from the list to prevent started timers from ticking after destruction
@@ -221,21 +222,6 @@ private:
*/
void reset();
- /**
- * Reshapes floater to fit participant list height
- */
- void reshapeToFitContent();
-
- /**
- * Returns height of participant list item
- */
- S32 getParticipantItemHeight();
-
- /**
- * Returns predefined max visible participants.
- */
- S32 getMaxVisibleItems();
-
private:
speaker_state_map_t mSpeakerStateMap;
LLSpeakerMgr* mSpeakerManager;
@@ -260,32 +246,11 @@ private:
boost::signals2::connection mAvatarListRefreshConnection;
+
/**
- * class LLAvatarListItemRemoveTimer
- *
- * Implements a timer that removes avatar list item of a participant
- * who has left the call.
+ * time out speakers when they are not part of current session
*/
- class LLAvatarListItemRemoveTimer : public LLEventTimer
- {
- public:
- typedef boost::function<void(const LLUUID&)> callback_t;
-
- LLAvatarListItemRemoveTimer(callback_t remove_cb, F32 period, const LLUUID& speaker_id);
- virtual ~LLAvatarListItemRemoveTimer() {};
-
- virtual BOOL tick();
-
- private:
- callback_t mRemoveCallback;
- LLUUID mSpeakerId;
- };
-
- typedef std::pair<LLUUID, LLAvatarListItemRemoveTimer*> timer_pair;
- typedef std::map<LLUUID, LLAvatarListItemRemoveTimer*> timers_map;
-
- timers_map mVoiceLeftTimersMap;
- S32 mVoiceLeftRemoveDelay;
+ LLSpeakersDelayActionsStorage* mSpeakerDelayRemover;
/**
* Stores reference to current voice channel.
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/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 5497d6121f..f1de4e2982 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -47,6 +47,7 @@
#include "llnotificationsutil.h"
#include "lloutputmonitorctrl.h"
#include "llscriptfloater.h"
+#include "llspeakers.h"
#include "lltextbox.h"
#include "llvoiceclient.h"
#include "llgroupmgr.h"
@@ -1271,6 +1272,7 @@ bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index)
chiclet->setChicletSizeChangedCallback(boost::bind(&LLChicletPanel::onChicletSizeChanged, this, _1, index));
arrange();
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, chiclet);
return true;
}
@@ -1298,6 +1300,7 @@ void LLChicletPanel::removeChiclet(chiclet_list_t::iterator it)
mChicletList.erase(it);
arrange();
+ LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, chiclet);
chiclet->die();
}
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/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index fb94657278..0e42ff09d8 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -51,6 +51,7 @@
#include "llinventorymodel.h"
#include "llfloaterworldmap.h"
#include "lllandmarkactions.h"
+#include "llnotificationsutil.h"
#include "llsidetray.h"
#include "lltoggleablemenu.h"
#include "llviewerinventory.h"
@@ -975,6 +976,10 @@ BOOL LLFavoritesBarCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
void copy_slurl_to_clipboard_cb(std::string& slurl)
{
gClipboard.copyFromString(utf8str_to_wstring(slurl));
+
+ LLSD args;
+ args["SLURL"] = slurl;
+ LLNotificationsUtil::add("CopySLURL", args);
}
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 e0f2fca580..4a1eb51dbe 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -277,13 +277,8 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)
{
object_owner.append("Unknown");
}
- childSetText("object_name", object_owner);
- std::string owner_link =
- LLSLURL::buildCommand("agent", mObjectID, "inspect");
- childSetText("owner_name", owner_link);
- childSetText("abuser_name_edit", object_owner);
- mAbuserID = object_id;
- mOwnerName = object_owner;
+
+ setFromAvatar(object_id, object_owner);
}
else
{
@@ -305,7 +300,6 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)
}
}
-
void LLFloaterReporter::onClickSelectAbuser()
{
gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE ));
@@ -323,6 +317,17 @@ void LLFloaterReporter::callbackAvatarID(const std::vector<std::string>& names,
}
+void LLFloaterReporter::setFromAvatar(const LLUUID& avatar_id, const std::string& avatar_name)
+{
+ mAbuserID = mObjectID = avatar_id;
+ mOwnerName = avatar_name;
+
+ std::string avatar_link = LLSLURL::buildCommand("agent", mObjectID, "inspect");
+ childSetText("owner_name", avatar_link);
+ childSetText("object_name", avatar_name);
+ childSetText("abuser_name_edit", avatar_name);
+}
+
// static
void LLFloaterReporter::onClickSend(void *userdata)
{
@@ -458,9 +463,8 @@ void LLFloaterReporter::showFromMenu(EReportType report_type)
}
}
-
// static
-void LLFloaterReporter::showFromObject(const LLUUID& object_id)
+void LLFloaterReporter::show(const LLUUID& object_id, const std::string& avatar_name)
{
LLFloaterReporter* f = LLFloaterReg::showTypedInstance<LLFloaterReporter>("reporter");
@@ -469,8 +473,11 @@ void LLFloaterReporter::showFromObject(const LLUUID& object_id)
LLAgentUI::buildFullname(fullname);
f->childSetText("reporter_field", fullname);
- // Request info for this object
- f->getObjectInfo(object_id);
+ if (avatar_name.empty())
+ // Request info for this object
+ f->getObjectInfo(object_id);
+ else
+ f->setFromAvatar(object_id, avatar_name);
// Need to deselect on close
f->mDeselectOnClose = TRUE;
@@ -479,6 +486,18 @@ void LLFloaterReporter::showFromObject(const LLUUID& object_id)
}
+// static
+void LLFloaterReporter::showFromObject(const LLUUID& object_id)
+{
+ show(object_id);
+}
+
+// static
+void LLFloaterReporter::showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name)
+{
+ show(avatar_id, avatar_name);
+}
+
void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id)
{
childSetText("object_name", object_name);
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index cc2dfb2f98..7c6473f975 100644
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -93,6 +93,7 @@ public:
static void showFromMenu(EReportType report_type);
static void showFromObject(const LLUUID& object_id);
+ static void showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name);
static void onClickSend (void *userdata);
static void onClickCancel (void *userdata);
@@ -109,6 +110,8 @@ public:
void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id);
private:
+ static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null);
+
void takeScreenshot();
void sendReportViaCaps(std::string url);
void uploadImage();
@@ -121,6 +124,7 @@ private:
void enableControls(BOOL own_avatar);
void getObjectInfo(const LLUUID& object_id);
void callbackAvatarID(const std::vector<std::string>& names, const std::vector<LLUUID>& ids);
+ void setFromAvatar(const LLUUID& avatar_id, const std::string& avatar_name = LLStringUtil::null);
private:
EReportType mReportType;
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/llfolderview.cpp b/indra/newview/llfolderview.cpp
index a63fb73032..b833c611bf 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -1391,6 +1391,7 @@ void LLFolderView::startRenamingSelectedItem( void )
// set focus will fail unless item is visible
mRenamer->setFocus( TRUE );
mRenamer->setTopLostCallback(boost::bind(onRenamerLost, _1));
+ mRenamer->setFocusLostCallback(boost::bind(onRenamerLost, _1));
gFocusMgr.setTopCtrl( mRenamer );
}
}
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 82293b4aa0..0ba7bdf613 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -98,6 +98,41 @@ void LLGestureManager::init()
// TODO
}
+void LLGestureManager::changed(U32 mask)
+{
+ LLInventoryFetchObserver::changed(mask);
+
+ if (mask & LLInventoryObserver::GESTURE)
+ {
+ // If there was a gesture label changed, update all the names in the
+ // active gestures and then notify observers
+ if (mask & LLInventoryObserver::LABEL)
+ {
+ for(item_map_t::iterator it = mActive.begin(); it != mActive.end(); ++it)
+ {
+ if(it->second)
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(it->first);
+ if(item)
+ {
+ it->second->mName = item->getName();
+ }
+ }
+ }
+ notifyObservers();
+ }
+ // If there was a gesture added or removed notify observers
+ // STRUCTURE denotes that the inventory item has been moved
+ // In the case of deleting gesture, it is moved to the trash
+ else if(mask & LLInventoryObserver::ADD ||
+ mask & LLInventoryObserver::REMOVE ||
+ mask & LLInventoryObserver::STRUCTURE)
+ {
+ notifyObservers();
+ }
+ }
+}
+
// Use this version when you have the item_id but not the asset_id,
// and you KNOW the inventory is loaded.
diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h
index c562587c6f..3dd184ddc7 100644
--- a/indra/newview/llgesturemgr.h
+++ b/indra/newview/llgesturemgr.h
@@ -140,6 +140,9 @@ public:
void removeObserver(LLGestureManagerObserver* observer);
void notifyObservers();
+ // Overriding so we can update active gesture names and notify observers
+ void changed(U32 mask);
+
BOOL matchPrefix(const std::string& in_str, std::string* out_str);
// Copy item ids into the vector
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/llimfloater.cpp b/indra/newview/llimfloater.cpp
index d7c60ff34e..73597e7de3 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -58,6 +58,7 @@
#include "llinventorymodel.h"
#include "llrootview.h"
+#include "llspeakers.h"
LLIMFloater::LLIMFloater(const LLUUID& session_id)
@@ -109,6 +110,8 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
}
}
setOverlapsScreenChannel(true);
+
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
}
void LLIMFloater::onFocusLost()
@@ -227,6 +230,7 @@ void LLIMFloater::sendMsg()
LLIMFloater::~LLIMFloater()
{
+ LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
}
//virtual
@@ -350,13 +354,15 @@ void* LLIMFloater::createPanelAdHocControl(void* userdata)
void LLIMFloater::onSlide()
{
- LLPanel* im_control_panel = getChild<LLPanel>("panel_im_control_panel");
- im_control_panel->setVisible(!im_control_panel->getVisible());
+ mControlPanel->setVisible(!mControlPanel->getVisible());
+
+ gSavedSettings.setBOOL("IMShowControlPanel", mControlPanel->getVisible());
- gSavedSettings.setBOOL("IMShowControlPanel", im_control_panel->getVisible());
+ getChild<LLButton>("slide_left_btn")->setVisible(mControlPanel->getVisible());
+ getChild<LLButton>("slide_right_btn")->setVisible(!mControlPanel->getVisible());
- getChild<LLButton>("slide_left_btn")->setVisible(im_control_panel->getVisible());
- getChild<LLButton>("slide_right_btn")->setVisible(!im_control_panel->getVisible());
+ LLLayoutStack* stack = getChild<LLLayoutStack>("im_panels");
+ if (stack) stack->setAnimate(true);
}
//static
@@ -510,14 +516,14 @@ bool LLIMFloater::toggle(const LLUUID& session_id)
if(!isChatMultiTab())
{
LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
- if (floater && floater->getVisible())
+ if (floater && floater->getVisible() && floater->hasFocus())
{
// clicking on chiclet to close floater just hides it to maintain existing
// scroll/text entry state
floater->setVisible(false);
return false;
}
- else if(floater && !floater->isDocked())
+ else if(floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus()))
{
floater->setVisible(TRUE);
floater->setFocus(TRUE);
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index d9db385d06..0ca0325451 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -116,6 +116,8 @@ public:
static void onIMChicletCreated(const LLUUID& session_id);
+ virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
+
private:
// process focus events to set a currently active session
/* virtual */ void onFocusLost();
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 6cc985aef4..06a7b4a29c 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -35,19 +35,22 @@
#include "llimfloatercontainer.h"
#include "llfloaterreg.h"
+#include "llimview.h"
+#include "llavatariconctrl.h"
+#include "llagent.h"
//
// LLIMFloaterContainer
//
LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
-: LLMultiFloater(seed),
- mActiveVoiceFloater(NULL)
+: LLMultiFloater(seed)
{
mAutoResize = FALSE;
}
LLIMFloaterContainer::~LLIMFloaterContainer()
{
+ LLGroupMgr::getInstance()->removeObserver(this);
}
BOOL LLIMFloaterContainer::postBuild()
@@ -87,13 +90,84 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
- // make sure active voice icon shows up for new tab
- if (floaterp == mActiveVoiceFloater)
+ LLUUID session_id = floaterp->getKey();
+
+ if(gAgent.isInGroup(session_id))
+ {
+ mSessions[session_id] = floaterp;
+ mID = session_id;
+ mGroupID.push_back(session_id);
+ LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(session_id);
+ LLGroupMgr* gm = LLGroupMgr::getInstance();
+ gm->addObserver(this);
+
+ if (group_data && group_data->mInsigniaID.notNull())
+ {
+ mTabContainer->setTabImage(get_ptr_in_map(mSessions, session_id), group_data->mInsigniaID);
+ }
+ else
+ {
+ gm->sendGroupPropertiesRequest(session_id);
+ }
+ }
+ else
+ {
+ LLUUID avatar_id = LLIMModel::getInstance()->getOtherParticipantID(session_id);
+ LLAvatarPropertiesProcessor& app = LLAvatarPropertiesProcessor::instance();
+ app.addObserver(avatar_id, this);
+ floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, avatar_id));
+ mSessions[avatar_id] = floaterp;
+
+ LLUUID* icon_id_ptr = LLAvatarIconIDCache::getInstance()->get(avatar_id);
+ if(!icon_id_ptr)
+ {
+ app.sendAvatarPropertiesRequest(avatar_id);
+ }
+ else
+ {
+ mTabContainer->setTabImage(floaterp, *icon_id_ptr);
+ }
+ }
+}
+
+void LLIMFloaterContainer::processProperties(void* data, enum EAvatarProcessorType type)
+{
+ if (APT_PROPERTIES == type)
+ {
+ LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data);
+ if (avatar_data)
+ {
+ LLUUID avatar_id = avatar_data->avatar_id;
+ if(avatar_data->image_id != *LLAvatarIconIDCache::getInstance()->get(avatar_id))
+ {
+ LLAvatarIconIDCache::getInstance()->add(avatar_id,avatar_data->image_id);
+ }
+ mTabContainer->setTabImage(get_ptr_in_map(mSessions, avatar_id), avatar_data->image_id);
+ }
+ }
+}
+
+void LLIMFloaterContainer::changed(LLGroupChange gc)
+{
+ if (GC_PROPERTIES == gc)
{
- mTabContainer->setTabImage(floaterp, "active_voice_tab.tga");
+ for(groupIDs_t::iterator it = mGroupID.begin(); it!=mGroupID.end(); it++)
+ {
+ LLUUID group_id = *it;
+ LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(group_id);
+ if (group_data && group_data->mInsigniaID.notNull())
+ {
+ mTabContainer->setTabImage(get_ptr_in_map(mSessions, group_id), group_data->mInsigniaID);
+ }
+ }
}
}
+void LLIMFloaterContainer::onCloseFloater(LLUUID id)
+{
+ LLAvatarPropertiesProcessor::instance().removeObserver(id, this);
+}
+
LLIMFloaterContainer* LLIMFloaterContainer::findInstance()
{
return LLFloaterReg::findTypedInstance<LLIMFloaterContainer>("im_container");
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index d4a542dfc2..1333b098bc 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -33,12 +33,17 @@
#ifndef LL_LLIMFLOATERCONTAINER_H
#define LL_LLIMFLOATERCONTAINER_H
+#include <map>
+#include <vector>
+
#include "llfloater.h"
#include "llmultifloater.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llgroupmgr.h"
class LLTabContainer;
-class LLIMFloaterContainer : public LLMultiFloater
+class LLIMFloaterContainer : public LLMultiFloater, public LLAvatarPropertiesObserver, public LLGroupMgrObserver
{
public:
LLIMFloaterContainer(const LLSD& seed);
@@ -51,15 +56,23 @@ public:
BOOL select_added_floater,
LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
+ void processProperties(void* data, EAvatarProcessorType type);
+ void changed(LLGroupChange gc);
+
static LLFloater* getCurrentVoiceFloater();
static LLIMFloaterContainer* findInstance();
static LLIMFloaterContainer* getInstance();
-protected:
-
- LLFloater* mActiveVoiceFloater;
+private:
+ typedef std::map<LLUUID,LLPanel*> avatarID_panel_map_t;
+ avatarID_panel_map_t mSessions;
+
+ typedef std::vector<LLUUID> groupIDs_t;
+ groupIDs_t mGroupID;
+
+ void onCloseFloater(LLUUID avatar_id);
};
#endif // LL_LLIMFLOATERCONTAINER_H
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 9a6115dd63..4bdf5f42dc 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -40,6 +40,7 @@
#include "llfontgl.h"
#include "llrect.h"
#include "llerror.h"
+#include "llmultifloater.h"
#include "llstring.h"
#include "message.h"
#include "lltextbox.h"
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 3ff156eca3..f90a51c3f3 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -42,47 +42,31 @@
#include "llhttpclient.h"
#include "llsdutil_math.h"
#include "llstring.h"
+#include "lltrans.h"
#include "lluictrlfactory.h"
#include "llagent.h"
+#include "llagentui.h"
#include "llappviewer.h"
#include "llavatariconctrl.h"
#include "llbottomtray.h"
#include "llcallingcard.h"
#include "llchat.h"
-#include "llchiclet.h"
-#include "llresmgr.h"
#include "llfloaterchatterbox.h"
-#include "llavataractions.h"
-#include "llhttpnode.h"
#include "llimfloater.h"
-#include "llimpanel.h"
#include "llgroupiconctrl.h"
-#include "llresizebar.h"
-#include "lltabcontainer.h"
-#include "llviewercontrol.h"
-#include "llfloater.h"
+#include "llmd5.h"
#include "llmutelist.h"
-#include "llresizehandle.h"
-#include "llkeyboard.h"
-#include "llui.h"
-#include "llviewermenu.h"
-#include "llcallingcard.h"
-#include "lltoolbar.h"
+#include "llrecentpeople.h"
#include "llviewermessage.h"
#include "llviewerwindow.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llnearbychat.h"
-#include "llviewerregion.h"
-#include "llvoicechannel.h"
-#include "lltrans.h"
-#include "llrecentpeople.h"
-#include "llsyswellwindow.h"
-
-//#include "llfirstuse.h"
-#include "llagentui.h"
+#include "llspeakers.h" //for LLIMSpeakerMgr
#include "lltextutil.h"
+#include "llviewercontrol.h"
+
const static std::string IM_TIME("time");
const static std::string IM_TEXT("message");
@@ -111,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;
}
@@ -232,12 +217,14 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionID);
}
+ buildHistoryFileName();
+
if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
{
std::list<LLSD> chat_history;
//involves parsing of a chat history
- LLLogChat::loadAllHistory(mName, chat_history);
+ LLLogChat::loadAllHistory(mHistoryFileName, chat_history);
addMessagesFromHistory(chat_history);
}
}
@@ -484,6 +471,44 @@ bool LLIMModel::LLIMSession::isOtherParticipantAvaline()
return !mOtherParticipantIsAvatar;
}
+void LLIMModel::LLIMSession::buildHistoryFileName()
+{
+ mHistoryFileName = mName;
+
+ //ad-hoc requires sophisticated chat history saving schemes
+ if (isAdHoc())
+ {
+ //in case of outgoing ad-hoc sessions
+ if (mInitialTargetIDs.size())
+ {
+ std::set<LLUUID> sorted_uuids(mInitialTargetIDs.begin(), mInitialTargetIDs.end());
+ mHistoryFileName = mName + " hash" + generateHash(sorted_uuids);
+ return;
+ }
+
+ //in case of incoming ad-hoc sessions
+ mHistoryFileName = mName + " " + LLLogChat::timestamp(true) + " " + mSessionID.asString().substr(0, 4);
+ }
+}
+
+//static
+std::string LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_uuids)
+{
+ LLMD5 md5_uuid;
+
+ std::set<LLUUID>::const_iterator it = sorted_uuids.begin();
+ while (it != sorted_uuids.end())
+ {
+ md5_uuid.update((unsigned char*)(*it).mData, 16);
+ it++;
+ }
+ md5_uuid.finalize();
+
+ LLUUID participants_md5_hash;
+ md5_uuid.raw_digest((unsigned char*) participants_md5_hash.mData);
+ return participants_md5_hash.asString();
+}
+
void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, const LLUUID& new_session_id)
{
@@ -631,11 +656,11 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,
return true;
}
-bool LLIMModel::logToFile(const std::string& session_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
+bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
{
if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
{
- LLLogChat::saveHistory(session_name, from, from_id, utf8_text);
+ LLLogChat::saveHistory(file_name, from, from_id, utf8_text);
return true;
}
else
@@ -646,15 +671,7 @@ bool LLIMModel::logToFile(const std::string& session_name, const std::string& fr
bool LLIMModel::logToFile(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
{
- if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
- {
- LLLogChat::saveHistory(LLIMModel::getInstance()->getName(session_id), from, from_id, utf8_text);
- return true;
- }
- else
- {
- return false;
- }
+ return logToFile(LLIMModel::getInstance()->getHistoryFileName(session_id), from, from_id, utf8_text);
}
bool LLIMModel::proccessOnlineOfflineNotification(
@@ -799,6 +816,18 @@ LLIMSpeakerMgr* LLIMModel::getSpeakerManager( const LLUUID& session_id ) const
return session->mSpeakers;
}
+const std::string& LLIMModel::getHistoryFileName(const LLUUID& session_id) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << " does not exist " << llendl;
+ return LLStringUtil::null;
+ }
+
+ return session->mHistoryFileName;
+}
+
// TODO get rid of other participant ID
void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing)
@@ -1549,7 +1578,7 @@ void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id)
}
}
-bool LLOutgoingCallDialog::lifetimeHasExpired()
+bool LLCallDialog::lifetimeHasExpired()
{
if (mLifetimeTimer.getStarted())
{
@@ -1562,7 +1591,7 @@ bool LLOutgoingCallDialog::lifetimeHasExpired()
return false;
}
-void LLOutgoingCallDialog::onLifetimeExpired()
+void LLCallDialog::onLifetimeExpired()
{
mLifetimeTimer.stop();
closeFloater();
@@ -1652,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 :
@@ -1664,6 +1694,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
getChild<LLTextBox>("nearby")->setVisible(true);
}
getChild<LLButton>("Cancel")->setVisible(false);
+ setCanClose(true);
mLifetimeTimer.start();
}
@@ -1714,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
@@ -3188,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 e72bda6c2b..0386ff234d 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -33,22 +33,19 @@
#ifndef LL_LLIMVIEW_H
#define LL_LLIMVIEW_H
-#include "lldarray.h"
-#include "lldockablefloater.h"
-#include "llspeakers.h" //for LLIMSpeakerMgr
-#include "llimpanel.h" //for voice channels
-#include "llmodaldialog.h"
#include "lldockablefloater.h"
#include "llinstantmessage.h"
-#include "lluuid.h"
-#include "llmultifloater.h"
+
#include "lllogchat.h"
+#include "llvoicechannel.h"
class LLFloaterChatterBox;
class LLUUID;
class LLFloaterIMPanel;
class LLFriendObserver;
class LLCallDialogManager;
+class LLIMSpeakerMgr;
+
class LLIMModel : public LLSingleton<LLIMModel>
{
@@ -72,6 +69,8 @@ public:
void addMessagesFromHistory(const std::list<LLSD>& history);
void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time);
void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction);
+
+ /** @deprecated */
static void chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata);
bool isAdHoc();
@@ -83,12 +82,20 @@ public:
bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;}
bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;}
+ //*TODO make private
+ /** ad-hoc sessions involve sophisticated chat history file naming schemes */
+ void buildHistoryFileName();
+
+ //*TODO make private
+ static std::string generateHash(const std::set<LLUUID>& sorted_uuids);
+
LLUUID mSessionID;
std::string mName;
EInstantMessage mType;
SType mSessionType;
LLUUID mOtherParticipantID;
std::vector<LLUUID> mInitialTargetIDs;
+ std::string mHistoryFileName;
// connection to voice channel state change signal
boost::signals2::connection mVoiceChannelStateChangeConnection;
@@ -234,6 +241,8 @@ public:
*/
LLIMSpeakerMgr* getSpeakerManager(const LLUUID& session_id) const;
+ const std::string& getHistoryFileName(const LLUUID& session_id) const;
+
static void sendLeaveSession(const LLUUID& session_id, const LLUUID& other_participant_id);
static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id,
const std::vector<LLUUID>& ids, EInstantMessage dialog);
@@ -246,7 +255,7 @@ public:
/**
* Saves an IM message into a file
*/
- bool logToFile(const std::string& session_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
+ bool logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
private:
@@ -503,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);
@@ -534,7 +543,6 @@ public:
static void onStartIM(void* user_data);
private:
- /*virtual*/ bool lifetimeHasExpired();
/*virtual*/ void onLifetimeExpired();
void processCallResponse(S32 response);
};
@@ -553,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 0374a1d25b..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));
@@ -689,7 +690,7 @@ void LLInspectAvatar::onToggleMute()
void LLInspectAvatar::onClickReport()
{
- LLFloaterReporter::showFromObject(mAvatarID);
+ LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName);
closeFloater();
}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 099f863dc9..6c9c7d15be 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -185,6 +185,11 @@ BOOL LLInvFVBridge::isItemRemovable()
{
return FALSE;
}
+ if (LLAppearanceManager::instance().getIsProtectedCOFItem(mUUID))
+ {
+ return FALSE;
+ }
+
const LLInventoryObject *obj = model->getItem(mUUID);
if (obj && obj->getIsLinkType())
{
@@ -574,8 +579,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
disabled_items.push_back(std::string("Paste As Link"));
}
}
- items.push_back(std::string("Paste Separator"));
+ items.push_back(std::string("Paste Separator"));
if (obj && obj->getIsLinkType() && !get_is_item_worn(mUUID))
{
@@ -712,14 +717,7 @@ BOOL LLInvFVBridge::isAgentInventory() const
BOOL LLInvFVBridge::isCOFFolder() const
{
- const LLInventoryModel* model = getInventoryModel();
- if(!model) return TRUE;
- const LLUUID cof_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
- if (mUUID == cof_id || model->isObjectDescendentOf(mUUID, cof_id))
- {
- return TRUE;
- }
- return FALSE;
+ return LLAppearanceManager::instance().getIsInCOF(mUUID);
}
BOOL LLInvFVBridge::isItemPermissive() const
@@ -3687,18 +3685,6 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
return rv;
}
-BOOL LLCallingCardBridge::removeItem()
-{
- if (LLFriendCardsManager::instance().isItemInAnyFriendsList(getItem()))
- {
- LLAvatarActions::removeFriendDialog(getItem()->getCreatorUUID());
- return FALSE;
- }
- else
- {
- return LLItemBridge::removeItem();
- }
-}
// +=================================================+
// | LLNotecardBridge |
// +=================================================+
@@ -3810,8 +3796,25 @@ void LLGestureBridge::openItem()
BOOL LLGestureBridge::removeItem()
{
- // Force close the preview window, if it exists
- LLGestureManager::instance().deactivateGesture(mUUID);
+ // Grab class information locally since *this may be deleted
+ // within this function. Not a great pattern...
+ const LLInventoryModel* model = getInventoryModel();
+ if(!model)
+ {
+ return FALSE;
+ }
+ const LLUUID item_id = mUUID;
+
+ // This will also force close the preview window, if it exists.
+ // This may actually delete *this, if mUUID is in the COF.
+ LLGestureManager::instance().deactivateGesture(item_id);
+
+ // If deactivateGesture deleted *this, then return out immediately.
+ if (!model->getObject(item_id))
+ {
+ return TRUE;
+ }
+
return LLItemBridge::removeItem();
}
@@ -4605,7 +4608,10 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
getClipboardEntries(true, items, disabled_items, flags);
- items.push_back(std::string("Wearable Separator"));
+ if (!is_sidepanel)
+ {
+ items.push_back(std::string("Wearable Separator"));
+ }
items.push_back(std::string("Wearable Edit"));
@@ -5070,8 +5076,12 @@ void LLLandmarkBridgeAction::doIt()
// Opening (double-clicking) a landmark immediately teleports,
// but warns you the first time.
LLSD payload;
- payload["asset_id"] = item->getAssetUUID();
- LLNotificationsUtil::add("TeleportFromLandmark", LLSD(), payload);
+ payload["asset_id"] = item->getAssetUUID();
+
+ LLSD args;
+ args["LOCATION"] = item->getDisplayName();
+
+ LLNotificationsUtil::add("TeleportFromLandmark", args, payload);
}
LLInvFVBridgeAction::doIt();
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index fced0047e8..759d0cba18 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -448,7 +448,6 @@ public:
EDragAndDropType cargo_type,
void* cargo_data);
void refreshFolderViewItem();
- BOOL removeItem();
protected:
LLCallingCardBridge( LLInventoryPanel* inventory, const LLUUID& uuid );
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index e44adfb511..961f7adc0a 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -755,6 +755,10 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)
gCacheName->get(id, FALSE, boost::bind(&LLViewerInventoryItem::onCallingCardNameLookup, new_item.get(), _1, _2, _3));
}
}
+ else if (new_item->getType() == LLAssetType::AT_GESTURE)
+ {
+ mask |= LLInventoryObserver::GESTURE;
+ }
addChangedMask(mask, new_item->getUUID());
return mask;
}
diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h
index c1f192e2bf..d6dded52d4 100644
--- a/indra/newview/llinventoryobserver.h
+++ b/indra/newview/llinventoryobserver.h
@@ -61,8 +61,9 @@ public:
REMOVE = 8, // something deleted
STRUCTURE = 16, // structural change (eg item or folder moved)
CALLING_CARD = 32, // (eg online, grant status, cancel)
- REBUILD = 64, // item UI changed (eg item type different)
- SORT = 128, // folder needs to be resorted.
+ GESTURE = 64,
+ REBUILD = 128, // item UI changed (eg item type different)
+ SORT = 256, // folder needs to be resorted.
ALL = 0xffffffff
};
LLInventoryObserver();
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 9141d50829..7e71ac90b4 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -682,6 +682,14 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc
mFolders->setSelectionByID(obj_id, take_keyboard_focus);
}
+void LLInventoryPanel::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)
+{
+ if (mFolders)
+ {
+ mFolders->setSelectCallback(cb);
+ }
+}
+
void LLInventoryPanel::clearSelection()
{
mFolders->clearSelection();
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 09533b52f1..ccff795a51 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -123,7 +123,7 @@ public:
// Call this method to set the selection.
void openAllFolders();
void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);
- void setSelectCallback(const LLFolderView::signal_t::slot_type& cb) { if (mFolders) mFolders->setSelectCallback(cb); }
+ void setSelectCallback(const LLFolderView::signal_t::slot_type& cb);
void clearSelection();
LLInventoryFilter* getFilter();
void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT);
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 404e266806..7f49a7defb 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -43,8 +43,11 @@
#include "lltrans.h"
#include "lluictrlfactory.h"
#include "lltooltip.h"
+#include "llnotificationsutil.h"
+#include "llregionflags.h"
// newview includes
+#include "llagent.h"
#include "llinventoryobserver.h"
#include "lllandmarkactions.h"
#include "lllandmarklist.h"
@@ -56,6 +59,7 @@
#include "lltrans.h"
#include "llviewerinventory.h"
#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
#include "llviewercontrol.h"
#include "llviewermenu.h"
#include "llurllineeditorctrl.h"
@@ -256,36 +260,42 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
voice_icon.tool_tip = LLTrans::getString("LocationCtrlVoiceTooltip");
voice_icon.mouse_opaque = true;
mParcelIcon[VOICE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(voice_icon);
+ mParcelIcon[VOICE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, VOICE_ICON));
addChild(mParcelIcon[VOICE_ICON]);
LLIconCtrl::Params fly_icon = p.fly_icon;
fly_icon.tool_tip = LLTrans::getString("LocationCtrlFlyTooltip");
fly_icon.mouse_opaque = true;
mParcelIcon[FLY_ICON] = LLUICtrlFactory::create<LLIconCtrl>(fly_icon);
+ mParcelIcon[FLY_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, FLY_ICON));
addChild(mParcelIcon[FLY_ICON]);
LLIconCtrl::Params push_icon = p.push_icon;
push_icon.tool_tip = LLTrans::getString("LocationCtrlPushTooltip");
push_icon.mouse_opaque = true;
mParcelIcon[PUSH_ICON] = LLUICtrlFactory::create<LLIconCtrl>(push_icon);
+ mParcelIcon[PUSH_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PUSH_ICON));
addChild(mParcelIcon[PUSH_ICON]);
LLIconCtrl::Params build_icon = p.build_icon;
build_icon.tool_tip = LLTrans::getString("LocationCtrlBuildTooltip");
build_icon.mouse_opaque = true;
mParcelIcon[BUILD_ICON] = LLUICtrlFactory::create<LLIconCtrl>(build_icon);
+ mParcelIcon[BUILD_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, BUILD_ICON));
addChild(mParcelIcon[BUILD_ICON]);
LLIconCtrl::Params scripts_icon = p.scripts_icon;
scripts_icon.tool_tip = LLTrans::getString("LocationCtrlScriptsTooltip");
scripts_icon.mouse_opaque = true;
mParcelIcon[SCRIPTS_ICON] = LLUICtrlFactory::create<LLIconCtrl>(scripts_icon);
+ mParcelIcon[SCRIPTS_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, SCRIPTS_ICON));
addChild(mParcelIcon[SCRIPTS_ICON]);
LLIconCtrl::Params damage_icon = p.damage_icon;
damage_icon.tool_tip = LLTrans::getString("LocationCtrlDamageTooltip");
damage_icon.mouse_opaque = true;
mParcelIcon[DAMAGE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(damage_icon);
+ mParcelIcon[DAMAGE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, DAMAGE_ICON));
addChild(mParcelIcon[DAMAGE_ICON]);
LLTextBox::Params damage_text = p.damage_text;
@@ -918,3 +928,45 @@ bool LLLocationInputCtrl::onLocationContextMenuItemEnabled(const LLSD& userdata)
return false;
}
+
+void LLLocationInputCtrl::onParcelIconClick(EParcelIcon icon)
+{
+ switch (icon)
+ {
+ case VOICE_ICON:
+ LLNotificationsUtil::add("NoVoice");
+ break;
+ case FLY_ICON:
+ LLNotificationsUtil::add("NoFly");
+ break;
+ case PUSH_ICON:
+ LLNotificationsUtil::add("PushRestricted");
+ break;
+ case BUILD_ICON:
+ LLNotificationsUtil::add("NoBuild");
+ break;
+ case SCRIPTS_ICON:
+ {
+ LLViewerRegion* region = gAgent.getRegion();
+ if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
+ {
+ LLNotificationsUtil::add("ScriptsStopped");
+ }
+ else if(region && region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
+ {
+ LLNotificationsUtil::add("ScriptsNotRunning");
+ }
+ else
+ {
+ LLNotificationsUtil::add("NoOutsideScripts");
+ }
+ break;
+ }
+ case DAMAGE_ICON:
+ LLNotificationsUtil::add("NotSafe");
+ break;
+ case ICON_COUNT:
+ break;
+ // no default to get compiler warning when a new icon gets added
+ }
+}
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
index 7959fab2de..607ccd4da6 100644
--- a/indra/newview/lllocationinputctrl.h
+++ b/indra/newview/lllocationinputctrl.h
@@ -102,6 +102,18 @@ public:
void handleLoginComplete();
private:
+
+ enum EParcelIcon
+ {
+ VOICE_ICON = 0,
+ FLY_ICON,
+ PUSH_ICON,
+ BUILD_ICON,
+ SCRIPTS_ICON,
+ DAMAGE_ICON,
+ ICON_COUNT
+ };
+
friend class LLUICtrlFactory;
LLLocationInputCtrl(const Params&);
virtual ~LLLocationInputCtrl();
@@ -138,6 +150,7 @@ private:
// callbacks
bool onLocationContextMenuItemEnabled(const LLSD& userdata);
void onLocationContextMenuItemClicked(const LLSD& userdata);
+ void onParcelIconClick(EParcelIcon icon);
LLMenuGL* mLocationContextMenu;
LLButton* mAddLandmarkBtn;
@@ -146,16 +159,6 @@ private:
S32 mIconHPad; // pad between all icons
S32 mAddLandmarkHPad; // pad to left of landmark star
- enum EParcelIcon
- {
- VOICE_ICON = 0,
- FLY_ICON,
- PUSH_ICON,
- BUILD_ICON,
- SCRIPTS_ICON,
- DAMAGE_ICON,
- ICON_COUNT
- };
LLIconCtrl* mParcelIcon[ICON_COUNT];
LLTextBox* mDamageText;
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 4e5aaeb66a..dc187bf36c 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -237,15 +237,15 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
messages.back()[IM_TEXT] = im_text;
}
-void LLLogChat::loadAllHistory(const std::string& session_name, std::list<LLSD>& messages)
+void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& messages)
{
- if (session_name.empty())
+ if (file_name.empty())
{
llwarns << "Session name is Empty!" << llendl;
return ;
}
- LLFILE* fptr = LLFile::fopen(makeLogFileName(session_name), "r"); /*Flawfinder: ignore*/
+ LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r"); /*Flawfinder: ignore*/
if (!fptr) return; //No previous conversation with this name.
char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index 3d3f5c4458..4290e4bbc0 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -56,7 +56,7 @@ public:
void (*callback)(ELogLineType, const LLSD&, void*),
void* userdata);
- static void loadAllHistory(const std::string& session_name, std::list<LLSD>& messages);
+ static void loadAllHistory(const std::string& file_name, std::list<LLSD>& messages);
private:
static std::string cleanFileName(std::string filename);
};
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 87ebce1d34..d464862eed 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -870,38 +870,6 @@ void LLMediaCtrl::convertInputCoords(S32& x, S32& y)
}
////////////////////////////////////////////////////////////////////////////////
-// static
-bool LLMediaCtrl::onClickLinkExternalTarget(const LLSD& notification, const LLSD& response )
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if ( 0 == option )
- {
- LLSD payload = notification["payload"];
- std::string url = payload["url"].asString();
- S32 target_type = payload["target_type"].asInteger();
-
- switch (target_type)
- {
- case LLPluginClassMedia::TARGET_EXTERNAL:
- // load target in an external browser
- LLWeb::loadURLExternal(url);
- break;
-
- case LLPluginClassMedia::TARGET_BLANK:
- // load target in the user's preferred browser
- LLWeb::loadURL(url);
- break;
-
- default:
- // unsupported link target - shouldn't happen
- LL_WARNS("LinkTarget") << "Unsupported link target type" << LL_ENDL;
- break;
- }
- }
- return false;
-}
-
-////////////////////////////////////////////////////////////////////////////////
// inherited from LLViewerMediaObserver
//virtual
void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
@@ -1014,44 +982,83 @@ void LLMediaCtrl::onClickLinkHref( LLPluginClassMedia* self )
U32 target_type = self->getClickTargetType();
// is there is a target specified for the link?
- if (target_type == LLPluginClassMedia::TARGET_EXTERNAL ||
- target_type == LLPluginClassMedia::TARGET_BLANK)
+ if (gSavedSettings.getBOOL("UseExternalBrowser") || target_type == LLPluginClassMedia::TARGET_EXTERNAL)
{
LLSD payload;
payload["url"] = url;
payload["target_type"] = LLSD::Integer(target_type);
LLNotificationsUtil::add( "WebLaunchExternalTarget", LLSD(), payload, onClickLinkExternalTarget);
- return;
}
-
- const std::string protocol1( "http://" );
- const std::string protocol2( "https://" );
- if( mOpenLinksInExternalBrowser )
+ else if (target_type == LLPluginClassMedia::TARGET_BLANK)
{
- if ( !url.empty() )
+ clickLinkWithTarget(url, target_type);
+ }
+ else {
+ const std::string protocol1( "http://" );
+ const std::string protocol2( "https://" );
+ if( mOpenLinksInExternalBrowser )
{
- if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
- LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
+ if ( !url.empty() )
{
- LLWeb::loadURLExternal( url );
+ if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
+ LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
+ {
+ LLWeb::loadURLExternal( url );
+ }
}
}
- }
- else
- if( mOpenLinksInInternalBrowser )
- {
- if ( !url.empty() )
+ else
+ if( mOpenLinksInInternalBrowser )
{
- if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
- LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
+ if ( !url.empty() )
{
- llwarns << "Dead, unimplemented path that we used to send to the built-in browser long ago." << llendl;
+ if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
+ LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
+ {
+ llwarns << "Dead, unimplemented path that we used to send to the built-in browser long ago." << llendl;
+ }
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
+// static
+bool LLMediaCtrl::onClickLinkExternalTarget(const LLSD& notification, const LLSD& response )
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if ( 0 == option )
+ {
+ LLSD payload = notification["payload"];
+ std::string url = payload["url"].asString();
+ S32 target_type = payload["target_type"].asInteger();
+ clickLinkWithTarget(url, target_type);
+ }
+ return false;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+void LLMediaCtrl::clickLinkWithTarget(const std::string& url, const S32& target_type )
+{
+ if (gSavedSettings.getBOOL("UseExternalBrowser") || target_type == LLPluginClassMedia::TARGET_EXTERNAL)
+ {
+ // load target in an external browser
+ LLWeb::loadURLExternal(url);
+ }
+ else if (target_type == LLPluginClassMedia::TARGET_BLANK)
+ {
+ // load target in the user's preferred browser
+ LLWeb::loadURL(url);
+ }
+ else {
+ // unsupported link target - shouldn't happen
+ LL_WARNS("LinkTarget") << "Unsupported link target type" << LL_ENDL;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
//
void LLMediaCtrl::onClickLinkNoFollow( LLPluginClassMedia* self )
{
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index b0aca3cfa4..60e0c4073b 100644
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -172,6 +172,7 @@ public:
private:
void onVisibilityChange ( const LLSD& new_visibility );
static bool onClickLinkExternalTarget( const LLSD&, const LLSD& );
+ static void clickLinkWithTarget(const std::string& url, const S32& target_type );
const S32 mTextureDepthBytes;
LLUUID mMediaTextureID;
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 cf4a08ce76..c1666f5666 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -52,22 +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"
@@ -218,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
@@ -714,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);
@@ -750,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/llpanelface.cpp b/indra/newview/llpanelface.cpp
index ee0426c7df..8c5208678e 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -65,6 +65,7 @@
#include "llvovolume.h"
#include "lluictrlfactory.h"
#include "llpluginclassmedia.h"
+#include "llviewertexturelist.h"
//
// Methods
@@ -406,14 +407,40 @@ void LLPanelFace::getState()
LLUUID id;
struct f1 : public LLSelectedTEGetFunctor<LLUUID>
{
- LLUUID get(LLViewerObject* object, S32 te)
+ LLUUID get(LLViewerObject* object, S32 te_index)
{
- LLViewerTexture* image = object->getTEImage(te);
- return image ? image->getID() : LLUUID::null;
+ LLUUID id;
+
+ LLViewerTexture* image = object->getTEImage(te_index);
+ if (image) id = image->getID();
+
+ if (!id.isNull() && LLViewerMedia::textureHasMedia(id))
+ {
+ LLTextureEntry *te = object->getTE(te_index);
+ if (te)
+ {
+ LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL ;
+ if(!tex)
+ {
+ tex = LLViewerFetchedTexture::sDefaultImagep;
+ }
+ if (tex)
+ {
+ id = tex->getID();
+ }
+ }
+ }
+ return id;
}
} func;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
+ if(LLViewerMedia::textureHasMedia(id))
+ {
+ childSetEnabled("textbox autofix",editable);
+ childSetEnabled("button align",editable);
+ }
+
if (identical)
{
// All selected have the same texture
@@ -444,13 +471,6 @@ void LLPanelFace::getState()
}
}
}
-
- if(LLViewerMedia::textureHasMedia(id))
- {
- childSetEnabled("textbox autofix",editable);
- childSetEnabled("button align",editable);
- }
-
}
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index 01291c4012..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);
@@ -425,6 +440,11 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
getChild<LLUICtrl>("group_name")->setVisible(false);
getChild<LLUICtrl>("group_name_editor")->setVisible(true);
+
+ if(button_call)
+ button_call->setVisible(false);
+ if(button_chat)
+ button_chat->setVisible(false);
}
else
{
@@ -452,6 +472,10 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
if(button_apply)
button_apply->setVisible(is_member);
+ if(button_call)
+ button_call->setVisible(is_member);
+ if(button_chat)
+ button_chat->setVisible(is_member);
}
reposButtons();
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 0e55ff3214..c6287472fe 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -452,6 +452,7 @@ LLPanelGroupSubTab::LLPanelGroupSubTab()
: LLPanelGroupTab(),
mHeader(NULL),
mFooter(NULL),
+ mActivated(false),
mSearchEditor(NULL)
{
}
@@ -504,13 +505,14 @@ void LLPanelGroupSubTab::setGroupID(const LLUUID& id)
mSearchEditor->clear();
setSearchFilter("");
}
+
+ mActivated = false;
}
void LLPanelGroupSubTab::setSearchFilter(const std::string& filter)
{
if(mSearchFilter == filter)
return;
- lldebugs << "LLPanelGroupSubTab::setSearchFilter() ==> '" << filter << "'" << llendl;
mSearchFilter = filter;
LLStringUtil::toLower(mSearchFilter);
update(GC_ALL);
@@ -518,13 +520,11 @@ void LLPanelGroupSubTab::setSearchFilter(const std::string& filter)
void LLPanelGroupSubTab::activate()
{
- lldebugs << "LLPanelGroupSubTab::activate()" << llendl;
setOthersVisible(TRUE);
}
void LLPanelGroupSubTab::deactivate()
{
- lldebugs << "LLPanelGroupSubTab::deactivate()" << llendl;
setOthersVisible(FALSE);
}
@@ -534,19 +534,11 @@ void LLPanelGroupSubTab::setOthersVisible(BOOL b)
{
mHeader->setVisible( b );
}
- else
- {
- llwarns << "LLPanelGroupSubTab missing header!" << llendl;
- }
if (mFooter)
{
mFooter->setVisible( b );
}
- else
- {
- llwarns << "LLPanelGroupSubTab missing footer!" << llendl;
- }
}
bool LLPanelGroupSubTab::matchesActionSearchFilter(std::string action)
@@ -875,10 +867,12 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()
for (itor = selection.begin();
itor != selection.end(); ++itor)
{
- selected_members.push_back( (*itor)->getUUID() );
+ LLUUID member_id = (*itor)->getUUID();
+
+ selected_members.push_back( member_id );
// Get this member's power mask including any unsaved changes
- U64 powers = getAgentPowersBasedOnRoleChanges((*itor)->getUUID());
+ U64 powers = getAgentPowersBasedOnRoleChanges( member_id );
allowed_by_all &= powers;
allowed_by_some |= powers;
@@ -1022,6 +1016,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()
//last owner. We should check for this special case
// -jwolk
check->setEnabled(cb_enable);
+ item->setEnabled(cb_enable);
}
}
else
@@ -1098,7 +1093,8 @@ void LLPanelGroupMembersSubTab::handleEjectMembers()
for (itor = selection.begin() ;
itor != selection.end(); ++itor)
{
- selected_members.push_back((*itor)->getUUID());
+ LLUUID member_id = (*itor)->getUUID();
+ selected_members.push_back( member_id );
}
mMembersList->deleteSelectedItems();
@@ -1154,6 +1150,7 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id,
for (std::vector<LLScrollListItem*>::iterator itor = selection.begin() ;
itor != selection.end(); ++itor)
{
+
member_id = (*itor)->getUUID();
//see if we requested a change for this member before
@@ -1245,15 +1242,19 @@ void LLPanelGroupMembersSubTab::handleMemberDoubleClick()
LLScrollListItem* selected = mMembersList->getFirstSelected();
if (selected)
{
- LLAvatarActions::showProfile(selected->getUUID());
+ LLUUID member_id = selected->getUUID();
+ LLAvatarActions::showProfile( member_id );
}
}
void LLPanelGroupMembersSubTab::activate()
{
LLPanelGroupSubTab::activate();
-
- update(GC_ALL);
+ if(!mActivated)
+ {
+ update(GC_ALL);
+ mActivated = true;
+ }
}
void LLPanelGroupMembersSubTab::deactivate()
@@ -1629,7 +1630,9 @@ void LLPanelGroupMembersSubTab::updateMembers()
row["columns"][2]["value"] = mMemberProgress->second->getOnlineStatus();
row["columns"][2]["font"] = "SANSSERIF_SMALL";
- mMembersList->addElement(row);//, ADD_SORTED);
+ LLScrollListItem* member = mMembersList->addElement(row);//, ADD_SORTED);
+
+ LLUUID id = member->getUUID();
mHasMatch = TRUE;
}
}
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index 2f81900e60..eac22a6338 100644
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -149,6 +149,8 @@ protected:
icon_map_t mActionIcons;
+ bool mActivated;
+
void setOthersVisible(BOOL b);
};
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index 0cfe501fab..ff1e43b526 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -46,6 +46,7 @@
#include "llimview.h"
#include "llvoicechannel.h"
#include "llsidetray.h"
+#include "llspeakers.h"
#include "lltrans.h"
void LLPanelChatControlPanel::onCallButtonClicked()
@@ -63,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()
@@ -86,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;
-
- bool session_initialized = session->mSessionInitialized;
- bool callback_enabled = session->mCallBackEnabled;
-
- BOOL enable_connect = session_initialized
- && voice_enabled
- && callback_enabled;
- childSetEnabled("call_btn", enable_connect);
+ gVoiceClient->addObserver(this);
- LLPanel::draw();
+ return TRUE;
}
void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id)
@@ -244,7 +259,6 @@ void LLPanelIMControlPanel::nameUpdatedCallback(const LLUUID& id, const std::str
LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id):
mParticipantList(NULL)
{
- mSpeakerManager = LLIMModel::getInstance()->getSpeakerManager(session_id);
}
BOOL LLPanelGroupControlPanel::postBuild()
@@ -263,12 +277,11 @@ LLPanelGroupControlPanel::~LLPanelGroupControlPanel()
// virtual
void LLPanelGroupControlPanel::draw()
{
- //Remove event does not raised until speakerp->mActivityTimer.hasExpired() is false, see LLSpeakerManager::update()
- //so we need update it to raise needed event
- mSpeakerManager->update(true);
// 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();
}
@@ -306,7 +319,10 @@ void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id)
// for group and Ad-hoc chat we need to include agent into list
if(!mParticipantList)
- mParticipantList = new LLParticipantList(mSpeakerManager, getChild<LLAvatarList>("speakers_list"), true,false);
+ {
+ LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(session_id);
+ mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true,false);
+ }
}
diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h
index c18be5a6df..3ab505a084 100644
--- a/indra/newview/llpanelimcontrolpanel.h
+++ b/indra/newview/llpanelimcontrolpanel.h
@@ -37,11 +37,11 @@
#include "llvoicechannel.h"
#include "llcallingcard.h"
-class LLSpeakerMgr;
-class LLAvatarList;
class LLParticipantList;
-class LLPanelChatControlPanel : public LLPanel
+class LLPanelChatControlPanel
+ : public LLPanel
+ , public LLVoiceClientStatusObserver
{
public:
LLPanelChatControlPanel() :
@@ -49,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; }
@@ -110,7 +116,6 @@ public:
protected:
LLUUID mGroupID;
- LLSpeakerMgr* mSpeakerManager;
LLParticipantList* mParticipantList;
diff --git a/indra/newview/llpanellandaudio.cpp b/indra/newview/llpanellandaudio.cpp
index 920fca66f2..6a4c909759 100644
--- a/indra/newview/llpanellandaudio.cpp
+++ b/indra/newview/llpanellandaudio.cpp
@@ -37,6 +37,7 @@
// viewer includes
#include "llmimetypes.h"
#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
#include "lluictrlfactory.h"
// library includes
@@ -83,8 +84,14 @@ BOOL LLPanelLandAudio::postBuild()
mCheckSoundLocal = getChild<LLCheckBoxCtrl>("check sound local");
childSetCommitCallback("check sound local", onCommitAny, this);
- mRadioVoiceChat = getChild<LLRadioGroup>("parcel_voice_channel");
- childSetCommitCallback("parcel_voice_channel", onCommitAny, this);
+ mCheckParcelEnableVoice = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel");
+ childSetCommitCallback("parcel_enable_voice_channel", onCommitAny, this);
+
+ // This one is always disabled so no need for a commit callback
+ mCheckEstateDisabledVoice = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel_is_estate_disabled");
+
+ mCheckParcelVoiceLocal = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel_local");
+ childSetCommitCallback("parcel_enable_voice_channel_local", onCommitAny, this);
mMusicURLEdit = getChild<LLLineEditor>("music_url");
childSetCommitCallback("music_url", onCommitAny, this);
@@ -118,19 +125,33 @@ void LLPanelLandAudio::refresh()
mMusicUrlCheck->set( parcel->getObscureMusic() );
mMusicUrlCheck->setEnabled( can_change_media );
- if(parcel->getParcelFlagAllowVoice())
+ bool allow_voice = parcel->getParcelFlagAllowVoice();
+
+ LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
+ if (region && region->isVoiceEnabled())
{
- if(parcel->getParcelFlagUseEstateVoiceChannel())
- mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate);
- else
- mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatPrivate);
+ mCheckEstateDisabledVoice->setVisible(false);
+
+ mCheckParcelEnableVoice->setVisible(true);
+ mCheckParcelEnableVoice->setEnabled( can_change_media );
+ mCheckParcelEnableVoice->set(allow_voice);
+
+ mCheckParcelVoiceLocal->setEnabled( can_change_media && allow_voice );
}
else
{
- mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatDisable);
+ // Voice disabled at estate level, overrides parcel settings
+ // Replace the parcel voice checkbox with a disabled one
+ // labelled with an explanatory message
+ mCheckEstateDisabledVoice->setVisible(true);
+
+ mCheckParcelEnableVoice->setVisible(false);
+ mCheckParcelEnableVoice->setEnabled(false);
+ mCheckParcelVoiceLocal->setEnabled(false);
}
- mRadioVoiceChat->setEnabled( can_change_media );
+ mCheckParcelEnableVoice->set(allow_voice);
+ mCheckParcelVoiceLocal->set(!parcel->getParcelFlagUseEstateVoiceChannel());
mMusicURLEdit->setText(parcel->getMusicURL());
mMusicURLEdit->setEnabled( can_change_media );
@@ -149,30 +170,11 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata)
// Extract data from UI
BOOL sound_local = self->mCheckSoundLocal->get();
- int voice_setting = self->mRadioVoiceChat->getSelectedIndex();
std::string music_url = self->mMusicURLEdit->getText();
U8 obscure_music = self->mMusicUrlCheck->get();
-
- BOOL voice_enabled;
- BOOL voice_estate_chan;
-
- switch(voice_setting)
- {
- default:
- case kRadioVoiceChatEstate:
- voice_enabled = TRUE;
- voice_estate_chan = TRUE;
- break;
- case kRadioVoiceChatPrivate:
- voice_enabled = TRUE;
- voice_estate_chan = FALSE;
- break;
- case kRadioVoiceChatDisable:
- voice_enabled = FALSE;
- voice_estate_chan = FALSE;
- break;
- }
+ BOOL voice_enabled = self->mCheckParcelEnableVoice->get();
+ BOOL voice_estate_chan = !self->mCheckParcelVoiceLocal->get();
// Remove leading/trailing whitespace (common when copying/pasting)
LLStringUtil::trim(music_url);
diff --git a/indra/newview/llpanellandaudio.h b/indra/newview/llpanellandaudio.h
index de5da95fa4..19766a40b6 100644
--- a/indra/newview/llpanellandaudio.h
+++ b/indra/newview/llpanellandaudio.h
@@ -52,7 +52,9 @@ private:
private:
LLCheckBoxCtrl* mCheckSoundLocal;
- LLRadioGroup* mRadioVoiceChat;
+ LLCheckBoxCtrl* mCheckParcelEnableVoice;
+ LLCheckBoxCtrl* mCheckEstateDisabledVoice;
+ LLCheckBoxCtrl* mCheckParcelVoiceLocal;
LLLineEditor* mMusicURLEdit;
LLCheckBoxCtrl* mMusicUrlCheck;
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/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index d6e407a0ed..47feef496a 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -305,6 +305,29 @@ void LLLandmarksPanel::updateShowFolderState()
);
}
+void LLLandmarksPanel::setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus)
+{
+ if (selectItemInAccordionTab(mFavoritesInventoryPanel, "tab_favorites", obj_id, take_keyboard_focus))
+ {
+ return;
+ }
+
+ if (selectItemInAccordionTab(mLandmarksInventoryPanel, "tab_landmarks", obj_id, take_keyboard_focus))
+ {
+ return;
+ }
+
+ if (selectItemInAccordionTab(mMyInventoryPanel, "tab_inventory", obj_id, take_keyboard_focus))
+ {
+ return;
+ }
+
+ if (selectItemInAccordionTab(mLibraryInventoryPanel, "tab_library", obj_id, take_keyboard_focus))
+ {
+ return;
+ }
+}
+
//////////////////////////////////////////////////////////////////////////
// PROTECTED METHODS
//////////////////////////////////////////////////////////////////////////
@@ -350,6 +373,36 @@ LLFolderViewItem* LLLandmarksPanel::getCurSelectedItem() const
return mCurrentSelectedList ? mCurrentSelectedList->getRootFolder()->getCurSelectedItem() : NULL;
}
+LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list,
+ const std::string& tab_name,
+ const LLUUID& obj_id,
+ BOOL take_keyboard_focus) const
+{
+ if (!inventory_list)
+ return NULL;
+
+ LLFolderView* folder_view = inventory_list->getRootFolder();
+
+ LLFolderViewItem* item = folder_view->getItemByID(obj_id);
+ if (!item)
+ return NULL;
+
+ LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(tab_name);
+ if (!tab->isExpanded())
+ {
+ tab->changeOpenClose(false);
+ }
+
+ folder_view->setSelection(item, FALSE, take_keyboard_focus);
+
+ LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion");
+ LLRect screen_rc;
+ localRectToScreen(item->getRect(), &screen_rc);
+ accordion->notifyParent(LLSD().with("scrollToShowRect", screen_rc.getValue()));
+
+ return item;
+}
+
void LLLandmarksPanel::updateSortOrder(LLInventoryPanel* panel, bool byDate)
{
if(!panel) return;
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index 569739237d..96b790844c 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -73,6 +73,11 @@ public:
*/
void updateShowFolderState();
+ /**
+ * Selects item with "obj_id" in one of accordion tabs.
+ */
+ void setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus);
+
protected:
/**
* @return true - if current selected panel is not null and selected item is a landmark
@@ -81,6 +86,17 @@ protected:
bool isReceivedFolderSelected() const;
void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb);
LLFolderViewItem* getCurSelectedItem() const;
+
+ /**
+ * Selects item with "obj_id" in "inventory_list" and scrolls accordion
+ * scrollbar to show the item.
+ * Returns pointer to the item if it is found in "inventory_list", otherwise NULL.
+ */
+ LLFolderViewItem* selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list,
+ const std::string& tab_name,
+ const LLUUID& obj_id,
+ BOOL take_keyboard_focus) const;
+
void updateSortOrder(LLInventoryPanel* panel, bool byDate);
//LLRemoteParcelInfoObserver interface
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/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index fd5ce7a46d..cf903958ee 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -61,6 +61,9 @@
#include "llviewercontrol.h"
+static const std::string OUTFITS_TAB_NAME = "outfitslist_tab";
+static const std::string COF_TAB_NAME = "cof_tab";
+
static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
bool LLPanelOutfitsInventory::sShowDebugEditor = false;
@@ -267,7 +270,7 @@ void LLPanelOutfitsInventory::onSaveCommit(const std::string& outfit_name)
if (mAppearanceTabs)
{
- mAppearanceTabs->selectTabByName("outfitslist_tab");
+ mAppearanceTabs->selectTabByName(OUTFITS_TAB_NAME);
}
}
@@ -503,8 +506,7 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
if (command_name == "wear")
{
- const BOOL is_my_outfits = (mActivePanel->getName() == "outfitslist_tab");
- if (!is_my_outfits)
+ if (isCOFPanelActive())
{
return FALSE;
}
@@ -558,17 +560,15 @@ bool LLPanelOutfitsInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropTy
void LLPanelOutfitsInventory::initTabPanels()
{
- mTabPanels.resize(2);
-
- LLInventoryPanel *cof_panel = getChild<LLInventoryPanel>("cof_tab");
+ LLInventoryPanel *cof_panel = getChild<LLInventoryPanel>(COF_TAB_NAME);
cof_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
- mTabPanels[0] = cof_panel;
-
- LLInventoryPanel *myoutfits_panel = getChild<LLInventoryPanel>("outfitslist_tab");
+ mTabPanels.push_back(cof_panel);
+
+ LLInventoryPanel *myoutfits_panel = getChild<LLInventoryPanel>(OUTFITS_TAB_NAME);
myoutfits_panel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, LLInventoryFilter::FILTERTYPE_CATEGORY);
myoutfits_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
- mTabPanels[1] = myoutfits_panel;
-
+ mTabPanels.push_back(myoutfits_panel);
+
for (tabpanels_vec_t::iterator iter = mTabPanels.begin();
iter != mTabPanels.end();
++iter)
@@ -615,19 +615,19 @@ void LLPanelOutfitsInventory::onTabChange()
updateVerbs();
}
-LLInventoryPanel* LLPanelOutfitsInventory::getActivePanel()
-{
- return mActivePanel;
-}
-
-bool LLPanelOutfitsInventory::isTabPanel(LLInventoryPanel *panel)
+BOOL LLPanelOutfitsInventory::isTabPanel(LLInventoryPanel *panel) const
{
- for(tabpanels_vec_t::iterator it = mTabPanels.begin();
+ for(tabpanels_vec_t::const_iterator it = mTabPanels.begin();
it != mTabPanels.end();
++it)
{
if (*it == panel)
- return true;
+ return TRUE;
}
- return false;
+ return FALSE;
+}
+
+BOOL LLPanelOutfitsInventory::isCOFPanelActive() const
+{
+ return (getActivePanel()->getName() == COF_TAB_NAME);
}
diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h
index 76110e2a3f..ab25ef0a49 100644
--- a/indra/newview/llpaneloutfitsinventory.h
+++ b/indra/newview/llpaneloutfitsinventory.h
@@ -78,24 +78,26 @@ protected:
bool getIsCorrectType(const LLFolderViewEventListener *listenerp) const;
private:
- LLSidepanelAppearance* mParent;
- LLSaveFolderState* mSavedFolderState;
- LLTabContainer* mAppearanceTabs;
- std::string mFilterSubString;
+ LLSidepanelAppearance* mParent;
+ LLSaveFolderState* mSavedFolderState;
+ LLTabContainer* mAppearanceTabs;
+ std::string mFilterSubString;
public:
//////////////////////////////////////////////////////////////////////////////////
// tab panels
- LLInventoryPanel* getActivePanel();
- bool isTabPanel(LLInventoryPanel *panel);
+ LLInventoryPanel* getActivePanel() { return mActivePanel; }
+ const LLInventoryPanel* getActivePanel() const { return mActivePanel; }
+ BOOL isTabPanel(LLInventoryPanel *panel) const;
protected:
- void initTabPanels();
- void onTabSelectionChange(LLInventoryPanel* tab_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action);
- void onTabChange();
-
+ void initTabPanels();
+ void onTabSelectionChange(LLInventoryPanel* tab_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action);
+ void onTabChange();
+ BOOL isCOFPanelActive() const;
+
private:
- LLInventoryPanel* mActivePanel;
+ LLInventoryPanel* mActivePanel;
typedef std::vector<LLInventoryPanel *> tabpanels_vec_t;
tabpanels_vec_t mTabPanels;
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 b80eb9db38..5f75668722 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -34,26 +34,22 @@
#include "llpanelplaceinfo.h"
-#include "roles_constants.h"
#include "llsdutil.h"
-#include "llsecondlifeurls.h"
#include "llsdutil_math.h"
+
#include "llregionhandle.h"
-#include "message.h"
#include "lliconctrl.h"
#include "lltextbox.h"
+#include "lltrans.h"
+
#include "llagent.h"
-#include "llavatarpropertiesprocessor.h"
#include "llexpandabletextbox.h"
#include "llpanelpick.h"
#include "lltexturectrl.h"
-#include "llviewerinventory.h"
-#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
-#include "llviewertexteditor.h"
LLPanelPlaceInfo::LLPanelPlaceInfo()
: LLPanel(),
@@ -105,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");
@@ -212,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;
@@ -265,25 +265,6 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
}
}
-// virtual
-void LLPanelPlaceInfo::handleVisibilityChange(BOOL new_visibility)
-{
- LLPanel::handleVisibilityChange(new_visibility);
-
- LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
- if (!parcel_mgr)
- return;
-
- // Remove land selection when panel hides.
- if (!new_visibility)
- {
- if (!parcel_mgr->selectionEmpty())
- {
- parcel_mgr->deselectLand();
- }
- }
-}
-
void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel)
{
std::string region_name = mRegionName->getText();
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 7dfc7b2444..3091f7ed24 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -94,7 +94,6 @@ public:
/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
- /*virtual*/ void handleVisibilityChange (BOOL new_visibility);
// Create a pick for the location specified
// by global_pos.
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index 402d50ba9c..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
@@ -257,6 +259,25 @@ void LLPanelPlaceProfile::processParcelInfo(const LLParcelData& parcel_data)
}
}
+// virtual
+void LLPanelPlaceProfile::handleVisibilityChange(BOOL new_visibility)
+{
+ LLPanel::handleVisibilityChange(new_visibility);
+
+ LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
+ if (!parcel_mgr)
+ return;
+
+ // Remove land selection when panel hides.
+ if (!new_visibility)
+ {
+ if (!parcel_mgr->selectionEmpty())
+ {
+ parcel_mgr->deselectUnused();
+ }
+ }
+}
+
void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
LLViewerRegion* region,
const LLVector3d& pos_global,
diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h
index 8c30ca92fb..8ca9526875 100644
--- a/indra/newview/llpanelplaceprofile.h
+++ b/indra/newview/llpanelplaceprofile.h
@@ -52,6 +52,8 @@ public:
/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
+ /*virtual*/ void handleVisibilityChange(BOOL new_visibility);
+
// Displays information about the currently selected parcel
// without sending a request to the server.
// If is_current_parcel true shows "You Are Here" banner.
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index a71c8d8958..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";
@@ -289,89 +292,92 @@ BOOL LLPanelPlaces::postBuild()
void LLPanelPlaces::onOpen(const LLSD& key)
{
- if(!mPlaceProfile || !mLandmarkInfo || key.size() == 0)
+ if (!mPlaceProfile || !mLandmarkInfo)
return;
- mFilterEditor->clear();
- onFilterEdit("", false);
-
- mPlaceInfoType = key["type"].asString();
- mPosGlobal.setZero();
- mItem = NULL;
- isLandmarkEditModeOn = false;
- togglePlaceInfoPanel(TRUE);
-
- if (mPlaceInfoType == AGENT_INFO_TYPE)
- {
- mPlaceProfile->setInfoType(LLPanelPlaceInfo::AGENT);
- }
- else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
+ if (key.size() != 0)
{
- mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK);
+ mFilterEditor->clear();
+ onFilterEdit("", false);
- if (key.has("x") && key.has("y") && key.has("z"))
+ mPlaceInfoType = key["type"].asString();
+ mPosGlobal.setZero();
+ mItem = NULL;
+ isLandmarkEditModeOn = false;
+ togglePlaceInfoPanel(TRUE);
+
+ if (mPlaceInfoType == AGENT_INFO_TYPE)
{
- mPosGlobal = LLVector3d(key["x"].asReal(),
- key["y"].asReal(),
- key["z"].asReal());
+ mPlaceProfile->setInfoType(LLPanelPlaceInfo::AGENT);
}
- else
+ else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
{
- mPosGlobal = gAgent.getPositionGlobal();
- }
-
- mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal);
+ mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK);
- // Disable Save button because there is no item to save yet.
- // The button will be enabled in onLandmarkLoaded callback.
- mSaveBtn->setEnabled(FALSE);
- }
- else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
- {
- mLandmarkInfo->setInfoType(LLPanelPlaceInfo::LANDMARK);
+ if (key.has("x") && key.has("y") && key.has("z"))
+ {
+ mPosGlobal = LLVector3d(key["x"].asReal(),
+ key["y"].asReal(),
+ key["z"].asReal());
+ }
+ else
+ {
+ mPosGlobal = gAgent.getPositionGlobal();
+ }
- LLInventoryItem* item = gInventory.getItem(key["id"].asUUID());
- if (!item)
- return;
+ mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal);
- setItem(item);
- }
- else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
- {
- if (key.has("id"))
+ // Disable Save button because there is no item to save yet.
+ // The button will be enabled in onLandmarkLoaded callback.
+ mSaveBtn->setEnabled(FALSE);
+ }
+ else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
{
- LLUUID parcel_id = key["id"].asUUID();
- mPlaceProfile->setParcelID(parcel_id);
+ mLandmarkInfo->setInfoType(LLPanelPlaceInfo::LANDMARK);
+
+ LLInventoryItem* item = gInventory.getItem(key["id"].asUUID());
+ if (!item)
+ return;
- // query the server to get the global 3D position of this
- // parcel - we need this for teleport/mapping functions.
- mRemoteParcelObserver->setParcelID(parcel_id);
+ setItem(item);
}
- else
+ else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
{
- mPosGlobal = LLVector3d(key["x"].asReal(),
- key["y"].asReal(),
- key["z"].asReal());
- mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
+ if (key.has("id"))
+ {
+ LLUUID parcel_id = key["id"].asUUID();
+ mPlaceProfile->setParcelID(parcel_id);
+
+ // query the server to get the global 3D position of this
+ // parcel - we need this for teleport/mapping functions.
+ mRemoteParcelObserver->setParcelID(parcel_id);
+ }
+ else
+ {
+ mPosGlobal = LLVector3d(key["x"].asReal(),
+ key["y"].asReal(),
+ key["z"].asReal());
+ mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
+ }
+
+ mPlaceProfile->setInfoType(LLPanelPlaceInfo::PLACE);
}
+ else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE)
+ {
+ S32 index = key["id"].asInteger();
- mPlaceProfile->setInfoType(LLPanelPlaceInfo::PLACE);
- }
- else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE)
- {
- S32 index = key["id"].asInteger();
+ const LLTeleportHistoryStorage::slurl_list_t& hist_items =
+ LLTeleportHistoryStorage::getInstance()->getItems();
- const LLTeleportHistoryStorage::slurl_list_t& hist_items =
- LLTeleportHistoryStorage::getInstance()->getItems();
+ mPosGlobal = hist_items[index].mGlobalPos;
- mPosGlobal = hist_items[index].mGlobalPos;
+ mPlaceProfile->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
+ mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
+ }
- mPlaceProfile->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
- mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
+ updateVerbs();
}
- updateVerbs();
-
LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
if (!parcel_mgr)
return;
@@ -381,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());
}
@@ -388,9 +398,12 @@ void LLPanelPlaces::onOpen(const LLSD& key)
{
parcel_mgr->removeObserver(mParcelObserver);
+ // Clear the reference to selection to allow its removal in deselectUnused().
+ mParcel.clear();
+
if (!parcel_mgr->selectionEmpty())
{
- parcel_mgr->deselectLand();
+ parcel_mgr->deselectUnused();
}
}
}
@@ -765,23 +778,23 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
mPickPanel->reshape(rect.getWidth(), rect.getHeight());
mPickPanel->setRect(rect);
}
- else if (item == "add_to_favbar")
- {
- if ( mItem.notNull() )
- {
- const LLUUID& favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
- if ( favorites_id.notNull() )
- {
- copy_inventory_item(gAgent.getID(),
- mItem->getPermissions().getOwner(),
- mItem->getUUID(),
- favorites_id,
- std::string(),
- LLPointer<LLInventoryCallback>(NULL));
- llinfos << "Copied inventory item #" << mItem->getUUID() << " to favorites." << llendl;
- }
- }
- }
+ else if (item == "add_to_favbar")
+ {
+ if ( mItem.notNull() )
+ {
+ const LLUUID& favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ if ( favorites_id.notNull() )
+ {
+ copy_inventory_item(gAgent.getID(),
+ mItem->getPermissions().getOwner(),
+ mItem->getUUID(),
+ favorites_id,
+ std::string(),
+ LLPointer<LLInventoryCallback>(NULL));
+ llinfos << "Copied inventory item #" << mItem->getUUID() << " to favorites." << llendl;
+ }
+ }
+ }
}
void LLPanelPlaces::onBackButtonClicked()
@@ -820,12 +833,24 @@ 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());
mLandmarkInfo->setVisible(FALSE);
}
+ else if (mPlaceInfoType == AGENT_INFO_TYPE)
+ {
+ LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver);
+
+ // Clear reference to parcel selection when closing place profile panel.
+ // LLViewerParcelMgr removes the selection if it has 1 reference to it.
+ mParcel.clear();
+ }
}
else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE ||
mPlaceInfoType == LANDMARK_INFO_TYPE)
@@ -842,6 +867,33 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
mPlaceProfile->setVisible(FALSE);
}
+ else
+ {
+ LLLandmarksPanel* landmarks_panel =
+ dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName("Landmarks"));
+ if (landmarks_panel && mItem.notNull())
+ {
+ // If a landmark info is being closed we open the landmarks tab
+ // and set this landmark selected.
+ mTabContainer->selectTabPanel(landmarks_panel);
+
+ landmarks_panel->setItemSelected(mItem->getUUID(), TRUE);
+ }
+ }
+ }
+}
+
+// virtual
+void LLPanelPlaces::handleVisibilityChange(BOOL new_visibility)
+{
+ LLPanel::handleVisibilityChange(new_visibility);
+
+ if (!new_visibility && mPlaceInfoType == AGENT_INFO_TYPE)
+ {
+ LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver);
+
+ // Clear reference to parcel selection when closing places panel.
+ mParcel.clear();
}
}
@@ -857,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);
@@ -873,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 27b5911ebb..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;
@@ -97,6 +99,8 @@ private:
void togglePickPanel(BOOL visible);
void togglePlaceInfoPanel(BOOL visible);
+ /*virtual*/ void handleVisibilityChange(BOOL new_visibility);
+
void updateVerbs();
LLPanelPlaceInfo* getCurrentInfoPanel();
@@ -130,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/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index 571745ee02..1b8fb49641 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -1036,7 +1036,7 @@ void LLTeleportHistoryPanel::setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool
bool LLTeleportHistoryPanel::isAccordionCollapsedByUser(LLUICtrl* acc_tab)
{
LLSD param = acc_tab->getValue();
- if(!param.has("acc_collapsed"))
+ if(!param.has(COLLAPSED_BY_USER))
{
return false;
}
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index b049f914ad..d54cbfe203 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -125,6 +125,8 @@ LLParticipantList::~LLParticipantList()
delete mParticipantListMenu;
mParticipantListMenu = NULL;
}
+
+ mAvatarList->setContextMenu(NULL);
}
void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible)
@@ -431,6 +433,16 @@ 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);
+ main_menu->setItemVisible("SortByRecentSpeakers", is_sort_visible);
main_menu->setItemVisible("Moderator Options", isGroupModerator());
main_menu->arrangeAndClear();
@@ -456,11 +468,6 @@ void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const
LLMenuGL::sMenuContainer->childSetVisible("ModerateVoiceUnMuteSelected", false);
LLMenuGL::sMenuContainer->childSetVisible("ModerateVoiceUnMuteOthers", false);
}
-
- // Don't show sort options for P2P chat
- bool is_sort_visible = (mParent.mAvatarList && mParent.mAvatarList->size() > 1);
- LLMenuGL::sMenuContainer->childSetVisible("SortByName", is_sort_visible);
- LLMenuGL::sMenuContainer->childSetVisible("SortByRecentSpeakers", is_sort_visible);
}
void LLParticipantList::LLParticipantListMenu::sortParticipantList(const LLSD& userdata)
@@ -627,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/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index a857e30d4f..028807a6bd 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -380,138 +380,53 @@ void LLPreviewTexture::updateDimensions()
mUpdateDimensions = FALSE;
- S32 image_height = llmax(1, mImage->getFullHeight());
- S32 image_width = llmax(1, mImage->getFullWidth());
- // Attempt to make the image 1:1 on screen.
- // If that fails, cut width by half.
- S32 client_width = image_width;
- S32 client_height = image_height;
- S32 horiz_pad = 2 * (LLPANEL_BORDER_WIDTH + PREVIEW_PAD) + PREVIEW_RESIZE_HANDLE_SIZE;
- S32 vert_pad = PREVIEW_HEADER_SIZE + 2 * CLIENT_RECT_VPAD + LLPANEL_BORDER_WIDTH;
- S32 max_client_width = gViewerWindow->getWindowWidthScaled() - horiz_pad;
- S32 max_client_height = gViewerWindow->getWindowHeightScaled() - vert_pad;
-
- if (mAspectRatio > 0.f)
- {
- client_height = llceil((F32)client_width / mAspectRatio);
- }
-
- while ((client_width > max_client_width) ||
- (client_height > max_client_height ))
- {
- client_width /= 2;
- client_height /= 2;
- }
-
- S32 view_width = client_width + horiz_pad;
- S32 view_height = client_height + vert_pad;
-
// set text on dimensions display (should be moved out of here and into a callback of some sort)
childSetTextArg("dimensions", "[WIDTH]", llformat("%d", mImage->getFullWidth()));
childSetTextArg("dimensions", "[HEIGHT]", llformat("%d", mImage->getFullHeight()));
-
+
+ LLRect dim_rect;
+ childGetRect("dimensions", dim_rect);
+
+ S32 horiz_pad = 2 * (LLPANEL_BORDER_WIDTH + PREVIEW_PAD) + PREVIEW_RESIZE_HANDLE_SIZE;
+
// add space for dimensions and aspect ratio
- S32 info_height = 0;
- LLRect aspect_rect;
- childGetRect("combo_aspect_ratio", aspect_rect);
- S32 aspect_height = aspect_rect.getHeight();
- info_height += aspect_height + CLIENT_RECT_VPAD;
- view_height += info_height;
-
- S32 button_height = 0;
-
- // add space for buttons
- view_height += (BTN_HEIGHT + CLIENT_RECT_VPAD) * 3;
- button_height = (BTN_HEIGHT + PREVIEW_PAD) * 3;
+ S32 info_height = dim_rect.mTop + CLIENT_RECT_VPAD;
- view_width = llmax(view_width, getMinWidth());
- view_height = llmax(view_height, getMinHeight());
-
- if (view_height != mLastHeight || view_width != mLastWidth)
- {
- if (getHost())
- {
- getHost()->growToFit(view_width, view_height);
- reshape( view_width, view_height );
- setOrigin( 0, getHost()->getRect().getHeight() - (view_height + PREVIEW_HEADER_SIZE) );
- }
- else
- {
- S32 old_top = getRect().mTop;
- S32 old_left = getRect().mLeft;
- reshape( view_width, view_height );
- S32 new_bottom = old_top - getRect().getHeight();
- setOrigin( old_left, new_bottom );
- }
-
- // Try to keep whole view onscreen, don't allow partial offscreen.
- if (getHost())
- gFloaterView->adjustToFitScreen(getHost(), FALSE);
- else
- gFloaterView->adjustToFitScreen(this, FALSE);
-
- if (image_height > 1 && image_width > 1)
- {
- // Resize until we know the image's height
- mLastWidth = view_width;
- mLastHeight = view_height;
- }
- }
-
- if (!mUserResized)
- {
- // clamp texture size to fit within actual size of floater after attempting resize
- client_width = llmin(client_width, getRect().getWidth() - horiz_pad);
- client_height = llmin(client_height, getRect().getHeight() - PREVIEW_HEADER_SIZE
- - (2 * CLIENT_RECT_VPAD) - LLPANEL_BORDER_WIDTH - info_height);
+ LLRect client_rect(horiz_pad, getRect().getHeight(), getRect().getWidth() - horiz_pad, 0);
+ client_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);
+ client_rect.mBottom += PREVIEW_BORDER + CLIENT_RECT_VPAD + info_height ;
-
- }
- else
+ S32 client_width = client_rect.getWidth();
+ S32 client_height = client_rect.getHeight();
+
+ if (mAspectRatio > 0.f)
{
- client_width = getRect().getWidth() - horiz_pad;
- if (mAspectRatio > 0)
+ if(mAspectRatio > 1.f)
{
- client_height = llround(client_width / mAspectRatio);
+ client_height = llceil((F32)client_width / mAspectRatio);
+ if(client_height > client_rect.getHeight())
+ {
+ client_height = client_rect.getHeight();
+ client_width = llceil((F32)client_height * mAspectRatio);
+ }
}
else
{
- client_height = getRect().getHeight() - vert_pad;
- }
- }
-
- S32 max_height = getRect().getHeight() - PREVIEW_BORDER - button_height
- - CLIENT_RECT_VPAD - info_height - CLIENT_RECT_VPAD - PREVIEW_HEADER_SIZE;
-
- if (mAspectRatio > 0.f)
- {
- max_height = llmax(max_height, 1);
-
- if (client_height > max_height)
- {
- client_height = max_height;
- client_width = llround(client_height * mAspectRatio);
+ client_width = llceil((F32)client_height * mAspectRatio);
+ if(client_width > client_rect.getWidth())
+ {
+ client_width = client_rect.getWidth();
+ client_height = llceil((F32)client_width / mAspectRatio);
+ }
}
}
- else
- {
- S32 max_width = getRect().getWidth() - horiz_pad;
- client_height = llclamp(client_height, 1, max_height);
- client_width = llclamp(client_width, 1, max_width);
- }
-
- LLRect window_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
- window_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);
- window_rect.mBottom += PREVIEW_BORDER + button_height + CLIENT_RECT_VPAD + info_height + CLIENT_RECT_VPAD;
+ mClientRect.setLeftTopAndSize(client_rect.getCenterX() - (client_width / 2), client_rect.getCenterY() + (client_height / 2), client_width, client_height);
- mClientRect.setLeftTopAndSize(window_rect.getCenterX() - (client_width / 2), window_rect.mTop, client_width, client_height);
-
// Hide the aspect ratio label if the window is too narrow
// Assumes the label should be to the right of the dimensions
- LLRect dim_rect, aspect_label_rect;
+ LLRect aspect_label_rect;
childGetRect("aspect_ratio", aspect_label_rect);
- childGetRect("dimensions", dim_rect);
childSetVisible("aspect_ratio", dim_rect.mRight < aspect_label_rect.mLeft);
}
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 0dd9203c6d..6f9a1ccdbe 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -44,7 +44,6 @@
#include "llvoavatar.h"
#include "llworld.h"
-const F32 SPEAKER_TIMEOUT = 10.f; // seconds of not being on voice channel before removed from list of active speakers
const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f);
const LLColor4 ACTIVE_COLOR(0.5f, 0.5f, 0.5f, 1.f);
@@ -71,10 +70,6 @@ LLSpeaker::LLSpeaker(const LLUUID& id, const std::string& name, const ESpeakerTy
{
mDisplayName = name;
}
-
- gVoiceClient->setUserVolume(id, LLMuteList::getInstance()->getSavedResidentVolume(id));
-
- mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
}
@@ -164,6 +159,89 @@ bool LLSortRecentSpeakers::operator()(const LLPointer<LLSpeaker> lhs, const LLPo
return( lhs->mDisplayName.compare(rhs->mDisplayName) < 0 );
}
+LLSpeakerActionTimer::LLSpeakerActionTimer(action_callback_t action_cb, F32 action_period, const LLUUID& speaker_id)
+: LLEventTimer(action_period)
+, mActionCallback(action_cb)
+, mSpeakerId(speaker_id)
+{
+}
+
+BOOL LLSpeakerActionTimer::tick()
+{
+ if (mActionCallback)
+ {
+ return (BOOL)mActionCallback(mSpeakerId);
+ }
+ return TRUE;
+}
+
+LLSpeakersDelayActionsStorage::LLSpeakersDelayActionsStorage(LLSpeakerActionTimer::action_callback_t action_cb, F32 action_delay)
+: mActionCallback(action_cb)
+, mActionDelay(action_delay)
+{
+}
+
+LLSpeakersDelayActionsStorage::~LLSpeakersDelayActionsStorage()
+{
+ removeAllTimers();
+}
+
+void LLSpeakersDelayActionsStorage::setActionTimer(const LLUUID& speaker_id)
+{
+ bool not_found = true;
+ if (mActionTimersMap.size() > 0)
+ {
+ not_found = mActionTimersMap.find(speaker_id) == mActionTimersMap.end();
+ }
+
+ // If there is already a started timer for the passed UUID don't do anything.
+ if (not_found)
+ {
+ // Starting a timer to remove an participant after delay is completed
+ mActionTimersMap.insert(LLSpeakerActionTimer::action_value_t(speaker_id,
+ new LLSpeakerActionTimer(
+ boost::bind(&LLSpeakersDelayActionsStorage::onTimerActionCallback, this, _1),
+ mActionDelay, speaker_id)));
+ }
+}
+
+void LLSpeakersDelayActionsStorage::unsetActionTimer(const LLUUID& speaker_id)
+{
+ if (mActionTimersMap.size() == 0) return;
+
+ LLSpeakerActionTimer::action_timer_iter_t it_speaker = mActionTimersMap.find(speaker_id);
+
+ if (it_speaker != mActionTimersMap.end())
+ {
+ delete it_speaker->second;
+ mActionTimersMap.erase(it_speaker);
+ }
+}
+
+void LLSpeakersDelayActionsStorage::removeAllTimers()
+{
+ LLSpeakerActionTimer::action_timer_iter_t iter = mActionTimersMap.begin();
+ for (; iter != mActionTimersMap.end(); ++iter)
+ {
+ delete iter->second;
+ }
+ mActionTimersMap.clear();
+}
+
+bool LLSpeakersDelayActionsStorage::onTimerActionCallback(const LLUUID& speaker_id)
+{
+ unsetActionTimer(speaker_id);
+
+ if (mActionCallback)
+ {
+ mActionCallback(speaker_id);
+ }
+
+ // do not return true to avoid deleting of an timer twice:
+ // in LLSpeakersDelayActionsStorage::unsetActionTimer() & LLEventTimer::updateClass()
+ return false;
+}
+
//
// LLSpeakerMgr
@@ -172,10 +250,14 @@ bool LLSortRecentSpeakers::operator()(const LLPointer<LLSpeaker> lhs, const LLPo
LLSpeakerMgr::LLSpeakerMgr(LLVoiceChannel* channelp) :
mVoiceChannel(channelp)
{
+ static LLUICachedControl<F32> remove_delay ("SpeakerParticipantRemoveDelay", 10.0);
+
+ mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLSpeakerMgr::removeSpeaker, this, _1), remove_delay);
}
LLSpeakerMgr::~LLSpeakerMgr()
{
+ delete mSpeakerDelayRemover;
}
LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::string& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type)
@@ -198,7 +280,6 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin
{
// keep highest priority status (lowest value) instead of overriding current value
speakerp->mStatus = llmin(speakerp->mStatus, status);
- speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
// RN: due to a weird behavior where IMs from attached objects come from the wearer's agent_id
// we need to override speakers that we think are objects when we find out they are really
// residents
@@ -210,6 +291,8 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin
}
}
+ mSpeakerDelayRemover->unsetActionTimer(speakerp->mID);
+
return speakerp;
}
@@ -314,7 +397,7 @@ void LLSpeakerMgr::update(BOOL resort_ok)
S32 sort_index = 0;
speaker_list_t::iterator sorted_speaker_it;
for(sorted_speaker_it = mSpeakersSorted.begin();
- sorted_speaker_it != mSpeakersSorted.end(); )
+ sorted_speaker_it != mSpeakersSorted.end(); ++sorted_speaker_it)
{
LLPointer<LLSpeaker> speakerp = *sorted_speaker_it;
@@ -327,19 +410,6 @@ void LLSpeakerMgr::update(BOOL resort_ok)
// stuff sort ordinal into speaker so the ui can sort by this value
speakerp->mSortIndex = sort_index++;
-
- // remove speakers that have been gone too long
- if (speakerp->mStatus == LLSpeaker::STATUS_NOT_IN_CHANNEL && speakerp->mActivityTimer.hasExpired())
- {
- fireEvent(new LLSpeakerListChangeEvent(this, speakerp->mID), "remove");
-
- mSpeakers.erase(speakerp->mID);
- sorted_speaker_it = mSpeakersSorted.erase(sorted_speaker_it);
- }
- else
- {
- ++sorted_speaker_it;
- }
}
}
@@ -363,6 +433,35 @@ void LLSpeakerMgr::updateSpeakerList()
}
}
+void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp)
+{
+ speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
+ speakerp->mDotColor = INACTIVE_COLOR;
+ mSpeakerDelayRemover->setActionTimer(speakerp->mID);
+}
+
+bool LLSpeakerMgr::removeSpeaker(const LLUUID& speaker_id)
+{
+ mSpeakers.erase(speaker_id);
+
+ speaker_list_t::iterator sorted_speaker_it = mSpeakersSorted.begin();
+
+ for(; sorted_speaker_it != mSpeakersSorted.end(); ++sorted_speaker_it)
+ {
+ if (speaker_id == (*sorted_speaker_it)->mID)
+ {
+ mSpeakersSorted.erase(sorted_speaker_it);
+ break;
+ }
+ }
+
+ fireEvent(new LLSpeakerListChangeEvent(this, speaker_id), "remove");
+
+ update(TRUE);
+
+ return false;
+}
+
LLPointer<LLSpeaker> LLSpeakerMgr::findSpeaker(const LLUUID& speaker_id)
{
//In some conditions map causes crash if it is empty(Windows only), adding check (EK)
@@ -511,9 +610,7 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
{
if (agent_data["transition"].asString() == "LEAVE" && speakerp.notNull())
{
- speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
- speakerp->mDotColor = INACTIVE_COLOR;
- speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
+ setSpeakerNotInChannel(speakerp);
}
else if (agent_data["transition"].asString() == "ENTER")
{
@@ -563,9 +660,7 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
std::string agent_transition = update_it->second.asString();
if (agent_transition == "LEAVE" && speakerp.notNull())
{
- speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
- speakerp->mDotColor = INACTIVE_COLOR;
- speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
+ setSpeakerNotInChannel(speakerp);
}
else if ( agent_transition == "ENTER")
{
@@ -734,12 +829,13 @@ void LLActiveSpeakerMgr::updateSpeakerList()
mVoiceChannel = LLVoiceChannel::getCurrentVoiceChannel();
// always populate from active voice channel
- if (LLVoiceChannel::getCurrentVoiceChannel() != mVoiceChannel)
+ if (LLVoiceChannel::getCurrentVoiceChannel() != mVoiceChannel) //MA: seems this is always false
{
fireEvent(new LLSpeakerListChangeEvent(this, LLUUID::null), "clear");
mSpeakers.clear();
mSpeakersSorted.clear();
mVoiceChannel = LLVoiceChannel::getCurrentVoiceChannel();
+ mSpeakerDelayRemover->removeAllTimers();
}
LLSpeakerMgr::updateSpeakerList();
@@ -800,9 +896,7 @@ void LLLocalSpeakerMgr::updateSpeakerList()
LLVOAvatar* avatarp = (LLVOAvatar*)gObjectList.findObject(speaker_id);
if (!avatarp || dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS)
{
- speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
- speakerp->mDotColor = INACTIVE_COLOR;
- speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
+ setSpeakerNotInChannel(speakerp);
}
}
}
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index da8dfdf548..63237204c8 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -73,7 +73,6 @@ public:
F32 mLastSpokeTime; // timestamp when this speaker last spoke
F32 mSpeechVolume; // current speech amplitude (timea average rms amplitude?)
std::string mDisplayName; // cache user name for this speaker
- LLFrameTimer mActivityTimer; // time out speakers when they are not part of current voice channel
BOOL mHasSpoken; // has this speaker said anything this session?
BOOL mHasLeftCurrentCall; // has this speaker left the current voice call?
LLColor4 mDotColor;
@@ -120,6 +119,92 @@ private:
const LLUUID& mSpeakerID;
};
+/**
+ * class LLSpeakerActionTimer
+ *
+ * Implements a timer that calls stored callback action for stored speaker after passed period.
+ *
+ * Action is called until callback returns "true".
+ * In this case the timer will be removed via LLEventTimer::updateClass().
+ * Otherwise it should be deleted manually in place where it is used.
+ * If action callback is not set timer will tick only once and deleted.
+ */
+class LLSpeakerActionTimer : public LLEventTimer
+{
+public:
+ typedef boost::function<bool(const LLUUID&)> action_callback_t;
+ typedef std::map<LLUUID, LLSpeakerActionTimer*> action_timers_map_t;
+ typedef action_timers_map_t::value_type action_value_t;
+ typedef action_timers_map_t::const_iterator action_timer_const_iter_t;
+ typedef action_timers_map_t::iterator action_timer_iter_t;
+
+ /**
+ * Constructor.
+ *
+ * @param action_cb - callback which will be called each time after passed action period.
+ * @param action_period - time in seconds timer should tick.
+ * @param speaker_id - LLUUID of speaker which will be passed into action callback.
+ */
+ LLSpeakerActionTimer(action_callback_t action_cb, F32 action_period, const LLUUID& speaker_id);
+ virtual ~LLSpeakerActionTimer() {};
+
+ /**
+ * Implements timer "tick".
+ *
+ * If action callback is not specified returns true. Instance will be deleted by LLEventTimer::updateClass().
+ */
+ virtual BOOL tick();
+
+private:
+ action_callback_t mActionCallback;
+ LLUUID mSpeakerId;
+};
+
+/**
+ * Represents a functionality to store actions for speakers with delay.
+ * Is based on LLSpeakerActionTimer.
+ */
+class LLSpeakersDelayActionsStorage
+{
+public:
+ LLSpeakersDelayActionsStorage(LLSpeakerActionTimer::action_callback_t action_cb, F32 action_delay);
+ ~LLSpeakersDelayActionsStorage();
+
+ /**
+ * Sets new LLSpeakerActionTimer with passed speaker UUID.
+ */
+ void setActionTimer(const LLUUID& speaker_id);
+
+ /**
+ * Removes stored LLSpeakerActionTimer for passed speaker UUID from internal map and deletes it.
+ *
+ * @see onTimerActionCallback()
+ */
+ void unsetActionTimer(const LLUUID& speaker_id);
+
+ void removeAllTimers();
+private:
+ /**
+ * Callback of the each instance of LLSpeakerActionTimer.
+ *
+ * Unsets an appropriate timer instance and calls action callback for specified speacker_id.
+ * It always returns false to not use LLEventTimer::updateClass functionality of timer deleting.
+ *
+ * @see unsetActionTimer()
+ */
+ bool onTimerActionCallback(const LLUUID& speaker_id);
+
+ LLSpeakerActionTimer::action_timers_map_t mActionTimersMap;
+ LLSpeakerActionTimer::action_callback_t mActionCallback;
+
+ /**
+ * Delay to call action callback for speakers after timer was set.
+ */
+ F32 mActionDelay;
+
+};
+
+
class LLSpeakerMgr : public LLOldEvents::LLObservable
{
public:
@@ -144,6 +229,8 @@ public:
protected:
virtual void updateSpeakerList();
+ void setSpeakerNotInChannel(LLSpeaker* speackerp);
+ bool removeSpeaker(const LLUUID& speaker_id);
typedef std::map<LLUUID, LLPointer<LLSpeaker> > speaker_map_t;
speaker_map_t mSpeakers;
@@ -151,6 +238,11 @@ protected:
speaker_list_t mSpeakersSorted;
LLFrameTimer mSpeechTimer;
LLVoiceChannel* mVoiceChannel;
+
+ /**
+ * time out speakers when they are not part of current session
+ */
+ LLSpeakersDelayActionsStorage* mSpeakerDelayRemover;
};
class LLIMSpeakerMgr : public LLSpeakerMgr
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 88b4c34e2b..6b816f8786 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -307,59 +307,6 @@ void update_texture_fetch()
gTextureList.updateImages(0.10f);
}
-//Copies landmarks from the "Library" to "My Favorites"
-void populate_favorites_bar()
-{
- //*TODO consider extending LLInventoryModel::findCategoryUUIDForType(...) to support both root's
- LLInventoryModel::cat_array_t* lib_cats = NULL;
- LLInventoryModel::item_array_t* lib_items = NULL;
- gInventory.getDirectDescendentsOf(gInventory.getLibraryRootFolderID(), lib_cats, lib_items);
- if (!lib_cats) return;
-
- LLUUID lib_landmarks(LLUUID::null);
- S32 count = lib_cats->count();
- for(S32 i = 0; i < count; ++i)
- {
- if(lib_cats->get(i)->getPreferredType() == LLFolderType::FT_LANDMARK)
- {
- lib_landmarks = lib_cats->get(i)->getUUID();
- break;
- }
- }
- if (lib_landmarks.isNull())
- {
- llerror("Library inventory is missing Landmarks", 0);
- return;
- }
-
- LLInventoryModel::cat_array_t* lm_cats = NULL;
- LLInventoryModel::item_array_t* lm_items = NULL;
- gInventory.getDirectDescendentsOf(lib_landmarks, lm_cats, lm_items);
- if (!lm_items) return;
-
- const LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
- if (favorites_id.isNull())
- {
- llerror("My Inventory is missing My Favorites", 0);
- return;
- }
-
- S32 lm_count = lm_items->count();
- for (S32 i = 0; i < lm_count; ++i)
- {
- LLInventoryItem* item = lm_items->get(i);
- if (item->getUUID().isNull()) continue;
-
- copy_inventory_item(gAgent.getID(),
- item->getPermissions().getOwner(),
- item->getUUID(),
- favorites_id,
- std::string(),
- LLPointer<LLInventoryCallback>(NULL));
- }
-}
-
-
// Returns false to skip other idle processing. Should only return
// true when all initialization done.
bool idle_startup()
@@ -1705,12 +1652,6 @@ bool idle_startup()
llinfos << "Creating Inventory Views" << llendl;
LLFloaterReg::getInstance("inventory");
- //default initial content for Favorites Bar
- if (gAgent.isFirstLogin())
- {
- populate_favorites_bar();
- }
-
LLStartUp::setStartupState( STATE_MISC );
return FALSE;
}
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index 4a7d784c3e..84c8b9d5f0 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -1140,6 +1140,10 @@ LLTexLayerInterface::LLTexLayerInterface(const LLTexLayerInterface &layer, LLWea
BOOL LLTexLayerInterface::setInfo(const LLTexLayerInfo *info, LLWearable* wearable ) // This sets mInfo and calls initialization functions
{
//llassert(mInfo == NULL); // nyx says this is probably bogus but needs investigating
+ if (mInfo != NULL) // above llassert(), but softened into a warning
+ {
+ llwarns << "BAD STUFF! mInfo != NULL" << llendl;
+ }
mInfo = info;
//mID = info->mID; // No ID
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 9c4825763b..2b846d33fc 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -1103,7 +1103,10 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op)
{
if (op == TEXTURE_CANCEL)
mViewModel->resetDirty();
- else
+ // If the "no_commit_on_selection" parameter is set
+ // we get dirty only when user presses OK in the picker
+ // (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
+ else if (mCommitOnSelection || op == TEXTURE_SELECT)
mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
if( floaterp->isDirty() )
@@ -1125,7 +1128,7 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op)
{
// If the "no_commit_on_selection" parameter is set
// we commit only when user presses OK in the picker
- // (i.e. op == TEXTURE_SELECT) or changes texture via DnD.
+ // (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
if (mCommitOnSelection || op == TEXTURE_SELECT)
onCommit();
}
@@ -1165,6 +1168,9 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
{
if(doDrop(item))
{
+ if (!mCommitOnSelection)
+ mViewModel->setDirty();
+
// This removes the 'Multiple' overlay, since
// there is now only one texture selected.
setTentative( FALSE );
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 023329a9b2..8ca92c3d87 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -74,7 +74,8 @@ public:
Optional<std::string> default_image_name;
Optional<bool> allow_no_texture;
Optional<bool> can_apply_immediately;
- Optional<bool> no_commit_on_selection; // don't commit unless it's DnD or OK button press
+ Optional<bool> no_commit_on_selection; // alternative mode: commit occurs and the widget gets dirty
+ // only on DnD or when OK is pressed in the picker
Optional<S32> label_width;
Optional<LLUIColor> border_color;
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index da68af1597..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;
@@ -661,341 +658,352 @@ static bool needs_tooltip(LLSelectNode* nodep)
return false;
}
-BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask)
-{
- if (!LLUI::sSettingGroups["config"]->getBOOL("ShowHoverTips")) return TRUE;
- if (!mHoverPick.isValid()) return TRUE;
-
- LLViewerObject* hover_object = mHoverPick.getObject();
-
- // update hover object and hover parcel
- LLSelectMgr::getInstance()->setHoverObject(hover_object, mHoverPick.mObjectFace);
- if (mHoverPick.mPickType == LLPickInfo::PICK_LAND)
+BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg)
+{
+ LLViewerParcelMgr::getInstance()->setHoverParcel( mHoverPick.mPosGlobal );
+ //
+ // Do not show hover for land unless prefs are set to allow it.
+ //
+
+ if (!gSavedSettings.getBOOL("ShowLandHoverTip")) return TRUE;
+
+ // Didn't hit an object, but since we have a land point we
+ // must be hovering over land.
+
+ LLParcel* hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
+ LLUUID owner;
+ S32 width = 0;
+ S32 height = 0;
+
+ if ( hover_parcel )
{
- LLViewerParcelMgr::getInstance()->setHoverParcel( mHoverPick.mPosGlobal );
+ owner = hover_parcel->getOwnerID();
+ width = S32(LLViewerParcelMgr::getInstance()->getHoverParcelWidth());
+ height = S32(LLViewerParcelMgr::getInstance()->getHoverParcelHeight());
}
-
- std::string tooltip_msg;
- std::string line;
-
- if ( hover_object )
+
+ // Line: "Land"
+ line.clear();
+ line.append(LLTrans::getString("TooltipLand"));
+ if (hover_parcel)
+ {
+ line.append(hover_parcel->getName());
+ }
+ tooltip_msg.append(line);
+ tooltip_msg.push_back('\n');
+
+ // Line: "Owner: James Linden"
+ line.clear();
+ line.append(LLTrans::getString("TooltipOwner") + " ");
+
+ if ( hover_parcel )
{
- if ( hover_object->isHUDAttachment() )
+ std::string name;
+ if (LLUUID::null == owner)
{
- // no hover tips for HUD elements, since they can obscure
- // what the HUD is displaying
- return TRUE;
+ line.append(LLTrans::getString("TooltipPublic"));
}
-
- if ( hover_object->isAttachment() )
+ else if (hover_parcel->getIsGroupOwned())
{
- // get root of attachment then parent, which is avatar
- LLViewerObject* root_edit = hover_object->getRootEdit();
- if (!root_edit)
+ if (gCacheName->getGroupName(owner, name))
{
- // Strange parenting issue, don't show any text
- return TRUE;
+ line.append(name);
+ line.append(LLTrans::getString("TooltipIsGroup"));
}
- hover_object = (LLViewerObject*)root_edit->getParent();
- if (!hover_object)
+ else
{
- // another strange parenting issue, bail out
- return TRUE;
+ line.append(LLTrans::getString("RetrievingData"));
}
}
-
- line.clear();
- if (hover_object->isAvatar())
+ else if(gCacheName->getFullName(owner, name))
{
- // only show tooltip if same inspector not already open
- LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_avatar");
- if (!existing_inspector
- || !existing_inspector->getVisible()
- || existing_inspector->getKey()["avatar_id"].asUUID() != hover_object->getID())
- {
- std::string avatar_name;
- LLNameValue* firstname = hover_object->getNVPair("FirstName");
- LLNameValue* lastname = hover_object->getNVPair("LastName");
- if (firstname && lastname)
- {
- avatar_name = llformat("%s %s", firstname->getString(), lastname->getString());
- }
- else
- {
- avatar_name = LLTrans::getString("TooltipPerson");
- }
-
- // *HACK: We may select this object, so pretend it was clicked
- mPick = mHoverPick;
- LLInspector::Params p;
- p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>());
- p.message(avatar_name);
- p.image.name("Inspector_I");
- p.click_callback(boost::bind(showAvatarInspector, hover_object->getID()));
- p.visible_time_near(6.f);
- p.visible_time_far(3.f);
- p.delay_time(0.35f);
- p.wrap(false);
-
- LLToolTipMgr::instance().show(p);
- }
+ line.append(name);
}
else
{
- //
- // We have hit a regular object (not an avatar or attachment)
- //
-
- //
- // Default prefs will suppress display unless the object is interactive
- //
- bool show_all_object_tips =
- (bool)gSavedSettings.getBOOL("ShowAllObjectHoverTip");
- LLSelectNode *nodep = LLSelectMgr::getInstance()->getHoverNode();
-
- // only show tooltip if same inspector not already open
- LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_object");
- if (nodep &&
- (!existing_inspector
- || !existing_inspector->getVisible()
- || existing_inspector->getKey()["object_id"].asUUID() != hover_object->getID()))
- {
- if (nodep->mName.empty())
- {
- tooltip_msg.append(LLTrans::getString("TooltipNoName"));
- }
- else
- {
- tooltip_msg.append( nodep->mName );
- }
-
- bool is_time_based_media = false;
- bool is_web_based_media = false;
- bool is_media_playing = false;
-
- // Does this face have media?
- const LLTextureEntry* tep = hover_object->getTE(mHoverPick.mObjectFace);
-
- if(tep)
- {
- const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
- if (mep)
- {
- viewer_media_t media_impl = mep ? LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()) : NULL;
- LLPluginClassMedia* media_plugin = NULL;
-
- if (media_impl.notNull() && (media_impl->hasMedia()))
- {
- LLStringUtil::format_map_t args;
-
- media_plugin = media_impl->getMediaPlugin();
- if(media_plugin)
- { if(media_plugin->pluginSupportsMediaTime())
- {
- is_time_based_media = true;
- is_web_based_media = false;
- //args["[CurrentURL]"] = media_impl->getMediaURL();
- is_media_playing = media_impl->isMediaPlaying();
- }
- else
- {
- is_time_based_media = false;
- is_web_based_media = true;
- //args["[CurrentURL]"] = media_plugin->getLocation();
- }
- //tooltip_msg.append(LLTrans::getString("CurrentURL", args));
- }
- }
- }
- }
-
- // also check the primary node since sometimes it can have an action even though
- // the root node doesn't
- bool needs_tip = needs_tooltip(nodep) ||
- needs_tooltip(LLSelectMgr::getInstance()->getPrimaryHoverNode());
-
- if (show_all_object_tips || needs_tip)
- {
- // We may select this object, so pretend it was clicked
- mPick = mHoverPick;
- LLInspector::Params p;
- p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>());
- p.message(tooltip_msg);
- p.image.name("Inspector_I");
- p.click_callback(boost::bind(showObjectInspector, hover_object->getID(), mHoverPick.mObjectFace));
- p.time_based_media(is_time_based_media);
- p.web_based_media(is_web_based_media);
- p.media_playing(is_media_playing);
- p.click_playmedia_callback(boost::bind(playCurrentMedia, mHoverPick));
- p.click_homepage_callback(boost::bind(VisitHomePage, mHoverPick));
- p.visible_time_near(6.f);
- p.visible_time_far(3.f);
- p.delay_time(0.35f);
- p.wrap(false);
-
- LLToolTipMgr::instance().show(p);
- }
- }
+ line.append(LLTrans::getString("RetrievingData"));
}
}
- else if ( mHoverPick.mPickType == LLPickInfo::PICK_LAND )
+ else
{
- //
- // Do not show hover for land unless prefs are set to allow it.
- //
+ line.append(LLTrans::getString("RetrievingData"));
+ }
+ tooltip_msg.append(line);
+ tooltip_msg.push_back('\n');
+
+ // Line: "no fly, not safe, no build"
+
+ // Don't display properties for your land. This is just
+ // confusing, because you can do anything on your own land.
+ if ( hover_parcel && owner != gAgent.getID() )
+ {
+ S32 words = 0;
- if (!gSavedSettings.getBOOL("ShowLandHoverTip")) return TRUE;
-
- // Didn't hit an object, but since we have a land point we
- // must be hovering over land.
-
- LLParcel* hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
- LLUUID owner;
- S32 width = 0;
- S32 height = 0;
-
- if ( hover_parcel )
- {
- owner = hover_parcel->getOwnerID();
- width = S32(LLViewerParcelMgr::getInstance()->getHoverParcelWidth());
- height = S32(LLViewerParcelMgr::getInstance()->getHoverParcelHeight());
- }
-
- // Line: "Land"
- line.clear();
- line.append(LLTrans::getString("TooltipLand"));
- if (hover_parcel)
- {
- line.append(hover_parcel->getName());
- }
- tooltip_msg.append(line);
- tooltip_msg.push_back('\n');
-
- // Line: "Owner: James Linden"
line.clear();
- line.append(LLTrans::getString("TooltipOwner") + " ");
-
- if ( hover_parcel )
+ // JC - Keep this in the same order as the checkboxes
+ // on the land info panel
+ if ( !hover_parcel->getAllowModify() )
{
- std::string name;
- if (LLUUID::null == owner)
+ if ( hover_parcel->getAllowGroupModify() )
{
- line.append(LLTrans::getString("TooltipPublic"));
+ line.append(LLTrans::getString("TooltipFlagGroupBuild"));
}
- else if (hover_parcel->getIsGroupOwned())
+ else
{
- if (gCacheName->getGroupName(owner, name))
- {
- line.append(name);
- line.append(LLTrans::getString("TooltipIsGroup"));
- }
- else
- {
- line.append(LLTrans::getString("RetrievingData"));
- }
+ line.append(LLTrans::getString("TooltipFlagNoBuild"));
}
- else if(gCacheName->getFullName(owner, name))
+ words++;
+ }
+
+ if ( !hover_parcel->getAllowTerraform() )
+ {
+ if (words) line.append(", ");
+ line.append(LLTrans::getString("TooltipFlagNoEdit"));
+ words++;
+ }
+
+ if ( hover_parcel->getAllowDamage() )
+ {
+ if (words) line.append(", ");
+ line.append(LLTrans::getString("TooltipFlagNotSafe"));
+ words++;
+ }
+
+ // Maybe we should reflect the estate's block fly bit here as well? DK 12/1/04
+ if ( !hover_parcel->getAllowFly() )
+ {
+ if (words) line.append(", ");
+ line.append(LLTrans::getString("TooltipFlagNoFly"));
+ words++;
+ }
+
+ if ( !hover_parcel->getAllowOtherScripts() )
+ {
+ if (words) line.append(", ");
+ if ( hover_parcel->getAllowGroupScripts() )
{
- line.append(name);
+ line.append(LLTrans::getString("TooltipFlagGroupScripts"));
}
else
{
- line.append(LLTrans::getString("RetrievingData"));
+ line.append(LLTrans::getString("TooltipFlagNoScripts"));
}
+
+ words++;
}
- else
+
+ if (words)
{
- line.append(LLTrans::getString("RetrievingData"));
+ tooltip_msg.append(line);
+ tooltip_msg.push_back('\n');
}
+ }
+
+ if (hover_parcel && hover_parcel->getParcelFlag(PF_FOR_SALE))
+ {
+ LLStringUtil::format_map_t args;
+ args["[AMOUNT]"] = llformat("%d", hover_parcel->getSalePrice());
+ line = LLTrans::getString("TooltipForSaleL$", args);
tooltip_msg.append(line);
tooltip_msg.push_back('\n');
+ }
+
+ // trim last newlines
+ if (!tooltip_msg.empty())
+ {
+ tooltip_msg.erase(tooltip_msg.size() - 1);
+ LLToolTipMgr::instance().show(tooltip_msg);
+ }
+
+ return TRUE;
+}
- // Line: "no fly, not safe, no build"
-
- // Don't display properties for your land. This is just
- // confusing, because you can do anything on your own land.
- if ( hover_parcel && owner != gAgent.getID() )
+BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string line, std::string tooltip_msg)
+{
+ if ( hover_object->isHUDAttachment() )
+ {
+ // no hover tips for HUD elements, since they can obscure
+ // what the HUD is displaying
+ return TRUE;
+ }
+
+ if ( hover_object->isAttachment() )
+ {
+ // get root of attachment then parent, which is avatar
+ LLViewerObject* root_edit = hover_object->getRootEdit();
+ if (!root_edit)
{
- S32 words = 0;
-
- line.clear();
- // JC - Keep this in the same order as the checkboxes
- // on the land info panel
- if ( !hover_parcel->getAllowModify() )
+ // Strange parenting issue, don't show any text
+ return TRUE;
+ }
+ hover_object = (LLViewerObject*)root_edit->getParent();
+ if (!hover_object)
+ {
+ // another strange parenting issue, bail out
+ return TRUE;
+ }
+ }
+
+ line.clear();
+ if (hover_object->isAvatar())
+ {
+ // only show tooltip if same inspector not already open
+ LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_avatar");
+ if (!existing_inspector
+ || !existing_inspector->getVisible()
+ || existing_inspector->getKey()["avatar_id"].asUUID() != hover_object->getID())
+ {
+ std::string avatar_name;
+ LLNameValue* firstname = hover_object->getNVPair("FirstName");
+ LLNameValue* lastname = hover_object->getNVPair("LastName");
+ if (firstname && lastname)
{
- if ( hover_parcel->getAllowGroupModify() )
- {
- line.append(LLTrans::getString("TooltipFlagGroupBuild"));
- }
- else
- {
- line.append(LLTrans::getString("TooltipFlagNoBuild"));
- }
- words++;
+ avatar_name = llformat("%s %s", firstname->getString(), lastname->getString());
}
-
- if ( !hover_parcel->getAllowTerraform() )
+ else
{
- if (words) line.append(", ");
- line.append(LLTrans::getString("TooltipFlagNoEdit"));
- words++;
+ avatar_name = LLTrans::getString("TooltipPerson");
}
-
- if ( hover_parcel->getAllowDamage() )
+
+ // *HACK: We may select this object, so pretend it was clicked
+ mPick = mHoverPick;
+ LLInspector::Params p;
+ p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>());
+ p.message(avatar_name);
+ p.image.name("Inspector_I");
+ p.click_callback(boost::bind(showAvatarInspector, hover_object->getID()));
+ p.visible_time_near(6.f);
+ p.visible_time_far(3.f);
+ p.delay_time(0.35f);
+ p.wrap(false);
+
+ LLToolTipMgr::instance().show(p);
+ }
+ }
+ else
+ {
+ //
+ // We have hit a regular object (not an avatar or attachment)
+ //
+
+ //
+ // Default prefs will suppress display unless the object is interactive
+ //
+ bool show_all_object_tips =
+ (bool)gSavedSettings.getBOOL("ShowAllObjectHoverTip");
+ LLSelectNode *nodep = LLSelectMgr::getInstance()->getHoverNode();
+
+ // only show tooltip if same inspector not already open
+ LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_object");
+ if (nodep &&
+ (!existing_inspector
+ || !existing_inspector->getVisible()
+ || existing_inspector->getKey()["object_id"].asUUID() != hover_object->getID()))
+ {
+ if (nodep->mName.empty())
{
- if (words) line.append(", ");
- line.append(LLTrans::getString("TooltipFlagNotSafe"));
- words++;
+ tooltip_msg.append(LLTrans::getString("TooltipNoName"));
}
-
- // Maybe we should reflect the estate's block fly bit here as well? DK 12/1/04
- if ( !hover_parcel->getAllowFly() )
+ else
{
- if (words) line.append(", ");
- line.append(LLTrans::getString("TooltipFlagNoFly"));
- words++;
+ tooltip_msg.append( nodep->mName );
}
-
- if ( !hover_parcel->getAllowOtherScripts() )
+
+ bool is_time_based_media = false;
+ bool is_web_based_media = false;
+ bool is_media_playing = false;
+
+ // Does this face have media?
+ const LLTextureEntry* tep = hover_object->getTE(mHoverPick.mObjectFace);
+
+ if(tep)
{
- if (words) line.append(", ");
- if ( hover_parcel->getAllowGroupScripts() )
+ const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
+ if (mep)
{
- line.append(LLTrans::getString("TooltipFlagGroupScripts"));
- }
- else
- {
- line.append(LLTrans::getString("TooltipFlagNoScripts"));
+ viewer_media_t media_impl = mep ? LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()) : NULL;
+ LLPluginClassMedia* media_plugin = NULL;
+
+ if (media_impl.notNull() && (media_impl->hasMedia()))
+ {
+ LLStringUtil::format_map_t args;
+
+ media_plugin = media_impl->getMediaPlugin();
+ if(media_plugin)
+ { if(media_plugin->pluginSupportsMediaTime())
+ {
+ is_time_based_media = true;
+ is_web_based_media = false;
+ //args["[CurrentURL]"] = media_impl->getMediaURL();
+ is_media_playing = media_impl->isMediaPlaying();
+ }
+ else
+ {
+ is_time_based_media = false;
+ is_web_based_media = true;
+ //args["[CurrentURL]"] = media_plugin->getLocation();
+ }
+ //tooltip_msg.append(LLTrans::getString("CurrentURL", args));
+ }
+ }
}
-
- words++;
}
-
- if (words)
+
+ // also check the primary node since sometimes it can have an action even though
+ // the root node doesn't
+ bool needs_tip = needs_tooltip(nodep) ||
+ needs_tooltip(LLSelectMgr::getInstance()->getPrimaryHoverNode());
+
+ if (show_all_object_tips || needs_tip)
{
- tooltip_msg.append(line);
- tooltip_msg.push_back('\n');
+ // We may select this object, so pretend it was clicked
+ mPick = mHoverPick;
+ LLInspector::Params p;
+ p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>());
+ p.message(tooltip_msg);
+ p.image.name("Inspector_I");
+ p.click_callback(boost::bind(showObjectInspector, hover_object->getID(), mHoverPick.mObjectFace));
+ p.time_based_media(is_time_based_media);
+ p.web_based_media(is_web_based_media);
+ p.media_playing(is_media_playing);
+ p.click_playmedia_callback(boost::bind(playCurrentMedia, mHoverPick));
+ p.click_homepage_callback(boost::bind(VisitHomePage, mHoverPick));
+ p.visible_time_near(6.f);
+ p.visible_time_far(3.f);
+ p.delay_time(0.35f);
+ p.wrap(false);
+
+ LLToolTipMgr::instance().show(p);
}
}
+ }
+
+ return TRUE;
+}
- if (hover_parcel && hover_parcel->getParcelFlag(PF_FOR_SALE))
- {
- LLStringUtil::format_map_t args;
- args["[AMOUNT]"] = llformat("%d", hover_parcel->getSalePrice());
- line = LLTrans::getString("TooltipForSaleL$", args);
- tooltip_msg.append(line);
- tooltip_msg.push_back('\n');
- }
+BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask)
+{
+ if (!LLUI::sSettingGroups["config"]->getBOOL("ShowHoverTips")) return TRUE;
+ if (!mHoverPick.isValid()) return TRUE;
- // trim last newlines
- if (!tooltip_msg.empty())
- {
- tooltip_msg.erase(tooltip_msg.size() - 1);
- LLToolTipMgr::instance().show(tooltip_msg);
- }
- }
+ LLViewerObject* hover_object = mHoverPick.getObject();
+
+ // update hover object and hover parcel
+ LLSelectMgr::getInstance()->setHoverObject(hover_object, mHoverPick.mObjectFace);
+
+
+ std::string tooltip_msg;
+ std::string line;
+ if ( hover_object )
+ {
+ handleTooltipObject(hover_object, line, tooltip_msg );
+ }
+ else if (mHoverPick.mPickType == LLPickInfo::PICK_LAND)
+ {
+ handleTooltipLand(line, tooltip_msg);
+ }
return TRUE;
}
diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h
index 5f0e28fa95..8a4c949aef 100644
--- a/indra/newview/lltoolpie.h
+++ b/indra/newview/lltoolpie.h
@@ -89,7 +89,9 @@ private:
bool handleMediaClick(const LLPickInfo& info);
bool handleMediaHover(const LLPickInfo& info);
- bool handleMediaMouseUp();
+ bool handleMediaMouseUp();
+ BOOL handleTooltipLand(std::string line, std::string tooltip_msg);
+ BOOL handleTooltipObject( LLViewerObject* hover_object, std::string line, std::string tooltip_msg);
private:
BOOL mGrabMouseButtonDown;
diff --git a/indra/newview/lltransientdockablefloater.cpp b/indra/newview/lltransientdockablefloater.cpp
index 7e4d4988d1..9d39aa5182 100644
--- a/indra/newview/lltransientdockablefloater.cpp
+++ b/indra/newview/lltransientdockablefloater.cpp
@@ -42,11 +42,20 @@ LLTransientDockableFloater::LLTransientDockableFloater(LLDockControl* dockContro
LLDockableFloater(dockControl, uniqueDocking, key, params)
{
LLTransientFloaterMgr::getInstance()->registerTransientFloater(this);
+ LLTransientFloater::init(this);
}
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)
@@ -54,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);
}
}
@@ -77,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/lltransientdockablefloater.h b/indra/newview/lltransientdockablefloater.h
index 6e8a3afd22..e0541d6597 100644
--- a/indra/newview/lltransientdockablefloater.h
+++ b/indra/newview/lltransientdockablefloater.h
@@ -37,12 +37,13 @@
#include "llfloater.h"
#include "lldockcontrol.h"
#include "lldockablefloater.h"
+#include "lltransientfloatermgr.h"
/**
* Represents floater that can dock and managed by transient floater manager.
* Transient floaters should be hidden if user click anywhere except defined view list.
*/
-class LLTransientDockableFloater : public LLDockableFloater
+class LLTransientDockableFloater : public LLDockableFloater, LLTransientFloater
{
public:
LOG_CLASS(LLTransientDockableFloater);
@@ -52,6 +53,7 @@ public:
/*virtual*/ void setVisible(BOOL visible);
/* virtual */void setDocked(bool docked, bool pop_on_undock = true);
+ virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }
};
#endif /* LL_TRANSIENTDOCKABLEFLOATER_H */
diff --git a/indra/newview/lltransientfloatermgr.cpp b/indra/newview/lltransientfloatermgr.cpp
index 347399f239..d82403070b 100644
--- a/indra/newview/lltransientfloatermgr.cpp
+++ b/indra/newview/lltransientfloatermgr.cpp
@@ -44,57 +44,69 @@ LLTransientFloaterMgr::LLTransientFloaterMgr()
{
gViewerWindow->getRootView()->addMouseDownCallback(boost::bind(
&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*>()));
}
-void LLTransientFloaterMgr::registerTransientFloater(LLFloater* floater)
+void LLTransientFloaterMgr::registerTransientFloater(LLTransientFloater* floater)
{
mTransSet.insert(floater);
}
-void LLTransientFloaterMgr::unregisterTransientFloater(LLFloater* floater)
+void LLTransientFloaterMgr::unregisterTransientFloater(LLTransientFloater* floater)
{
mTransSet.erase(floater);
}
+void LLTransientFloaterMgr::addControlView(ETransientGroup group, LLView* view)
+{
+ mGroupControls.find(group)->second.insert(view);
+}
+
+void LLTransientFloaterMgr::removeControlView(ETransientGroup group, LLView* view)
+{
+ mGroupControls.find(group)->second.erase(view);
+}
+
void LLTransientFloaterMgr::addControlView(LLView* view)
{
- mControlsSet.insert(view);
+ addControlView(GLOBAL, view);
}
void LLTransientFloaterMgr::removeControlView(LLView* view)
{
// we will still get focus lost callbacks on this view, but that's ok
// since we run sanity checking logic every time
- mControlsSet.erase(view);
+ removeControlView(GLOBAL, view);
}
-void LLTransientFloaterMgr::hideTransientFloaters()
+void LLTransientFloaterMgr::hideTransientFloaters(S32 x, S32 y)
{
- for (std::set<LLFloater*>::iterator it = mTransSet.begin(); it
+ for (std::set<LLTransientFloater*>::iterator it = mTransSet.begin(); it
!= mTransSet.end(); it++)
{
- LLFloater* floater = *it;
- if (floater->isDocked())
+ LLTransientFloater* floater = *it;
+ if (floater->isTransientDocked())
{
- floater->setVisible(FALSE);
+ ETransientGroup group = floater->getGroup();
+
+ bool hide = isControlClicked(mGroupControls.find(group)->second, x, y);
+ if (hide)
+ {
+ floater->setTransientVisible(FALSE);
+ }
}
}
}
-void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y,
- MASK mask)
+bool LLTransientFloaterMgr::isControlClicked(std::set<LLView*>& set, S32 x, S32 y)
{
- bool hide = true;
- for (controls_set_t::iterator it = mControlsSet.begin(); it
- != mControlsSet.end(); it++)
+ bool res = true;
+ for (controls_set_t::iterator it = set.begin(); it
+ != set.end(); it++)
{
- // don't hide transient floater if any context menu opened
- if (LLMenuGL::sMenuContainer->getVisibleMenu() != NULL)
- {
- hide = false;
- break;
- }
-
LLView* control_view = *it;
if (!control_view->getVisible())
{
@@ -105,14 +117,33 @@ void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y,
// if click inside view rect
if (rect.pointInRect(x, y))
{
- hide = false;
+ res = false;
break;
}
}
+ return res;
+}
+
+void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y,
+ MASK mask)
+{
+ // don't hide transient floater if any context menu opened
+ if (LLMenuGL::sMenuContainer->getVisibleMenu() != NULL)
+ {
+ return;
+ }
+ bool hide = isControlClicked(mGroupControls.find(DOCKED)->second, x, y)
+ && isControlClicked(mGroupControls.find(GLOBAL)->second, x, y);
if (hide)
{
- hideTransientFloaters();
+ hideTransientFloaters(x, y);
}
}
+void LLTransientFloater::init(LLFloater* thiz)
+{
+ // used since LLTransientFloater(this) can't be used in descendant constructor parameter initialization.
+ mFloater = thiz;
+}
+
diff --git a/indra/newview/lltransientfloatermgr.h b/indra/newview/lltransientfloatermgr.h
index cef6e1fe45..9c5ae295f2 100644
--- a/indra/newview/lltransientfloatermgr.h
+++ b/indra/newview/lltransientfloatermgr.h
@@ -37,27 +37,60 @@
#include "llsingleton.h"
#include "llfloater.h"
+class LLTransientFloater;
/**
* Provides functionality to hide transient floaters.
*/
class LLTransientFloaterMgr: public LLSingleton<LLTransientFloaterMgr>
{
-public:
+protected:
LLTransientFloaterMgr();
- void registerTransientFloater(LLFloater* floater);
- void unregisterTransientFloater(LLFloater* floater);
+ friend class LLSingleton<LLTransientFloaterMgr>;
+
+public:
+ enum ETransientGroup
+ {
+ GLOBAL, DOCKED, IM
+ };
+
+ void registerTransientFloater(LLTransientFloater* floater);
+ void unregisterTransientFloater(LLTransientFloater* floater);
+ void addControlView(ETransientGroup group, LLView* view);
+ void removeControlView(ETransientGroup group, LLView* view);
void addControlView(LLView* view);
void removeControlView(LLView* view);
private:
- void hideTransientFloaters();
+ void hideTransientFloaters(S32 x, S32 y);
void leftMouseClickCallback(S32 x, S32 y, MASK mask);
-
+ bool isControlClicked(std::set<LLView*>& set, S32 x, S32 y);
private:
- std::set<LLFloater*> mTransSet;
+ std::set<LLTransientFloater*> mTransSet;
+
typedef std::set<LLView*> controls_set_t;
- controls_set_t mControlsSet;
+ typedef std::map<ETransientGroup, std::set<LLView*> > group_controls_t;
+ group_controls_t mGroupControls;
+};
+
+/**
+ * An abstract class declares transient floater interfaces.
+ */
+class LLTransientFloater
+{
+protected:
+ /**
+ * Class initialization method.
+ * Should be called from descendant constructor.
+ */
+ void init(LLFloater* thiz);
+public:
+ virtual LLTransientFloaterMgr::ETransientGroup getGroup() = 0;
+ bool isTransientDocked() { return mFloater->isDocked(); };
+ void setTransientVisible(BOOL visible) {mFloater->setVisible(visible); }
+
+private:
+ LLFloater* mFloater;
};
#endif // LL_LLTRANSIENTFLOATERMGR_H
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 7b9b12108d..ba256d70e8 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -483,7 +483,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected");
render_ui();
- render_disconnected_background();
}
//////////////////////////
@@ -1141,6 +1140,10 @@ void render_ui(F32 zoom_factor, int subfield)
render_ui_3d();
LLGLState::checkStates();
}
+ else
+ {
+ render_disconnected_background();
+ }
render_ui_2d();
LLGLState::checkStates();
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 3a834e7532..e87d380e4d 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -204,6 +204,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 04d67fe750..98d8780b34 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -752,6 +752,11 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
impl_count_interest_normal++;
}
+ else if(pimpl->isParcelMedia())
+ {
+ new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
+ impl_count_interest_normal++;
+ }
else
{
// Look at interest and CPU usage for instances that aren't in any of the above states.
@@ -935,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);
@@ -956,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 3f556e5608..96251f7571 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -6099,7 +6099,8 @@ class LLAttachmentEnableDrop : public view_listener_t
LLViewerJointAttachment* attachment = NULL;
LLInventoryItem* item = NULL;
- if (object)
+ // Do not enable drop if all faces of object are not enabled
+ if (object && LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES ))
{
S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getState());
attachment = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL);
@@ -6141,8 +6142,14 @@ class LLAttachmentEnableDrop : public view_listener_t
BOOL enable_detach(const LLSD&)
{
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (!object) return FALSE;
- if (!object->isAttachment()) return FALSE;
+
+ // Only enable detach if all faces of object are selected
+ if (!object ||
+ !object->isAttachment() ||
+ !LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES ))
+ {
+ return FALSE;
+ }
// Find the avatar who owns this attachment
LLViewerObject* avatar = object;
@@ -6382,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
@@ -6418,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);
}
}
}
@@ -7952,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 31a18a2e98..d6ce356c4b 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -78,6 +78,7 @@
#include "llstatenums.h"
#include "llstatusbar.h"
#include "llimview.h"
+#include "llspeakers.h"
#include "lltrans.h"
#include "llviewerfoldertype.h"
#include "lluri.h"
@@ -1364,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.
@@ -1409,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))
{
@@ -1435,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
@@ -1471,7 +1495,12 @@ void inventory_offer_handler(LLOfferInfo* info)
{
LLStringUtil::truncate(msg, indx);
}
-
+
+ if(LLAssetType::AT_LANDMARK == info->mType)
+ {
+ msg = get_display_name(msg);
+ }
+
LLSD args;
args["[OBJECTNAME]"] = msg;
@@ -1837,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;
@@ -2008,7 +2035,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// Someone has offered us some inventory.
{
LLOfferInfo* info = new LLOfferInfo;
- bool mute_im = false;
if (IM_INVENTORY_OFFERED == dialog)
{
struct offer_agent_bucket_t
@@ -2025,11 +2051,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0];
info->mType = (LLAssetType::EType) bucketp->asset_type;
info->mObjectID = bucketp->object_id;
-
- if(accept_im_from_only_friend&&!is_friend)
- {
- mute_im = true;
- }
}
else
{
@@ -2060,7 +2081,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
info->mDesc = message;
info->mHost = msg->getSender();
//if (((is_busy && !is_owned_by_me) || is_muted))
- if ( is_muted || mute_im)
+ if (is_muted)
{
// Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331)
LLInventoryFetchObserver::item_ref_t items;
@@ -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 e8b435fc8f..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();
@@ -212,22 +212,15 @@ void LLViewerParcelMedia::play(LLParcel* parcel)
else
{
// Since the texture id is different, we need to generate a new impl
- LL_DEBUGS("Media") << "new media impl with mime type " << mime_type << ", url " << media_url << LL_ENDL;
// Delete the old one first so they don't fight over the texture.
sMediaImpl = NULL;
-
- sMediaImpl = LLViewerMedia::newMediaImpl(
- placeholder_texture_id,
- media_width,
- media_height,
- media_auto_scale,
- media_loop);
- sMediaImpl->setIsParcelMedia(true);
- sMediaImpl->navigateTo(media_url, mime_type, true);
+
+ // A new impl will be created below.
}
}
- else
+
+ if(!sMediaImpl)
{
LL_DEBUGS("Media") << "new media impl with mime type " << mime_type << ", url " << media_url << LL_ENDL;
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index ad993bc056..b80dc7d902 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1560,7 +1560,11 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
void LLViewerFetchedTexture::setDecodePriority(F32 priority)
{
- llassert(!mInImageList);
+ //llassert(!mInImageList); // firing a lot, figure out why
+ if (mInImageList) // above llassert() softened to a warning
+ {
+ llwarns << "BAD STUFF! mInImageList" << llendl;
+ }
mDecodePriority = priority;
}
@@ -2773,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/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 6bb547373c..ee934ab9c5 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -502,7 +502,10 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)
{
llerrs << "LLViewerTextureList::addImageToList - Image already in list" << llendl;
}
- llverify((mImageList.insert(image)).second == true);
+ if ((mImageList.insert(image)).second != true)
+ {
+ llwarns << "BAD STUFF! (mImageList.insert(image)).second != true" << llendl;
+ }
image->setInImageList(TRUE) ;
}
@@ -519,7 +522,10 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
}
llerrs << "LLViewerTextureList::removeImageFromList - Image not in list" << llendl;
}
- llverify(mImageList.erase(image) == 1);
+ if (mImageList.erase(image) != 1)
+ {
+ llwarns << "BAD STUFF! mImageList.erase(image) != 1" << llendl;
+ }
image->setInImageList(FALSE) ;
}
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 51a75b5825..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"
@@ -63,6 +65,7 @@
#include "llparcel.h"
#include "llviewerparcelmgr.h"
//#include "llfirstuse.h"
+#include "llspeakers.h"
#include "lltrans.h"
#include "llviewerwindow.h"
#include "llviewercamera.h"
@@ -1091,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() :
@@ -4913,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;
}
@@ -5852,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;
@@ -6157,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/llvovolume.cpp b/indra/newview/llvovolume.cpp
index d5dd19e470..295c0c8010 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -1852,12 +1852,22 @@ void LLVOVolume::mediaNavigateBounceBack(U8 texture_index)
if (mep && impl)
{
std::string url = mep->getCurrentURL();
+ // Look for a ":", if not there, assume "http://"
+ if (!url.empty() && std::string::npos == url.find(':'))
+ {
+ url = "http://" + url;
+ }
// If the url we're trying to "bounce back" to is either empty or not
// allowed by the whitelist, try the home url. If *that* doesn't work,
// set the media as failed and unload it
if (url.empty() || !mep->checkCandidateUrl(url))
{
url = mep->getHomeURL();
+ // Look for a ":", if not there, assume "http://"
+ if (!url.empty() && std::string::npos == url.find(':'))
+ {
+ url = "http://" + url;
+ }
}
if (url.empty() || !mep->checkCandidateUrl(url))
{
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 70859e8ea5..c19be37e75 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -252,9 +252,8 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
// mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // usefull for debugging
mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);
mCurlRequest->setWriteCallback(&curlDownloadCallback, (void*)this);
- BOOL vefifySSLCert = !gSavedSettings.getBOOL("NoVerifySSLCert");
- mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, vefifySSLCert);
- mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, vefifySSLCert ? 2 : 0);
+ mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, LLCurl::getSSLVerify());
+ mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, LLCurl::getSSLVerify() ? 2 : 0);
// Be a little impatient about establishing connections.
mCurlRequest->setopt(CURLOPT_CONNECTTIMEOUT, 40L);
diff --git a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png
index 661d1c5611..6cb33efb93 100644
--- a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png
+++ b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png
index f927fd3989..6cb33efb93 100644
--- a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png
+++ b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml
index faa24b5877..eb63b5c975 100644
--- a/indra/newview/skins/default/xui/da/floater_about.xml
+++ b/indra/newview/skins/default/xui/da/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_about" title="OM [APP_NAME]">
+<floater name="floater_about" title="OM [CAPITALIZED_APP_NAME]">
<floater.string name="AboutHeader">
[APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2] ([VIEWER_VERSION_3]) [BUILD_DATE] [BUILD_TIME] ([CHANNEL])
[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]
diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml
index 664c6e3072..0beb54032f 100644
--- a/indra/newview/skins/default/xui/de/floater_about.xml
+++ b/indra/newview/skins/default/xui/de/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_about" title="INFO ÜBER [APP_NAME]">
+<floater name="floater_about" title="INFO ÜBER [CAPITALIZED_APP_NAME]">
<floater.string name="AboutHeader">
[APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2] ([VIEWER_VERSION_3]) [BUILD_DATE] [BUILD_TIME] ([CHANNEL])
[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]
diff --git a/indra/newview/skins/default/xui/de/panel_edit_profile.xml b/indra/newview/skins/default/xui/de/panel_edit_profile.xml
index 1c53ca64dd..811ca118d6 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_profile.xml
@@ -39,7 +39,7 @@
<line_editor name="homepage_edit" value="http://"/>
<check_box label="In Suchergebnissen anzeigen" name="show_in_search_checkbox"/>
<text name="title_acc_status_text" value="Mein Konto:"/>
- <text name="my_account_link" value="Meine Startseite aufrufen"/>
+ <text name="my_account_link" value="[[URL] Meine Startseite aufrufen]"/>
<text name="acc_status_text" value="Einwohner. Keine Zahlungsinfo archiviert."/>
<text name="title_partner_text" value="Mein Partner:"/>
<text name="partner_edit_link" value="[[URL] bearbeiten]"/>
diff --git a/indra/newview/skins/default/xui/en/favorites_bar_button.xml b/indra/newview/skins/default/xui/en/favorites_bar_button.xml
index dfb0695ec3..b365040c20 100644
--- a/indra/newview/skins/default/xui/en/favorites_bar_button.xml
+++ b/indra/newview/skins/default/xui/en/favorites_bar_button.xml
@@ -3,7 +3,6 @@
<!-- All buttons in the Favorites bar will be created from this one -->
<button
follows="left|bottom"
- font_halign="center"
halign="center"
height="15"
image_disabled="transparent.j2c"
@@ -11,6 +10,8 @@
image_selected="transparent.j2c"
image_unselected="transparent.j2c"
image_pressed="Favorite_Link_Over"
+ image_hover_selected="Favorite_Link_Over"
+ image_hover_unselected="Favorite_Link_Over"
hover_glow_amount="0.15"
label_shadow="false"
layout="topleft"
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_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index c58c1f00b9..61ca783d14 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1871,13 +1871,14 @@ Only large parcels can be listed in search.
layout="topleft"
left="110"
name="parcel_enable_voice_channel_is_estate_disabled"
+ top_delta="0"
width="300" />
<check_box
height="16"
label="Restrict Voice to this parcel"
layout="topleft"
left="110"
- name="parcel_enable_voice_channel_parcel"
+ name="parcel_enable_voice_channel_local"
width="300" />
</panel>
<panel
diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
index d202bf1b9f..8f67f564a2 100644
--- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
@@ -304,7 +304,7 @@ Re-enter amount to see the latest exchange rate.
</text>
<text
type="string"
- width="175"
+ width="176"
height="125"
top="60"
left="165"
diff --git a/indra/newview/skins/default/xui/en/floater_customize.xml b/indra/newview/skins/default/xui/en/floater_customize.xml
index ddc0d9af72..b048eeceb6 100644
--- a/indra/newview/skins/default/xui/en/floater_customize.xml
+++ b/indra/newview/skins/default/xui/en/floater_customize.xml
@@ -3,7 +3,7 @@
legacy_header_height="18"
can_minimize="false"
follows="left|top"
- height="607"
+ height="583"
layout="topleft"
left_delta="-3"
name="floater customize"
@@ -20,7 +20,7 @@
tab_min_width="96"
tab_position="left"
tab_height="50"
- top="50"
+ top="26"
width="506">
<text
type="string"
@@ -184,7 +184,6 @@
layout="topleft"
name="radio2"
value="1"
- top="32"
width="82" />
</radio_group>
<text
@@ -270,9 +269,9 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="no modify instructions"
- top_delta="0"
+ top="31"
word_wrap="true"
width="373">
You do not have permission to modify this wearable.
@@ -473,9 +472,9 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="no modify instructions"
- top_delta="0"
+ top="31"
word_wrap="true"
width="373">
You do not have permission to modify this wearable.
@@ -723,9 +722,9 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="no modify instructions"
- top_delta="0"
+ top="31"
word_wrap="true"
width="373">
You do not have permission to modify this wearable.
@@ -798,16 +797,16 @@
width="82" />
</panel>
<panel
- border="true"
+ border="false"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
follows="left|top|right|bottom"
- height="481"
+ height="508"
label="Eyes"
layout="topleft"
- left_delta="0"
name="Eyes"
help_topic="customize_eyes_tab"
- top_delta="0"
- width="389">
+ width="400">
<icon
follows="top|right"
height="18"
@@ -820,10 +819,10 @@
width="18" />
<icon
height="16"
+ top="10"
+ left="10"
layout="topleft"
- left_delta="-325"
mouse_opaque="true"
- top_delta="3"
width="16" />
<text
type="string"
@@ -832,9 +831,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_pad="2"
+ left="31"
name="title"
- top_delta="0"
+ top="10"
width="355">
[DESC]
</text>
@@ -845,9 +844,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_no_modify"
- top_delta="0"
+ top="10"
width="355">
[DESC]: cannot modify
</text>
@@ -858,9 +857,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_loading"
- top_delta="0"
+ top="10"
width="355">
[DESC]: loading...
</text>
@@ -871,21 +870,21 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_not_worn"
- top_delta="0"
+ top="10"
width="355">
[DESC]: not worn
</text>
<text
type="string"
length="1"
- follows="left|top|right"
- height="14"
+ follows="left|top"
+ height="16"
layout="topleft"
- left="8"
+ left="10"
name="path"
- top="24"
+ top="36"
width="373">
Located in [PATH]
</text>
@@ -895,9 +894,9 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="not worn instructions"
- top_pad="8"
+ top="31"
word_wrap="true"
width="373">
Put on a new set of eyes by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
@@ -908,9 +907,9 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="no modify instructions"
- top_delta="0"
+ top="31"
word_wrap="true"
width="373">
You do not have permission to modify this wearable.
@@ -918,14 +917,14 @@
<text
type="string"
length="1"
- bottom="486"
- follows="left|top|right"
+ bottom="4"
+ follows="left|bottom|right"
font="SansSerif"
halign="right"
- height="28"
- layout="topleft"
+ height="23"
+ layout="bottomleft"
name="Item Action Label"
- right="117"
+ right="132"
width="100">
Eyes:
</text>
@@ -933,23 +932,22 @@
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
+ height="108"
label="Iris"
layout="topleft"
- left="8"
+ left="10"
name="Iris"
tool_tip="Click to choose a picture"
- top="65"
- width="64" />
+ top="66"
+ width="82" />
<button
follows="left|top"
height="23"
label="Create New Eyes"
label_selected="Create New Eyes"
layout="topleft"
- left_delta="0"
name="Create New"
- top_delta="39"
+ top="66"
width="160" />
<button
follows="right|bottom"
@@ -957,9 +955,9 @@
label="Save"
label_selected="Save"
layout="topleft"
- left="123"
+ right="218"
name="Save"
- top="458"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -967,9 +965,9 @@
label="Save As..."
label_selected="Save As..."
layout="topleft"
- left_pad="6"
+ right="304"
name="Save As"
- top_delta="0"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -977,9 +975,9 @@
label="Revert"
label_selected="Revert"
layout="topleft"
- left_pad="6"
+ right="390"
name="Revert"
- top_delta="0"
+ top="477"
width="82" />
</panel>
<text
@@ -997,85 +995,83 @@
</text>
<placeholder />
<panel
- border="true"
+ border="false"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
follows="left|top|right|bottom"
- height="481"
+ height="508"
label="Shirt"
layout="topleft"
- left_delta="0"
name="Shirt"
help_topic="customize_shirt_tab"
top_delta="0"
- width="389">
+ width="400">
<icon
- follows="top|right"
+ follows="top|left"
height="18"
image_name="Lock"
layout="topleft"
- left="315"
+ left="10"
mouse_opaque="true"
name="square"
- top="4"
+ top="10"
width="18" />
<icon
height="16"
+ top="10"
+ left="10"
layout="topleft"
- left="8"
mouse_opaque="true"
- top_delta="3"
width="16" />
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
+ height="108"
label="Fabric"
layout="topleft"
- left_delta="0"
+ left="10"
name="Fabric"
tool_tip="Click to choose a picture"
- top_pad="41"
- width="64" />
+ top="66"
+ width="82" />
<color_swatch
can_apply_immediately="true"
follows="left|top"
- height="80"
+ height="108"
label="Color/Tint"
layout="topleft"
- left_delta="0"
name="Color/Tint"
tool_tip="Click to open color picker"
- top_delta="80"
- width="64" />
- <button
- follows="left|top"
- height="23"
- label="Create New Shirt"
- label_selected="Create New Shirt"
- layout="topleft"
- left_delta="0"
- name="Create New"
- top_delta="-41"
- width="160" />
+ top_delta="102"
+ width="82" />
<button
follows="left|top"
height="23"
label="Take Off"
label_selected="Take Off"
layout="topleft"
- left_delta="0"
name="Take Off"
- top_pad="102"
+ top_pad="4"
width="82" />
<button
+ follows="left|top"
+ height="23"
+ label="Create New Shirt"
+ label_selected="Create New Shirt"
+ layout="topleft"
+ name="Create New"
+ top="66"
+ width="160" />
+ <button
follows="right|bottom"
height="23"
label="Save"
label_selected="Save"
layout="topleft"
- left="123"
+ right="218"
name="Save"
- top="458"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -1083,9 +1079,9 @@
label="Save As..."
label_selected="Save As..."
layout="topleft"
- left_pad="6"
+ right="304"
name="Save As"
- top_delta="0"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -1093,9 +1089,9 @@
label="Revert"
label_selected="Revert"
layout="topleft"
- left_pad="6"
+ right="390"
name="Revert"
- top_delta="0"
+ top="477"
width="82" />
<text
type="string"
@@ -1104,9 +1100,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left="8"
+ left="31"
name="title"
- top="8"
+ top="10"
width="355">
[DESC]
</text>
@@ -1117,9 +1113,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_no_modify"
- top_delta="0"
+ top="10"
width="355">
[DESC]: cannot modify
</text>
@@ -1130,9 +1126,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_loading"
- top_delta="0"
+ top="10"
width="355">
[DESC]: loading...
</text>
@@ -1143,21 +1139,21 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_not_worn"
- top_delta="0"
+ top="10"
width="355">
[DESC]: not worn
</text>
<text
type="string"
length="1"
- follows="left|top|right"
- height="14"
+ follows="left|top"
+ height="16"
layout="topleft"
- left="8"
+ left="10"
name="path"
- top="24"
+ top="36"
width="373">
Located in [PATH]
</text>
@@ -1167,9 +1163,9 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="not worn instructions"
- top_pad="8"
+ top="31"
word_wrap="true"
width="373">
Put on a new shirt by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
@@ -1180,9 +1176,9 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="no modify instructions"
- top_delta="0"
+ top="31"
word_wrap="true"
width="373">
You do not have permission to modify this wearable.
@@ -1190,98 +1186,95 @@
<text
type="string"
length="1"
- bottom="486"
- follows="left|top|right"
+ bottom="4"
+ follows="left|bottom|right"
font="SansSerif"
halign="right"
- height="28"
- layout="topleft"
+ height="23"
+ layout="bottomleft"
name="Item Action Label"
- right="117"
+ right="132"
width="100">
Shirt:
</text>
</panel>
<panel
- border="true"
+ border="false"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
follows="left|top|right|bottom"
- height="481"
+ height="508"
label="Pants"
layout="topleft"
- left_delta="0"
name="Pants"
help_topic="customize_pants_tab"
- top_delta="0"
- width="389">
+ width="400">
<icon
- follows="top|right"
+ follows="top|left"
height="18"
image_name="Lock"
layout="topleft"
- left="315"
+ left="10"
mouse_opaque="true"
name="square"
- top="4"
+ top="10"
width="18" />
<icon
height="16"
layout="topleft"
- left="8"
+ left="10"
mouse_opaque="true"
- top_delta="3"
+ top="10"
width="16" />
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
+ height="108"
label="Fabric"
layout="topleft"
- left_delta="0"
+ left="10"
name="Fabric"
tool_tip="Click to choose a picture"
- top_pad="41"
- width="64" />
+ top="66"
+ width="82" />
<color_swatch
can_apply_immediately="true"
follows="left|top"
- height="80"
+ height="108"
label="Color/Tint"
layout="topleft"
- left_delta="0"
name="Color/Tint"
tool_tip="Click to open color picker"
- top_delta="80"
- width="64" />
- <button
- follows="left|top"
- height="23"
- label="Create New Pants"
- label_selected="Create New Pants"
- layout="topleft"
- left_delta="0"
- name="Create New"
- top_delta="-41"
- width="160" />
+ top_delta="102"
+ width="82" />
<button
follows="left|top"
height="23"
label="Take Off"
label_selected="Take Off"
layout="topleft"
- left_delta="0"
name="Take Off"
- top_pad="102"
+ top_pad="4"
width="82" />
<button
+ follows="left|top"
+ height="23"
+ label="Create New Pants"
+ label_selected="Create New Pants"
+ layout="topleft"
+ name="Create New"
+ top="66"
+ width="160" />
+ <button
follows="right|bottom"
height="23"
label="Save"
label_selected="Save"
layout="topleft"
- left="123"
+ right="218"
name="Save"
- top="458"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -1289,9 +1282,9 @@
label="Save As..."
label_selected="Save As..."
layout="topleft"
- left_pad="6"
+ right="304"
name="Save As"
- top_delta="0"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -1299,9 +1292,9 @@
label="Revert"
label_selected="Revert"
layout="topleft"
- left_pad="6"
+ right="390"
name="Revert"
- top_delta="0"
+ top="477"
width="82" />
<text
type="string"
@@ -1310,9 +1303,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left="8"
+ left="31"
name="title"
- top="8"
+ top="10"
width="355">
[DESC]
</text>
@@ -1323,9 +1316,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_no_modify"
- top_delta="0"
+ top="10"
width="355">
[DESC]: cannot modify
</text>
@@ -1336,9 +1329,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_loading"
- top_delta="0"
+ top="10"
width="355">
[DESC]: loading...
</text>
@@ -1349,9 +1342,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_not_worn"
- top_delta="0"
+ top="10"
width="355">
[DESC]: not worn
</text>
@@ -1361,9 +1354,9 @@
follows="left|top|right"
height="14"
layout="topleft"
- left="8"
+ left="10"
name="path"
- top="24"
+ top="36"
width="373">
Located in [PATH]
</text>
@@ -1373,9 +1366,9 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="not worn instructions"
- top_pad="8"
+ top="31"
word_wrap="true"
width="373">
Put on new pants by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
@@ -1386,9 +1379,9 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="no modify instructions"
- top_delta="0"
+ top="31"
word_wrap="true"
width="373">
You do not have permission to modify this wearable.
@@ -1396,45 +1389,45 @@
<text
type="string"
length="1"
- bottom="486"
- follows="left|top|right"
+ bottom="4"
+ follows="left|bottom|right"
font="SansSerif"
halign="right"
- height="28"
- layout="topleft"
+ height="23"
+ layout="bottomleft"
name="Item Action Label"
- right="117"
+ right="132"
width="100">
Pants:
</text>
</panel>
<panel
- border="true"
+ border="false"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
follows="left|top|right|bottom"
- height="481"
+ height="508"
label="Shoes"
layout="topleft"
- left_delta="0"
name="Shoes"
help_topic="customize_shoes_tab"
- top_delta="0"
- width="389">
+ width="400">
<icon
- follows="top|right"
+ follows="top|left"
height="18"
image_name="Lock"
layout="topleft"
- left="315"
+ left="10"
mouse_opaque="true"
name="square"
- top="4"
+ top="10"
width="18" />
<icon
height="16"
layout="topleft"
- left_delta="-325"
+ left="10"
mouse_opaque="true"
- top_delta="3"
+ top="10"
width="16" />
<text
type="string"
@@ -1443,9 +1436,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_pad="2"
+ left="31"
name="title"
- top_delta="0"
+ top="10"
width="355">
[DESC]
</text>
@@ -1456,9 +1449,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_no_modify"
- top_delta="0"
+ top="10"
width="355">
[DESC]: cannot modify
</text>
@@ -1469,9 +1462,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_loading"
- top_delta="0"
+ top="10"
width="355">
[DESC]: loading...
</text>
@@ -1482,9 +1475,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_not_worn"
- top_delta="0"
+ top="10"
width="355">
[DESC]: not worn
</text>
@@ -1494,9 +1487,9 @@
follows="left|top|right"
height="14"
layout="topleft"
- left="8"
+ left="10"
name="path"
- top="24"
+ top="36"
width="373">
Located in [PATH]
</text>
@@ -1506,22 +1499,31 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="not worn instructions"
- top_pad="8"
+ top="31"
word_wrap="true"
width="373">
Put on a new pair of shoes by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
</text>
+ <button
+ follows="left|top"
+ height="23"
+ label="Create New Shoes"
+ label_selected="Create New Shoes"
+ layout="topleft"
+ name="Create New"
+ top_pad="18"
+ width="160" />
<text
type="string"
length="1"
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="no modify instructions"
- top_delta="0"
+ top="31"
word_wrap="true"
width="373">
You do not have permission to modify this wearable.
@@ -1529,14 +1531,14 @@
<text
type="string"
length="1"
- bottom="486"
- follows="left|top|right"
+ bottom="4"
+ follows="left|bottom|right"
font="SansSerif"
halign="right"
- height="28"
- layout="topleft"
+ height="23"
+ layout="bottomleft"
name="Item Action Label"
- right="117"
+ right="132"
width="100">
Shoes:
</text>
@@ -1544,44 +1546,32 @@
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
+ height="108"
label="Fabric"
layout="topleft"
- left="8"
+ left="10"
name="Fabric"
tool_tip="Click to choose a picture"
- top="65"
- width="64" />
+ top="66"
+ width="82" />
<color_swatch
can_apply_immediately="true"
follows="left|top"
- height="80"
+ height="108"
label="Color/Tint"
layout="topleft"
- left_delta="0"
name="Color/Tint"
tool_tip="Click to open color picker"
- top_delta="80"
- width="64" />
- <button
- follows="left|top"
- height="23"
- label="Create New Shoes"
- label_selected="Create New Shoes"
- layout="topleft"
- left_delta="0"
- name="Create New"
- top_delta="-41"
- width="160" />
+ top_delta="102"
+ width="82" />
<button
follows="left|top"
height="23"
label="Take Off"
label_selected="Take Off"
layout="topleft"
- left_delta="0"
name="Take Off"
- top_pad="102"
+ top_pad="4"
width="82" />
<button
follows="right|bottom"
@@ -1589,9 +1579,9 @@
label="Save"
label_selected="Save"
layout="topleft"
- left="123"
+ right="218"
name="Save"
- top="458"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -1599,9 +1589,9 @@
label="Save As..."
label_selected="Save As..."
layout="topleft"
- left_pad="6"
+ right="304"
name="Save As"
- top_delta="0"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -1609,38 +1599,38 @@
label="Revert"
label_selected="Revert"
layout="topleft"
- left_pad="6"
+ right="390"
name="Revert"
- top_delta="0"
+ top="477"
width="82" />
</panel>
<panel
- border="true"
+ border="false"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
follows="left|top|right|bottom"
- height="481"
+ height="508"
label="Socks"
layout="topleft"
- left_delta="0"
name="Socks"
help_topic="customize_socks_tab"
- top_delta="0"
- width="389">
+ width="400">
<icon
- follows="top|right"
+ follows="top|left"
height="18"
image_name="Lock"
layout="topleft"
- left="315"
+ left="10"
mouse_opaque="true"
name="square"
- top="4"
+ top="10"
width="18" />
<icon
height="16"
layout="topleft"
- left_delta="-325"
+ left="10"
mouse_opaque="true"
- top_delta="3"
+ top="10"
width="16" />
<text
type="string"
@@ -1649,9 +1639,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_pad="2"
+ left="31"
name="title"
- top_delta="0"
+ top="10"
width="355">
[DESC]
</text>
@@ -1662,9 +1652,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_no_modify"
- top_delta="0"
+ top="10"
width="355">
[DESC]: cannot modify
</text>
@@ -1675,9 +1665,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_loading"
- top_delta="0"
+ top="10"
width="355">
[DESC]: loading...
</text>
@@ -1688,9 +1678,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_not_worn"
- top_delta="0"
+ top="10"
width="355">
[DESC]: not worn
</text>
@@ -1700,9 +1690,9 @@
follows="left|top|right"
height="14"
layout="topleft"
- left="8"
+ left="10"
name="path"
- top="24"
+ top="36"
width="373">
Located in [PATH]
</text>
@@ -1712,22 +1702,31 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="not worn instructions"
- top_pad="8"
+ top="31"
word_wrap="true"
width="373">
Put on new socks by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
</text>
+ <button
+ follows="left|top"
+ height="23"
+ label="Create New Socks"
+ label_selected="Create New Socks"
+ layout="topleft"
+ name="Create New"
+ top_pad="7"
+ width="160" />
<text
type="string"
length="1"
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="no modify instructions"
- top_delta="0"
+ top="31"
word_wrap="true"
width="373">
You do not have permission to modify this wearable.
@@ -1735,14 +1734,14 @@
<text
type="string"
length="1"
- bottom="486"
- follows="left|top|right"
+ bottom="4"
+ follows="left|bottom|right"
font="SansSerif"
halign="right"
- height="28"
- layout="topleft"
+ height="23"
+ layout="bottomleft"
name="Item Action Label"
- right="117"
+ right="132"
width="100">
Socks:
</text>
@@ -1750,44 +1749,32 @@
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
+ height="108"
label="Fabric"
layout="topleft"
- left="8"
+ left="10"
name="Fabric"
tool_tip="Click to choose a picture"
- top="65"
- width="64" />
+ top="66"
+ width="82" />
<color_swatch
can_apply_immediately="true"
follows="left|top"
- height="80"
+ height="108"
label="Color/Tint"
layout="topleft"
- left_delta="0"
name="Color/Tint"
tool_tip="Click to open color picker"
- top_delta="80"
- width="64" />
- <button
- follows="left|top"
- height="23"
- label="Create New Socks"
- label_selected="Create New Socks"
- layout="topleft"
- left_delta="0"
- name="Create New"
- top_delta="-41"
- width="160" />
+ top_delta="102"
+ width="82" />
<button
follows="left|top"
height="23"
label="Take Off"
label_selected="Take Off"
layout="topleft"
- left_delta="0"
name="Take Off"
- top_pad="102"
+ top_pad="4"
width="82" />
<button
follows="right|bottom"
@@ -1795,9 +1782,9 @@
label="Save"
label_selected="Save"
layout="topleft"
- left="123"
+ right="218"
name="Save"
- top="458"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -1805,9 +1792,9 @@
label="Save As..."
label_selected="Save As..."
layout="topleft"
- left_pad="6"
+ right="304"
name="Save As"
- top_delta="0"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -1815,38 +1802,38 @@
label="Revert"
label_selected="Revert"
layout="topleft"
- left_pad="6"
+ right="390"
name="Revert"
- top_delta="0"
+ top="477"
width="82" />
</panel>
<panel
- border="true"
+ border="false"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
follows="left|top|right|bottom"
- height="481"
+ height="508"
label="Jacket"
layout="topleft"
- left_delta="0"
name="Jacket"
help_topic="customize_jacket_tab"
- top_delta="0"
- width="389">
+ width="400">
<icon
- follows="top|right"
+ follows="top|left"
height="18"
image_name="Lock"
layout="topleft"
- left="315"
+ left="10"
mouse_opaque="true"
name="square"
- top="4"
+ top="10"
width="18" />
<icon
height="16"
layout="topleft"
- left_delta="-325"
+ left="10"
mouse_opaque="true"
- top_delta="3"
+ top="10"
width="16" />
<text
type="string"
@@ -1855,9 +1842,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_pad="2"
+ left="31"
name="title"
- top_delta="0"
+ top="10"
width="355">
[DESC]
</text>
@@ -1868,9 +1855,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_no_modify"
- top_delta="0"
+ top="10"
width="355">
[DESC]: cannot modify
</text>
@@ -1881,9 +1868,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_loading"
- top_delta="0"
+ top="10"
width="355">
[DESC]: loading...
</text>
@@ -1894,9 +1881,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_not_worn"
- top_delta="0"
+ top="10"
width="355">
[DESC]: not worn
</text>
@@ -1906,9 +1893,9 @@
follows="left|top|right"
height="14"
layout="topleft"
- left="8"
+ left="10"
name="path"
- top="24"
+ top="36"
width="373">
Located in [PATH]
</text>
@@ -1918,22 +1905,31 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="not worn instructions"
- top_pad="8"
+ top="31"
word_wrap="true"
width="373">
Put on a new jacket by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
</text>
+ <button
+ follows="left|top"
+ height="23"
+ label="Create New Jacket"
+ label_selected="Create New Jacket"
+ layout="topleft"
+ name="Create New"
+ top_pad="7"
+ width="160" />
<text
type="string"
length="1"
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="no modify instructions"
- top_delta="0"
+ top="31"
word_wrap="true"
width="373">
You do not have permission to modify this wearable.
@@ -1941,14 +1937,14 @@
<text
type="string"
length="1"
- bottom="486"
- follows="left|top|right"
+ bottom="4"
+ follows="left|bottom|right"
font="SansSerif"
halign="right"
- height="28"
- layout="topleft"
+ height="23"
+ layout="bottomleft"
name="Item Action Label"
- right="117"
+ right="132"
width="100">
Jacket:
</text>
@@ -1956,56 +1952,43 @@
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
+ height="108"
label="Upper Fabric"
layout="topleft"
- left="8"
+ left="10"
name="Upper Fabric"
tool_tip="Click to choose a picture"
- top="65"
- width="64" />
+ top="66"
+ width="82" />
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
+ height="108"
label="Lower Fabric"
layout="topleft"
- left_delta="0"
name="Lower Fabric"
tool_tip="Click to choose a picture"
- top_delta="80"
- width="64" />
+ top_delta="102"
+ width="82" />
<color_swatch
can_apply_immediately="true"
follows="left|top"
- height="80"
+ height="108"
label="Color/Tint"
layout="topleft"
- left_delta="0"
name="Color/Tint"
tool_tip="Click to open color picker"
- top_delta="80"
- width="64" />
- <button
- follows="left|top"
- height="23"
- label="Create New Jacket"
- label_selected="Create New Jacket"
- layout="topleft"
- left_delta="0"
- name="Create New"
- top_delta="-121"
- width="160" />
+ top_delta="102"
+ width="82" />
<button
follows="left|top"
height="23"
label="Take Off"
label_selected="Take Off"
layout="topleft"
- left_delta="0"
name="Take Off"
- top_pad="182"
+ top_pad="4"
width="82" />
<button
follows="right|bottom"
@@ -2013,9 +1996,9 @@
label="Save"
label_selected="Save"
layout="topleft"
- left="123"
+ right="218"
name="Save"
- top="458"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -2023,9 +2006,9 @@
label="Save As..."
label_selected="Save As..."
layout="topleft"
- left_pad="6"
+ right="304"
name="Save As"
- top_delta="0"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -2033,38 +2016,38 @@
label="Revert"
label_selected="Revert"
layout="topleft"
- left_pad="6"
+ right="390"
name="Revert"
- top_delta="0"
+ top="477"
width="82" />
</panel>
<panel
- border="true"
+ border="false"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
follows="left|top|right|bottom"
- height="481"
+ height="508"
label="Gloves"
layout="topleft"
- left_delta="0"
name="Gloves"
help_topic="customize_gloves_tab"
- top_delta="0"
- width="389">
+ width="400">
<icon
- follows="top|right"
+ follows="top|left"
height="18"
image_name="Lock"
layout="topleft"
- left="315"
+ left="10"
mouse_opaque="true"
name="square"
- top="4"
+ top="10"
width="18" />
<icon
height="16"
layout="topleft"
- left_delta="-325"
+ left="10"
mouse_opaque="true"
- top_delta="3"
+ top="10"
width="16" />
<text
type="string"
@@ -2073,9 +2056,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_pad="2"
+ left="31"
name="title"
- top_delta="0"
+ top="10"
width="355">
[DESC]
</text>
@@ -2086,9 +2069,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_no_modify"
- top_delta="0"
+ top="10"
width="355">
[DESC]: cannot modify
</text>
@@ -2099,9 +2082,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_loading"
- top_delta="0"
+ top="10"
width="355">
[DESC]: loading...
</text>
@@ -2112,9 +2095,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_not_worn"
- top_delta="0"
+ top="10"
width="355">
[DESC]: not worn
</text>
@@ -2124,9 +2107,9 @@
follows="left|top|right"
height="14"
layout="topleft"
- left="8"
+ left="10"
name="path"
- top="24"
+ top="36"
width="373">
Located in [PATH]
</text>
@@ -2136,22 +2119,31 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="not worn instructions"
- top_pad="8"
+ top="31"
word_wrap="true"
width="373">
Put on new gloves by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
</text>
+ <button
+ follows="left|top"
+ height="23"
+ label="Create New Gloves"
+ label_selected="Create New Gloves"
+ layout="topleft"
+ name="Create New"
+ top_pad="7"
+ width="160" />
<text
type="string"
length="1"
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="no modify instructions"
- top_delta="0"
+ top="31"
word_wrap="true"
width="373">
You do not have permission to modify this wearable.
@@ -2159,14 +2151,14 @@
<text
type="string"
length="1"
- bottom="486"
- follows="left|top|right"
+ bottom="4"
+ follows="left|bottom|right"
font="SansSerif"
halign="right"
- height="28"
- layout="topleft"
+ height="23"
+ layout="bottomleft"
name="Item Action Label"
- right="117"
+ right="132"
width="100">
Gloves:
</text>
@@ -2174,44 +2166,32 @@
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
+ height="108"
label="Fabric"
layout="topleft"
- left="8"
+ left="10"
name="Fabric"
tool_tip="Click to choose a picture"
- top="65"
- width="64" />
+ top="66"
+ width="82" />
<color_swatch
can_apply_immediately="true"
follows="left|top"
- height="80"
+ height="108"
label="Color/Tint"
layout="topleft"
- left_delta="0"
name="Color/Tint"
tool_tip="Click to open color picker"
- top_delta="80"
- width="64" />
- <button
- follows="left|top"
- height="23"
- label="Create New Gloves"
- label_selected="Create New Gloves"
- layout="topleft"
- left_delta="0"
- name="Create New"
- top_delta="-41"
- width="160" />
+ top_delta="102"
+ width="82" />
<button
follows="left|top"
height="23"
label="Take Off"
label_selected="Take Off"
layout="topleft"
- left_delta="0"
name="Take Off"
- top_pad="102"
+ top_pad="4"
width="82" />
<button
follows="right|bottom"
@@ -2219,9 +2199,9 @@
label="Save"
label_selected="Save"
layout="topleft"
- left="123"
+ right="218"
name="Save"
- top="458"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -2229,9 +2209,9 @@
label="Save As..."
label_selected="Save As..."
layout="topleft"
- left_pad="6"
+ right="304"
name="Save As"
- top_delta="0"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -2239,38 +2219,38 @@
label="Revert"
label_selected="Revert"
layout="topleft"
- left_pad="6"
+ right="390"
name="Revert"
- top_delta="0"
+ top="477"
width="82" />
</panel>
<panel
- border="true"
+ border="false"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
follows="left|top|right|bottom"
- height="481"
+ height="508"
label="Undershirt"
layout="topleft"
- left_delta="0"
name="Undershirt"
help_topic="customize_undershirt_tab"
- top_delta="0"
- width="389">
+ width="400">
<icon
- follows="top|right"
+ follows="top|left"
height="18"
image_name="Lock"
layout="topleft"
- left="315"
+ left="10"
mouse_opaque="true"
name="square"
- top="4"
+ top="10"
width="18" />
<icon
height="16"
layout="topleft"
- left_delta="-325"
+ left="10"
mouse_opaque="true"
- top_delta="3"
+ top="10"
width="16" />
<text
type="string"
@@ -2279,9 +2259,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_pad="2"
+ left="31"
name="title"
- top_delta="0"
+ top="10"
width="355">
[DESC]
</text>
@@ -2292,9 +2272,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_no_modify"
- top_delta="0"
+ top="10"
width="355">
[DESC]: cannot modify
</text>
@@ -2305,9 +2285,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_loading"
- top_delta="0"
+ top="10"
width="355">
[DESC]: loading...
</text>
@@ -2318,9 +2298,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_not_worn"
- top_delta="0"
+ top="10"
width="355">
[DESC]: not worn
</text>
@@ -2330,9 +2310,9 @@
follows="left|top|right"
height="14"
layout="topleft"
- left="8"
+ left="10"
name="path"
- top="24"
+ top="36"
width="373">
Located in [PATH]
</text>
@@ -2342,22 +2322,31 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="not worn instructions"
- top_pad="8"
+ top="31"
word_wrap="true"
width="373">
Put on a new undershirt by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
</text>
+ <button
+ follows="left|top"
+ height="23"
+ label="Create New Undershirt"
+ label_selected="Create New Undershirt"
+ layout="topleft"
+ name="Create New"
+ top_pad="7"
+ width="160" />
<text
type="string"
length="1"
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="no modify instructions"
- top_delta="0"
+ top="31"
word_wrap="true"
width="373">
You do not have permission to modify this wearable.
@@ -2365,14 +2354,14 @@
<text
type="string"
length="1"
- bottom="486"
- follows="left|top|right"
+ bottom="4"
+ follows="left|bottom|right"
font="SansSerif"
halign="right"
- height="28"
- layout="topleft"
+ height="23"
+ layout="bottomleft"
name="Item Action Label"
- right="117"
+ right="132"
width="100">
Undershirt:
</text>
@@ -2380,44 +2369,32 @@
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
+ height="108"
label="Fabric"
layout="topleft"
- left="8"
+ left="10"
name="Fabric"
tool_tip="Click to choose a picture"
- top="65"
- width="64" />
+ top="66"
+ width="82" />
<color_swatch
can_apply_immediately="true"
follows="left|top"
- height="80"
+ height="108"
label="Color/Tint"
layout="topleft"
- left_delta="0"
name="Color/Tint"
tool_tip="Click to open color picker"
- top_delta="80"
- width="64" />
- <button
- follows="left|top"
- height="23"
- label="Create New Undershirt"
- label_selected="Create New Undershirt"
- layout="topleft"
- left_delta="0"
- name="Create New"
- top_delta="-41"
- width="160" />
+ top_delta="102"
+ width="82" />
<button
follows="left|top"
height="23"
label="Take Off"
label_selected="Take Off"
layout="topleft"
- left_delta="0"
name="Take Off"
- top_pad="102"
+ top_pad="4"
width="82" />
<button
follows="right|bottom"
@@ -2425,9 +2402,9 @@
label="Save"
label_selected="Save"
layout="topleft"
- left="123"
+ right="218"
name="Save"
- top="458"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -2435,9 +2412,9 @@
label="Save As..."
label_selected="Save As..."
layout="topleft"
- left_pad="6"
+ right="304"
name="Save As"
- top_delta="0"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -2445,38 +2422,38 @@
label="Revert"
label_selected="Revert"
layout="topleft"
- left_pad="6"
+ right="390"
name="Revert"
- top_delta="0"
+ top="477"
width="82" />
</panel>
<panel
- border="true"
+ border="false"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
follows="left|top|right|bottom"
- height="481"
+ height="508"
label="Underpants"
layout="topleft"
- left_delta="0"
name="Underpants"
help_topic="customize_underpants_tab"
- top_delta="0"
- width="389">
+ width="400">
<icon
- follows="top|right"
+ follows="top|left"
height="18"
image_name="Lock"
layout="topleft"
- left="315"
+ left="10"
mouse_opaque="true"
name="square"
- top="4"
+ top="10"
width="18" />
<icon
height="16"
layout="topleft"
- left_delta="-325"
+ left="10"
mouse_opaque="true"
- top_delta="3"
+ top="10"
width="16" />
<text
type="string"
@@ -2485,9 +2462,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_pad="2"
+ left="31"
name="title"
- top_delta="0"
+ top="10"
width="355">
[DESC]
</text>
@@ -2498,9 +2475,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_no_modify"
- top_delta="0"
+ top="10"
width="355">
[DESC]: cannot modify
</text>
@@ -2511,9 +2488,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_loading"
- top_delta="0"
+ top="10"
width="355">
[DESC]: loading...
</text>
@@ -2524,9 +2501,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_not_worn"
- top_delta="0"
+ top="10"
width="355">
[DESC]: not worn
</text>
@@ -2536,9 +2513,9 @@
follows="left|top|right"
height="14"
layout="topleft"
- left="8"
+ left="10"
name="path"
- top="24"
+ top="36"
width="373">
Located in [PATH]
</text>
@@ -2548,22 +2525,31 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="not worn instructions"
- top_pad="8"
+ top="31"
word_wrap="true"
width="373">
Put on new underpants by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
</text>
+ <button
+ follows="left|top"
+ height="23"
+ label="Create New Underpants"
+ label_selected="Create New Underpants"
+ layout="topleft"
+ name="Create New"
+ top_pad="7"
+ width="160" />
<text
type="string"
length="1"
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="no modify instructions"
- top_delta="0"
+ top="31"
word_wrap="true"
width="373">
You do not have permission to modify this wearable.
@@ -2571,14 +2557,14 @@
<text
type="string"
length="1"
- bottom="486"
- follows="left|top|right"
+ bottom="4"
+ follows="left|bottom|right"
font="SansSerif"
halign="right"
- height="28"
- layout="topleft"
+ height="23"
+ layout="bottomleft"
name="Item Action Label"
- right="117"
+ right="132"
width="100">
Underpants:
</text>
@@ -2586,44 +2572,32 @@
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
+ height="108"
label="Fabric"
layout="topleft"
- left="8"
+ left="10"
name="Fabric"
tool_tip="Click to choose a picture"
- top="65"
- width="64" />
+ top="66"
+ width="82" />
<color_swatch
can_apply_immediately="true"
follows="left|top"
- height="80"
+ height="108"
label="Color/Tint"
layout="topleft"
- left_delta="0"
name="Color/Tint"
tool_tip="Click to open color picker"
- top_delta="80"
- width="64" />
- <button
- follows="left|top"
- height="23"
- label="Create New Underpants"
- label_selected="Create New Underpants"
- layout="topleft"
- left_delta="0"
- name="Create New"
- top_delta="-41"
- width="160" />
+ top_delta="102"
+ width="82" />
<button
follows="left|top"
height="23"
label="Take Off"
label_selected="Take Off"
layout="topleft"
- left_delta="0"
name="Take Off"
- top_pad="102"
+ top_pad="4"
width="82" />
<button
follows="right|bottom"
@@ -2631,9 +2605,9 @@
label="Save"
label_selected="Save"
layout="topleft"
- left="123"
+ right="218"
name="Save"
- top="458"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -2641,9 +2615,9 @@
label="Save As..."
label_selected="Save As..."
layout="topleft"
- left_pad="6"
+ right="304"
name="Save As"
- top_delta="0"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -2651,38 +2625,38 @@
label="Revert"
label_selected="Revert"
layout="topleft"
- left_pad="6"
+ right="390"
name="Revert"
- top_delta="0"
+ top="477"
width="82" />
</panel>
<panel
- border="true"
+ border="false"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
follows="left|top|right|bottom"
- height="481"
+ height="508"
label="Skirt"
layout="topleft"
- left_delta="0"
name="Skirt"
help_topic="customize_skirt_tab"
- top_delta="0"
- width="389">
+ width="400">
<icon
- follows="top|right"
+ follows="top|left"
height="18"
image_name="Lock"
layout="topleft"
- left="315"
+ left="10"
mouse_opaque="true"
name="square"
- top="4"
+ top="10"
width="18" />
<icon
height="16"
layout="topleft"
- left_delta="-325"
+ left="10"
mouse_opaque="true"
- top_delta="3"
+ top="10"
width="16" />
<text
type="string"
@@ -2691,9 +2665,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_pad="2"
+ left="31"
name="title"
- top_delta="0"
+ top="10"
width="355">
[DESC]
</text>
@@ -2704,9 +2678,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_no_modify"
- top_delta="0"
+ top="10"
width="355">
[DESC]: cannot modify
</text>
@@ -2717,9 +2691,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_loading"
- top_delta="0"
+ top="10"
width="355">
[DESC]: loading...
</text>
@@ -2730,9 +2704,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_not_worn"
- top_delta="0"
+ top="10"
width="355">
[DESC]: not worn
</text>
@@ -2742,9 +2716,9 @@
follows="left|top|right"
height="14"
layout="topleft"
- left="8"
+ left="10"
name="path"
- top="24"
+ top="36"
width="373">
Located in [PATH]
</text>
@@ -2754,22 +2728,31 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="not worn instructions"
- top_pad="8"
+ top="31"
word_wrap="true"
width="373">
Put on a new skirt by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
</text>
+ <button
+ follows="left|top"
+ height="23"
+ label="Create New Skirt"
+ label_selected="Create New Skirt"
+ layout="topleft"
+ name="Create New"
+ top_pad="7"
+ width="160" />
<text
type="string"
length="1"
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="no modify instructions"
- top_delta="0"
+ top="31"
word_wrap="true"
width="373">
You do not have permission to modify this wearable.
@@ -2777,14 +2760,14 @@
<text
type="string"
length="1"
- bottom="486"
- follows="left|top|right"
+ bottom="4"
+ follows="left|bottom|right"
font="SansSerif"
halign="right"
- height="28"
- layout="topleft"
+ height="23"
+ layout="bottomleft"
name="Item Action Label"
- right="117"
+ right="132"
width="100">
Skirt:
</text>
@@ -2792,44 +2775,32 @@
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
+ height="108"
label="Fabric"
layout="topleft"
- left="8"
+ left="10"
name="Fabric"
tool_tip="Click to choose a picture"
- top="65"
- width="64" />
+ top="66"
+ width="82" />
<color_swatch
can_apply_immediately="true"
follows="left|top"
- height="80"
+ height="108"
label="Color/Tint"
layout="topleft"
- left_delta="0"
name="Color/Tint"
tool_tip="Click to open color picker"
- top_delta="80"
- width="64" />
- <button
- follows="left|top"
- height="23"
- label="Create New Skirt"
- label_selected="Create New Skirt"
- layout="topleft"
- left_delta="0"
- name="Create New"
- top_delta="-41"
- width="160" />
+ top_delta="102"
+ width="82" />
<button
follows="left|top"
height="23"
label="Take Off"
label_selected="Take Off"
layout="topleft"
- left_delta="0"
name="Take Off"
- top_pad="102"
+ top_pad="4"
width="82" />
<button
follows="right|bottom"
@@ -2837,9 +2808,9 @@
label="Save"
label_selected="Save"
layout="topleft"
- left="123"
+ right="218"
name="Save"
- top="458"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -2847,9 +2818,9 @@
label="Save As..."
label_selected="Save As..."
layout="topleft"
- left_pad="6"
+ right="304"
name="Save As"
- top_delta="0"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -2857,38 +2828,38 @@
label="Revert"
label_selected="Revert"
layout="topleft"
- left_pad="6"
+ right="390"
name="Revert"
- top_delta="0"
+ top="477"
width="82" />
</panel>
<panel
- border="true"
+ border="false"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
follows="left|top|right|bottom"
- height="481"
- label="Alpha"
+ height="508"
+ label="Tattoo"
layout="topleft"
- left_delta="0"
- name="Alpha"
- help_topic="customize_alpha_tab"
- top_delta="0"
- width="389">
+ name="Tattoo"
+ help_topic="customize_tattoo_tab"
+ width="400">
<icon
- follows="top|right"
+ follows="top|left"
height="18"
image_name="Lock"
layout="topleft"
- left="315"
+ left="10"
mouse_opaque="true"
name="square"
- top="4"
+ top="10"
width="18" />
<icon
height="16"
layout="topleft"
- left_delta="-325"
+ left="10"
mouse_opaque="true"
- top_delta="3"
+ top="10"
width="16" />
<text
type="string"
@@ -2897,9 +2868,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_pad="2"
+ left="31"
name="title"
- top_delta="0"
+ top="10"
width="355">
[DESC]
</text>
@@ -2910,9 +2881,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_no_modify"
- top_delta="0"
+ top="10"
width="355">
[DESC]: cannot modify
</text>
@@ -2923,9 +2894,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_loading"
- top_delta="0"
+ top="10"
width="355">
[DESC]: loading...
</text>
@@ -2936,9 +2907,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_not_worn"
- top_delta="0"
+ top="10"
width="355">
[DESC]: not worn
</text>
@@ -2948,9 +2919,9 @@
follows="left|top|right"
height="14"
layout="topleft"
- left="8"
+ left="10"
name="path"
- top="24"
+ top="36"
width="373">
Located in [PATH]
</text>
@@ -2960,22 +2931,31 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="-2"
+ left="10"
name="not worn instructions"
- top_pad="8"
+ top="31"
word_wrap="true"
width="373">
- Put on a new alpha mask by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
+ Put on a new tattoo by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
</text>
+ <button
+ follows="left|top"
+ height="23"
+ label="Create New Tattoo"
+ label_selected="Create New Tattoo"
+ layout="topleft"
+ name="Create New"
+ top_pad="7"
+ width="160" />
<text
type="string"
length="1"
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="no modify instructions"
- top_delta="0"
+ top="31"
word_wrap="true"
width="373">
You do not have permission to modify this wearable.
@@ -2983,141 +2963,60 @@
<text
type="string"
length="1"
- bottom="486"
- follows="left|top|right"
+ bottom="4"
+ follows="left|bottom|right"
font="SansSerif"
halign="right"
- height="28"
- layout="topleft"
+ height="23"
+ layout="bottomleft"
name="Item Action Label"
- right="119"
+ right="132"
width="100">
- Alpha:
+ Tattoo:
</text>
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
- label="Lower Alpha"
- layout="topleft"
- left="8"
- name="Lower Alpha"
- tool_tip="Click to choose a picture"
- top="65"
- width="64" />
- <check_box
- control_name="LowerAlphaTextureInvisible"
- follows="left"
- height="16"
- layout="topleft"
- left_pad="6"
- name="lower alpha texture invisible"
- top_delta="4"
- width="16" />
- <texture_picker
- can_apply_immediately="true"
- default_image_name="Default"
- follows="left|top"
- height="80"
- label="Upper Alpha"
- layout="topleft"
- left="8"
- name="Upper Alpha"
- tool_tip="Click to choose a picture"
- top="145"
- width="64" />
- <check_box
- control_name="UpperAlphaTextureInvisible"
- follows="left"
- height="16"
- layout="topleft"
- left_pad="6"
- name="upper alpha texture invisible"
- top_delta="4"
- width="16" />
- <texture_picker
- can_apply_immediately="true"
- default_image_name="Default"
- follows="left|top"
- height="80"
- label="Head Alpha"
+ height="108"
+ label="Head Tattoo"
layout="topleft"
- left="8"
- name="Head Alpha"
+ left="10"
+ name="Head Tattoo"
tool_tip="Click to choose a picture"
- top="225"
- width="64" />
- <check_box
- control_name="HeadAlphaTextureInvisible"
- follows="left"
- height="16"
- layout="topleft"
- left_pad="6"
- name="head alpha texture invisible"
- top_delta="4"
- width="16" />
+ top="66"
+ width="82" />
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
- label="Eye Alpha"
+ height="108"
+ label="Upper Tattoo"
layout="topleft"
- left="8"
- name="Eye Alpha"
+ name="Upper Tattoo"
tool_tip="Click to choose a picture"
- top="305"
- width="64" />
- <check_box
- control_name="Eye AlphaTextureInvisible"
- follows="left"
- height="16"
- layout="topleft"
- left_pad="6"
- name="eye alpha texture invisible"
- top_delta="4"
- width="16" />
+ left_delta="90"
+ width="82" />
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
- label="Hair Alpha"
+ height="108"
+ label="Lower Tattoo"
layout="topleft"
- left="8"
- name="Hair Alpha"
+ name="Lower Tattoo"
tool_tip="Click to choose a picture"
- top="385"
- width="64" />
- <check_box
- control_name="HairAlphaTextureInvisible"
- follows="left"
- height="16"
- layout="topleft"
- left_pad="6"
- name="hair alpha texture invisible"
- top_delta="4"
- width="16" />
- <button
- follows="left|top"
- height="23"
- label="Create New Alpha"
- label_selected="Create New Alpha"
- layout="topleft"
- left="8"
- name="Create New"
- top="104"
- width="160" />
+ left_delta="90"
+ width="82" />
<button
follows="left|top"
height="23"
label="Take Off"
label_selected="Take Off"
layout="topleft"
- left_delta="-4"
name="Take Off"
- top_pad="332"
+ top_pad="4"
+ left="10"
width="82" />
<button
follows="right|bottom"
@@ -3125,9 +3024,9 @@
label="Save"
label_selected="Save"
layout="topleft"
- left_pad="37"
+ right="218"
name="Save"
- top_delta="-2"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -3135,9 +3034,9 @@
label="Save As..."
label_selected="Save As..."
layout="topleft"
- left_pad="6"
+ right="304"
name="Save As"
- top_delta="0"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -3145,38 +3044,38 @@
label="Revert"
label_selected="Revert"
layout="topleft"
- left_pad="6"
+ right="390"
name="Revert"
- top_delta="0"
+ top="477"
width="82" />
</panel>
<panel
- border="true"
+ border="false"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
follows="left|top|right|bottom"
- height="481"
- label="Tattoo"
+ height="508"
+ label="Alpha"
layout="topleft"
- left_delta="0"
- name="Tattoo"
- help_topic="customize_tattoo_tab"
- top_delta="0"
- width="389">
+ name="Alpha"
+ help_topic="customize_alpha_tab"
+ width="400">
<icon
- follows="top|right"
+ follows="top|left"
height="18"
image_name="Lock"
layout="topleft"
- left="315"
+ left="10"
mouse_opaque="true"
name="square"
- top="4"
+ top="10"
width="18" />
<icon
height="16"
layout="topleft"
- left_delta="-325"
+ left="10"
mouse_opaque="true"
- top_delta="3"
+ top="10"
width="16" />
<text
type="string"
@@ -3185,9 +3084,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_pad="2"
+ left="31"
name="title"
- top_delta="0"
+ top="10"
width="355">
[DESC]
</text>
@@ -3198,9 +3097,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_no_modify"
- top_delta="0"
+ top="10"
width="355">
[DESC]: cannot modify
</text>
@@ -3211,9 +3110,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_loading"
- top_delta="0"
+ top="10"
width="355">
[DESC]: loading...
</text>
@@ -3224,9 +3123,9 @@
font="SansSerif"
height="16"
layout="topleft"
- left_delta="0"
+ left="31"
name="title_not_worn"
- top_delta="0"
+ top="10"
width="355">
[DESC]: not worn
</text>
@@ -3236,9 +3135,9 @@
follows="left|top|right"
height="14"
layout="topleft"
- left="8"
+ left="10"
name="path"
- top="24"
+ top="36"
width="373">
Located in [PATH]
</text>
@@ -3248,22 +3147,31 @@
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="-2"
+ left="10"
name="not worn instructions"
- top_pad="8"
+ top="31"
word_wrap="true"
width="373">
- Put on a new tattoo by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
+ Put on a new alpha mask by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
</text>
+ <button
+ follows="left|top"
+ height="23"
+ label="Create New Alpha"
+ label_selected="Create New Alpha"
+ layout="topleft"
+ name="Create New"
+ top_pad="18"
+ width="160" />
<text
type="string"
length="1"
follows="left|top|right"
height="28"
layout="topleft"
- left_delta="0"
+ left="10"
name="no modify instructions"
- top_delta="0"
+ top="31"
word_wrap="true"
width="373">
You do not have permission to modify this wearable.
@@ -3271,72 +3179,125 @@
<text
type="string"
length="1"
- bottom="486"
- follows="left|top|right"
+ bottom="4"
+ follows="left|bottom|right"
font="SansSerif"
halign="right"
- height="28"
- layout="topleft"
+ height="23"
+ layout="bottomleft"
name="Item Action Label"
- right="119"
+ right="132"
width="100">
- Tattoo:
+ Alpha:
</text>
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
- label="Head Tattoo"
+ height="108"
+ label="Lower Alpha"
layout="topleft"
- left="8"
- name="Head Tattoo"
+ left="10"
+ name="Lower Alpha"
tool_tip="Click to choose a picture"
- top="65"
- width="64" />
+ top="66"
+ width="82" />
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
- label="Upper Tattoo"
+ height="108"
+ label="Upper Alpha"
layout="topleft"
- left_delta="0"
- name="Upper Tattoo"
+ name="Upper Alpha"
tool_tip="Click to choose a picture"
- top_delta="80"
- width="64" />
+ left_delta="90"
+ width="82" />
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="80"
- label="Lower Tattoo"
+ height="108"
+ label="Head Alpha"
layout="topleft"
- left_delta="0"
- name="Lower Tattoo"
+ name="Head Alpha"
tool_tip="Click to choose a picture"
- top_delta="80"
- width="64" />
- <button
+ left_delta="90"
+ width="82" />
+ <check_box
+ control_name="LowerAlphaTextureInvisible"
+ follows="left"
+ height="16"
+ layout="topleft"
+ left="43"
+ name="lower alpha texture invisible"
+ top_delta="96"
+ width="16" />
+ <check_box
+ control_name="UpperAlphaTextureInvisible"
+ follows="left"
+ height="16"
+ layout="topleft"
+ left_pad="72"
+ name="upper alpha texture invisible"
+ width="16" />
+ <check_box
+ control_name="HeadAlphaTextureInvisible"
+ follows="left"
+ height="16"
+ layout="topleft"
+ left_pad="72"
+ name="head alpha texture invisible"
+ width="16" />
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
follows="left|top"
- height="23"
- label="Create New Tattoo"
- label_selected="Create New Tattoo"
+ height="108"
+ label="Eye Alpha"
layout="topleft"
- left_delta="0"
- name="Create New"
- top_delta="-121"
- width="160" />
+ name="Eye Alpha"
+ tool_tip="Click to choose a picture"
+ left="10"
+ top_pad="20"
+ width="82" />
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="108"
+ label="Hair Alpha"
+ layout="topleft"
+ name="Hair Alpha"
+ left_delta="90"
+ tool_tip="Click to choose a picture"
+ width="82" />
+ <check_box
+ control_name="Eye AlphaTextureInvisible"
+ follows="left"
+ height="16"
+ layout="topleft"
+ left="43"
+ name="eye alpha texture invisible"
+ top_delta="96"
+ width="16" />
+ <check_box
+ control_name="HairAlphaTextureInvisible"
+ follows="left"
+ height="16"
+ layout="topleft"
+ left_pad="72"
+ name="hair alpha texture invisible"
+ width="16" />
<button
follows="left|top"
height="23"
label="Take Off"
label_selected="Take Off"
layout="topleft"
- left_delta="-4"
name="Take Off"
- top_pad="332"
+ left="10"
+ top_pad="20"
width="82" />
<button
follows="right|bottom"
@@ -3344,9 +3305,9 @@
label="Save"
label_selected="Save"
layout="topleft"
- left_pad="37"
+ right="218"
name="Save"
- top_delta="-2"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -3354,9 +3315,9 @@
label="Save As..."
label_selected="Save As..."
layout="topleft"
- left_pad="6"
+ right="304"
name="Save As"
- top_delta="0"
+ top="477"
width="82" />
<button
follows="right|bottom"
@@ -3364,9 +3325,9 @@
label="Revert"
label_selected="Revert"
layout="topleft"
- left_pad="6"
+ right="390"
name="Revert"
- top_delta="0"
+ top="477"
width="82" />
</panel>
</tab_container>
@@ -3377,7 +3338,7 @@
left="211"
mouse_opaque="false"
name="panel_container"
- top="116"
+ top="92"
width="292">
<scrolling_panel_list
follows="left|bottom"
@@ -3385,17 +3346,18 @@
name="panel_list" />
</scroll_container>
<button
- bottom="598"
+ bottom="460"
follows="right|left"
- height="20"
+ height="23"
label="Script Info"
label_selected="Script Info"
layout="topleft"
name="script_info"
- left="2"
- width="98" />
+ tool_tip="Show scripts attached to your avatar"
+ left="13"
+ width="90" />
<button
- bottom="598"
+ bottom="574"
follows="right|bottom"
height="23"
label="Make Outfit"
@@ -3405,7 +3367,7 @@
right="-218"
width="100" />
<button
- bottom="598"
+ bottom="574"
follows="right|bottom"
height="23"
label="Cancel"
@@ -3415,7 +3377,7 @@
right="-10"
width="100" />
<button
- bottom="598"
+ bottom="574"
follows="right|bottom"
height="23"
label="OK"
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 1d51d19a4a..bd25288a9e 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<multi_floater
- can_minimize="false"
+ can_close="false"
+ can_minimize="true"
can_resize="true"
height="390"
layout="topleft"
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 243b63db00..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,12 +11,13 @@
can_dock="false"
can_minimize="true"
can_close="true"
- visible="true"
+ visible="false"
width="360"
can_resize="true"
min_width="250"
min_height="190">
<layout_stack
+ animate="false"
follows="all"
height="320"
width="360"
diff --git a/indra/newview/skins/default/xui/en/floater_media_browser.xml b/indra/newview/skins/default/xui/en/floater_media_browser.xml
index 4b280ac59f..70dac7e41c 100644
--- a/indra/newview/skins/default/xui/en/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/en/floater_media_browser.xml
@@ -80,7 +80,7 @@
height="20"
layout="topleft"
left_pad="5"
- max_chars="255"
+ max_chars="1024"
name="address"
top_delta="0"
width="540">
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_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml
index 3fc57372de..005952f3f2 100644
--- a/indra/newview/skins/default/xui/en/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml
@@ -3,13 +3,13 @@
legacy_header_height="18"
bevel_style="in"
left="0"
- top="0"
+ top="0"
follows="right|bottom"
layout="topleft"
name="sys_well_window"
help_topic="notification_chiclet"
save_rect="true"
- title="NOTIFICATIONS"
+ title="NOTIFICATIONS"
width="320"
min_width="320"
height="23"
@@ -23,13 +23,13 @@
>
<string
name="title_im_well_window">
- IM SESSIONS
+ CONVERSATIONS
</string>
<string
name="title_notification_well_window">
NOTIFICATIONS
</string>
-
+
<flat_list_view
color="FloaterDefaultBackgroundColor"
follows="all"
diff --git a/indra/newview/skins/default/xui/en/floater_test_checkbox.xml b/indra/newview/skins/default/xui/en/floater_test_checkbox.xml
index 9977e85a9d..042b4226c3 100644
--- a/indra/newview/skins/default/xui/en/floater_test_checkbox.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_checkbox.xml
@@ -71,4 +71,83 @@
name="font_checkbox"
top_pad="14"
width="150" />
+
+<chiclet_im_p2p
+ height="25"
+ name="im_p2p_chiclet"
+ show_speaker="false"
+ width="25">
+ <chiclet_im_p2p.chiclet_button
+ height="25"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ name="chiclet_button"
+ tab_stop="false"
+ width="25"/>
+ <chiclet_im_p2p.speaker
+ auto_update="true"
+ draw_border="false"
+ height="25"
+ left="25"
+ name="speaker"
+ visible="false"
+ width="20" />
+ <chiclet_im_p2p.avatar_icon
+ bottom="3"
+ follows="left|top|bottom"
+ height="20"
+ left="2"
+ mouse_opaque="false"
+ name="avatar_icon"
+ width="21" />
+ <chiclet_im_p2p.unread_notifications
+ height="25"
+ font_halign="center"
+ left="25"
+ mouse_opaque="false"
+ name="unread"
+ text_color="white"
+ v_pad="5"
+ visible="false"
+ width="20"/>
+ <chiclet_im_p2p.new_message_icon
+ bottom="11"
+ height="14"
+ image_name="Unread_Chiclet"
+ left="12"
+ name="new_message_icon"
+ visible="false"
+ width="14" />
+</chiclet_im_p2p>
+
+
+<chiclet_offer
+ height="25"
+ name="offer_chiclet"
+ width="25">
+ <chiclet_offer.chiclet_button
+ height="25"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ name="chiclet_button"
+ tab_stop="false"
+ width="25"/>
+ <chiclet_offer.icon
+ bottom="3"
+ default_icon="Generic_Object_Small"
+ follows="all"
+ height="19"
+ left="3"
+ mouse_opaque="false"
+ name="chiclet_icon"
+ width="19" />
+ <chiclet_offer.new_message_icon
+ bottom="11"
+ height="14"
+ image_name="Unread_Chiclet"
+ left="12"
+ name="new_message_icon"
+ visible="false"
+ width="14" />
+</chiclet_offer>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index a1e190fc5e..f1aa5c27c1 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -1687,6 +1687,7 @@ even though the user gets a free copy.
Taper
</text>
<text
+ visible="false"
type="string"
length="1"
follows="left|top"
@@ -1769,6 +1770,7 @@ even though the user gets a free copy.
top_delta="0"
width="68" />
<text
+ visible="false"
type="string"
length="1"
follows="left|top"
@@ -1781,6 +1783,7 @@ even though the user gets a free copy.
Profile Cut (begin/end)
</text>
<text
+ visible="false"
type="string"
length="1"
follows="left|top"
@@ -1831,6 +1834,7 @@ even though the user gets a free copy.
top_delta="0"
width="68" />
<text
+ visible="false"
type="string"
length="1"
follows="left|top"
@@ -1843,6 +1847,7 @@ even though the user gets a free copy.
Taper
</text>
<spinner
+ visible="false"
decimal_digits="2"
follows="left|top"
height="19"
@@ -1857,6 +1862,7 @@ even though the user gets a free copy.
top_pad="3"
width="68" />
<spinner
+ visible="false"
decimal_digits="2"
follows="left|top"
height="19"
@@ -1871,6 +1877,7 @@ even though the user gets a free copy.
top_delta="0"
width="68" />
<text
+ visible="false"
type="string"
length="1"
follows="left|top"
@@ -1883,6 +1890,7 @@ even though the user gets a free copy.
Radius
</text>
<text
+ visible="false"
type="string"
length="1"
follows="left|top"
@@ -1894,6 +1902,7 @@ even though the user gets a free copy.
Revolutions
</text>
<spinner
+ visible="false"
follows="left|top"
height="19"
increment="0.05"
@@ -1905,6 +1914,7 @@ even though the user gets a free copy.
top_pad="4"
width="68" />
<spinner
+ visible="false"
decimal_digits="2"
follows="left|top"
height="19"
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 ae198d69a3..c4411db8c5 100644
--- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
@@ -3,9 +3,9 @@
can_resize="true"
can_minimize="true"
can_close="false"
- height="275"
+ height="202"
layout="topleft"
- min_height="100"
+ min_height="124"
min_width="190"
name="floater_voice_controls"
help_topic="floater_voice_controls"
@@ -36,7 +36,7 @@
<layout_stack
clip="false"
follows="all"
- height="262"
+ height="189"
layout="topleft"
left="10"
mouse_opaque="false"
@@ -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"
@@ -105,13 +106,13 @@
layout="topleft"
left="2"
top_pad="0"
- height="205"
+ height="132"
name="callers_panel"
user_resize="false"
width="280">
<avatar_list
follows="all"
- height="205"
+ height="132"
ignore_online_status="true"
layout="topleft"
multi_select="true"
diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml
index a666b8a427..9796f7b5b6 100644
--- a/indra/newview/skins/default/xui/en/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml
@@ -58,8 +58,10 @@
height="35"
left="8"
name="user_details"
+ right="-10"
word_wrap="true"
top_pad="6"
+ use_ellipses="true"
width="220">This is my second life description and I really think it is great.
</text>
<slider
diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml
index 861eb9009a..1d4377e339 100644
--- a/indra/newview/skins/default/xui/en/main_view.xml
+++ b/indra/newview/skins/default/xui/en/main_view.xml
@@ -5,6 +5,7 @@
layout="topleft"
left="0"
mouse_opaque="false"
+ tab_stop="false"
name="main_view"
width="1024">
<layout_stack border_size="0"
@@ -18,6 +19,7 @@
height="60"
mouse_opaque="false"
name="nav_bar_container"
+ tab_stop="false"
width="1024"
user_resize="false"
visible="false">
@@ -27,6 +29,7 @@
height="500"
layout="topleft"
mouse_opaque="false"
+ tab_stop="false"
name="hud"
width="1024">
<layout_stack border_size="0"
@@ -38,11 +41,12 @@
orientation="horizontal"
top="0"
width="1024">
- <panel auto_resize="true"
+ <layout_panel auto_resize="true"
follows="all"
height="500"
layout="topleft"
mouse_opaque="false"
+ tab_stop="false"
name="non_side_tray_view"
user_resize="false"
width="500">
@@ -60,19 +64,22 @@
left="0"
mouse_opaque="false"
name="world_stack"
- orientation="vertical">
+ orientation="vertical"
+ tab_stop="false">
<panel auto_resize="true"
follows="all"
height="500"
layout="topleft"
+ tab_stop="false"
mouse_opaque="false"
- name="hud container"
+ name="hud container"
width="500">
<panel follows="right|top|bottom"
height="500"
mouse_opaque="false"
name="side_bar_tabs"
right="500"
+ tab_stop="false"
top="0"
width="32"/>
<panel bottom="500"
@@ -80,6 +87,7 @@
height="25"
left="0"
mouse_opaque="false"
+ tab_stop="false"
name="stand_stop_flying_container"
visible="false"
width="500"/>
@@ -91,13 +99,14 @@
name="bottom_tray_container"
visible="false"/>
</layout_stack>
- </panel>
+ </layout_panel>
<!-- side tray -->
<layout_panel auto_resize="false"
follows="all"
height="500"
min_width="333"
mouse_opaque="false"
+ tab_stop="false"
name="side_tray_container"
user_resize="false"
visible="false"
@@ -132,8 +141,9 @@
</layout_panel>
</layout_stack>
<panel mouse_opaque="false"
- follows="left|right|top"
+ follows="left|right|top"
name="status_bar_container"
+ tab_stop="false"
height="19"
left="0"
top="0"
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 dddd178aea..41f4621d66 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.
@@ -3078,7 +3088,7 @@ Join me in [REGION]
icon="alertmodal.tga"
name="TeleportFromLandmark"
type="alertmodal">
-Are you sure you want to teleport?
+Are you sure you want to teleport to [LOCATION]?
<usetemplate
ignoretext="Confirm that I want to teleport to a landmark"
name="okcancelignore"
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_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index de3de45718..09ec2137b7 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -265,7 +265,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.
left="1"
min_width="110"
name="chiclet_list"
- top="6"
+ top="8"
chiclet_padding="4"
scrolling_offset="40"
width="189">
@@ -284,7 +284,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.
name="chicklet_left_scroll_button"
scale_image="true"
tab_stop="false"
- top="-2"
+ top="-4"
right_pad="2"
visible="false"
width="7" />
@@ -303,7 +303,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.
name="chicklet_right_scroll_button"
scale_image="true"
tab_stop="false"
- top="-2"
+ top="-4"
visible="false"
width="7" />
</chiclet_panel>
@@ -334,11 +334,11 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.
max_displayed_count="99"
flash_period="0.3"
follows="right"
- height="23"
+ height="28"
layout="topleft"
left="0"
name="im_well"
- top="5"
+ top="0"
width="35">
<!--
Emulate 4 states of button by background images, see details in EXT-3147. The same should be for notification_well button
@@ -350,7 +350,6 @@ image_pressed_selected "Lit" + "Selected" - there are new messages and the Well
-->
<button
auto_resize="true"
- flash_color="ChicletFlashColor"
follows="right"
halign="center"
height="23"
@@ -358,12 +357,12 @@ image_pressed_selected "Lit" + "Selected" - there are new messages and the Well
image_overlay_alignment="center"
image_pressed="WellButton_Lit"
image_pressed_selected="WellButton_Lit_Selected"
- image_selected="PushButton_Selected_Press"
+ image_selected="PushButton_Press"
label_color="Black"
left="0"
name="Unread IM messages"
tool_tip="Conversations"
- width="35" >
+ width="34" >
<button.init_callback
function="Button.SetDockableFloaterToggle"
parameter="im_well_window" />
@@ -407,25 +406,23 @@ image_pressed_selected "Lit" + "Selected" - there are new messages and the Well
bottom_pad="3"
image_pressed="WellButton_Lit"
image_pressed_selected="WellButton_Lit_Selected"
- image_selected="PushButton_Selected_Press"
+ image_selected="PushButton_Press"
auto_resize="true"
halign="center"
height="23"
follows="right"
- flash_color="ChicletFlashColor"
label_color="Black"
left="0"
name="Unread"
image_overlay="Notices_Unread"
image_overlay_alignment="center"
- pad_right="15"
tool_tip="Notifications"
- width="35" >
+ width="34" >
<button.init_callback
function="Button.SetDockableFloaterToggle"
parameter="notification_well_window" />
</button>
- <icon
+ <icon
auto_resize="false"
color="0 0 0 0"
follows="left|right"
diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
index 673052c3b5..0893c204e7 100644
--- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
@@ -67,6 +67,7 @@ background_visible="true"
layout="topleft"
left="20"
name="insignia"
+ no_commit_on_selection="true"
tool_tip="Click to choose a picture"
top_pad="5"
width="100" />
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_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
index 6b3fb04549..618d2f3b8e 100644
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -49,6 +49,18 @@
Select multiple Members by holding the Ctrl key and
clicking on their names.
</panel.string>
+ <panel.string
+ name="power_folder_icon">
+ Inv_FolderClosed
+ </panel.string>
+ <panel.string
+ name="power_all_have_icon">
+ Checkbox_On
+ </panel.string>
+ <panel.string
+ name="power_partial_icon">
+ Checkbox_Off
+ </panel.string>
<filter_editor
layout="topleft"
top="5"
@@ -310,7 +322,7 @@ things in this group. There&apos;s a broad variety of Abilities.
width="285">
Allowed Abilities
</text>
- <scroll_list
+ <scroll_list
draw_stripes="true"
height="90"
layout="topleft"
@@ -322,8 +334,16 @@ things in this group. There&apos;s a broad variety of Abilities.
width="300">
<scroll_list.columns
label=""
+ name="icon"
+ width="2" />
+ <scroll_list.columns
+ label=""
+ name="checkbox"
+ width="20" />
+ <scroll_list.columns
+ label=""
name="action"
- width="300" />
+ width="270" />
</scroll_list>
</panel>
<panel
diff --git a/indra/newview/skins/default/xui/en/panel_my_profile.xml b/indra/newview/skins/default/xui/en/panel_my_profile.xml
index 2659156ba8..4894ae01da 100644
--- a/indra/newview/skins/default/xui/en/panel_my_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_my_profile.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
follows="all"
- height="535"
+ height="500"
label="Profile"
layout="topleft"
left="0"
@@ -41,7 +41,7 @@
layout="topleft"
left="0"
top="0"
- height="535"
+ height="480"
width="313"
border_size="0">
<layout_panel
@@ -50,7 +50,8 @@
layout="topleft"
top="0"
left="0"
- height="505"
+ height="480"
+ user_resize="false"
width="313">
<scroll_container
color="DkGray2"
@@ -59,7 +60,7 @@
left="0"
name="profile_scroll"
opaque="true"
- height="505"
+ height="480"
width="313"
top="0">
<panel
@@ -365,6 +366,7 @@
top_pad="0"
name="profile_me_buttons_panel"
visible="false"
+ user_resize="false"
auto_resize="false"
height="28"
width="313">
@@ -372,8 +374,9 @@
follows="bottom|right"
height="23"
left="20"
- top="0"
+ top="5"
label="Edit Profile"
+ layout="topleft"
name="edit_profile_btn"
tool_tip="Edit your personal information"
width="130" />
@@ -382,7 +385,9 @@
height="23"
label="Edit Appearance"
left_pad="10"
+ layout="topleft"
name="edit_appearance_btn"
+ top="5"
tool_tip="Create/edit your appearance: physical data, clothes and etc."
width="130" />
</layout_panel>
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index bfc97ed5da..baa6c2e51f 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -142,8 +142,8 @@
left="0"
name="favorite"
image_drag_indication="Accordion_ArrowOpened_Off"
- bottom="55"
- width="590">
+ bottom="55"
+ width="590">
<chevron_button name=">>"
image_unselected="TabIcon_Close_Off"
image_selected="TabIcon_Close_Off"
diff --git a/indra/newview/skins/default/xui/en/panel_notes.xml b/indra/newview/skins/default/xui/en/panel_notes.xml
index 45b64d5e26..ac100a2c06 100644
--- a/indra/newview/skins/default/xui/en/panel_notes.xml
+++ b/indra/newview/skins/default/xui/en/panel_notes.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
follows="all"
- height="535"
+ height="540"
label="Notes &amp; Privacy"
layout="topleft"
left="0"
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
index 8895484326..710ca733e0 100644
--- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
@@ -45,7 +45,7 @@
left="0"
top="0"
mouse_opaque="true"
- name="cof_accordionpanel"
+ name="cof_tab"
start_folder="Current Outfit"
width="313" />
</tab_container>
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 8a02637817..da3a2274c9 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -3,7 +3,7 @@
<panel
background_visible="true"
follows="all"
- height="570"
+ height="575"
label="People"
layout="topleft"
min_height="350"
@@ -337,7 +337,7 @@ background_visible="true"
</tab_container>
<panel
follows="bottom|left"
- height="25"
+ height="35"
layout="topleft"
left="10"
name="button_bar"
diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml
index 822e049eec..65ccd10cf0 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml
@@ -39,7 +39,7 @@
height="500"
layout="topleft"
left="10"
- top_pad="10"
+ top_pad="5"
name="profile_scroll"
width="313">
<panel
@@ -102,7 +102,7 @@
</scroll_container>
<panel
follows="left|right|bottom"
- height="20"
+ height="35"
layout="topleft"
top_pad="8"
left="10"
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
index a2b0adf9d9..d31f4d039f 100644
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ b/indra/newview/skins/default/xui/en/panel_picks.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
follows="all"
- height="535"
+ height="540"
label="Picks"
layout="topleft"
left="0"
@@ -121,7 +121,7 @@
<panel
layout="topleft"
left="0"
- height="25"
+ height="30"
top_pad="10"
name="buttons_cucks"
width="313">
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 f6900cc31c..8723e0a832 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -9,64 +9,64 @@
name="Input panel"
top="1"
width="517">
- <button
- height="23"
- label="Other Devices"
- layout="topleft"
- left="30"
- name="joystick_setup_button"
- top="10"
- width="155">
- <button.commit_callback
- function="Floater.Show"
- parameter="pref_joystick" />
- </button>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="30"
- name="Mouselook:"
- top_pad="10"
- width="300">
- Mouselook:
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_delta="50"
- name=" Mouse Sensitivity"
- top_pad="10"
- width="150">
- Mouse sensitivity
- </text>
- <slider
- control_name="MouseSensitivity"
- follows="left|top"
- height="15"
- initial_value="2"
- layout="topleft"
- show_text="false"
- left_delta="150"
- max_val="15"
- name="mouse_sensitivity"
- top_delta="0"
- width="145" />
- <check_box
- control_name="InvertMouse"
- height="16"
- label="Invert"
- layout="topleft"
- left_pad="2"
- name="invert_mouse"
- top_delta="0"
- width="128" />
- <text
+ <button
+ height="23"
+ label="Other Devices"
+ layout="topleft"
+ left="30"
+ name="joystick_setup_button"
+ top="10"
+ width="155">
+ <button.commit_callback
+ function="Floater.Show"
+ parameter="pref_joystick" />
+ </button>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="30"
+ name="Mouselook:"
+ top_pad="10"
+ width="300">
+ Mouselook:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="50"
+ name=" Mouse Sensitivity"
+ top_pad="10"
+ width="150">
+ Mouse sensitivity
+ </text>
+ <slider
+ control_name="MouseSensitivity"
+ follows="left|top"
+ height="15"
+ initial_value="2"
+ layout="topleft"
+ show_text="false"
+ left_delta="150"
+ max_val="15"
+ name="mouse_sensitivity"
+ top_delta="0"
+ width="145" />
+ <check_box
+ control_name="InvertMouse"
+ height="16"
+ label="Invert"
+ layout="topleft"
+ left_pad="2"
+ name="invert_mouse"
+ top_delta="0"
+ width="128" />
+ <text
type="string"
length="1"
follows="left|top"
@@ -77,266 +77,270 @@
mouse_opaque="false"
top_pad="4"
width="300">
- Network:
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_delta="50"
- name="Maximum bandwidth"
- mouse_opaque="false"
- top_pad="10"
- width="200">
- Maximum bandwidth
- </text>
- <slider
- can_edit_text="true"
- control_name="ThrottleBandwidthKBPS"
- decimal_digits="0"
- follows="left|top"
- height="15"
- increment="100"
- initial_value="500"
- layout="topleft"
- left_delta="150"
- max_val="10000"
- min_val="100"
- name="max_bandwidth"
- top_delta="0"
- width="180" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_pad="6"
- mouse_opaque="false"
- name="text_box2"
- top_delta="1"
- width="200">
- kbps
- </text>
- <check_box
- control_name="ConnectionPortEnabled"
- height="16"
- label="Custom port"
- layout="topleft"
- left="77"
- name="connection_port_enabled"
- top_pad="20"
- width="256">
- <check_box.commit_callback
- function="Notification.Show"
- parameter="ChangeConnectionPort" />
- </check_box>
- <spinner
- control_name="BrowserProxyPort"
- enabled_control="BrowserProxyEnabled"
- decimal_digits="0"
- follows="left|top"
- height="23"
- increment="1"
- initial_value="80"
- label="Port number:"
- label_width="75"
- layout="topleft"
- left_delta="160"
- max_val="12000"
- min_val="10"
- name="web_proxy_port"
- top_delta="-2"
- width="140" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="80"
- mouse_opaque="false"
- name="cache_size_label_l"
- top_pad="20"
- width="200">
- Cache size
- </text>
- <slider
- can_edit_text="true"
- control_name="CacheSize"
- decimal_digits="0"
- follows="left|top"
- height="15"
- increment="16"
- initial_value="512"
- layout="topleft"
- left_delta="150"
- max_val="1024"
- min_val="32"
- name="cache_size"
- top_delta="-2"
- width="180" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_pad="6"
- mouse_opaque="false"
- name="text_box5"
- top_delta="1"
- width="40">
- MB
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="80"
- name="Cache location"
- top_delta="20"
- width="300">
- Cache location:
- </text>
- <line_editor
- control_name="CacheLocationTopFolder"
- border_style="line"
- border_thickness="1"
- enabled="false"
- follows="left|top"
- font="SansSerif"
- handle_edit_keys_directly="true"
- height="23"
- layout="topleft"
- left="80"
- max_length="4096"
- name="cache_location"
- top_pad="5"
- width="205" />
- <button
- follows="left|top"
- height="23"
- label="Browse"
- label_selected="Browse"
- layout="topleft"
- left_pad="5"
- name="set_cache"
- top_delta="-1"
- width="100">
- <button.commit_callback
- function="Pref.SetCache" />
- </button>
- <button
- follows="left|top"
- height="23"
- label="Reset"
- label_selected="Reset"
- layout="topleft"
- left_pad="3"
- name="reset_cache"
- top_delta="0"
- width="100">
- <button.commit_callback
- function="Pref.ResetCache" />
- </button>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="30"
- name="Web:"
- top_pad="5"
- width="300">
- Web:
- </text>
- <radio_group
- control_name="UseExternalBrowser"
- draw_border="false"
- follows="top|left"
- height="40"
- layout="topleft"
- left_delta="50"
- name="use_external_browser"
- top_pad="4"
- width="480">
- <radio_item
- height="20"
- label="Use built-in browser"
- layout="topleft"
- left="0"
- name="internal"
- value="0"
- tool_tip="Use the built-in web browser for help, web links, etc. This browser opens as a new window inside [APP_NAME]."
- top="0"
- width="480" />
- <radio_item
- height="20"
- label="Use my browser (IE, Firefox)"
- layout="topleft"
- left_delta="0"
- name="external"
- value="1"
- tool_tip="Use the default system web browser for help, web links, etc. Not recommended if running full screen."
- top_delta="20"
- width="480" />
- </radio_group>
-
- <check_box
- top_delta="4"
- enabled="true"
- follows="left|top"
- height="16"
- initial_value="false"
- label="Web proxy"
- left_delta="0"
- mouse_opaque="true"
- name="web_proxy_enabled"
- radio_style="false"
- width="400"
- top_pad="5"/>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_delta="1"
- name="Proxy location"
- top_delta="20"
- width="300">
- Proxy location:
- </text>
- <line_editor
- control_name="BrowserProxyAddress"
- enabled_control="BrowserProxyEnabled"
- follows="left|top"
- font="SansSerif"
- height="23"
- layout="topleft"
- left_delta="0"
- name="web_proxy_editor"
- tool_tip="The name or IP address of the proxy you would like to use"
- top_pad="4"
- width="200" />
- <button
- follows="left|top"
- height="23"
- enabled="false"
- label="Browse"
- label_selected="Browse"
- layout="topleft"
- left_pad="5"
- name="set_proxy"
- top_pad="-21"
- width="100">
- <button.commit_callback
- function="Pref.SetCache" />
- </button>
- </panel>
+ Network:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="50"
+ name="Maximum bandwidth"
+ mouse_opaque="false"
+ top_pad="10"
+ width="200">
+ Maximum bandwidth
+ </text>
+ <slider
+ can_edit_text="true"
+ control_name="ThrottleBandwidthKBPS"
+ decimal_digits="0"
+ follows="left|top"
+ height="15"
+ increment="100"
+ initial_value="500"
+ layout="topleft"
+ left_delta="150"
+ max_val="10000"
+ min_val="100"
+ name="max_bandwidth"
+ top_delta="0"
+ width="180" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="6"
+ mouse_opaque="false"
+ name="text_box2"
+ top_delta="1"
+ width="200">
+ kbps
+ </text>
+ <check_box
+ control_name="ConnectionPortEnabled"
+ height="16"
+ label="Custom port"
+ layout="topleft"
+ left="77"
+ name="connection_port_enabled"
+ top_pad="20"
+ width="256">
+ <check_box.commit_callback
+ function="Notification.Show"
+ parameter="ChangeConnectionPort" />
+ </check_box>
+ <spinner
+ control_name="ConnectionPort"
+ enabled_control="ConnectionPortEnabled"
+ decimal_digits="0"
+ follows="left|top"
+ height="23"
+ increment="1"
+ initial_value="13000"
+ label="Port number:"
+ label_width="75"
+ layout="topleft"
+ left_delta="160"
+ max_val="13050"
+ min_val="13000"
+ name="connection_port"
+ top_delta="-2"
+ width="140" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="80"
+ mouse_opaque="false"
+ name="cache_size_label_l"
+ top_pad="20"
+ width="200">
+ Cache size
+ </text>
+ <slider
+ can_edit_text="true"
+ control_name="CacheSize"
+ decimal_digits="0"
+ follows="left|top"
+ height="15"
+ increment="16"
+ initial_value="512"
+ layout="topleft"
+ left_delta="150"
+ max_val="1024"
+ min_val="32"
+ name="cache_size"
+ top_delta="-2"
+ width="180" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="6"
+ mouse_opaque="false"
+ name="text_box5"
+ top_delta="1"
+ width="40">
+ MB
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="80"
+ name="Cache location"
+ top_delta="20"
+ width="300">
+ Cache location:
+ </text>
+ <line_editor
+ control_name="CacheLocationTopFolder"
+ border_style="line"
+ border_thickness="1"
+ enabled="false"
+ follows="left|top"
+ font="SansSerif"
+ handle_edit_keys_directly="true"
+ height="23"
+ layout="topleft"
+ left="80"
+ max_length="4096"
+ name="cache_location"
+ top_pad="5"
+ width="205" />
+ <button
+ follows="left|top"
+ height="23"
+ label="Browse"
+ label_selected="Browse"
+ layout="topleft"
+ left_pad="5"
+ name="set_cache"
+ top_delta="-1"
+ width="100">
+ <button.commit_callback
+ function="Pref.SetCache" />
+ </button>
+ <button
+ follows="left|top"
+ height="23"
+ label="Reset"
+ label_selected="Reset"
+ layout="topleft"
+ left_pad="3"
+ name="reset_cache"
+ top_delta="0"
+ width="100">
+ <button.commit_callback
+ function="Pref.ResetCache" />
+ </button>
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="30"
+ name="Web:"
+ top_pad="5"
+ width="300">
+ Web:
+ </text>
+ <radio_group
+ control_name="UseExternalBrowser"
+ draw_border="false"
+ follows="top|left"
+ height="40"
+ layout="topleft"
+ left_delta="50"
+ name="use_external_browser"
+ top_pad="4"
+ width="480">
+ <radio_item
+ height="20"
+ label="Use built-in browser"
+ layout="topleft"
+ left="0"
+ name="internal"
+ value="0"
+ tool_tip="Use the built-in web browser for help, web links, etc. This browser opens as a new window inside [APP_NAME]."
+ top="0"
+ width="480" />
+ <radio_item
+ height="20"
+ label="Use my browser (IE, Firefox, Safari)"
+ layout="topleft"
+ left_delta="0"
+ name="external"
+ value="1"
+ tool_tip="Use the default system web browser for help, web links, etc. Not recommended if running full screen."
+ top_delta="20"
+ width="480" />
+ </radio_group>
+
+ <check_box
+ top_delta="4"
+ enabled="true"
+ follows="left|top"
+ height="16"
+ initial_value="false"
+ control_name="BrowserProxyEnabled"
+ label="Enable Web Proxy"
+ left_delta="0"
+ mouse_opaque="true"
+ name="web_proxy_enabled"
+ radio_style="false"
+ width="400" top_pad="5"/>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="1"
+ name="Proxy location"
+ top_delta="20"
+ width="300">
+ Proxy location:
+ </text>
+ <line_editor
+ control_name="BrowserProxyAddress"
+ enabled_control="BrowserProxyEnabled"
+ follows="left|top"
+ font="SansSerif"
+ height="23"
+ layout="topleft"
+ left_delta="0"
+ name="web_proxy_editor"
+ tool_tip="The name or IP address of the proxy you would like to use"
+ top_pad="4"
+ width="200" />
+ <spinner
+ control_name="BrowserProxyPort"
+ enabled_control="BrowserProxyEnabled"
+ decimal_digits="0"
+ follows="left|top"
+ height="23"
+ increment="1"
+ initial_value="80"
+ label="Port number:"
+ label_width="75"
+ layout="topleft"
+ left_delta="230"
+ max_val="12000"
+ min_val="10"
+ name="web_proxy_port"
+ top_delta="0"
+ width="140" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml
index 2b907ed251..7c584ba2c8 100644
--- a/indra/newview/skins/default/xui/en/panel_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
follows="all"
- height="535"
+ height="540"
label="Profile"
layout="topleft"
left="0"
@@ -66,6 +66,7 @@
layout="topleft"
follows="left|top|right"
height="505"
+ min_height="505"
name="profile_scroll_panel"
top="0"
left="0"
@@ -108,10 +109,10 @@
textbox.max_length="512"
name="sl_description_edit"
top_pad="-3"
- width="185"
+ width="180"
expanded_bg_visible="true"
expanded_bg_color="DkGray">
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum.
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra orci et justo sagittis aliquet.Nullamma lesuada mauris sit amet ipsum. adipiscing elit. Ae nean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum.
</expandable_text>
</panel>
<panel
@@ -151,7 +152,7 @@
textbox.max_length="512"
name="fl_description_edit"
top_pad="-3"
- width="185"
+ width="180"
expanded_bg_visible="true"
expanded_bg_color="DkGray">
Lorem ipsum dolor sit amet, consectetur adlkjpiscing elit moose moose. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet. adipiscing elit. Aenean rigviverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet sorbet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum.
@@ -284,10 +285,10 @@
</layout_panel>
<layout_panel
follows="bottom|left"
- height="28"
+ height="30"
layout="topleft"
name="profile_buttons_panel"
- auto_resize="false"
+ auto_resize="false"
width="313">
<button
follows="bottom|left"
@@ -355,7 +356,7 @@
</layout_panel>
<layout_panel
follows="bottom|left"
- height="28"
+ height="30"
layout="topleft"
name="profile_me_buttons_panel"
visible="false"
@@ -364,7 +365,7 @@
follows="bottom|right"
height="23"
left="20"
- top="0"
+ top="0"
label="Edit Profile"
name="edit_profile_btn"
tool_tip="Edit your personal information"
@@ -378,6 +379,6 @@
tool_tip="Create/edit your appearance: physical data, clothes and etc."
width="130" />
</layout_panel>
-
+
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml
index c51447eaf0..d46e1f9852 100644
--- a/indra/newview/skins/default/xui/en/panel_profile_view.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml
@@ -60,7 +60,7 @@
tab_min_width="80"
tab_height="30"
tab_position="top"
- top_pad="10"
+ top_pad="5"
width="313">
<panel
class="panel_profile"
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/en/widgets/chiclet_im_adhoc.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml
index 328d521636..63f08a4250 100644
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml
+++ b/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml
@@ -4,13 +4,13 @@
name="im_adhoc_chiclet"
show_speaker="false"
width="25">
- <chiclet_im_adhoc.chiclet_button
- height="23"
- image_selected="PushButton_Selected"
+ <chiclet_im_adhoc.chiclet_button
+ height="25"
+ image_selected="PushButton_On"
image_unselected="PushButton_Off"
name="chiclet_button"
tab_stop="false"
- width="25"/>
+ width="25" />
<chiclet_im_adhoc.speaker
auto_update="true"
draw_border="false"
@@ -20,15 +20,15 @@
visible="false"
width="20" />
<chiclet_im_adhoc.avatar_icon
- bottom="2"
+ bottom="3"
follows="left|top|bottom"
- height="19"
- left="3"
+ height="20"
+ left="2"
mouse_opaque="true"
name="adhoc_icon"
- width="18" />
+ width="21" />
<chiclet_im_adhoc.unread_notifications
- font_halign="center"
+ halign="center"
height="23"
left="25"
mouse_opaque="false"
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml
index 60658899ee..372a89cbc7 100644
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml
+++ b/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml
@@ -4,33 +4,33 @@
name="im_group_chiclet"
show_speaker="false"
width="25">
- <chiclet_im_group.chiclet_button
- height="23"
- image_selected="PushButton_Selected"
+ <chiclet_im_group.chiclet_button
+ height="25"
+ image_selected="PushButton_On"
image_unselected="PushButton_Off"
name="chiclet_button"
tab_stop="false"
- width="25"/>
+ width="25" />
<chiclet_im_group.speaker
auto_update="true"
draw_border="false"
- height="23"
+ height="25"
left="25"
name="speaker"
visible="false"
width="20" />
<chiclet_im_group.group_icon
- bottom="2"
+ bottom="3"
default_icon="Generic_Group"
follows="left|top|bottom"
- height="18"
- left="3"
+ height="20"
+ left="2"
mouse_opaque="false"
name="group_icon"
- width="19" />
+ width="21" />
<chiclet_im_group.unread_notifications
height="23"
- font_halign="center"
+ halign="center"
left="25"
mouse_opaque="false"
name="unread"
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml
index b5b8f0d07a..99807d4717 100644
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml
+++ b/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml
@@ -4,9 +4,9 @@
name="im_p2p_chiclet"
show_speaker="false"
width="25">
- <chiclet_im_p2p.chiclet_button
- height="23"
- image_selected="PushButton_Selected"
+ <chiclet_im_p2p.chiclet_button
+ height="25"
+ image_selected="PushButton_On"
image_unselected="PushButton_Off"
name="chiclet_button"
tab_stop="false"
@@ -18,18 +18,18 @@
left="25"
name="speaker"
visible="false"
- width="20"/>
+ width="20" />
<chiclet_im_p2p.avatar_icon
- bottom="2"
+ bottom="3"
follows="left|top|bottom"
- height="18"
- left="3"
+ height="20"
+ left="2"
mouse_opaque="false"
name="avatar_icon"
- width="19" />
+ width="21" />
<chiclet_im_p2p.unread_notifications
height="23"
- font_halign="center"
+ halign="center"
left="25"
mouse_opaque="false"
name="unread"
@@ -45,4 +45,4 @@
name="new_message_icon"
visible="false"
width="14" />
-</chiclet_im_p2p> \ No newline at end of file
+</chiclet_im_p2p>
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_offer.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_offer.xml
index 1bf9bc9e71..4bc295f747 100644
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_offer.xml
+++ b/indra/newview/skins/default/xui/en/widgets/chiclet_offer.xml
@@ -3,22 +3,22 @@
height="23"
name="offer_chiclet"
width="25">
- <chiclet_offer.chiclet_button
- height="23"
- image_selected="PushButton_Selected"
+ <chiclet_offer.chiclet_button
+ height="25"
+ image_selected="PushButton_On"
image_unselected="PushButton_Off"
name="chiclet_button"
tab_stop="false"
- width="25"/>
+ width="25" />
<chiclet_offer.icon
- bottom="2"
+ bottom="3"
default_icon="Generic_Object_Small"
follows="all"
- height="18"
- left="3"
+ height="20"
+ left="2"
mouse_opaque="false"
name="chiclet_icon"
- width="19" />
+ width="21" />
<chiclet_offer.new_message_icon
bottom="11"
height="14"
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml
index f3207ddeae..5f51f4afd9 100644
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml
+++ b/indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<chiclet_panel
- name="chiclet_panel"
+ name="chiclet_panel"
chiclet_padding="3"
scrolling_offset="40"
- scroll_button_hpad="5"
+ scroll_button_hpad="0"
scroll_ratio="10"
min_width="180"
/> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_script.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_script.xml
index 38d9904d13..db6a9434df 100644
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_script.xml
+++ b/indra/newview/skins/default/xui/en/widgets/chiclet_script.xml
@@ -3,22 +3,22 @@
height="23"
name="script_chiclet"
width="25">
- <chiclet_script.chiclet_button
- height="23"
- image_selected="PushButton_Selected"
+ <chiclet_script.chiclet_button
+ height="25"
+ image_selected="PushButton_On"
image_unselected="PushButton_Off"
name="chiclet_button"
tab_stop="false"
width="25"/>
<chiclet_script.icon
- bottom="2"
+ bottom="3"
follows="all"
height="18"
image_name="Generic_Object_Small"
- left="3"
+ left="2"
mouse_opaque="false"
name="chiclet_icon"
- width="19"/>
+ width="21"/>
<chiclet_script.new_message_icon
bottom="11"
height="14"
diff --git a/indra/newview/skins/default/xui/en/widgets/color_swatch.xml b/indra/newview/skins/default/xui/en/widgets/color_swatch.xml
index bda88857ae..dfd301a770 100644
--- a/indra/newview/skins/default/xui/en/widgets/color_swatch.xml
+++ b/indra/newview/skins/default/xui/en/widgets/color_swatch.xml
@@ -3,6 +3,6 @@
border_color="ColorSwatchBorderColor"
name="color_swatch">
<color_swatch.caption_text name="caption"
- font="SansSerifSmall"
+ halign="center"
follows="left|right|bottom"/>
</color_swatch>
diff --git a/indra/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml
index 5545ab29e0..e8e38316f9 100644
--- a/indra/newview/skins/default/xui/es/floater_about.xml
+++ b/indra/newview/skins/default/xui/es/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_about" title="ACERCA DE [APP_NAME]">
+<floater name="floater_about" title="ACERCA DE [CAPITALIZED_APP_NAME]">
<tab_container name="about_tab">
<panel name="credits_panel">
<text_editor name="credits_editor">
diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml
index 33299f4cd4..7d6d736c5e 100644
--- a/indra/newview/skins/default/xui/fr/floater_about.xml
+++ b/indra/newview/skins/default/xui/fr/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_about" title="À PROPOS DE [APP_NAME]">
+<floater name="floater_about" title="À PROPOS DE [CAPITALIZED_APP_NAME]">
<floater.string name="AboutHeader">
[APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2] ([VIEWER_VERSION_3]) [BUILD_DATE] [BUILD_TIME] ([CHANNEL])
[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]
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_profile.xml b/indra/newview/skins/default/xui/fr/panel_edit_profile.xml
index b8ab805b13..a4771db91b 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_profile.xml
@@ -39,10 +39,10 @@
<line_editor name="homepage_edit" value="http://"/>
<check_box label="Afficher dans les résultats de recherche" name="show_in_search_checkbox"/>
<text name="title_acc_status_text" value="Mon compte :"/>
- <text name="my_account_link" value="Accéder à ma Page d&apos;accueil"/>
+ <text name="my_account_link" value="[[URL] Accéder à ma Page d&apos;accueil]"/>
<text name="acc_status_text" value="Résident. Aucune info de paiement enregistrée."/>
<text name="title_partner_text" value="Mon partenaire :"/>
- <text name="partner_edit_link" value="[Modifier [URL]]"/>
+ <text name="partner_edit_link" value="[[URL] Modifier]"/>
<panel name="partner_data_panel">
<text name="partner_text" value="[FIRST] [LAST]"/>
</panel>
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
diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml
index a5aff9d486..f80f810dba 100644
--- a/indra/newview/skins/default/xui/it/floater_about.xml
+++ b/indra/newview/skins/default/xui/it/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_about" title="INFORMAZIONI SU [APP_NAME]">
+<floater name="floater_about" title="INFORMAZIONI SU [CAPITALIZED_APP_NAME]">
<tab_container name="about_tab">
<panel name="credits_panel">
<text_editor name="credits_editor">
diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml
index bab805dbd2..0fa20ab1ac 100644
--- a/indra/newview/skins/default/xui/ja/floater_about.xml
+++ b/indra/newview/skins/default/xui/ja/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_about" title="[APP_NAME] について">
+<floater name="floater_about" title="[CAPITALIZED_APP_NAME] について">
<floater.string name="AboutHeader">
[APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2] ([VIEWER_VERSION_3]) [BUILD_DATE] [BUILD_TIME] ([CHANNEL])
[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_profile.xml b/indra/newview/skins/default/xui/ja/panel_edit_profile.xml
index 8af0802ac2..b232a8db61 100644
--- a/indra/newview/skins/default/xui/ja/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_profile.xml
@@ -39,7 +39,7 @@
<line_editor name="homepage_edit" value="http://"/>
<check_box label="検索結果に表示" name="show_in_search_checkbox"/>
<text name="title_acc_status_text" value="マイアカウント:"/>
- <text name="my_account_link" value="マイアカウントに移動"/>
+ <text name="my_account_link" value="[[URL] マイアカウントに移動]"/>
<text name="acc_status_text" value="住人。 支払情報未登録。"/>
<text name="title_partner_text" value="マイパートナー:"/>
<text name="partner_edit_link" value="[[URL] 編集]"/>
diff --git a/indra/newview/skins/default/xui/nl/floater_about.xml b/indra/newview/skins/default/xui/nl/floater_about.xml
index 0c57a22be1..10c30eb361 100644
--- a/indra/newview/skins/default/xui/nl/floater_about.xml
+++ b/indra/newview/skins/default/xui/nl/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_about" title="OVER [APP_NAME]">
+<floater name="floater_about" title="OVER [CAPITALIZED_APP_NAME]">
<tab_container name="about_tab">
<panel name="credits_panel">
<text_editor name="credits_editor">
diff --git a/indra/newview/skins/default/xui/pl/floater_about.xml b/indra/newview/skins/default/xui/pl/floater_about.xml
index 0f100b9d83..f59630edc7 100755
--- a/indra/newview/skins/default/xui/pl/floater_about.xml
+++ b/indra/newview/skins/default/xui/pl/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater name="floater_about" title="O [APP_NAME]">
+<floater name="floater_about" title="O [CAPITALIZED_APP_NAME]">
<tab_container name="about_tab">
<panel name="credits_panel">
<text_editor name="credits_editor">
diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml
index 9c19b12893..704e2f4107 100644
--- a/indra/newview/skins/default/xui/pt/floater_about.xml
+++ b/indra/newview/skins/default/xui/pt/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_about" title="SOBRE O [APP_NAME]">
+<floater name="floater_about" title="SOBRE O [CAPITALIZED_APP_NAME]">
<tab_container name="about_tab">
<panel name="credits_panel">
<text_editor name="credits_editor">
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 00a903431a..15a51bbe14 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -822,8 +822,8 @@ class LinuxManifest(ViewerManifest):
'dst': self.get_dst_prefix(),
'inst': self.build_path_of(installer_name)})
try:
- # only create tarball if it's not a debug build.
- if self.args['buildtype'].lower() != 'debug':
+ # only create tarball if it's a release build.
+ if self.args['buildtype'].lower() == 'release':
# --numeric-owner hides the username of the builder for
# security etc.
self.run_command('tar -C %(dir)s --numeric-owner -cjf '
@@ -855,7 +855,7 @@ class Linux_i686Manifest(LinuxManifest):
pass
- if(self.args['buildtype'].lower() != 'debug'):
+ if(self.args['buildtype'].lower() == 'release'):
print "* packaging stripped viewer binary."
self.path("secondlife-stripped","bin/do-not-directly-run-secondlife-bin")
else: